diff options
657 files changed, 26216 insertions, 4817 deletions
diff --git a/Android.mk b/Android.mk index 121bc8e4b7bb..a7a2ecb6c6ce 100644 --- a/Android.mk +++ b/Android.mk @@ -285,7 +285,7 @@ LOCAL_SRC_FILES += \ core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \ core/java/com/android/internal/backup/IBackupTransport.aidl \ core/java/com/android/internal/backup/IObbBackupService.aidl \ - core/java/com/android/internal/policy/IKeyguardShowCallback.aidl \ + core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl \ core/java/com/android/internal/policy/IKeyguardExitCallback.aidl \ core/java/com/android/internal/policy/IKeyguardService.aidl \ core/java/com/android/internal/policy/IKeyguardStateCallback.aidl \ diff --git a/api/current.txt b/api/current.txt index ea33eaf40fb9..e16294edb380 100644 --- a/api/current.txt +++ b/api/current.txt @@ -66,6 +66,7 @@ package android { 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 GET_ACCOUNTS = "android.permission.GET_ACCOUNTS"; + field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED"; 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 GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH"; @@ -1806,6 +1807,7 @@ package android { field public static final int defaultVoiceMailAlphaTag = 17039364; // 0x1040004 field public static final int dialog_alert_title = 17039380; // 0x1040014 field public static final int emptyPhoneNumber = 17039366; // 0x1040006 + field public static final int fingerprint_icon_content_description = 17039384; // 0x1040018 field public static final int httpErrorBadUrl = 17039367; // 0x1040007 field public static final int httpErrorUnsupportedScheme = 17039368; // 0x1040008 field public static final int no = 17039369; // 0x1040009 @@ -3339,6 +3341,7 @@ package android.app { method public boolean isImmersive(); method public boolean isTaskRoot(); method public boolean isVoiceInteraction(); + method public boolean isVoiceInteractionRoot(); method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String); method public boolean moveTaskToBack(boolean); method public boolean navigateUpTo(android.content.Intent); @@ -3466,6 +3469,7 @@ package android.app { method public final void setVolumeControlStream(int); method public boolean shouldShowRequestPermissionRationale(java.lang.String); method public boolean shouldUpRecreateTask(android.content.Intent); + method public boolean showAssist(android.os.Bundle); method public final deprecated void showDialog(int); method public final deprecated boolean showDialog(int, android.os.Bundle); method public void showLockTaskEscapeMessage(); @@ -3863,12 +3867,14 @@ package android.app { field public static final java.lang.String OPSTR_RECEIVE_WAP_PUSH = "android:receive_wap_push"; field public static final java.lang.String OPSTR_RECORD_AUDIO = "android:record_audio"; field public static final java.lang.String OPSTR_SEND_SMS = "android:send_sms"; + field public static final java.lang.String OPSTR_SYSTEM_ALERT_WINDOW = "android:system_alert_window"; field public static final java.lang.String OPSTR_USE_FINGERPRINT = "android:use_fingerprint"; field public static final java.lang.String OPSTR_USE_SIP = "android:use_sip"; 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"; + field public static final java.lang.String OPSTR_WRITE_SETTINGS = "android:write_settings"; } public static abstract interface AppOpsManager.OnOpChangedListener { @@ -4772,9 +4778,9 @@ package android.app { field public int flags; field public android.app.PendingIntent fullScreenIntent; field public android.widget.RemoteViews headsUpContentView; - field public int icon; + field public deprecated int icon; field public int iconLevel; - field public android.graphics.Bitmap largeIcon; + field public deprecated android.graphics.Bitmap largeIcon; field public int ledARGB; field public int ledOffMS; field public int ledOnMS; @@ -4790,20 +4796,22 @@ package android.app { } public static class Notification.Action implements android.os.Parcelable { - ctor public Notification.Action(int, java.lang.CharSequence, android.app.PendingIntent); + ctor public deprecated Notification.Action(int, java.lang.CharSequence, android.app.PendingIntent); method public android.app.Notification.Action clone(); method public int describeContents(); method public android.os.Bundle getExtras(); + method public android.graphics.drawable.Icon getIcon(); method public android.app.RemoteInput[] getRemoteInputs(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.Notification.Action> CREATOR; field public android.app.PendingIntent actionIntent; - field public int icon; + field public deprecated int icon; field public java.lang.CharSequence title; } public static final class Notification.Action.Builder { - ctor public Notification.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent); + ctor public deprecated Notification.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent); + ctor public Notification.Action.Builder(android.graphics.drawable.Icon, java.lang.CharSequence, android.app.PendingIntent); ctor public Notification.Action.Builder(android.app.Notification.Action); method public android.app.Notification.Action.Builder addExtras(android.os.Bundle); method public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput); @@ -4851,7 +4859,7 @@ package android.app { public static class Notification.Builder { ctor public Notification.Builder(android.content.Context); - method public android.app.Notification.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent); + method public deprecated android.app.Notification.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent); method public android.app.Notification.Builder addAction(android.app.Notification.Action); method public android.app.Notification.Builder addExtras(android.os.Bundle); method public android.app.Notification.Builder addPerson(java.lang.String); @@ -5690,6 +5698,7 @@ package android.app.admin { method public void uninstallCaCert(android.content.ComponentName, byte[]); method public void wipeData(int); field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN"; + field public static final java.lang.String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED"; field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED"; field public static final java.lang.String ACTION_PROVISION_MANAGED_DEVICE = "android.app.action.PROVISION_MANAGED_DEVICE"; field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE"; @@ -9308,6 +9317,7 @@ package android.content.pm { field public static final java.lang.String FEATURE_FAKETOUCH = "android.hardware.faketouch"; field public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT = "android.hardware.faketouch.multitouch.distinct"; field public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = "android.hardware.faketouch.multitouch.jazzhand"; + field public static final java.lang.String FEATURE_FINGERPRINT = "android.hardware.fingerprint"; field public static final java.lang.String FEATURE_GAMEPAD = "android.hardware.gamepad"; field public static final java.lang.String FEATURE_HIFI_SENSORS = "android.hardware.sensor.hifi_sensors"; field public static final java.lang.String FEATURE_HOME_SCREEN = "android.software.home_screen"; @@ -9440,6 +9450,7 @@ package android.content.pm { method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager); field public static final android.os.Parcelable.Creator<android.content.pm.PermissionInfo> CREATOR; field public static final int FLAG_COSTS_MONEY = 1; // 0x1 + field public static final int FLAG_INSTALLED = 1073741824; // 0x40000000 field public static final int PROTECTION_DANGEROUS = 1; // 0x1 field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40 field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20 @@ -18138,8 +18149,11 @@ package android.net { method public boolean requestBandwidthUpdate(android.net.Network); method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent); + method public deprecated boolean requestRouteToHost(int, int); method public deprecated void setNetworkPreference(int); method public static deprecated boolean setProcessDefaultNetwork(android.net.Network); + method public deprecated int startUsingNetworkFeature(int, java.lang.String); + method public deprecated int stopUsingNetworkFeature(int, java.lang.String); method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback); method public void unregisterNetworkCallback(android.app.PendingIntent); field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"; @@ -22691,7 +22705,7 @@ package android.os { 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 = 23; // 0x17 + field public static final int M = 23; // 0x17 } public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable { @@ -26391,6 +26405,7 @@ package android.provider { public final class Settings { ctor public Settings(); + method public static boolean canDrawOverlays(android.content.Context); field public static final java.lang.String ACTION_ACCESSIBILITY_SETTINGS = "android.settings.ACCESSIBILITY_SETTINGS"; field public static final java.lang.String ACTION_ADD_ACCOUNT = "android.settings.ADD_ACCOUNT_SETTINGS"; field public static final java.lang.String ACTION_AIRPLANE_MODE_SETTINGS = "android.settings.AIRPLANE_MODE_SETTINGS"; @@ -26563,7 +26578,7 @@ package android.provider { field public static final deprecated java.lang.String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed"; field public static final deprecated java.lang.String LOCK_PATTERN_ENABLED = "lock_pattern_autolock"; field public static final deprecated java.lang.String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled"; - field public static final java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern"; + field public static final deprecated java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern"; field public static final deprecated java.lang.String LOGGING_ID = "logging_id"; field public static final deprecated java.lang.String NETWORK_PREFERENCE = "network_preference"; field public static final java.lang.String PARENTAL_CONTROL_ENABLED = "parental_control_enabled"; @@ -26610,6 +26625,7 @@ package android.provider { public static final class Settings.System extends android.provider.Settings.NameValueTable { ctor public Settings.System(); + method public static boolean canWrite(android.content.Context); method public static void getConfiguration(android.content.ContentResolver, android.content.res.Configuration); method public static float getFloat(android.content.ContentResolver, java.lang.String, float); method public static float getFloat(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException; @@ -28534,14 +28550,13 @@ package android.service.carrier { package android.service.chooser { public final class ChooserTarget implements android.os.Parcelable { - ctor public ChooserTarget(java.lang.CharSequence, android.graphics.drawable.Icon, float, android.app.PendingIntent); - ctor public ChooserTarget(java.lang.CharSequence, android.graphics.drawable.Icon, float, android.content.IntentSender); + ctor public ChooserTarget(java.lang.CharSequence, android.graphics.drawable.Icon, float, android.content.ComponentName, android.os.Bundle); method public int describeContents(); + method public android.content.ComponentName getComponentName(); method public android.graphics.drawable.Icon getIcon(); - method public android.content.IntentSender getIntentSender(); + method public android.os.Bundle getIntentExtras(); method public float getScore(); method public java.lang.CharSequence getTitle(); - method public boolean sendIntent(android.content.Context, android.content.Intent); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.service.chooser.ChooserTarget> CREATOR; } @@ -28801,10 +28816,12 @@ package android.service.voice { ctor public VoiceInteractionSession(android.content.Context); ctor public VoiceInteractionSession(android.content.Context, android.os.Handler); method public void closeSystemDialogs(); + method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]); method public void finish(); method public android.content.Context getContext(); method public int getDisabledShowContext(); method public android.view.LayoutInflater getLayoutInflater(); + method public int getUserDisabledShowContext(); method public android.app.Dialog getWindow(); method public void hide(); method public void onAssistStructureFailure(java.lang.Throwable); @@ -28824,6 +28841,7 @@ package android.service.voice { method public boolean onKeyLongPress(int, android.view.KeyEvent); method public boolean onKeyMultiple(int, int, android.view.KeyEvent); method public boolean onKeyUp(int, android.view.KeyEvent); + method public void onLockscreenShown(); method public void onLowMemory(); method public void onRequestAbortVoice(android.service.voice.VoiceInteractionSession.AbortVoiceRequest); method public void onRequestCommand(android.service.voice.VoiceInteractionSession.CommandRequest); @@ -28840,6 +28858,7 @@ package android.service.voice { method public void setTheme(int); method public void show(android.os.Bundle, int); method public void startVoiceActivity(android.content.Intent); + field public static final int SHOW_SOURCE_APPLICATION = 8; // 0x8 field public static final int SHOW_SOURCE_ASSIST_GESTURE = 4; // 0x4 field public static final int SHOW_WITH_ASSIST = 1; // 0x1 field public static final int SHOW_WITH_SCREENSHOT = 2; // 0x2 @@ -28892,6 +28911,7 @@ package android.service.voice { method public java.lang.String getCallingPackage(); method public int getCallingUid(); method public android.os.Bundle getExtras(); + method public boolean isActive(); } public abstract class VoiceInteractionSessionService extends android.app.Service { @@ -30103,6 +30123,9 @@ package android.telecom { field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800 field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2 field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8 + field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT"; + field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS"; + field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER"; field public static final int STATE_ACTIVE = 4; // 0x4 field public static final int STATE_DIALING = 3; // 0x3 field public static final int STATE_DISCONNECTED = 6; // 0x6 @@ -30272,6 +30295,7 @@ package android.telecom { method public android.telecom.PhoneAccount.Builder toBuilder(); method public void writeToParcel(android.os.Parcel, int); field public static final int CAPABILITY_CALL_PROVIDER = 2; // 0x2 + field public static final int CAPABILITY_CALL_SUBJECT = 64; // 0x40 field public static final int CAPABILITY_CONNECTION_MANAGER = 1; // 0x1 field public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 16; // 0x10 field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4 @@ -30462,6 +30486,7 @@ package android.telecom { field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER"; field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE"; field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE"; + field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT"; field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME"; field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS"; field public static final java.lang.String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS"; diff --git a/api/removed.txt b/api/removed.txt index 6d88cb654a89..642d2a8ac19c 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -34,13 +34,6 @@ package android.media { package android.net { - public class ConnectivityManager { - method public deprecated boolean requestRouteToHost(int, int); - method public deprecated boolean requestRouteToHostAddress(int, java.net.InetAddress); - method public deprecated int startUsingNetworkFeature(int, java.lang.String); - method public deprecated int stopUsingNetworkFeature(int, java.lang.String); - } - public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory { method public static deprecated org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache); } diff --git a/api/system-current.txt b/api/system-current.txt index cbb1bb26dc06..a784378e5f5f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -95,6 +95,7 @@ package android { field public static final java.lang.String FORCE_BACK = "android.permission.FORCE_BACK"; 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_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED"; 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"; @@ -104,6 +105,7 @@ package android { field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST"; field public static final java.lang.String HDMI_CEC = "android.permission.HDMI_CEC"; field public static final java.lang.String INJECT_EVENTS = "android.permission.INJECT_EVENTS"; + field public static final java.lang.String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS"; 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"; @@ -139,6 +141,7 @@ package android { field public static final java.lang.String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG"; field public static final java.lang.String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS"; field public static final java.lang.String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT"; + field public static final java.lang.String PEERS_MAC_ADDRESS = "android.permission.PEERS_MAC_ADDRESS"; field public static final java.lang.String PERFORM_CDMA_PROVISIONING = "android.permission.PERFORM_CDMA_PROVISIONING"; field public static final java.lang.String PERFORM_SIM_ACTIVATION = "android.permission.PERFORM_SIM_ACTIVATION"; field public static final deprecated java.lang.String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY"; @@ -181,6 +184,7 @@ package android { field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES"; field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES"; field public static final java.lang.String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT"; + field public static final java.lang.String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS"; field public static final java.lang.String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS"; 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"; @@ -1902,6 +1906,7 @@ package android { field public static final int defaultVoiceMailAlphaTag = 17039364; // 0x1040004 field public static final int dialog_alert_title = 17039380; // 0x1040014 field public static final int emptyPhoneNumber = 17039366; // 0x1040006 + field public static final int fingerprint_icon_content_description = 17039384; // 0x1040018 field public static final int httpErrorBadUrl = 17039367; // 0x1040007 field public static final int httpErrorUnsupportedScheme = 17039368; // 0x1040008 field public static final int no = 17039369; // 0x1040009 @@ -3439,6 +3444,7 @@ package android.app { method public boolean isImmersive(); method public boolean isTaskRoot(); method public boolean isVoiceInteraction(); + method public boolean isVoiceInteractionRoot(); method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String); method public boolean moveTaskToBack(boolean); method public boolean navigateUpTo(android.content.Intent); @@ -3567,6 +3573,7 @@ package android.app { method public final void setVolumeControlStream(int); method public boolean shouldShowRequestPermissionRationale(java.lang.String); method public boolean shouldUpRecreateTask(android.content.Intent); + method public boolean showAssist(android.os.Bundle); method public final deprecated void showDialog(int); method public final deprecated boolean showDialog(int, android.os.Bundle); method public void showLockTaskEscapeMessage(); @@ -3973,12 +3980,14 @@ package android.app { field public static final java.lang.String OPSTR_RECEIVE_WAP_PUSH = "android:receive_wap_push"; field public static final java.lang.String OPSTR_RECORD_AUDIO = "android:record_audio"; field public static final java.lang.String OPSTR_SEND_SMS = "android:send_sms"; + field public static final java.lang.String OPSTR_SYSTEM_ALERT_WINDOW = "android:system_alert_window"; field public static final java.lang.String OPSTR_USE_FINGERPRINT = "android:use_fingerprint"; field public static final java.lang.String OPSTR_USE_SIP = "android:use_sip"; 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"; + field public static final java.lang.String OPSTR_WRITE_SETTINGS = "android:write_settings"; } public static abstract interface AppOpsManager.OnOpChangedListener { @@ -4888,9 +4897,9 @@ package android.app { field public int flags; field public android.app.PendingIntent fullScreenIntent; field public android.widget.RemoteViews headsUpContentView; - field public int icon; + field public deprecated int icon; field public int iconLevel; - field public android.graphics.Bitmap largeIcon; + field public deprecated android.graphics.Bitmap largeIcon; field public int ledARGB; field public int ledOffMS; field public int ledOnMS; @@ -4906,20 +4915,22 @@ package android.app { } public static class Notification.Action implements android.os.Parcelable { - ctor public Notification.Action(int, java.lang.CharSequence, android.app.PendingIntent); + ctor public deprecated Notification.Action(int, java.lang.CharSequence, android.app.PendingIntent); method public android.app.Notification.Action clone(); method public int describeContents(); method public android.os.Bundle getExtras(); + method public android.graphics.drawable.Icon getIcon(); method public android.app.RemoteInput[] getRemoteInputs(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.Notification.Action> CREATOR; field public android.app.PendingIntent actionIntent; - field public int icon; + field public deprecated int icon; field public java.lang.CharSequence title; } public static final class Notification.Action.Builder { - ctor public Notification.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent); + ctor public deprecated Notification.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent); + ctor public Notification.Action.Builder(android.graphics.drawable.Icon, java.lang.CharSequence, android.app.PendingIntent); ctor public Notification.Action.Builder(android.app.Notification.Action); method public android.app.Notification.Action.Builder addExtras(android.os.Bundle); method public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput); @@ -4967,7 +4978,7 @@ package android.app { public static class Notification.Builder { ctor public Notification.Builder(android.content.Context); - method public android.app.Notification.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent); + method public deprecated android.app.Notification.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent); method public android.app.Notification.Builder addAction(android.app.Notification.Action); method public android.app.Notification.Builder addExtras(android.os.Bundle); method public android.app.Notification.Builder addPerson(java.lang.String); @@ -5820,6 +5831,7 @@ package android.app.admin { method public void uninstallCaCert(android.content.ComponentName, byte[]); method public void wipeData(int); field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN"; + field public static final java.lang.String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED"; field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED"; field public static final java.lang.String ACTION_PROVISION_MANAGED_DEVICE = "android.app.action.PROVISION_MANAGED_DEVICE"; field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE"; @@ -9436,6 +9448,7 @@ package android.content.pm { method public void setAppIcon(android.graphics.Bitmap); method public void setAppLabel(java.lang.CharSequence); method public void setAppPackageName(java.lang.String); + method public void setGrantedRuntimePermissions(java.lang.String[]); method public void setInstallLocation(int); method public void setOriginatingUri(android.net.Uri); method public void setReferrerUri(android.net.Uri); @@ -9599,6 +9612,7 @@ package android.content.pm { field public static final java.lang.String FEATURE_FAKETOUCH = "android.hardware.faketouch"; field public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT = "android.hardware.faketouch.multitouch.distinct"; field public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = "android.hardware.faketouch.multitouch.jazzhand"; + field public static final java.lang.String FEATURE_FINGERPRINT = "android.hardware.fingerprint"; field public static final java.lang.String FEATURE_GAMEPAD = "android.hardware.gamepad"; field public static final java.lang.String FEATURE_HIFI_SENSORS = "android.hardware.sensor.hifi_sensors"; field public static final java.lang.String FEATURE_HOME_SCREEN = "android.software.home_screen"; @@ -9775,6 +9789,7 @@ package android.content.pm { method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager); field public static final android.os.Parcelable.Creator<android.content.pm.PermissionInfo> CREATOR; field public static final int FLAG_COSTS_MONEY = 1; // 0x1 + field public static final int FLAG_INSTALLED = 1073741824; // 0x40000000 field public static final int PROTECTION_DANGEROUS = 1; // 0x1 field public static final int PROTECTION_FLAG_APPOP = 64; // 0x40 field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20 @@ -19648,8 +19663,11 @@ package android.net { method public boolean requestBandwidthUpdate(android.net.Network); method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent); + method public deprecated boolean requestRouteToHost(int, int); method public deprecated void setNetworkPreference(int); method public static deprecated boolean setProcessDefaultNetwork(android.net.Network); + method public deprecated int startUsingNetworkFeature(int, java.lang.String); + method public deprecated int stopUsingNetworkFeature(int, java.lang.String); method public void unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback); method public void unregisterNetworkCallback(android.app.PendingIntent); field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED"; @@ -24633,7 +24651,7 @@ package android.os { 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 = 23; // 0x17 + field public static final int M = 23; // 0x17 } public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable { @@ -28447,6 +28465,7 @@ package android.provider { public final class Settings { ctor public Settings(); + method public static boolean canDrawOverlays(android.content.Context); field public static final java.lang.String ACTION_ACCESSIBILITY_SETTINGS = "android.settings.ACCESSIBILITY_SETTINGS"; field public static final java.lang.String ACTION_ADD_ACCOUNT = "android.settings.ADD_ACCOUNT_SETTINGS"; field public static final java.lang.String ACTION_AIRPLANE_MODE_SETTINGS = "android.settings.AIRPLANE_MODE_SETTINGS"; @@ -28620,7 +28639,7 @@ package android.provider { field public static final deprecated java.lang.String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed"; field public static final deprecated java.lang.String LOCK_PATTERN_ENABLED = "lock_pattern_autolock"; field public static final deprecated java.lang.String LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED = "lock_pattern_tactile_feedback_enabled"; - field public static final java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern"; + field public static final deprecated java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern"; field public static final deprecated java.lang.String LOGGING_ID = "logging_id"; field public static final deprecated java.lang.String NETWORK_PREFERENCE = "network_preference"; field public static final java.lang.String PARENTAL_CONTROL_ENABLED = "parental_control_enabled"; @@ -28667,6 +28686,7 @@ package android.provider { public static final class Settings.System extends android.provider.Settings.NameValueTable { ctor public Settings.System(); + method public static boolean canWrite(android.content.Context); method public static void getConfiguration(android.content.ContentResolver, android.content.res.Configuration); method public static float getFloat(android.content.ContentResolver, java.lang.String, float); method public static float getFloat(android.content.ContentResolver, java.lang.String) throws android.provider.Settings.SettingNotFoundException; @@ -30591,14 +30611,13 @@ package android.service.carrier { package android.service.chooser { public final class ChooserTarget implements android.os.Parcelable { - ctor public ChooserTarget(java.lang.CharSequence, android.graphics.drawable.Icon, float, android.app.PendingIntent); - ctor public ChooserTarget(java.lang.CharSequence, android.graphics.drawable.Icon, float, android.content.IntentSender); + ctor public ChooserTarget(java.lang.CharSequence, android.graphics.drawable.Icon, float, android.content.ComponentName, android.os.Bundle); method public int describeContents(); + method public android.content.ComponentName getComponentName(); method public android.graphics.drawable.Icon getIcon(); - method public android.content.IntentSender getIntentSender(); + method public android.os.Bundle getIntentExtras(); method public float getScore(); method public java.lang.CharSequence getTitle(); - method public boolean sendIntent(android.content.Context, android.content.Intent); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.service.chooser.ChooserTarget> CREATOR; } @@ -30950,10 +30969,12 @@ package android.service.voice { ctor public VoiceInteractionSession(android.content.Context); ctor public VoiceInteractionSession(android.content.Context, android.os.Handler); method public void closeSystemDialogs(); + method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]); method public void finish(); method public android.content.Context getContext(); method public int getDisabledShowContext(); method public android.view.LayoutInflater getLayoutInflater(); + method public int getUserDisabledShowContext(); method public android.app.Dialog getWindow(); method public void hide(); method public void onAssistStructureFailure(java.lang.Throwable); @@ -30973,6 +30994,7 @@ package android.service.voice { method public boolean onKeyLongPress(int, android.view.KeyEvent); method public boolean onKeyMultiple(int, int, android.view.KeyEvent); method public boolean onKeyUp(int, android.view.KeyEvent); + method public void onLockscreenShown(); method public void onLowMemory(); method public void onRequestAbortVoice(android.service.voice.VoiceInteractionSession.AbortVoiceRequest); method public void onRequestCommand(android.service.voice.VoiceInteractionSession.CommandRequest); @@ -30989,6 +31011,7 @@ package android.service.voice { method public void setTheme(int); method public void show(android.os.Bundle, int); method public void startVoiceActivity(android.content.Intent); + field public static final int SHOW_SOURCE_APPLICATION = 8; // 0x8 field public static final int SHOW_SOURCE_ASSIST_GESTURE = 4; // 0x4 field public static final int SHOW_WITH_ASSIST = 1; // 0x1 field public static final int SHOW_WITH_SCREENSHOT = 2; // 0x2 @@ -31041,6 +31064,7 @@ package android.service.voice { method public java.lang.String getCallingPackage(); method public int getCallingUid(); method public android.os.Bundle getExtras(); + method public boolean isActive(); } public abstract class VoiceInteractionSessionService extends android.app.Service { @@ -32284,6 +32308,9 @@ package android.telecom { field public static final int CAPABILITY_SUPPORTS_VT_REMOTE_TX = 2048; // 0x800 field public static final int CAPABILITY_SUPPORT_HOLD = 2; // 0x2 field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8 + field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT"; + field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS"; + field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER"; field public static final int STATE_ACTIVE = 4; // 0x4 field public static final int STATE_DIALING = 3; // 0x3 field public static final int STATE_DISCONNECTED = 6; // 0x6 @@ -32477,6 +32504,7 @@ package android.telecom { method public android.telecom.PhoneAccount.Builder toBuilder(); method public void writeToParcel(android.os.Parcel, int); field public static final int CAPABILITY_CALL_PROVIDER = 2; // 0x2 + field public static final int CAPABILITY_CALL_SUBJECT = 64; // 0x40 field public static final int CAPABILITY_CONNECTION_MANAGER = 1; // 0x1 field public static final int CAPABILITY_MULTI_USER = 32; // 0x20 field public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 16; // 0x10 @@ -32691,6 +32719,7 @@ package android.telecom { field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER"; field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE"; field public static final java.lang.String EXTRA_CALL_DISCONNECT_MESSAGE = "android.telecom.extra.CALL_DISCONNECT_MESSAGE"; + field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT"; field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME"; field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecom.extra.CONNECTION_SERVICE"; field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS"; diff --git a/api/system-removed.txt b/api/system-removed.txt index 6d88cb654a89..642d2a8ac19c 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -34,13 +34,6 @@ package android.media { package android.net { - public class ConnectivityManager { - method public deprecated boolean requestRouteToHost(int, int); - method public deprecated boolean requestRouteToHostAddress(int, java.net.InetAddress); - method public deprecated int startUsingNetworkFeature(int, java.lang.String); - method public deprecated int stopUsingNetworkFeature(int, java.lang.String); - } - public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory { method public static deprecated org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache); } diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 9f4bc52763be..96c0dbddee41 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -26,6 +26,7 @@ import android.app.IActivityController; import android.app.IActivityManager; import android.app.IInstrumentationWatcher; import android.app.Instrumentation; +import android.app.IStopUserCallback; import android.app.ProfilerInfo; import android.app.UiAutomationConnection; import android.app.usage.ConfigurationStats; @@ -133,7 +134,7 @@ public class Am extends BaseCommand { " am to-app-uri [INTENT]\n" + " am switch-user <USER_ID>\n" + " am start-user <USER_ID>\n" + - " am stop-user <USER_ID>\n" + + " am stop-user [-w] <USER_ID>\n" + " am stack start <DISPLAY_ID> <INTENT>\n" + " am stack movetask <TASK_ID> <STACK_ID> [true|false]\n" + " am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" + @@ -257,6 +258,7 @@ public class Am extends BaseCommand { "\n" + "am stop-user: stop execution of USER_ID, not allowing it to run any\n" + " code until a later explicit start or switch to it.\n" + + " -w: wait for stop-user to complete.\n" + "\n" + "am stack start: start a new activity on <DISPLAY_ID> using <INTENT>.\n" + "\n" + @@ -293,7 +295,7 @@ public class Am extends BaseCommand { "\n" + "am get-inactive: returns the inactive state of an app.\n" + "\n" + - " am send-trim-memory: Send a memory trim event to a <PROCESS>.\n" + + "am send-trim-memory: Send a memory trim event to a <PROCESS>.\n" + "\n" + "<INTENT> specifications include these flags and arguments:\n" + " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" + @@ -1303,9 +1305,45 @@ public class Am extends BaseCommand { } } + private static class StopUserCallback extends IStopUserCallback.Stub { + private boolean mFinished = false; + + public synchronized void waitForFinish() { + try { + while (!mFinished) wait(); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + } + + @Override + public synchronized void userStopped(int userId) { + mFinished = true; + notifyAll(); + } + + @Override + public synchronized void userStopAborted(int userId) { + mFinished = true; + notifyAll(); + } + } + private void runStopUser() throws Exception { - String user = nextArgRequired(); - int res = mAm.stopUser(Integer.parseInt(user), null); + boolean wait = false; + String opt = null; + while ((opt = nextOption()) != null) { + if ("-w".equals(opt)) { + wait = true; + } else { + System.err.println("Error: unknown option: " + opt); + return; + } + } + int user = Integer.parseInt(nextArgRequired()); + StopUserCallback callback = wait ? new StopUserCallback() : null; + + int res = mAm.stopUser(user, callback); if (res != ActivityManager.USER_OP_SUCCESS) { String txt = ""; switch (res) { @@ -1317,6 +1355,8 @@ public class Am extends BaseCommand { break; } System.err.println("Switch failed: " + res + txt); + } else if (callback != null) { + callback.waitForFinish(); } } diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index 2dcd9cbffaac..b39376c22be7 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -16,6 +16,11 @@ package com.android.commands.pm; +import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; +import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; +import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; +import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; + import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.IActivityManager; @@ -212,6 +217,14 @@ public final class Pm { return runSetPermissionEnforced(); } + if ("set-app-link".equals(op)) { + return runSetAppLink(); + } + + if ("get-app-link".equals(op)) { + return runGetAppLink(); + } + if ("set-install-location".equals(op)) { return runSetInstallLocation(); } @@ -827,6 +840,148 @@ public final class Pm { return Integer.toString(result); } + // pm set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined} + private int runSetAppLink() { + int userId = UserHandle.USER_OWNER; + + String opt; + while ((opt = nextOption()) != null) { + if (opt.equals("--user")) { + userId = Integer.parseInt(nextOptionData()); + if (userId < 0) { + System.err.println("Error: user must be >= 0"); + return 1; + } + } else { + System.err.println("Error: unknown option: " + opt); + showUsage(); + return 1; + } + } + + // Package name to act on; required + final String pkg = nextArg(); + if (pkg == null) { + System.err.println("Error: no package specified."); + showUsage(); + return 1; + } + + // State to apply; {always|ask|never|undefined}, required + final String modeString = nextArg(); + if (modeString == null) { + System.err.println("Error: no app link state specified."); + showUsage(); + return 1; + } + + final int newMode; + switch (modeString.toLowerCase()) { + case "undefined": + newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; + break; + + case "always": + newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; + break; + + case "ask": + newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; + break; + + case "never": + newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; + break; + + default: + System.err.println("Error: unknown app link state '" + modeString + "'"); + return 1; + } + + try { + final PackageInfo info = mPm.getPackageInfo(pkg, 0, userId); + if (info == null) { + System.err.println("Error: package " + pkg + " not found."); + return 1; + } + + if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) { + System.err.println("Error: package " + pkg + " does not handle web links."); + return 1; + } + + if (!mPm.updateIntentVerificationStatus(pkg, newMode, userId)) { + System.err.println("Error: unable to update app link status for " + pkg); + return 1; + } + } catch (Exception e) { + System.err.println(e.toString()); + System.err.println(PM_NOT_RUNNING_ERR); + return 1; + } + + return 0; + } + + // pm get-app-link [--user USER_ID] PACKAGE + private int runGetAppLink() { + int userId = UserHandle.USER_OWNER; + + String opt; + while ((opt = nextOption()) != null) { + if (opt.equals("--user")) { + userId = Integer.parseInt(nextOptionData()); + if (userId < 0) { + System.err.println("Error: user must be >= 0"); + return 1; + } + } else { + System.err.println("Error: unknown option: " + opt); + showUsage(); + return 1; + } + } + + // Package name to act on; required + final String pkg = nextArg(); + if (pkg == null) { + System.err.println("Error: no package specified."); + showUsage(); + return 1; + } + + try { + final PackageInfo info = mPm.getPackageInfo(pkg, 0, userId); + if (info == null) { + System.err.println("Error: package " + pkg + " not found."); + return 1; + } + + if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) { + System.err.println("Error: package " + pkg + " does not handle web links."); + return 1; + } + + System.out.println(linkStateToString(mPm.getIntentVerificationStatus(pkg, userId))); + } catch (Exception e) { + System.err.println(e.toString()); + System.err.println(PM_NOT_RUNNING_ERR); + return 1; + } + + return 0; + } + + private String linkStateToString(int state) { + switch (state) { + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined"; + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask"; + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always"; + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never"; + } + return "Unknown link state: " + state; + } + private int runSetInstallLocation() { int loc; @@ -1936,6 +2091,8 @@ public final class Pm { 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-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}"); + System.err.println(" pm get-app-link [--user USER_ID] PACKAGE"); 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]"); diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java index 0dad4dcec892..0a1ba4d19c5c 100644 --- a/cmds/sm/src/com/android/commands/sm/Sm.java +++ b/cmds/sm/src/com/android/commands/sm/Sm.java @@ -81,6 +81,8 @@ public final class Sm { runUnmount(); } else if ("format".equals(op)) { runFormat(); + } else if ("benchmark".equals(op)) { + runBenchmark(); } else if ("forget".equals(op)) { runForget(); } else { @@ -89,9 +91,12 @@ public final class Sm { } public void runListDisks() throws RemoteException { + final boolean onlyAdoptable = "adoptable".equals(nextArg()); final DiskInfo[] disks = mSm.getDisks(); for (DiskInfo disk : disks) { - System.out.println(disk.getId()); + if (!onlyAdoptable || disk.isAdoptable()) { + System.out.println(disk.getId()); + } } } @@ -161,6 +166,11 @@ public final class Sm { mSm.format(volId); } + public void runBenchmark() throws RemoteException { + final String volId = nextArg(); + mSm.benchmark(volId); + } + public void runForget() throws RemoteException{ final String fsUuid = nextArg(); if ("all".equals(fsUuid)) { @@ -180,7 +190,7 @@ public final class Sm { } private static int showUsage() { - System.err.println("usage: sm list-disks"); + System.err.println("usage: sm list-disks [adoptable]"); System.err.println(" sm list-volumes [public|private|emulated|all]"); System.err.println(" sm has-adoptable"); System.err.println(" sm get-primary-storage-uuid"); @@ -190,6 +200,7 @@ public final class Sm { System.err.println(" sm mount VOLUME"); System.err.println(" sm unmount VOLUME"); System.err.println(" sm format VOLUME"); + System.err.println(" sm benchmark VOLUME"); System.err.println(""); System.err.println(" sm forget [UUID|all]"); System.err.println(""); diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java index c7ab36cedfa8..b7c729b4834b 100644 --- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java +++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java @@ -18,6 +18,7 @@ package com.android.commands.telecom; import android.content.ComponentName; import android.content.Context; +import android.net.Uri; import android.os.RemoteException; import android.os.ServiceManager; import android.telecom.PhoneAccount; @@ -43,6 +44,7 @@ public final class Telecom extends BaseCommand { private static final String COMMAND_SET_PHONE_ACCOUNT_ENABLED = "set-phone-account-enabled"; private static final String COMMAND_SET_PHONE_ACCOUNT_DISABLED = "set-phone-account-disabled"; private static final String COMMAND_REGISTER_PHONE_ACCOUNT = "register-phone-account"; + private static final String COMMAND_REGISTER_SIM_PHONE_ACCOUNT = "register-sim-phone-account"; private static final String COMMAND_UNREGISTER_PHONE_ACCOUNT = "unregister-phone-account"; private static final String COMMAND_SET_DEFAULT_DIALER = "set-default-dialer"; private static final String COMMAND_GET_DEFAULT_DIALER = "get-default-dialer"; @@ -59,6 +61,7 @@ public final class Telecom extends BaseCommand { "usage: telecom set-phone-account-enabled <COMPONENT> <ID>\n" + "usage: telecom set-phone-account-disabled <COMPONENT> <ID>\n" + "usage: telecom register-phone-account <COMPONENT> <ID> <LABEL>\n" + + "usage: telecom register-sim-phone-account <COMPONENT> <ID> <LABEL> <ADDRESS>\n" + "usage: telecom unregister-phone-account <COMPONENT> <ID>\n" + "usage: telecom set-default-dialer <PACKAGE>\n" + "usage: telecom get-default-dialer\n" + @@ -98,6 +101,9 @@ public final class Telecom extends BaseCommand { case COMMAND_REGISTER_PHONE_ACCOUNT: runRegisterPhoneAccount(); break; + case COMMAND_REGISTER_SIM_PHONE_ACCOUNT: + runRegisterSimPhoneAccount(); + break; case COMMAND_UNREGISTER_PHONE_ACCOUNT: runUnregisterPhoneAccount(); break; @@ -134,6 +140,24 @@ public final class Telecom extends BaseCommand { System.out.println("Success - " + handle + " registered."); } + private void runRegisterSimPhoneAccount() throws RemoteException { + final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); + final String label = nextArgRequired(); + final String address = nextArgRequired(); + PhoneAccount account = PhoneAccount.builder( + handle, label) + .setAddress(Uri.parse(address)) + .setSubscriptionAddress(Uri.parse(address)) + .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | + PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) + .setShortDescription(label) + .addSupportedUriScheme(PhoneAccount.SCHEME_TEL) + .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL) + .build(); + mTelecomService.registerPhoneAccount(account); + System.out.println("Success - " + handle + " registered."); + } + private void runUnregisterPhoneAccount() throws RemoteException { final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); mTelecomService.unregisterPhoneAccount(handle); diff --git a/cmds/wm/src/com/android/commands/wm/Wm.java b/cmds/wm/src/com/android/commands/wm/Wm.java index fb050e545931..f7f7c887aeb0 100644 --- a/cmds/wm/src/com/android/commands/wm/Wm.java +++ b/cmds/wm/src/com/android/commands/wm/Wm.java @@ -65,7 +65,10 @@ public class Wm extends BaseCommand { "\n" + "wm scaling: set display scaling mode.\n" + "\n" + - "wm screen-capture: enable/disable screen capture.\n" + "wm screen-capture: enable/disable screen capture.\n" + + "\n" + + "wm dismiss-keyguard: dismiss the keyguard, prompting the user for auth if " + + "necessary.\n" ); } @@ -90,6 +93,8 @@ public class Wm extends BaseCommand { runDisplayScaling(); } else if (op.equals("screen-capture")) { runSetScreenCapture(); + } else if (op.equals("dismiss-keyguard")) { + runDismissKeyguard(); } else { showError("Error: unknown command '" + op + "'"); return; @@ -240,6 +245,10 @@ public class Wm extends BaseCommand { } } + private void runDismissKeyguard() throws Exception { + mWm.dismissKeyguard(); + } + private int parseDimension(String s) throws NumberFormatException { if (s.endsWith("px")) { return Integer.parseInt(s.substring(0, s.length() - 2)); diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index dd3d3a8307f2..9394d2c05a2e 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -321,6 +321,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that owns the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * AUTHENTICATE_ACCOUNTS permission is needed for those platforms. See docs for + * this function in API level 22. + * * @param account The account to query for a password. Must not be {@code null}. * @return The account's password, null if none or if the account doesn't exist */ @@ -345,6 +349,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that owns the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * AUTHENTICATE_ACCOUNTS permission is needed for those platforms. See docs + * for this function in API level 22. + * * @param account The account to query for user data * @return The user data, null if the account or key doesn't exist */ @@ -493,6 +501,10 @@ public class AccountManager { * {@link android.Manifest.permission#GET_ACCOUNTS} or share a uid with the * authenticator that owns the account type. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * GET_ACCOUNTS permission is needed for those platforms, irrespective of uid + * or signature match. See docs for this function in API level 22. + * * @param type The type of accounts to return, null to retrieve all accounts * @return An array of {@link Account}, one per matching account. Empty * (never null) if no accounts of the specified type have been added. @@ -623,6 +635,11 @@ public class AccountManager { * @param type The type of accounts to return, must not be null * @param features An array of the account features to require, * may be null or empty + * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * GET_ACCOUNTS permission is needed for those platforms, irrespective of uid + * or signature match. See docs for this function in API level 22. + * * @param callback Callback to invoke when the request completes, * null for no callback * @param handler {@link Handler} identifying the callback thread, @@ -668,6 +685,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that owns the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * AUTHENTICATE_ACCOUNTS permission is needed for those platforms. See docs + * for this function in API level 22. + * * @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 @@ -720,6 +741,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that manages the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator + * is needed for those platforms. See docs for this function in API level 22. + * * @param account The {@link Account} to rename * @param newName String name to be associated with the account. * @param callback Callback to invoke when the request completes, null for @@ -784,6 +809,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that manages the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for + * this function in API level 22. + * * @param account The {@link Account} to remove * @param callback Callback to invoke when the request completes, * null for no callback @@ -826,6 +855,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that manages the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for + * this function in API level 22. + * * @param account The {@link Account} to remove * @param activity The {@link Activity} context to use for launching a new * authenticator-defined sub-Activity to prompt the user to delete an @@ -919,6 +952,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that manages the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator + * is needed for those platforms. See docs for this function in API level 22. + * * @param account The {@link Account} to delete. * @return True if the account was successfully deleted, false if the * account did not exist, the account is null, or another error @@ -943,6 +980,10 @@ public class AccountManager { * * <p>It is safe to call this method from the main thread. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * MANAGE_ACCOUNTS or USE_CREDENTIALS permission is needed for those + * platforms. See docs for this function in API level 22. + * * @param accountType The account type of the auth token to invalidate, must not be null * @param authToken The auth token to invalidate, may be null */ @@ -969,6 +1010,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that manages the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator + * is needed for those platforms. See docs for this function in API level 22. + * * @param account The account for which an auth token is to be fetched. Cannot be {@code null}. * @param authTokenType The type of auth token to fetch. Cannot be {@code null}. * @return The cached auth token for this account and type, or null if @@ -998,6 +1043,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that manages the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator + * is needed for those platforms. See docs for this function in API level 22. + * * @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 @@ -1025,6 +1074,10 @@ public class AccountManager { * * <p>It is safe to call this method from the main thread. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for + * this function in API level 22. + * * @param account The account whose password to clear */ public void clearPassword(final Account account) { @@ -1047,6 +1100,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that manages the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator + * is needed for those platforms. See docs for this function in API level 22. + * * @param account Account whose user data is to be set. Must not be {@code null}. * @param key String user data key to set. Must not be null * @param value String value to set, {@code null} to clear this user data key @@ -1073,6 +1130,10 @@ public class AccountManager { * <p>This method requires the caller to have a signature match with the * authenticator that manages the specified account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * AUTHENTICATE_ACCOUNTS permission and same UID as account's authenticator + * is needed for those platforms. See docs for this function in API level 22. + * * @param account The account to set an auth token for * @param authTokenType The type of the auth token, see {#getAuthToken} * @param authToken The auth token to add to the cache @@ -1095,6 +1156,10 @@ public class AccountManager { * <p>This method may block while a network request completes, and must * never be made from the main thread. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * USE_CREDENTIALS permission is needed for those platforms. See docs for + * this function in API level 22. + * * @param account The account to fetch an auth token for * @param authTokenType The auth token type, see {@link #getAuthToken getAuthToken()} * @param notifyAuthFailure If true, display a notification and return null @@ -1143,6 +1208,10 @@ public class AccountManager { * access different functionality -- for example, Google uses different auth * tokens to access Gmail and Google Calendar for the same account. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * USE_CREDENTIALS permission is needed for those platforms. See docs for + * this function in API level 22. + * * <p>This method may be called from any thread, but the returned * {@link AccountManagerFuture} must not be used on the main thread. * @@ -1306,6 +1375,10 @@ public class AccountManager { * <p>This method may be called from any thread, but the returned * {@link AccountManagerFuture} must not be used on the main thread. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * USE_CREDENTIALS permission is needed for those platforms. See docs for + * this function in API level 22. + * * @param account The account to fetch an auth token for * @param authTokenType The auth token type, an authenticator-dependent * string token, must not be null @@ -1369,6 +1442,10 @@ public class AccountManager { * * <p>This method may be called from any thread, but the returned * {@link AccountManagerFuture} must not be used on the main thread. + * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for + * this function in API level 22. * * @param accountType The type of account to add; must not be null * @param authTokenType The type of auth token (see {@link #getAuthToken}) @@ -1551,6 +1628,10 @@ public class AccountManager { * <p>This method may be called from any thread, but the returned * {@link AccountManagerFuture} must not be used on the main thread. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * MANAGE_ACCOUNTS permission is needed for those platforms. See docs + * for this function in API level 22. + * * @param account The account to confirm password knowledge for * @param options Authenticator-specific options for the request; * if the {@link #KEY_PASSWORD} string field is present, the @@ -1629,6 +1710,10 @@ public class AccountManager { * <p>This method may be called from any thread, but the returned * {@link AccountManagerFuture} must not be used on the main thread. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for + * this function in API level 22. + * * @param account The account to update credentials for * @param authTokenType The credentials entered must allow an auth token * of this type to be created (but no actual auth token is returned); @@ -1689,6 +1774,10 @@ public class AccountManager { * <p>This method requires the caller to have the same signature as the * authenticator associated with the specified account type. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * MANAGE_ACCOUNTS permission is needed for those platforms. See docs + * for this function in API level 22. + * * @param accountType The account type associated with the authenticator * to adjust * @param activity The {@link Activity} context to use for launching a new @@ -2209,6 +2298,10 @@ public class AccountManager { * <p>This method may be called from any thread, but the returned * {@link AccountManagerFuture} must not be used on the main thread. * + * <p><b>NOTE:</b> If targeting your app to work on API level 22 and before, + * MANAGE_ACCOUNTS permission is needed for those platforms. See docs for + * this function in API level 22. + * * @param accountType The account type required * (see {@link #getAccountsByType}), must not be null * @param authTokenType The desired auth token type diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 7572799108a1..3c8af0d5444a 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1229,6 +1229,22 @@ public class Activity extends ContextThemeWrapper } /** + * Like {@link #isVoiceInteraction}, but only returns true if this is also the root + * of a voice interaction. That is, returns true if this activity was directly + * started by the voice interaction service as the initiation of a voice interaction. + * Otherwise, for example if it was started by another activity while under voice + * interaction, returns false. + */ + public boolean isVoiceInteractionRoot() { + try { + return mVoiceInteractor != null + && ActivityManagerNative.getDefault().isRootVoiceInteraction(mToken); + } catch (RemoteException e) { + } + return false; + } + + /** * Retrieve the active {@link VoiceInteractor} that the user is going through to * interact with this activity. */ @@ -1545,6 +1561,24 @@ public class Activity extends ContextThemeWrapper } /** + * Ask to have the current assistant shown to the user. This only works if the calling + * activity is the current foreground activity. It is the same as calling + * {@link android.service.voice.VoiceInteractionService#showSession + * VoiceInteractionService.showSession} and requesting all of the possible context. + * The receiver will always see + * {@link android.service.voice.VoiceInteractionSession#SHOW_SOURCE_APPLICATION} set. + * @return Returns true if the assistant was successfully invoked, else false. For example + * false will be returned if the caller is not the current top activity. + */ + public boolean showAssist(Bundle args) { + try { + return ActivityManagerNative.getDefault().showAssistFromActivity(mToken, args); + } catch (RemoteException e) { + } + return false; + } + + /** * Called when you are no longer visible to the user. You will next * receive either {@link #onRestart}, {@link #onDestroy}, or nothing, * depending on later user activity. @@ -1846,7 +1880,10 @@ public class Activity extends ContextThemeWrapper nci.children = children; nci.fragments = fragments; nci.loaders = loaders; - nci.voiceInteractor = mVoiceInteractor; + if (mVoiceInteractor != null) { + mVoiceInteractor.retainInstance(); + nci.voiceInteractor = mVoiceInteractor; + } return nci; } @@ -3771,6 +3808,11 @@ public class Activity extends ContextThemeWrapper /** * Callback for the result from requesting permissions. This method * is invoked for every call on {@link #requestPermissions(String[], int)}. + * <p> + * <strong>Note:</strong> It is possible that the permissions request interaction + * with the user is interrupted. In this case you will receive empty permissions + * and results arrays which should be treated as a cancellation. + * </p> * * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}. * @param permissions The requested permissions. Never null. @@ -3977,16 +4019,24 @@ public class Activity extends ContextThemeWrapper * as intermediaries that dispatch their intent to the target the user selects -- to * do this, they must perform all security checks including permission grants as if * their launch had come from the original activity. + * @param intent The Intent to start. + * @param options ActivityOptions or null. + * @param ignoreTargetSecurity If true, the activity manager will not check whether the + * caller it is doing the start is, is actually allowed to start the target activity. + * If you set this to true, you must set an explicit component in the Intent and do any + * appropriate security checks yourself. + * @param userId The user the new activity should run as. * @hide */ - public void startActivityAsCaller(Intent intent, @Nullable Bundle options, int userId) { + public void startActivityAsCaller(Intent intent, @Nullable Bundle options, + boolean ignoreTargetSecurity, int userId) { if (mParent != null) { throw new RuntimeException("Can't be called from a child"); } Instrumentation.ActivityResult ar = mInstrumentation.execStartActivityAsCaller( this, mMainThread.getApplicationThread(), mToken, this, - intent, -1, options, userId); + intent, -1, options, ignoreTargetSecurity, userId); if (ar != null) { mMainThread.sendActivityResult( mToken, mEmbeddedID, -1, ar.getResultCode(), @@ -5516,6 +5566,9 @@ public class Activity extends ContextThemeWrapper mFragments.dumpLoaders(innerPrefix, fd, writer, args); mFragments.getFragmentManager().dump(innerPrefix, fd, writer, args); + if (mVoiceInteractor != null) { + mVoiceInteractor.dump(innerPrefix, fd, writer, args); + } if (getWindow() != null && getWindow().peekDecorView() != null && diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 9ca206a42c00..55b2fd92c824 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -2807,7 +2807,7 @@ public class ActivityManager { /** * Request that the system start watching for the calling process to exceed a pss - * size as given here. Once called, the system will look for any occassions where it + * size as given here. Once called, the system will look for any occasions where it * sees the associated process with a larger pss size and, when this happens, automatically * pull a heap dump from it and allow the user to share the data. Note that this request * continues running even if the process is killed and restarted. To remove the watch, diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index fc408a8158b6..e144c297f50e 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -206,9 +206,11 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM ? ProfilerInfo.CREATOR.createFromParcel(data) : null; Bundle options = data.readInt() != 0 ? Bundle.CREATOR.createFromParcel(data) : null; + boolean ignoreTargetSecurity = data.readInt() != 0; int userId = data.readInt(); int result = startActivityAsCaller(app, callingPackage, intent, resolvedType, - resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId); + resultTo, resultWho, requestCode, startFlags, profilerInfo, options, + ignoreTargetSecurity, userId); reply.writeNoException(); reply.writeInt(result); return true; @@ -2191,8 +2193,10 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM data.enforceInterface(IActivityManager.descriptor); int requestType = data.readInt(); IResultReceiver receiver = IResultReceiver.Stub.asInterface(data.readStrongBinder()); - requestAssistContextExtras(requestType, receiver); + IBinder activityToken = data.readStrongBinder(); + boolean res = requestAssistContextExtras(requestType, receiver, activityToken); reply.writeNoException(); + reply.writeInt(res ? 1 : 0); return true; } @@ -2223,7 +2227,17 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM case IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); - boolean res = isScreenCaptureAllowedOnCurrentActivity(); + boolean res = isAssistDataAllowedOnCurrentActivity(); + reply.writeNoException(); + reply.writeInt(res ? 1 : 0); + return true; + } + + case SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder token = data.readStrongBinder(); + Bundle args = data.readBundle(); + boolean res = showAssistFromActivity(token, args); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; @@ -2568,6 +2582,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeInt(res ? 1 : 0); return true; } + + case IS_ROOT_VOICE_INTERACTION_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder token = data.readStrongBinder(); + boolean res = isRootVoiceInteraction(token); + reply.writeNoException(); + reply.writeInt(res ? 1 : 0); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -2675,7 +2698,8 @@ class ActivityManagerProxy implements IActivityManager } public int startActivityAsCaller(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, - int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException { + int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity, + int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); @@ -2699,6 +2723,7 @@ class ActivityManagerProxy implements IActivityManager } else { data.writeInt(0); } + data.writeInt(ignoreTargetSecurity ? 1 : 0); data.writeInt(userId); mRemote.transact(START_ACTIVITY_AS_CALLER_TRANSACTION, data, reply, 0); reply.readException(); @@ -5373,17 +5398,20 @@ class ActivityManagerProxy implements IActivityManager return res; } - public void requestAssistContextExtras(int requestType, IResultReceiver receiver) - throws RemoteException { + public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver, + IBinder activityToken) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeInt(requestType); data.writeStrongBinder(receiver.asBinder()); + data.writeStrongBinder(activityToken); mRemote.transact(REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0); reply.readException(); + boolean res = reply.readInt() != 0; data.recycle(); reply.recycle(); + return res; } public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure, @@ -5425,7 +5453,7 @@ class ActivityManagerProxy implements IActivityManager return res; } - public boolean isScreenCaptureAllowedOnCurrentActivity() throws RemoteException { + public boolean isAssistDataAllowedOnCurrentActivity() throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); @@ -5437,6 +5465,20 @@ class ActivityManagerProxy implements IActivityManager return res; } + public boolean showAssistFromActivity(IBinder token, Bundle args) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(token); + data.writeBundle(args); + mRemote.transact(SHOW_ASSIST_FROM_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(); @@ -5929,5 +5971,19 @@ class ActivityManagerProxy implements IActivityManager return res != 0; } + @Override + public boolean isRootVoiceInteraction(IBinder token) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(token); + mRemote.transact(IS_ROOT_VOICE_INTERACTION_TRANSACTION, data, reply, 0); + reply.readException(); + int res = reply.readInt(); + data.recycle(); + reply.recycle(); + return res != 0; + } + private IBinder mRemote; } diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index dc83a011e596..330d730b89cb 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -720,7 +720,7 @@ public class AlarmManager { } // Reject this timezone if it isn't an Olson zone we recognize. - if (mTargetSdkVersion >= Build.VERSION_CODES.MNC) { + if (mTargetSdkVersion >= Build.VERSION_CODES.M) { boolean hasTimeZone = false; try { hasTimeZone = ZoneInfoDB.getInstance().hasTimeZone(timeZone); diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 08e1696759cc..42ac67c7ae44 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -325,6 +325,12 @@ public class AppOpsManager { /** Write external storage. */ public static final String OPSTR_WRITE_EXTERNAL_STORAGE = "android:write_external_storage"; + /** Required to draw on top of other apps. */ + public static final String OPSTR_SYSTEM_ALERT_WINDOW + = "android:system_alert_window"; + /** Required to write/modify/update system settingss. */ + public static final String OPSTR_WRITE_SETTINGS + = "android:write_settings"; /** * This maps each operation to the operation that serves as the @@ -427,8 +433,8 @@ public class AppOpsManager { OPSTR_SEND_SMS, null, null, - null, - null, + OPSTR_WRITE_SETTINGS, + OPSTR_SYSTEM_ALERT_WINDOW, null, OPSTR_CAMERA, OPSTR_RECORD_AUDIO, @@ -772,7 +778,7 @@ public class AppOpsManager { AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ALLOWED, + AppOpsManager.MODE_DEFAULT, // OP_WRITE_SETTINGS AppOpsManager.MODE_DEFAULT, // OP_SYSTEM_ALERT_WINDOW AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, @@ -1228,6 +1234,14 @@ public class AppOpsManager { } /** @hide */ + public void setUidMode(int code, int uid, int mode) { + try { + mService.setUidMode(code, uid, mode); + } catch (RemoteException e) { + } + } + + /** @hide */ public void setMode(int code, int uid, String packageName, int mode) { try { mService.setMode(code, uid, packageName, mode); diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 1fb0b2af3366..0adce5dc193d 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -110,6 +110,9 @@ final class ApplicationPackageManager extends PackageManager { @GuardedBy("mDelegates") private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>(); + @GuardedBy("mLock") + private String mPermissionsControllerPackageName; + UserManager getUserManager() { synchronized (mLock) { if (mUserManager == null) { @@ -429,6 +432,23 @@ final class ApplicationPackageManager extends PackageManager { } } + /** + * @hide + */ + @Override + public String getPermissionControllerPackageName() { + synchronized (mLock) { + if (mPermissionsControllerPackageName == null) { + try { + mPermissionsControllerPackageName = mPM.getPermissionControllerPackageName(); + } catch (RemoteException e) { + throw new RuntimeException("Package manager has died", e); + } + } + return mPermissionsControllerPackageName; + } + } + @Override public boolean addPermission(PermissionInfo info) { try { @@ -757,7 +777,9 @@ final class ApplicationPackageManager extends PackageManager { public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) { try { - return mPM.queryContentProviders(processName, uid, flags); + ParceledListSlice<ProviderInfo> slice + = mPM.queryContentProviders(processName, uid, flags); + return slice != null ? slice.getList() : null; } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java index 13030ca285b5..84cbea9b24bc 100644 --- a/core/java/android/app/BackStackRecord.java +++ b/core/java/android/app/BackStackRecord.java @@ -1094,8 +1094,10 @@ final class BackStackRecord extends FragmentTransaction implements container.getViewTreeObserver().removeOnPreDrawListener(this); // Don't include any newly-hidden fragments in the transition. - excludeHiddenFragments(hiddenFragmentViews, inFragment.mContainerId, - overallTransition); + if (inFragment != null) { + excludeHiddenFragments(hiddenFragmentViews, inFragment.mContainerId, + overallTransition); + } ArrayMap<String, View> namedViews = null; if (sharedElementTransition != null) { @@ -1692,7 +1694,7 @@ final class BackStackRecord extends FragmentTransaction implements private static void setNameOverrides(TransitionState state, ArrayList<String> sourceNames, ArrayList<String> targetNames) { - if (sourceNames != null) { + if (sourceNames != null && targetNames != null) { for (int i = 0; i < sourceNames.size(); i++) { String source = sourceNames.get(i); String target = targetNames.get(i); @@ -1703,7 +1705,9 @@ final class BackStackRecord extends FragmentTransaction implements private void setBackNameOverrides(TransitionState state, ArrayMap<String, View> namedViews, boolean isEnd) { - int count = mSharedElementTargetNames == null ? 0 : mSharedElementTargetNames.size(); + int targetCount = mSharedElementTargetNames == null ? 0 : mSharedElementTargetNames.size(); + int sourceCount = mSharedElementSourceNames == null ? 0 : mSharedElementSourceNames.size(); + final int count = Math.min(targetCount, sourceCount); for (int i = 0; i < count; i++) { String source = mSharedElementSourceNames.get(i); String originalTarget = mSharedElementTargetNames.get(i); diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index 532764682693..fb0e79b849b2 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -1013,14 +1013,10 @@ public class DownloadManager { /** * Returns the {@link Uri} of the given downloaded file id, if the file is * downloaded successfully. Otherwise, null is returned. - *<p> - * If the specified downloaded file is in external storage (for example, /sdcard dir), - * then it is assumed to be safe for anyone to read and the returned {@link Uri} corresponds - * to the filepath on sdcard. * * @param id the id of the downloaded file. - * @return the {@link Uri} of the given downloaded file id, if download was successful. null - * otherwise. + * @return the {@link Uri} of the given downloaded file id, if download was + * successful. null otherwise. */ public Uri getUriForDownloadedFile(long id) { // to check if the file is in cache, get its destination from the database @@ -1034,24 +1030,7 @@ public class DownloadManager { if (cursor.moveToFirst()) { int status = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_STATUS)); if (DownloadManager.STATUS_SUCCESSFUL == status) { - int indx = cursor.getColumnIndexOrThrow( - Downloads.Impl.COLUMN_DESTINATION); - int destination = cursor.getInt(indx); - // TODO: if we ever add API to DownloadManager to let the caller specify - // non-external storage for a downloaded file, then the following code - // should also check for that destination. - if (destination == Downloads.Impl.DESTINATION_CACHE_PARTITION || - destination == Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION || - destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING || - destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE) { - // return private uri - return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id); - } else { - // return public uri - String path = cursor.getString( - cursor.getColumnIndexOrThrow(COLUMN_LOCAL_FILENAME)); - return Uri.fromFile(new File(path)); - } + return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id); } } } finally { diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java index 7fbb99acc0cf..4b670cd52f00 100644 --- a/core/java/android/app/ExitTransitionCoordinator.java +++ b/core/java/android/app/ExitTransitionCoordinator.java @@ -240,7 +240,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK)); } final boolean targetsM = decorView == null || decorView.getContext() - .getApplicationInfo().targetSdkVersion >= VERSION_CODES.MNC; + .getApplicationInfo().targetSdkVersion >= VERSION_CODES.M; ArrayList<String> sharedElementNames = targetsM ? mSharedElementNames : mAllSharedElementNames; ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this, diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 5490fe729131..82206ea998ea 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -1213,6 +1213,11 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene /** * Callback for the result from requesting permissions. This method * is invoked for every call on {@link #requestPermissions(String[], int)}. + * <p> + * <strong>Note:</strong> It is possible that the permissions request interaction + * with the user is interrupted. In this case you will receive empty permissions + * and results arrays which should be treated as a cancellation. + * </p> * * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}. * @param permissions The requested permissions. Never null. @@ -1249,7 +1254,8 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene */ public boolean shouldShowRequestPermissionRationale(@NonNull String permission) { if (mHost != null) { - mHost.getContext().getPackageManager().shouldShowRequestPermissionRationale(permission); + return mHost.getContext().getPackageManager() + .shouldShowRequestPermissionRationale(permission); } return false; } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 1d87d77957fc..90216af3745c 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -72,7 +72,8 @@ public interface IActivityManager extends IInterface { ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException; public int startActivityAsCaller(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, - int flags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException; + int flags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity, + int userId) throws RemoteException; public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options, @@ -433,8 +434,8 @@ public interface IActivityManager extends IInterface { public Bundle getAssistContextExtras(int requestType) throws RemoteException; - public void requestAssistContextExtras(int requestType, IResultReceiver receiver) - throws RemoteException; + public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver, + IBinder activityToken) throws RemoteException; public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure, AssistContent content, Uri referrer) throws RemoteException; @@ -442,7 +443,9 @@ public interface IActivityManager extends IInterface { public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle, Bundle args) throws RemoteException; - public boolean isScreenCaptureAllowedOnCurrentActivity() throws RemoteException; + public boolean isAssistDataAllowedOnCurrentActivity() throws RemoteException; + + public boolean showAssistFromActivity(IBinder token, Bundle args) throws RemoteException; public void killUid(int uid, String reason) throws RemoteException; @@ -512,6 +515,8 @@ public interface IActivityManager extends IInterface { public boolean setProcessMemoryTrimLevel(String process, int uid, int level) throws RemoteException; + public boolean isRootVoiceInteraction(IBinder token) throws RemoteException; + /* * Private non-Binder interfaces */ @@ -857,4 +862,6 @@ public interface IActivityManager extends IInterface { int UNREGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+298; int IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+299; + int SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+300; + int IS_ROOT_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+301; } diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl index 8ab9ac3aff06..474154b16a19 100644 --- a/core/java/android/app/IUiAutomationConnection.aidl +++ b/core/java/android/app/IUiAutomationConnection.aidl @@ -38,10 +38,12 @@ interface IUiAutomationConnection { boolean injectInputEvent(in InputEvent event, boolean sync); boolean setRotation(int rotation); Bitmap takeScreenshot(int width, int height); - void shutdown(); boolean clearWindowContentFrameStats(int windowId); WindowContentFrameStats getWindowContentFrameStats(int windowId); void clearWindowAnimationFrameStats(); WindowAnimationFrameStats getWindowAnimationFrameStats(); void executeShellCommand(String command, in ParcelFileDescriptor fd); + + // Called from the system process. + oneway void shutdown(); } diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index 653f1b661662..69b8b9510b3a 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1701,7 +1701,8 @@ public class Instrumentation { */ public ActivityResult execStartActivityAsCaller( Context who, IBinder contextThread, IBinder token, Activity target, - Intent intent, int requestCode, Bundle options, int userId) { + Intent intent, int requestCode, Bundle options, boolean ignoreTargetSecurity, + int userId) { IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { @@ -1725,7 +1726,7 @@ public class Instrumentation { .startActivityAsCaller(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, - requestCode, 0, null, options, userId); + requestCode, 0, null, options, ignoreTargetSecurity, userId); checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); @@ -1809,9 +1810,14 @@ public class Instrumentation { throw new SecurityException( "Starting under voice control not allowed for: " + intent); case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY: - throw new SecurityException( - "Not allowed to start background user activity that shouldn't be" - + " displayed for all users."); + // Fail silently for this case so we don't break current apps. + // TODO(b/22929608): Instead of failing silently or throwing an exception, + // we should properly position the activity in the stack (i.e. behind all current + // user activity/task) and not change the positioning of stacks. + Log.e(TAG, + "Not allowed to start background user activity that shouldn't be displayed" + + " for all users. Failing silently..."); + break; default: throw new AndroidRuntimeException("Unknown error code " + res + " when starting " + intent); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index c3dece82f0bf..f3f24280d435 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -166,8 +166,10 @@ public class Notification implements Parcelable /** * The resource id of a drawable to use as the icon in the status bar. - * This is required; notifications with an invalid icon resource will not be shown. + * + * @deprecated Use {@link Builder#setSmallIcon(Icon)} instead. */ + @Deprecated @DrawableRes public int icon; @@ -269,8 +271,11 @@ public class Notification implements Parcelable public RemoteViews headsUpContentView; /** - * The bitmap that may escape the bounds of the panel and bar. + * A large bitmap to be shown in the notification content area. + * + * @deprecated Use {@link Builder#setLargeIcon(Icon)} instead. */ + @Deprecated public Bitmap largeIcon; /** @@ -900,11 +905,15 @@ public class Notification implements Parcelable */ public static class Action implements Parcelable { private final Bundle mExtras; + private Icon mIcon; private final RemoteInput[] mRemoteInputs; /** * Small icon representing the action. + * + * @deprecated Use {@link Action#getIcon()} instead. */ + @Deprecated public int icon; /** @@ -919,7 +928,12 @@ public class Notification implements Parcelable public PendingIntent actionIntent; private Action(Parcel in) { - icon = in.readInt(); + if (in.readInt() != 0) { + mIcon = Icon.CREATOR.createFromParcel(in); + if (mIcon.getType() == Icon.TYPE_RESOURCE) { + icon = mIcon.getResId(); + } + } title = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); if (in.readInt() == 1) { actionIntent = PendingIntent.CREATOR.createFromParcel(in); @@ -929,15 +943,16 @@ public class Notification implements Parcelable } /** - * Use {@link Notification.Builder#addAction(int, CharSequence, PendingIntent)}. + * @deprecated Use {@link android.app.Notification.Action.Builder}. */ + @Deprecated public Action(int icon, CharSequence title, PendingIntent intent) { - this(icon, title, intent, new Bundle(), null); + this(Icon.createWithResource("", icon), title, intent, new Bundle(), null); } - private Action(int icon, CharSequence title, PendingIntent intent, Bundle extras, + private Action(Icon icon, CharSequence title, PendingIntent intent, Bundle extras, RemoteInput[] remoteInputs) { - this.icon = icon; + this.mIcon = icon; this.title = title; this.actionIntent = intent; this.mExtras = extras != null ? extras : new Bundle(); @@ -945,6 +960,17 @@ public class Notification implements Parcelable } /** + * Return an icon representing the action. + */ + public Icon getIcon() { + if (mIcon == null && icon != 0) { + // you snuck an icon in here without using the builder; let's try to keep it + mIcon = Icon.createWithResource("", icon); + } + return mIcon; + } + + /** * Get additional metadata carried around with this Action. */ public Bundle getExtras() { @@ -963,7 +989,7 @@ public class Notification implements Parcelable * Builder class for {@link Action} objects. */ public static final class Builder { - private final int mIcon; + private final Icon mIcon; private final CharSequence mTitle; private final PendingIntent mIntent; private final Bundle mExtras; @@ -975,7 +1001,18 @@ public class Notification implements Parcelable * @param title the title of the action * @param intent the {@link PendingIntent} to fire when users trigger this action */ + @Deprecated public Builder(int icon, CharSequence title, PendingIntent intent) { + this(Icon.createWithResource("", icon), title, intent, new Bundle(), null); + } + + /** + * Construct a new builder for {@link Action} object. + * @param icon icon to show for this action + * @param title the title of the action + * @param intent the {@link PendingIntent} to fire when users trigger this action + */ + public Builder(Icon icon, CharSequence title, PendingIntent intent) { this(icon, title, intent, new Bundle(), null); } @@ -985,11 +1022,11 @@ public class Notification implements Parcelable * @param action the action to read fields from. */ public Builder(Action action) { - this(action.icon, action.title, action.actionIntent, new Bundle(action.mExtras), + this(action.getIcon(), action.title, action.actionIntent, new Bundle(action.mExtras), action.getRemoteInputs()); } - private Builder(int icon, CharSequence title, PendingIntent intent, Bundle extras, + private Builder(Icon icon, CharSequence title, PendingIntent intent, Bundle extras, RemoteInput[] remoteInputs) { mIcon = icon; mTitle = title; @@ -1063,7 +1100,7 @@ public class Notification implements Parcelable @Override public Action clone() { return new Action( - icon, + getIcon(), title, actionIntent, // safe to alias new Bundle(mExtras), @@ -1075,7 +1112,13 @@ public class Notification implements Parcelable } @Override public void writeToParcel(Parcel out, int flags) { - out.writeInt(icon); + final Icon ic = getIcon(); + if (ic != null) { + out.writeInt(1); + ic.writeToParcel(out, 0); + } else { + out.writeInt(0); + } TextUtils.writeToParcel(title, out, flags); if (actionIntent != null) { out.writeInt(1); @@ -1819,6 +1862,9 @@ public class Notification implements Parcelable } else { sb.append("null"); } + if (this.tickerText != null) { + sb.append(" tick"); + } sb.append(" defaults=0x"); sb.append(Integer.toHexString(this.defaults)); sb.append(" flags=0x"); @@ -2725,7 +2771,10 @@ public class Notification implements Parcelable * @param icon Resource ID of a drawable that represents the action. * @param title Text describing the action. * @param intent PendingIntent to be fired when the action is invoked. + * + * @deprecated Use {@link #addAction(Action)} instead. */ + @Deprecated public Builder addAction(int icon, CharSequence title, PendingIntent intent) { mActions.add(new Action(icon, safeCharSequence(title), intent)); return this; @@ -3122,10 +3171,11 @@ public class Notification implements Parcelable private RemoteViews generateActionButton(Action action) { final boolean tombstone = (action.actionIntent == null); - RemoteViews button = new RemoteViews(mContext.getPackageName(), + RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(), tombstone ? getActionTombstoneLayoutResource() : getActionLayoutResource()); - button.setTextViewCompoundDrawablesRelative(R.id.action0, action.icon, 0, 0, 0); + final Icon ai = action.getIcon(); + button.setTextViewCompoundDrawablesRelative(R.id.action0, ai, null, null, null); button.setTextViewText(R.id.action0, processLegacyText(action.title)); if (!tombstone) { button.setOnClickPendingIntent(R.id.action0, action.actionIntent); @@ -3144,7 +3194,7 @@ public class Notification implements Parcelable } private void processLegacyAction(Action action, RemoteViews button) { - if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, action.icon)) { + if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, action.getIcon())) { button.setTextViewCompoundDrawablesRelativeColorFilter(R.id.action0, 0, mContext.getColor(R.color.notification_action_color_filter), PorterDuff.Mode.MULTIPLY); @@ -3559,7 +3609,6 @@ public class Notification implements Parcelable mContentText = extras.getCharSequence(EXTRA_TEXT); mSubText = extras.getCharSequence(EXTRA_SUB_TEXT); mContentInfo = extras.getCharSequence(EXTRA_INFO_TEXT); - mSmallIcon = extras.getParcelable(EXTRA_SMALL_ICON); mProgress = extras.getInt(EXTRA_PROGRESS); mProgressMax = extras.getInt(EXTRA_PROGRESS_MAX); mProgressIndeterminate = extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE); @@ -4265,7 +4314,7 @@ public class Notification implements Parcelable * * In the expanded form, {@link Notification#bigContentView}, up to 5 * {@link Notification.Action}s specified with - * {@link Notification.Builder#addAction(int, CharSequence, PendingIntent) addAction} will be + * {@link Notification.Builder#addAction(Action) addAction} will be * shown as icon-only pushbuttons, suitable for transport controls. The Bitmap given to * {@link Notification.Builder#setLargeIcon(android.graphics.Bitmap) setLargeIcon()} will be * treated as album artwork. @@ -4391,9 +4440,9 @@ public class Notification implements Parcelable private RemoteViews generateMediaActionButton(Action action) { final boolean tombstone = (action.actionIntent == null); - RemoteViews button = new RemoteViews(mBuilder.mContext.getPackageName(), + RemoteViews button = new BuilderRemoteViews(mBuilder.mContext.getApplicationInfo(), R.layout.notification_material_media_action); - button.setImageViewResource(R.id.action0, action.icon); + button.setImageViewIcon(R.id.action0, action.getIcon()); button.setDrawableParameters(R.id.action0, false, -1, 0xFFFFFFFF, PorterDuff.Mode.SRC_ATOP, -1); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 10e8a535014b..3d264c6f2cba 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -220,11 +220,12 @@ final class SystemServiceRegistry { SYSTEM_SERVICE_NAMES.put(android.text.ClipboardManager.class, Context.CLIPBOARD_SERVICE); registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class, - new StaticServiceFetcher<ConnectivityManager>() { + new StaticOuterContextServiceFetcher<ConnectivityManager>() { @Override - public ConnectivityManager createService() { + public ConnectivityManager createService(Context context) { IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); - return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b)); + IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); + return new ConnectivityManager(context, service); }}); registerService(Context.COUNTRY_DETECTOR, CountryDetector.class, @@ -691,6 +692,9 @@ final class SystemServiceRegistry { @Override public MidiManager createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(Context.MIDI_SERVICE); + if (b == null) { + return null; + } return new MidiManager(IMidiManager.Stub.asInterface(b)); }}); @@ -790,4 +794,30 @@ final class SystemServiceRegistry { public abstract T createService(); } + + /** + * Like StaticServiceFetcher, creates only one instance of the service per process, but when + * creating the service for the first time, passes it the outer context of the creating + * component. + * + * TODO: Is this safe in the case where multiple applications share the same process? + * TODO: Delete this once its only user (ConnectivityManager) is known to work well in the + * case where multiple application components each have their own ConnectivityManager object. + */ + static abstract class StaticOuterContextServiceFetcher<T> implements ServiceFetcher<T> { + private T mCachedInstance; + + @Override + public final T getService(ContextImpl ctx) { + synchronized (StaticOuterContextServiceFetcher.this) { + if (mCachedInstance == null) { + mCachedInstance = createService(ctx.getOuterContext()); + } + return mCachedInstance; + } + } + + public abstract T createService(Context applicationContext); + } + } diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java index bf7458c0c245..823c4271adf2 100644 --- a/core/java/android/app/VoiceInteractor.java +++ b/core/java/android/app/VoiceInteractor.java @@ -27,6 +27,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.util.ArrayMap; +import android.util.DebugUtils; import android.util.Log; import com.android.internal.app.IVoiceInteractor; import com.android.internal.app.IVoiceInteractorCallback; @@ -34,6 +35,8 @@ import com.android.internal.app.IVoiceInteractorRequest; import com.android.internal.os.HandlerCaller; import com.android.internal.os.SomeArgs; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; /** @@ -68,6 +71,7 @@ public final class VoiceInteractor { Context mContext; Activity mActivity; + boolean mRetaining; final HandlerCaller mHandlerCaller; final HandlerCaller.Callback mHandlerCallerCallback = new HandlerCaller.Callback() { @@ -272,6 +276,29 @@ public final class VoiceInteractor { public void onDetached() { } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(128); + DebugUtils.buildShortClassTag(this, sb); + sb.append(" "); + sb.append(getRequestTypeName()); + sb.append(" name="); + sb.append(mName); + sb.append('}'); + return sb.toString(); + } + + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + writer.print(prefix); writer.print("mRequestInterface="); + writer.println(mRequestInterface.asBinder()); + writer.print(prefix); writer.print("mActivity="); writer.println(mActivity); + writer.print(prefix); writer.print("mName="); writer.println(mName); + } + + String getRequestTypeName() { + return "Request"; + } + void clear() { mRequestInterface = null; mContext = null; @@ -333,6 +360,18 @@ public final class VoiceInteractor { public void onConfirmationResult(boolean confirmed, Bundle result) { } + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mPrompt="); writer.println(mPrompt); + if (mExtras != null) { + writer.print(prefix); writer.print("mExtras="); writer.println(mExtras); + } + } + + String getRequestTypeName() { + return "Confirmation"; + } + IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName, IVoiceInteractorCallback callback) throws RemoteException { return interactor.startConfirmation(packageName, callback, mPrompt, mExtras); @@ -515,6 +554,38 @@ public final class VoiceInteractor { public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) { } + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mPrompt="); writer.println(mPrompt); + if (mOptions != null) { + writer.print(prefix); writer.println("Options:"); + for (int i=0; i<mOptions.length; i++) { + Option op = mOptions[i]; + writer.print(prefix); writer.print(" #"); writer.print(i); writer.println(":"); + writer.print(prefix); writer.print(" mLabel="); writer.println(op.mLabel); + writer.print(prefix); writer.print(" mIndex="); writer.println(op.mIndex); + if (op.mSynonyms != null && op.mSynonyms.size() > 0) { + writer.print(prefix); writer.println(" Synonyms:"); + for (int j=0; j<op.mSynonyms.size(); j++) { + writer.print(prefix); writer.print(" #"); writer.print(j); + writer.print(": "); writer.println(op.mSynonyms.get(j)); + } + } + if (op.mExtras != null) { + writer.print(prefix); writer.print(" mExtras="); + writer.println(op.mExtras); + } + } + } + if (mExtras != null) { + writer.print(prefix); writer.print("mExtras="); writer.println(mExtras); + } + } + + String getRequestTypeName() { + return "PickOption"; + } + IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName, IVoiceInteractorCallback callback) throws RemoteException { return interactor.startPickOption(packageName, callback, mPrompt, mOptions, mExtras); @@ -560,6 +631,18 @@ public final class VoiceInteractor { public void onCompleteResult(Bundle result) { } + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mPrompt="); writer.println(mPrompt); + if (mExtras != null) { + writer.print(prefix); writer.print("mExtras="); writer.println(mExtras); + } + } + + String getRequestTypeName() { + return "CompleteVoice"; + } + IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName, IVoiceInteractorCallback callback) throws RemoteException { return interactor.startCompleteVoice(packageName, callback, mPrompt, mExtras); @@ -607,6 +690,18 @@ public final class VoiceInteractor { public void onAbortResult(Bundle result) { } + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mPrompt="); writer.println(mPrompt); + if (mExtras != null) { + writer.print(prefix); writer.print("mExtras="); writer.println(mExtras); + } + } + + String getRequestTypeName() { + return "AbortVoice"; + } + IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName, IVoiceInteractorCallback callback) throws RemoteException { return interactor.startAbortVoice(packageName, callback, mPrompt, mExtras); @@ -650,6 +745,18 @@ public final class VoiceInteractor { public void onCommandResult(boolean isCompleted, Bundle result) { } + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mCommand="); writer.println(mCommand); + if (mArgs != null) { + writer.print(prefix); writer.print("mArgs="); writer.println(mArgs); + } + } + + String getRequestTypeName() { + return "Command"; + } + IVoiceInteractorRequest submit(IVoiceInteractor interactor, String packageName, IVoiceInteractorCallback callback) throws RemoteException { return interactor.startCommand(packageName, callback, mCommand, mArgs); @@ -721,6 +828,30 @@ public final class VoiceInteractor { return mVisualPrompt; } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(128); + DebugUtils.buildShortClassTag(this, sb); + if (mVisualPrompt != null && mVoicePrompts != null && mVoicePrompts.length == 1 + && mVisualPrompt.equals(mVoicePrompts[0])) { + sb.append(" "); + sb.append(mVisualPrompt); + } else { + if (mVisualPrompt != null) { + sb.append(" visual="); sb.append(mVisualPrompt); + } + if (mVoicePrompts != null) { + sb.append(", voice="); + for (int i=0; i<mVoicePrompts.length; i++) { + if (i > 0) sb.append(" | "); + sb.append(mVoicePrompts[i]); + } + } + } + sb.append('}'); + return sb.toString(); + } + /** Constructor to support Parcelable behavior. */ Prompt(Parcel in) { mVoicePrompts = in.readCharSequenceArray(); @@ -773,7 +904,7 @@ public final class VoiceInteractor { if (N < 1) { return null; } - ArrayList<Request> list = new ArrayList<Request>(N); + ArrayList<Request> list = new ArrayList<>(N); for (int i=0; i<N; i++) { list.add(mActiveRequests.valueAt(i)); } @@ -781,6 +912,7 @@ public final class VoiceInteractor { } void attachActivity(Activity activity) { + mRetaining = false; if (mActivity == activity) { return; } @@ -797,6 +929,10 @@ public final class VoiceInteractor { } } + void retainInstance() { + mRetaining = true; + } + void detachActivity() { ArrayList<Request> reqs = makeRequestList(); if (reqs != null) { @@ -807,6 +943,16 @@ public final class VoiceInteractor { req.mContext = null; } } + if (!mRetaining) { + reqs = makeRequestList(); + if (reqs != null) { + for (int i=0; i<reqs.size(); i++) { + Request req = reqs.get(i); + req.cancel(); + } + } + mActiveRequests.clear(); + } mContext = null; mActivity = null; } @@ -902,4 +1048,22 @@ public final class VoiceInteractor { throw new RuntimeException("Voice interactor has died", e); } } + + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + String innerPrefix = prefix + " "; + if (mActiveRequests.size() > 0) { + writer.print(prefix); writer.println("Active voice requests:"); + for (int i=0; i<mActiveRequests.size(); i++) { + Request req = mActiveRequests.valueAt(i); + writer.print(prefix); writer.print(" #"); writer.print(i); + writer.print(": "); + writer.println(req); + req.dump(innerPrefix, fd, writer, args); + } + } + writer.print(prefix); writer.println("VoiceInteractor misc state:"); + writer.print(prefix); writer.print(" mInteractor="); + writer.println(mInteractor.asBinder()); + writer.print(prefix); writer.print(" mActivity="); writer.println(mActivity); + } } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 33cbc9d8c737..f21422e0d7cb 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -112,7 +112,7 @@ public class DevicePolicyManager { * * In version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this intent must contain the * extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}. - * As of {@link android.os.Build.VERSION_CODES#MNC}, it should contain the extra + * As of {@link android.os.Build.VERSION_CODES#M}, it should contain the extra * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead, although specifying only * {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported. * @@ -417,7 +417,7 @@ public class DevicePolicyManager { * * <p><strong>Note:</strong> for devices running {@link android.os.Build.VERSION_CODES#LOLLIPOP} * and {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} only SHA-1 hash is supported. - * Starting from {@link android.os.Build.VERSION_CODES#MNC}, this parameter accepts SHA-256 in + * Starting from {@link android.os.Build.VERSION_CODES#M}, this parameter accepts SHA-256 in * addition to SHA-1. Support for SHA-1 is likely to be removed in future OS releases. */ public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM @@ -590,7 +590,7 @@ public class DevicePolicyManager { * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li></ul> * * <p> - * As of {@link android.os.Build.VERSION_CODES#MNC}, the properties should contain + * As of {@link android.os.Build.VERSION_CODES#M}, the properties should contain * {@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). @@ -603,7 +603,7 @@ public class DevicePolicyManager { * @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 + * {@link android.os.Build.VERSION_CODES#M} in addition to those supported in earlier * versions. * * <p>During device owner provisioning a device admin app is set as the owner of the device. @@ -690,7 +690,7 @@ public class DevicePolicyManager { = "android.app.extra.PROFILE_OWNER_NAME"; /** - * Activity action: send when any policy admin changes a policy. + * Broadcast action: send when any policy admin changes a policy. * This is generally used to find out when a new policy is in effect. * * @hide @@ -699,6 +699,16 @@ public class DevicePolicyManager { = "android.app.action.DEVICE_POLICY_MANAGER_STATE_CHANGED"; /** + * Broadcast action: sent when the device owner is set or changed. + * + * This broadcast is sent only to the primary user. + * @see #ACTION_PROVISION_MANAGED_DEVICE + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_DEVICE_OWNER_CHANGED + = "android.app.action.DEVICE_OWNER_CHANGED"; + + /** * The ComponentName of the administrator component. * * @see #ACTION_ADD_DEVICE_ADMIN @@ -2405,7 +2415,7 @@ public class DevicePolicyManager { * <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 + * <p>From version {@link android.os.Build.VERSION_CODES#M} disabling screen capture also * blocks assist requests for all activities of the relevant user. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. @@ -2489,9 +2499,9 @@ public class DevicePolicyManager { * this method; if it has not, a security exception will be thrown. * * <p>Calling this from a managed profile before version - * {@link android.os.Build.VERSION_CODES#MNC} will throw a security exception. + * {@link android.os.Build.VERSION_CODES#M} will throw a security exception. * - * <p>From version {@link android.os.Build.VERSION_CODES#MNC} a profile owner can set: + * <p>From version {@link android.os.Build.VERSION_CODES#M} a profile owner can set: * <ul> * <li>{@link #KEYGUARD_DISABLE_TRUST_AGENTS}, {@link #KEYGUARD_DISABLE_FINGERPRINT} * these will affect the profile's parent user. @@ -3613,7 +3623,7 @@ public class DevicePolicyManager { * @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 From {@link android.os.Build.VERSION_CODES#M} */ @Deprecated public UserHandle createUser(@NonNull ComponentName admin, String name) { @@ -3650,7 +3660,7 @@ public class DevicePolicyManager { * @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 From {@link android.os.Build.VERSION_CODES#M} */ @Deprecated public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name, @@ -3904,7 +3914,7 @@ public class DevicePolicyManager { * <p>Any packages that shares uid with an allowed package will also be allowed * to activate lock task. * - * From {@link android.os.Build.VERSION_CODES#MNC} removing packages from the lock task + * From {@link android.os.Build.VERSION_CODES#M} removing packages from the lock task * package list results in locked tasks belonging to those packages to be finished. * * This function can only be called by the device owner. @@ -3972,14 +3982,14 @@ public class DevicePolicyManager { * <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</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 + * This setting is only available from {@link android.os.Build.VERSION_CODES#M} 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> - * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards. + * This setting is only available from {@link android.os.Build.VERSION_CODES#M} onwards. * </li> * </ul> * <p>Changing the following settings has no effect as of - * {@link android.os.Build.VERSION_CODES#MNC}: + * {@link android.os.Build.VERSION_CODES#M}: * <ul> * <li>{@link Settings.Global#BLUETOOTH_ON}. * Use {@link android.bluetooth.BluetoothAdapter#enable()} and @@ -4334,7 +4344,7 @@ public class DevicePolicyManager { * the permission grant state via {@link #setPermissionGrantState}. * * <p/>As this policy only acts on runtime permission requests, it only applies to applications - * built with a {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#MNC} or later. + * built with a {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} or later. * * @param admin Which profile or device owner this request is associated with. * @param policy One of the policy constants {@link #PERMISSION_POLICY_PROMPT}, @@ -4378,7 +4388,7 @@ public class DevicePolicyManager { * 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. + * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#M} 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. diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index 40126d6f62a9..6b720c0a22f6 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.ComponentName; import android.graphics.Matrix; import android.graphics.Rect; +import android.os.BadParcelableException; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; @@ -31,8 +32,12 @@ public class AssistStructure implements Parcelable { static final String TAG = "AssistStructure"; static final boolean DEBUG_PARCEL = false; + static final boolean DEBUG_PARCEL_CHILDREN = false; static final boolean DEBUG_PARCEL_TREE = false; + static final int VALIDATE_WINDOW_TOKEN = 0x11111111; + static final int VALIDATE_VIEW_TOKEN = 0x22222222; + boolean mHaveData; ComponentName mActivityComponent; @@ -136,10 +141,10 @@ public class AssistStructure implements Parcelable { if (DEBUG_PARCEL) Log.d(TAG, "Creating PooledStringWriter @ " + out.dataPosition()); PooledStringWriter pwriter = new PooledStringWriter(out); while (writeNextEntryToParcel(as, out, pwriter)) { - // If the parcel contains more than 100K of data, then we are getting too + // If the parcel is above the IPC limit, then we are getting too // large for a single IPC so stop here and let the caller come back when it // is ready for more. - if (out.dataSize() > 1024*1024) { + if (out.dataSize() > IBinder.MAX_IPC_SIZE) { if (DEBUG_PARCEL) Log.d(TAG, "Assist data size is " + out.dataSize() + " @ pos " + out.dataPosition() + "; returning partial result"); out.writeInt(0); @@ -173,6 +178,26 @@ public class AssistStructure implements Parcelable { mCurViewStackEntry = entry; } + void writeView(ViewNode child, Parcel out, PooledStringWriter pwriter, int levelAdj) { + if (DEBUG_PARCEL) Log.d(TAG, "write view: at " + out.dataPosition() + + ", windows=" + mNumWrittenWindows + + ", views=" + mNumWrittenViews + + ", level=" + (mCurViewStackPos+levelAdj)); + out.writeInt(VALIDATE_VIEW_TOKEN); + int flags = child.writeSelfToParcel(out, pwriter, mTmpMatrix); + mNumWrittenViews++; + // If the child has children, push it on the stack to write them next. + if ((flags&ViewNode.FLAGS_HAS_CHILDREN) != 0) { + if (DEBUG_PARCEL_TREE || DEBUG_PARCEL_CHILDREN) Log.d(TAG, + "Preparing to write " + child.mChildren.length + + " children: @ #" + mNumWrittenViews + + ", level " + (mCurViewStackPos+levelAdj)); + out.writeInt(child.mChildren.length); + int pos = ++mCurViewStackPos; + pushViewStackEntry(child, pos); + } + } + boolean writeNextEntryToParcel(AssistStructure as, Parcel out, PooledStringWriter pwriter) { // Write next view node if appropriate. if (mCurViewStackEntry != null) { @@ -182,20 +207,7 @@ public class AssistStructure implements Parcelable { + mCurViewStackEntry.curChild + " in " + mCurViewStackEntry.node); ViewNode child = mCurViewStackEntry.node.mChildren[mCurViewStackEntry.curChild]; mCurViewStackEntry.curChild++; - if (DEBUG_PARCEL) Log.d(TAG, "write view: at " + out.dataPosition() - + ", windows=" + mNumWrittenWindows - + ", views=" + mNumWrittenViews); - out.writeInt(1); - int flags = child.writeSelfToParcel(out, pwriter, mTmpMatrix); - mNumWrittenViews++; - // If the child has children, push it on the stack to write them next. - if ((flags&ViewNode.FLAGS_HAS_CHILDREN) != 0) { - if (DEBUG_PARCEL_TREE) Log.d(TAG, "Preparing to write " - + child.mChildren.length + " children under " + child); - out.writeInt(child.mChildren.length); - int pos = ++mCurViewStackPos; - pushViewStackEntry(child, pos); - } + writeView(child, out, pwriter, 1); return true; } @@ -223,13 +235,13 @@ public class AssistStructure implements Parcelable { if (DEBUG_PARCEL) Log.d(TAG, "write window #" + pos + ": at " + out.dataPosition() + ", windows=" + mNumWrittenWindows + ", views=" + mNumWrittenViews); - out.writeInt(1); + out.writeInt(VALIDATE_WINDOW_TOKEN); win.writeSelfToParcel(out, pwriter, mTmpMatrix); mNumWrittenWindows++; ViewNode root = win.mRoot; mCurViewStackPos = 0; - if (DEBUG_PARCEL_TREE) Log.d(TAG, "Pushing initial root view " + root); - pushViewStackEntry(root, 0); + if (DEBUG_PARCEL_TREE) Log.d(TAG, "Writing initial root view " + root); + writeView(root, out, pwriter, 0); return true; } @@ -271,11 +283,16 @@ public class AssistStructure implements Parcelable { + ", views=" + mNumReadViews); } - Parcel readParcel() { + Parcel readParcel(int validateToken, int level) { if (DEBUG_PARCEL) Log.d(TAG, "readParcel: at " + mCurParcel.dataPosition() + ", avail=" + mCurParcel.dataAvail() + ", windows=" + mNumReadWindows - + ", views=" + mNumReadViews); - if (mCurParcel.readInt() != 0) { + + ", views=" + mNumReadViews + ", level=" + level); + int token = mCurParcel.readInt(); + if (token != 0) { + if (token != validateToken) { + throw new BadParcelableException("Got token " + Integer.toHexString(token) + + ", expected token " + Integer.toHexString(validateToken)); + } return mCurParcel; } // We have run out of partial data, need to read another batch. @@ -406,7 +423,7 @@ public class AssistStructure implements Parcelable { } WindowNode(ParcelTransferReader reader) { - Parcel in = reader.readParcel(); + Parcel in = reader.readParcel(VALIDATE_WINDOW_TOKEN, 0); reader.mNumReadWindows++; mX = in.readInt(); mY = in.readInt(); @@ -414,7 +431,7 @@ public class AssistStructure implements Parcelable { mHeight = in.readInt(); mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mDisplayId = in.readInt(); - mRoot = new ViewNode(reader); + mRoot = new ViewNode(reader, 0); } void writeSelfToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) { @@ -548,8 +565,8 @@ public class AssistStructure implements Parcelable { ViewNode() { } - ViewNode(ParcelTransferReader reader) { - final Parcel in = reader.readParcel(); + ViewNode(ParcelTransferReader reader, int nestingLevel) { + final Parcel in = reader.readParcel(VALIDATE_VIEW_TOKEN, nestingLevel); reader.mNumReadViews++; final PooledStringReader preader = reader.mStringReader; mClassName = preader.readString(); @@ -604,9 +621,13 @@ public class AssistStructure implements Parcelable { } if ((flags&FLAGS_HAS_CHILDREN) != 0) { final int NCHILDREN = in.readInt(); + if (DEBUG_PARCEL_TREE || DEBUG_PARCEL_CHILDREN) Log.d(TAG, + "Preparing to read " + NCHILDREN + + " children: @ #" + reader.mNumReadViews + + ", level " + nestingLevel); mChildren = new ViewNode[NCHILDREN]; for (int i=0; i<NCHILDREN; i++) { - mChildren[i] = new ViewNode(reader); + mChildren[i] = new ViewNode(reader, nestingLevel + 1); } } } @@ -1085,7 +1106,7 @@ public class AssistStructure implements Parcelable { @Override public void setAssistBlocked(boolean state) { mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ASSIST_BLOCKED) - | (state ? 0 : ViewNode.FLAGS_ASSIST_BLOCKED); + | (state ? ViewNode.FLAGS_ASSIST_BLOCKED : 0); } @Override @@ -1391,6 +1412,9 @@ public class AssistStructure implements Parcelable { if (extras != null) { Log.i(TAG, prefix + " Extras: " + extras); } + if (node.isAssistBlocked()) { + Log.i(TAG, prefix + " BLOCKED"); + } final int NCHILDREN = node.getChildCount(); if (NCHILDREN > 0) { Log.i(TAG, prefix + " Children:"); diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java index 4d2158ffb457..954ccef93b44 100644 --- a/core/java/android/app/backup/BackupTransport.java +++ b/core/java/android/app/backup/BackupTransport.java @@ -415,7 +415,7 @@ public class BackupTransport { * if this method returns TRANSPORT_OK. To avoid storing such payloads the transport * must recognize this case and return TRANSPORT_PACKAGE_REJECTED. * - * Added in MNC (API 23). + * Added in {@link android.os.Build.VERSION_CODES#M}. * * @param size The estimated size of the full-data payload for this app. This includes * manifest and archive format overhead, but is not guaranteed to be precise. diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java index e09ab5676de7..2ba87744d087 100644 --- a/core/java/android/bluetooth/le/BluetoothLeScanner.java +++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java @@ -79,6 +79,10 @@ public final class BluetoothLeScanner { * delivered through {@code callback}. * <p> * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. + * An app must hold + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission + * in order to get results. * * @param callback Callback used to deliver scan results. * @throws IllegalArgumentException If {@code callback} is null. @@ -95,6 +99,10 @@ public final class BluetoothLeScanner { * Start Bluetooth LE scan. The scan results will be delivered through {@code callback}. * <p> * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. + * An app must hold + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission + * in order to get results. * * @param filters {@link ScanFilter}s for finding exact BLE devices. * @param settings Settings for the scan. diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 3cc76841bd70..ba9cf7c780fa 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -16,8 +16,11 @@ package android.content; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.Manifest.permission.INTERACT_ACROSS_USERS; +import static android.app.AppOpsManager.MODE_ALLOWED; +import static android.app.AppOpsManager.MODE_ERRORED; +import static android.app.AppOpsManager.MODE_IGNORED; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.annotation.NonNull; import android.annotation.Nullable; @@ -40,8 +43,8 @@ import android.os.OperationCanceledException; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.UserHandle; -import android.util.Log; import android.text.TextUtils; +import android.util.Log; import java.io.File; import java.io.FileDescriptor; @@ -474,14 +477,9 @@ public abstract class ContentProvider implements ComponentCallbacks2 { private int enforceReadPermission(String callingPkg, Uri uri, IBinder callerToken) throws SecurityException { - enforceReadPermissionInner(uri, callerToken); - - final int permOp = AppOpsManager.permissionToOpCode(mReadPermission); - if (permOp != AppOpsManager.OP_NONE) { - final int mode = mAppOpsManager.noteProxyOp(permOp, callingPkg); - if (mode != AppOpsManager.MODE_ALLOWED) { - return mode; - } + final int mode = enforceReadPermissionInner(uri, callingPkg, callerToken); + if (mode != MODE_ALLOWED) { + return mode; } if (mReadOp != AppOpsManager.OP_NONE) { @@ -493,14 +491,9 @@ public abstract class ContentProvider implements ComponentCallbacks2 { private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken) throws SecurityException { - enforceWritePermissionInner(uri, callerToken); - - final int permOp = AppOpsManager.permissionToOpCode(mWritePermission); - if (permOp != AppOpsManager.OP_NONE) { - final int mode = mAppOpsManager.noteProxyOp(permOp, callingPkg); - if (mode != AppOpsManager.MODE_ALLOWED) { - return mode; - } + final int mode = enforceWritePermissionInner(uri, callingPkg, callerToken); + if (mode != MODE_ALLOWED) { + return mode; } if (mWriteOp != AppOpsManager.OP_NONE) { @@ -518,26 +511,47 @@ public abstract class ContentProvider implements ComponentCallbacks2 { == PERMISSION_GRANTED; } + /** + * Verify that calling app holds both the given permission and any app-op + * associated with that permission. + */ + private int checkPermissionAndAppOp(String permission, String callingPkg, + IBinder callerToken) { + if (getContext().checkPermission(permission, Binder.getCallingPid(), Binder.getCallingUid(), + callerToken) != PERMISSION_GRANTED) { + return MODE_ERRORED; + } + + final int permOp = AppOpsManager.permissionToOpCode(permission); + if (permOp != AppOpsManager.OP_NONE) { + return mTransport.mAppOpsManager.noteProxyOp(permOp, callingPkg); + } + + return MODE_ALLOWED; + } + /** {@hide} */ - protected void enforceReadPermissionInner(Uri uri, IBinder callerToken) + protected int enforceReadPermissionInner(Uri uri, String callingPkg, IBinder callerToken) throws SecurityException { final Context context = getContext(); final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); String missingPerm = null; + int strongestMode = MODE_ALLOWED; if (UserHandle.isSameApp(uid, mMyUid)) { - return; + return MODE_ALLOWED; } if (mExported && checkUser(pid, uid, context)) { final String componentPerm = getReadPermission(); if (componentPerm != null) { - if (context.checkPermission(componentPerm, pid, uid, callerToken) - == PERMISSION_GRANTED) { - return; + final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken); + if (mode == MODE_ALLOWED) { + return MODE_ALLOWED; } else { missingPerm = componentPerm; + strongestMode = Math.max(strongestMode, mode); } } @@ -551,14 +565,15 @@ public abstract class ContentProvider implements ComponentCallbacks2 { for (PathPermission pp : pps) { final String pathPerm = pp.getReadPermission(); if (pathPerm != null && pp.match(path)) { - if (context.checkPermission(pathPerm, pid, uid, callerToken) - == PERMISSION_GRANTED) { - return; + final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken); + if (mode == MODE_ALLOWED) { + return MODE_ALLOWED; } else { // any denied <path-permission> means we lose // default <provider> access. allowDefaultRead = false; missingPerm = pathPerm; + strongestMode = Math.max(strongestMode, mode); } } } @@ -566,7 +581,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { // if we passed <path-permission> checks above, and no default // <provider> permission, then allow access. - if (allowDefaultRead) return; + if (allowDefaultRead) return MODE_ALLOWED; } // last chance, check against any uri grants @@ -575,7 +590,13 @@ public abstract class ContentProvider implements ComponentCallbacks2 { ? maybeAddUserId(uri, callingUserId) : uri; if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, callerToken) == PERMISSION_GRANTED) { - return; + return MODE_ALLOWED; + } + + // If the worst denial we found above was ignored, then pass that + // ignored through; otherwise we assume it should be a real error below. + if (strongestMode == MODE_IGNORED) { + return MODE_IGNORED; } final String failReason = mExported @@ -587,25 +608,27 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } /** {@hide} */ - protected void enforceWritePermissionInner(Uri uri, IBinder callerToken) + protected int enforceWritePermissionInner(Uri uri, String callingPkg, IBinder callerToken) throws SecurityException { final Context context = getContext(); final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); String missingPerm = null; + int strongestMode = MODE_ALLOWED; if (UserHandle.isSameApp(uid, mMyUid)) { - return; + return MODE_ALLOWED; } if (mExported && checkUser(pid, uid, context)) { final String componentPerm = getWritePermission(); if (componentPerm != null) { - if (context.checkPermission(componentPerm, pid, uid, callerToken) - == PERMISSION_GRANTED) { - return; + final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken); + if (mode == MODE_ALLOWED) { + return MODE_ALLOWED; } else { missingPerm = componentPerm; + strongestMode = Math.max(strongestMode, mode); } } @@ -619,14 +642,15 @@ public abstract class ContentProvider implements ComponentCallbacks2 { for (PathPermission pp : pps) { final String pathPerm = pp.getWritePermission(); if (pathPerm != null && pp.match(path)) { - if (context.checkPermission(pathPerm, pid, uid, callerToken) - == PERMISSION_GRANTED) { - return; + final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken); + if (mode == MODE_ALLOWED) { + return MODE_ALLOWED; } else { // any denied <path-permission> means we lose // default <provider> access. allowDefaultWrite = false; missingPerm = pathPerm; + strongestMode = Math.max(strongestMode, mode); } } } @@ -634,13 +658,19 @@ public abstract class ContentProvider implements ComponentCallbacks2 { // if we passed <path-permission> checks above, and no default // <provider> permission, then allow access. - if (allowDefaultWrite) return; + if (allowDefaultWrite) return MODE_ALLOWED; } // last chance, check against any uri grants if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, callerToken) == PERMISSION_GRANTED) { - return; + return MODE_ALLOWED; + } + + // If the worst denial we found above was ignored, then pass that + // ignored through; otherwise we assume it should be a real error below. + if (strongestMode == MODE_IGNORED) { + return MODE_IGNORED; } final String failReason = mExported diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 55716621f515..ec443cddf99b 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1021,9 +1021,9 @@ public class Intent implements Parcelable, Cloneable { * 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} + * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} * 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 + * permission which is not granted, then attempting to use this action will * result in a {@link java.lang.SecurityException}. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) @@ -1782,14 +1782,6 @@ public class Intent implements Parcelable, Cloneable { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED"; /** - * Sync State Changed Action: This is broadcast when the sync starts or stops or when one has - * been failing for a long time. It is used by the SyncManager and the StatusBar service. - * @hide - */ - @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String ACTION_SYNC_STATE_CHANGED - = "android.intent.action.SYNC_STATE_CHANGED"; - /** * Broadcast Action: This is broadcast once, after the system has finished * booting. It can be used to perform application-specific initialization, * such as installing alarms. You must hold the diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java index 19329ceaefec..3a17e23b0547 100644 --- a/core/java/android/content/IntentFilter.java +++ b/core/java/android/content/IntentFilter.java @@ -1206,7 +1206,7 @@ public class IntentFilter implements Parcelable { * {@link #MATCH_CATEGORY_PORT}, {@link #NO_MATCH_DATA}. */ public final int matchDataAuthority(Uri data) { - if (mDataAuthorities == null) { + if (mDataAuthorities == null || data == null) { return NO_MATCH_DATA; } final int numDataAuthorities = mDataAuthorities.size(); @@ -1277,7 +1277,7 @@ public class IntentFilter implements Parcelable { } final ArrayList<PatternMatcher> schemeSpecificParts = mDataSchemeSpecificParts; - if (schemeSpecificParts != null) { + if (schemeSpecificParts != null && data != null) { match = hasDataSchemeSpecificPart(data.getSchemeSpecificPart()) ? MATCH_CATEGORY_SCHEME_SPECIFIC_PART : NO_MATCH_DATA; } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index ceb610ac5c9d..a5e9faf7b1b9 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -203,7 +203,7 @@ interface IPackageManager { void querySyncProviders(inout List<String> outNames, inout List<ProviderInfo> outInfo); - List<ProviderInfo> queryContentProviders( + ParceledListSlice queryContentProviders( String processName, int uid, int flags); InstrumentationInfo getInstrumentationInfo( @@ -253,7 +253,7 @@ interface IPackageManager { List<PackageInfo> getPreferredPackages(int flags); - void resetPreferredActivities(int userId); + void resetApplicationPreferences(int userId); ResolveInfo getLastChosenActivity(in Intent intent, String resolvedType, int flags); @@ -505,4 +505,6 @@ interface IPackageManager { void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId); boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId); + + String getPermissionControllerPackageName(); } diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index b7ee82d41693..9341be16c28f 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -18,8 +18,10 @@ package android.content.pm; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SystemApi; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; @@ -889,6 +891,8 @@ public class PackageInstaller { public String abiOverride; /** {@hide} */ public String volumeUuid; + /** {@hide} */ + public String[] grantedRuntimePermissions; /** * Construct parameters for a new package install session. @@ -914,6 +918,7 @@ public class PackageInstaller { referrerUri = source.readParcelable(null); abiOverride = source.readString(); volumeUuid = source.readString(); + grantedRuntimePermissions = source.readStringArray(); } /** @@ -987,6 +992,23 @@ public class PackageInstaller { this.referrerUri = referrerUri; } + /** + * Sets which runtime permissions to be granted to the package at installation. + * Using this API requires holding {@link android.Manifest.permission + * #INSTALL_GRANT_RUNTIME_PERMISSIONS} + * + * @param permissions The permissions to grant or null to grant all runtime + * permissions. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS) + public void setGrantedRuntimePermissions(String[] permissions) { + installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS; + this.grantedRuntimePermissions = permissions; + } + /** {@hide} */ public void setInstallFlagsInternal() { installFlags |= PackageManager.INSTALL_INTERNAL; @@ -1012,6 +1034,7 @@ public class PackageInstaller { pw.printPair("referrerUri", referrerUri); pw.printPair("abiOverride", abiOverride); pw.printPair("volumeUuid", volumeUuid); + pw.printPair("grantedRuntimePermissions", grantedRuntimePermissions); pw.println(); } @@ -1033,6 +1056,7 @@ public class PackageInstaller { dest.writeParcelable(referrerUri, flags); dest.writeString(abiOverride); dest.writeString(volumeUuid); + dest.writeStringArray(grantedRuntimePermissions); } public static final Parcelable.Creator<SessionParams> diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 6533bbcc6299..0f936fd693ed 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1514,6 +1514,13 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and + * {@link #hasSystemFeature}: The device has biometric hardware to detect a fingerprint. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_FINGERPRINT = "android.hardware.fingerprint"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device supports portrait orientation * screens. For backwards compatibility, you can assume that if neither * this nor {@link #FEATURE_SCREEN_LANDSCAPE} is set then the device supports @@ -1869,14 +1876,6 @@ public abstract class PackageManager { "android.content.pm.action.REQUEST_PERMISSIONS"; /** - * The component name handling runtime permission grants. - * - * @hide - */ - public static final String GRANT_PERMISSIONS_PACKAGE_NAME = - "com.android.packageinstaller"; - - /** * The names of the requested permissions. * <p> * <strong>Type:</strong> String[] @@ -2424,7 +2423,17 @@ public abstract class PackageManager { * @return Whether the permission is restricted by policy. */ @CheckResult - public abstract boolean isPermissionRevokedByPolicy(String permName, String pkgName); + public abstract boolean isPermissionRevokedByPolicy(@NonNull String permName, + @NonNull String pkgName); + + /** + * Gets the package name of the component controlling runtime permissions. + * + * @return The package name. + * + * @hide + */ + public abstract String getPermissionControllerPackageName(); /** * Add a new dynamic permission to the system. For this to work, your @@ -2608,7 +2617,7 @@ public abstract class PackageManager { } Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS); intent.putExtra(EXTRA_REQUEST_PERMISSIONS_NAMES, permissions); - intent.setPackage(GRANT_PERMISSIONS_PACKAGE_NAME); + intent.setPackage(getPermissionControllerPackageName()); return intent; } diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index ea089562243f..bf70d6ca9dfe 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -83,6 +83,12 @@ public abstract class PackageManagerInternal { public abstract void setDialerAppPackagesProvider(PackagesProvider provider); /** + * Sets the sim call manager packages provider. + * @param provider The packages provider. + */ + public abstract void setSimCallManagerPackagesProvider(PackagesProvider provider); + + /** * Sets the sync adapter packages provider. * @param provider The provider. */ @@ -101,4 +107,12 @@ public abstract class PackageManagerInternal { * @param userId The user for which to grant the permissions. */ public abstract void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId); + + /** + * Requests granting of the default permissions to the current default sim call manager. + * @param packageName The default sim call manager package name. + * @param userId The user for which to grant the permissions. + */ + public abstract void grantDefaultPermissionsToDefaultSimCallManager(String packageName, + int userId); } diff --git a/core/java/android/content/pm/ParceledListSlice.java b/core/java/android/content/pm/ParceledListSlice.java index e5c2203a2d20..cfb447334406 100644 --- a/core/java/android/content/pm/ParceledListSlice.java +++ b/core/java/android/content/pm/ParceledListSlice.java @@ -46,8 +46,7 @@ public class ParceledListSlice<T extends Parcelable> implements Parcelable { * TODO get this number from somewhere else. For now set it to a quarter of * the 1MB limit. */ - private static final int MAX_IPC_SIZE = 256 * 1024; - private static final int MAX_FIRST_IPC_SIZE = MAX_IPC_SIZE / 2; + private static final int MAX_IPC_SIZE = IBinder.MAX_IPC_SIZE; private final List<T> mList; @@ -150,7 +149,7 @@ public class ParceledListSlice<T extends Parcelable> implements Parcelable { final Class<?> listElementClass = mList.get(0).getClass(); dest.writeParcelableCreator(mList.get(0)); int i = 0; - while (i < N && dest.dataSize() < MAX_FIRST_IPC_SIZE) { + while (i < N && dest.dataSize() < MAX_IPC_SIZE) { dest.writeInt(1); final T parcelable = mList.get(i); diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index 2828d83bcdae..d51451340690 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -145,12 +145,10 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { 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 + * Flag for {@link #flags}, indicating that this permission has been + * installed into the system's globally defined permissions. */ - public static final int PROTECTION_FLAG_HIDE = 1<<1; + public static final int FLAG_INSTALLED = 1<<30; /** * Additional flags about this permission as given by @@ -210,6 +208,15 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { if ((level&PermissionInfo.PROTECTION_FLAG_PRE23) != 0) { protLevel += "|pre23"; } + if ((level&PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0) { + protLevel += "|installer"; + } + if ((level&PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0) { + protLevel += "|verifier"; + } + if ((level&PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0) { + protLevel += "|preinstalled"; + } return protLevel; } diff --git a/core/java/android/content/res/DrawableCache.java b/core/java/android/content/res/DrawableCache.java index fc70bc60b5c2..ba00134f742c 100644 --- a/core/java/android/content/res/DrawableCache.java +++ b/core/java/android/content/res/DrawableCache.java @@ -52,6 +52,6 @@ class DrawableCache extends ThemedResourceCache<Drawable.ConstantState> { @Override public boolean shouldInvalidateEntry(Drawable.ConstantState entry, int configChanges) { - return false; + return Configuration.needNewResources(configChanges, entry.getChangingConfigurations()); } } diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java index 9548d49af418..26205718c44d 100644 --- a/core/java/android/content/res/ResourcesKey.java +++ b/core/java/android/content/res/ResourcesKey.java @@ -16,6 +16,8 @@ package android.content.res; +import android.annotation.NonNull; + import java.util.Objects; /** @hide */ @@ -25,27 +27,27 @@ public final class ResourcesKey { private final int mHash; public final int mDisplayId; + @NonNull public final Configuration mOverrideConfiguration; public ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) { mResDir = resDir; mDisplayId = displayId; - mOverrideConfiguration = overrideConfiguration; + mOverrideConfiguration = overrideConfiguration != null + ? overrideConfiguration : Configuration.EMPTY; mScale = scale; int hash = 17; hash = 31 * hash + (mResDir == null ? 0 : mResDir.hashCode()); hash = 31 * hash + mDisplayId; - hash = 31 * hash + (mOverrideConfiguration != null - ? mOverrideConfiguration.hashCode() : 0); + hash = 31 * hash + mOverrideConfiguration.hashCode(); hash = 31 * hash + Float.floatToIntBits(mScale); mHash = hash; } public boolean hasOverrideConfiguration() { - return mOverrideConfiguration != null - && !Configuration.EMPTY.equals(mOverrideConfiguration); + return !Configuration.EMPTY.equals(mOverrideConfiguration); } @Override @@ -66,13 +68,8 @@ public final class ResourcesKey { if (mDisplayId != peer.mDisplayId) { return false; } - if (mOverrideConfiguration != peer.mOverrideConfiguration) { - if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) { - return false; - } - if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) { - return false; - } + if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) { + return false; } if (mScale != peer.mScale) { return false; diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java index d456b5eeaefb..5d405f92e380 100644 --- a/core/java/android/hardware/SensorManager.java +++ b/core/java/android/hardware/SensorManager.java @@ -19,7 +19,6 @@ package android.hardware; import android.annotation.SystemApi; import android.os.Build; import android.os.Handler; -import android.os.SystemClock; import android.util.Log; import android.util.SparseArray; @@ -1632,7 +1631,7 @@ public abstract class SensorManager { if (values == null) { throw new IllegalArgumentException("sensor data cannot be null"); } - int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.MNC); + int expectedNumValues = Sensor.getMaxLengthValuesArray(sensor, Build.VERSION_CODES.M); if (values.length != expectedNumValues) { throw new IllegalArgumentException ("Wrong number of values for sensor " + sensor.getName() + " actual=" + values.length + " expected=" + diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index 46cafadd2bdd..46ffe365d66c 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -138,6 +138,45 @@ public abstract class CameraCaptureSession implements AutoCloseable { */ public abstract void prepare(@NonNull Surface surface) throws CameraAccessException; + + /** + * <p>Free all buffers allocated for an output Surface.</p> + * + * <p>Normally, once allocated, the image buffers for a given output Surface remain allocated + * for the lifetime of the capture session, to minimize latency of captures and to reduce + * memory allocation overhead.</p> + * + * <p>However, in some cases, it may be desirable for allocated buffers to be freed to reduce + * the application's memory consumption, if the particular output Surface will not be used by + * the application for some time.</p> + * + * <p>The tearDown() method can be used to perform this operation. After the call finishes, all + * unfilled image buffers will have been freed. Any future use of the target Surface may require + * allocation of additional buffers, as if the session had just been created. Buffers being + * held by the application (either explicitly as Image objects from ImageReader, or implicitly + * as the current texture in a SurfaceTexture or the current contents of a RS Allocation, will + * remain valid and allocated even when tearDown is invoked.</p> + * + * <p>A Surface that has had tearDown() called on it is eligible to have prepare() invoked on it + * again even if it was used as a request target before the tearDown() call, as long as it + * doesn't get used as a target of a request between the tearDown() and prepare() calls.</p> + * + * @param surface the output Surface for which buffers should be freed. Must be one of the + * the output Surfaces used to create this session. + * + * @throws CameraAccessException if the camera device is no longer connected or has + * encountered a fatal error. + * @throws IllegalStateException if this session is no longer active, either because the session + * was explicitly closed, a new session has been created + * or the camera device has been closed. + * @throws IllegalArgumentException if the Surface is invalid, not part of this Session, or has + * already been used as a target of a CaptureRequest in this + * session or immediately prior sessions. + * + * @hide + */ + public abstract void tearDown(@NonNull Surface surface) throws CameraAccessException; + /** * <p>Submit a request for an image to be captured by the camera device.</p> * diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index c36683bfb9c1..c580083b94d9 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -173,6 +173,28 @@ public abstract class CameraMetadata<TKey> { } } + ArrayList<TKey> vendorKeys = CameraMetadataNative.getAllVendorKeys(keyClass); + + if (vendorKeys != null) { + for (TKey k : vendorKeys) { + String keyName; + if (k instanceof CaptureRequest.Key<?>) { + keyName = ((CaptureRequest.Key<?>) k).getName(); + } else if (k instanceof CaptureResult.Key<?>) { + keyName = ((CaptureResult.Key<?>) k).getName(); + } else if (k instanceof CameraCharacteristics.Key<?>) { + keyName = ((CameraCharacteristics.Key<?>) k).getName(); + } else { + continue; + } + + if (filterTags == null || Arrays.binarySearch(filterTags, + CameraMetadataNative.getTag(keyName)) >= 0) { + keyList.add(k); + } + } + } + return keyList; } @@ -1994,8 +2016,9 @@ public abstract class CameraMetadata<TKey> { public static final int EDGE_MODE_OFF = 0; /** - * <p>Apply edge enhancement at a quality level that does not slow down frame rate relative to sensor - * output</p> + * <p>Apply edge enhancement at a quality level that does not slow down frame rate + * relative to sensor output. It may be the same as OFF if edge enhancement will + * slow down frame rate relative to sensor.</p> * @see CaptureRequest#EDGE_MODE */ public static final int EDGE_MODE_FAST = 1; @@ -2117,7 +2140,8 @@ public abstract class CameraMetadata<TKey> { /** * <p>Noise reduction is applied without reducing frame rate relative to sensor - * output.</p> + * output. It may be the same as OFF if noise reduction will reduce frame rate + * relative to sensor.</p> * @see CaptureRequest#NOISE_REDUCTION_MODE */ public static final int NOISE_REDUCTION_MODE_FAST = 1; diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index a136d0ff4903..e965d654fcc7 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -1584,8 +1584,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * will be applied. HIGH_QUALITY mode indicates that the * camera device will use the highest-quality enhancement algorithms, * even if it slows down capture rate. FAST means the camera device will - * not slow down capture rate when applying edge enhancement. Every output stream will - * have a similar amount of enhancement applied.</p> + * not slow down capture rate when applying edge enhancement. FAST may be the same as OFF if + * edge enhancement will slow down capture rate. Every output stream will have a similar + * amount of enhancement applied.</p> * <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular * buffer of high-resolution images during preview and reprocess image(s) from that buffer * into a final capture when triggered by the user. In this mode, the camera device applies @@ -1594,7 +1595,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * since those will be reprocessed later if necessary.</p> * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera * device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively. - * The camera device may adjust its internal noise reduction parameters for best + * The camera device may adjust its internal edge enhancement parameters for best * image quality based on the {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor}, if it is set.</p> * <p><b>Possible values:</b> * <ul> @@ -2003,8 +2004,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * will be applied. HIGH_QUALITY mode indicates that the camera device * will use the highest-quality noise filtering algorithms, * even if it slows down capture rate. FAST means the camera device will not - * slow down capture rate when applying noise filtering. Every output stream will - * have a similar amount of enhancement applied.</p> + * slow down capture rate when applying noise filtering. FAST may be the same as MINIMAL if + * MINIMAL is listed, or the same as OFF if any noise filtering will slow down capture rate. + * Every output stream will have a similar amount of enhancement applied.</p> * <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular * buffer of high-resolution images during preview and reprocess image(s) from that buffer * into a final capture when triggered by the user. In this mode, the camera device applies diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index f7cf1850ab46..d5511c122c3d 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -2095,8 +2095,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * will be applied. HIGH_QUALITY mode indicates that the * camera device will use the highest-quality enhancement algorithms, * even if it slows down capture rate. FAST means the camera device will - * not slow down capture rate when applying edge enhancement. Every output stream will - * have a similar amount of enhancement applied.</p> + * not slow down capture rate when applying edge enhancement. FAST may be the same as OFF if + * edge enhancement will slow down capture rate. Every output stream will have a similar + * amount of enhancement applied.</p> * <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular * buffer of high-resolution images during preview and reprocess image(s) from that buffer * into a final capture when triggered by the user. In this mode, the camera device applies @@ -2105,7 +2106,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * since those will be reprocessed later if necessary.</p> * <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera * device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively. - * The camera device may adjust its internal noise reduction parameters for best + * The camera device may adjust its internal edge enhancement parameters for best * image quality based on the {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor}, if it is set.</p> * <p><b>Possible values:</b> * <ul> @@ -2786,8 +2787,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * will be applied. HIGH_QUALITY mode indicates that the camera device * will use the highest-quality noise filtering algorithms, * even if it slows down capture rate. FAST means the camera device will not - * slow down capture rate when applying noise filtering. Every output stream will - * have a similar amount of enhancement applied.</p> + * slow down capture rate when applying noise filtering. FAST may be the same as MINIMAL if + * MINIMAL is listed, or the same as OFF if any noise filtering will slow down capture rate. + * Every output stream will have a similar amount of enhancement applied.</p> * <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular * buffer of high-resolution images during preview and reprocess image(s) from that buffer * into a final capture when triggered by the user. In this mode, the camera device applies diff --git a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl index 1574f93a81ad..7cb367329dbe 100644 --- a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl +++ b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl @@ -100,4 +100,6 @@ interface ICameraDeviceUser int flush(out LongParcelable lastFrameNumber); int prepare(int streamId); + + int tearDown(int streamId); } diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java index 3c19cd202fe2..d325c77de0ef 100644 --- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java @@ -146,6 +146,11 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession } @Override + public void tearDown(Surface surface) throws CameraAccessException { + mDeviceImpl.tearDown(surface); + } + + @Override public synchronized int capture(CaptureRequest request, CaptureCallback callback, Handler handler) throws CameraAccessException { if (request == null) { diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java index d732535af7d9..a920e2b37361 100644 --- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java @@ -169,6 +169,11 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl } @Override + public void tearDown(Surface surface) throws CameraAccessException { + mSessionImpl.tearDown(surface); + } + + @Override public int capture(CaptureRequest request, CaptureCallback listener, Handler handler) throws CameraAccessException { throw new UnsupportedOperationException("Constrained high speed session doesn't support" diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index c594228509e6..91d623eae5f9 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -679,6 +679,31 @@ public class CameraDeviceImpl extends CameraDevice { } } + public void tearDown(Surface surface) throws CameraAccessException { + if (surface == null) throw new IllegalArgumentException("Surface is null"); + + synchronized(mInterfaceLock) { + int streamId = -1; + for (int i = 0; i < mConfiguredOutputs.size(); i++) { + if (surface == mConfiguredOutputs.valueAt(i).getSurface()) { + streamId = mConfiguredOutputs.keyAt(i); + break; + } + } + if (streamId == -1) { + throw new IllegalArgumentException("Surface is not part of this session"); + } + try { + mRemoteDevice.tearDown(streamId); + } catch (CameraRuntimeException e) { + throw e.asChecked(); + } catch (RemoteException e) { + // impossible + return; + } + } + } + public int capture(CaptureRequest request, CaptureCallback callback, Handler handler) throws CameraAccessException { if (DEBUG) { diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java index 7e50fd9f623a..12a2910b2055 100644 --- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java +++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java @@ -1078,6 +1078,7 @@ public class CameraMetadataNative implements Parcelable { private native synchronized void nativeWriteValues(int tag, byte[] src); private native synchronized void nativeDump() throws IOException; // dump to ALOGD + private static native ArrayList nativeGetAllVendorKeys(Class keyClass); private static native int nativeGetTagFromKey(String keyName) throws IllegalArgumentException; private static native int nativeGetTypeFromTag(int tag) @@ -1113,6 +1114,19 @@ public class CameraMetadataNative implements Parcelable { return nativeIsEmpty(); } + + /** + * Return a list containing keys of the given key class for all defined vendor tags. + * + * @hide + */ + public static <K> ArrayList<K> getAllVendorKeys(Class<K> keyClass) { + if (keyClass == null) { + throw new NullPointerException(); + } + return (ArrayList<K>) nativeGetAllVendorKeys(keyClass); + } + /** * Convert a key string into the equivalent native tag. * diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java index f5314da70520..e20eaa778ab9 100644 --- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java +++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java @@ -636,6 +636,20 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { return CameraBinderDecorator.NO_ERROR; } + public int tearDown(int streamId) { + if (DEBUG) { + Log.d(TAG, "tearDown called."); + } + if (mLegacyDevice.isClosed()) { + Log.e(TAG, "Cannot tear down stream, device has been closed."); + return CameraBinderDecorator.ENODEV; + } + + // LEGACY doesn't support actual teardown, so just a no-op + + return CameraBinderDecorator.NO_ERROR; + } + @Override public IBinder asBinder() { // This is solely intended to be used for in-process binding. diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index c5f142a81487..ee3704704425 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -321,6 +321,14 @@ public class FingerprintManager { * Called when a fingerprint is valid but not recognized. */ public void onAuthenticationFailed() { } + + /** + * Called when a fingerprint image has been acquired, but wasn't processed yet. + * + * @param acquireInfo one of FINGERPRINT_ACQUIRED_* constants + * @hide + */ + public void onAuthenticationAcquired(int acquireInfo) {} }; /** @@ -737,9 +745,13 @@ public class FingerprintManager { } private void sendAcquiredResult(long deviceId, int acquireInfo) { + if (mAuthenticationCallback != null) { + mAuthenticationCallback.onAuthenticationAcquired(acquireInfo); + } final String msg = getAcquiredString(acquireInfo); - if (msg == null) return; - + if (msg == null) { + return; + } if (mEnrollmentCallback != null) { mEnrollmentCallback.onEnrollmentHelp(acquireInfo, msg); } else if (mAuthenticationCallback != null) { diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl index 80c7b1a220f4..6e4c9de1c8ef 100644 --- a/core/java/android/hardware/usb/IUsbManager.aidl +++ b/core/java/android/hardware/usb/IUsbManager.aidl @@ -97,9 +97,6 @@ interface IUsbManager */ void setUsbDataUnlocked(boolean unlock); - /* Returns true iff sensitive user data is exposed on the USB connection. */ - boolean isUsbDataUnlocked(); - /* Allow USB debugging from the attached host. If alwaysAllow is true, add the * the public key to list of host keys that the user has approved. */ diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index c88f2133155e..3b3ee52929e5 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -520,21 +520,6 @@ public class UsbManager { } /** - * Returns {@code true} iff access to sensitive USB data is currently allowed when - * in device mode. - * - * {@hide} - */ - public boolean isUsbDataUnlocked() { - try { - return mService.isUsbDataUnlocked(); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException in isUsbDataUnlocked", e); - } - return false; - } - - /** * Returns a list of physical USB ports on the device. * <p> * This list is guaranteed to contain all dual-role USB Type C ports but it might diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java index b039fc762245..a2c1d1841c20 100644 --- a/core/java/android/inputmethodservice/ExtractEditText.java +++ b/core/java/android/inputmethodservice/ExtractEditText.java @@ -103,8 +103,12 @@ public class ExtractEditText extends EditText { } @Override public boolean onTextContextMenuItem(int id) { - // Select all shouldn't be handled by the original edit text, but by the extracted one. - if (id != android.R.id.selectAll && mIME != null && mIME.onExtractTextContextMenuItem(id)) { + // Select all and Replace text shouldn't be handled by the original edit text, but by the + // extracted one. + if (id == android.R.id.selectAll || id == android.R.id.replaceText) { + return super.onTextContextMenuItem(id); + } + if (mIME != null && mIME.onExtractTextContextMenuItem(id)) { // Mode was started on Extracted, needs to be stopped here. // Cut will change the text, which stops selection mode. if (id == android.R.id.copy || id == android.R.id.paste) stopTextActionMode(); diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 4d45076a469e..605acb08ff0c 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -22,6 +22,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.NetworkUtils; import android.os.Binder; import android.os.Build.VERSION_CODES; @@ -33,6 +34,7 @@ import android.os.INetworkManagementService; import android.os.Looper; import android.os.Message; import android.os.Messenger; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; @@ -490,6 +492,8 @@ public class ConnectivityManager { */ private static ConnectivityManager sInstance; + private final Context mContext; + private INetworkManagementService mNMService; /** @@ -892,9 +896,11 @@ public class ConnectivityManager { * * @deprecated Deprecated in favor of the cleaner * {@link #requestNetwork(NetworkRequest, NetworkCallback)} API. - * @removed + * In {@link VERSION_CODES#M}, and above, this method is unsupported and will + * throw {@code UnsupportedOperationException} if called. */ public int startUsingNetworkFeature(int networkType, String feature) { + checkLegacyRoutingApiAccess(); NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature); if (netCap == null) { Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " + @@ -939,10 +945,12 @@ public class ConnectivityManager { * implementation+feature combination, except that the value {@code -1} * always indicates failure. * - * @deprecated Deprecated in favor of the cleaner {@link unregisterNetworkCallback} API. - * @removed + * @deprecated Deprecated in favor of the cleaner {@link #unregisterNetworkCallback} API. + * In {@link VERSION_CODES#M}, and above, this method is unsupported and will + * throw {@code UnsupportedOperationException} if called. */ public int stopUsingNetworkFeature(int networkType, String feature) { + checkLegacyRoutingApiAccess(); NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature); if (netCap == null) { Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " + @@ -1185,7 +1193,8 @@ public class ConnectivityManager { * @deprecated Deprecated in favor of the * {@link #requestNetwork(NetworkRequest, NetworkCallback)}, * {@link #bindProcessToNetwork} and {@link Network#getSocketFactory} API. - * @removed + * In {@link VERSION_CODES#M}, and above, this method is unsupported and will + * throw {@code UnsupportedOperationException} if called. */ public boolean requestRouteToHost(int networkType, int hostAddress) { return requestRouteToHostAddress(networkType, NetworkUtils.intToInetAddress(hostAddress)); @@ -1204,9 +1213,9 @@ public class ConnectivityManager { * @hide * @deprecated Deprecated in favor of the {@link #requestNetwork} and * {@link #bindProcessToNetwork} API. - * @removed */ public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) { + checkLegacyRoutingApiAccess(); try { return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress()); } catch (RemoteException e) { @@ -1385,7 +1394,8 @@ public class ConnectivityManager { /** * {@hide} */ - public ConnectivityManager(IConnectivityManager service) { + public ConnectivityManager(Context context, IConnectivityManager service) { + mContext = checkNotNull(context, "missing context"); mService = checkNotNull(service, "missing IConnectivityManager"); sInstance = this; } @@ -2672,6 +2682,34 @@ public class ConnectivityManager { return new Network(netId); } + private void unsupportedStartingFrom(int version) { + if (Process.myUid() == Process.SYSTEM_UID) { + // The getApplicationInfo() call we make below is not supported in system context, and + // we want to allow the system to use these APIs anyway. + return; + } + + if (mContext.getApplicationInfo().targetSdkVersion >= version) { + throw new UnsupportedOperationException( + "This method is not supported in target SDK version " + version + " and above"); + } + } + + // Checks whether the calling app can use the legacy routing API (startUsingNetworkFeature, + // stopUsingNetworkFeature, requestRouteToHost), and if not throw UnsupportedOperationException. + // TODO: convert the existing system users (Tethering, GpsLocationProvider) to the new APIs and + // remove these exemptions. Note that this check is not secure, and apps can still access these + // functions by accessing ConnectivityService directly. However, it should be clear that doing + // so is unsupported and may break in the future. http://b/22728205 + private void checkLegacyRoutingApiAccess() { + if (mContext.checkCallingOrSelfPermission("com.android.permission.INJECT_OMADM_SETTINGS") + == PackageManager.PERMISSION_GRANTED) { + return; + } + + unsupportedStartingFrom(VERSION_CODES.M); + } + /** * Binds host resolutions performed by this process to {@code network}. * {@link #bindProcessToNetwork} takes precedence over this setting. diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index cfd5bf159671..c4de4a21e093 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -662,6 +662,17 @@ public final class LinkProperties implements Parcelable { } /** + * Returns true if this link or any of its stacked interfaces has an IPv4 address. + * + * @return {@code true} if there is an IPv4 address, {@code false} otherwise. + */ + private boolean hasIPv4AddressOnInterface(String iface) { + return (mIfaceName.equals(iface) && hasIPv4Address()) || + (iface != null && mStackedLinks.containsKey(iface) && + mStackedLinks.get(iface).hasIPv4Address()); + } + + /** * Returns true if this link has a global preferred IPv6 address. * * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise. @@ -792,7 +803,7 @@ public final class LinkProperties implements Parcelable { if (ip instanceof Inet4Address) { // For IPv4, it suffices for now to simply have any address. - return hasIPv4Address(); + return hasIPv4AddressOnInterface(bestRoute.getInterface()); } else if (ip instanceof Inet6Address) { if (ip.isLinkLocalAddress()) { // For now, just make sure link-local destinations have diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index e6fc1ea293a0..808a8827a076 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -148,6 +148,13 @@ public abstract class NetworkAgent extends Handler { */ public static final int CMD_REQUEST_BANDWIDTH_UPDATE = BASE + 10; + /** + * Sent by ConnectivityService to the NeworkAgent to inform the agent to avoid + * automatically reconnecting to this network (e.g. via autojoin). Happens + * when user selects "No" option on the "Stay connected?" dialog box. + */ + public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 11; + public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni, NetworkCapabilities nc, LinkProperties lp, int score) { this(looper, context, logTag, ni, nc, lp, score, null); @@ -240,6 +247,11 @@ public abstract class NetworkAgent extends Handler { } case CMD_SAVE_ACCEPT_UNVALIDATED: { saveAcceptUnvalidated(msg.arg1 != 0); + break; + } + case CMD_PREVENT_AUTOMATIC_RECONNECT: { + preventAutomaticReconnect(); + break; } } } @@ -365,6 +377,15 @@ public abstract class NetworkAgent extends Handler { protected void saveAcceptUnvalidated(boolean accept) { } + /** + * Called when the user asks to not stay connected to this network because it was found to not + * provide Internet access. Usually followed by call to {@code unwanted}. The transport is + * responsible for making sure the device does not automatically reconnect to the same network + * after the {@code unwanted} call. + */ + protected void preventAutomaticReconnect() { + } + protected void log(String s) { Log.d(LOG_TAG, "NetworkAgent: " + s); } diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 0154eb518b51..29b063a49f28 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -661,6 +661,7 @@ public final class NetworkCapabilities implements Parcelable { case NET_CAPABILITY_TRUSTED: capabilities += "TRUSTED"; break; case NET_CAPABILITY_NOT_VPN: capabilities += "NOT_VPN"; break; case NET_CAPABILITY_VALIDATED: capabilities += "VALIDATED"; break; + case NET_CAPABILITY_CAPTIVE_PORTAL: capabilities += "CAPTIVE_PORTAL"; break; } if (++i < types.length) capabilities += "&"; } diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index 243ddf787727..521df280c2c4 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -292,7 +292,9 @@ public abstract class AsyncTask<Params, Progress, Result> { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked - return postResult(doInBackground(mParams)); + Result result = doInBackground(mParams); + Binder.flushPendingCommands(); + return postResult(result); } }; diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index ecb7f5a200f2..80169a956f41 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -2615,7 +2615,9 @@ public abstract class BatteryStats implements Parcelable { getMobileRadioActiveAdjustedTime(which) / 1000, interactiveTime / 1000, powerSaveModeEnabledTime / 1000, connChanges, deviceIdleModeEnabledTime / 1000, getDeviceIdleModeEnabledCount(which), deviceIdlingTime / 1000, - getDeviceIdlingCount(which)); + getDeviceIdlingCount(which), + getMobileRadioActiveCount(which), + getMobileRadioActiveUnknownTime(which) / 1000); // Dump screen brightness stats Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS]; diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index b2ced7fbca61..a0162f7f6cef 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -622,7 +622,7 @@ public class Build { /** * M comes after L. */ - public static final int MNC = 23; + public static final int M = 23; } /** The type of build, like "user" or "eng". */ diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 208085624e3b..64d6da57718f 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -80,7 +80,8 @@ public class Environment { } public File[] getExternalDirs() { - final StorageVolume[] volumes = StorageManager.getVolumeList(mUserId); + final StorageVolume[] volumes = StorageManager.getVolumeList(mUserId, + StorageManager.FLAG_FOR_WRITE); final File[] files = new File[volumes.length]; for (int i = 0; i < volumes.length; i++) { files[i] = volumes[i].getPathFile(); diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 864225a0df12..af4c2bc23658 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -16,6 +16,7 @@ package android.os; +import android.annotation.NonNull; import android.provider.DocumentsContract.Document; import android.system.ErrnoException; import android.system.Os; @@ -69,6 +70,8 @@ public class FileUtils { /** Regular expression for safe filenames: no spaces or metacharacters */ private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+"); + private static final File[] EMPTY = new File[0]; + /** * Set owner and mode of of given {@link File}. * @@ -634,4 +637,13 @@ public class FileUtils { return new File(parent, name + "." + ext); } } + + public static @NonNull File[] listFilesOrEmpty(File dir) { + File[] res = dir.listFiles(); + if (res != null) { + return res; + } else { + return EMPTY; + } + } } diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java index 73a0f658f5f0..2c21d135e2b8 100644 --- a/core/java/android/os/IBinder.java +++ b/core/java/android/os/IBinder.java @@ -149,7 +149,14 @@ public interface IBinder { * processes. */ int FLAG_ONEWAY = 0x00000001; - + + /** + * Limit that should be placed on IPC sizes to keep them safely under the + * transaction buffer limit. + * @hide + */ + public static final int MAX_IPC_SIZE = 64 * 1024; + /** * Get the canonical name of the interface supported by this binder. */ diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl index b7688524a78a..d3eec1ed2198 100644 --- a/core/java/android/os/IDeviceIdleController.aidl +++ b/core/java/android/os/IDeviceIdleController.aidl @@ -29,5 +29,6 @@ interface IDeviceIdleController { boolean isPowerSaveWhitelistApp(String name); void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason); long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason); + long addPowerSaveTempWhitelistAppForSms(String name, int userId, String reason); void exitIdle(String reason); } diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index b104135756c9..83a1993775de 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -45,7 +45,9 @@ public class UserManager { private final Context mContext; /** - * Specifies if a user is disallowed from adding and removing accounts. + * Specifies if a user is disallowed from adding and removing accounts, unless they are + * {@link android.accounts.AccountManager#addAccountExplicitly programmatically} added by + * Authenticator. * The default value is <code>false</code>. * * <p/>Key for user restrictions. @@ -178,7 +180,7 @@ public class UserManager { * Specifies if a user is disallowed from configuring VPN. * The default value is <code>false</code>. * This restriction has an effect in a managed profile only from - * {@link android.os.Build.VERSION_CODES#MNC} + * {@link android.os.Build.VERSION_CODES#M} * * <p/>Key for user restrictions. * <p/>Type: Boolean diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index c3b098beb422..fce09dd4c80c 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -758,7 +758,7 @@ public interface IMountService extends IInterface { return _result; } - public StorageVolume[] getVolumeList(int uid, String packageName) + public StorageVolume[] getVolumeList(int uid, String packageName, int flags) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); @@ -767,6 +767,7 @@ public interface IMountService extends IInterface { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(uid); _data.writeString(packageName); + _data.writeInt(flags); mRemote.transact(Stub.TRANSACTION_getVolumeList, _data, _reply, 0); _reply.readException(); _result = _reply.createTypedArray(StorageVolume.CREATOR); @@ -1609,7 +1610,8 @@ public interface IMountService extends IInterface { data.enforceInterface(DESCRIPTOR); int uid = data.readInt(); String packageName = data.readString(); - StorageVolume[] result = getVolumeList(uid, packageName); + int _flags = data.readInt(); + StorageVolume[] result = getVolumeList(uid, packageName, _flags); reply.writeNoException(); reply.writeTypedArray(result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); return true; @@ -2059,7 +2061,7 @@ public interface IMountService extends IInterface { /** * Returns list of all mountable volumes. */ - public StorageVolume[] getVolumeList(int uid, String packageName) throws RemoteException; + public StorageVolume[] getVolumeList(int uid, String packageName, int flags) throws RemoteException; /** * Gets the path on the filesystem for the ASEC container itself. diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index b2cec60c0412..d1f37436e4ba 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -86,6 +86,9 @@ public class StorageManager { /** {@hide} */ public static final int DEBUG_FORCE_ADOPTABLE = 1 << 0; + /** {@hide} */ + public static final int FLAG_FOR_WRITE = 1 << 0; + private final Context mContext; private final ContentResolver mResolver; @@ -812,7 +815,7 @@ public class StorageManager { /** {@hide} */ public static @Nullable StorageVolume getStorageVolume(File file, int userId) { - return getStorageVolume(getVolumeList(userId), file); + return getStorageVolume(getVolumeList(userId, 0), file); } /** {@hide} */ @@ -852,11 +855,11 @@ public class StorageManager { /** {@hide} */ public @NonNull StorageVolume[] getVolumeList() { - return getVolumeList(mContext.getUserId()); + return getVolumeList(mContext.getUserId(), 0); } /** {@hide} */ - public static @NonNull StorageVolume[] getVolumeList(int userId) { + public static @NonNull StorageVolume[] getVolumeList(int userId, int flags) { final IMountService mountService = IMountService.Stub.asInterface( ServiceManager.getService("mount")); try { @@ -877,7 +880,7 @@ public class StorageManager { if (uid <= 0) { return new StorageVolume[0]; } - return mountService.getVolumeList(uid, packageName); + return mountService.getVolumeList(uid, packageName, flags); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index 8d603a17f186..ef54d84fdebf 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -46,6 +46,19 @@ import java.util.Objects; * Information about a storage volume that may be mounted. A volume may be a * partition on a physical {@link DiskInfo}, an emulated volume above some other * storage medium, or a standalone container like an ASEC or OBB. + * <p> + * Volumes may be mounted with various flags: + * <ul> + * <li>{@link #MOUNT_FLAG_PRIMARY} means the volume provides primary external + * storage, historically found at {@code /sdcard}. + * <li>{@link #MOUNT_FLAG_VISIBLE} means the volume is visible to third-party + * apps for direct filesystem access. The system should send out relevant + * storage broadcasts and index any media on visible volumes. Visible volumes + * are considered a more stable part of the device, which is why we take the + * time to index them. In particular, transient volumes like USB OTG devices + * <em>should not</em> be marked as visible; their contents should be surfaced + * to apps through the Storage Access Framework. + * </ul> * * @hide */ @@ -255,8 +268,23 @@ public class VolumeInfo implements Parcelable { return (mountFlags & MOUNT_FLAG_VISIBLE) != 0; } - public boolean isVisibleToUser(int userId) { - if (type == TYPE_PUBLIC && userId == this.mountUserId) { + public boolean isVisibleForRead(int userId) { + if (type == TYPE_PUBLIC) { + if (isPrimary() && mountUserId != userId) { + // Primary physical is only visible to single user + return false; + } else { + return isVisible(); + } + } else if (type == TYPE_EMULATED) { + return isVisible(); + } else { + return false; + } + } + + public boolean isVisibleForWrite(int userId) { + if (type == TYPE_PUBLIC && mountUserId == userId) { return isVisible(); } else if (type == TYPE_EMULATED) { return isVisible(); @@ -276,7 +304,7 @@ public class VolumeInfo implements Parcelable { public File getPathForUser(int userId) { if (path == null) { return null; - } else if (type == TYPE_PUBLIC && userId == this.mountUserId) { + } else if (type == TYPE_PUBLIC) { return new File(path); } else if (type == TYPE_EMULATED) { return new File(path, Integer.toString(userId)); @@ -306,6 +334,7 @@ public class VolumeInfo implements Parcelable { final boolean allowMassStorage = false; final String envState = reportUnmounted ? Environment.MEDIA_UNMOUNTED : getEnvironmentForState(state); + File userPath = getPathForUser(userId); if (userPath == null) { userPath = new File("/dev/null"); diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index 23555d6d998d..4f880b1275e4 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -421,7 +421,7 @@ public class CallLog { int presentation, int callType, int features, PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage) { return addCall(ci, context, number, presentation, callType, features, accountHandle, - start, duration, dataUsage, false); + start, duration, dataUsage, false, false); } @@ -450,8 +450,41 @@ public class CallLog { * {@hide} */ public static Uri addCall(CallerInfo ci, Context context, String number, + int presentation, int callType, int features, PhoneAccountHandle accountHandle, + long start, int duration, Long dataUsage, boolean addForAllUsers) { + return addCall(ci, context, number, presentation, callType, features, accountHandle, + start, duration, dataUsage, addForAllUsers, false); + } + + /** + * Adds a call to the call log. + * + * @param ci the CallerInfo object to get the target contact from. Can be null + * if the contact is unknown. + * @param context the context used to get the ContentResolver + * @param number the phone number to be added to the calls db + * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which + * is set by the network and denotes the number presenting rules for + * "allowed", "payphone", "restricted" or "unknown" + * @param callType enumerated values for "incoming", "outgoing", or "missed" + * @param features features of the call (e.g. Video). + * @param accountHandle The accountHandle object identifying the provider of the call + * @param start time stamp for the call in milliseconds + * @param duration call duration in seconds + * @param dataUsage data usage for the call in bytes, null if data usage was not tracked for + * the call. + * @param addForAllUsers If true, the call is added to the call log of all currently + * running users. The caller must have the MANAGE_USERS permission if this is true. + * @param is_read Flag to show if the missed call log has been read by the user or not. + * Used for call log restore of missed calls. + * + * @result The URI of the call log entry belonging to the user that made or received this + * call. + * {@hide} + */ + public static Uri addCall(CallerInfo ci, Context context, String number, int presentation, int callType, int features, PhoneAccountHandle accountHandle, - long start, int duration, Long dataUsage, boolean addForAllUsers) { + long start, int duration, Long dataUsage, boolean addForAllUsers, boolean is_read) { final ContentResolver resolver = context.getContentResolver(); int numberPresentation = PRESENTATION_ALLOWED; @@ -516,7 +549,7 @@ public class CallLog { values.put(NEW, Integer.valueOf(1)); if (callType == MISSED_TYPE) { - values.put(IS_READ, Integer.valueOf(0)); + values.put(IS_READ, Integer.valueOf(is_read ? 1 : 0)); } if ((ci != null) && (ci.contactIdOrZero > 0)) { diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index d547a604eb8b..8ce1cbf43f7d 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -5957,9 +5957,7 @@ public final class ContactsContract { */ public static final CharSequence getTypeLabel(Resources res, int type, CharSequence label) { - if (type == TYPE_CUSTOM) { - return (label != null ? label : ""); - } else if (type == TYPE_ASSISTANT && !TextUtils.isEmpty(label)) { + if ((type == TYPE_CUSTOM || type == TYPE_ASSISTANT) && !TextUtils.isEmpty(label)) { return label; } else { final int labelRes = getTypeLabelResource(type); diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java index 6979beefa24c..5a341fce41cd 100644 --- a/core/java/android/provider/DocumentsProvider.java +++ b/core/java/android/provider/DocumentsProvider.java @@ -640,7 +640,7 @@ public abstract class DocumentsProvider extends ContentProvider { final Bundle out = new Bundle(); try { if (METHOD_CREATE_DOCUMENT.equals(method)) { - enforceWritePermissionInner(documentUri, null); + enforceWritePermissionInner(documentUri, getCallingPackage(), null); final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE); final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME); @@ -654,7 +654,7 @@ public abstract class DocumentsProvider extends ContentProvider { out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri); } else if (METHOD_RENAME_DOCUMENT.equals(method)) { - enforceWritePermissionInner(documentUri, null); + enforceWritePermissionInner(documentUri, getCallingPackage(), null); final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME); final String newDocumentId = renameDocument(documentId, displayName); @@ -678,7 +678,7 @@ public abstract class DocumentsProvider extends ContentProvider { } } else if (METHOD_DELETE_DOCUMENT.equals(method)) { - enforceWritePermissionInner(documentUri, null); + enforceWritePermissionInner(documentUri, getCallingPackage(), null); deleteDocument(documentId); // Document no longer exists, clean up any grants diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index e63fb0464890..9babf4309fab 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -284,7 +284,7 @@ public final class MediaStore { * 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 + * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} 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}. @@ -338,7 +338,7 @@ public final class MediaStore { * 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 + * <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#M M} 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}. diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index fff355b452ce..6f98788976bf 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -19,6 +19,9 @@ package android.provider; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; +import android.app.ActivityThread; +import android.app.AppOpsManager; +import android.app.Application; import android.app.SearchManager; import android.app.WallpaperManager; import android.content.ComponentName; @@ -39,6 +42,7 @@ import android.net.ConnectivityManager; import android.net.Uri; import android.net.wifi.WifiManager; import android.os.BatteryManager; +import android.os.Binder; import android.os.Bundle; import android.os.DropBoxManager; import android.os.IBinder; @@ -562,13 +566,14 @@ public final class Settings { "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS"; /** - * Activity Action: Show settings to toggle permission to draw on top of - * other apps. + * Activity Action: Show screen for controlling which apps can 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. + * Input: Optionally, the Intent's data URI can specify the application package name to + * directly invoke the management GUI specific to the package name. For example + * "package:com.my.app". * <p> * Output: Nothing. */ @@ -577,13 +582,15 @@ public final class Settings { "android.settings.action.MANAGE_OVERLAY_PERMISSION"; /** - * Activity Action: Show settings to toggle apps' capablity to - * to read/write system settings. + * Activity Action: Show screen for controlling which apps are allowed to write/modify + * system settings. * <p> * In some cases, a matching Activity may not exist, so ensure you * safeguard against this. * <p> - * Input: Nothing. + * Input: Optionally, the Intent's data URI can specify the application package name to + * directly invoke the management GUI specific to the package name. For example + * "package:com.my.app". * <p> * Output: Nothing. */ @@ -1384,6 +1391,23 @@ public final class Settings { } /** + * An app can use this method to check if it is currently allowed to draw on top of other + * apps. In order to be allowed to do so, an app must first declare the + * {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission in its manifest. If it + * is currently disallowed, it can prompt the user to grant it this capability through a + * management UI by sending an Intent with action + * {@link android.provider.Settings#ACTION_MANAGE_OVERLAY_PERMISSION}. + * + * @param context A context + * @return true if the calling app can draw on top of other apps, false otherwise. + */ + public static boolean canDrawOverlays(Context context) { + int uid = Binder.getCallingUid(); + return Settings.isCallingPackageAllowedToDrawOverlays(context, uid, Settings + .getPackageNameForUid(context, uid), false); + } + + /** * System settings, containing miscellaneous system preferences. This * table holds simple name/value pairs. There are convenience * functions for accessing individual settings entries. @@ -3656,6 +3680,23 @@ public final class Settings { @Deprecated public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS = Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS; + + /** + * An app can use this method to check if it is currently allowed to write or modify system + * settings. In order to gain write access to the system settings, an app must declare the + * {@link android.Manifest.permission#WRITE_SETTINGS} permission in its manifest. If it is + * currently disallowed, it can prompt the user to grant it this capability through a + * management UI by sending an Intent with action + * {@link android.provider.Settings#ACTION_MANAGE_WRITE_SETTINGS}. + * + * @param context A context + * @return true if the calling app can write to system settings, false otherwise + */ + public static boolean canWrite(Context context) { + int uid = Binder.getCallingUid(); + return isCallingPackageAllowedToWriteSettings(context, uid, getPackageNameForUid( + context, uid), false); + } } /** @@ -3839,10 +3880,24 @@ public final class Settings { } } if (sLockSettings != null && !sIsSystemProcess) { - try { - return sLockSettings.getString(name, "0", userHandle); - } catch (RemoteException re) { - // Fall through + // No context; use the ActivityThread's context as an approximation for + // determining the target API level. + Application application = ActivityThread.currentApplication(); + + boolean isPreMnc = application != null + && application.getApplicationInfo() != null + && application.getApplicationInfo().targetSdkVersion + <= VERSION_CODES.LOLLIPOP_MR1; + if (isPreMnc) { + try { + return sLockSettings.getString(name, "0", userHandle); + } catch (RemoteException re) { + // Fall through + } + } else { + throw new SecurityException("Settings.Secure." + name + + " is deprecated and no longer accessible." + + " See API documentation for potential replacements."); } } } @@ -4378,14 +4433,19 @@ public final class Settings { * Whether autolock is enabled (0 = false, 1 = true) * * @deprecated Use {@link android.app.KeyguardManager} to determine the state and security - * level of the keyguard. + * level of the keyguard. Accessing this setting from an app that is targeting + * {@link VERSION_CODES#M} or later throws a {@code SecurityException}. */ @Deprecated public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock"; /** * Whether lock pattern is visible as user enters (0 = false, 1 = true) + * + * @deprecated Accessing this setting from an app that is targeting + * {@link VERSION_CODES#M} or later throws a {@code SecurityException}. */ + @Deprecated public static final String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern"; /** @@ -4395,6 +4455,8 @@ public final class Settings { * @deprecated Starting in {@link VERSION_CODES#JELLY_BEAN_MR1} the * lockscreen uses * {@link Settings.System#HAPTIC_FEEDBACK_ENABLED}. + * Accessing this setting from an app that is targeting + * {@link VERSION_CODES#M} or later throws a {@code SecurityException}. */ @Deprecated public static final String @@ -5658,7 +5720,6 @@ public final class Settings { MOUNT_UMS_AUTOSTART, MOUNT_UMS_PROMPT, MOUNT_UMS_NOTIFY_ENABLED, - UI_NIGHT_MODE, SLEEP_TIMEOUT, DOUBLE_TAP_TO_WAKE, }; @@ -7578,14 +7639,6 @@ public final class Settings { public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled"; /** - * Global override to disable VoLTE (independent of user setting) - * <p> - * Type: int (1 for disable VoLTE, 0 to use user configuration) - * @hide - */ - public static final String VOLTE_FEATURE_DISABLED = "volte_feature_disabled"; - - /** * Whether user can enable/disable LTE as a preferred network. A carrier might control * this via gservices, OMA-DM, carrier app, etc. * <p> @@ -8191,4 +8244,121 @@ public final class Settings { public static String getGTalkDeviceId(long androidId) { return "android-" + Long.toHexString(androidId); } + + /** + * Performs a strict and comprehensive check of whether a calling package is allowed to + * write/modify system settings, as the condition differs for pre-M, M+, and + * privileged/preinstalled apps. If the provided uid does not match the + * callingPackage, a negative result will be returned. + * @hide + */ + public static boolean isCallingPackageAllowedToWriteSettings(Context context, int uid, + String callingPackage, boolean throwException) { + return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, + callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, + android.Manifest.permission.WRITE_SETTINGS, false); + } + + /** + * Performs a strict and comprehensive check of whether a calling package is allowed to + * write/modify system settings, as the condition differs for pre-M, M+, and + * privileged/preinstalled apps. If the provided uid does not match the + * callingPackage, a negative result will be returned. + * + * Note: if the check is successful, the operation of this app will be updated to the + * current time. + * @hide + */ + public static boolean checkAndNoteWriteSettingsOperation(Context context, int uid, + String callingPackage, boolean throwException) { + return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, + callingPackage, throwException, AppOpsManager.OP_WRITE_SETTINGS, + android.Manifest.permission.WRITE_SETTINGS, true); + } + + /** + * Performs a strict and comprehensive check of whether a calling package is allowed to + * draw on top of other apps, as the conditions differs for pre-M, M+, and + * privileged/preinstalled apps. If the provided uid does not match the callingPackage, + * a negative result will be returned. + * @hide + */ + public static boolean isCallingPackageAllowedToDrawOverlays(Context context, int uid, + String callingPackage, boolean throwException) { + return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, + callingPackage, throwException, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, + android.Manifest.permission.SYSTEM_ALERT_WINDOW, false); + } + + /** + * Performs a strict and comprehensive check of whether a calling package is allowed to + * draw on top of other apps, as the conditions differs for pre-M, M+, and + * privileged/preinstalled apps. If the provided uid does not match the callingPackage, + * a negative result will be returned. + * + * Note: if the check is successful, the operation of this app will be updated to the + * current time. + * @hide + */ + public static boolean checkAndNoteDrawOverlaysOperation(Context context, int uid, String + callingPackage, boolean throwException) { + return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid, + callingPackage, throwException, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, + android.Manifest.permission.SYSTEM_ALERT_WINDOW, true); + } + + /** + * Helper method to perform a general and comprehensive check of whether an operation that is + * protected by appops can be performed by a caller or not. e.g. OP_SYSTEM_ALERT_WINDOW and + * OP_WRITE_SETTINGS + * @hide + */ + public static boolean isCallingPackageAllowedToPerformAppOpsProtectedOperation(Context context, + int uid, String callingPackage, boolean throwException, int appOpsOpCode, String + permissionName, boolean makeNote) { + if (callingPackage == null) { + return false; + } + + AppOpsManager appOpsMgr = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); + int mode = AppOpsManager.MODE_DEFAULT; + if (makeNote) { + mode = appOpsMgr.noteOpNoThrow(appOpsOpCode, uid, callingPackage); + } else { + mode = appOpsMgr.checkOpNoThrow(appOpsOpCode, uid, callingPackage); + } + + switch (mode) { + case AppOpsManager.MODE_ALLOWED: + return true; + case AppOpsManager.MODE_DEFAULT: + // this is the default operating mode after an app's installation + if(context.checkCallingOrSelfPermission(permissionName) == PackageManager + .PERMISSION_GRANTED) { + return true; + } + default: + // this is for all other cases trickled down here... + if (!throwException) { + return false; + } + } + throw new SecurityException(callingPackage + " was not granted " + + permissionName + " permission"); + } + + /** + * Retrieves a correponding package name for a given uid. It will query all + * packages that are associated with the given uid, but it will return only + * the zeroth result. + * Note: If package could not be found, a null is returned. + * @hide + */ + public static String getPackageNameForUid(Context context, int uid) { + String[] packages = context.getPackageManager().getPackagesForUid(uid); + if (packages == null) { + return null; + } + return packages[0]; + } } diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java index e1b5a6da90e4..76eaea9998cd 100644 --- a/core/java/android/provider/VoicemailContract.java +++ b/core/java/android/provider/VoicemailContract.java @@ -314,11 +314,16 @@ public class VoicemailContract { contentValues.put(Voicemails.IS_READ, voicemail.isRead() ? 1 : 0); PhoneAccountHandle phoneAccount = voicemail.getPhoneAccount(); - if (voicemail.getPhoneAccount() != null) { + if (phoneAccount != null) { contentValues.put(Voicemails.PHONE_ACCOUNT_COMPONENT_NAME, phoneAccount.getComponentName().flattenToString()); contentValues.put(Voicemails.PHONE_ACCOUNT_ID, phoneAccount.getId()); } + + if (voicemail.getTranscription() != null) { + contentValues.put(Voicemails.TRANSCRIPTION, voicemail.getTranscription()); + } + return contentValues; } } diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java index bae5455961a8..04d59522e40b 100644 --- a/core/java/android/security/keymaster/KeymasterDefs.java +++ b/core/java/android/security/keymaster/KeymasterDefs.java @@ -51,6 +51,7 @@ public final class KeymasterDefs { public static final int KM_TAG_DIGEST = KM_ENUM_REP | 5; public static final int KM_TAG_PADDING = KM_ENUM_REP | 6; public static final int KM_TAG_CALLER_NONCE = KM_BOOL | 7; + public static final int KM_TAG_MIN_MAC_LENGTH = KM_UINT | 8; public static final int KM_TAG_RESCOPING_ADD = KM_ENUM_REP | 101; public static final int KM_TAG_RESCOPING_DEL = KM_ENUM_REP | 102; @@ -194,6 +195,9 @@ public final class KeymasterDefs { 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_INVALID_MAC_LENGTH = -57; + public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58; + public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59; 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; @@ -237,6 +241,8 @@ public final class KeymasterDefs { sErrorCodeToString.put(KM_ERROR_INVALID_NONCE, "Invalid IV"); sErrorCodeToString.put(KM_ERROR_CALLER_NONCE_PROHIBITED, "Caller-provided IV not permitted"); + sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH, + "Invalid MAC or authentication tag length"); sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented"); sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error"); } diff --git a/core/java/android/service/chooser/ChooserTarget.java b/core/java/android/service/chooser/ChooserTarget.java index 50c435a90d1c..c2f70cc02f05 100644 --- a/core/java/android/service/chooser/ChooserTarget.java +++ b/core/java/android/service/chooser/ChooserTarget.java @@ -17,20 +17,14 @@ package android.service.chooser; -import android.app.Activity; -import android.app.PendingIntent; +import android.annotation.Nullable; import android.content.ComponentName; -import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.IntentSender; -import android.graphics.Bitmap; import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; -import android.os.UserHandle; -import android.util.Log; /** * A ChooserTarget represents a deep-link into an application as returned by a @@ -62,52 +56,21 @@ public final class ChooserTarget implements Parcelable { private Icon mIcon; /** - * The IntentSender that will be used to deliver the intent to the target. - * It will be {@link android.content.Intent#fillIn(android.content.Intent, int)} filled in} - * by the real intent sent by the application. + * The ComponentName of the Activity to be invoked. Must be part of the target creator's + * own package or an Activity exported by its package. */ - private IntentSender mIntentSender; + private ComponentName mComponentName; /** - * The score given to this item. It can be normalized. + * A Bundle to merge with the extras of the intent sent to this target. + * Any extras here will override the extras from the original intent. */ - private float mScore; + private Bundle mIntentExtras; /** - * Construct a deep link target for presentation by a chooser UI. - * - * <p>A target is composed of a title and an icon for presentation to the user. - * The UI presenting this target may truncate the title if it is too long to be presented - * in the available space, as well as crop, resize or overlay the supplied icon.</p> - * - * <p>The creator of a target may supply a ranking score. This score is assumed to be relative - * to the other targets supplied by the same - * {@link ChooserTargetService#onGetChooserTargets(ComponentName, IntentFilter) query}. - * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match). - * Scores for a set of targets do not need to sum to 1.</p> - * - * <p>Before being sent, the PendingIntent supplied will be - * {@link Intent#fillIn(Intent, int) filled in} by the Intent originally supplied - * to the chooser. When constructing a PendingIntent for use in a ChooserTarget, make sure - * that you permit the relevant fields to be filled in using the appropriate flags such as - * {@link Intent#FILL_IN_ACTION}, {@link Intent#FILL_IN_CATEGORIES}, - * {@link Intent#FILL_IN_DATA} and {@link Intent#FILL_IN_CLIP_DATA}. Note that - * {@link Intent#FILL_IN_CLIP_DATA} is required to appropriately receive URI permission grants - * for {@link Intent#ACTION_SEND} intents.</p> - * - * <p>Take care not to place custom {@link android.os.Parcelable} types into - * the PendingIntent as extras, as the system will not be able to unparcel it to merge - * additional extras.</p> - * - * @param title title of this target that will be shown to a user - * @param icon icon to represent this target - * @param score ranking score for this target between 0.0f and 1.0f, inclusive - * @param pendingIntent PendingIntent to fill in and send if the user chooses this target + * The score given to this item. It can be normalized. */ - public ChooserTarget(CharSequence title, Icon icon, float score, - PendingIntent pendingIntent) { - this(title, icon, score, pendingIntent.getIntentSender()); - } + private float mScore; /** * Construct a deep link target for presentation by a chooser UI. @@ -122,25 +85,23 @@ public final class ChooserTarget implements Parcelable { * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match). * Scores for a set of targets do not need to sum to 1.</p> * - * <p>Before being sent, the IntentSender supplied will be - * {@link Intent#fillIn(Intent, int) filled in} by the Intent originally supplied - * to the chooser. When constructing an IntentSender for use in a ChooserTarget, make sure - * that you permit the relevant fields to be filled in using the appropriate flags such as - * {@link Intent#FILL_IN_ACTION}, {@link Intent#FILL_IN_CATEGORIES}, - * {@link Intent#FILL_IN_DATA} and {@link Intent#FILL_IN_CLIP_DATA}. Note that - * {@link Intent#FILL_IN_CLIP_DATA} is required to appropriately receive URI permission grants - * for {@link Intent#ACTION_SEND} intents.</p> + * <p>The ComponentName must be the name of an Activity component in the creator's own + * package, or an exported component from any other package. You may provide an optional + * Bundle of extras that will be merged into the final intent before it is sent to the + * target Activity; use this to add any additional data about the deep link that the target + * activity will read. e.g. conversation IDs, email addresses, etc.</p> * * <p>Take care not to place custom {@link android.os.Parcelable} types into - * the IntentSender as extras, as the system will not be able to unparcel it to merge - * additional extras.</p> + * the extras bundle, as the system will not be able to unparcel them to merge them.</p> * * @param title title of this target that will be shown to a user * @param icon icon to represent this target * @param score ranking score for this target between 0.0f and 1.0f, inclusive - * @param intentSender IntentSender to fill in and send if the user chooses this target + * @param componentName Name of the component to be launched if this target is chosen + * @param intentExtras Bundle of extras to merge with the extras of the launched intent */ - public ChooserTarget(CharSequence title, Icon icon, float score, IntentSender intentSender) { + public ChooserTarget(CharSequence title, Icon icon, float score, + ComponentName componentName, @Nullable Bundle intentExtras) { mTitle = title; mIcon = icon; if (score > 1.f || score < 0.f) { @@ -148,7 +109,8 @@ public final class ChooserTarget implements Parcelable { + "must be between 0.0f and 1.0f"); } mScore = score; - mIntentSender = intentSender; + mComponentName = componentName; + mIntentExtras = intentExtras; } ChooserTarget(Parcel in) { @@ -159,7 +121,8 @@ public final class ChooserTarget implements Parcelable { mIcon = null; } mScore = in.readFloat(); - mIntentSender = IntentSender.readIntentSenderOrNullFromParcel(in); + mComponentName = ComponentName.readFromParcel(in); + mIntentExtras = in.readBundle(); } /** @@ -194,49 +157,29 @@ public final class ChooserTarget implements Parcelable { } /** - * Returns the raw IntentSender supplied by the ChooserTarget's creator. - * This may be null if the creator specified a regular Intent instead. - * - * <p>To fill in and send the intent, see {@link #sendIntent(Context, Intent)}.</p> + * Returns the ComponentName of the Activity that should be launched for this ChooserTarget. * - * @return the IntentSender supplied by the ChooserTarget's creator + * @return the name of the target Activity to launch */ - public IntentSender getIntentSender() { - return mIntentSender; + public ComponentName getComponentName() { + return mComponentName; } /** - * Fill in the IntentSender supplied by the ChooserTarget's creator and send it. + * Returns the Bundle of extras to be added to an intent launched to this target. * - * @param context the sending Context; generally the Activity presenting the chooser UI - * @param fillInIntent the Intent provided to the Chooser to be sent to a selected target - * @return true if sending the Intent was successful + * @return the extras to merge with the extras of the intent being launched */ - public boolean sendIntent(Context context, Intent fillInIntent) { - if (fillInIntent != null) { - fillInIntent.migrateExtraStreamToClipData(); - fillInIntent.prepareToLeaveProcess(); - } - if (mIntentSender != null) { - try { - mIntentSender.sendIntent(context, 0, fillInIntent, null, null); - return true; - } catch (IntentSender.SendIntentException e) { - Log.e(TAG, "sendIntent " + this + " failed", e); - return false; - } - } else { - Log.e(TAG, "sendIntent " + this + " failed - no IntentSender to send"); - return false; - } + public Bundle getIntentExtras() { + return mIntentExtras; } @Override public String toString() { return "ChooserTarget{" - + (mIntentSender != null ? mIntentSender.getCreatorPackage() : null) - + ", " - + "'" + mTitle + + mComponentName + + ", " + mIntentExtras + + ", '" + mTitle + "', " + mScore + "}"; } @@ -255,7 +198,8 @@ public final class ChooserTarget implements Parcelable { dest.writeInt(0); } dest.writeFloat(mScore); - IntentSender.writeIntentSenderOrNullToParcel(mIntentSender, dest); + ComponentName.writeToParcel(mComponentName, dest); + dest.writeBundle(mIntentExtras); } public static final Creator<ChooserTarget> CREATOR diff --git a/core/java/android/service/chooser/ChooserTargetService.java b/core/java/android/service/chooser/ChooserTargetService.java index a3bfeced361c..e0541855bbab 100644 --- a/core/java/android/service/chooser/ChooserTargetService.java +++ b/core/java/android/service/chooser/ChooserTargetService.java @@ -105,9 +105,8 @@ public abstract class ChooserTargetService extends Service { * can handle an intent. * * <p>The returned list should be sorted such that the most relevant targets appear first. - * Any PendingIntents used to construct the resulting ChooserTargets should always be prepared - * to have the relevant data fields filled in by the sender. See - * {@link ChooserTarget#ChooserTarget(CharSequence, android.graphics.drawable.Icon, float, android.app.PendingIntent) ChooserTarget}.</p> + * The score for each ChooserTarget will be combined with the system's score for the original + * target Activity to sort and filter targets presented to the user.</p> * * <p><em>Important:</em> Calls to this method from other applications will occur on * a binder thread, not on your app's main thread. Make sure that access to relevant data diff --git a/core/java/android/service/chooser/IChooserTargetResult.aidl b/core/java/android/service/chooser/IChooserTargetResult.aidl index dbd7cbd23af2..6c648a24ddfc 100644 --- a/core/java/android/service/chooser/IChooserTargetResult.aidl +++ b/core/java/android/service/chooser/IChooserTargetResult.aidl @@ -21,7 +21,7 @@ import android.service.chooser.ChooserTarget; /** * @hide */ -interface IChooserTargetResult +oneway interface IChooserTargetResult { void sendResult(in List<ChooserTarget> targets); } diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index 0eda69238aa7..2cab914bed62 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -17,6 +17,9 @@ package android.service.notification; import android.app.Notification; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; @@ -40,6 +43,7 @@ public class StatusBarNotification implements Parcelable { private final long postTime; private final int score; + private Context mContext; // used for inflation & icon expansion /** @hide */ public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid, @@ -261,4 +265,24 @@ public class StatusBarNotification implements Parcelable { public String getGroupKey() { return groupKey; } + + /** + * @hide + */ + public Context getPackageContext(Context context) { + if (mContext == null) { + try { + ApplicationInfo ai = context.getPackageManager() + .getApplicationInfo(pkg, PackageManager.GET_UNINSTALLED_PACKAGES); + mContext = context.createApplicationContext(ai, + Context.CONTEXT_RESTRICTED); + } catch (PackageManager.NameNotFoundException e) { + mContext = null; + } + } + if (mContext == null) { + mContext = context; + } + return mContext; + } } diff --git a/core/java/android/service/voice/IVoiceInteractionSession.aidl b/core/java/android/service/voice/IVoiceInteractionSession.aidl index 8fe84e16bae3..dbc28f72ca98 100644 --- a/core/java/android/service/voice/IVoiceInteractionSession.aidl +++ b/core/java/android/service/voice/IVoiceInteractionSession.aidl @@ -35,5 +35,6 @@ oneway interface IVoiceInteractionSession { void taskStarted(in Intent intent, int taskId); void taskFinished(in Intent intent, int taskId); void closeSystemDialogs(); + void onLockscreenShown(); void destroy(); } diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index 95f96e801558..ec14740bd815 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -37,7 +37,9 @@ import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.RemoteException; +import android.os.UserHandle; import android.util.ArrayMap; +import android.util.DebugUtils; import android.util.Log; import android.view.Gravity; import android.view.KeyEvent; @@ -55,6 +57,8 @@ import com.android.internal.app.IVoiceInteractorRequest; import com.android.internal.os.HandlerCaller; import com.android.internal.os.SomeArgs; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.lang.ref.WeakReference; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; @@ -91,6 +95,12 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall */ public static final int SHOW_SOURCE_ASSIST_GESTURE = 1<<2; + /** + * Flag for use with {@link #onShow}: indicates that the application itself has invoked + * the assistant. + */ + public static final int SHOW_SOURCE_APPLICATION = 1<<3; + final Context mContext; final HandlerCaller mHandlerCaller; @@ -259,6 +269,11 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } @Override + public void onLockscreenShown() { + mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_ON_LOCKSCREEN_SHOWN)); + } + + @Override public void destroy() { mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_DESTROY)); } @@ -316,6 +331,22 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall return mExtras; } + /** + * Check whether this request is currently active. A request becomes inactive after + * calling {@link #cancel} or a final result method that completes the request. After + * this point, further interactions with the request will result in + * {@link java.lang.IllegalStateException} errors; you should not catch these errors, + * but can use this method if you need to determine the state of the request. Returns + * true if the request is still active. + */ + public boolean isActive() { + VoiceInteractionSession session = mSession.get(); + if (session == null) { + return false; + } + return session.isRequestActive(mInterface.asBinder()); + } + void finishRequest() { VoiceInteractionSession session = mSession.get(); if (session == null) { @@ -332,6 +363,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall /** * Ask the app to cancel this current request. + * This also finishes the request (it is no longer active). */ public void cancel() { try { @@ -341,6 +373,34 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } catch (RemoteException e) { } } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(128); + DebugUtils.buildShortClassTag(this, sb); + sb.append(" "); + sb.append(mInterface.asBinder()); + sb.append(" pkg="); + sb.append(mCallingPackage); + sb.append(" uid="); + UserHandle.formatUid(sb, mCallingUid); + sb.append('}'); + return sb.toString(); + } + + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + writer.print(prefix); writer.print("mInterface="); + writer.println(mInterface.asBinder()); + writer.print(prefix); writer.print("mCallingPackage="); writer.print(mCallingPackage); + writer.print(" mCallingUid="); UserHandle.formatUid(writer, mCallingUid); + writer.println(); + writer.print(prefix); writer.print("mCallback="); + writer.println(mCallback.asBinder()); + if (mExtras != null) { + writer.print(prefix); writer.print("mExtras="); + writer.println(mExtras); + } + } } /** @@ -383,6 +443,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * in a call to * {@link android.app.VoiceInteractor.ConfirmationRequest#onConfirmationResult * VoiceInteractor.ConfirmationRequest.onConfirmationResult}. + * This finishes the request (it is no longer active). */ public void sendConfirmationResult(boolean confirmed, Bundle result) { try { @@ -393,6 +454,12 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } catch (RemoteException e) { } } + + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mPrompt="); + writer.println(mPrompt); + } } /** @@ -469,11 +536,40 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * and resulting in a call to * {@link android.app.VoiceInteractor.PickOptionRequest#onPickOptionResult * VoiceInteractor.PickOptionRequest.onPickOptionResult} with false for finished. + * This finishes the request (it is no longer active). */ public void sendPickOptionResult( VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) { sendPickOptionResult(true, selections, result); } + + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mPrompt="); + writer.println(mPrompt); + if (mOptions != null) { + writer.print(prefix); writer.println("Options:"); + for (int i=0; i<mOptions.length; i++) { + VoiceInteractor.PickOptionRequest.Option op = mOptions[i]; + writer.print(prefix); writer.print(" #"); writer.print(i); writer.println(":"); + writer.print(prefix); writer.print(" mLabel="); + writer.println(op.getLabel()); + writer.print(prefix); writer.print(" mIndex="); + writer.println(op.getIndex()); + if (op.countSynonyms() > 0) { + writer.print(prefix); writer.println(" Synonyms:"); + for (int j=0; j<op.countSynonyms(); j++) { + writer.print(prefix); writer.print(" #"); writer.print(j); + writer.print(": "); writer.println(op.getSynonymAt(j)); + } + } + if (op.getExtras() != null) { + writer.print(prefix); writer.print(" mExtras="); + writer.println(op.getExtras()); + } + } + } + } } /** @@ -516,6 +612,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * in a call to * {@link android.app.VoiceInteractor.CompleteVoiceRequest#onCompleteResult * VoiceInteractor.CompleteVoiceRequest.onCompleteResult}. + * This finishes the request (it is no longer active). */ public void sendCompleteResult(Bundle result) { try { @@ -526,6 +623,12 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } catch (RemoteException e) { } } + + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mPrompt="); + writer.println(mPrompt); + } } /** @@ -564,7 +667,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * Report that the voice interactor has finished aborting the voice operation, resulting * in a call to * {@link android.app.VoiceInteractor.AbortVoiceRequest#onAbortResult - * VoiceInteractor.AbortVoiceRequest.onAbortResult}. + * VoiceInteractor.AbortVoiceRequest.onAbortResult}. This finishes the request (it + * is no longer active). */ public void sendAbortResult(Bundle result) { try { @@ -575,6 +679,12 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } catch (RemoteException e) { } } + + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mPrompt="); + writer.println(mPrompt); + } } /** @@ -624,10 +734,17 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * Report the final result of the request, completing the request and resulting in a call to * {@link android.app.VoiceInteractor.CommandRequest#onCommandResult * VoiceInteractor.CommandRequest.onCommandResult} with true for isCompleted. + * This finishes the request (it is no longer active). */ public void sendResult(Bundle result) { sendCommandResult(true, result); } + + void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + writer.print(prefix); writer.print("mCommand="); + writer.println(mCommand); + } } static final int MSG_START_CONFIRMATION = 1; @@ -646,6 +763,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall static final int MSG_HANDLE_SCREENSHOT = 105; static final int MSG_SHOW = 106; static final int MSG_HIDE = 107; + static final int MSG_ON_LOCKSCREEN_SHOWN = 108; class MyCallbacks implements HandlerCaller.Callback, SoftInputWindow.Callback { @Override @@ -724,6 +842,10 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall if (DEBUG) Log.d(TAG, "doHide"); doHide(); break; + case MSG_ON_LOCKSCREEN_SHOWN: + if (DEBUG) Log.d(TAG, "onLockscreenShown"); + onLockscreenShown(); + break; } if (args != null) { args.recycle(); @@ -814,7 +936,15 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } void addRequest(Request req) { - mActiveRequests.put(req.mInterface.asBinder(), req); + synchronized (this) { + mActiveRequests.put(req.mInterface.asBinder(), req); + } + } + + boolean isRequestActive(IBinder reqInterface) { + synchronized (this) { + return mActiveRequests.containsKey(reqInterface); + } } Request removeRequest(IBinder reqInterface) { @@ -936,6 +1066,23 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } /** + * Return which show context flags have been disabled by the user through the system + * settings UI, so the session will never get this data. Returned flags are any combination of + * {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and + * {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT + * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}. Note that this only tells you about + * global user settings, not about restrictions that may be applied contextual based on + * the current application the user is in or other transient states. + */ + public int getUserDisabledShowContext() { + try { + return mSystemService.getUserDisabledShowContext(); + } catch (RemoteException e) { + return 0; + } + } + + /** * Show the UI for this session. This asks the system to go through the process of showing * your UI, which will eventually culminate in {@link #onShow}. This is similar to calling * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}. @@ -1179,23 +1326,33 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall /** * Called to receive data from the application that the user was currently viewing when - * an assist session is started. + * an assist session is started. If the original show request did not specify + * {@link #SHOW_WITH_ASSIST}, this method will not be called. * * @param data Arbitrary data supplied by the app through * {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}. + * May be null if assist data has been disabled by the user or device policy. * @param structure If available, the structure definition of all windows currently - * displayed by the app; if structure has been turned off by the user, will be null. + * displayed by the app. May be null if assist data has been disabled by the user + * or device policy; will be an empty stub if the application has disabled assist + * by marking its window as secure. * @param content Additional content data supplied by the app through * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. + * May be null if assist data has been disabled by the user or device policy; will + * not be automatically filled in with data from the app if the app has marked its + * window as secure. */ - public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) { + public void onHandleAssist(@Nullable Bundle data, @Nullable AssistStructure structure, + @Nullable AssistContent content) { } /** * Called to receive a screenshot of what the user was currently viewing when an assist - * session is started. Will be null if screenshots are disabled by the user. + * session is started. May be null if screenshots are disabled by the user, policy, + * or application. If the original show request did not specify + * {@link #SHOW_WITH_SCREENSHOT}, this method will not be called. */ - public void onHandleScreenshot(Bitmap screenshot) { + public void onHandleScreenshot(@Nullable Bitmap screenshot) { } public boolean onKeyDown(int keyCode, KeyEvent event) { @@ -1233,6 +1390,13 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall hide(); } + /** + * Called when the lockscreen was shown. + */ + public void onLockscreenShown() { + hide(); + } + @Override public void onConfigurationChanged(Configuration newConfig) { } @@ -1366,4 +1530,37 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall */ public void onCancelRequest(Request request) { } + + /** + * Print the Service's state into the given stream. This gets invoked by + * {@link VoiceInteractionSessionService} when its Service + * {@link android.app.Service#dump} method is called. + * + * @param prefix Text to print at the front of each line. + * @param fd The raw file descriptor that the dump is being sent to. + * @param writer The PrintWriter to which you should dump your state. This will be + * closed for you after you return. + * @param args additional arguments to the dump request. + */ + public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + writer.print(prefix); writer.print("mToken="); writer.println(mToken); + writer.print(prefix); writer.print("mTheme=#"); writer.println(Integer.toHexString(mTheme)); + writer.print(prefix); writer.print("mInitialized="); writer.println(mInitialized); + writer.print(prefix); writer.print("mWindowAdded="); writer.print(mWindowAdded); + writer.print(" mWindowVisible="); writer.println(mWindowVisible); + writer.print(prefix); writer.print("mWindowWasVisible="); writer.print(mWindowWasVisible); + writer.print(" mInShowWindow="); writer.println(mInShowWindow); + if (mActiveRequests.size() > 0) { + writer.print(prefix); writer.println("Active requests:"); + String innerPrefix = prefix + " "; + for (int i=0; i<mActiveRequests.size(); i++) { + Request req = mActiveRequests.valueAt(i); + writer.print(prefix); writer.print(" #"); writer.print(i); + writer.print(": "); + writer.println(req); + req.dump(innerPrefix, fd, writer, args); + + } + } + } } diff --git a/core/java/android/service/voice/VoiceInteractionSessionService.java b/core/java/android/service/voice/VoiceInteractionSessionService.java index fb9f973ec8d7..424ff9def41c 100644 --- a/core/java/android/service/voice/VoiceInteractionSessionService.java +++ b/core/java/android/service/voice/VoiceInteractionSessionService.java @@ -30,6 +30,9 @@ import com.android.internal.app.IVoiceInteractionManagerService; import com.android.internal.os.HandlerCaller; import com.android.internal.os.SomeArgs; +import java.io.FileDescriptor; +import java.io.PrintWriter; + /** * An active voice interaction session, initiated by a {@link VoiceInteractionService}. */ @@ -101,6 +104,16 @@ public abstract class VoiceInteractionSessionService extends Service { } } + @Override + protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + if (mSession == null) { + writer.println("(no active session)"); + } else { + writer.println("VoiceInteractionSession:"); + mSession.dump(" ", fd, writer, args); + } + } + void doNewSession(IBinder token, Bundle args, int startFlags) { if (mSession != null) { mSession.doDestroy(); diff --git a/core/java/android/text/BidiFormatter.java b/core/java/android/text/BidiFormatter.java index 7ea9da1715c4..5c088cdd9d3a 100644 --- a/core/java/android/text/BidiFormatter.java +++ b/core/java/android/text/BidiFormatter.java @@ -173,7 +173,7 @@ public final class BidiFormatter { /** * Specifies whether the BidiFormatter to be built should also "reset" directionality before - * a string being bidi-wrapped, not just after it. The default is false. + * a string being bidi-wrapped, not just after it. The default is true. */ public Builder stereoReset(boolean stereoReset) { if (stereoReset) { @@ -363,12 +363,13 @@ public final class BidiFormatter { * If {@code isolate}, directionally isolates the string so that it does not garble its * surroundings. Currently, this is done by "resetting" the directionality after the string by * appending a trailing Unicode bidi mark matching the context directionality (LRM or RLM) when - * either the overall directionality or the exit directionality of the string is opposite to that - * of the context. If the formatter was built using {@link Builder#stereoReset(boolean)} and - * passing "true" as an argument, also prepends a Unicode bidi mark matching the context - * directionality when either the overall directionality or the entry directionality of the - * string is opposite to that of the context. Note that as opposed to the overall - * directionality, the entry and exit directionalities are determined from the string itself. + * either the overall directionality or the exit directionality of the string is opposite to + * that of the context. Unless the formatter was built using + * {@link Builder#stereoReset(boolean)} with a {@code false} argument, also prepends a Unicode + * bidi mark matching the context directionality when either the overall directionality or the + * entry directionality of the string is opposite to that of the context. Note that as opposed + * to the overall directionality, the entry and exit directionalities are determined from the + * string itself. * <p> * Does *not* do HTML-escaping. * diff --git a/core/java/android/text/Hyphenator.java b/core/java/android/text/Hyphenator.java index 1ee382735d53..10a994adde2a 100644 --- a/core/java/android/text/Hyphenator.java +++ b/core/java/android/text/Hyphenator.java @@ -45,6 +45,8 @@ public class Hyphenator { @GuardedBy("sLock") final static HashMap<Locale, Hyphenator> sMap = new HashMap<Locale, Hyphenator>(); + final static Hyphenator sEmptyHyphenator = new Hyphenator(StaticLayout.nLoadHyphenator("")); + final private long mNativePtr; private Hyphenator(long nativePtr) { @@ -53,19 +55,19 @@ public class Hyphenator { public static long get(@Nullable Locale locale) { synchronized (sLock) { - if (sMap.containsKey(locale)) { - Hyphenator result = sMap.get(locale); - return (result == null) ? 0 : result.mNativePtr; + Hyphenator result = sMap.get(locale); + if (result != null) { + return result.mNativePtr; } // TODO: Convert this a proper locale-fallback system // Fall back to language-only, if available Locale languageOnlyLocale = new Locale(locale.getLanguage()); - if (sMap.containsKey(languageOnlyLocale)) { - Hyphenator result = sMap.get(languageOnlyLocale); + result = sMap.get(languageOnlyLocale); + if (result != null) { sMap.put(locale, result); - return (result == null) ? 0 : result.mNativePtr; + return result.mNativePtr; } // Fall back to script-only, if available @@ -75,16 +77,16 @@ public class Hyphenator { .setLanguage("und") .setScript(script) .build(); - if (sMap.containsKey(scriptOnlyLocale)) { - Hyphenator result = sMap.get(scriptOnlyLocale); + result = sMap.get(scriptOnlyLocale); + if (result != null) { sMap.put(locale, result); - return (result == null) ? 0 : result.mNativePtr; + return result.mNativePtr; } } - sMap.put(locale, null); // To remember we found nothing. + sMap.put(locale, sEmptyHyphenator); // To remember we found nothing. } - return 0; + return sEmptyHyphenator.mNativePtr; } private static Hyphenator loadHyphenator(String languageTag) { diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index efc9e1ae4aa6..3b0def29f006 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -112,6 +112,10 @@ public class StaticLayout extends Layout { // release any expensive state /* package */ void finish() { nFinishBuilder(mNativePtr); + mText = null; + mPaint = null; + mLeftIndents = null; + mRightIndents = null; mMeasuredText.finish(); } diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 605b91dee9c0..39e86948d187 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -741,11 +741,11 @@ class TextLine { if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) { if (mCharsValid) { - ret = wp.getRunAdvance(mChars, start, contextEnd, contextStart, contextEnd, + ret = wp.getRunAdvance(mChars, start, end, contextStart, contextEnd, runIsRtl, end); } else { int delta = mStart; - ret = wp.getRunAdvance(mText, delta + start, delta + contextEnd, + ret = wp.getRunAdvance(mText, delta + start, delta + end, delta + contextStart, delta + contextEnd, runIsRtl, delta + end); } } diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java index 82689b98e64b..b5068b2e7ccc 100644 --- a/core/java/android/text/format/Formatter.java +++ b/core/java/android/text/format/Formatter.java @@ -16,12 +16,18 @@ package android.text.format; +import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.res.Resources; +import android.text.BidiFormatter; +import android.text.TextUtils; +import android.view.View; import android.net.NetworkUtils; import android.net.TrafficStats; +import java.util.Locale; + /** * Utility class to aid in formatting common values that are not covered * by the {@link java.util.Formatter} class in {@link java.util} @@ -46,8 +52,23 @@ public final class Formatter { } } + /* Wraps the source string in bidi formatting characters in RTL locales */ + private static String bidiWrap(@NonNull Context context, String source) { + final Locale locale = context.getResources().getConfiguration().locale; + if (TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL) { + return BidiFormatter.getInstance(true /* RTL*/).unicodeWrap(source); + } else { + return source; + } + } + /** - * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc + * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc. + * + * If the context has a right-to-left locale, the returned string is wrapped in bidi formatting + * characters to make sure it's displayed correctly if inserted inside a right-to-left string. + * (This is useful in cases where the unit strings, like "MB", are left-to-right, but the + * locale is right-to-left.) * * @param context Context to use to load the localized units * @param sizeBytes size value to be formatted, in bytes @@ -58,8 +79,8 @@ public final class Formatter { return ""; } final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0); - return context.getString(com.android.internal.R.string.fileSizeSuffix, - res.value, res.units); + return bidiWrap(context, context.getString(com.android.internal.R.string.fileSizeSuffix, + res.value, res.units)); } /** @@ -71,8 +92,8 @@ public final class Formatter { return ""; } final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER); - return context.getString(com.android.internal.R.string.fileSizeSuffix, - res.value, res.units); + return bidiWrap(context, context.getString(com.android.internal.R.string.fileSizeSuffix, + res.value, res.units)); } /** {@hide} */ diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index de61c3153914..43c578fe7faf 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -56,7 +56,6 @@ import android.graphics.Shader; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.hardware.display.DisplayManagerGlobal; -import android.os.Build; import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Handler; @@ -3802,14 +3801,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // of whether a layout was requested on that View. sIgnoreMeasureCache = targetSdkVersion < KITKAT; - Canvas.sCompatibilityRestore = targetSdkVersion < MNC; + Canvas.sCompatibilityRestore = targetSdkVersion < M; - // In MNC and newer, our widgets can pass a "hint" value in the size + // In M and newer, our widgets can pass a "hint" value in the size // for UNSPECIFIED MeasureSpecs. This lets child views of scrolling containers // know what the expected parent size is going to be, so e.g. list items can size // themselves at 1/3 the size of their container. It breaks older apps though, // specifically apps that use some popular open source libraries. - sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < MNC; + sUseZeroUnspecifiedMeasureSpec = targetSdkVersion < M; sCompatibilityDone = true; } @@ -4277,27 +4276,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback, PROVIDER_BACKGROUND)); break; case R.styleable.View_foreground: - if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) { + if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) { setForeground(a.getDrawable(attr)); } break; case R.styleable.View_foregroundGravity: - if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) { + if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) { setForegroundGravity(a.getInt(attr, Gravity.NO_GRAVITY)); } break; case R.styleable.View_foregroundTintMode: - if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) { + if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) { setForegroundTintMode(Drawable.parseTintMode(a.getInt(attr, -1), null)); } break; case R.styleable.View_foregroundTint: - if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) { + if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) { setForegroundTintList(a.getColorStateList(attr)); } break; case R.styleable.View_foregroundInsidePadding: - if (targetSdkVersion >= VERSION_CODES.MNC || this instanceof FrameLayout) { + if (targetSdkVersion >= VERSION_CODES.M || this instanceof FrameLayout) { if (mForegroundInfo == null) { mForegroundInfo = new ForegroundInfo(); } @@ -11417,10 +11416,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * strongly recommended for performance reasons to either override * {@link #hasOverlappingRendering()} to return <code>false</code> if appropriate, or setting a * {@link #setLayerType(int, android.graphics.Paint) layer type} on the view for the duration - * of the animation. On versions {@link android.os.Build.VERSION_CODES#MNC} and below, + * of the animation. On versions {@link android.os.Build.VERSION_CODES#M} and below, * the default path for rendering an unlayered View with alpha could add multiple milliseconds * of rendering cost, even for simple or small views. Starting with - * {@link android.os.Build.VERSION_CODES#MNC}, {@link #LAYER_TYPE_HARDWARE} is automatically + * {@link android.os.Build.VERSION_CODES#M}, {@link #LAYER_TYPE_HARDWARE} is automatically * applied to the view at the rendering level.</p> * * <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is @@ -11431,7 +11430,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * associated with a {@link #setLayerPaint(android.graphics.Paint) layer paint}, setting an * alpha value less than 1.0 will supersede the alpha of the layer paint.</p> * - * <p>Starting with {@link android.os.Build.VERSION_CODES#MNC}, setting a translucent alpha + * <p>Starting with {@link android.os.Build.VERSION_CODES#M}, setting a translucent alpha * value will clip a View to its bounds, unless the View returns <code>false</code> from * {@link #hasOverlappingRendering}.</p> * @@ -18773,22 +18772,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL; if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2); - final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT; - final boolean isExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY && - MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY; - final boolean matchingSize = isExactly && - getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec) && - getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec); - if (forceLayout || !matchingSize && - (widthMeasureSpec != mOldWidthMeasureSpec || - heightMeasureSpec != mOldHeightMeasureSpec)) { + if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT || + widthMeasureSpec != mOldWidthMeasureSpec || + heightMeasureSpec != mOldHeightMeasureSpec) { // first clears the measured dimension flag mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET; resolveRtlPropertiesIfNeeded(); - int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key); + int cacheIndex = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ? -1 : + mMeasureCache.indexOfKey(key); if (cacheIndex < 0 || sIgnoreMeasureCache) { // measure ourselves, this should set the measured dimension flag back onMeasure(widthMeasureSpec, heightMeasureSpec); diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 6dca26b18f26..fab81a424f76 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -5467,7 +5467,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #setAnimationCacheEnabled(boolean) * @see View#setDrawingCacheEnabled(boolean) * - * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored. + * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored. * Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}. */ public boolean isAnimationCacheEnabled() { @@ -5485,7 +5485,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #isAnimationCacheEnabled() * @see View#setDrawingCacheEnabled(boolean) * - * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored. + * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored. * Caching behavior of children may be controlled through {@link View#setLayerType(int, Paint)}. */ public void setAnimationCacheEnabled(boolean enabled) { @@ -5502,7 +5502,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #setChildrenDrawnWithCacheEnabled(boolean) * @see View#setDrawingCacheEnabled(boolean) * - * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored. + * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored. * Child views may no longer have their caching behavior disabled by parents. */ public boolean isAlwaysDrawnWithCacheEnabled() { @@ -5526,7 +5526,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see View#setDrawingCacheEnabled(boolean) * @see View#setDrawingCacheQuality(int) * - * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored. + * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored. * Child views may no longer have their caching behavior disabled by parents. */ public void setAlwaysDrawnWithCacheEnabled(boolean always) { @@ -5542,7 +5542,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #setAlwaysDrawnWithCacheEnabled(boolean) * @see #setChildrenDrawnWithCacheEnabled(boolean) * - * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored. + * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored. * Child views may no longer be forced to cache their rendering state by their parents. * Use {@link View#setLayerType(int, Paint)} on individual Views instead. */ @@ -5563,7 +5563,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @see #setAlwaysDrawnWithCacheEnabled(boolean) * @see #isChildrenDrawnWithCacheEnabled() * - * @deprecated As of {@link android.os.Build.VERSION_CODES#MNC}, this property is ignored. + * @deprecated As of {@link android.os.Build.VERSION_CODES#M}, this property is ignored. * Child views may no longer be forced to cache their rendering state by their parents. * Use {@link View#setLayerType(int, Paint)} on individual Views instead. */ diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 9b1db57a17a7..6e93a3031de5 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -79,7 +79,6 @@ import android.widget.Scroller; import com.android.internal.R; import com.android.internal.os.SomeArgs; import com.android.internal.policy.PhoneFallbackEventHandler; -import com.android.internal.util.ScreenShapeHelper; import com.android.internal.view.BaseSurfaceHolder; import com.android.internal.view.RootViewSurfaceTaker; @@ -555,11 +554,6 @@ public final class ViewRootImpl implements ViewParent, mPendingContentInsets.set(mAttachInfo.mContentInsets); mPendingStableInsets.set(mAttachInfo.mStableInsets); mPendingVisibleInsets.set(0, 0, 0, 0); - try { - relayoutWindow(attrs, getHostVisibility(), false); - } catch (RemoteException e) { - if (DEBUG_LAYOUT) Log.e(TAG, "failed to relayoutWindow", e); - } if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow); if (res < WindowManagerGlobal.ADD_OKAY) { mAttachInfo.mRootView = null; @@ -3165,6 +3159,17 @@ public final class ViewRootImpl implements ViewParent, return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent); } + private static void forceLayout(View view) { + view.forceLayout(); + if (view instanceof ViewGroup) { + ViewGroup group = (ViewGroup) view; + final int count = group.getChildCount(); + for (int i = 0; i < count; i++) { + forceLayout(group.getChildAt(i)); + } + } + } + private final static int MSG_INVALIDATE = 1; private final static int MSG_INVALIDATE_RECT = 2; private final static int MSG_DIE = 3; @@ -3303,6 +3308,10 @@ public final class ViewRootImpl implements ViewParent, mReportNextDraw = true; } + if (mView != null) { + forceLayout(mView); + } + requestLayout(); } break; @@ -3317,6 +3326,9 @@ public final class ViewRootImpl implements ViewParent, mWinFrame.top = t; mWinFrame.bottom = t + h; + if (mView != null) { + forceLayout(mView); + } requestLayout(); } break; @@ -5928,7 +5940,7 @@ public final class ViewRootImpl implements ViewParent, } private void adjustInputEventForCompatibility(InputEvent e) { - if (mTargetSdkVersion < Build.VERSION_CODES.MNC && e instanceof MotionEvent) { + if (mTargetSdkVersion < Build.VERSION_CODES.M && e instanceof MotionEvent) { MotionEvent motion = (MotionEvent) e; final int mask = MotionEvent.BUTTON_STYLUS_PRIMARY | MotionEvent.BUTTON_STYLUS_SECONDARY; diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index be564f84d221..aaf605274a9a 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -995,6 +995,12 @@ public interface WindowManagerPolicy { public void screenTurningOn(ScreenOnListener screenOnListener); /** + * Called when the device has actually turned on the screen, i.e. the display power state has + * been set to ON and the screen is unblocked. + */ + public void screenTurnedOn(); + + /** * Called when the device has turned the screen off. */ public void screenTurnedOff(); diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java index 76c8fbd4b295..6130fd58ac9a 100644 --- a/core/java/android/view/inputmethod/EditorInfo.java +++ b/core/java/android/view/inputmethod/EditorInfo.java @@ -303,10 +303,12 @@ public class EditorInfo implements InputType, Parcelable { * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and prior, do not trust this package * name. The system had not verified the consistency between the package name here and * application's uid. Consider to use {@link InputBinding#getUid()}, which is trustworthy. - * Starting from Android MNC, the system verifies the consistency between this package name - * and application uid before {@link EditorInfo} is passed to the input method.</p> + * Starting from {@link android.os.Build.VERSION_CODES#M}, the system verifies the consistency + * between this package name and application uid before {@link EditorInfo} is passed to the + * input method.</p> * - * <p><strong>Editor authors:</strong> Starting from Android MNC, the application is no longer + * <p><strong>Editor authors:</strong> Starting from {@link android.os.Build.VERSION_CODES#M}, + * the application is no longer * able to establish input connections if the package name provided here is inconsistent with * application's uid.</p> */ diff --git a/core/java/android/view/inputmethod/InputMethodManagerInternal.java b/core/java/android/view/inputmethod/InputMethodManagerInternal.java new file mode 100644 index 000000000000..c22127b65e2b --- /dev/null +++ b/core/java/android/view/inputmethod/InputMethodManagerInternal.java @@ -0,0 +1,30 @@ +/* + * 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.view.inputmethod; + +/** + * Input method manager local system service interface. + * + * @hide Only for use within the system server. + */ +public interface InputMethodManagerInternal { + /** + * Called by the power manager to tell the input method manager whether it + * should start watching for wake events. + */ + public void setInteractive(boolean interactive); +} diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java index 0b18bb8c4dde..4737e9be3f99 100644 --- a/core/java/android/webkit/WebChromeClient.java +++ b/core/java/android/webkit/WebChromeClient.java @@ -284,19 +284,13 @@ public class WebChromeClient { * currently set for that origin. The host application should invoke the * specified callback with the desired permission state. See * {@link GeolocationPermissions} for details. - * - * If this method isn't overridden, the callback is invoked with permission - * denied state. - * * @param origin The origin of the web content attempting to use the * Geolocation API. * @param callback The callback to use to set the permission state for the * origin. */ public void onGeolocationPermissionsShowPrompt(String origin, - GeolocationPermissions.Callback callback) { - callback.invoke(origin, false, false); - } + GeolocationPermissions.Callback callback) {} /** * Notify the host application that a request for Geolocation permissions, diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index b2b98db25015..ed858e7a9836 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -1556,13 +1556,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (accessibilityId == getAccessibilityViewId()) { return this; } - // If the data changed the children are invalid since the data model changed. - // Hence, we pretend they do not exist. After a layout the children will sync - // with the model at which point we notify that the accessibility state changed, - // so a service will be able to re-fetch the views. - if (mDataChanged) { - return null; - } return super.findViewByAccessibilityIdTraversal(accessibilityId); } @@ -2409,18 +2402,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te class ListItemAccessibilityDelegate extends AccessibilityDelegate { @Override - public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) { - // If the data changed the children are invalid since the data model changed. - // Hence, we pretend they do not exist. After a layout the children will sync - // with the model at which point we notify that the accessibility state changed, - // so a service will be able to re-fetch the views. - if (mDataChanged) { - return null; - } - return super.createAccessibilityNodeInfo(host); - } - - @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java index e3ce6f2e7469..a12b15ef0129 100644 --- a/core/java/android/widget/AppSecurityPermissions.java +++ b/core/java/android/widget/AppSecurityPermissions.java @@ -533,6 +533,12 @@ public class AppSecurityPermissions { int existingReqFlags) { final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; final boolean isNormal = (base == PermissionInfo.PROTECTION_NORMAL); + + // We do not show normal permissions in the UI. + if (isNormal) { + return false; + } + final boolean isDangerous = (base == PermissionInfo.PROTECTION_DANGEROUS) || ((pInfo.protectionLevel&PermissionInfo.PROTECTION_FLAG_PRE23) != 0); final boolean isRequired = @@ -546,7 +552,7 @@ public class AppSecurityPermissions { // Dangerous and normal permissions are always shown to the user if the permission // is required, or it was previously granted - if ((isNormal || isDangerous) && (isRequired || wasGranted || isGranted)) { + if (isDangerous && (isRequired || wasGranted || isGranted)) { return true; } diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java index 0b5824ae56a7..d20b9244a4b2 100644 --- a/core/java/android/widget/DateTimeView.java +++ b/core/java/android/widget/DateTimeView.java @@ -16,6 +16,7 @@ package android.widget; +import android.app.ActivityThread; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -25,7 +26,6 @@ import android.os.Handler; import android.text.format.Time; import android.util.AttributeSet; import android.util.Log; -import android.widget.TextView; import android.widget.RemoteViews.RemoteView; import java.text.DateFormat; @@ -228,14 +228,14 @@ public class DateTimeView extends TextView { final boolean register = mAttachedViews.isEmpty(); mAttachedViews.add(v); if (register) { - register(v.getContext().getApplicationContext()); + register(getApplicationContextIfAvailable(v.getContext())); } } public void removeView(DateTimeView v) { mAttachedViews.remove(v); if (mAttachedViews.isEmpty()) { - unregister(v.getContext().getApplicationContext()); + unregister(getApplicationContextIfAvailable(v.getContext())); } } @@ -258,6 +258,11 @@ public class DateTimeView extends TextView { return result; } + static final Context getApplicationContextIfAvailable(Context context) { + final Context ac = context.getApplicationContext(); + return ac != null ? ac : ActivityThread.currentApplication().getApplicationContext(); + } + void register(Context context) { final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_TIME_TICK); diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index d897f49dbffd..010cb27dbc71 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -1004,7 +1004,8 @@ public class Editor { } if (!handled && mTextActionMode != null) { - if (touchPositionIsInSelection()) { + // TODO: Fix dragging in extracted mode. + if (touchPositionIsInSelection() && !mTextView.isInExtractedMode()) { // Start a drag final int start = mTextView.getSelectionStart(); final int end = mTextView.getSelectionEnd(); @@ -3225,7 +3226,8 @@ public class Editor { } private void updateReplaceItem(Menu menu) { - boolean canReplace = mTextView.isSuggestionsEnabled() && shouldOfferToShowSuggestions(); + boolean canReplace = mTextView.isSuggestionsEnabled() && shouldOfferToShowSuggestions() + && !(mTextView.isInExtractedMode() && mTextView.hasSelection()); boolean replaceItemExists = menu.findItem(TextView.ID_REPLACE) != null; if (canReplace && !replaceItemExists) { menu.add(Menu.NONE, TextView.ID_REPLACE, MENU_ITEM_ORDER_REPLACE, @@ -4058,9 +4060,17 @@ public class Editor { private float mPrevX; // Indicates if the handle has moved a boundary between LTR and RTL text. private boolean mLanguageDirectionChanged = false; + // Distance from edge of horizontally scrolling text view + // to use to switch to character mode. + private final float mTextViewEdgeSlop; + // Used to save text view location. + private final int[] mTextViewLocation = new int[2]; public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) { super(drawableLtr, drawableRtl); + ViewConfiguration viewConfiguration = ViewConfiguration.get( + mTextView.getContext()); + mTextViewEdgeSlop = viewConfiguration.getScaledTouchSlop() * 4; } @Override @@ -4098,7 +4108,7 @@ public class Editor { if (layout == null) { // HandleView will deal appropriately in positionAtCursorOffset when // layout is null. - positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false); + positionAndAdjustForCrossingHandles(mTextView.getOffsetForPosition(x, y)); return; } @@ -4140,12 +4150,12 @@ public class Editor { // to the current position. mLanguageDirectionChanged = true; mTouchWordDelta = 0.0f; - positionAtCursorOffset(offset, false); + positionAndAdjustForCrossingHandles(offset); 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); + positionAndAdjustForCrossingHandles(offset); mTouchWordDelta = 0.0f; mLanguageDirectionChanged = false; return; @@ -4158,6 +4168,21 @@ public class Editor { } } + if (mTextView.getHorizontallyScrolling()) { + if (positionNearEdgeOfScrollingView(x, atRtl) + && (mTextView.getScrollX() != 0) + && ((isExpanding && offset < selectionStart) || !isExpanding)) { + // If we're expanding ensure that the offset is smaller than the + // selection start, if the handle snapped to the word, the finger position + // may be out of sync and we don't want the selection to jump back. + mTouchWordDelta = 0.0f; + final int nextOffset = atRtl ? layout.getOffsetToRightOf(mPreviousOffset) + : layout.getOffsetToLeftOf(mPreviousOffset); + positionAndAdjustForCrossingHandles(nextOffset); + return; + } + } + if (isExpanding) { // User is increasing the selection. if (!mInWord || currLine < mPrevLine) { @@ -4213,17 +4238,22 @@ public class Editor { } if (positionCursor) { - // Handles can not cross and selection is at least one character. - if (offset >= selectionEnd) { - offset = getNextCursorOffset(selectionEnd, false); - mTouchWordDelta = 0.0f; - } mPreviousLineTouched = currLine; - positionAtCursorOffset(offset, false); + positionAndAdjustForCrossingHandles(offset); } mPrevX = x; } + private void positionAndAdjustForCrossingHandles(int offset) { + final int selectionEnd = mTextView.getSelectionEnd(); + if (offset >= selectionEnd) { + // Handles can not cross and selection is at least one character. + offset = getNextCursorOffset(selectionEnd, false); + mTouchWordDelta = 0.0f; + } + positionAtCursorOffset(offset, false); + } + @Override protected void positionAtCursorOffset(int offset, boolean parentScrolled) { super.positionAtCursorOffset(offset, parentScrolled); @@ -4241,6 +4271,20 @@ public class Editor { } return superResult; } + + private boolean positionNearEdgeOfScrollingView(float x, boolean atRtl) { + mTextView.getLocationOnScreen(mTextViewLocation); + boolean nearEdge; + if (atRtl) { + int rightEdge = mTextViewLocation[0] + mTextView.getWidth() + - mTextView.getPaddingRight(); + nearEdge = x > rightEdge - mTextViewEdgeSlop; + } else { + int leftEdge = mTextViewLocation[0] + mTextView.getPaddingLeft(); + nearEdge = x < leftEdge + mTextViewEdgeSlop; + } + return nearEdge; + } } private class SelectionEndHandleView extends HandleView { @@ -4252,9 +4296,17 @@ public class Editor { private float mPrevX; // Indicates if the handle has moved a boundary between LTR and RTL text. private boolean mLanguageDirectionChanged = false; + // Distance from edge of horizontally scrolling text view + // to use to switch to character mode. + private final float mTextViewEdgeSlop; + // Used to save the text view location. + private final int[] mTextViewLocation = new int[2]; public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) { super(drawableLtr, drawableRtl); + ViewConfiguration viewConfiguration = ViewConfiguration.get( + mTextView.getContext()); + mTextViewEdgeSlop = viewConfiguration.getScaledTouchSlop() * 4; } @Override @@ -4292,7 +4344,7 @@ public class Editor { if (layout == null) { // HandleView will deal appropriately in positionAtCursorOffset when // layout is null. - positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false); + positionAndAdjustForCrossingHandles(mTextView.getOffsetForPosition(x, y)); return; } @@ -4334,12 +4386,12 @@ public class Editor { // to the current position. mLanguageDirectionChanged = true; mTouchWordDelta = 0.0f; - positionAtCursorOffset(offset, false); + positionAndAdjustForCrossingHandles(offset); 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); + positionAndAdjustForCrossingHandles(offset); mTouchWordDelta = 0.0f; mLanguageDirectionChanged = false; return; @@ -4352,6 +4404,21 @@ public class Editor { } } + if (mTextView.getHorizontallyScrolling()) { + if (positionNearEdgeOfScrollingView(x, atRtl) + && mTextView.canScrollHorizontally(atRtl ? -1 : 1) + && ((isExpanding && offset > selectionEnd) || !isExpanding)) { + // If we're expanding ensure that the offset is actually greater than the + // selection end, if the handle snapped to the word, the finger position + // may be out of sync and we don't want the selection to jump back. + mTouchWordDelta = 0.0f; + final int nextOffset = atRtl ? layout.getOffsetToLeftOf(mPreviousOffset) + : layout.getOffsetToRightOf(mPreviousOffset); + positionAndAdjustForCrossingHandles(nextOffset); + return; + } + } + if (isExpanding) { // User is increasing the selection. if (!mInWord || currLine > mPrevLine) { @@ -4407,17 +4474,22 @@ public class Editor { } if (positionCursor) { - // Handles can not cross and selection is at least one character. - if (offset <= selectionStart) { - offset = getNextCursorOffset(selectionStart, true); - mTouchWordDelta = 0.0f; - } mPreviousLineTouched = currLine; - positionAtCursorOffset(offset, false); + positionAndAdjustForCrossingHandles(offset); } mPrevX = x; } + private void positionAndAdjustForCrossingHandles(int offset) { + final int selectionStart = mTextView.getSelectionStart(); + if (offset <= selectionStart) { + // Handles can not cross and selection is at least one character. + offset = getNextCursorOffset(selectionStart, true); + mTouchWordDelta = 0.0f; + } + positionAtCursorOffset(offset, false); + } + @Override protected void positionAtCursorOffset(int offset, boolean parentScrolled) { super.positionAtCursorOffset(offset, parentScrolled); @@ -4435,6 +4507,20 @@ public class Editor { } return superResult; } + + private boolean positionNearEdgeOfScrollingView(float x, boolean atRtl) { + mTextView.getLocationOnScreen(mTextViewLocation); + boolean nearEdge; + if (atRtl) { + int leftEdge = mTextViewLocation[0] + mTextView.getPaddingLeft(); + nearEdge = x < leftEdge + mTextViewEdgeSlop; + } else { + int rightEdge = mTextViewLocation[0] + mTextView.getWidth() + - mTextView.getPaddingRight(); + nearEdge = x > rightEdge - mTextViewEdgeSlop; + } + return nearEdge; + } } private int getCurrentLineAdjustedForSlop(Layout layout, int prevLine, float y) { diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index dac02fafba4c..4dfa7db793b2 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -676,33 +676,42 @@ public class RelativeLayout extends ViewGroup { child.measure(childWidthMeasureSpec, childHeightMeasureSpec); } - private void measureChildHorizontal(View child, LayoutParams params, int myWidth, int myHeight) { - int childWidthMeasureSpec = getChildMeasureSpec(params.mLeft, - params.mRight, params.width, - params.leftMargin, params.rightMargin, - mPaddingLeft, mPaddingRight, + private void measureChildHorizontal( + View child, LayoutParams params, int myWidth, int myHeight) { + final int childWidthMeasureSpec = getChildMeasureSpec(params.mLeft, params.mRight, + params.width, params.leftMargin, params.rightMargin, mPaddingLeft, mPaddingRight, myWidth); - int maxHeight = myHeight; - if (mMeasureVerticalWithPaddingMargin) { - maxHeight = Math.max(0, myHeight - mPaddingTop - mPaddingBottom - - params.topMargin - params.bottomMargin); - } - int childHeightMeasureSpec; + + final int childHeightMeasureSpec; if (myHeight < 0 && !mAllowBrokenMeasureSpecs) { if (params.height >= 0) { childHeightMeasureSpec = MeasureSpec.makeMeasureSpec( params.height, MeasureSpec.EXACTLY); } else { - // Negative values in a mySize/myWidth/myWidth value in RelativeLayout measurement - // is code for, "we got an unspecified mode in the RelativeLayout's measurespec." + // Negative values in a mySize/myWidth/myWidth value in + // RelativeLayout measurement is code for, "we got an + // unspecified mode in the RelativeLayout's measure spec." // Carry it forward. childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } - } else if (params.width == LayoutParams.MATCH_PARENT) { - childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.EXACTLY); } else { - childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST); + final int maxHeight; + if (mMeasureVerticalWithPaddingMargin) { + maxHeight = Math.max(0, myHeight - mPaddingTop - mPaddingBottom + - params.topMargin - params.bottomMargin); + } else { + maxHeight = Math.max(0, myHeight); + } + + final int heightMode; + if (params.width == LayoutParams.MATCH_PARENT) { + heightMode = MeasureSpec.EXACTLY; + } else { + heightMode = MeasureSpec.AT_MOST; + } + childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, heightMode); } + child.measure(childWidthMeasureSpec, childHeightMeasureSpec); } @@ -731,7 +740,8 @@ public class RelativeLayout extends ViewGroup { // Negative values in a mySize value in RelativeLayout // measurement is code for, "we got an unspecified mode in the // RelativeLayout's measure spec." - if (mySize < 0 && !mAllowBrokenMeasureSpecs) { + final boolean isUnspecified = mySize < 0; + if (isUnspecified && !mAllowBrokenMeasureSpecs) { if (childStart != VALUE_NOT_SET && childEnd != VALUE_NOT_SET) { // Constraints fixed both edges, so child has an exact size. childSpecSize = Math.max(0, childEnd - childStart); @@ -767,7 +777,7 @@ public class RelativeLayout extends ViewGroup { if (childStart != VALUE_NOT_SET && childEnd != VALUE_NOT_SET) { // Constraints fixed both edges, so child must be an exact size. - childSpecMode = MeasureSpec.EXACTLY; + childSpecMode = isUnspecified ? MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY; childSpecSize = Math.max(0, maxAvailable); } else { if (childSize >= 0) { @@ -784,7 +794,7 @@ public class RelativeLayout extends ViewGroup { } else if (childSize == LayoutParams.MATCH_PARENT) { // Child wanted to be as big as possible. Give all available // space. - childSpecMode = MeasureSpec.EXACTLY; + childSpecMode = isUnspecified ? MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY; childSpecSize = Math.max(0, maxAvailable); } else if (childSize == LayoutParams.WRAP_CONTENT) { // Child wants to wrap content. Use AT_MOST to communicate diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 74843ee0f06b..7ca333947918 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -1412,39 +1412,108 @@ public class RemoteViews implements Parcelable, Filter { public TextViewDrawableAction(int viewId, boolean isRelative, int d1, int d2, int d3, int d4) { this.viewId = viewId; this.isRelative = isRelative; + this.useIcons = false; this.d1 = d1; this.d2 = d2; this.d3 = d3; this.d4 = d4; } + public TextViewDrawableAction(int viewId, boolean isRelative, + Icon i1, Icon i2, Icon i3, Icon i4) { + this.viewId = viewId; + this.isRelative = isRelative; + this.useIcons = true; + this.i1 = i1; + this.i2 = i2; + this.i3 = i3; + this.i4 = i4; + } + public TextViewDrawableAction(Parcel parcel) { viewId = parcel.readInt(); isRelative = (parcel.readInt() != 0); - d1 = parcel.readInt(); - d2 = parcel.readInt(); - d3 = parcel.readInt(); - d4 = parcel.readInt(); + useIcons = (parcel.readInt() != 0); + if (useIcons) { + if (parcel.readInt() != 0) { + i1 = Icon.CREATOR.createFromParcel(parcel); + } + if (parcel.readInt() != 0) { + i2 = Icon.CREATOR.createFromParcel(parcel); + } + if (parcel.readInt() != 0) { + i3 = Icon.CREATOR.createFromParcel(parcel); + } + if (parcel.readInt() != 0) { + i4 = Icon.CREATOR.createFromParcel(parcel); + } + } else { + d1 = parcel.readInt(); + d2 = parcel.readInt(); + d3 = parcel.readInt(); + d4 = parcel.readInt(); + } } public void writeToParcel(Parcel dest, int flags) { dest.writeInt(TAG); dest.writeInt(viewId); dest.writeInt(isRelative ? 1 : 0); - dest.writeInt(d1); - dest.writeInt(d2); - dest.writeInt(d3); - dest.writeInt(d4); + dest.writeInt(useIcons ? 1 : 0); + if (useIcons) { + if (i1 != null) { + dest.writeInt(1); + i1.writeToParcel(dest, 0); + } else { + dest.writeInt(0); + } + if (i2 != null) { + dest.writeInt(1); + i2.writeToParcel(dest, 0); + } else { + dest.writeInt(0); + } + if (i3 != null) { + dest.writeInt(1); + i3.writeToParcel(dest, 0); + } else { + dest.writeInt(0); + } + if (i4 != null) { + dest.writeInt(1); + i4.writeToParcel(dest, 0); + } else { + dest.writeInt(0); + } + } else { + dest.writeInt(d1); + dest.writeInt(d2); + dest.writeInt(d3); + dest.writeInt(d4); + } } @Override public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { final TextView target = (TextView) root.findViewById(viewId); if (target == null) return; - if (isRelative) { - target.setCompoundDrawablesRelativeWithIntrinsicBounds(d1, d2, d3, d4); + if (useIcons) { + final Context ctx = target.getContext(); + final Drawable id1 = i1 == null ? null : i1.loadDrawable(ctx); + final Drawable id2 = i2 == null ? null : i2.loadDrawable(ctx); + final Drawable id3 = i3 == null ? null : i3.loadDrawable(ctx); + final Drawable id4 = i4 == null ? null : i4.loadDrawable(ctx); + if (isRelative) { + target.setCompoundDrawablesRelativeWithIntrinsicBounds(id1, id2, id3, id4); + } else { + target.setCompoundDrawablesWithIntrinsicBounds(id1, id2, id3, id4); + } } else { - target.setCompoundDrawablesWithIntrinsicBounds(d1, d2, d3, d4); + if (isRelative) { + target.setCompoundDrawablesRelativeWithIntrinsicBounds(d1, d2, d3, d4); + } else { + target.setCompoundDrawablesWithIntrinsicBounds(d1, d2, d3, d4); + } } } @@ -1453,7 +1522,9 @@ public class RemoteViews implements Parcelable, Filter { } boolean isRelative = false; + boolean useIcons = false; int d1, d2, d3, d4; + Icon i1, i2, i3, i4; public final static int TAG = 11; } @@ -2067,6 +2138,41 @@ public class RemoteViews implements Parcelable, Filter { } /** + * Equivalent to calling {@link + * TextView#setCompoundDrawablesWithIntrinsicBounds(Drawable, Drawable, Drawable, Drawable)} + * using the drawables yielded by {@link Icon#loadDrawable(Context)}. + * + * @param viewId The id of the view whose text should change + * @param left an Icon to place to the left of the text, or 0 + * @param top an Icon to place above the text, or 0 + * @param right an Icon to place to the right of the text, or 0 + * @param bottom an Icon to place below the text, or 0 + * + * @hide + */ + public void setTextViewCompoundDrawables(int viewId, Icon left, Icon top, Icon right, Icon bottom) { + addAction(new TextViewDrawableAction(viewId, false, left, top, right, bottom)); + } + + /** + * Equivalent to calling {@link + * TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(Drawable, Drawable, Drawable, Drawable)} + * using the drawables yielded by {@link Icon#loadDrawable(Context)}. + * + * @param viewId The id of the view whose text should change + * @param start an Icon to place before the text (relative to the + * layout direction), or 0 + * @param top an Icon to place above the text, or 0 + * @param end an Icon to place after the text, or 0 + * @param bottom an Icon to place below the text, or 0 + * + * @hide + */ + public void setTextViewCompoundDrawablesRelative(int viewId, Icon start, Icon top, Icon end, Icon bottom) { + addAction(new TextViewDrawableAction(viewId, true, start, top, end, bottom)); + } + + /** * Equivalent to calling ImageView.setImageResource * * @param viewId The id of the view whose drawable should change @@ -2640,6 +2746,10 @@ public class RemoteViews implements Parcelable, Filter { public Resources.Theme getTheme() { return contextForResources.getTheme(); } + @Override + public String getPackageName() { + return contextForResources.getPackageName(); + } }; LayoutInflater inflater = (LayoutInflater) diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index 58a94b96a7f2..529d29530a61 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -356,7 +356,7 @@ public class ScrollView extends FrameLayout { final int heightPadding; final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion; - if (targetSdkVersion >= VERSION_CODES.MNC) { + if (targetSdkVersion >= VERSION_CODES.M) { widthPadding = mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin; heightPadding = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin; } else { diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java index acf1df931798..6e04eac4b18f 100644 --- a/core/java/android/widget/SimpleMonthView.java +++ b/core/java/android/widget/SimpleMonthView.java @@ -42,6 +42,7 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import com.android.internal.R; import com.android.internal.widget.ExploreByTouchHelper; +import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Locale; @@ -73,6 +74,7 @@ class SimpleMonthView extends View { private final SimpleDateFormat mTitleFormatter; private final SimpleDateFormat mDayOfWeekFormatter; + private final NumberFormat mDayFormatter; // Desired dimensions. private final int mDesiredMonthHeight; @@ -162,6 +164,7 @@ class SimpleMonthView extends View { final String titleFormat = DateFormat.getBestDateTimePattern(locale, DEFAULT_TITLE_FORMAT); mTitleFormatter = new SimpleDateFormat(titleFormat, locale); mDayOfWeekFormatter = new SimpleDateFormat(DAY_OF_WEEK_FORMAT, locale); + mDayFormatter = NumberFormat.getIntegerInstance(locale); initPaints(res); } @@ -454,7 +457,7 @@ class SimpleMonthView extends View { } p.setColor(dayTextColor); - canvas.drawText(Integer.toString(day), colCenterRtl, rowCenter - halfLineHeight, p); + canvas.drawText(mDayFormatter.format(day), colCenterRtl, rowCenter - halfLineHeight, p); col++; @@ -866,7 +869,7 @@ class SimpleMonthView extends View { */ private CharSequence getDayText(int id) { if (isValidDayOfMonth(id)) { - return Integer.toString(id); + return mDayFormatter.format(id); } return null; diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java index 5d7b56979218..bcde3158866a 100644 --- a/core/java/android/widget/TextClock.java +++ b/core/java/android/widget/TextClock.java @@ -120,12 +120,16 @@ public class TextClock extends TextView { private CharSequence mFormat12; private CharSequence mFormat24; + private CharSequence mDescFormat12; + private CharSequence mDescFormat24; @ExportedProperty private CharSequence mFormat; @ExportedProperty private boolean mHasSeconds; + private CharSequence mDescFormat; + private boolean mAttached; private Calendar mTime; @@ -301,6 +305,17 @@ public class TextClock extends TextView { } /** + * Like setFormat12Hour, but for the content description. + * @hide + */ + public void setContentDescriptionFormat12Hour(CharSequence format) { + mDescFormat12 = format; + + chooseFormat(); + onTimeChanged(); + } + + /** * Returns the formatting pattern used to display the date and/or time * in 24-hour mode. The formatting pattern syntax is described in * {@link DateFormat}. @@ -348,6 +363,17 @@ public class TextClock extends TextView { } /** + * Like setFormat24Hour, but for the content description. + * @hide + */ + public void setContentDescriptionFormat24Hour(CharSequence format) { + mDescFormat24 = format; + + chooseFormat(); + onTimeChanged(); + } + + /** * Sets whether this clock should always track the current user and not the user of the * current process. This is used for single instance processes like the systemUI who need * to display time for different users. @@ -460,8 +486,10 @@ public class TextClock extends TextView { if (format24Requested) { mFormat = abc(mFormat24, mFormat12, ld.timeFormat_Hm); + mDescFormat = abc(mDescFormat24, mDescFormat12, mFormat); } else { mFormat = abc(mFormat12, mFormat24, ld.timeFormat_hm); + mDescFormat = abc(mDescFormat12, mDescFormat24, mFormat); } boolean hadSeconds = mHasSeconds; @@ -547,6 +575,7 @@ public class TextClock extends TextView { private void onTimeChanged() { mTime.setTimeInMillis(System.currentTimeMillis()); setText(DateFormat.format(mFormat, mTime)); + setContentDescription(DateFormat.format(mDescFormat, mTime)); } /** @hide */ diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 131ba4674755..a1462c4886a0 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -2270,6 +2270,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @attr ref android.R.styleable#TextView_drawableRight * @attr ref android.R.styleable#TextView_drawableBottom */ + @android.view.RemotableViewMethod public void setCompoundDrawablesWithIntrinsicBounds(@Nullable Drawable left, @Nullable Drawable top, @Nullable Drawable right, @Nullable Drawable bottom) { @@ -2302,6 +2303,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @attr ref android.R.styleable#TextView_drawableEnd * @attr ref android.R.styleable#TextView_drawableBottom */ + @android.view.RemotableViewMethod public void setCompoundDrawablesRelative(@Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, @Nullable Drawable bottom) { Drawables dr = mDrawables; @@ -2472,6 +2474,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @attr ref android.R.styleable#TextView_drawableEnd * @attr ref android.R.styleable#TextView_drawableBottom */ + @android.view.RemotableViewMethod public void setCompoundDrawablesRelativeWithIntrinsicBounds(@Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, @Nullable Drawable bottom) { diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java index 6ba09c991bec..d552e542e527 100644 --- a/core/java/com/android/internal/app/AssistUtils.java +++ b/core/java/com/android/internal/app/AssistUtils.java @@ -23,6 +23,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; @@ -45,18 +46,24 @@ public class AssistUtils { ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE)); } - public void showSessionForActiveService(Bundle args, - IVoiceInteractionSessionShowCallback showCallback) { + public boolean showSessionForActiveService(Bundle args, int sourceFlags, + IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) { try { - mVoiceInteractionManagerService.showSessionForActiveService(args, showCallback); + if (mVoiceInteractionManagerService != null) { + return mVoiceInteractionManagerService.showSessionForActiveService(args, + sourceFlags, showCallback, activityToken); + } } catch (RemoteException e) { Log.w(TAG, "Failed to call showSessionForActiveService", e); } + return false; } public void launchVoiceAssistFromKeyguard() { try { - mVoiceInteractionManagerService.launchVoiceAssistFromKeyguard(); + if (mVoiceInteractionManagerService != null) { + mVoiceInteractionManagerService.launchVoiceAssistFromKeyguard(); + } } catch (RemoteException e) { Log.w(TAG, "Failed to call launchVoiceAssistFromKeyguard", e); } @@ -84,7 +91,11 @@ public class AssistUtils { public ComponentName getActiveServiceComponentName() { try { - return mVoiceInteractionManagerService.getActiveServiceComponentName(); + if (mVoiceInteractionManagerService != null) { + return mVoiceInteractionManagerService.getActiveServiceComponentName(); + } else { + return null; + } } catch (RemoteException e) { Log.w(TAG, "Failed to call getActiveServiceComponentName", e); return null; @@ -103,12 +114,24 @@ public class AssistUtils { public void hideCurrentSession() { try { - mVoiceInteractionManagerService.hideCurrentSession(); + if (mVoiceInteractionManagerService != null) { + mVoiceInteractionManagerService.hideCurrentSession(); + } } catch (RemoteException e) { Log.w(TAG, "Failed to call hideCurrentSession", e); } } + public void onLockscreenShown() { + try { + if (mVoiceInteractionManagerService != null) { + mVoiceInteractionManagerService.onLockscreenShown(); + } + } catch (RemoteException e) { + Log.w(TAG, "Failed to call onLockscreenShown", e); + } + } + public ComponentName getAssistComponentForUser(int userId) { final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(), Settings.Secure.ASSISTANT, userId); diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index c4f57c7c38bf..d9faece9485f 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -471,6 +471,36 @@ public class ChooserActivity extends ResolverActivity { return false; } + void filterServiceTargets(String packageName, List<ChooserTarget> targets) { + if (targets == null) { + return; + } + + final PackageManager pm = getPackageManager(); + for (int i = targets.size() - 1; i >= 0; i--) { + final ChooserTarget target = targets.get(i); + final ComponentName targetName = target.getComponentName(); + if (packageName != null && packageName.equals(targetName.getPackageName())) { + // Anything from the original target's package is fine. + continue; + } + + boolean remove; + try { + final ActivityInfo ai = pm.getActivityInfo(targetName, 0); + remove = !ai.exported || ai.permission != null; + } catch (NameNotFoundException e) { + Log.e(TAG, "Target " + target + " returned by " + packageName + + " component not found"); + remove = true; + } + + if (remove) { + targets.remove(i); + } + } + } + @Override ResolveListAdapter createAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid, @@ -487,6 +517,7 @@ public class ChooserActivity extends ResolverActivity { private final ResolveInfo mBackupResolveInfo; private final ChooserTarget mChooserTarget; private Drawable mBadgeIcon = null; + private CharSequence mBadgeContentDescription; private Drawable mDisplayIcon; private final Intent mFillInIntent; private final int mFillInFlags; @@ -502,7 +533,9 @@ public class ChooserActivity extends ResolverActivity { if (ri != null) { final ActivityInfo ai = ri.activityInfo; if (ai != null && ai.applicationInfo != null) { - mBadgeIcon = getPackageManager().getApplicationIcon(ai.applicationInfo); + final PackageManager pm = getPackageManager(); + mBadgeIcon = pm.getApplicationIcon(ai.applicationInfo); + mBadgeContentDescription = pm.getApplicationLabel(ai.applicationInfo); } } } @@ -525,6 +558,7 @@ public class ChooserActivity extends ResolverActivity { mBackupResolveInfo = other.mBackupResolveInfo; mChooserTarget = other.mChooserTarget; mBadgeIcon = other.mBadgeIcon; + mBadgeContentDescription = other.mBadgeContentDescription; mDisplayIcon = other.mDisplayIcon; mFillInIntent = fillInIntent; mFillInFlags = flags; @@ -554,11 +588,11 @@ public class ChooserActivity extends ResolverActivity { return null; } - private Intent getFillInIntent() { + private Intent getBaseIntentToSend() { Intent result = mSourceInfo != null ? mSourceInfo.getResolvedIntent() : getTargetIntent(); if (result == null) { - Log.e(TAG, "ChooserTargetInfo#getFillInIntent: no fillIn intent available"); + Log.e(TAG, "ChooserTargetInfo: no base intent available to send"); } else { result = new Intent(result); if (mFillInIntent != null) { @@ -571,31 +605,24 @@ public class ChooserActivity extends ResolverActivity { @Override public boolean start(Activity activity, Bundle options) { - final Intent intent = getFillInIntent(); - if (intent == null) { - return false; - } - return mChooserTarget.sendIntent(activity, intent); + throw new RuntimeException("ChooserTargets should be started as caller."); } @Override public boolean startAsCaller(Activity activity, Bundle options, int userId) { - final Intent intent = getFillInIntent(); + final Intent intent = getBaseIntentToSend(); if (intent == null) { return false; } - // ChooserTargets will launch with their IntentSender's identity - return mChooserTarget.sendIntent(activity, intent); + intent.setComponent(mChooserTarget.getComponentName()); + intent.putExtras(mChooserTarget.getIntentExtras()); + activity.startActivityAsCaller(intent, options, true, userId); + return true; } @Override public boolean startAsUser(Activity activity, Bundle options, UserHandle user) { - final Intent intent = getFillInIntent(); - if (intent == null) { - return false; - } - // ChooserTargets will launch with their IntentSender's identity - return mChooserTarget.sendIntent(activity, intent); + throw new RuntimeException("ChooserTargets should be started as caller."); } @Override @@ -624,6 +651,11 @@ public class ChooserActivity extends ResolverActivity { } @Override + public CharSequence getBadgeContentDescription() { + return mBadgeContentDescription; + } + + @Override public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) { return new ChooserTargetInfo(this, fillInIntent, flags); } @@ -998,6 +1030,8 @@ public class ChooserActivity extends ResolverActivity { private final IChooserTargetResult mChooserTargetResult = new IChooserTargetResult.Stub() { @Override public void sendResult(List<ChooserTarget> targets) throws RemoteException { + filterServiceTargets(mOriginalTarget.getResolveInfo().activityInfo.packageName, + targets); final Message msg = Message.obtain(); msg.what = CHOOSER_TARGET_SERVICE_RESULT; msg.obj = new ServiceResultInfo(mOriginalTarget, targets, diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index 73c48334b1d1..9fa2c23dc953 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -38,6 +38,7 @@ interface IAppOpsService { int checkPackage(int uid, String packageName); List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops); List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops); + void setUidMode(int code, int uid, int mode); void setMode(int code, int uid, String packageName, int mode); void resetAllModes(int reqUserId, String reqPackageName); int checkAudioOperation(int code, int usage, int uid, String packageName); diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl index 73ad98107ae4..1a963f30ca07 100644 --- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl +++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl @@ -39,6 +39,7 @@ interface IVoiceInteractionManagerService { void finish(IBinder token); void setDisabledShowContext(int flags); int getDisabledShowContext(); + int getUserDisabledShowContext(); /** * Gets the registered Sound model for keyphrase detection for the current user. @@ -96,10 +97,12 @@ interface IVoiceInteractionManagerService { * affordances. * * @param args the bundle to pass as arguments to the voice interaction session - * @param showCallback callback to be notified when the session was shown + * @param sourceFlags flags indicating the source of this show + * @param showCallback optional callback to be notified when the session was shown + * @param activityToken optional token of activity that needs to be on top */ - void showSessionForActiveService(in Bundle args, - IVoiceInteractionSessionShowCallback showCallback); + boolean showSessionForActiveService(in Bundle args, int sourceFlags, + IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken); /** * Hides the session from the active service, if it is showing. @@ -128,4 +131,9 @@ interface IVoiceInteractionManagerService { * from the lockscreen. */ boolean activeServiceSupportsLaunchFromKeyguard(); + + /** + * Called when the lockscreen got shown. + */ + void onLockscreenShown(); } diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index 233bee3b5bc0..39b66aa24a82 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -103,7 +103,7 @@ public class IntentForwarderActivity extends Activity { || ChooserActivity.class.getName().equals(ri.activityInfo.name)); try { - startActivityAsCaller(newIntent, null, targetUserId); + startActivityAsCaller(newIntent, null, false, targetUserId); } catch (RuntimeException e) { int launchedFromUid = -1; String launchedFromPackage = "?"; diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 7bc18f39c8af..7dd3bed079fc 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -19,14 +19,11 @@ 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; @@ -503,7 +500,7 @@ public class ResolverActivity extends Activity { mPackageMonitor.unregister(); mRegistered = false; } - if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { + if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && !isVoiceInteraction()) { // This resolver is in the unusual situation where it has been // launched at the top of a new task. We don't let it be added // to the recent tasks shown to the user, and we need to make sure @@ -813,8 +810,13 @@ public class ResolverActivity extends Activity { void configureContentView(List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, boolean alwaysUseOption) { + // The last argument of createAdapter is whether to do special handling + // of the last used choice to highlight it in the list. We need to always + // turn this off when running under voice interaction, since it results in + // a more complicated UI that the current voice interaction flow is not able + // to handle. mAdapter = createAdapter(this, payloadIntents, initialIntents, rList, - mLaunchedFromUid, alwaysUseOption); + mLaunchedFromUid, alwaysUseOption && !isVoiceInteraction()); final int layoutId; if (mAdapter.hasFilteredItem()) { @@ -930,6 +932,11 @@ public class ResolverActivity extends Activity { } @Override + public CharSequence getBadgeContentDescription() { + return null; + } + + @Override public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) { return new DisplayResolveInfo(this, fillInIntent, flags); } @@ -973,7 +980,7 @@ public class ResolverActivity extends Activity { @Override public boolean startAsCaller(Activity activity, Bundle options, int userId) { - activity.startActivityAsCaller(mResolvedIntent, options, userId); + activity.startActivityAsCaller(mResolvedIntent, options, false, userId); return true; } @@ -1070,6 +1077,11 @@ public class ResolverActivity extends Activity { public Drawable getBadgeIcon(); /** + * @return The content description for the badge icon + */ + public CharSequence getBadgeContentDescription(); + + /** * Clone this target with the given fill-in information. */ public TargetInfo cloneFilledIn(Intent fillInIntent, int flags); @@ -1540,6 +1552,7 @@ public class ResolverActivity extends Activity { final Drawable badge = info.getBadgeIcon(); if (badge != null) { holder.badge.setImageDrawable(badge); + holder.badge.setContentDescription(info.getBadgeContentDescription()); holder.badge.setVisibility(View.VISIBLE); } else { holder.badge.setVisibility(View.GONE); diff --git a/core/java/com/android/internal/logging/MetricsConstants.java b/core/java/com/android/internal/logging/MetricsConstants.java index 7278d5c07f00..b90cb364defa 100644 --- a/core/java/com/android/internal/logging/MetricsConstants.java +++ b/core/java/com/android/internal/logging/MetricsConstants.java @@ -250,6 +250,18 @@ public interface MetricsConstants { public static final int OVERVIEW_ACTIVITY = 224; public static final int ABOUT_LEGAL_SETTINGS = 225; public static final int ACTION_SEARCH_RESULTS = 226; + public static final int TUNER = 227; + public static final int TUNER_QS = 228; + public static final int TUNER_DEMO_MODE = 229; + public static final int TUNER_QS_REORDER = 230; + public static final int TUNER_QS_ADD = 231; + public static final int TUNER_QS_REMOVE = 232; + public static final int TUNER_STATUS_BAR_ENABLE = 233; + public static final int TUNER_STATUS_BAR_DISABLE = 234; + public static final int TUNER_DEMO_MODE_ENABLED = 235; + public static final int TUNER_DEMO_MODE_ON = 236; + public static final int TUNER_BATTERY_PERCENTAGE = 237; + public static final int FUELGAUGE_INACTIVE_APPS = 238; // These constants must match those in the analytic pipeline, do not edit. // Add temporary values to the top of MetricsLogger instead. diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index cbe535fb74fd..d954b7161513 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -27,7 +27,7 @@ import android.view.View; */ public class MetricsLogger implements MetricsConstants { // Temporary constants go here, to await migration to MetricsConstants. - // next value is 227; + // next value is 239; public static void visible(Context context, int category) throws IllegalArgumentException { if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) { diff --git a/core/java/com/android/internal/midi/MidiConstants.java b/core/java/com/android/internal/midi/MidiConstants.java index c13e5fcca839..b6b8bf0a34b6 100644 --- a/core/java/com/android/internal/midi/MidiConstants.java +++ b/core/java/com/android/internal/midi/MidiConstants.java @@ -55,18 +55,30 @@ public final class MidiConstants { public final static int SYSTEM_BYTE_LENGTHS[] = { 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - /********************************************************************/ - public static int getBytesPerMessage(int command) { - if ((command < 0x80) || (command > 0xFF)) { - return 0; - } else if (command >= 0xF0) { - return SYSTEM_BYTE_LENGTHS[command & 0x0F]; + /** + * MIDI messages, except for SysEx, are 1,2 or 3 bytes long. + * You can tell how long a MIDI message is from the first status byte. + * Do not call this for SysEx, which has variable length. + * @param statusByte + * @return number of bytes in a complete message or zero if data byte passed + */ + public static int getBytesPerMessage(byte statusByte) { + // Java bytes are signed so we need to mask off the high bits + // to get a value between 0 and 255. + int statusInt = statusByte & 0xFF; + if (statusInt >= 0xF0) { + // System messages use low nibble for size. + return SYSTEM_BYTE_LENGTHS[statusInt & 0x0F]; + } else if(statusInt >= 0x80) { + // Channel voice messages use high nibble for size. + return CHANNEL_BYTE_LENGTHS[(statusInt >> 4) - 8]; } else { - return CHANNEL_BYTE_LENGTHS[(command >> 4) - 8]; + return 0; // data byte } } + /** * @param msg * @param offset diff --git a/core/java/com/android/internal/midi/MidiFramer.java b/core/java/com/android/internal/midi/MidiFramer.java index 058f57cff38c..62517fa82953 100644 --- a/core/java/com/android/internal/midi/MidiFramer.java +++ b/core/java/com/android/internal/midi/MidiFramer.java @@ -17,7 +17,7 @@ package com.android.internal.midi; import android.media.midi.MidiReceiver; -import android.util.Log; +//import android.util.Log; import java.io.IOException; @@ -37,7 +37,7 @@ public class MidiFramer extends MidiReceiver { private MidiReceiver mReceiver; private byte[] mBuffer = new byte[3]; private int mCount; - private int mRunningStatus; + private byte mRunningStatus; private int mNeeded; private boolean mInSysEx; @@ -59,22 +59,22 @@ public class MidiFramer extends MidiReceiver { @Override public void onSend(byte[] data, int offset, int count, long timestamp) throws IOException { - // Log.i(TAG, formatMidiData(data, offset, count)); int sysExStartOffset = (mInSysEx ? offset : -1); for (int i = 0; i < count; i++) { - int b = data[offset] & 0xFF; - if (b >= 0x80) { // status byte? - if (b < 0xF0) { // channel message? - mRunningStatus = (byte) b; + final byte currentByte = data[offset]; + final int currentInt = currentByte & 0xFF; + if (currentInt >= 0x80) { // status byte? + if (currentInt < 0xF0) { // channel message? + mRunningStatus = currentByte; mCount = 1; - mNeeded = MidiConstants.getBytesPerMessage(b) - 1; - } else if (b < 0xF8) { // system common? - if (b == 0xF0 /* SysEx Start */) { + mNeeded = MidiConstants.getBytesPerMessage(currentByte) - 1; + } else if (currentInt < 0xF8) { // system common? + if (currentInt == 0xF0 /* SysEx Start */) { // Log.i(TAG, "SysEx Start"); mInSysEx = true; sysExStartOffset = offset; - } else if (b == 0xF7 /* SysEx End */) { + } else if (currentInt == 0xF7 /* SysEx End */) { // Log.i(TAG, "SysEx End"); if (mInSysEx) { mReceiver.send(data, sysExStartOffset, @@ -83,10 +83,10 @@ public class MidiFramer extends MidiReceiver { sysExStartOffset = -1; } } else { - mBuffer[0] = (byte) b; + mBuffer[0] = currentByte; mRunningStatus = 0; mCount = 1; - mNeeded = MidiConstants.getBytesPerMessage(b) - 1; + mNeeded = MidiConstants.getBytesPerMessage(currentByte) - 1; } } else { // real-time? // Single byte message interleaved with other data. @@ -98,12 +98,11 @@ public class MidiFramer extends MidiReceiver { mReceiver.send(data, offset, 1, timestamp); } } else { // data byte - // Save SysEx data for SysEx End marker or end of buffer. if (!mInSysEx) { - mBuffer[mCount++] = (byte) b; + mBuffer[mCount++] = currentByte; if (--mNeeded == 0) { if (mRunningStatus != 0) { - mBuffer[0] = (byte) mRunningStatus; + mBuffer[0] = mRunningStatus; } mReceiver.send(mBuffer, 0, mCount, timestamp); mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1; diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java index 264b8c1458ff..f178c8cf7ece 100644 --- a/core/java/com/android/internal/os/BatteryStatsHelper.java +++ b/core/java/com/android/internal/os/BatteryStatsHelper.java @@ -47,6 +47,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Locale; /** * A helper class for retrieving the power usage information for all applications and services. @@ -125,6 +126,9 @@ public final class BatteryStatsHelper { PowerCalculator mCameraPowerCalculator; PowerCalculator mFlashlightPowerCalculator; + boolean mHasWifiPowerReporting = false; + boolean mHasBluetoothPowerReporting = false; + public static boolean checkWifiOnly(Context context) { ConnectivityManager cm = (ConnectivityManager)context.getSystemService( Context.CONNECTIVITY_SERVICE); @@ -267,15 +271,20 @@ public final class BatteryStatsHelper { public static String makemAh(double power) { if (power == 0) return "0"; - else if (power < .00001) return String.format("%.8f", power); - else if (power < .0001) return String.format("%.7f", power); - else if (power < .001) return String.format("%.6f", power); - else if (power < .01) return String.format("%.5f", power); - else if (power < .1) return String.format("%.4f", power); - else if (power < 1) return String.format("%.3f", power); - else if (power < 10) return String.format("%.2f", power); - else if (power < 100) return String.format("%.1f", power); - else return String.format("%.0f", power); + + final String format; + if (power < .00001) format = "%.8f"; + else if (power < .0001) format = "%.7f"; + else if (power < .001) format = "%.6f"; + else if (power < .01) format = "%.5f"; + else if (power < .1) format = "%.4f"; + else if (power < 1) format = "%.3f"; + else if (power < 10) format = "%.2f"; + else if (power < 100) format = "%.1f"; + else format = "%.0f"; + + // Use English locale because this is never used in UI (only in checkin and dump). + return String.format(Locale.ENGLISH, format, power); } /** @@ -343,21 +352,23 @@ public final class BatteryStatsHelper { } mMobileRadioPowerCalculator.reset(mStats); - if (mWifiPowerCalculator == null) { - if (checkHasWifiPowerReporting(mStats, mPowerProfile)) { - mWifiPowerCalculator = new WifiPowerCalculator(mPowerProfile); - } else { - mWifiPowerCalculator = new WifiPowerEstimator(mPowerProfile); - } + // checkHasWifiPowerReporting can change if we get energy data at a later point, so + // always check this field. + final boolean hasWifiPowerReporting = checkHasWifiPowerReporting(mStats, mPowerProfile); + if (mWifiPowerCalculator == null || hasWifiPowerReporting != mHasWifiPowerReporting) { + mWifiPowerCalculator = hasWifiPowerReporting ? + new WifiPowerCalculator(mPowerProfile) : + new WifiPowerEstimator(mPowerProfile); + mHasWifiPowerReporting = hasWifiPowerReporting; } mWifiPowerCalculator.reset(); - if (mBluetoothPowerCalculator == null) { - if (checkHasBluetoothPowerReporting(mStats, mPowerProfile)) { - mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile); - } else { - mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile); - } + final boolean hasBluetoothPowerReporting = checkHasBluetoothPowerReporting(mStats, + mPowerProfile); + if (mBluetoothPowerCalculator == null || + hasBluetoothPowerReporting != mHasBluetoothPowerReporting) { + mBluetoothPowerCalculator = new BluetoothPowerCalculator(mPowerProfile); + mHasBluetoothPowerReporting = hasBluetoothPowerReporting; } mBluetoothPowerCalculator.reset(); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 60f47d673c18..6c7e2984bb4c 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -2560,14 +2560,24 @@ public final class BatteryStatsImpl extends BatteryStats { addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid); } + boolean ensureStartClockTime(final long currentTime) { + final long ABOUT_ONE_YEAR = 365*24*60*60*1000L; + if (currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) { + // If the start clock time has changed by more than a year, then presumably + // the previous time was completely bogus. So we are going to figure out a + // new time based on how much time has elapsed since we started counting. + mStartClockTime = currentTime - (SystemClock.elapsedRealtime()-(mRealtimeStart/1000)); + return true; + } + return false; + } + public void noteCurrentTimeChangedLocked() { final long currentTime = System.currentTimeMillis(); final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime); - if (isStartClockTimeValid()) { - mStartClockTime = currentTime; - } + ensureStartClockTime(currentTime); } public void noteProcessStartLocked(String name, int uid) { @@ -4306,19 +4316,11 @@ public final class BatteryStatsImpl extends BatteryStats { } } - boolean isStartClockTimeValid() { - return mStartClockTime > 365*24*60*60*1000L; - } - @Override public long getStartClockTime() { - if (!isStartClockTimeValid()) { - // If the last clock time we got was very small, then we hadn't had a real - // time yet, so try to get it again. - mStartClockTime = System.currentTimeMillis(); - if (isStartClockTimeValid()) { - recordCurrentTimeChangeLocked(mStartClockTime, SystemClock.elapsedRealtime(), - SystemClock.uptimeMillis()); - } + final long currentTime = System.currentTimeMillis(); + if (ensureStartClockTime(currentTime)) { + recordCurrentTimeChangeLocked(currentTime, SystemClock.elapsedRealtime(), + SystemClock.uptimeMillis()); } return mStartClockTime; } @@ -7672,6 +7674,7 @@ public final class BatteryStatsImpl extends BatteryStats { final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs; long leftOverRxTimeMs = rxTimeMs; + long leftOverTxTimeMs = txTimeMs; if (DEBUG_ENERGY) { Slog.d(TAG, "------ BEGIN WiFi power blaming ------"); @@ -7703,6 +7706,10 @@ public final class BatteryStatsImpl extends BatteryStats { Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > " + rxTimeMs + " ms). Normalizing scan time."); } + if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) { + Slog.d(TAG, " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > " + + txTimeMs + " ms). Normalizing scan time."); + } // Actually assign and distribute power usage to apps. for (int i = 0; i < uidStatsSize; i++) { @@ -7714,23 +7721,34 @@ public final class BatteryStatsImpl extends BatteryStats { // Set the new mark so that next time we get new data since this point. uid.mWifiScanTimer.setMark(elapsedRealtimeMs); + long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs; + long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs; + + // Our total scan time is more than the reported Tx/Rx time. + // This is possible because the cost of a scan is approximate. + // Let's normalize the result so that we evenly blame each app + // scanning. + // + // This means that we may have apps that transmitted/received packets not be + // blamed for this, but this is fine as scans are relatively more expensive. if (totalScanTimeMs > rxTimeMs) { - // Our total scan time is more than the reported Rx time. - // This is possible because the cost of a scan is approximate. - // Let's normalize the result so that we evenly blame each app - // scanning. - // - // This means that we may have apps that received packets not be blamed - // for this, but this is fine as scans are relatively more expensive. - scanTimeSinceMarkMs = (rxTimeMs * scanTimeSinceMarkMs) / totalScanTimeMs; + scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) / + totalScanTimeMs; + } + if (totalScanTimeMs > txTimeMs) { + scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) / + totalScanTimeMs; } if (DEBUG_ENERGY) { - Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": " - + scanTimeSinceMarkMs + " ms)"); + Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:" + + scanRxTimeSinceMarkMs + " ms Tx:" + + scanTxTimeSinceMarkMs + " ms)"); } - uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanTimeSinceMarkMs); - leftOverRxTimeMs -= scanTimeSinceMarkMs; + uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanRxTimeSinceMarkMs); + uid.noteWifiControllerActivityLocked(CONTROLLER_TX_TIME, scanTxTimeSinceMarkMs); + leftOverRxTimeMs -= scanRxTimeSinceMarkMs; + leftOverTxTimeMs -= scanTxTimeSinceMarkMs; } // Distribute evenly the power consumed while Idle to each app holding a WiFi @@ -7753,12 +7771,14 @@ public final class BatteryStatsImpl extends BatteryStats { if (DEBUG_ENERGY) { Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms"); + Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms"); } - // Distribute the Tx power appropriately between all apps that transmitted packets. + // Distribute the remaining Tx power appropriately between all apps that transmitted + // packets. for (int i = 0; i < txPackets.size(); i++) { final Uid uid = getUidStatsLocked(txPackets.keyAt(i)); - final long myTxTimeMs = (txPackets.valueAt(i) * txTimeMs) / totalTxPackets; + final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs) / totalTxPackets; if (DEBUG_ENERGY) { Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms"); } @@ -7913,6 +7933,8 @@ public final class BatteryStatsImpl extends BatteryStats { return; } + // Record whether we've seen a non-zero time (for debugging b/22716723). + boolean seenNonZeroTime = false; for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) { String name = ent.getKey(); KernelWakelockStats.Entry kws = ent.getValue(); @@ -7926,17 +7948,31 @@ public final class BatteryStatsImpl extends BatteryStats { kwlt.updateCurrentReportedCount(kws.mCount); kwlt.updateCurrentReportedTotalTime(kws.mTotalTime); kwlt.setUpdateVersion(kws.mVersion); + + if (kws.mVersion != wakelockStats.kernelWakelockVersion) + seenNonZeroTime |= kws.mTotalTime > 0; } + int numWakelocksSetStale = 0; if (wakelockStats.size() != mKernelWakelockStats.size()) { // Set timers to stale if they didn't appear in /proc/wakelocks this time. for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) { SamplingTimer st = ent.getValue(); if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) { st.setStale(); + numWakelocksSetStale++; } } } + + if (!seenNonZeroTime) { + Slog.wtf(TAG, "All kernel wakelocks had time of zero"); + } + + if (numWakelocksSetStale == mKernelWakelockStats.size()) { + Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" + + wakelockStats.kernelWakelockVersion); + } } // We use an anonymous class to access these variables, diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java index 768d586b6f1a..6654ea5683e3 100644 --- a/core/java/com/android/internal/os/KernelWakelockReader.java +++ b/core/java/com/android/internal/os/KernelWakelockReader.java @@ -68,13 +68,15 @@ public class KernelWakelockReader { try { FileInputStream is; try { - is = new FileInputStream(sWakeupSourceFile); - wakeup_sources = true; + is = new FileInputStream(sWakelockFile); + wakeup_sources = false; } catch (java.io.FileNotFoundException e) { try { - is = new FileInputStream(sWakelockFile); - wakeup_sources = false; + is = new FileInputStream(sWakeupSourceFile); + wakeup_sources = true; } catch (java.io.FileNotFoundException e2) { + Slog.wtf(TAG, "neither " + sWakelockFile + " nor " + + sWakeupSourceFile + " exists"); return null; } } @@ -82,6 +84,7 @@ public class KernelWakelockReader { len = is.read(buffer); is.close(); } catch (java.io.IOException e) { + Slog.wtf(TAG, "failed to read kernel wakelocks", e); return null; } @@ -171,6 +174,13 @@ public class KernelWakelockReader { numUpdatedWlNames++; } } + } else if (!parsed) { + try { + Slog.wtf(TAG, "Failed to parse proc line: " + + new String(wlBuffer, startIndex, endIndex - startIndex)); + } catch (Exception e) { + Slog.wtf(TAG, "Failed to parse proc line!"); + } } startIndex = endIndex; } diff --git a/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl b/core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl index a2784d941474..ef8478c4a5ab 100644 --- a/core/java/com/android/internal/policy/IKeyguardShowCallback.aidl +++ b/core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl @@ -15,6 +15,6 @@ */ package com.android.internal.policy; -oneway interface IKeyguardShowCallback { - void onShown(IBinder windowToken); +oneway interface IKeyguardDrawnCallback { + void onDrawn(); } diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl index 7ab4651979e9..e330de24f6d6 100644 --- a/core/java/com/android/internal/policy/IKeyguardService.aidl +++ b/core/java/com/android/internal/policy/IKeyguardService.aidl @@ -15,7 +15,7 @@ */ package com.android.internal.policy; -import com.android.internal.policy.IKeyguardShowCallback; +import com.android.internal.policy.IKeyguardDrawnCallback; import com.android.internal.policy.IKeyguardStateCallback; import com.android.internal.policy.IKeyguardExitCallback; @@ -57,7 +57,23 @@ oneway interface IKeyguardService { /** * Called when the device has started waking up. */ - void onStartedWakingUp(IKeyguardShowCallback callback); + void onStartedWakingUp(); + + /** + * Called when the device screen is turning on. + */ + void onScreenTurningOn(IKeyguardDrawnCallback callback); + + /** + * Called when the screen has actually turned on. + */ + void onScreenTurnedOn(); + + /** + * Called when the screen has turned off. + */ + void onScreenTurnedOff(); + void setKeyguardEnabled(boolean enabled); void onSystemReady(); void doKeyguardTimeout(in Bundle options); diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 9bd2eec96233..dd7ea4506432 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -32,7 +32,6 @@ import android.os.UserHandle; import android.view.ActionMode; import android.view.ContextThemeWrapper; -import android.view.Display; import android.view.Gravity; import android.view.IRotationWatcher.Stub; import android.view.IWindowManager; @@ -3533,7 +3532,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { public void onDestroyActionMode(ActionMode mode) { mWrapped.onDestroyActionMode(mode); final boolean isMncApp = mContext.getApplicationInfo().targetSdkVersion - >= Build.VERSION_CODES.MNC; + >= Build.VERSION_CODES.M; final boolean isPrimary; final boolean isFloating; if (isMncApp) { diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java index 32746c2e2d8e..6393fbae7180 100644 --- a/core/java/com/android/internal/util/XmlUtils.java +++ b/core/java/com/android/internal/util/XmlUtils.java @@ -20,6 +20,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Bitmap.CompressFormat; import android.net.Uri; +import android.text.TextUtils; import android.util.ArrayMap; import android.util.Base64; import android.util.Xml; @@ -45,6 +46,8 @@ import java.util.Set; /** {@hide} */ public class XmlUtils { + private static final String STRING_ARRAY_SEPARATOR = ":"; + public static void skipCurrentTag(XmlPullParser parser) throws XmlPullParserException, IOException { int outerDepth = parser.getDepth(); diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 444f878caac0..9211eaaf4592 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -23,10 +23,10 @@ import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; +import android.graphics.CanvasProperty; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; -import android.graphics.RectF; import android.media.AudioManager; import android.os.Bundle; import android.os.Debug; @@ -38,8 +38,10 @@ import android.provider.Settings; import android.util.AttributeSet; import android.util.IntArray; import android.util.Log; +import android.view.DisplayListCanvas; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; +import android.view.RenderNodeAnimator; import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -92,7 +94,7 @@ public class LockPatternView extends View { */ private static final float DRAG_THRESHHOLD = 0.0f; public static final int VIRTUAL_BASE_VIEW_ID = 1; - public static final boolean DEBUG_A11Y = true; + public static final boolean DEBUG_A11Y = false; private static final String TAG = "LockPatternView"; private OnPatternListener mOnPatternListener; @@ -200,10 +202,16 @@ public class LockPatternView extends View { } public static class CellState { - public float scale = 1.0f; - public float translateY = 0.0f; - public float alpha = 1.0f; - public float size; + int row; + int col; + boolean hwAnimating; + CanvasProperty<Float> hwRadius; + CanvasProperty<Float> hwCenterX; + CanvasProperty<Float> hwCenterY; + CanvasProperty<Paint> hwPaint; + float radius; + float translationY; + float alpha = 1f; public float lineEndX = Float.MIN_VALUE; public float lineEndY = Float.MIN_VALUE; public ValueAnimator lineAnimator; @@ -313,7 +321,9 @@ public class LockPatternView extends View { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { mCellStates[i][j] = new CellState(); - mCellStates[i][j].size = mDotSize; + mCellStates[i][j].radius = mDotSize/2; + mCellStates[i][j].row = i; + mCellStates[i][j].col = j; } } @@ -412,6 +422,112 @@ public class LockPatternView extends View { invalidate(); } + public void startCellStateAnimation(CellState cellState, float startAlpha, float endAlpha, + float startTranslationY, float endTranslationY, float startScale, float endScale, + long delay, long duration, + Interpolator interpolator, Runnable finishRunnable) { + if (isHardwareAccelerated()) { + startCellStateAnimationHw(cellState, startAlpha, endAlpha, startTranslationY, + endTranslationY, startScale, endScale, delay, duration, interpolator, + finishRunnable); + } else { + startCellStateAnimationSw(cellState, startAlpha, endAlpha, startTranslationY, + endTranslationY, startScale, endScale, delay, duration, interpolator, + finishRunnable); + } + } + + private void startCellStateAnimationSw(final CellState cellState, + final float startAlpha, final float endAlpha, + final float startTranslationY, final float endTranslationY, + final float startScale, final float endScale, + long delay, long duration, Interpolator interpolator, final Runnable finishRunnable) { + cellState.alpha = startAlpha; + cellState.translationY = startTranslationY; + cellState.radius = mDotSize/2 * startScale; + ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f); + animator.setDuration(duration); + animator.setStartDelay(delay); + animator.setInterpolator(interpolator); + animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + float t = (float) animation.getAnimatedValue(); + cellState.alpha = (1 - t) * startAlpha + t * endAlpha; + cellState.translationY = (1 - t) * startTranslationY + t * endTranslationY; + cellState.radius = mDotSize/2 * ((1 - t) * startScale + t * endScale); + invalidate(); + } + }); + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + if (finishRunnable != null) { + finishRunnable.run(); + } + } + }); + animator.start(); + } + + private void startCellStateAnimationHw(final CellState cellState, + float startAlpha, float endAlpha, + float startTranslationY, float endTranslationY, + float startScale, float endScale, + long delay, long duration, Interpolator interpolator, final Runnable finishRunnable) { + cellState.alpha = endAlpha; + cellState.translationY = endTranslationY; + cellState.radius = mDotSize/2 * endScale; + cellState.hwAnimating = true; + cellState.hwCenterY = CanvasProperty.createFloat( + getCenterYForRow(cellState.row) + startTranslationY); + cellState.hwCenterX = CanvasProperty.createFloat(getCenterXForColumn(cellState.col)); + cellState.hwRadius = CanvasProperty.createFloat(mDotSize/2 * startScale); + mPaint.setColor(getCurrentColor(false)); + mPaint.setAlpha((int) (startAlpha * 255)); + cellState.hwPaint = CanvasProperty.createPaint(new Paint(mPaint)); + + startRtFloatAnimation(cellState.hwCenterY, + getCenterYForRow(cellState.row) + endTranslationY, delay, duration, interpolator); + startRtFloatAnimation(cellState.hwRadius, mDotSize/2 * endScale, delay, duration, + interpolator); + startRtAlphaAnimation(cellState, endAlpha, delay, duration, interpolator, + new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + cellState.hwAnimating = false; + if (finishRunnable != null) { + finishRunnable.run(); + } + } + }); + + invalidate(); + } + + private void startRtAlphaAnimation(CellState cellState, float endAlpha, + long delay, long duration, Interpolator interpolator, + Animator.AnimatorListener listener) { + RenderNodeAnimator animator = new RenderNodeAnimator(cellState.hwPaint, + RenderNodeAnimator.PAINT_ALPHA, (int) (endAlpha * 255)); + animator.setDuration(duration); + animator.setStartDelay(delay); + animator.setInterpolator(interpolator); + animator.setTarget(this); + animator.addListener(listener); + animator.start(); + } + + private void startRtFloatAnimation(CanvasProperty<Float> property, float endValue, + long delay, long duration, Interpolator interpolator) { + RenderNodeAnimator animator = new RenderNodeAnimator(property, endValue); + animator.setDuration(duration); + animator.setStartDelay(delay); + animator.setInterpolator(interpolator); + animator.setTarget(this); + animator.start(); + } + private void notifyCellAdded() { // sendAccessEvent(R.string.lockscreen_access_pattern_cell_added); if (mOnPatternListener != null) { @@ -452,9 +568,11 @@ public class LockPatternView extends View { @Override protected boolean dispatchHoverEvent(MotionEvent event) { - // Give TouchHelper first right of refusal - boolean handled = mExploreByTouchHelper.dispatchHoverEvent(event); - return super.dispatchHoverEvent(event) || handled; + // Dispatch to onHoverEvent first so mPatternInProgress is up to date when the + // helper gets the event. + boolean handled = super.dispatchHoverEvent(event); + handled |= mExploreByTouchHelper.dispatchHoverEvent(event); + return handled; } /** @@ -603,14 +721,15 @@ public class LockPatternView extends View { private void startCellActivatedAnimation(Cell cell) { final CellState cellState = mCellStates[cell.row][cell.column]; - startSizeAnimation(mDotSize, mDotSizeActivated, 96, mLinearOutSlowInInterpolator, + startRadiusAnimation(mDotSize/2, mDotSizeActivated/2, 96, mLinearOutSlowInInterpolator, cellState, new Runnable() { - @Override - public void run() { - startSizeAnimation(mDotSizeActivated, mDotSize, 192, mFastOutSlowInInterpolator, - cellState, null); - } - }); + @Override + public void run() { + startRadiusAnimation(mDotSizeActivated/2, mDotSize/2, 192, + mFastOutSlowInInterpolator, + cellState, null); + } + }); startLineEndAnimation(cellState, mInProgressX, mInProgressY, getCenterXForColumn(cell.column), getCenterYForRow(cell.row)); } @@ -639,13 +758,13 @@ public class LockPatternView extends View { state.lineAnimator = valueAnimator; } - private void startSizeAnimation(float start, float end, long duration, Interpolator interpolator, - final CellState state, final Runnable endRunnable) { + private void startRadiusAnimation(float start, float end, long duration, + Interpolator interpolator, final CellState state, final Runnable endRunnable) { ValueAnimator valueAnimator = ValueAnimator.ofFloat(start, end); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { - state.size = (float) animation.getAnimatedValue(); + state.radius = (float) animation.getAnimatedValue(); invalidate(); } }); @@ -760,7 +879,7 @@ public class LockPatternView extends View { return true; case MotionEvent.ACTION_CANCEL: if (mPatternInProgress) { - mPatternInProgress = false; + setPatternInProgress(false); resetPattern(); notifyPatternCleared(); } @@ -775,6 +894,11 @@ public class LockPatternView extends View { return false; } + private void setPatternInProgress(boolean progress) { + mPatternInProgress = progress; + mExploreByTouchHelper.invalidateRoot(); + } + private void handleActionMove(MotionEvent event) { // Handle all recent motion events so we don't skip any cells even when the device // is busy... @@ -788,7 +912,7 @@ public class LockPatternView extends View { Cell hitCell = detectAndAddHit(x, y); final int patternSize = mPattern.size(); if (hitCell != null && patternSize == 1) { - mPatternInProgress = true; + setPatternInProgress(true); notifyPatternStarted(); } // note current x and y for rubber banding of in progress patterns @@ -846,7 +970,7 @@ public class LockPatternView extends View { private void handleActionUp() { // report pattern detected if (!mPattern.isEmpty()) { - mPatternInProgress = false; + setPatternInProgress(false); cancelLineAnimations(); notifyPatternDetected(); invalidate(); @@ -877,11 +1001,11 @@ public class LockPatternView extends View { final float y = event.getY(); final Cell hitCell = detectAndAddHit(x, y); if (hitCell != null) { - mPatternInProgress = true; + setPatternInProgress(true); mPatternDisplayMode = DisplayMode.Correct; notifyPatternStarted(); } else if (mPatternInProgress) { - mPatternInProgress = false; + setPatternInProgress(false); notifyPatternCleared(); } if (hitCell != null) { @@ -969,10 +1093,16 @@ public class LockPatternView extends View { for (int j = 0; j < 3; j++) { CellState cellState = mCellStates[i][j]; float centerX = getCenterXForColumn(j); - float size = cellState.size * cellState.scale; - float translationY = cellState.translateY; - drawCircle(canvas, (int) centerX, (int) centerY + translationY, - size, drawLookup[i][j], cellState.alpha); + float translationY = cellState.translationY; + if (isHardwareAccelerated() && cellState.hwAnimating) { + DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas; + displayListCanvas.drawCircle(cellState.hwCenterX, cellState.hwCenterY, + cellState.hwRadius, cellState.hwPaint); + } else { + drawCircle(canvas, (int) centerX, (int) centerY + translationY, + cellState.radius, drawLookup[i][j], cellState.alpha); + + } } } @@ -1055,11 +1185,11 @@ public class LockPatternView extends View { /** * @param partOfPattern Whether this circle is part of the pattern. */ - private void drawCircle(Canvas canvas, float centerX, float centerY, float size, + private void drawCircle(Canvas canvas, float centerX, float centerY, float radius, boolean partOfPattern, float alpha) { mPaint.setColor(getCurrentColor(partOfPattern)); mPaint.setAlpha((int) (alpha * 255)); - canvas.drawCircle(centerX, centerY, size/2, mPaint); + canvas.drawCircle(centerX, centerY, radius, mPaint); } @Override @@ -1192,6 +1322,9 @@ public class LockPatternView extends View { @Override protected void getVisibleVirtualViews(IntArray virtualViewIds) { if (DEBUG_A11Y) Log.v(TAG, "getVisibleVirtualViews(len=" + virtualViewIds.size() + ")"); + if (!mPatternInProgress) { + return; + } for (int i = VIRTUAL_BASE_VIEW_ID; i < VIRTUAL_BASE_VIEW_ID + 9; i++) { if (!mItems.containsKey(i)) { VirtualViewContainer item = new VirtualViewContainer(getTextForVirtualView(i)); @@ -1214,6 +1347,16 @@ public class LockPatternView extends View { } @Override + public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) { + super.onPopulateAccessibilityEvent(host, event); + if (!mPatternInProgress) { + CharSequence contentDescription = getContext().getText( + com.android.internal.R.string.lockscreen_access_pattern_area); + event.setContentDescription(contentDescription); + } + } + + @Override protected void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfo node) { if (DEBUG_A11Y) Log.v(TAG, "onPopulateNodeForVirtualView(view=" + virtualViewId + ")"); @@ -1222,10 +1365,14 @@ public class LockPatternView extends View { node.setText(getTextForVirtualView(virtualViewId)); node.setContentDescription(getTextForVirtualView(virtualViewId)); - if (isClickable(virtualViewId)) { - // Mark this node of interest by making it clickable. - node.addAction(AccessibilityAction.ACTION_CLICK); - node.setClickable(isClickable(virtualViewId)); + if (mPatternInProgress) { + node.setFocusable(true); + + if (isClickable(virtualViewId)) { + // Mark this node of interest by making it clickable. + node.addAction(AccessibilityAction.ACTION_CLICK); + node.setClickable(isClickable(virtualViewId)); + } } // Compute bounds for this object @@ -1290,7 +1437,6 @@ public class LockPatternView extends View { float centerY = getCenterYForRow(row); float cellheight = mSquareHeight * mHitFactor * 0.5f; float cellwidth = mSquareWidth * mHitFactor * 0.5f; - float translationY = cell.translateY; bounds.left = (int) (centerX - cellwidth); bounds.right = (int) (centerX + cellwidth); bounds.top = (int) (centerY - cellheight); diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index fc9a1a50801e..76796243f3f5 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -34,6 +34,7 @@ import android.view.ViewParent; import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.animation.AnimationUtils; import android.widget.AbsListView; import android.widget.OverScroller; @@ -609,19 +610,37 @@ public class ResolverDrawerLayout extends ViewGroup { } @Override - public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(info); + public CharSequence getAccessibilityClassName() { + // Since we support scrolling, make this ViewGroup look like a + // ScrollView. This is kind of a hack until we have support for + // specifying auto-scroll behavior. + return android.widget.ScrollView.class.getName(); + } + + @Override + public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfoInternal(info); + if (isEnabled()) { if (mCollapseOffset != 0) { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); info.setScrollable(true); } } + + // This view should never get accessibility focus, but it's interactive + // via nested scrolling, so we can't hide it completely. + info.removeAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS); } @Override - public boolean performAccessibilityAction(int action, Bundle arguments) { - if (super.performAccessibilityAction(action, arguments)) { + public boolean performAccessibilityActionInternal(int action, Bundle arguments) { + if (action == AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS.getId()) { + // This view should never get accessibility focus. + return false; + } + + if (super.performAccessibilityActionInternal(action, arguments)) { return true; } @@ -629,6 +648,7 @@ public class ResolverDrawerLayout extends ViewGroup { smoothScrollTo(0, 0); return true; } + return false; } diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index bffbab7f1e69..bae2cdea69fb 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -590,6 +590,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) 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]; + char fingerprintBuf[sizeof("-Xfingerprint:") + PROPERTY_VALUE_MAX]; bool checkJni = false; property_get("dalvik.vm.checkjni", propBuf, ""); @@ -908,6 +909,12 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) addOption("--generate-debug-info"); } + /* + * Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will + * contain the fingerprint and can be parsed. + */ + parseRuntimeOption("ro.build.fingerprint", fingerprintBuf, "-Xfingerprint:"); + initArgs.version = JNI_VERSION_1_4; initArgs.options = mOptions.editArray(); initArgs.nOptions = mOptions.size(); diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index 0d80a7f9fbe2..fbe3ececc348 100755 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -218,7 +218,6 @@ int Bitmap::getAshmemFd() const { } const SkImageInfo& Bitmap::info() const { - assertValid(); return mPixelRef->info(); } @@ -475,6 +474,14 @@ static void FromColor_D4444_Raw(void* dst, const SkColor src[], int width, } } +static void FromColor_DA8(void* dst, const SkColor src[], int width, int x, int y) { + uint8_t* d = (uint8_t*)dst; + + for (int stop = x + width; x < stop; x++) { + *d++ = SkColorGetA(*src++); + } +} + // can return NULL static FromColorProc ChooseFromColorProc(const SkBitmap& bitmap) { switch (bitmap.colorType()) { @@ -485,6 +492,8 @@ static FromColorProc ChooseFromColorProc(const SkBitmap& bitmap) { FromColor_D4444_Raw; case kRGB_565_SkColorType: return FromColor_D565; + case kAlpha_8_SkColorType: + return FromColor_DA8; default: break; } @@ -632,6 +641,15 @@ static void ToColor_SI8_Opaque(SkColor dst[], const void* src, int width, } while (--width != 0); } +static void ToColor_SA8(SkColor dst[], const void* src, int width, SkColorTable*) { + SkASSERT(width > 0); + const uint8_t* s = (const uint8_t*)src; + do { + uint8_t c = *s++; + *dst++ = SkColorSetARGB(c, c, c, c); + } while (--width != 0); +} + // can return NULL static ToColorProc ChooseToColorProc(const SkBitmap& src) { switch (src.colorType()) { @@ -673,6 +691,8 @@ static ToColorProc ChooseToColorProc(const SkBitmap& src) { default: return NULL; } + case kAlpha_8_SkColorType: + return ToColor_SA8; default: break; } diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp index 7c8769d0e93f..fb2268911be3 100644 --- a/core/jni/android_hardware_camera2_CameraMetadata.cpp +++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp @@ -23,7 +23,9 @@ #include <utils/Vector.h> #include <utils/SortedVector.h> #include <utils/KeyedVector.h> +#include <stdio.h> #include <string.h> +#include <vector> #include "jni.h" #include "JNIHelp.h" @@ -45,9 +47,30 @@ static const bool kIsDebug = false; // fully-qualified class name #define CAMERA_METADATA_CLASS_NAME "android/hardware/camera2/impl/CameraMetadataNative" +#define CHARACTERISTICS_KEY_CLASS_NAME "android/hardware/camera2/CameraCharacteristics$Key" +#define REQUEST_KEY_CLASS_NAME "android/hardware/camera2/CaptureRequest$Key" +#define RESULT_KEY_CLASS_NAME "android/hardware/camera2/CaptureResult$Key" using namespace android; +static struct metadata_java_key_offsets_t { + jclass mCharacteristicsKey; + jclass mResultKey; + jclass mRequestKey; + jmethodID mCharacteristicsConstr; + jmethodID mResultConstr; + jmethodID mRequestConstr; + jclass mByteArray; + jclass mInt32Array; + jclass mFloatArray; + jclass mInt64Array; + jclass mDoubleArray; + jclass mRationalArray; + jclass mArrayList; + jmethodID mArrayListConstr; + jmethodID mArrayListAdd; +} gMetadataOffsets; + struct fields_t { jfieldID metadata_ptr; }; @@ -141,6 +164,7 @@ struct Helpers { extern "C" { static void CameraMetadata_classInit(JNIEnv *env, jobject thiz); +static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType); static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName); static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag); static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz); @@ -510,6 +534,9 @@ static JNINativeMethod gCameraMetadataMethods[] = { { "nativeClassInit", "()V", (void *)CameraMetadata_classInit }, + { "nativeGetAllVendorKeys", + "(Ljava/lang/Class;)Ljava/util/ArrayList;", + (void *)CameraMetadata_getAllVendorKeys}, { "nativeGetTagFromKey", "(Ljava/lang/String;)I", (void *)CameraMetadata_getTagFromKey }, @@ -588,6 +615,44 @@ static int find_fields(JNIEnv *env, field *fields, int count) // Get all the required offsets in java class and register native functions int register_android_hardware_camera2_CameraMetadata(JNIEnv *env) { + + // Store global references to Key-related classes and methods used natively + jclass characteristicsKeyClazz = FindClassOrDie(env, CHARACTERISTICS_KEY_CLASS_NAME); + jclass requestKeyClazz = FindClassOrDie(env, REQUEST_KEY_CLASS_NAME); + jclass resultKeyClazz = FindClassOrDie(env, RESULT_KEY_CLASS_NAME); + gMetadataOffsets.mCharacteristicsKey = MakeGlobalRefOrDie(env, characteristicsKeyClazz); + gMetadataOffsets.mRequestKey = MakeGlobalRefOrDie(env, requestKeyClazz); + gMetadataOffsets.mResultKey = MakeGlobalRefOrDie(env, resultKeyClazz); + gMetadataOffsets.mCharacteristicsConstr = GetMethodIDOrDie(env, + gMetadataOffsets.mCharacteristicsKey, "<init>", + "(Ljava/lang/String;Ljava/lang/Class;)V"); + gMetadataOffsets.mRequestConstr = GetMethodIDOrDie(env, + gMetadataOffsets.mRequestKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V"); + gMetadataOffsets.mResultConstr = GetMethodIDOrDie(env, + gMetadataOffsets.mResultKey, "<init>", "(Ljava/lang/String;Ljava/lang/Class;)V"); + + // Store global references for primitive array types used by Keys + jclass byteClazz = FindClassOrDie(env, "[B"); + jclass int32Clazz = FindClassOrDie(env, "[I"); + jclass floatClazz = FindClassOrDie(env, "[F"); + jclass int64Clazz = FindClassOrDie(env, "[J"); + jclass doubleClazz = FindClassOrDie(env, "[D"); + jclass rationalClazz = FindClassOrDie(env, "[Landroid/util/Rational;"); + gMetadataOffsets.mByteArray = MakeGlobalRefOrDie(env, byteClazz); + gMetadataOffsets.mInt32Array = MakeGlobalRefOrDie(env, int32Clazz); + gMetadataOffsets.mFloatArray = MakeGlobalRefOrDie(env, floatClazz); + gMetadataOffsets.mInt64Array = MakeGlobalRefOrDie(env, int64Clazz); + gMetadataOffsets.mDoubleArray = MakeGlobalRefOrDie(env, doubleClazz); + gMetadataOffsets.mRationalArray = MakeGlobalRefOrDie(env, rationalClazz); + + // Store global references for ArrayList methods used + jclass arrayListClazz = FindClassOrDie(env, "java/util/ArrayList"); + gMetadataOffsets.mArrayList = MakeGlobalRefOrDie(env, arrayListClazz); + gMetadataOffsets.mArrayListConstr = GetMethodIDOrDie(env, gMetadataOffsets.mArrayList, + "<init>", "(I)V"); + gMetadataOffsets.mArrayListAdd = GetMethodIDOrDie(env, gMetadataOffsets.mArrayList, + "add", "(Ljava/lang/Object;)Z"); + // Register native functions return RegisterMethodsOrDie(env, CAMERA_METADATA_CLASS_NAME, @@ -596,6 +661,7 @@ int register_android_hardware_camera2_CameraMetadata(JNIEnv *env) } extern "C" { + static void CameraMetadata_classInit(JNIEnv *env, jobject thiz) { // XX: Why do this separately instead of doing it in the register function? ALOGV("%s", __FUNCTION__); @@ -612,6 +678,107 @@ static void CameraMetadata_classInit(JNIEnv *env, jobject thiz) { env->FindClass(CAMERA_METADATA_CLASS_NAME); } +static jobject CameraMetadata_getAllVendorKeys(JNIEnv* env, jobject thiz, jclass keyType) { + + // Get all vendor tags + sp<VendorTagDescriptor> vTags = VendorTagDescriptor::getGlobalVendorTagDescriptor(); + if (vTags.get() == nullptr) { + // No vendor tags. + return NULL; + } + + int count = vTags->getTagCount(); + if (count <= 0) { + // No vendor tags. + return NULL; + } + + std::vector<uint32_t> tagIds(count, /*initializer value*/0); + vTags->getTagArray(&tagIds[0]); + + // Which key class/constructor should we use? + jclass keyClazz; + jmethodID keyConstr; + if (env->IsSameObject(keyType, gMetadataOffsets.mCharacteristicsKey)) { + keyClazz = gMetadataOffsets.mCharacteristicsKey; + keyConstr = gMetadataOffsets.mCharacteristicsConstr; + } else if (env->IsSameObject(keyType, gMetadataOffsets.mResultKey)) { + keyClazz = gMetadataOffsets.mResultKey; + keyConstr = gMetadataOffsets.mResultConstr; + } else if (env->IsSameObject(keyType, gMetadataOffsets.mRequestKey)) { + keyClazz = gMetadataOffsets.mRequestKey; + keyConstr = gMetadataOffsets.mRequestConstr; + } else { + jniThrowException(env, "java/lang/IllegalArgumentException", + "Invalid key class given as argument."); + return NULL; + } + + // Allocate arrayList to return + jobject arrayList = env->NewObject(gMetadataOffsets.mArrayList, + gMetadataOffsets.mArrayListConstr, static_cast<jint>(count)); + if (env->ExceptionCheck()) { + return NULL; + } + + for (uint32_t id : tagIds) { + const char* section = vTags->getSectionName(id); + const char* tag = vTags->getTagName(id); + int type = vTags->getTagType(id); + + size_t totalLen = strlen(section) + strlen(tag) + 2; + std::vector<char> fullName(totalLen, 0); + snprintf(&fullName[0], totalLen, "%s.%s", section, tag); + + jstring name = env->NewStringUTF(&fullName[0]); + + if (env->ExceptionCheck()) { + return NULL; + } + + jclass valueClazz; + switch (type) { + case TYPE_BYTE: + valueClazz = gMetadataOffsets.mByteArray; + break; + case TYPE_INT32: + valueClazz = gMetadataOffsets.mInt32Array; + break; + case TYPE_FLOAT: + valueClazz = gMetadataOffsets.mFloatArray; + break; + case TYPE_INT64: + valueClazz = gMetadataOffsets.mInt64Array; + break; + case TYPE_DOUBLE: + valueClazz = gMetadataOffsets.mDoubleArray; + break; + case TYPE_RATIONAL: + valueClazz = gMetadataOffsets.mRationalArray; + break; + default: + jniThrowExceptionFmt(env, "java/lang/IllegalStateException", + "Invalid type %d given for key %s", type, &fullName[0]); + return NULL; + } + + jobject key = env->NewObject(keyClazz, keyConstr, name, valueClazz); + if (env->ExceptionCheck()) { + return NULL; + } + + env->CallBooleanMethod(arrayList, gMetadataOffsets.mArrayListAdd, key); + if (env->ExceptionCheck()) { + return NULL; + } + + env->DeleteLocalRef(name); + env->DeleteLocalRef(key); + } + + return arrayList; +} + static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName) { ScopedUtfChars keyScoped(env, keyName); diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp index 995d39f33fbb..ba08237d9843 100644 --- a/core/jni/android_hardware_camera2_DngCreator.cpp +++ b/core/jni/android_hardware_camera2_DngCreator.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -//#define LOG_NDEBUG 0 +#define LOG_NDEBUG 0 #define LOG_TAG "DngCreator_JNI" #include <inttypes.h> #include <string.h> @@ -26,6 +26,7 @@ #include <utils/StrongPointer.h> #include <utils/RefBase.h> #include <utils/Vector.h> +#include <utils/String8.h> #include <cutils/properties.h> #include <system/camera_metadata.h> #include <camera/CameraMetadata.h> @@ -48,13 +49,22 @@ using namespace android; using namespace img_utils; -#define BAIL_IF_INVALID(expr, jnienv, tagId, writer) \ +#define BAIL_IF_INVALID_RET_BOOL(expr, jnienv, tagId, writer) \ if ((expr) != OK) { \ jniThrowExceptionFmt(jnienv, "java/lang/IllegalArgumentException", \ "Invalid metadata for tag %s (%x)", (writer)->getTagName(tagId), (tagId)); \ - return; \ + return false; \ } + +#define BAIL_IF_INVALID_RET_NULL_SP(expr, jnienv, tagId, writer) \ + if ((expr) != OK) { \ + jniThrowExceptionFmt(jnienv, "java/lang/IllegalArgumentException", \ + "Invalid metadata for tag %s (%x)", (writer)->getTagName(tagId), (tagId)); \ + return nullptr; \ + } + + #define BAIL_IF_INVALID_R(expr, jnienv, tagId, writer) \ if ((expr) != OK) { \ jniThrowExceptionFmt(jnienv, "java/lang/IllegalArgumentException", \ @@ -62,14 +72,14 @@ using namespace img_utils; return -1; \ } - -#define BAIL_IF_EMPTY(entry, jnienv, tagId, writer) \ +#define BAIL_IF_EMPTY_RET_NULL_SP(entry, jnienv, tagId, writer) \ if (entry.count == 0) { \ jniThrowExceptionFmt(jnienv, "java/lang/IllegalArgumentException", \ "Missing metadata fields for tag %s (%x)", (writer)->getTagName(tagId), (tagId)); \ - return; \ + return nullptr; \ } + #define ANDROID_DNGCREATOR_CTX_JNI_ID "mNativeContext" static struct { @@ -102,6 +112,26 @@ enum { TIFF_IFD_GPSINFO = 2, }; + +/** + * POD container class for GPS tag data. + */ +class GpsData { +public: + enum { + GPS_VALUE_LENGTH = 6, + GPS_REF_LENGTH = 2, + GPS_DATE_LENGTH = 11, + }; + + uint32_t mLatitude[GPS_VALUE_LENGTH]; + uint32_t mLongitude[GPS_VALUE_LENGTH]; + uint32_t mTimestamp[GPS_VALUE_LENGTH]; + uint8_t mLatitudeRef[GPS_REF_LENGTH]; + uint8_t mLongitudeRef[GPS_REF_LENGTH]; + uint8_t mDate[GPS_DATE_LENGTH]; +}; + // ---------------------------------------------------------------------------- /** @@ -109,8 +139,11 @@ enum { */ class NativeContext : public LightRefBase<NativeContext> { - public: + enum { + DATETIME_COUNT = 20, + }; + NativeContext(const CameraMetadata& characteristics, const CameraMetadata& result); virtual ~NativeContext(); @@ -119,12 +152,28 @@ public: std::shared_ptr<const CameraMetadata> getCharacteristics() const; std::shared_ptr<const CameraMetadata> getResult() const; - uint32_t getThumbnailWidth(); - uint32_t getThumbnailHeight(); - const uint8_t* getThumbnail(); + uint32_t getThumbnailWidth() const; + uint32_t getThumbnailHeight() const; + const uint8_t* getThumbnail() const; + bool hasThumbnail() const; bool setThumbnail(const uint8_t* buffer, uint32_t width, uint32_t height); + void setOrientation(uint16_t orientation); + uint16_t getOrientation() const; + + void setDescription(const String8& desc); + String8 getDescription() const; + bool hasDescription() const; + + void setGpsData(const GpsData& data); + GpsData getGpsData() const; + bool hasGpsData() const; + + void setCaptureTime(const String8& formattedCaptureTime); + String8 getCaptureTime() const; + bool hasCaptureTime() const; + private: Vector<uint8_t> mCurrentThumbnail; TiffWriter mWriter; @@ -132,12 +181,21 @@ private: std::shared_ptr<CameraMetadata> mResult; uint32_t mThumbnailWidth; uint32_t mThumbnailHeight; + uint16_t mOrientation; + bool mThumbnailSet; + bool mGpsSet; + bool mDescriptionSet; + bool mCaptureTimeSet; + String8 mDescription; + GpsData mGpsData; + String8 mFormattedCaptureTime; }; NativeContext::NativeContext(const CameraMetadata& characteristics, const CameraMetadata& result) : mCharacteristics(std::make_shared<CameraMetadata>(characteristics)), mResult(std::make_shared<CameraMetadata>(result)), mThumbnailWidth(0), - mThumbnailHeight(0) {} + mThumbnailHeight(0), mOrientation(0), mThumbnailSet(false), mGpsSet(false), + mDescriptionSet(false), mCaptureTimeSet(false) {} NativeContext::~NativeContext() {} @@ -153,18 +211,22 @@ std::shared_ptr<const CameraMetadata> NativeContext::getResult() const { return mResult; } -uint32_t NativeContext::getThumbnailWidth() { +uint32_t NativeContext::getThumbnailWidth() const { return mThumbnailWidth; } -uint32_t NativeContext::getThumbnailHeight() { +uint32_t NativeContext::getThumbnailHeight() const { return mThumbnailHeight; } -const uint8_t* NativeContext::getThumbnail() { +const uint8_t* NativeContext::getThumbnail() const { return mCurrentThumbnail.array(); } +bool NativeContext::hasThumbnail() const { + return mThumbnailSet; +} + bool NativeContext::setThumbnail(const uint8_t* buffer, uint32_t width, uint32_t height) { mThumbnailWidth = width; mThumbnailHeight = height; @@ -177,9 +239,57 @@ bool NativeContext::setThumbnail(const uint8_t* buffer, uint32_t width, uint32_t uint8_t* thumb = mCurrentThumbnail.editArray(); memcpy(thumb, buffer, size); + mThumbnailSet = true; return true; } +void NativeContext::setOrientation(uint16_t orientation) { + mOrientation = orientation; +} + +uint16_t NativeContext::getOrientation() const { + return mOrientation; +} + +void NativeContext::setDescription(const String8& desc) { + mDescription = desc; + mDescriptionSet = true; +} + +String8 NativeContext::getDescription() const { + return mDescription; +} + +bool NativeContext::hasDescription() const { + return mDescriptionSet; +} + +void NativeContext::setGpsData(const GpsData& data) { + mGpsData = data; + mGpsSet = true; +} + +GpsData NativeContext::getGpsData() const { + return mGpsData; +} + +bool NativeContext::hasGpsData() const { + return mGpsSet; +} + +void NativeContext::setCaptureTime(const String8& formattedCaptureTime) { + mFormattedCaptureTime = formattedCaptureTime; + mCaptureTimeSet = true; +} + +String8 NativeContext::getCaptureTime() const { + return mFormattedCaptureTime; +} + +bool NativeContext::hasCaptureTime() const { + return mCaptureTimeSet; +} + // End of NativeContext // ---------------------------------------------------------------------------- @@ -211,7 +321,7 @@ private: JniOutputStream::JniOutputStream(JNIEnv* env, jobject outStream) : mOutputStream(outStream), mEnv(env) { mByteArray = env->NewByteArray(BYTE_ARRAY_LENGTH); - if (mByteArray == NULL) { + if (mByteArray == nullptr) { jniThrowException(env, "java/lang/OutOfMemoryError", "Could not allocate byte array."); } } @@ -286,7 +396,7 @@ private: JniInputStream::JniInputStream(JNIEnv* env, jobject inStream) : mInStream(inStream), mEnv(env) { mByteArray = env->NewByteArray(BYTE_ARRAY_LENGTH); - if (mByteArray == NULL) { + if (mByteArray == nullptr) { jniThrowException(env, "java/lang/OutOfMemoryError", "Could not allocate byte array."); } } @@ -372,7 +482,7 @@ private: JniInputByteBuffer::JniInputByteBuffer(JNIEnv* env, jobject inBuf) : mInBuf(inBuf), mEnv(env) { mByteArray = env->NewByteArray(BYTE_ARRAY_LENGTH); - if (mByteArray == NULL) { + if (mByteArray == nullptr) { jniThrowException(env, "java/lang/OutOfMemoryError", "Could not allocate byte array."); } } @@ -600,6 +710,7 @@ status_t DirectStripSource::writeToStream(Output& stream, uint32_t count) { return BAD_VALUE; } + if (mPixStride == mBytesPerSample * mSamplesPerPixel && mRowStride == mWidth * mBytesPerSample * mSamplesPerPixel) { ALOGV("%s: Using direct single-pass write for strip.", __FUNCTION__); @@ -643,37 +754,48 @@ uint32_t DirectStripSource::getIfd() const { // ---------------------------------------------------------------------------- /** - * 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. + * Given a buffer crop rectangle relative to the pixel array size, and the pre-correction 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) { + uint32_t bufWidth, uint32_t bufHeight, sp<TiffWriter> writer) { camera_metadata_ro_entry entry = - characteristics.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE); + characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_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]); + const uint32_t margin = 8; // Default margin recommended by Adobe for interpolation. + + // Crop based on pre-correction array for pixel array 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; + // 8 pixel border crop for pixel array dimens + uint32_t bLeft = margin; + uint32_t bTop = margin; + uint32_t bRight = bufWidth - margin; + uint32_t bBottom = bufHeight - margin; + // Set the crop to be the intersection of the two rectangles 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]}; + // If using buffers with pre-correction array dimens, switch to 8 pixel border crop + // relative to the pixel array dimens + if (bufWidth == width && bufHeight == height) { + defaultCropOrigin[0] = xmin + margin; + defaultCropOrigin[1] = ymin + margin; + defaultCropSize[0] = width - margin; + defaultCropSize[1] = height - margin; + } + 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, @@ -682,9 +804,8 @@ static status_t calculateAndSetCrop(JNIEnv* env, const CameraMetadata& character return OK; } -static bool validateDngHeader(JNIEnv* env, TiffWriter* writer, +static bool validateDngHeader(JNIEnv* env, sp<TiffWriter> writer, const CameraMetadata& characteristics, jint width, jint height) { - // TODO: handle lens shading map, etc. conversions for other raw buffer sizes. if (width <= 0) { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", \ "Image width %d is invalid", width); @@ -710,20 +831,7 @@ static bool validateDngHeader(JNIEnv* env, TiffWriter* writer, 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 { + if (!(matchesPixelArray || matchesPreCorrectionArray)) { 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)", @@ -734,12 +842,12 @@ static bool validateDngHeader(JNIEnv* env, TiffWriter* writer, return true; } -static status_t moveEntries(TiffWriter* writer, uint32_t ifdFrom, uint32_t ifdTo, +static status_t moveEntries(sp<TiffWriter> writer, uint32_t ifdFrom, uint32_t ifdTo, const Vector<uint16_t>& entries) { for (size_t i = 0; i < entries.size(); ++i) { uint16_t tagId = entries[i]; sp<TiffEntry> entry = writer->getEntry(tagId, ifdFrom); - if (entry == NULL) { + if (entry.get() == nullptr) { ALOGE("%s: moveEntries failed, entry %u not found in IFD %u", __FUNCTION__, tagId, ifdFrom); return BAD_VALUE; @@ -881,7 +989,7 @@ static void DngCreator_setNativeContext(JNIEnv* env, jobject thiz, sp<NativeCont ALOGV("%s:", __FUNCTION__); NativeContext* current = DngCreator_getNativeContext(env, thiz); - if (context != NULL) { + if (context != nullptr) { context->incStrong((void*) DngCreator_setNativeContext); } @@ -893,15 +1001,6 @@ static void DngCreator_setNativeContext(JNIEnv* env, jobject thiz, sp<NativeCont reinterpret_cast<jlong>(context.get())); } -static TiffWriter* DngCreator_getCreator(JNIEnv* env, jobject thiz) { - ALOGV("%s:", __FUNCTION__); - NativeContext* current = DngCreator_getNativeContext(env, thiz); - if (current) { - return current->getWriter(); - } - return NULL; -} - static void DngCreator_nativeClassInit(JNIEnv* env, jclass clazz) { ALOGV("%s:", __FUNCTION__); @@ -938,7 +1037,62 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt } sp<NativeContext> nativeContext = new NativeContext(characteristics, results); - TiffWriter* writer = nativeContext->getWriter(); + + const char* captureTime = env->GetStringUTFChars(formattedCaptureTime, nullptr); + + size_t len = strlen(captureTime) + 1; + if (len != NativeContext::DATETIME_COUNT) { + jniThrowException(env, "java/lang/IllegalArgumentException", + "Formatted capture time string length is not required 20 characters"); + return; + } + + nativeContext->setCaptureTime(String8(captureTime)); + + DngCreator_setNativeContext(env, thiz, nativeContext); +} + +static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t imageWidth, + uint32_t imageHeight) { + + NativeContext* nativeContext = DngCreator_getNativeContext(env, thiz); + + if (nativeContext == nullptr) { + jniThrowException(env, "java/lang/AssertionError", + "No native context, must call init before other operations."); + return nullptr; + } + + CameraMetadata characteristics = *(nativeContext->getCharacteristics()); + CameraMetadata results = *(nativeContext->getResult()); + + sp<TiffWriter> writer = new TiffWriter(); + + uint32_t preWidth = 0; + uint32_t preHeight = 0; + { + // Check dimensions + camera_metadata_entry entry = + characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE); + BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_IMAGEWIDTH, writer); + preWidth = static_cast<uint32_t>(entry.data.i32[2]); + preHeight = static_cast<uint32_t>(entry.data.i32[3]); + + camera_metadata_entry pixelArrayEntry = + characteristics.find(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE); + uint32_t pixWidth = static_cast<uint32_t>(pixelArrayEntry.data.i32[0]); + uint32_t pixHeight = static_cast<uint32_t>(pixelArrayEntry.data.i32[1]); + + if (!((imageWidth == preWidth && imageHeight == preHeight) || + (imageWidth == pixWidth && imageHeight == pixHeight))) { + jniThrowException(env, "java/lang/AssertionError", + "Height and width of imate buffer did not match height and width of" + "either the preCorrectionActiveArraySize or the pixelArraySize."); + return nullptr; + } + } + + writer->addIfd(TIFF_IFD_0); @@ -946,8 +1100,6 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt const uint32_t samplesPerPixel = 1; const uint32_t bitsPerSample = BITS_PER_SAMPLE; - uint32_t imageWidth = 0; - uint32_t imageHeight = 0; OpcodeListBuilder::CfaLayout opcodeCfaLayout = OpcodeListBuilder::CFA_RGGB; uint8_t cfaPlaneColor[3] = {0, 1, 2}; @@ -961,93 +1113,86 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt { // Set orientation uint16_t orientation = 1; // Normal - BAIL_IF_INVALID(writer->addEntry(TAG_ORIENTATION, 1, &orientation, TIFF_IFD_0), env, - TAG_ORIENTATION, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_ORIENTATION, 1, &orientation, TIFF_IFD_0), + env, TAG_ORIENTATION, writer); } { // Set subfiletype uint32_t subfileType = 0; // Main image - BAIL_IF_INVALID(writer->addEntry(TAG_NEWSUBFILETYPE, 1, &subfileType, TIFF_IFD_0), env, - TAG_NEWSUBFILETYPE, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_NEWSUBFILETYPE, 1, &subfileType, + TIFF_IFD_0), env, TAG_NEWSUBFILETYPE, writer); } { // Set bits per sample uint16_t bits = static_cast<uint16_t>(bitsPerSample); - BAIL_IF_INVALID(writer->addEntry(TAG_BITSPERSAMPLE, 1, &bits, TIFF_IFD_0), env, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BITSPERSAMPLE, 1, &bits, TIFF_IFD_0), env, TAG_BITSPERSAMPLE, writer); } { // Set compression uint16_t compression = 1; // None - BAIL_IF_INVALID(writer->addEntry(TAG_COMPRESSION, 1, &compression, TIFF_IFD_0), env, - TAG_COMPRESSION, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_COMPRESSION, 1, &compression, + TIFF_IFD_0), env, TAG_COMPRESSION, writer); } { // Set dimensions - camera_metadata_entry entry = - 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]); - BAIL_IF_INVALID(writer->addEntry(TAG_IMAGEWIDTH, 1, &width, TIFF_IFD_0), env, - TAG_IMAGEWIDTH, writer); - BAIL_IF_INVALID(writer->addEntry(TAG_IMAGELENGTH, 1, &height, TIFF_IFD_0), env, - TAG_IMAGELENGTH, writer); - imageWidth = width; - imageHeight = height; + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_IMAGEWIDTH, 1, &imageWidth, TIFF_IFD_0), + env, TAG_IMAGEWIDTH, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_IMAGELENGTH, 1, &imageHeight, TIFF_IFD_0), + env, TAG_IMAGELENGTH, writer); } { // Set photometric interpretation uint16_t interpretation = 32803; // CFA - BAIL_IF_INVALID(writer->addEntry(TAG_PHOTOMETRICINTERPRETATION, 1, &interpretation, - TIFF_IFD_0), env, TAG_PHOTOMETRICINTERPRETATION, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_PHOTOMETRICINTERPRETATION, 1, + &interpretation, TIFF_IFD_0), env, TAG_PHOTOMETRICINTERPRETATION, writer); } { // Set blacklevel tags camera_metadata_entry entry = characteristics.find(ANDROID_SENSOR_BLACK_LEVEL_PATTERN); - BAIL_IF_EMPTY(entry, env, TAG_BLACKLEVEL, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_BLACKLEVEL, writer); const uint32_t* blackLevel = reinterpret_cast<const uint32_t*>(entry.data.i32); - BAIL_IF_INVALID(writer->addEntry(TAG_BLACKLEVEL, entry.count, blackLevel, TIFF_IFD_0), env, - TAG_BLACKLEVEL, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVEL, entry.count, blackLevel, + TIFF_IFD_0), env, TAG_BLACKLEVEL, writer); uint16_t repeatDim[2] = {2, 2}; - BAIL_IF_INVALID(writer->addEntry(TAG_BLACKLEVELREPEATDIM, 2, repeatDim, TIFF_IFD_0), env, - TAG_BLACKLEVELREPEATDIM, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVELREPEATDIM, 2, repeatDim, + TIFF_IFD_0), env, TAG_BLACKLEVELREPEATDIM, writer); } { // Set samples per pixel uint16_t samples = static_cast<uint16_t>(samplesPerPixel); - BAIL_IF_INVALID(writer->addEntry(TAG_SAMPLESPERPIXEL, 1, &samples, TIFF_IFD_0), + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_SAMPLESPERPIXEL, 1, &samples, TIFF_IFD_0), env, TAG_SAMPLESPERPIXEL, writer); } { // Set planar configuration uint16_t config = 1; // Chunky - BAIL_IF_INVALID(writer->addEntry(TAG_PLANARCONFIGURATION, 1, &config, TIFF_IFD_0), - env, TAG_PLANARCONFIGURATION, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_PLANARCONFIGURATION, 1, &config, + TIFF_IFD_0), env, TAG_PLANARCONFIGURATION, writer); } { // Set CFA pattern dimensions uint16_t repeatDim[2] = {2, 2}; - BAIL_IF_INVALID(writer->addEntry(TAG_CFAREPEATPATTERNDIM, 2, repeatDim, TIFF_IFD_0), - env, TAG_CFAREPEATPATTERNDIM, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CFAREPEATPATTERNDIM, 2, repeatDim, + TIFF_IFD_0), env, TAG_CFAREPEATPATTERNDIM, writer); } { // Set CFA pattern camera_metadata_entry entry = characteristics.find(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT); - BAIL_IF_EMPTY(entry, env, TAG_CFAPATTERN, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_CFAPATTERN, writer); const int cfaLength = 4; cfaEnum = entry.data.u8[0]; @@ -1057,30 +1202,30 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt "Invalid metadata for tag %d", TAG_CFAPATTERN); } - BAIL_IF_INVALID(writer->addEntry(TAG_CFAPATTERN, cfaLength, cfa, TIFF_IFD_0), env, - TAG_CFAPATTERN, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CFAPATTERN, cfaLength, cfa, TIFF_IFD_0), + env, TAG_CFAPATTERN, writer); opcodeCfaLayout = convertCFAEnumToOpcodeLayout(cfaEnum); } { // Set CFA plane color - BAIL_IF_INVALID(writer->addEntry(TAG_CFAPLANECOLOR, 3, cfaPlaneColor, TIFF_IFD_0), - env, TAG_CFAPLANECOLOR, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CFAPLANECOLOR, 3, cfaPlaneColor, + TIFF_IFD_0), env, TAG_CFAPLANECOLOR, writer); } { // Set CFA layout uint16_t cfaLayout = 1; - BAIL_IF_INVALID(writer->addEntry(TAG_CFALAYOUT, 1, &cfaLayout, TIFF_IFD_0), + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CFALAYOUT, 1, &cfaLayout, TIFF_IFD_0), env, TAG_CFALAYOUT, writer); } { // image description uint8_t imageDescription = '\0'; // empty - BAIL_IF_INVALID(writer->addEntry(TAG_IMAGEDESCRIPTION, 1, &imageDescription, TIFF_IFD_0), - env, TAG_IMAGEDESCRIPTION, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_IMAGEDESCRIPTION, 1, &imageDescription, + TIFF_IFD_0), env, TAG_IMAGEDESCRIPTION, writer); } { @@ -1091,8 +1236,8 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt property_get("ro.product.manufacturer", manufacturer, ""); uint32_t count = static_cast<uint32_t>(strlen(manufacturer)) + 1; - BAIL_IF_INVALID(writer->addEntry(TAG_MAKE, count, reinterpret_cast<uint8_t*>(manufacturer), - TIFF_IFD_0), env, TAG_MAKE, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_MAKE, count, + reinterpret_cast<uint8_t*>(manufacturer), TIFF_IFD_0), env, TAG_MAKE, writer); } { @@ -1103,23 +1248,23 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt property_get("ro.product.model", model, ""); uint32_t count = static_cast<uint32_t>(strlen(model)) + 1; - BAIL_IF_INVALID(writer->addEntry(TAG_MODEL, count, reinterpret_cast<uint8_t*>(model), - TIFF_IFD_0), env, TAG_MODEL, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_MODEL, count, + reinterpret_cast<uint8_t*>(model), TIFF_IFD_0), env, TAG_MODEL, writer); } { // x resolution uint32_t xres[] = { 72, 1 }; // default 72 ppi - BAIL_IF_INVALID(writer->addEntry(TAG_XRESOLUTION, 1, xres, TIFF_IFD_0), + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_XRESOLUTION, 1, xres, TIFF_IFD_0), env, TAG_XRESOLUTION, writer); // y resolution uint32_t yres[] = { 72, 1 }; // default 72 ppi - BAIL_IF_INVALID(writer->addEntry(TAG_YRESOLUTION, 1, yres, TIFF_IFD_0), + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_YRESOLUTION, 1, yres, TIFF_IFD_0), env, TAG_YRESOLUTION, writer); uint16_t unit = 2; // inches - BAIL_IF_INVALID(writer->addEntry(TAG_RESOLUTIONUNIT, 1, &unit, TIFF_IFD_0), + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_RESOLUTIONUNIT, 1, &unit, TIFF_IFD_0), env, TAG_RESOLUTIONUNIT, writer); } @@ -1128,52 +1273,41 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt char software[PROPERTY_VALUE_MAX]; property_get("ro.build.fingerprint", software, ""); uint32_t count = static_cast<uint32_t>(strlen(software)) + 1; - BAIL_IF_INVALID(writer->addEntry(TAG_SOFTWARE, count, reinterpret_cast<uint8_t*>(software), - TIFF_IFD_0), env, TAG_SOFTWARE, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_SOFTWARE, count, + reinterpret_cast<uint8_t*>(software), TIFF_IFD_0), env, TAG_SOFTWARE, writer); } - { + if (nativeContext->hasCaptureTime()) { // datetime - const size_t DATETIME_COUNT = 20; - const char* captureTime = env->GetStringUTFChars(formattedCaptureTime, NULL); - - size_t len = strlen(captureTime) + 1; - if (len != DATETIME_COUNT) { - jniThrowException(env, "java/lang/IllegalArgumentException", - "Timestamp string length is not required 20 characters"); - return; - } + String8 captureTime = nativeContext->getCaptureTime(); - if (writer->addEntry(TAG_DATETIME, DATETIME_COUNT, - reinterpret_cast<const uint8_t*>(captureTime), TIFF_IFD_0) != OK) { - env->ReleaseStringUTFChars(formattedCaptureTime, captureTime); + if (writer->addEntry(TAG_DATETIME, NativeContext::DATETIME_COUNT, + reinterpret_cast<const uint8_t*>(captureTime.string()), TIFF_IFD_0) != OK) { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "Invalid metadata for tag %x", TAG_DATETIME); - return; + return nullptr; } // datetime original - if (writer->addEntry(TAG_DATETIMEORIGINAL, DATETIME_COUNT, - reinterpret_cast<const uint8_t*>(captureTime), TIFF_IFD_0) != OK) { - env->ReleaseStringUTFChars(formattedCaptureTime, captureTime); + if (writer->addEntry(TAG_DATETIMEORIGINAL, NativeContext::DATETIME_COUNT, + reinterpret_cast<const uint8_t*>(captureTime.string()), TIFF_IFD_0) != OK) { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "Invalid metadata for tag %x", TAG_DATETIMEORIGINAL); - return; + return nullptr; } - env->ReleaseStringUTFChars(formattedCaptureTime, captureTime); } { // TIFF/EP standard id uint8_t standardId[] = { 1, 0, 0, 0 }; - BAIL_IF_INVALID(writer->addEntry(TAG_TIFFEPSTANDARDID, 4, standardId, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_TIFFEPSTANDARDID, 4, standardId, TIFF_IFD_0), env, TAG_TIFFEPSTANDARDID, writer); } { // copyright uint8_t copyright = '\0'; // empty - BAIL_IF_INVALID(writer->addEntry(TAG_COPYRIGHT, 1, ©right, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_COPYRIGHT, 1, ©right, TIFF_IFD_0), env, TAG_COPYRIGHT, writer); } @@ -1181,7 +1315,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // exposure time camera_metadata_entry entry = results.find(ANDROID_SENSOR_EXPOSURE_TIME); - BAIL_IF_EMPTY(entry, env, TAG_EXPOSURETIME, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_EXPOSURETIME, writer); int64_t exposureTime = *(entry.data.i64); @@ -1189,7 +1323,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // Should be unreachable jniThrowException(env, "java/lang/IllegalArgumentException", "Negative exposure time in metadata"); - return; + return nullptr; } // Ensure exposure time doesn't overflow (for exposures > 4s) @@ -1201,12 +1335,12 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // Should be unreachable jniThrowException(env, "java/lang/IllegalArgumentException", "Exposure time too long"); - return; + return nullptr; } } uint32_t exposure[] = { static_cast<uint32_t>(exposureTime), denominator }; - BAIL_IF_INVALID(writer->addEntry(TAG_EXPOSURETIME, 1, exposure, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_EXPOSURETIME, 1, exposure, TIFF_IFD_0), env, TAG_EXPOSURETIME, writer); } @@ -1215,13 +1349,13 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // ISO speed ratings camera_metadata_entry entry = results.find(ANDROID_SENSOR_SENSITIVITY); - BAIL_IF_EMPTY(entry, env, TAG_ISOSPEEDRATINGS, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_ISOSPEEDRATINGS, writer); int32_t tempIso = *(entry.data.i32); if (tempIso < 0) { jniThrowException(env, "java/lang/IllegalArgumentException", "Negative ISO value"); - return; + return nullptr; } if (tempIso > UINT16_MAX) { @@ -1230,7 +1364,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt } uint16_t iso = static_cast<uint16_t>(tempIso); - BAIL_IF_INVALID(writer->addEntry(TAG_ISOSPEEDRATINGS, 1, &iso, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_ISOSPEEDRATINGS, 1, &iso, TIFF_IFD_0), env, TAG_ISOSPEEDRATINGS, writer); } @@ -1238,10 +1372,10 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // focal length camera_metadata_entry entry = results.find(ANDROID_LENS_FOCAL_LENGTH); - BAIL_IF_EMPTY(entry, env, TAG_FOCALLENGTH, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_FOCALLENGTH, writer); uint32_t focalLength[] = { static_cast<uint32_t>(*(entry.data.f) * 100), 100 }; - BAIL_IF_INVALID(writer->addEntry(TAG_FOCALLENGTH, 1, focalLength, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_FOCALLENGTH, 1, focalLength, TIFF_IFD_0), env, TAG_FOCALLENGTH, writer); } @@ -1249,39 +1383,39 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // f number camera_metadata_entry entry = results.find(ANDROID_LENS_APERTURE); - BAIL_IF_EMPTY(entry, env, TAG_FNUMBER, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_FNUMBER, writer); uint32_t fnum[] = { static_cast<uint32_t>(*(entry.data.f) * 100), 100 }; - BAIL_IF_INVALID(writer->addEntry(TAG_FNUMBER, 1, fnum, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_FNUMBER, 1, fnum, TIFF_IFD_0), env, TAG_FNUMBER, writer); } { // Set DNG version information uint8_t version[4] = {1, 4, 0, 0}; - BAIL_IF_INVALID(writer->addEntry(TAG_DNGVERSION, 4, version, TIFF_IFD_0), + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_DNGVERSION, 4, version, TIFF_IFD_0), env, TAG_DNGVERSION, writer); uint8_t backwardVersion[4] = {1, 1, 0, 0}; - BAIL_IF_INVALID(writer->addEntry(TAG_DNGBACKWARDVERSION, 4, backwardVersion, TIFF_IFD_0), - env, TAG_DNGBACKWARDVERSION, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_DNGBACKWARDVERSION, 4, backwardVersion, + TIFF_IFD_0), env, TAG_DNGBACKWARDVERSION, writer); } { // Set whitelevel camera_metadata_entry entry = characteristics.find(ANDROID_SENSOR_INFO_WHITE_LEVEL); - BAIL_IF_EMPTY(entry, env, TAG_WHITELEVEL, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_WHITELEVEL, writer); uint32_t whiteLevel = static_cast<uint32_t>(entry.data.i32[0]); - BAIL_IF_INVALID(writer->addEntry(TAG_WHITELEVEL, 1, &whiteLevel, TIFF_IFD_0), env, - TAG_WHITELEVEL, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_WHITELEVEL, 1, &whiteLevel, TIFF_IFD_0), + env, TAG_WHITELEVEL, writer); } { // Set default scale uint32_t defaultScale[4] = {1, 1, 1, 1}; - BAIL_IF_INVALID(writer->addEntry(TAG_DEFAULTSCALE, 2, defaultScale, TIFF_IFD_0), - env, TAG_DEFAULTSCALE, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_DEFAULTSCALE, 2, defaultScale, + TIFF_IFD_0), env, TAG_DEFAULTSCALE, writer); } bool singleIlluminant = false; @@ -1289,7 +1423,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // Set calibration illuminants camera_metadata_entry entry1 = characteristics.find(ANDROID_SENSOR_REFERENCE_ILLUMINANT1); - BAIL_IF_EMPTY(entry1, env, TAG_CALIBRATIONILLUMINANT1, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry1, env, TAG_CALIBRATIONILLUMINANT1, writer); camera_metadata_entry entry2 = characteristics.find(ANDROID_SENSOR_REFERENCE_ILLUMINANT2); if (entry2.count == 0) { @@ -1297,12 +1431,12 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt } uint16_t ref1 = entry1.data.u8[0]; - BAIL_IF_INVALID(writer->addEntry(TAG_CALIBRATIONILLUMINANT1, 1, &ref1, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CALIBRATIONILLUMINANT1, 1, &ref1, TIFF_IFD_0), env, TAG_CALIBRATIONILLUMINANT1, writer); if (!singleIlluminant) { uint16_t ref2 = entry2.data.u8[0]; - BAIL_IF_INVALID(writer->addEntry(TAG_CALIBRATIONILLUMINANT2, 1, &ref2, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CALIBRATIONILLUMINANT2, 1, &ref2, TIFF_IFD_0), env, TAG_CALIBRATIONILLUMINANT2, writer); } } @@ -1311,7 +1445,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // Set color transforms camera_metadata_entry entry1 = characteristics.find(ANDROID_SENSOR_COLOR_TRANSFORM1); - BAIL_IF_EMPTY(entry1, env, TAG_COLORMATRIX1, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry1, env, TAG_COLORMATRIX1, writer); int32_t colorTransform1[entry1.count * 2]; @@ -1321,12 +1455,12 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt colorTransform1[ctr++] = entry1.data.r[i].denominator; } - BAIL_IF_INVALID(writer->addEntry(TAG_COLORMATRIX1, entry1.count, colorTransform1, - TIFF_IFD_0), env, TAG_COLORMATRIX1, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_COLORMATRIX1, entry1.count, + colorTransform1, TIFF_IFD_0), env, TAG_COLORMATRIX1, writer); if (!singleIlluminant) { camera_metadata_entry entry2 = characteristics.find(ANDROID_SENSOR_COLOR_TRANSFORM2); - BAIL_IF_EMPTY(entry2, env, TAG_COLORMATRIX2, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry2, env, TAG_COLORMATRIX2, writer); int32_t colorTransform2[entry2.count * 2]; ctr = 0; @@ -1335,8 +1469,8 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt colorTransform2[ctr++] = entry2.data.r[i].denominator; } - BAIL_IF_INVALID(writer->addEntry(TAG_COLORMATRIX2, entry2.count, colorTransform2, - TIFF_IFD_0), env, TAG_COLORMATRIX2, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_COLORMATRIX2, entry2.count, + colorTransform2, TIFF_IFD_0), env, TAG_COLORMATRIX2, writer); } } @@ -1344,7 +1478,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // Set calibration transforms camera_metadata_entry entry1 = characteristics.find(ANDROID_SENSOR_CALIBRATION_TRANSFORM1); - BAIL_IF_EMPTY(entry1, env, TAG_CAMERACALIBRATION1, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry1, env, TAG_CAMERACALIBRATION1, writer); int32_t calibrationTransform1[entry1.count * 2]; @@ -1354,13 +1488,13 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt calibrationTransform1[ctr++] = entry1.data.r[i].denominator; } - BAIL_IF_INVALID(writer->addEntry(TAG_CAMERACALIBRATION1, entry1.count, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CAMERACALIBRATION1, entry1.count, calibrationTransform1, TIFF_IFD_0), env, TAG_CAMERACALIBRATION1, writer); if (!singleIlluminant) { camera_metadata_entry entry2 = characteristics.find(ANDROID_SENSOR_CALIBRATION_TRANSFORM2); - BAIL_IF_EMPTY(entry2, env, TAG_CAMERACALIBRATION2, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry2, env, TAG_CAMERACALIBRATION2, writer); int32_t calibrationTransform2[entry2.count * 2]; ctr = 0; @@ -1369,7 +1503,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt calibrationTransform2[ctr++] = entry2.data.r[i].denominator; } - BAIL_IF_INVALID(writer->addEntry(TAG_CAMERACALIBRATION2, entry2.count, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CAMERACALIBRATION2, entry2.count, calibrationTransform2, TIFF_IFD_0), env, TAG_CAMERACALIBRATION2, writer); } } @@ -1378,7 +1512,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // Set forward transforms camera_metadata_entry entry1 = characteristics.find(ANDROID_SENSOR_FORWARD_MATRIX1); - BAIL_IF_EMPTY(entry1, env, TAG_FORWARDMATRIX1, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry1, env, TAG_FORWARDMATRIX1, writer); int32_t forwardTransform1[entry1.count * 2]; @@ -1388,13 +1522,13 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt forwardTransform1[ctr++] = entry1.data.r[i].denominator; } - BAIL_IF_INVALID(writer->addEntry(TAG_FORWARDMATRIX1, entry1.count, forwardTransform1, - TIFF_IFD_0), env, TAG_FORWARDMATRIX1, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_FORWARDMATRIX1, entry1.count, + forwardTransform1, TIFF_IFD_0), env, TAG_FORWARDMATRIX1, writer); if (!singleIlluminant) { camera_metadata_entry entry2 = characteristics.find(ANDROID_SENSOR_FORWARD_MATRIX2); - BAIL_IF_EMPTY(entry2, env, TAG_FORWARDMATRIX2, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry2, env, TAG_FORWARDMATRIX2, writer); int32_t forwardTransform2[entry2.count * 2]; ctr = 0; @@ -1403,8 +1537,8 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt forwardTransform2[ctr++] = entry2.data.r[i].denominator; } - BAIL_IF_INVALID(writer->addEntry(TAG_FORWARDMATRIX2, entry2.count, forwardTransform2, - TIFF_IFD_0), env, TAG_FORWARDMATRIX2, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_FORWARDMATRIX2, entry2.count, + forwardTransform2, TIFF_IFD_0), env, TAG_FORWARDMATRIX2, writer); } } @@ -1412,7 +1546,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt // Set camera neutral camera_metadata_entry entry = results.find(ANDROID_SENSOR_NEUTRAL_COLOR_POINT); - BAIL_IF_EMPTY(entry, env, TAG_ASSHOTNEUTRAL, writer); + BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_ASSHOTNEUTRAL, writer); uint32_t cameraNeutral[entry.count * 2]; size_t ctr = 0; @@ -1423,33 +1557,27 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt static_cast<uint32_t>(entry.data.r[i].denominator); } - BAIL_IF_INVALID(writer->addEntry(TAG_ASSHOTNEUTRAL, entry.count, cameraNeutral, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_ASSHOTNEUTRAL, entry.count, cameraNeutral, TIFF_IFD_0), env, TAG_ASSHOTNEUTRAL, writer); } - { - // Setup data strips - // TODO: Switch to tiled implementation. - if (writer->addStrip(TIFF_IFD_0) != OK) { - ALOGE("%s: Could not setup strip tags.", __FUNCTION__); - jniThrowException(env, "java/lang/IllegalStateException", - "Failed to setup strip tags."); - return; - } - } { // Set dimensions + if (calculateAndSetCrop(env, characteristics, imageWidth, imageHeight, writer) != OK) { + return nullptr; + } camera_metadata_entry entry = characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE); - BAIL_IF_EMPTY(entry, env, TAG_DEFAULTCROPSIZE, writer); + BAIL_IF_EMPTY_RET_NULL_SP(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; - } + + uint32_t activeArea[] = {ymin, xmin, ymin + height, xmin + width}; + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_ACTIVEAREA, 4, activeArea, TIFF_IFD_0), + env, TAG_ACTIVEAREA, writer); } { @@ -1469,7 +1597,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt cameraModel += "-"; cameraModel += brand; - BAIL_IF_INVALID(writer->addEntry(TAG_UNIQUECAMERAMODEL, cameraModel.size() + 1, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_UNIQUECAMERAMODEL, cameraModel.size() + 1, reinterpret_cast<const uint8_t*>(cameraModel.string()), TIFF_IFD_0), env, TAG_UNIQUECAMERAMODEL, writer); } @@ -1486,7 +1614,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt if ((err = convertCFA(cfaEnum, /*out*/cfaOut)) != OK) { jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid CFA from camera characteristics"); - return; + return nullptr; } double noiseProfile[numPlaneColors * 2]; @@ -1500,8 +1628,9 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt if ((err = generateNoiseProfile(entry.data.d, cfaOut, numCfaChannels, cfaPlaneColor, numPlaneColors, /*out*/ noiseProfile)) == OK) { - BAIL_IF_INVALID(writer->addEntry(TAG_NOISEPROFILE, numPlaneColors * 2, - noiseProfile, TIFF_IFD_0), env, TAG_NOISEPROFILE, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_NOISEPROFILE, + numPlaneColors * 2, noiseProfile, TIFF_IFD_0), env, TAG_NOISEPROFILE, + writer); } else { ALOGW("%s: Error converting coefficients for noise profile, no noise profile" " tag written...", __FUNCTION__); @@ -1533,19 +1662,26 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt camera_metadata_entry entry2 = results.find(ANDROID_STATISTICS_LENS_SHADING_MAP); + camera_metadata_entry entry = + characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE); + BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_IMAGEWIDTH, 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 (entry2.count > 0 && entry2.count == lsmWidth * lsmHeight * 4) { err = builder.addGainMapsForMetadata(lsmWidth, lsmHeight, - 0, - 0, - imageHeight, - imageWidth, + ymin, + xmin, + height, + width, opcodeCfaLayout, entry2.data.f); if (err != OK) { ALOGE("%s: Could not add Lens shading map.", __FUNCTION__); jniThrowRuntimeException(env, "failed to add lens shading map."); - return; + return nullptr; } } @@ -1553,14 +1689,14 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt uint8_t opcodeListBuf[listSize]; err = builder.buildOpList(opcodeListBuf); if (err == OK) { - BAIL_IF_INVALID(writer->addEntry(TAG_OPCODELIST2, listSize, opcodeListBuf, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_OPCODELIST2, listSize, opcodeListBuf, TIFF_IFD_0), env, TAG_OPCODELIST2, writer); } else { ALOGE("%s: Could not build list of opcodes for distortion correction and lens shading" "map.", __FUNCTION__); jniThrowRuntimeException(env, "failed to construct opcode list for distortion" " correction and lens shading map"); - return; + return nullptr; } } @@ -1578,12 +1714,12 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt if (entry3.count == 6 && entry4.count == 5) { float cx = entry4.data.f[/*c_x*/2]; float cy = entry4.data.f[/*c_y*/3]; - err = builder.addWarpRectilinearForMetadata(entry3.data.f, imageWidth, imageHeight, cx, + err = builder.addWarpRectilinearForMetadata(entry3.data.f, preWidth, preHeight, cx, cy); if (err != OK) { ALOGE("%s: Could not add distortion correction.", __FUNCTION__); jniThrowRuntimeException(env, "failed to add distortion correction."); - return; + return nullptr; } } @@ -1591,30 +1727,236 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt uint8_t opcodeListBuf[listSize]; err = builder.buildOpList(opcodeListBuf); if (err == OK) { - BAIL_IF_INVALID(writer->addEntry(TAG_OPCODELIST3, listSize, opcodeListBuf, + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_OPCODELIST3, listSize, opcodeListBuf, TIFF_IFD_0), env, TAG_OPCODELIST3, writer); } else { ALOGE("%s: Could not build list of opcodes for distortion correction and lens shading" "map.", __FUNCTION__); jniThrowRuntimeException(env, "failed to construct opcode list for distortion" " correction and lens shading map"); - return; + return nullptr; } } - DngCreator_setNativeContext(env, thiz, nativeContext); + { + // Set up orientation tags. + uint16_t orientation = nativeContext->getOrientation(); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_ORIENTATION, 1, &orientation, TIFF_IFD_0), + env, TAG_ORIENTATION, writer); + + } + + if (nativeContext->hasDescription()){ + // Set Description + String8 description = nativeContext->getDescription(); + size_t len = description.bytes() + 1; + if (writer->addEntry(TAG_IMAGEDESCRIPTION, len, + reinterpret_cast<const uint8_t*>(description.string()), TIFF_IFD_0) != OK) { + jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", + "Invalid metadata for tag %x", TAG_IMAGEDESCRIPTION); + } + } + + if (nativeContext->hasGpsData()) { + // Set GPS tags + GpsData gpsData = nativeContext->getGpsData(); + if (!writer->hasIfd(TIFF_IFD_GPSINFO)) { + if (writer->addSubIfd(TIFF_IFD_0, TIFF_IFD_GPSINFO, TiffWriter::GPSINFO) != OK) { + ALOGE("%s: Failed to add GpsInfo IFD %u to IFD %u", __FUNCTION__, TIFF_IFD_GPSINFO, + TIFF_IFD_0); + jniThrowException(env, "java/lang/IllegalStateException", "Failed to add GPSINFO"); + return nullptr; + } + } + + { + uint8_t version[] = {2, 3, 0, 0}; + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_GPSVERSIONID, 4, version, + TIFF_IFD_GPSINFO), env, TAG_GPSVERSIONID, writer); + } + + { + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_GPSLATITUDEREF, + GpsData::GPS_REF_LENGTH, gpsData.mLatitudeRef, TIFF_IFD_GPSINFO), env, + TAG_GPSLATITUDEREF, writer); + } + + { + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_GPSLONGITUDEREF, + GpsData::GPS_REF_LENGTH, gpsData.mLongitudeRef, TIFF_IFD_GPSINFO), env, + TAG_GPSLONGITUDEREF, writer); + } + + { + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_GPSLATITUDE, 3, gpsData.mLatitude, + TIFF_IFD_GPSINFO), env, TAG_GPSLATITUDE, writer); + } + + { + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_GPSLONGITUDE, 3, gpsData.mLongitude, + TIFF_IFD_GPSINFO), env, TAG_GPSLONGITUDE, writer); + } + + { + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_GPSTIMESTAMP, 3, gpsData.mTimestamp, + TIFF_IFD_GPSINFO), env, TAG_GPSTIMESTAMP, writer); + } + + { + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_GPSDATESTAMP, + GpsData::GPS_DATE_LENGTH, gpsData.mDate, TIFF_IFD_GPSINFO), env, + TAG_GPSDATESTAMP, writer); + } + } + + + if (nativeContext->hasThumbnail()) { + if (!writer->hasIfd(TIFF_IFD_SUB1)) { + if (writer->addSubIfd(TIFF_IFD_0, TIFF_IFD_SUB1) != OK) { + ALOGE("%s: Failed to add SubIFD %u to IFD %u", __FUNCTION__, TIFF_IFD_SUB1, + TIFF_IFD_0); + jniThrowException(env, "java/lang/IllegalStateException", "Failed to add SubIFD"); + return nullptr; + } + } + + Vector<uint16_t> tagsToMove; + tagsToMove.add(TAG_ORIENTATION); + tagsToMove.add(TAG_NEWSUBFILETYPE); + tagsToMove.add(TAG_ACTIVEAREA); + tagsToMove.add(TAG_BITSPERSAMPLE); + tagsToMove.add(TAG_COMPRESSION); + tagsToMove.add(TAG_IMAGEWIDTH); + tagsToMove.add(TAG_IMAGELENGTH); + tagsToMove.add(TAG_PHOTOMETRICINTERPRETATION); + tagsToMove.add(TAG_BLACKLEVEL); + tagsToMove.add(TAG_BLACKLEVELREPEATDIM); + tagsToMove.add(TAG_SAMPLESPERPIXEL); + tagsToMove.add(TAG_PLANARCONFIGURATION); + tagsToMove.add(TAG_CFAREPEATPATTERNDIM); + tagsToMove.add(TAG_CFAPATTERN); + tagsToMove.add(TAG_CFAPLANECOLOR); + tagsToMove.add(TAG_CFALAYOUT); + tagsToMove.add(TAG_XRESOLUTION); + tagsToMove.add(TAG_YRESOLUTION); + tagsToMove.add(TAG_RESOLUTIONUNIT); + tagsToMove.add(TAG_WHITELEVEL); + tagsToMove.add(TAG_DEFAULTSCALE); + tagsToMove.add(TAG_DEFAULTCROPORIGIN); + tagsToMove.add(TAG_DEFAULTCROPSIZE); + tagsToMove.add(TAG_OPCODELIST2); + tagsToMove.add(TAG_OPCODELIST3); + + if (moveEntries(writer, TIFF_IFD_0, TIFF_IFD_SUB1, tagsToMove) != OK) { + jniThrowException(env, "java/lang/IllegalStateException", "Failed to move entries"); + return nullptr; + } + + // Make sure both IFDs get the same orientation tag + sp<TiffEntry> orientEntry = writer->getEntry(TAG_ORIENTATION, TIFF_IFD_SUB1); + if (orientEntry.get() != nullptr) { + writer->addEntry(orientEntry, TIFF_IFD_0); + } + + // Setup thumbnail tags + + { + // Set photometric interpretation + uint16_t interpretation = 2; // RGB + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_PHOTOMETRICINTERPRETATION, 1, + &interpretation, TIFF_IFD_0), env, TAG_PHOTOMETRICINTERPRETATION, writer); + } + + { + // Set planar configuration + uint16_t config = 1; // Chunky + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_PLANARCONFIGURATION, 1, &config, + TIFF_IFD_0), env, TAG_PLANARCONFIGURATION, writer); + } + + { + // Set samples per pixel + uint16_t samples = SAMPLES_PER_RGB_PIXEL; + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_SAMPLESPERPIXEL, 1, &samples, + TIFF_IFD_0), env, TAG_SAMPLESPERPIXEL, writer); + } + + { + // Set bits per sample + uint16_t bits = BITS_PER_RGB_SAMPLE; + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BITSPERSAMPLE, 1, &bits, TIFF_IFD_0), + env, TAG_BITSPERSAMPLE, writer); + } + + { + // Set subfiletype + uint32_t subfileType = 1; // Thumbnail image + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_NEWSUBFILETYPE, 1, &subfileType, + TIFF_IFD_0), env, TAG_NEWSUBFILETYPE, writer); + } + + { + // Set compression + uint16_t compression = 1; // None + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_COMPRESSION, 1, &compression, + TIFF_IFD_0), env, TAG_COMPRESSION, writer); + } + + { + // Set dimensions + uint32_t uWidth = nativeContext->getThumbnailWidth(); + uint32_t uHeight = nativeContext->getThumbnailHeight(); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_IMAGEWIDTH, 1, &uWidth, TIFF_IFD_0), + env, TAG_IMAGEWIDTH, writer); + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_IMAGELENGTH, 1, &uHeight, TIFF_IFD_0), + env, TAG_IMAGELENGTH, writer); + } + + { + // x resolution + uint32_t xres[] = { 72, 1 }; // default 72 ppi + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_XRESOLUTION, 1, xres, TIFF_IFD_0), + env, TAG_XRESOLUTION, writer); + + // y resolution + uint32_t yres[] = { 72, 1 }; // default 72 ppi + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_YRESOLUTION, 1, yres, TIFF_IFD_0), + env, TAG_YRESOLUTION, writer); + + uint16_t unit = 2; // inches + BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_RESOLUTIONUNIT, 1, &unit, TIFF_IFD_0), + env, TAG_RESOLUTIONUNIT, writer); + } + } + + if (writer->addStrip(TIFF_IFD_0) != OK) { + ALOGE("%s: Could not setup thumbnail strip tags.", __FUNCTION__); + jniThrowException(env, "java/lang/IllegalStateException", + "Failed to setup thumbnail strip tags."); + return nullptr; + } + + if (writer->hasIfd(TIFF_IFD_SUB1)) { + if (writer->addStrip(TIFF_IFD_SUB1) != OK) { + ALOGE("%s: Could not main image strip tags.", __FUNCTION__); + jniThrowException(env, "java/lang/IllegalStateException", + "Failed to setup main image strip tags."); + return nullptr; + } + } + return writer; } static void DngCreator_destroy(JNIEnv* env, jobject thiz) { ALOGV("%s:", __FUNCTION__); - DngCreator_setNativeContext(env, thiz, NULL); + DngCreator_setNativeContext(env, thiz, nullptr); } static void DngCreator_nativeSetOrientation(JNIEnv* env, jobject thiz, jint orient) { ALOGV("%s:", __FUNCTION__); - TiffWriter* writer = DngCreator_getCreator(env, thiz); - if (writer == NULL) { + NativeContext* context = DngCreator_getNativeContext(env, thiz); + if (context == nullptr) { ALOGE("%s: Failed to initialize DngCreator", __FUNCTION__); jniThrowException(env, "java/lang/AssertionError", "setOrientation called with uninitialized DngCreator"); @@ -1622,138 +1964,73 @@ static void DngCreator_nativeSetOrientation(JNIEnv* env, jobject thiz, jint orie } uint16_t orientation = static_cast<uint16_t>(orient); - BAIL_IF_INVALID(writer->addEntry(TAG_ORIENTATION, 1, &orientation, TIFF_IFD_0), env, - TAG_ORIENTATION, writer); - - // Set main image orientation also if in a separate IFD - if (writer->hasIfd(TIFF_IFD_SUB1)) { - BAIL_IF_INVALID(writer->addEntry(TAG_ORIENTATION, 1, &orientation, TIFF_IFD_SUB1), env, - TAG_ORIENTATION, writer); - } + context->setOrientation(orientation); } static void DngCreator_nativeSetDescription(JNIEnv* env, jobject thiz, jstring description) { ALOGV("%s:", __FUNCTION__); - TiffWriter* writer = DngCreator_getCreator(env, thiz); - if (writer == NULL) { + NativeContext* context = DngCreator_getNativeContext(env, thiz); + if (context == nullptr) { ALOGE("%s: Failed to initialize DngCreator", __FUNCTION__); jniThrowException(env, "java/lang/AssertionError", "setDescription called with uninitialized DngCreator"); return; } - const char* desc = env->GetStringUTFChars(description, NULL); - size_t len = strlen(desc) + 1; - - if (writer->addEntry(TAG_IMAGEDESCRIPTION, len, - reinterpret_cast<const uint8_t*>(desc), TIFF_IFD_0) != OK) { - jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", - "Invalid metadata for tag %x", TAG_IMAGEDESCRIPTION); - } - + const char* desc = env->GetStringUTFChars(description, nullptr); + context->setDescription(String8(desc)); env->ReleaseStringUTFChars(description, desc); } -static void DngCreator_nativeSetGpsTags(JNIEnv* env, jobject thiz, jintArray latTag, jstring latRef, - jintArray longTag, jstring longRef, jstring dateTag, jintArray timeTag) { +static void DngCreator_nativeSetGpsTags(JNIEnv* env, jobject thiz, jintArray latTag, + jstring latRef, jintArray longTag, jstring longRef, jstring dateTag, jintArray timeTag) { ALOGV("%s:", __FUNCTION__); - TiffWriter* writer = DngCreator_getCreator(env, thiz); - if (writer == NULL) { + NativeContext* context = DngCreator_getNativeContext(env, thiz); + if (context == nullptr) { ALOGE("%s: Failed to initialize DngCreator", __FUNCTION__); jniThrowException(env, "java/lang/AssertionError", "setGpsTags called with uninitialized DngCreator"); return; } - if (!writer->hasIfd(TIFF_IFD_GPSINFO)) { - if (writer->addSubIfd(TIFF_IFD_0, TIFF_IFD_GPSINFO, TiffWriter::GPSINFO) != OK) { - ALOGE("%s: Failed to add GpsInfo IFD %u to IFD %u", __FUNCTION__, TIFF_IFD_GPSINFO, - TIFF_IFD_0); - jniThrowException(env, "java/lang/IllegalStateException", "Failed to add GPSINFO"); - return; - } - } + GpsData data; - const jsize GPS_VALUE_LENGTH = 6; jsize latLen = env->GetArrayLength(latTag); jsize longLen = env->GetArrayLength(longTag); jsize timeLen = env->GetArrayLength(timeTag); - if (latLen != GPS_VALUE_LENGTH) { + if (latLen != GpsData::GPS_VALUE_LENGTH) { jniThrowException(env, "java/lang/IllegalArgumentException", "invalid latitude tag length"); return; - } else if (longLen != GPS_VALUE_LENGTH) { + } else if (longLen != GpsData::GPS_VALUE_LENGTH) { jniThrowException(env, "java/lang/IllegalArgumentException", "invalid longitude tag length"); return; - } else if (timeLen != GPS_VALUE_LENGTH) { + } else if (timeLen != GpsData::GPS_VALUE_LENGTH) { jniThrowException(env, "java/lang/IllegalArgumentException", "invalid time tag length"); return; } - uint32_t latitude[GPS_VALUE_LENGTH]; - uint32_t longitude[GPS_VALUE_LENGTH]; - uint32_t timestamp[GPS_VALUE_LENGTH]; - - env->GetIntArrayRegion(latTag, 0, static_cast<jsize>(GPS_VALUE_LENGTH), - reinterpret_cast<jint*>(&latitude)); - env->GetIntArrayRegion(longTag, 0, static_cast<jsize>(GPS_VALUE_LENGTH), - reinterpret_cast<jint*>(&longitude)); - env->GetIntArrayRegion(timeTag, 0, static_cast<jsize>(GPS_VALUE_LENGTH), - reinterpret_cast<jint*>(×tamp)); - - const jsize GPS_REF_LENGTH = 2; - const jsize GPS_DATE_LENGTH = 11; - uint8_t latitudeRef[GPS_REF_LENGTH]; - uint8_t longitudeRef[GPS_REF_LENGTH]; - uint8_t date[GPS_DATE_LENGTH]; - - env->GetStringUTFRegion(latRef, 0, 1, reinterpret_cast<char*>(&latitudeRef)); - latitudeRef[GPS_REF_LENGTH - 1] = '\0'; - env->GetStringUTFRegion(longRef, 0, 1, reinterpret_cast<char*>(&longitudeRef)); - longitudeRef[GPS_REF_LENGTH - 1] = '\0'; - - env->GetStringUTFRegion(dateTag, 0, GPS_DATE_LENGTH - 1, reinterpret_cast<char*>(&date)); - date[GPS_DATE_LENGTH - 1] = '\0'; - - { - uint8_t version[] = {2, 3, 0, 0}; - BAIL_IF_INVALID(writer->addEntry(TAG_GPSVERSIONID, 4, version, - TIFF_IFD_GPSINFO), env, TAG_GPSVERSIONID, writer); - } - - { - BAIL_IF_INVALID(writer->addEntry(TAG_GPSLATITUDEREF, GPS_REF_LENGTH, latitudeRef, - TIFF_IFD_GPSINFO), env, TAG_GPSLATITUDEREF, writer); - } - - { - BAIL_IF_INVALID(writer->addEntry(TAG_GPSLONGITUDEREF, GPS_REF_LENGTH, longitudeRef, - TIFF_IFD_GPSINFO), env, TAG_GPSLONGITUDEREF, writer); - } - - { - BAIL_IF_INVALID(writer->addEntry(TAG_GPSLATITUDE, 3, latitude, - TIFF_IFD_GPSINFO), env, TAG_GPSLATITUDE, writer); - } + env->GetIntArrayRegion(latTag, 0, static_cast<jsize>(GpsData::GPS_VALUE_LENGTH), + reinterpret_cast<jint*>(&data.mLatitude)); + env->GetIntArrayRegion(longTag, 0, static_cast<jsize>(GpsData::GPS_VALUE_LENGTH), + reinterpret_cast<jint*>(&data.mLongitude)); + env->GetIntArrayRegion(timeTag, 0, static_cast<jsize>(GpsData::GPS_VALUE_LENGTH), + reinterpret_cast<jint*>(&data.mTimestamp)); - { - BAIL_IF_INVALID(writer->addEntry(TAG_GPSLONGITUDE, 3, longitude, - TIFF_IFD_GPSINFO), env, TAG_GPSLONGITUDE, writer); - } - { - BAIL_IF_INVALID(writer->addEntry(TAG_GPSTIMESTAMP, 3, timestamp, - TIFF_IFD_GPSINFO), env, TAG_GPSTIMESTAMP, writer); - } + env->GetStringUTFRegion(latRef, 0, 1, reinterpret_cast<char*>(&data.mLatitudeRef)); + data.mLatitudeRef[GpsData::GPS_REF_LENGTH - 1] = '\0'; + env->GetStringUTFRegion(longRef, 0, 1, reinterpret_cast<char*>(&data.mLongitudeRef)); + data.mLongitudeRef[GpsData::GPS_REF_LENGTH - 1] = '\0'; + env->GetStringUTFRegion(dateTag, 0, GpsData::GPS_DATE_LENGTH - 1, + reinterpret_cast<char*>(&data.mDate)); + data.mDate[GpsData::GPS_DATE_LENGTH - 1] = '\0'; - { - BAIL_IF_INVALID(writer->addEntry(TAG_GPSDATESTAMP, GPS_DATE_LENGTH, date, - TIFF_IFD_GPSINFO), env, TAG_GPSDATESTAMP, writer); - } + context->setGpsData(data); } static void DngCreator_nativeSetThumbnail(JNIEnv* env, jobject thiz, jobject buffer, jint width, @@ -1761,8 +2038,7 @@ static void DngCreator_nativeSetThumbnail(JNIEnv* env, jobject thiz, jobject buf ALOGV("%s:", __FUNCTION__); NativeContext* context = DngCreator_getNativeContext(env, thiz); - TiffWriter* writer = DngCreator_getCreator(env, thiz); - if (writer == NULL || context == NULL) { + if (context == nullptr) { ALOGE("%s: Failed to initialize DngCreator", __FUNCTION__); jniThrowException(env, "java/lang/AssertionError", "setThumbnail called with uninitialized DngCreator"); @@ -1779,147 +2055,12 @@ static void DngCreator_nativeSetThumbnail(JNIEnv* env, jobject thiz, jobject buf } uint8_t* pixelBytes = reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(buffer)); - if (pixelBytes == NULL) { + if (pixelBytes == nullptr) { ALOGE("%s: Could not get native ByteBuffer", __FUNCTION__); jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid ByteBuffer"); return; } - if (!writer->hasIfd(TIFF_IFD_SUB1)) { - if (writer->addSubIfd(TIFF_IFD_0, TIFF_IFD_SUB1) != OK) { - ALOGE("%s: Failed to add SubIFD %u to IFD %u", __FUNCTION__, TIFF_IFD_SUB1, - TIFF_IFD_0); - jniThrowException(env, "java/lang/IllegalStateException", "Failed to add SubIFD"); - return; - } - - Vector<uint16_t> tagsToMove; - tagsToMove.add(TAG_ORIENTATION); - tagsToMove.add(TAG_NEWSUBFILETYPE); - tagsToMove.add(TAG_BITSPERSAMPLE); - tagsToMove.add(TAG_COMPRESSION); - tagsToMove.add(TAG_IMAGEWIDTH); - tagsToMove.add(TAG_IMAGELENGTH); - tagsToMove.add(TAG_PHOTOMETRICINTERPRETATION); - tagsToMove.add(TAG_BLACKLEVEL); - tagsToMove.add(TAG_BLACKLEVELREPEATDIM); - tagsToMove.add(TAG_SAMPLESPERPIXEL); - tagsToMove.add(TAG_PLANARCONFIGURATION); - tagsToMove.add(TAG_CFAREPEATPATTERNDIM); - tagsToMove.add(TAG_CFAPATTERN); - tagsToMove.add(TAG_CFAPLANECOLOR); - tagsToMove.add(TAG_CFALAYOUT); - tagsToMove.add(TAG_XRESOLUTION); - tagsToMove.add(TAG_YRESOLUTION); - tagsToMove.add(TAG_RESOLUTIONUNIT); - tagsToMove.add(TAG_WHITELEVEL); - tagsToMove.add(TAG_DEFAULTSCALE); - tagsToMove.add(TAG_ROWSPERSTRIP); - tagsToMove.add(TAG_STRIPBYTECOUNTS); - tagsToMove.add(TAG_STRIPOFFSETS); - tagsToMove.add(TAG_DEFAULTCROPORIGIN); - tagsToMove.add(TAG_DEFAULTCROPSIZE); - tagsToMove.add(TAG_OPCODELIST2); - tagsToMove.add(TAG_OPCODELIST3); - - if (moveEntries(writer, TIFF_IFD_0, TIFF_IFD_SUB1, tagsToMove) != OK) { - jniThrowException(env, "java/lang/IllegalStateException", "Failed to move entries"); - return; - } - - // Make sure both IFDs get the same orientation tag - sp<TiffEntry> orientEntry = writer->getEntry(TAG_ORIENTATION, TIFF_IFD_SUB1); - if (orientEntry != NULL) { - writer->addEntry(orientEntry, TIFF_IFD_0); - } - } - - // Setup thumbnail tags - - { - // Set photometric interpretation - uint16_t interpretation = 2; // RGB - BAIL_IF_INVALID(writer->addEntry(TAG_PHOTOMETRICINTERPRETATION, 1, &interpretation, - TIFF_IFD_0), env, TAG_PHOTOMETRICINTERPRETATION, writer); - } - - { - // Set planar configuration - uint16_t config = 1; // Chunky - BAIL_IF_INVALID(writer->addEntry(TAG_PLANARCONFIGURATION, 1, &config, TIFF_IFD_0), - env, TAG_PLANARCONFIGURATION, writer); - } - - { - // Set samples per pixel - uint16_t samples = SAMPLES_PER_RGB_PIXEL; - BAIL_IF_INVALID(writer->addEntry(TAG_SAMPLESPERPIXEL, 1, &samples, TIFF_IFD_0), - env, TAG_SAMPLESPERPIXEL, writer); - } - - { - // Set bits per sample - uint16_t bits = BITS_PER_RGB_SAMPLE; - BAIL_IF_INVALID(writer->addEntry(TAG_BITSPERSAMPLE, 1, &bits, TIFF_IFD_0), env, - TAG_BITSPERSAMPLE, writer); - } - - { - // Set subfiletype - uint32_t subfileType = 1; // Thumbnail image - BAIL_IF_INVALID(writer->addEntry(TAG_NEWSUBFILETYPE, 1, &subfileType, TIFF_IFD_0), env, - TAG_NEWSUBFILETYPE, writer); - } - - { - // Set compression - uint16_t compression = 1; // None - BAIL_IF_INVALID(writer->addEntry(TAG_COMPRESSION, 1, &compression, TIFF_IFD_0), env, - TAG_COMPRESSION, writer); - } - - { - // Set dimensions - uint32_t uWidth = static_cast<uint32_t>(width); - uint32_t uHeight = static_cast<uint32_t>(height); - BAIL_IF_INVALID(writer->addEntry(TAG_IMAGEWIDTH, 1, &uWidth, TIFF_IFD_0), env, - TAG_IMAGEWIDTH, writer); - BAIL_IF_INVALID(writer->addEntry(TAG_IMAGELENGTH, 1, &uHeight, TIFF_IFD_0), env, - TAG_IMAGELENGTH, writer); - } - - { - // x resolution - uint32_t xres[] = { 72, 1 }; // default 72 ppi - BAIL_IF_INVALID(writer->addEntry(TAG_XRESOLUTION, 1, xres, TIFF_IFD_0), - env, TAG_XRESOLUTION, writer); - - // y resolution - uint32_t yres[] = { 72, 1 }; // default 72 ppi - BAIL_IF_INVALID(writer->addEntry(TAG_YRESOLUTION, 1, yres, TIFF_IFD_0), - env, TAG_YRESOLUTION, writer); - - uint16_t unit = 2; // inches - BAIL_IF_INVALID(writer->addEntry(TAG_RESOLUTIONUNIT, 1, &unit, TIFF_IFD_0), - env, TAG_RESOLUTIONUNIT, writer); - } - - { - // Setup data strips - if (writer->addStrip(TIFF_IFD_0) != OK) { - ALOGE("%s: Could not setup thumbnail strip tags.", __FUNCTION__); - jniThrowException(env, "java/lang/IllegalStateException", - "Failed to setup thumbnail strip tags."); - return; - } - if (writer->addStrip(TIFF_IFD_SUB1) != OK) { - ALOGE("%s: Could not main image strip tags.", __FUNCTION__); - jniThrowException(env, "java/lang/IllegalStateException", - "Failed to setup main image strip tags."); - return; - } - } - if (!context->setThumbnail(pixelBytes, width, height)) { jniThrowException(env, "java/lang/IllegalStateException", "Failed to set thumbnail."); @@ -1947,16 +2088,20 @@ static void DngCreator_nativeWriteImage(JNIEnv* env, jobject thiz, jobject outSt return; } - TiffWriter* writer = DngCreator_getCreator(env, thiz); NativeContext* context = DngCreator_getNativeContext(env, thiz); - if (writer == NULL || context == NULL) { + if (context == nullptr) { ALOGE("%s: Failed to initialize DngCreator", __FUNCTION__); jniThrowException(env, "java/lang/AssertionError", "Write called with uninitialized DngCreator"); return; } + sp<TiffWriter> writer = DngCreator_setup(env, thiz, uWidth, uHeight); - // Validate DNG header + if (writer.get() == nullptr) { + return; + } + + // Validate DNG size if (!validateDngHeader(env, writer, *(context->getCharacteristics()), width, height)) { return; } @@ -1991,7 +2136,7 @@ static void DngCreator_nativeWriteImage(JNIEnv* env, jobject thiz, jobject outSt } uint8_t* pixelBytes = reinterpret_cast<uint8_t*>(env->GetDirectBufferAddress(inBuffer)); - if (pixelBytes == NULL) { + if (pixelBytes == nullptr) { ALOGE("%s: Could not get native ByteBuffer", __FUNCTION__); jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid ByteBuffer"); return; @@ -2051,16 +2196,20 @@ static void DngCreator_nativeWriteInputStream(JNIEnv* env, jobject thiz, jobject return; } - TiffWriter* writer = DngCreator_getCreator(env, thiz); NativeContext* context = DngCreator_getNativeContext(env, thiz); - if (writer == NULL || context == NULL) { + if (context == nullptr) { ALOGE("%s: Failed to initialize DngCreator", __FUNCTION__); jniThrowException(env, "java/lang/AssertionError", "Write called with uninitialized DngCreator"); return; } + sp<TiffWriter> writer = DngCreator_setup(env, thiz, uWidth, uHeight); + + if (writer.get() == nullptr) { + return; + } - // Validate DNG header + // Validate DNG size if (!validateDngHeader(env, writer, *(context->getCharacteristics()), width, height)) { return; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 062ae27618fd..1f47ce37e2ba 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -319,6 +319,7 @@ <protected-broadcast android:name="android.internal.policy.action.BURN_IN_PROTECTION" /> <protected-broadcast android:name="android.app.action.SYSTEM_UPDATE_POLICY_CHANGED" /> + <protected-broadcast android:name="android.app.action.DEVICE_OWNER_CHANGED" /> <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> <!-- ====================================================================== --> @@ -331,7 +332,7 @@ <!-- Used for runtime permissions related to user's contacts and profile. --> <permission-group android:name="android.permission-group.CONTACTS" - android:icon="@drawable/perm_group_social_info" + android:icon="@drawable/perm_group_contacts" android:label="@string/permgrouplab_contacts" android:description="@string/permgroupdesc_contacts" android:priority="100" /> @@ -391,7 +392,7 @@ <!-- Used for runtime permissions related to user's SMS messages. --> <permission-group android:name="android.permission-group.SMS" - android:icon="@drawable/perm_group_messages" + android:icon="@drawable/perm_group_sms" android:label="@string/permgrouplab_sms" android:description="@string/permgroupdesc_sms" android:priority="300" /> @@ -729,6 +730,7 @@ <!-- Used for permissions that are associated with accessing camera or capturing images/video from the device. --> <permission-group android:name="android.permission-group.SENSORS" + android:icon="@drawable/perm_group_sensors" android:label="@string/permgrouplab_sensors" android:description="@string/permgroupdesc_sensors" android:priority="800" /> @@ -959,9 +961,7 @@ android:label="@string/permlab_changeWimaxState" android:protectionLevel="normal" /> - <!--@SystemApi Allows applications to the the local WiFi and Bluetooth MAC address. - @hide - --> + <!-- Allows applications to act as network scorers. @hide @SystemApi--> <permission android:name="android.permission.SCORE_NETWORKS" android:protectionLevel="signature|privileged" /> @@ -1535,7 +1535,9 @@ <permission android:name="android.permission.CHANGE_CONFIGURATION" android:protectionLevel="signature|privileged|development" /> - <!-- Allows an application to read or write the system settings. --> + <!-- Allows an application to read or write the system settings. + <p>Protection level: signature + --> <permission android:name="android.permission.WRITE_SETTINGS" android:label="@string/permlab_writeSettings" android:description="@string/permdesc_writeSettings" @@ -1746,6 +1748,10 @@ <!-- ==================================== --> <eat-comment /> + <!-- @SystemApi Allows access to the list of accounts in the Accounts Service. --> + <permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED" + android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows applications to RW to diagnostic resources. <p>Not for use by third-party applications. --> <permission android:name="android.permission.DIAGNOSTIC" @@ -2052,10 +2058,24 @@ <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" android:protectionLevel="signature|privileged" /> - <!-- @hide Allows an application to grant or revoke specific permissions. --> - <permission android:name="android.permission.GRANT_REVOKE_PERMISSIONS" + <!-- Allows an application to grant specific permissions. + @hide --> + <permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" android:protectionLevel="signature|installer" /> + <!-- Allows an app that has this permission and the permissions to install packages + to request certain runtime permissions to be granted at installation. + @hide + @SystemApi --> + <permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" + android:protectionLevel="signature|installer|verifier" /> + + <!-- Allows an application to revoke specific permissions. + @hide + @SystemApi --> + <permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS" + android:protectionLevel="signature|installer|verifier" /> + <!-- @hide Allows an application to observe permission changes. --> <permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS" android:protectionLevel="signature|privileged" /> @@ -2539,12 +2559,6 @@ <permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" android:protectionLevel="signature" /> - <!-- Allows an app that has this permission and a permissions to install packages - to request all runtime permissions to be granted at installation. - @hide --> - <permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" - android:protectionLevel="signature" /> - <!-- 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. @@ -2567,10 +2581,16 @@ <permission android:name="android.permission.KILL_UID" android:protectionLevel="signature|installer" /> - <!-- Allows applications to act as network scorers. @hide @SystemApi--> + <!-- @SystemApi Allows applications to read the local WiFi and Bluetooth MAC address. + @hide --> <permission android:name="android.permission.LOCAL_MAC_ADDRESS" android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows access to MAC addresses of WiFi and Bluetooth peer devices. + @hide --> + <permission android:name="android.permission.PEERS_MAC_ADDRESS" + android:protectionLevel="signature" /> + <!-- 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. diff --git a/core/res/res/drawable/perm_group_messages.xml b/core/res/res/drawable/ic_more_items.xml index 4140e6ce204b..5fdcdcef7317 100644 --- a/core/res/res/drawable/perm_group_messages.xml +++ b/core/res/res/drawable/ic_more_items.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2015 The Android Open Source Project @@ -14,11 +15,15 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#000000" + android:pathData="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 +7v2h14V7H7z" /> <path - android:fillColor="#FF000000" - android:pathData="M40.0,4.0L8.0,4.0C5.79,4.0 4.02,5.79 4.02,8.0L4.0,44.0l8.0,-8.0l28.0,0.0c2.21,0.0 4.0,-1.79 4.0,-4.0L44.0,8.0c0.0,-2.21 -1.79,-4.0 -4.0,-4.0zm-4.0,24.0L12.0,28.0l0.0,-4.0l16.0,0.0l0.0,4.0zm0.0,-6.0L12.0,22.0l0.0,-4.0l24.0,0.0l0.0,4.0zm0.0,-6.0L12.0,16.0l0.0,-4.0l24.0,0.0l0.0,4.0z"/> -</vector> + android:pathData="M0 0h24v24H0z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/perm_group_calendar.xml b/core/res/res/drawable/perm_group_calendar.xml index a0f9dd24edaf..4dc7b37dbf25 100644 --- a/core/res/res/drawable/perm_group_calendar.xml +++ b/core/res/res/drawable/perm_group_calendar.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2015 The Android Open Source Project @@ -14,11 +15,15 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#000000" + android:pathData="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99 .9 -1.99 2L3 19c0 1.1 .89 2 2 +2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z" /> <path - android:fillColor="#FF000000" - android:pathData="M34.0,24.0L24.0,24.0l0.0,10.0l10.0,0.0L34.0,24.0zM32.0,2.0l0.0,4.0L16.0,6.0L16.0,2.0l-4.0,0.0l0.0,4.0l-2.0,0.0c-2.21,0.0 -3.98,1.79 -3.98,4.0L6.0,38.0c0.0,2.21 1.79,4.0 4.0,4.0l28.0,0.0c2.21,0.0 4.0,-1.79 4.0,-4.0L42.0,10.0c0.0,-2.21 -1.79,-4.0 -4.0,-4.0l-2.0,0.0L36.0,2.0l-4.0,0.0zm6.0,36.0L10.0,38.0L10.0,16.0l28.0,0.0l0.0,22.0z"/> -</vector> + android:pathData="M0 0h24v24H0z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/perm_group_camera.xml b/core/res/res/drawable/perm_group_camera.xml index 30d31ce625de..741a40e2891d 100644 --- a/core/res/res/drawable/perm_group_camera.xml +++ b/core/res/res/drawable/perm_group_camera.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2015 The Android Open Source Project @@ -14,11 +15,19 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#000000" + android:pathData="M 12 8.8 C 13.7673111995 8.8 15.2 10.2326888005 15.2 12 C 15.2 13.7673111995 13.7673111995 15.2 12 15.2 C 10.2326888005 15.2 8.8 13.7673111995 8.8 12 C 8.8 10.2326888005 10.2326888005 8.8 12 8.8 Z" /> + <path + android:fillColor="#000000" + android:pathData="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1 .9 2 2 2h16c1.1 0 2-.9 +2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 +5-2.24 5-5 5z" /> <path - android:fillColor="#FF000000" - android:pathData="M18.8,21.0l9.53,-16.51C26.94,4.18 25.49,4.0 24.0,4.0c-4.8,0.0 -9.19,1.69 -12.64,4.51l7.33,12.6 0.11,-0.2zm24.28,-3.0c-1.84,-5.85 -6.3,-10.52 -11.99,-12.68L23.77,18.0l19.31,0.0zm0.52,2.0L28.62,20.0l0.58,1.0 9.53,16.5C41.99,33.94 44.0,29.21 44.0,24.0c0.0,-1.37 -0.14,-2.71 -0.4,-4.0zm-26.53,4.0l-7.8,-13.5C6.01,14.06 4.0,18.79 4.0,24.0c0.0,1.3 0.14,2.7 0.4,4.0l14.98,0.0l-2.31,-4.0zM4.92,30.0c1.84,5.85 6.3,10.52 11.99,12.68L24.23,30.0L4.92,30.0zm22.54,0.0l-7.8,13.51c1.0,0.31 2.8,0.49 4.3,0.49 4.8,0.0 9.19,-1.69 12.64,-4.51L29.31,26.8 27.46,30.0z"/> -</vector> + android:pathData="M0 0h24v24H0z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/perm_group_social_info.xml b/core/res/res/drawable/perm_group_contacts.xml index f0f7a909357b..d698fd1735de 100644 --- a/core/res/res/drawable/perm_group_social_info.xml +++ b/core/res/res/drawable/perm_group_contacts.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2015 The Android Open Source Project @@ -14,11 +15,17 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:pathData="M0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0z" /> <path - android:fillColor="#FF000000" - android:pathData="M32.0,22.0c3.31,0.0 5.98,-2.69 5.98,-6.0s-2.67,-6.0 -5.98,-6.0c-3.31,0.0 -6.0,2.69 -6.0,6.0s2.69,6.0 6.0,6.0zm-16.0,0.0c3.31,0.0 5.98,-2.69 5.98,-6.0s-2.67,-6.0 -5.98,-6.0c-3.31,0.0 -6.0,2.69 -6.0,6.0s2.69,6.0 6.0,6.0zm0.0,4.0c-4.67,0.0 -14.0,2.34 -14.0,7.0l0.0,5.0l28.0,0.0l0.0,-5.0c0.0,-4.66 -9.33,-7.0 -14.0,-7.0zm16.0,0.0c-0.58,0.0 -1.2,0.04 -1.9,0.11C32.39,27.78 34.0,30.03 34.0,33.0l0.0,5.0l12.0,0.0l0.0,-5.0c0.0,-4.66 -9.33,-7.0 -14.0,-7.0z"/> -</vector> + android:fillColor="#000000" + android:pathData="M20 0H4v2h16V0zM4 24h16v-2H4v2zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1 .9 2 2 2h16c1.1 +0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 2.75c1.24 0 2.25 1.01 2.25 2.25s-1.01 2.25-2.25 +2.25S9.75 10.24 9.75 9 10.76 6.75 12 6.75zM17 17H7v-1.5c0-1.67 3.33-2.5 5-2.5s5 +.83 5 2.5V17z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/perm_group_location.xml b/core/res/res/drawable/perm_group_location.xml index 4184cf9e13b4..fbc6066b218e 100644 --- a/core/res/res/drawable/perm_group_location.xml +++ b/core/res/res/drawable/perm_group_location.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2015 The Android Open Source Project @@ -14,11 +15,15 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#000000" + android:pathData="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 +9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" /> <path - android:fillColor="#FF000000" - android:pathData="M24.0,16.0c-4.42,0.0 -8.0,3.58 -8.0,8.0s3.58,8.0 8.0,8.0 8.0,-3.58 8.0,-8.0 -3.58,-8.0 -8.0,-8.0zm17.88,6.0C40.96,13.66 34.34,7.04 26.0,6.12L26.0,2.0l-4.0,0.0l0.0,4.12C13.66,7.04 7.04,13.66 6.12,22.0L2.0,22.0l0.0,4.0l4.12,0.0c0.92,8.34 7.54,14.96 15.88,15.88L22.0,46.0l4.0,0.0l0.0,-4.12c8.34,-0.92 14.96,-7.54 15.88,-15.88L46.0,26.0l0.0,-4.0l-4.12,0.0zM24.0,38.0c-7.73,0.0 -14.0,-6.27 -14.0,-14.0s6.27,-14.0 14.0,-14.0 14.0,6.27 14.0,14.0 -6.27,14.0 -14.0,14.0z"/> -</vector> + android:pathData="M0 0h24v24H0z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/perm_group_microphone.xml b/core/res/res/drawable/perm_group_microphone.xml index 670ef9813521..c565d203caa4 100644 --- a/core/res/res/drawable/perm_group_microphone.xml +++ b/core/res/res/drawable/perm_group_microphone.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2015 The Android Open Source Project @@ -14,11 +15,16 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#000000" + android:pathData="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 +3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 +6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z" /> <path - android:fillColor="#FF000000" - android:pathData="M24.0,28.0c3.31,0.0 5.98,-2.69 5.98,-6.0L30.0,10.0c0.0,-3.32 -2.68,-6.0 -6.0,-6.0 -3.31,0.0 -6.0,2.68 -6.0,6.0l0.0,12.0c0.0,3.31 2.69,6.0 6.0,6.0zm10.6,-6.0c0.0,6.0 -5.07,10.2 -10.6,10.2 -5.52,0.0 -10.6,-4.2 -10.6,-10.2L10.0,22c0.0,6.83 5.44,12.47 12.0,13.44L22.0,42.0l4.0,0.0l0.0,-6.56c6.56,-0.97 12.0,-6.61 12.0,-13.44l-3.4,0.0z"/> -</vector> + android:pathData="M0 0h24v24H0z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/perm_group_phone_calls.xml b/core/res/res/drawable/perm_group_phone_calls.xml index 04ac6b96717c..a64789433608 100644 --- a/core/res/res/drawable/perm_group_phone_calls.xml +++ b/core/res/res/drawable/perm_group_phone_calls.xml @@ -1,3 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2015 The Android Open Source Project @@ -14,11 +15,17 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:pathData="M0 0h24v24H0z" /> <path - android:fillColor="#FF000000" - android:pathData="M13.25,21.59c2.88,5.66 7.51,10.29 13.18,13.17l4.4,-4.41c0.55,-0.55 1.34,-0.71 2.03,-0.49C35.1,30.6 37.51,31.0 40.0,31.0c1.11,0.0 2.0,0.89 2.0,2.0l0.0,7.0c0.0,1.11 -0.89,2.0 -2.0,2.0C21.22,42.0 6.0,26.78 6.0,8.0c0.0,-1.1 0.9,-2.0 2.0,-2.0l7.0,0.0c1.11,0.0 2.0,0.89 2.0,2.0 0.0,2.4 0.4,4.9 1.14,7.1 0.2,0.6 0.06,1.48 -0.49,2.03l-4.4,4.42z"/> -</vector> + android:fillColor="#000000" + android:pathData="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27 .67 -.36 1.02-.24 1.12 +.37 2.33 .57 3.57 .57 .55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 +0-.55 .45 -1 1-1h3.5c.55 0 1 .45 1 1 0 1.25 .2 2.45 .57 3.57 .11 .35 .03 .74-.25 +1.02l-2.2 2.2z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/perm_group_sensors.xml b/core/res/res/drawable/perm_group_sensors.xml new file mode 100644 index 000000000000..ce36c13e1690 --- /dev/null +++ b/core/res/res/drawable/perm_group_sensors.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#000000" + android:pathData="M13.49 5.48c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-3.6 13.9l1-4.4 2.1 +2v6h2v-7.5l-2.1-2 .6-3c1.3 1.5 3.3 2.5 5.5 2.5v-2c-1.9 +0-3.5-1-4.3-2.4l-1-1.6c-.4-.6-1-1-1.7-1-.3 0-.5 .1 -.8 .1 l-5.2 +2.2v4.7h2v-3.4l1.8-.7-1.6 8.1-4.9-1-.4 2 7 1.4z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/perm_group_sms.xml b/core/res/res/drawable/perm_group_sms.xml new file mode 100644 index 000000000000..9b32c60150aa --- /dev/null +++ b/core/res/res/drawable/perm_group_sms.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#000000" + android:pathData="M20 2H4c-1.1 0-1.99 .9 -1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9 +11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z" /> + <path + android:pathData="M0 0h24v24H0z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/perm_group_storage.xml b/core/res/res/drawable/perm_group_storage.xml index 74f16d866b15..477270d202e6 100644 --- a/core/res/res/drawable/perm_group_storage.xml +++ b/core/res/res/drawable/perm_group_storage.xml @@ -1,7 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> <!-- -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"); + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -14,11 +15,15 @@ Copyright (C) 2015 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + + <path + android:fillColor="#000000" + android:pathData="M10 4H4c-1.1 0-1.99 .9 -1.99 2L2 18c0 1.1 .9 2 2 2h16c1.1 0 2-.9 +2-2V8c0-1.1-.9-2-2-2h-8l-2-2z" /> <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"/> -</vector> + android:pathData="M0 0h24v24H0z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/layout/time_picker_header_material.xml b/core/res/res/layout/time_picker_header_material.xml index 3f5e300628b2..3c3a8a8ff3ed 100644 --- a/core/res/res/layout/time_picker_header_material.xml +++ b/core/res/res/layout/time_picker_header_material.xml @@ -22,7 +22,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" - android:padding="@dimen/timepicker_separator_padding"> + android:padding="@dimen/timepicker_separator_padding" + android:paddingStart="16dp" + android:paddingEnd="16dp"> <!-- The hour should always be to the left of the separator, regardless of the current locale's layout direction. --> @@ -68,14 +70,14 @@ android:layout_height="wrap_content" android:layout_toRightOf="@+id/minutes" android:layout_alignBaseline="@+id/minutes" + android:paddingStart="8dp" + android:paddingEnd="8dp" android:orientation="vertical" android:baselineAlignedChildIndex="1"> <CheckedTextView android:id="@+id/am_label" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingStart="@dimen/timepicker_ampm_horizontal_padding" - android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding" android:paddingTop="@dimen/timepicker_am_top_padding" android:textAppearance="@style/TextAppearance.Material.TimePicker.AmPmLabel" android:lines="1" @@ -84,8 +86,6 @@ android:id="@+id/pm_label" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingStart="@dimen/timepicker_ampm_horizontal_padding" - android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding" android:paddingTop="@dimen/timepicker_pm_top_padding" android:textAppearance="@style/TextAppearance.Material.TimePicker.AmPmLabel" android:lines="1" diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index ae948abf7e0f..f784ce543199 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Vingerafdrukikoon"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lees sinkroniseer-instellings"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Laat die program toe om die sinkroniseringinstellings van \'n rekening te lees. Byvoorbeeld, dit kan bepaal of die People-program met \'n rekening gesinkroniseer is."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"wissel tussen sinkronisasie aan en af"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Sel bygevoeg"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Sel <xliff:g id="CELL_INDEX">%1$s</xliff:g> is bygevoeg"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patroon klaar"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Patroonarea."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Legstuk %2$d van %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Voeg legstuk by."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leeg"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 00c3ee5c4cb3..49fe30ddff69 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"የጣት አሻራ አዶ"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"የሥምሪያ ቅንብሮች አንብብ"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"መተግበሪያው የአንድ መለያ የማመሳሰል ቅንብሮችን እንዲያነብ ይፈቅድለታል። ለምሳሌ ይህ የሰዎች መተግበሪያ ከመለያ ጋር መመሳሰሉን አለመመሳሰሉን ሊወስን ይችላል።"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ማመሳሰያ በማብራትና በማጥፋት መካከል ቀያይር"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"ንድፍ ተጠናቋል"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"የስርዓተ-ጥለት አካባቢ።"</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ባዶ"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index a6d81fc35090..169a2296508c 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -438,6 +438,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"رمز بصمة الإصبع"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"قراءة إعدادات المزامنة"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"للسماح للتطبيق بقراءة الإعدادات المتزامنة لحساب ما. على سبيل المثال، يمكن أن يؤدي هذا إلى تحديد ما إذا تمت مزامنة تطبيق \"الأشخاص\" مع حساب ما."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"التبديل بين تشغيل المزامنة وإيقافها"</string> @@ -716,6 +717,7 @@ <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_detected" msgid="4988730895554057058">"اكتمل النمط"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"منطقة النقش."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"فارغة"</string> diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml index fa6ea9f14b37..275d4b9450ff 100644 --- a/core/res/res/values-az-rAZ/strings.xml +++ b/core/res/res/values-az-rAZ/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Barmaq izi ikonası"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"sinx ayarlarını oxu"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Tətbiqə hesablar üçün sinxronizasiya nizamlarını oxuma icazəsi verir. Məsələn, bu Şəxslər tətbiqinin sinxronizə olunub-olunmadığını təyin edə bilər."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"sinxronizasiyaya davam edir və onu söndürür"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Xana əlavə edildi"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Xana <xliff:g id="CELL_INDEX">%1$s</xliff:g> əlavə edildi"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Model tamamlandı"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Model sahəsi."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget əlavə edin."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 199c13c25760..455f4cf475a1 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Икона за отпечатък"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"четене на настройките за синхронизиране"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Разрешава на приложението да чете настройките за синхронизиране на профил. Например това може да определи дали приложението Хора е синхронизирано с даден профил."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"включване и изключване на синхронизирането"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"Фигурата е завършена"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Област на фигурата."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Празно"</string> diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml index f249fe98cd5f..c5e2275b14fe 100644 --- a/core/res/res/values-bn-rBD/strings.xml +++ b/core/res/res/values-bn-rBD/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"আঙ্গুলের ছাপ আইকন"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"সিঙ্ক সেটিংস পড়ে"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"অ্যাপ্লিকেশানটিকে একটি অ্যাকাউন্টের জন্য সিঙ্ক সেটিংস পড়ার অনুমতি দেয়৷ উদাহরণস্বরূপ, \'পিপল\' অ্যাপ্লিকেশানটি কোনো অ্যাকাউন্টের সাথে সিঙ্ক করা আছে কিনা তা নির্ধারণ করতে পারে৷"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"সমন্বয় চালু এবং বন্ধ করা টগল করুন"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"প্যাটার্ন সম্পন্ন হয়েছে"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"প্যাটার্ন এলাকা৷"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s৷ %3$d এর %2$d উইজেট৷"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"উইজেট যোগ করুন"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"খালি"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 789b13cf189a..82d255c9831e 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona d\'empremta digital"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"llegir la configuració de sincronització"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet que l\'aplicació llegeixi la configuració de sincronització d\'un compte. Per exemple, això pot determinar que l\'aplicació Persones estigui sincronitzada amb un compte."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activar o desactivar la sincronització"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"S\'ha afegit una cel·la"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"S\'ha afegit la cel·la <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patró completat"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Àrea de patró"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Afegeix un widget"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Buit"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 9952cdb16193..44b813f9e998 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -436,6 +436,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona otisku prstů"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"čtení nastavení synchronizace"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Umožňuje aplikaci číst nastavení synchronizace v účtu. Může například určit, zda je s účtem synchronizována aplikace Lidé."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"vypnutí nebo zapnutí synchronizace"</string> @@ -714,6 +715,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Buňka přidána"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Byla přidána buňka <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Bezpečnostní gesto dokončeno"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Oblast pro zadání bezpečnostního gesta."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d z %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Přidat widget"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prázdné"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 9e22ff716dce..28d699fcd327 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -354,8 +354,8 @@ <string name="permdesc_flashlight" msgid="6522284794568368310">"Tillader, at appen kan kontrollere lommelygten."</string> <string name="permlab_callPhone" msgid="3925836347681847954">"ringe direkte op til telefonnumre"</string> <string name="permdesc_callPhone" msgid="3740797576113760827">"Tillader, at appen kan ringe til telefonnumre uden din indgriben. Dette kan resultere i uventede opkrævninger eller opkald. Bemærk, at appen med denne tilladelse ikke kan ringe til nødopkaldsnumre. Skadelige apps kan koste dig penge ved at foretage opkald uden din bekræftelse."</string> - <string name="permlab_accessImsCallService" msgid="3574943847181793918">"få adgang til IMS-opkaldstjeneste"</string> - <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Tillader, at appen kan bruge IMS-tjenesten til at foretage opkald, uden at du foretager dig noget."</string> + <string name="permlab_accessImsCallService" msgid="3574943847181793918">"få adgang til chat-opkaldstjeneste"</string> + <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Tillader, at appen kan bruge chat-tjenesten til at foretage opkald, uden du gør noget."</string> <string name="permlab_readPhoneState" msgid="9178228524507610486">"læse telefonens status og identitet"</string> <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tillader, at appen kan få adgang til telefonfunktionerne på enheden. Med denne tilladelse kan appen fastslå telefonnummeret og enheds-id\'erne, hvorvidt et opkald er aktivt samt det eksterne nummer, der oprettes forbindelse til via et opkald."</string> <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"afholde tabletcomputeren fra at gå i dvale"</string> @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon for fingeraftryk"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"læse indstillinger for synkronisering"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Tillader, at appen kan læse synkroniseringsindstillingerne for en konto. Denne tilladelse kan f.eks. fastslå, om appen Personer er synkroniseret med en konto."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"slå synkronisering til og fra"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celle er tilføjet"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Celle <xliff:g id="CELL_INDEX">%1$s</xliff:g> blev tilføjet"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Mønster er fuldført"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Mønsterområde."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d af %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tilføj widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 9e191fe961a6..e460a5d80536 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingerabdruck-Symbol"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"Synchronisierungseinstellungen lesen"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Ermöglicht der App, die Synchronisierungseinstellungen eines Kontos zu lesen. Beispielsweise kann damit festgestellt werden, ob Kontakte mit einem Konto synchronisiert werden."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"Synchronisierung aktivieren oder deaktivieren"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Zelle hinzugefügt"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Punkt <xliff:g id="CELL_INDEX">%1$s</xliff:g> hinzugefügt"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Muster abgeschlossen"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Bereich für Muster"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d von %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget hinzufügen"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leer"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 89c758d3e8ad..748b22f3cf1b 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ανάγνωση ρυθμίσεων συγχρονισμού"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Επιτρέπει στην εφαρμογή την ανάγνωση των ρυθμίσεων συγχρονισμού για έναν λογαριασμό. Για παράδειγμα, αυτό μπορεί να καθορίσει εάν η εφαρμογή \"Άτομα\" είναι συγχρονισμένη με έναν λογαριασμό."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"εναλλαγή ενεργοποίησης και απενεργοποίησης συγχρονισμού"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"Το μοτίβο ολοκληρώθηκε"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Περιοχή μοτίβου."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Κενή"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 5e551a97ed8a..8ab48590a05a 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingerprint icon"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Allows the app to read the sync settings for an account. For example, this can determine whether the People app is synced with an account."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"toggle sync on and off"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cell added"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cell <xliff:g id="CELL_INDEX">%1$s</xliff:g> added"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pattern completed"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Pattern area."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 5e551a97ed8a..8ab48590a05a 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingerprint icon"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Allows the app to read the sync settings for an account. For example, this can determine whether the People app is synced with an account."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"toggle sync on and off"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cell added"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cell <xliff:g id="CELL_INDEX">%1$s</xliff:g> added"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pattern completed"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Pattern area."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 5e551a97ed8a..8ab48590a05a 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingerprint icon"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Allows the app to read the sync settings for an account. For example, this can determine whether the People app is synced with an account."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"toggle sync on and off"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cell added"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cell <xliff:g id="CELL_INDEX">%1$s</xliff:g> added"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pattern completed"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Pattern area."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d of %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Add widget"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Empty"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 15cfa6e1ac79..647b3012060d 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ícono de huella digital"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"leer la configuración de sincronización"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Este permiso permite que la aplicación consulte la configuración de sincronización de una cuenta. Esto permite, por ejemplo, determinar si la aplicación Personas está sincronizada con una cuenta."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activar y desactivar la sincronización"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Se agregó una celda."</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Se agregó la celda <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Se completó el patrón"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Área de patrón"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Agregar widget"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vacío"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index be2b9624b8f3..49d296c650e2 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icono de huella digital"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"leer la configuración de sincronización"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite que la aplicación consulte la configuración de sincronización de una cuenta. La aplicación puede utilizar este permiso, por ejemplo, para determinar si la aplicación Contactos está sincronizada con una cuenta."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activar y desactivar la sincronización"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Se ha añadido una celda."</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Se ha añadido la celda <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patrón completado"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Área de patrón"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Añadir widget"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vacío"</string> @@ -1001,7 +1003,7 @@ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Puedes cambiar esta opción más tarde en Ajustes > Aplicaciones."</string> <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Permitir siempre"</string> <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"No permitir nunca"</string> - <string name="sim_removed_title" msgid="6227712319223226185">"Tarjeta SIM eliminada"</string> + <string name="sim_removed_title" msgid="6227712319223226185">"Tarjeta SIM retirada"</string> <string name="sim_removed_message" msgid="5450336489923274918">"La red móvil no estará disponible hasta que reinicies el dispositivo con una tarjeta SIM válida insertada."</string> <string name="sim_done_button" msgid="827949989369963775">"Listo"</string> <string name="sim_added_title" msgid="3719670512889674693">"Tarjeta SIM añadida"</string> diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml index faeb76378d3e..2822119be560 100644 --- a/core/res/res/values-et-rEE/strings.xml +++ b/core/res/res/values-et-rEE/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Sõrm <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Sõrmejälje ikoon"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"loe sünkroonimisseadeid"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Võimaldab rakendusel lugeda konto sünkroonimisseadeid. Näiteks võib see määrata, kas rakendus Inimesed on kontoga sünkroonitud."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"lülitage sünkroonimine sisse ja välja"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Lahter on lisatud"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Lisati lahter <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Muster on valmis"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Mustri ala."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Vidin %2$d/%3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Vidina lisamine."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tühi"</string> diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml index 960bc563f712..4d8e62123a36 100644 --- a/core/res/res/values-eu-rES/strings.xml +++ b/core/res/res/values-eu-rES/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> hatza"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Hatz-markaren ikonoa"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"Irakurri sinkronizazio-ezarpenak"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Kontu baten sinkronizazio-ezarpenak irakurtzeko baimena ematen die aplikazioei. Adibidez, Jendea aplikazioa konturen batekin sinkronizatuta dagoen zehatz dezake."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"sinkronizazioa aktibatzea eta desaktibatzea"</string> @@ -712,6 +713,7 @@ <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> puntua"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Eredua osatu da"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Eredua marrazteko eremua."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Hutsik"</string> @@ -883,7 +885,7 @@ <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Irekin %1$s aplikazioarekin"</string> <string name="whichEditApplication" msgid="144727838241402655">"Editatu honekin:"</string> <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editatu %1$s aplikazioarekin"</string> - <string name="whichSendApplication" msgid="6902512414057341668">"Partekatu honekin:"</string> + <string name="whichSendApplication" msgid="6902512414057341668">"Partekatu hauen bidez:"</string> <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Partekatu %1$s aplikazioarekin"</string> <string name="whichHomeApplication" msgid="4307587691506919691">"Hautatu hasierako aplikazioa"</string> <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Erabili %1$s hasierako aplikazio gisa"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 48ab9bfa178a..d9e2656d0eba 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"نماد اثر انگشت"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"خواندن تنظیمات همگامسازی"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"به برنامه اجازه میدهد تنظیمات را برای یک حساب بخواند. بهعنوان مثال، این ویژگی میتواند تعیین کند آیا حساب «افراد» شما با یک حساب همگامسازی شده است."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"تغییر وضعیت همگامسازی بین فعال و غیرفعال"</string> @@ -464,8 +465,8 @@ <string name="permdesc_control_incall_experience" msgid="915159066039828124">"به برنامه امکان میدهد تجربه کاربر در حال تماس را ارائه دهد."</string> <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"خواندن سابقه استفاده از شبکه"</string> <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"به برنامه اجازه میدهد تا کاربرد شبکه را در طول زمان برای برنامهها و شبکههای خاص بخواند."</string> - <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"مدیریت خط مشی شبکه"</string> - <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"به برنامه اجازه میدهد تا خط مشیهای شبکه را مدیریت کند و قوانین خاص برنامه را تعیین کند."</string> + <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"مدیریت خطمشی شبکه"</string> + <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"به برنامه اجازه میدهد تا خطمشیهای شبکه را مدیریت کند و قوانین خاص برنامه را تعیین کند."</string> <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"اصلاح محاسبه استفاده از شبکه"</string> <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"به برنامه اجازه میدهد تا نحوه محاسبه کاربرد شبکه در برنامه را تغییر دهد. برای استفاده برنامههای عادی نیست."</string> <string name="permlab_accessNotifications" msgid="7673416487873432268">"اعلانهای دسترسی"</string> @@ -667,7 +668,7 @@ <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"سیم کارت را وارد کنید."</string> <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"سیم کارت موجود نیست یا قابل خواندن نیست. یک سیم کارت وارد کنید."</string> <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"سیم کارت غیرقابل استفاده است."</string> - <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"سیم کارت شما به طور دائم غیر فعال شده است. \nبرای داشتن سیم کارت دیگر با ارائهدهنده سرویس بیسیم خود تماس بگیرید."</string> + <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"سیم کارت شما بهطور دائم غیر فعال شده است. \nبرای داشتن سیم کارت دیگر با ارائهدهنده سرویس بیسیم خود تماس بگیرید."</string> <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"آهنگ قبلی"</string> <string name="lockscreen_transport_next_description" msgid="573285210424377338">"آهنگ بعدی"</string> <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"توقف موقت"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"الگو تکمیل شد"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ناحیه الگو."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"خالی"</string> @@ -911,8 +913,8 @@ <string name="screen_compat_mode_scale" msgid="3202955667675944499">"مقیاس"</string> <string name="screen_compat_mode_show" msgid="4013878876486655892">"همیشه نشان داده شود"</string> <string name="screen_compat_mode_hint" msgid="1064524084543304459">"در تنظیمات سیستم >برنامهها > مورد دانلود شده آن را دوباره فعال کنید."</string> - <string name="smv_application" msgid="3307209192155442829">"برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> (پردازش <xliff:g id="PROCESS">%2$s</xliff:g>) خط مشی StrictMode اجرایی خود را نقض کرده است."</string> - <string name="smv_process" msgid="5120397012047462446">"فرآیند <xliff:g id="PROCESS">%1$s</xliff:g> خط مشی StrictMode اجرای خودکار خود را نقض کرده است."</string> + <string name="smv_application" msgid="3307209192155442829">"برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> (پردازش <xliff:g id="PROCESS">%2$s</xliff:g>) خطمشی StrictMode اجرایی خود را نقض کرده است."</string> + <string name="smv_process" msgid="5120397012047462446">"فرآیند <xliff:g id="PROCESS">%1$s</xliff:g> خطمشی StrictMode اجرای خودکار خود را نقض کرده است."</string> <string name="android_upgrading_title" msgid="1584192285441405746">"Android در حال ارتقا است..."</string> <string name="android_start_title" msgid="8418054686415318207">"Android در حال راهاندازی است..."</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"بهینهسازی فضای ذخیرهسازی."</string> @@ -1060,7 +1062,7 @@ <string name="ext_media_unmountable_notification_message" msgid="1586311304430052169">"<xliff:g id="NAME">%s</xliff:g> خراب است. برای اصلاح لمس کنید."</string> <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> پشتیبانی نشده"</string> <string name="ext_media_unsupported_notification_message" msgid="8789610369456474891">"این دستگاه از این <xliff:g id="NAME">%s</xliff:g> پشتیبانی نمیکند. برای نصب آن در یک قالب پشتیبانی شده، لمس کنید."</string> - <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> به طور غیرمنتظره جدا شد"</string> + <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> بهطور غیرمنتظره جدا شد"</string> <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"قبل از جدا کردن، برای جلوگیری از از دست رفتن اطلاعات، ارتباط <xliff:g id="NAME">%s</xliff:g> را قطع کنید."</string> <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"<xliff:g id="NAME">%s</xliff:g> جدا شده است"</string> <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"<xliff:g id="NAME">%s</xliff:g> جدا شد؛ رسانه جدیدی وارد کنید"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index b4963629e41d..6e6c3dd46cc1 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Sormenjälkikuvake"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lue synkronointiasetuksia"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Antaa sovelluksen lukea tilien synkronointiasetuksia. Sovellus voi esimerkiksi määrittää, onko Henkilöt-sovellus synkronoitu tilin kanssa."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ota synkronointi käyttöön tai poista se käytöstä"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Solu lisätty"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Solu <xliff:g id="CELL_INDEX">%1$s</xliff:g> lisätty"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Kuvio valmis"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Kuvioalue."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d/%3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Lisää widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tyhjä"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index b74b055fa38a..b75ea48391b8 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icône d\'empreinte digitale"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lire les paramètres de synchronisation"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet à l\'application d\'accéder aux paramètres de synchronisation d\'un compte. Par exemple, cette autorisation peut permettre de déterminer si l\'application Contacts est synchronisée avec un compte ou non."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activer ou désactiver la synchronisation"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cellule ajoutée."</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cellule <xliff:g id="CELL_INDEX">%1$s</xliff:g> ajoutée"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Schéma terminé."</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zone du schéma"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d sur %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ajouter un widget"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vide"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 6ed07a9652eb..085e23c1b88e 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icône d\'empreinte digitale"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lire les paramètres de synchronisation"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet à l\'application d\'accéder aux paramètres de synchronisation d\'un compte. Par exemple, cette autorisation peut permettre de déterminer si l\'application Contacts est synchronisée avec un compte ou non."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activer/désactiver la synchronisation"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cellule ajoutée."</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Le point <xliff:g id="CELL_INDEX">%1$s</xliff:g> a bien été ajouté."</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Schéma terminé."</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zone du schéma"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d sur %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ajouter un widget"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vide"</string> diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml index ee2a0359f20b..4838fee6d827 100644 --- a/core/res/res/values-gl-rES/strings.xml +++ b/core/res/res/values-gl-rES/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona de impresión dixital"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler a configuración de sincronización"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite á aplicación ler a configuración de sincronización dunha conta. Por exemplo, esta acción pode determinar se a aplicación Contactos se sincroniza cunha conta."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activar e desactivar a sincronización"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Engadiuse un móbil"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Engadiuse a cela <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Completouse o padrón"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zona do padrón"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Engadir widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Baleiro"</string> diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml index f5f51269baab..1e5d07650cb5 100644 --- a/core/res/res/values-gu-rIN/strings.xml +++ b/core/res/res/values-gu-rIN/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ફિંગરપ્રિન્ટ આયકન"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"સમન્વયન સેટિંગ્સ વાંચો"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"એપ્લિકેશનને એકાઉન્ટ માટે સમન્વયન સેટિંગ્સને વાંચવાની મંજૂરી આપે છે. ઉદાહરણ તરીકે, આ એકાઉન્ટ સાથે લોકો એપ્લિકેશન સમન્વયિત થઈ છે કે કેમ તે નિર્ધારિત કરી શકે છે."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"સમન્વયન ચાલુ અને બંધ ટોગલ કરો"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"પેટર્ન પૂર્ણ કરી"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"પેટર્ન ક્ષેત્ર."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d માંથી %2$d વિજેટ."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"વિજેટ ઉમેરો."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ખાલી"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 38b7456a136a..522c2a0f8783 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"अंगुली <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"फ़िंगरप्रिंट आइकन"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"समन्वयन सेटिंग पढ़ें"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ऐप्स को किसी खाते की समन्वयन सेटिंग पढ़ने देता है. उदाहरण के लिए, इससे यह निर्धारित किया जा सकता है कि लोग ऐप्स किसी खाते के साथ समन्वयित है या नहीं."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"समन्वयन बंद या चालू टॉगल करें"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"आकार पूरा किया गया"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"आकार क्षेत्र."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d विजेट में से %2$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट जोड़ें"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"खाली"</string> @@ -875,7 +877,7 @@ <string name="no" msgid="5141531044935541497">"अभी नहीं"</string> <string name="dialog_alert_title" msgid="2049658708609043103">"ध्यान दें"</string> <string name="loading" msgid="7933681260296021180">"लोड हो रहे हैं..."</string> - <string name="capital_on" msgid="1544682755514494298">"चालू"</string> + <string name="capital_on" msgid="1544682755514494298">"ऑन"</string> <string name="capital_off" msgid="6815870386972805832">"बंद"</string> <string name="whichApplication" msgid="4533185947064773386">"इसका उपयोग करके क्रिया पूर्ण करें"</string> <string name="whichApplicationNamed" msgid="8260158865936942783">"%1$s का उपयोग करके कार्रवाई पूर्ण करें"</string> @@ -1043,7 +1045,7 @@ <string name="usb_notification_message" msgid="7347368030849048437">"और विकल्पों के लिए स्पर्श करें."</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="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदलें"</string> <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड चुनें"</string> <string name="show_ime" msgid="9157568568695230830">"इनपुट विधि दिखाएं"</string> <string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 5277ec27ad1a..69b8577f9375 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -435,6 +435,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona otiska prsta"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"čitanje postavki sinkronizacije"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Aplikaciji omogućuje čitanje postavki sinkronizacije za račun. Time se, primjerice, može utvrditi je li aplikacija Osobe sinkronizirana s računom."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"uključivanje/isključivanje sinkronizacije"</string> @@ -713,6 +714,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Dodan je mobitel"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Dodana je ćelija <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Uzorak je dovršen"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Područje uzorka."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d od %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodavanje widgeta."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prazno"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 2388a8c719e3..1b45d1ce019c 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ujjlenyomat ikon"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"szinkronizálási beállítások olvasása"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Lehetővé teszi az alkalmazás számára egy fiók szinkronizálási beállításainak beolvasását. Például ellenőrizheti, hogy a Személyek alkalmazás szinkronizálva van-e egy fiókkal."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"szinkronizálás be-és kikapcsolása"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cella hozzáadva"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g>. pont hozzáadva"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Minta befejezve"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Mintaterület"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Modul %3$d/%2$d"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Modul hozzáadása."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Üres"</string> diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml index 725b0080909a..92842b4c303d 100644 --- a/core/res/res/values-hy-rAM/strings.xml +++ b/core/res/res/values-hy-rAM/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Մատնահետքի պատկերակ"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"կարդալ համաժամեցման կարգավորումները"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Թույլ է տալիս հավելվածին կարդալ համաժամեցման կարգավորումները հաշվի համար: Օրինակ` այն կարող է որոշել, արդյոք Մարդիկ հավելվածը համաժամեցված է հաշվի հետ:"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"համաժամեցումը փոխարկել միացվածի և անջատվածի"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"Սխեմայի հավաքումն ավարտված է"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Սխեմայի տարածք:"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Վիջեթ %2$d of %3$d:"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ավելացնել վիջեթ:"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Դատարկ"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 8a4e58013e3e..02299b011bc6 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon sidik jari"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"baca setelan sinkron"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Memungkinkan aplikasi membaca setelan sinkronisasi untuk sebuah akun. Misalnya, izin ini dapat menentukan apakah aplikasi Orang disinkronkan dengan sebuah akun."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"nyalakan dan matikan sinkronisasi"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Sel ditambahkan"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Sel <xliff:g id="CELL_INDEX">%1$s</xliff:g> ditambahkan"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Pola selesai"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Area pola."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tambahkan widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Kosong"</string> diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml index e17805f9b5e9..e57400a2b765 100644 --- a/core/res/res/values-is-rIS/strings.xml +++ b/core/res/res/values-is-rIS/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingrafaratákn"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lesa samstillingar"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Leyfir forriti að lesa kosti samstillingar fyrir reikning. Þetta er til dæmis hægt að nota til að komast að því hvort forritið Fólk er samstillt við reikning."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"kveikja og slökkva á samstillingu"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Hólfi bætt við"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Hólfi <xliff:g id="CELL_INDEX">%1$s</xliff:g> bætt við"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Mynstur teiknað"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Svæði mynsturs."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Græja %2$d af %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Bæta græju við."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Autt"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 216a68edc1d0..5722c6aa7122 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona dell\'impronta digitale"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lettura impostazioni di sincronizz."</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Consente all\'applicazione di leggere le impostazioni di sincronizzazione per un account. Ad esempio, questa autorizzazione può determinare se l\'applicazione Persone è sincronizzata con un account."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"attivazione e disattivazione della sincronizzazione"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cella aggiunta"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"È stata aggiunta la cella <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Sequenza completata"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Area sequenza."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d di %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Aggiungi widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vuoto"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index fa7388b8b562..7f67caf6c2b7 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -436,6 +436,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"סמל טביעת אצבע"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"קרא את הגדרות הסינכרון"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"מאפשר לאפליקציה לקרוא את הגדרות הסנכרון של חשבון. לדוגמה, ניתן לגלות כך האם האפליקציה \'אנשים\' מסונכרן עם חשבון כלשהו."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"הפעלת וכיבוי סנכרון"</string> @@ -714,6 +715,7 @@ <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_detected" msgid="4988730895554057058">"התבנית הושלמה"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"אזור ציור קו."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d מתוך %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"הוסף Widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ריק"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 56b4662c1e55..2ce3bad4a3e4 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"指紋<xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指紋アイコン"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"同期設定の読み取り"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"アカウントの同期設定の読み取りをアプリに許可します。たとえば、連絡帳アプリがアカウントと同期しているかどうかをアプリから特定できるようになります。"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"同期のON/OFFの切り替え"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"パターンの描画が完了しました"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"パターンエリアです。"</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"なし"</string> diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml index 0d94ad5b83a5..f77167903ece 100644 --- a/core/res/res/values-ka-rGE/strings.xml +++ b/core/res/res/values-ka-rGE/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"თითის ანაბეჭდის ხატულა"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"სინქრონიზაციის პარამეტრების წაკითხვა"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"აპს შეეძლება, წაიკითხოს ანგარიშის სინქრონიზაციის პარამეტრები. მაგალითად, მას შეეძლება განსაზღვროს, არის თუ არა People აპი სინქრონიზებული ანგარიშთან."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"სინქრონიზაციის ჩართვა და გამორთვა"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"ნიმუშის შექმნა დასრულებულია"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ნიმუშების სივრცე."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. ვიჯეტი %2$d of %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ვიჯეტის დამატება"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ცარიელი"</string> diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml index d121a8d060b9..7165254bd81f 100644 --- a/core/res/res/values-kk-rKZ/strings.xml +++ b/core/res/res/values-kk-rKZ/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> саусағы"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Саусақ ізі белгішесі"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"синх параметрлерін оқу"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Қолданбаға есептік жазба синхрондау параметрлерін оқу мүмкіндігін береді. Мысалы, бұл арқылы People қолданбасының есептік жазбамен сихрондалғаны анықталуы мүмкін."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"синх қосу және өшіру арасында ауысу"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"Кескін аяқталды"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Кескін арқылы ашу аймағы."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Бос"</string> diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml index 96c22fb0c79d..b74484ee903a 100644 --- a/core/res/res/values-km-rKH/strings.xml +++ b/core/res/res/values-km-rKH/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"រូបតំណាងស្នាមម្រាមដៃ"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"អានការកំណត់ធ្វើសមកាលកម្ម"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ឲ្យកម្មវិធីអានការកំណត់ធ្វើសមកាលកម្មសម្រាប់គណនី។ ឧទាហរណ៍ វាអាចកំណត់ថាតើកម្មវិធីត្រូវបានបើកជាមួយគណនីដែរឬទេ។"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"បិទ/បើកការធ្វើសមកាលកម្ម"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"បានបញ្ចប់លំនាំ"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ផ្ទៃលំនាំ។"</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ទទេ"</string> diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml index e22532408075..e4807606cffe 100644 --- a/core/res/res/values-kn-rIN/strings.xml +++ b/core/res/res/values-kn-rIN/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಐಕಾನ್"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ಸಿಂಕ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ರೀಡ್ ಮಾಡು"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ಒಂದು ಖಾತೆಯ ಸಿಂಕ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ಖಾತೆಯೊಂದಿಗೆ ಜನರ ಅಪ್ಲಿಕೇಶನ್ ಸಿಂಕ್ ಮಾಡಲಾಗಿದೆಯೇ ಎಂಬುದನ್ನು ಇದು ನಿರ್ಧರಿಸಬಹುದು."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ಸಿಂಕ್ ಆನ್ ಮತ್ತು ಸಿಂಕ್ ಆಫ್ ಟಾಗಲ್ ಮಾಡಿ"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"ಪ್ಯಾಟರ್ನ್ ಪೂರ್ಣಗೊಂಡಿದೆ"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ಪ್ಯಾಟರ್ನ್ ಪ್ರದೇಶ."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s.%3$d ರಲ್ಲಿ %2$d ವಿಜೆಟ್."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ವಿಜೆಟ್ ಸೇರಿಸು."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ಖಾಲಿ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index bc0dd4781ca8..360d7231cb9b 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>번째 손가락"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"지문 아이콘"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"동기화 설정 읽기"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"앱이 계정의 동기화 설정을 읽을 수 있도록 허용합니다. 예를 들어, 계정에서 주소록 앱을 동기화할지 여부를 확인할 수 있습니다."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"동기화 사용 및 사용 중지 전환"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"패턴 완료"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"패턴을 그리는 부분입니다."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d의 위젯 %2$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"위젯 추가"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"비어 있음"</string> diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml index 05c401ccd640..91de30a75c6e 100644 --- a/core/res/res/values-ky-rKG/strings.xml +++ b/core/res/res/values-ky-rKG/strings.xml @@ -562,6 +562,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> манжасы"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Манжа изинин сөлөкөтү"</string> <!-- no translation found for permlab_readSyncSettings (6201810008230503052) --> <skip /> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Колдонмого эсеп менен синхрондошуу тууралоолорун окуганга уруксат берет. Мисалы, Кишилер колдонмосу эсеп менен синхрондошкондугун аныктай алат."</string> @@ -936,6 +937,7 @@ <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_detected" msgid="4988730895554057058">"Үлгү аягына чыкты"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Үлгү аймагы."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d ичинен %2$d виджет."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Виджет кошуу."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Бош"</string> diff --git a/core/res/res/values-land/dimens_material.xml b/core/res/res/values-land/dimens_material.xml index 202f4a4b73b6..660210af5367 100644 --- a/core/res/res/values-land/dimens_material.xml +++ b/core/res/res/values-land/dimens_material.xml @@ -17,8 +17,6 @@ <!-- Default height of an action bar. --> <dimen name="action_bar_default_height_material">48dp</dimen> - <!-- Default padding of an action bar. --> - <dimen name="action_bar_default_padding_material">0dp</dimen> <!-- Default text size for action bar title.--> <dimen name="text_size_title_material_toolbar">14dp</dimen> <!-- Default text size for action bar subtitle.--> diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml index 6bfcafff1414..dada9ce75c6e 100644 --- a/core/res/res/values-lo-rLA/strings.xml +++ b/core/res/res/values-lo-rLA/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"ນີ້ວມື <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ໄອຄອນລາຍນິ້ວມື"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ອ່ານການຕັ້ງຄ່າຊິ້ງຂໍ້ມູນ"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ອະນຸຍາດໃຫ້ແອັບຯ ອ່ານການຕັ້ງຄ່າການຊິ້ງຂໍ້ມູນຂອງບັນຊີໄດ້. ຕົວຢ່າງເຊັ່ນ: ມັນຈະສາມາດກວດສອບໄດ້ແອັບຯ People ຖືກຊິ້ງຂໍ້ມູນກັບບັນຊີໃດນຶ່ງແລ້ວຫຼືຍັງ."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ສະລັບການເປີດ ແລະປິດການຊິ້ງຂໍ້ມູນ"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"ຮູບແບບສຳເລັດແລ້ວ"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ພື້ນທີ່ຮູບແບບ."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ຫວ່າງເປົ່າ"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 4b7309fcd5a3..bdf0f3fa784e 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -436,6 +436,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Kontrolinio kodo piktograma"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"skaityti sinchronizavimo nustatymus"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Leidžiama programai skaityti ir sinchronizuoti paskyros nustatymus. Pvz., taip gali būti nustatoma, ar su paskyra sinchronizuota Žmonių programa."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"įjungti arba išjungti sinchronizavimą"</string> @@ -714,6 +715,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Pridėtas langelis"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Pridėtas <xliff:g id="CELL_INDEX">%1$s</xliff:g> taškas"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Šablonas užbaigtas"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Atrakinimo pagal piešinį sritis."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d valdiklis iš %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pridėti valdiklį."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tuščia"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index c017f31323e8..4939eb31593b 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -435,6 +435,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Pirksta nospieduma ikona"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lasīt sinhronizācijas iestatījumus"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Ļauj lietotnei lasīt konta sinhronizācijas iestatījumus. Piemēram, šādi var noteikt, vai lietotne Personas ir sinhronizēta ar kontu."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ieslēgt un izslēgt sinhronizāciju"</string> @@ -713,6 +714,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Šūna pievienota"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Pievienota <xliff:g id="CELL_INDEX">%1$s</xliff:g>. šūna"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Kombinācija pabeigta"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Kombinācijas ievades apgabals."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %2$d. logrīks no %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pievienot logrīku."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tukšs"</string> diff --git a/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml new file mode 100644 index 000000000000..bad49c3771f2 --- /dev/null +++ b/core/res/res/values-mcc310-mnc260-pt-rBR/strings.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* +** Copyright 2015, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You my obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<!-- These resources are around just to allow their values to be customized + for different hardware and product builds. --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string-array name="wfcOperatorErrorAlertMessages"> + <item msgid="7239039348648848288">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item> + </string-array> + <string-array name="wfcOperatorErrorNotificationMessages"> + <item msgid="483847327467331298">"Faça registro na sua operadora"</item> + </string-array> + <string name="wfcSpnFormat" msgid="4982938551498609442">"%s chamada Wi-Fi"</string> +</resources> diff --git a/core/res/res/values-mcc425/config.xml b/core/res/res/values-mcc425/config.xml new file mode 100644 index 000000000000..95d30a487576 --- /dev/null +++ b/core/res/res/values-mcc425/config.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> +<resources> + <bool name="config_use_sim_language_file">false</bool> +</resources> diff --git a/core/res/res/values-mcc432/config.xml b/core/res/res/values-mcc432/config.xml new file mode 100644 index 000000000000..95d30a487576 --- /dev/null +++ b/core/res/res/values-mcc432/config.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> +<resources> + <bool name="config_use_sim_language_file">false</bool> +</resources> diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml index 447831001591..19d03a8df2f3 100644 --- a/core/res/res/values-mk-rMK/strings.xml +++ b/core/res/res/values-mk-rMK/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Икона за отпечатоци"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"прочитај синхронизирани подесувања"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Овозможува апликацијата да ги чита подесувањата за синхронизирање на сметка. На пример, така може да се утврди дали апликацијата „Луѓе“ е синхронизирана со сметка."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"вклучи и исклучи синхронизација"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"Шемата е целосна"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Област за шема."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Празно"</string> diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml index 8ccf2fb4046d..edb470bc26d9 100644 --- a/core/res/res/values-ml-rIN/strings.xml +++ b/core/res/res/values-ml-rIN/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"കൈവിരൽ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"വിരലടയാള ഐക്കൺ"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"സമന്വയ ക്രമീകരണങ്ങൾ റീഡുചെയ്യുക"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ഒരു അക്കൗണ്ടിനായി സമന്വയ ക്രമീകരണങ്ങൾ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഉദാഹരണത്തിന്, ആളുകൾ അപ്ലിക്കേഷൻ ഒരു അക്കൗണ്ടിൽ സമന്വയിപ്പിച്ചിട്ടുണ്ടോയെന്നത് നിർണ്ണയിക്കാൻ ഇതിനാകും."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"സമന്വയം ഓണാക്കുക, ഓഫാക്കുക ടോഗിൾചെയ്യുക"</string> @@ -569,7 +570,7 @@ <item msgid="1648797903785279353">"Jabber"</item> </string-array> <string name="phoneTypeCustom" msgid="1644738059053355820">"ഇഷ്ടാനുസൃതം"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"വീട്ടുനമ്പർ"</string> + <string name="phoneTypeHome" msgid="2570923463033985887">"വീട്"</string> <string name="phoneTypeMobile" msgid="6501463557754751037">"മൊബൈൽ"</string> <string name="phoneTypeWork" msgid="8863939667059911633">"ഔദ്യോഗിക നമ്പർ"</string> <string name="phoneTypeFaxWork" msgid="3517792160008890912">"ഔദ്യോഗിക ഫാക്സ്"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"പാറ്റേൺ പൂർത്തിയാക്കി"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"പാറ്റേൺ ഏരിയ."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ശൂന്യം"</string> @@ -999,7 +1001,7 @@ <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"റദ്ദാക്കുക"</string> <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"എന്റെ ഇഷ്ടം ഓർമ്മിച്ചുവയ്ക്കുക"</string> <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"നിങ്ങൾക്ക് ഇത് പിന്നീട് ക്രമീകരണങ്ങൾ > അപ്ലിക്കേഷനുകൾ എന്നതിൽ മാറ്റാനാകും"</string> - <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"എല്ലായ്പ്പോഴും അനുവദിക്കുക"</string> + <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"എപ്പോഴും അനുവദിക്കൂ"</string> <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"ഒരിക്കലുമനുവദിക്കരുത്"</string> <string name="sim_removed_title" msgid="6227712319223226185">"സിം കാർഡ് നീക്കംചെയ്തു"</string> <string name="sim_removed_message" msgid="5450336489923274918">"സാധുതയുള്ള ഒരു സിം കാർഡ് ചേർത്ത് പുനരാരംഭിക്കുന്നതുവരെ സെല്ലുലാർ നെറ്റ്വർക്ക് ലഭ്യമാകില്ല."</string> diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml index be72354994e1..ff4cfb2fa176 100644 --- a/core/res/res/values-mn-rMN/strings.xml +++ b/core/res/res/values-mn-rMN/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Хурууны хээний дүрс"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"синк тохиргоог унших"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Апп нь акаунтын синк тохиргоог унших боломжтой. Жишээ нь энэ нь Хүмүүс апп акаунттай синк хийгдсэн эсэхийг тодорхойлох боломжтой."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"синкийг унтрааж асаах тохиргоо"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"Хээ дуусав"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Хээний хэсэг."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d. -н %2$d виджет"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Виджет нэмэх."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Хоосон"</string> @@ -1042,7 +1044,7 @@ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB төхөөрөмжид холбогдов"</string> <string name="usb_notification_message" msgid="7347368030849048437">"Нэмэлт сонголтыг харахын тулд дарна."</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-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml index 484de1d10af5..99262b0083fe 100644 --- a/core/res/res/values-mr-rIN/strings.xml +++ b/core/res/res/values-mr-rIN/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"फिंगरप्रिंट चिन्ह"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"संकालन सेटिंग्ज वाचा"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"खात्याच्या संकालन सेटिंग्ज वाचण्यासाठी अॅप ला अनुमती देते. उदाहरणार्थ, हे खात्यासह लोकांचा अॅप संकालित केला आहे किंवा नाही हे निर्धारित करू शकते."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"संकालन चालू आणि बंद करा टॉगल करा"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"नमुना पूर्ण केला"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"नमुना क्षेत्र."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d पैकी %2$d विजेट."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट जोडा."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"रिक्त"</string> diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml index 1ac30363ebc5..01f5c468dbc7 100644 --- a/core/res/res/values-ms-rMY/strings.xml +++ b/core/res/res/values-ms-rMY/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon cap jari"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"membaca tetapan penyegerakan"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Membenarkan apl membaca tetapan segerak untuk akaun. Sebagai contoh, ini boleh menentukan sama ada apl Orang disegerakkan dengan akaun."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"togol segerak hidup dan mati"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Sel ditambahkan"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Sel <xliff:g id="CELL_INDEX">%1$s</xliff:g> ditambahkan"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Corak siap"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Kawasan corak."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Tambah widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Kosong"</string> diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml index b304def34224..690a0ef59b05 100644 --- a/core/res/res/values-my-rMM/strings.xml +++ b/core/res/res/values-my-rMM/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"လက်ဗွေ အိုင်ကွန်"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ထပ်တူပြုအဆင်အပြင်အားဖတ်ခြင်း"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"အပလီကေးရှင်းအား အကောင့်တစ်ခုအတွက် ထပ်တူညီအောင် လုပ်ဆောင်မှု ဆက်တင်အား ကြည့်ခွင့် ပြုပါ။ ဥပမာ People app က အကောင့်တစ်ခုနဲ့ ထပ်တူညီအောင် လုပ်ရန် ဆက်သွယ်ထားမှု ရှိမရှိ သိရှိနိုင်ခြင်း"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ထပ်တူညီအောင် လုပ်ခြင်းအား ပြုနိုင်၊ မပြုနိုင် အပြောင်းအလဲလုပ်ခြင်း"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"ပုံစံပြီးဆုံးခြင်း"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ပုံစံနေရာ"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$d ရဲ့ဝဒ်ဂျက် %2$d"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ဝဒ်ဂျက်ထည့်ရန်"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"အလွတ်"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 649e68084768..5df9a82bbea0 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon for fingeravtrykk"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lese synkroniseringsinnstillinger"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Lar appen lese synkroniseringsinnstillingene for en konto. For eksempel kan den finne ut om Personer-appen er synkronisert med en konto."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"slå synkronisering av og på"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celle er lagt til"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Celle <xliff:g id="CELL_INDEX">%1$s</xliff:g> er lagt til"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Mønsteret er fullført"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Mønsterområde."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Modul %2$d av %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Legg til modul."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string> @@ -746,7 +748,7 @@ <string name="factorytest_not_system" msgid="4435201656767276723">"The FACTORY_TEST action is only supported for packages installed in /system/app."</string> <string name="factorytest_no_action" msgid="872991874799998561">"No package was found that provides the FACTORY_TEST action."</string> <string name="factorytest_reboot" msgid="6320168203050791643">"Omstart"</string> - <string name="js_dialog_title" msgid="1987483977834603872">"Siden på «<xliff:g id="TITLE">%s</xliff:g>» sier:"</string> + <string name="js_dialog_title" msgid="1987483977834603872">"Varsel fra «<xliff:g id="TITLE">%s</xliff:g>»:"</string> <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Bekreft navigasjon"</string> <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Forlat denne siden"</string> @@ -950,7 +952,7 @@ <string name="ringtone_default" msgid="3789758980357696936">"Standard ringetone"</string> <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standard ringetone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> <string name="ringtone_silent" msgid="7937634392408977062">"Ingen"</string> - <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringetoner"</string> + <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringelyder"</string> <string name="ringtone_unknown" msgid="5477919988701784788">"Ukjent ringetone"</string> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi-nettverk er tilgjengelig</item> diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml index 19b9ec601af7..3e8e5b66d151 100644 --- a/core/res/res/values-ne-rNP/strings.xml +++ b/core/res/res/values-ne-rNP/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"फिंगरप्रिन्ट आइकन"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"समीकरण सेटिङहरू पढ्नुहोस्"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"अनुप्रयोगलाई खाताको लागि सिङ्क सेटिङहरू पढ्न अनुमति दिन्छ। उदाहरणको लागि यसले व्यक्तिहरको अनुप्रयोग खातासँग सिङ्क भएको नभएको निर्धारण गर्न सक्दछ।"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"टगल सिङ्क खुला र बन्द"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"ढाँचा पुरा भयो"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ढाँचा क्षेत्र।"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. विजेट %2$d of %3$d।"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"विजेट थप गर्नुहोस्।"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"खाली"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 485c1391ebdc..27dd5dd7ef7c 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Vingerafdruk-pictogram"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"synchronisatie-instellingen lezen"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Hiermee kan de app de synchronisatie-instellingen voor een account lezen. Dit kan bijvoorbeeld bepalen of de app Personen wordt gesynchroniseerd met een account."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"synchronisatie in- en uitschakelen"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Cel toegevoegd"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cel <xliff:g id="CELL_INDEX">%1$s</xliff:g> toegevoegd"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Patroon voltooid"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Tekengebied voor patroon."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d van %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget toevoegen."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Leeg"</string> diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml index 59dece740286..5a9d2c1db727 100644 --- a/core/res/res/values-pa-rIN/strings.xml +++ b/core/res/res/values-pa-rIN/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਆਈਕਨ"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ਸਿੰਕ ਸੈਟਿੰਗਾਂ ਪੜ੍ਹੋ"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ਐਪ ਨੂੰ ਇੱਕ ਖਾਤੇ ਲਈ ਸਿੰਕ ਸੈਟਿੰਗਾਂ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਉਦਾਹਰਨ ਲਈ, ਇਹ ਨਿਰਧਾਰਿਤ ਕਰ ਸਕਦਾ ਹੈ ਕਿ People ਐਪ ਨੂੰ ਇੱਕ ਖਾਤੇ ਨਾਲ ਸਿੰਕ ਕੀਤਾ ਗਿਆ ਹੈ ਜਾਂ ਨਹੀਂ।"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ਸਿੰਕ ਟੌਗਲ ਚਾਲੂ ਅਤੇ ਬੰਦ"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"ਪੈਟਰਨ ਪੂਰਾ ਕੀਤਾ"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"ਪੈਟਰਨ ਖੇਤਰ।"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s। %3$d ਦਾ ਵਿਜੇਟ %2$d।"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"ਵਿਜੇਟ ਜੋੜੋ।"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ਖਾਲੀ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 466e69d18fa2..488ee3072d4a 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -436,6 +436,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Palec <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona odcisku palca"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"czytanie ustawień synchronizacji"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Zezwala aplikacji na odczyt ustawień synchronizacji konta. Pozwala to na przykład określić, czy aplikacja Ludzie jest zsynchronizowana z kontem."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"włączanie i wyłączanie synchronizacji"</string> @@ -714,6 +715,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Dodano komórkę."</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Dodano komórkę <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Wzór ukończony"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Obszar wzoru."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widżet %2$d z %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodaj widżet."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Puste"</string> diff --git a/core/res/res/values-pt-rBR-watch/strings.xml b/core/res/res/values-pt-rBR-watch/strings.xml new file mode 100644 index 000000000000..120e4a56044c --- /dev/null +++ b/core/res/res/values-pt-rBR-watch/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* //device/apps/common/assets/res/any/strings.xml +** +** Copyright 2015, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="android_upgrading_apk" msgid="1090732262010398759">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string> +</resources> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000000..4972ce97e8f8 --- /dev/null +++ b/core/res/res/values-pt-rBR/strings.xml @@ -0,0 +1,1519 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/* //device/apps/common/assets/res/any/strings.xml +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="byteShort" msgid="8340973892742019101">"B"</string> + <string name="kilobyteShort" msgid="5973789783504771878">"Kb"</string> + <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> + <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> + <string name="terabyteShort" msgid="231613018159186962">"TB"</string> + <string name="petabyteShort" msgid="5637816680144990219">"PB"</string> + <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string> + <string name="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> + <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> h"</string> + <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string> + <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> h <xliff:g id="MINUTES">%2$d</xliff:g> min"</string> + <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string> + <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> m"</string> + <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string> + <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> s"</string> + <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string> + <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> s"</string> + <string name="untitled" msgid="4638956954852782576">"<Sem título>"</string> + <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nenhum número de telefone)"</string> + <string name="unknownName" msgid="6867811765370350269">"Desconhecido"</string> + <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Correio de voz"</string> + <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string> + <string name="mmiError" msgid="5154499457739052907">"Problema de conexão ou código MMI inválido."</string> + <string name="mmiFdnError" msgid="5224398216385316471">"A operação é limitada somente a números de chamadas fixas."</string> + <string name="serviceEnabled" msgid="8147278346414714315">"O serviço foi ativado."</string> + <string name="serviceEnabledFor" msgid="6856228140453471041">"O serviço foi ativado para:"</string> + <string name="serviceDisabled" msgid="1937553226592516411">"O serviço foi desativado."</string> + <string name="serviceRegistered" msgid="6275019082598102493">"Registro bem-sucedido."</string> + <string name="serviceErased" msgid="1288584695297200972">"Exclusão bem-sucedida."</string> + <string name="passwordIncorrect" msgid="7612208839450128715">"Senha incorreta."</string> + <string name="mmiComplete" msgid="8232527495411698359">"MMI concluído."</string> + <string name="badPin" msgid="9015277645546710014">"O PIN antigo digitado está incorreto."</string> + <string name="badPuk" msgid="5487257647081132201">"O PUK digitado está incorreto."</string> + <string name="mismatchPin" msgid="609379054496863419">"Os PINs digitados não correspondem."</string> + <string name="invalidPin" msgid="3850018445187475377">"Digite um PIN com 4 a 8 números."</string> + <string name="invalidPuk" msgid="8761456210898036513">"Digite um PUK com oito números ou mais."</string> + <string name="needPuk" msgid="919668385956251611">"O seu cartão SIM está bloqueado por um PUK. Digite o código PUK para desbloqueá-lo."</string> + <string name="needPuk2" msgid="4526033371987193070">"Digite o PUK2 para desbloquear o cartão SIM."</string> + <string name="enablePin" msgid="209412020907207950">"Falha. Ative o bloqueio do SIM/R-UIM."</string> + <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582"> + <item quantity="one">Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o SIM será bloqueado.</item> + <item quantity="other">Tentativas restantes: <xliff:g id="NUMBER_1">%d</xliff:g>. Caso o código correto não seja digitado, o SIM será bloqueado.</item> + </plurals> + <string name="imei" msgid="2625429890869005782">"IMEI"</string> + <string name="meid" msgid="4841221237681254195">"MEID"</string> + <string name="ClipMmi" msgid="6952821216480289285">"ID do chamador de entrada"</string> + <string name="ClirMmi" msgid="7784673673446833091">"ID do chamador de saída"</string> + <string name="ColpMmi" msgid="3065121483740183974">"ID de linha conectada"</string> + <string name="ColrMmi" msgid="4996540314421889589">"Restrição de ID de linha conectada"</string> + <string name="CfMmi" msgid="5123218989141573515">"Encaminhamento de chamada"</string> + <string name="CwMmi" msgid="9129678056795016867">"Chamada em espera"</string> + <string name="BaMmi" msgid="455193067926770581">"Bloqueio de chamadas"</string> + <string name="PwdMmi" msgid="7043715687905254199">"Alteração da senha"</string> + <string name="PinMmi" msgid="3113117780361190304">"Alteração do PIN"</string> + <string name="CnipMmi" msgid="3110534680557857162">"Chamando número atual"</string> + <string name="CnirMmi" msgid="3062102121430548731">"Chamando número restrito"</string> + <string name="ThreeWCMmi" msgid="9051047170321190368">"Chamada com três participantes"</string> + <string name="RuacMmi" msgid="7827887459138308886">"Rejeição das chamadas indesejadas"</string> + <string name="CndMmi" msgid="3116446237081575808">"Chamando número de entrega"</string> + <string name="DndMmi" msgid="1265478932418334331">"Não perturbe"</string> + <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"O ID do chamador assume o padrão de restrito. Próxima chamada: Restrita"</string> + <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"O ID do chamador assume o padrão de restrito. Próxima chamada: Não restrita"</string> + <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"O ID do chamador assume o padrão de não restrito. Próxima chamada: Restrita"</string> + <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"O ID do chamador assume o padrão de não restrito. Próxima chamada: Não restrita"</string> + <string name="serviceNotProvisioned" msgid="8614830180508686666">"O serviço não foi habilitado."</string> + <string name="CLIRPermanent" msgid="3377371145926835671">"Não é possível alterar a configuração de identificação de chamadas."</string> + <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Acesso restrito alterado"</string> + <string name="RestrictedOnData" msgid="8653794784690065540">"O serviço de dados está bloqueado."</string> + <string name="RestrictedOnEmergency" msgid="6581163779072833665">"O serviço de emergência está bloqueado."</string> + <string name="RestrictedOnNormal" msgid="4953867011389750673">"O serviço de voz está bloqueado."</string> + <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Todos os serviços de voz estão bloqueados."</string> + <string name="RestrictedOnSms" msgid="8314352327461638897">"O serviço de SMS está bloqueado."</string> + <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Os serviços de voz/dados estão bloqueados."</string> + <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Os serviços de voz/SMS estão bloqueados."</string> + <string name="RestrictedOnAll" msgid="5643028264466092821">"Todos os serviços de voz/dados/SMS estão bloqueados."</string> + <string name="peerTtyModeFull" msgid="6165351790010341421">"TTD modo COMPLETO solicitado"</string> + <string name="peerTtyModeHco" msgid="5728602160669216784">"TTD modo HCO solicitado"</string> + <string name="peerTtyModeVco" msgid="1742404978686538049">"TTD modo VCO solicitado"</string> + <string name="peerTtyModeOff" msgid="3280819717850602205">"TTD modo DESLIGADO solicitado"</string> + <string name="serviceClassVoice" msgid="1258393812335258019">"Voz"</string> + <string name="serviceClassData" msgid="872456782077937893">"Dados"</string> + <string name="serviceClassFAX" msgid="5566624998840486475">"FAX"</string> + <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string> + <string name="serviceClassDataAsync" msgid="4523454783498551468">"Assíncrono"</string> + <string name="serviceClassDataSync" msgid="7530000519646054776">"Sincronizar"</string> + <string name="serviceClassPacket" msgid="6991006557993423453">"Pacote"</string> + <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string> + <string name="roamingText0" msgid="7170335472198694945">"Indicador de roaming ativado"</string> + <string name="roamingText1" msgid="5314861519752538922">"Indicador de roaming desativado"</string> + <string name="roamingText2" msgid="8969929049081268115">"Indicador de roaming piscando"</string> + <string name="roamingText3" msgid="5148255027043943317">"Fora da vizinhança"</string> + <string name="roamingText4" msgid="8808456682550796530">"Ao ar livre"</string> + <string name="roamingText5" msgid="7604063252850354350">"Roaming - Sistema recomendado"</string> + <string name="roamingText6" msgid="2059440825782871513">"Roaming - Sistema disponível"</string> + <string name="roamingText7" msgid="7112078724097233605">"Roaming - Parceiro do Alliance"</string> + <string name="roamingText8" msgid="5989569778604089291">"Roaming - Parceiro do Google Premium"</string> + <string name="roamingText9" msgid="7969296811355152491">"Roaming - Funcionalidade de serviço completo"</string> + <string name="roamingText10" msgid="3992906999815316417">"Roaming - Funcionalidade de serviço parcial"</string> + <string name="roamingText11" msgid="4154476854426920970">"Banner de roaming ativado"</string> + <string name="roamingText12" msgid="1189071119992726320">"Banner de roaming desativado"</string> + <string name="roamingTextSearching" msgid="8360141885972279963">"Pesquisando serviço"</string> + <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Chamadas por Wi-Fi"</string> + <string-array name="wfcOperatorErrorAlertMessages"> + </string-array> + <string-array name="wfcOperatorErrorNotificationMessages"> + </string-array> + <string name="wfcSpnFormat" msgid="8211621332478306568">"%s"</string> + <string name="wfcDataSpnFormat" msgid="1118052028767666883">"%s"</string> + <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desativado"</string> + <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferido"</string> + <string name="wfc_mode_cellular_preferred_summary" msgid="5920549484600758786">"Celular preferido"</string> + <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Somente Wi-Fi"</string> + <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não encaminhado"</string> + <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string> + <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> após <xliff:g id="TIME_DELAY">{2}</xliff:g> segundos"</string> + <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não encaminhado"</string> + <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não encaminhado"</string> + <string name="fcComplete" msgid="3118848230966886575">"Código de recurso concluído."</string> + <string name="fcError" msgid="3327560126588500777">"Problema de conexão ou código de recurso inválido."</string> + <string name="httpErrorOk" msgid="1191919378083472204">"OK"</string> + <string name="httpError" msgid="7956392511146698522">"Ocorreu um erro na rede."</string> + <string name="httpErrorLookup" msgid="4711687456111963163">"Não foi possível encontrar o URL."</string> + <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"O esquema de autenticação do site não é suportado."</string> + <string name="httpErrorAuth" msgid="1435065629438044534">"Não foi possível autenticar."</string> + <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Falha na autenticação por meio do servidor proxy."</string> + <string name="httpErrorConnect" msgid="8714273236364640549">"Não foi possível se conectar ao servidor."</string> + <string name="httpErrorIO" msgid="2340558197489302188">"Não foi possível estabelecer comunicação com o servidor. Tente novamente mais tarde."</string> + <string name="httpErrorTimeout" msgid="4743403703762883954">"O tempo limite de conexão com o servidor esgotou."</string> + <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"A página contém muitos redirecionamentos do servidor."</string> + <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"O protocolo não é compatível."</string> + <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Não foi possível estabelecer uma conexão segura."</string> + <string name="httpErrorBadUrl" msgid="3636929722728881972">"Não foi possível abrir a página porque o URL é inválido."</string> + <string name="httpErrorFile" msgid="2170788515052558676">"Não foi possível acessar o arquivo."</string> + <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Não foi possível encontrar o arquivo solicitado."</string> + <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Há muitas solicitações sendo processadas. Tente novamente mais tarde."</string> + <string name="notification_title" msgid="8967710025036163822">"Erro de login para <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string> + <string name="contentServiceSync" msgid="8353523060269335667">"Sincronizar"</string> + <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronizar"</string> + <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Muitas exclusões de <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string> + <string name="low_memory" product="tablet" msgid="6494019234102154896">"O armazenamento do tablet está cheio. Exclua alguns arquivos para liberar espaço."</string> + <string name="low_memory" product="watch" msgid="4415914910770005166">"Armazenamento do relógio cheio. Exclua alguns arquivos para liberar espaço."</string> + <string name="low_memory" product="tv" msgid="516619861191025923">"O armazenamento da TV está cheio. Exclua alguns arquivos para liberar espaço."</string> + <string name="low_memory" product="default" msgid="3475999286680000541">"O armazenamento do telefone está cheio. Exclua alguns arquivos para liberar espaço."</string> + <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"A rede pode ser monitorada"</string> + <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Por terceiros desconhecidos"</string> + <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"Pelo seu perfil profissional de administrador"</string> + <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Por <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string> + <string name="work_profile_deleted" msgid="5005572078641980632">"Perfil de trabalho excluído"</string> + <string name="work_profile_deleted_description" msgid="6305147513054341102">"Perfil de trabalho excluído devido à ausência de um app para administrador."</string> + <string name="work_profile_deleted_details" msgid="226615743462361248">"O app para administrador do perfil de trabalho não foi encontrado ou está corrompido. Consequentemente, seu perfil de trabalho e os dados relacionados foram excluídos. Entre em contato com seu administrador para receber assistência."</string> + <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Seu perfil de trabalho não está mais disponível neste dispositivo."</string> + <string name="factory_reset_warning" msgid="5423253125642394387">"Seu dispositivo será limpo"</string> + <string name="factory_reset_message" msgid="4905025204141900666">"O app para administrador está sem alguns componentes ou foi corrompido e não pode ser usado. Seu dispositivo será limpo agora. Entre em contato com seu administrador para receber assistência."</string> + <string name="me" msgid="6545696007631404292">"Eu"</string> + <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opções do tablet"</string> + <string name="power_dialog" product="tv" msgid="6153888706430556356">"Opções de TV"</string> + <string name="power_dialog" product="default" msgid="1319919075463988638">"Opções do telefone"</string> + <string name="silent_mode" msgid="7167703389802618663">"Modo silencioso"</string> + <string name="turn_on_radio" msgid="3912793092339962371">"Ativar sem fio"</string> + <string name="turn_off_radio" msgid="8198784949987062346">"Desativar a rede sem fio"</string> + <string name="screen_lock" msgid="799094655496098153">"Bloquear tela"</string> + <string name="power_off" msgid="4266614107412865048">"Desligar"</string> + <string name="silent_mode_silent" msgid="319298163018473078">"Campainha desligada"</string> + <string name="silent_mode_vibrate" msgid="7072043388581551395">"Vibração da campainha"</string> + <string name="silent_mode_ring" msgid="8592241816194074353">"Campainha ligada"</string> + <string name="reboot_to_update_title" msgid="6212636802536823850">"Atualização do sistema Android"</string> + <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Preparando para atualizar..."</string> + <string name="reboot_to_update_package" msgid="3871302324500927291">"Processando o pacote de atualização…"</string> + <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Reiniciando..."</string> + <string name="reboot_to_reset_title" msgid="4142355915340627490">"Redefinição para configuração original"</string> + <string name="reboot_to_reset_message" msgid="2432077491101416345">"Reiniciando..."</string> + <string name="shutdown_progress" msgid="2281079257329981203">"Encerrando…"</string> + <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Seu tablet será desligado."</string> + <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Sua TV será desligada."</string> + <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Seu relógio será desligado."</string> + <string name="shutdown_confirm" product="default" msgid="649792175242821353">"O seu telefone será desligado."</string> + <string name="shutdown_confirm_question" msgid="2906544768881136183">"Deseja desligar?"</string> + <string name="reboot_safemode_title" msgid="7054509914500140361">"Reiniciar no modo de segurança"</string> + <string name="reboot_safemode_confirm" msgid="55293944502784668">"Deseja reiniciar no modo de segurança? Isso desativará todos os apps de terceiros instalados. Eles serão restaurados quando você reiniciar novamente."</string> + <string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string> + <string name="no_recent_tasks" msgid="8794906658732193473">"Nenhum app recente"</string> + <string name="global_actions" product="tablet" msgid="408477140088053665">"Opções do tablet"</string> + <string name="global_actions" product="tv" msgid="7240386462508182976">"Opções da TV"</string> + <string name="global_actions" product="default" msgid="2406416831541615258">"Opções do telefone"</string> + <string name="global_action_lock" msgid="2844945191792119712">"Bloquear tela"</string> + <string name="global_action_power_off" msgid="4471879440839879722">"Desligar"</string> + <string name="global_action_bug_report" msgid="7934010578922304799">"Relatório de bugs"</string> + <string name="bugreport_title" msgid="2667494803742548533">"Obter relatório de bugs"</string> + <string name="bugreport_message" msgid="398447048750350456">"Isto coletará informações sobre o estado atual do dispositivo para enviá-las em uma mensagem de e-mail. Após iniciar o relatório de bugs, será necessário aguardar algum tempo até que esteja pronto para ser enviado."</string> + <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string> + <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Som DESATIVADO"</string> + <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"O som está ATIVADO"</string> + <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modo avião"</string> + <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modo avião ATIVADO"</string> + <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modo avião DESATIVADO"</string> + <string name="global_action_settings" msgid="1756531602592545966">"Configurações"</string> + <string name="global_action_assist" msgid="3892832961594295030">"Assistência"</string> + <string name="global_action_voice_assist" msgid="7751191495200504480">"Ajuda de voz"</string> + <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string> + <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string> + <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="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">"acesse o local do dispositivo"</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">"acesse fotos, mídia e arquivos do seu dispositivo"</string> + <string name="permgrouplab_microphone" msgid="171539900250043464">"Microfone"</string> + <string name="permgroupdesc_microphone" msgid="4988812113943554584">"grave áudio"</string> + <string name="permgrouplab_camera" msgid="4820372495894586615">"Câmera"</string> + <string name="permgroupdesc_camera" msgid="3250611594678347720">"tire fotos e grave 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="416037179223226722">"Sensores corporais"</string> + <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> + <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Itens tocados serão falados em voz alta e a tela poderá ser explorada por meio de gestos."</string> + <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Ativar acessibilidade na Web aprimorada"</string> + <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Scripts podem ser instalados para tornar o conteúdo do app mais acessível."</string> + <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Observar o texto digitado"</string> + <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Inclui dados pessoais, como números de cartão de crédito e senhas."</string> + <string name="permlab_statusBar" msgid="7417192629601890791">"desativar ou modificar a barra de status"</string> + <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que o app desative a barra de status ou adicione e remova ícones do sistema."</string> + <string name="permlab_statusBarService" msgid="7247281911387931485">"barra de status"</string> + <string name="permdesc_statusBarService" msgid="716113660795976060">"Permite que o app seja a barra de status."</string> + <string name="permlab_expandStatusBar" msgid="1148198785937489264">"expandir/recolher barra de status"</string> + <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Permite que o app expanda ou recolha a barra de status."</string> + <string name="permlab_install_shortcut" msgid="4279070216371564234">"instalar atalhos"</string> + <string name="permdesc_install_shortcut" msgid="8341295916286736996">"Permite que um app adicione atalhos da tela inicial sem a intervenção do usuário."</string> + <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"desinstalar atalhos"</string> + <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permite que o app remova atalhos da tela inicial sem a intervenção do usuário."</string> + <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redirecionar as chamadas efetuadas"</string> + <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permite que o app veja o número discado ao realizar uma chamada, com a opção de redirecionar a chamada para outro número ou abortá-la."</string> + <string name="permlab_receiveSms" msgid="8673471768947895082">"receber mensagens de texto (SMS)"</string> + <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que o app receba e processe mensagens SMS. Isso significa que o app pode monitorar ou excluir mensagens enviadas para o dispositivo sem mostrá-las para você."</string> + <string name="permlab_receiveMms" msgid="1821317344668257098">"receber mensagens de texto (MMS)"</string> + <string name="permdesc_receiveMms" msgid="533019437263212260">"Permite que o app receba e processe mensagens MMS. Isso significa que o app pode monitorar ou excluir as mensagens enviadas para o dispositivo sem mostrá-las para você."</string> + <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"ler mensagens de difusão celular"</string> + <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite que o app leia mensagens de difusão celular recebidas por seu dispositivo. Alertas de difusão celular são recebidos em alguns locais para avisar você de situações de emergência. Apps maliciosos podem interferir no desempenho ou funcionamento de seu dispositivo quando uma difusão celular de emergência é recebida."</string> + <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ler feeds inscritos"</string> + <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite que o app obtenha detalhes sobre os feeds sincronizados no momento."</string> + <string name="permlab_sendSms" msgid="7544599214260982981">"enviar e ver mensagens SMS"</string> + <string name="permdesc_sendSms" msgid="7094729298204937667">"Permite que o app envie mensagens SMS. Isso pode resultar em cobranças inesperadas. Apps maliciosos podem gerar custos através do envio de mensagens sem sua confirmação."</string> + <string name="permlab_readSms" msgid="8745086572213270480">"ler suas mensagens de texto (SMS ou MMS)"</string> + <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Permite que o app leia mensagens SMS armazenadas no tablet ou cartão SIM. Isso permite que o app leia todas as mensagens SMS, independentemente de seu conteúdo ou confidencialidade."</string> + <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Permite que o app leia as mensagens SMS armazenadas na sua TV ou no cartão SIM. Isso permite que o app leia todas as mensagens SMS, independentemente do seu conteúdo ou confidencialidade."</string> + <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Permite que o app leia mensagens SMS armazenadas no telefone ou cartão SIM. Isso permite que o app leia todas as mensagens SMS, independentemente de seu conteúdo ou confidencialidade."</string> + <string name="permlab_receiveWapPush" msgid="5991398711936590410">"receber mensagens de texto (WAP)"</string> + <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite que o app receba e processe mensagens WAP. Esta permissão inclui a capacidade de monitorar ou excluir mensagens enviadas para você sem mostrá-las para você."</string> + <string name="permlab_getTasks" msgid="6466095396623933906">"recuperar apps em execução"</string> + <string name="permdesc_getTasks" msgid="7454215995847658102">"Permite que o app obtenha informações sobre tarefas em execução atuais e recentes. Pode permitir que o app descubra informações sobre os apps usados no dispositivo."</string> + <string name="permlab_manageProfileAndDeviceOwners" msgid="5979288447973722097">"Gerenciar proprietários de perfis e de dispositivos"</string> + <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permitir que os apps definam os proprietários de perfis e de dispositivos."</string> + <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordenar os apps em execução"</string> + <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite que o app mova tarefas para o primeiro plano e o plano de fundo, sem sua intervenção."</string> + <string name="permlab_enableCarMode" msgid="5684504058192921098">"ativar o modo carro"</string> + <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Permite que o app ative o modo Carro."</string> + <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"fechar outros apps"</string> + <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Permite que o app encerre processos em segundo plano de outros apps. Pode ser que outros apps parem de funcionar."</string> + <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"sobrepor outros apps"</string> + <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Permite que o app se sobreponha visualmente a outros apps ou a partes da interface do usuário. Podem interferir com o uso da interface de qualquer app ou alterar o que você acha que está vendo em outros apps."</string> + <string name="permlab_persistentActivity" msgid="8841113627955563938">"sempre executar o app"</string> + <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Permite que o app torne partes de si mesmo persistentes na memória. Pode limitar a memória disponível para outros apps, deixando o tablet mais lento."</string> + <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Permite que o app torne partes de si mesmo persistentes na memória. Isso pode limitar a memória disponível para outros apps, deixando a TV mais lenta."</string> + <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Permite que o app torne partes de si mesmo persistentes na memória. Pode limitar a memória disponível para outros apps, deixando o telefone mais lento."</string> + <string name="permlab_getPackageSize" msgid="7472921768357981986">"medir o espaço de armazenamento do app"</string> + <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Permite que o app recupere o código, os dados e os tamanhos de cache"</string> + <string name="permlab_writeSettings" msgid="2226195290955224730">"modificar configurações do sistema"</string> + <string name="permdesc_writeSettings" msgid="7775723441558907181">"Permite que o app modifique os dados das configurações do sistema. Apps maliciosos podem corromper a configuração de seu sistema."</string> + <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"executar na inicialização"</string> + <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Permite que o app inicie-se logo que o sistema concluir a inicialização. Isso pode tornar a inicialização do tablet mais lenta e permitir que o app deixe o telefone mais lento por estar sempre em execução."</string> + <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"Permite que o app seja iniciado assim que o sistema terminar de ser iniciado. Isso pode fazer com que demore mais tempo para a TV ser iniciada, além de permitir que o app deixe o tablet em geral mais lento por estar sempre em execução."</string> + <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Permite que o app inicie-se logo que o sistema concluir a inicialização. Isso pode tornar a inicialização do telefone mais lenta e permitir que o app deixe o telefone mais lento por estar sempre em execução."</string> + <string name="permlab_broadcastSticky" msgid="7919126372606881614">"enviar transmissão persistente"</string> + <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Permite que o app envie transmissões fixas, que permaneçam depois que a transmissão terminar. O uso excessivo pode desacelerar ou desestabilizar o tablet, fazendo com que ele utilize muita memória."</string> + <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Permite que o app envie transmissões aderentes, que permanecem depois que a transmissão termina. O uso excessivo pode fazer com que a TV fique lenta ou instável ao fazer com que ela use muita memória."</string> + <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Permite que o app envie transmissões fixas, que permanecem depois que a transmissão termina. O uso excessivo pode deixar o telefone lento ou instável, fazendo com que ele use muita memória."</string> + <string name="permlab_readContacts" msgid="8348481131899886131">"ler seus contatos"</string> + <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Permite que o app leia dados dos contatos armazenados no tablet, incluindo a frequência com que você chamou, enviou e-mails ou se comunicou de qualquer outra forma com indivíduos específicos. Esta permissão autoriza o app a salvar seus dados de contato, e apps maliciosos podem compartilhar esses dados de contato sem seu conhecimento."</string> + <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Permite que o app leia os dados dos seus contatos armazenados na sua TV, incluindo a frequência com que você ligou, enviou e-mail ou se comunicou de outras formas com pessoas específicas. Essa permissão autoriza apps a salvarem seus dados de contato, e apps maliciosos podem compartilhar os dados de contato sem seu conhecimento."</string> + <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Permite que o app leia dados dos contatos armazenados no telefone, incluindo a frequência com que você chamou, enviou e-mails ou se comunicou de qualquer outra forma com indivíduos específicos. Esta permissão autoriza o app a salvar seus dados de contato, e apps maliciosos podem compartilhar esses dados de contato sem seu conhecimento."</string> + <string name="permlab_writeContacts" msgid="5107492086416793544">"modificar seus contatos"</string> + <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Permite que o app modifique os dados sobre os contatos armazenados no tablet, incluindo a frequência com que você fez chamadas, enviou e-mails ou se comunicou de outras formas com contatos específicos. Esta permissão autoriza o app a excluir dados de contatos."</string> + <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Permite que o app modifique os dados de contatos armazenados na sua TV, incluindo a frequência com que você fez chamadas, enviou e-mails ou se comunicou de outras formas com contatos específicos. Essa permissão autoriza o app a excluir dados de contatos."</string> + <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Permite que o app modifique os dados dos contatos armazenados no telefone, incluindo a frequência com que você fez chamadas, enviou e-mails ou se comunicou de outras formas com contatos específicos. Esta permissão autoriza o app a excluir dados de contatos."</string> + <string name="permlab_readCallLog" msgid="3478133184624102739">"ler registro de chamadas"</string> + <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Permite que o app leia o histórico de chamadas do tablet, incluindo dados de chamadas recebidas e realizadas. Esta permissão autoriza o app a salvar os dados de seu histórico de chamadas, e apps maliciosos podem compartilhar esses dados do histórico de chamadas sem seu conhecimento."</string> + <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Permite que o app leia o registro de chamadas da sua TV, incluindo dados sobre chamadas recebidas e efetuadas. Essa permissão autoriza apps a salvarem os dados do seu registro de chamadas, e apps maliciosos podem compartilhar dados do registro de chamadas sem seu conhecimento."</string> + <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Permite que o app leia o histórico de chamadas do telefone, incluindo dados de chamadas recebidas e realizadas. Esta permissão autoriza o app a salvar os dados de seu histórico de chamadas, e apps maliciosos podem compartilhar os dados de seu histórico de chamadas sem seu conhecimento."</string> + <string name="permlab_writeCallLog" msgid="8552045664743499354">"salvar no registo de chamadas"</string> + <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_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_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> + <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Permite que o app leia todos os eventos do calendário armazenados no telefone, 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="permlab_writeCalendar" msgid="8438874755193825647">"adicionar ou modificar compromissos e enviar e-mail para os convidados sem o conhecimento dos donos"</string> + <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permite que o app adicione, remova e altere eventos que você pode modificar em seu tablet, incluindo os de amigos e colegas de trabalho. Isso pode permitir que o app envie mensagens que parecem ser de autoria do proprietário do calendário, ou modifique eventos sem conhecimento do proprietário."</string> + <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permite que o app adicione, remova ou altere eventos que podem ser modificados na sua TV, incluindo eventos de amigos ou colegas de trabalho. Isso pode permitir que o app envie mensagens que parecem vir dos proprietários de agendas ou modifique eventos sem o conhecimento dos proprietários."</string> + <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permite que o app adicione, remova e altere eventos que você pode modificar em seu telefone, incluindo os de amigos e colegas de trabalho. Isso pode permitir que o app envie mensagens que parecem ser de autoria do proprietário do calendário, ou modifique eventos sem conhecimento do proprietário."</string> + <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"acessar comandos extras do provedor de localização"</string> + <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string> + <string name="permlab_accessFineLocation" msgid="1191898061965273372">"localização precisa (GPS e com base na rede)"</string> + <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Permite que o app acesse sua localização exata por meio do sistema de posicionamento global (GPS) ou de fontes de localização da rede, como torres de celulares e redes Wi-Fi. Esses serviços de localização devem estar ativados e disponíveis para que sejam usados pelo app. O app pode usar esta permissão para determinar onde você está, além de consumir mais bateria."</string> + <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"localização aproximada (com base na rede)"</string> + <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Permite que o app acesse sua localização aproximada por meio do sistema de posicionamento global (GPS) ou de fontes de localização da rede, como torres de celulares e redes Wi-Fi. Esses serviços de localização devem estar ativados e disponíveis para que sejam usados pelo app. O app pode usar esta permissão para determinar aproximadamente onde você está."</string> + <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"alterar as suas configurações de áudio"</string> + <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permite que o app modifique configurações de áudio globais como volume e alto-falantes de saída."</string> + <string name="permlab_recordAudio" msgid="3876049771427466323">"gravar áudio"</string> + <string name="permdesc_recordAudio" msgid="4906839301087980680">"Permite que o app grave áudio com o microfone. Esta permissão autoriza o app a gravar áudio a qualquer momento, sem sua confirmação."</string> + <string name="permlab_sim_communication" msgid="1180265879464893029">"comunicação com sim"</string> + <string name="permdesc_sim_communication" msgid="5725159654279639498">"Permite que o app envie comandos ao SIM. Muito perigoso."</string> + <string name="permlab_camera" msgid="3616391919559751192">"tirar fotos e gravar vídeos"</string> + <string name="permdesc_camera" msgid="8497216524735535009">"Permite que o app tire fotos e filme vídeos com a câmera. Esta permissão autoriza o app a usar a câmera a qualquer momento sem sua confirmação."</string> + <string name="permlab_vibrate" msgid="7696427026057705834">"controlar vibração"</string> + <string name="permdesc_vibrate" msgid="6284989245902300945">"Permite que o app controle a vibração."</string> + <string name="permlab_flashlight" msgid="2155920810121984215">"controlar lanterna"</string> + <string name="permdesc_flashlight" msgid="6522284794568368310">"Permite que o app controle a lanterna."</string> + <string name="permlab_callPhone" msgid="3925836347681847954">"ligar diretamente para números de telefone"</string> + <string name="permdesc_callPhone" msgid="3740797576113760827">"Permite que o app ligue para números de telefone sem sua intervenção. Isso pode resultar em cobranças ou chamadas inesperadas. Esta opção não permite que o app ligue para números de emergência. Apps maliciosos podem gerar custos com chamadas feitas sem sua confirmação."</string> + <string name="permlab_accessImsCallService" msgid="3574943847181793918">"acessar serviço de mensagens instantâneas para chamadas"</string> + <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Permite que o app use o serviço de mensagens instantâneas para fazer chamadas sem sua intervenção."</string> + <string name="permlab_readPhoneState" msgid="9178228524507610486">"ler status e identidade do telefone"</string> + <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que o app acesse os recursos de telefonia do dispositivo. Esta permissão autoriza o app a determinar o número de telefone e IDs de dispositivo, quando uma chamada está ativa, e o número remoto conectado a uma chamada."</string> + <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"impedir modo de inatividade do tablet"</string> + <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"impedir a suspensão da TV"</string> + <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"impedir modo de inatividade do telefone"</string> + <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite que o app impeça o tablet de entrar no modo de inatividade."</string> + <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"Permite que o app impeça a suspensão da TV."</string> + <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permite que o app impeça o telefone de entrar no modo de inatividade."</string> + <string name="permlab_transmitIr" msgid="7545858504238530105">"transmitir infravermelhos"</string> + <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Permite que o app use o transmissor infravermelho do tablet."</string> + <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"Permite que o app use o transmissor de infravermelho da TV."</string> + <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Permite que o app use o transmissor infravermelho do telefone."</string> + <string name="permlab_setWallpaper" msgid="6627192333373465143">"definir plano de fundo"</string> + <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Permite que o app defina o plano de fundo do sistema."</string> + <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"ajustar tamanho do plano de fundo"</string> + <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Permite que o app defina as dicas de tamanho do plano de fundo do sistema."</string> + <string name="permlab_setTimeZone" msgid="2945079801013077340">"definir fuso horário"</string> + <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Permite que o app altere o fuso horário do tablet."</string> + <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Permite que o app altere o fuso horário da TV."</string> + <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Permite que o app altera o fuso horário do telefone."</string> + <string name="permlab_getAccounts" msgid="1086795467760122114">"encontrar contas no dispositivo"</string> + <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Permite que o app obtenha a lista de contas conhecidas pelo tablet. Isso pode incluir todas as contas criadas pelos apps instalados."</string> + <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Permite que o app receba a lista de contas conhecidas pela TV. Isso pode incluir todas as contas criadas pelos apps instalados."</string> + <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Permite que o app obtenha a lista de contas conhecidas pelo telefone. Isso pode incluir todas as contas criadas pelos apps instalados."</string> + <string name="permlab_accessNetworkState" msgid="4951027964348974773">"ver conexões de rede"</string> + <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Permite que o app acesse informações sobre conexões de rede, como as redes existentes e conectadas."</string> + <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"acesso total à rede"</string> + <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Permite que o app crie soquetes de rede e utilize protocolos de rede personalizados. O navegador e outros apps fornecem meios de enviar dados para a Internet, e por isso esta permissão não é necessária para enviar os dados."</string> + <string name="permlab_changeNetworkState" msgid="958884291454327309">"alterar conectividade da rede"</string> + <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Permite que o app altere o estado de conectividade de rede."</string> + <string name="permlab_changeTetherState" msgid="5952584964373017960">"alterar conectividade vinculada"</string> + <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Permite que o app altere o estado de conectividade de rede conectada."</string> + <string name="permlab_accessWifiState" msgid="5202012949247040011">"ver conexões Wi-Fi"</string> + <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Permite que o app acesse informações sobre redes Wi-Fi, como a ativação do Wi-Fi e o nome dos dispositivos Wi-Fi conectados."</string> + <string name="permlab_changeWifiState" msgid="6550641188749128035">"conectar e desconectar do Wi-Fi"</string> + <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Permite que o app conecte e desconecte dos pontos de acesso Wi-Fi e faça alterações nas configurações do dispositivo para redes Wi-Fi."</string> + <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"permitir recebimento de multicast Wi-Fi"</string> + <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Permite que o app receba pacotes enviados para todos os dispositivos em uma rede Wi-Fi usando endereços de difusão seletiva, e não apenas o tablet. Consome mais energia do que o modo não multicast."</string> + <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Permite que o app receba pacotes enviados para todos os dispositivos em uma rede Wi-Fi usando endereços multicast, não apenas sua TV. Usa mais energia do que o modo não multicast."</string> + <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Permite que o app receba pacotes enviados para todos os dispositivos em uma rede Wi-Fi usando endereços de difusão seletiva, e não apenas o telefone. Consome mais energia do que o modo não multicast."</string> + <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"acessar configurações de Bluetooth"</string> + <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite que um app configure o tablet Bluetooth local, descubra dispositivos remotos e emparelhe com eles."</string> + <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Permite que o app configure a TV com Bluetooth local, descubra dispositivos remotos e faça pareamento com eles."</string> + <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite que um app configure o telefone Bluetooth local, descubra e emparelhe com dispositivos remotos."</string> + <string name="permlab_accessWimaxState" msgid="4195907010610205703">"conectar e desconectar do WiMAX"</string> + <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Permite que o app determine se o WiMAX está ativado e acesse informações sobre as redes WiMAX conectadas."</string> + <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Alterar estado do WiMAX"</string> + <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Permite que o app conecte e desconecte o tablet de redes WiMAX."</string> + <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"Permite que o app se conecte à TV e desconecte-a de redes WiMAX."</string> + <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Permite que o app conecte e desconecte o telefone de redes WiMAX."</string> + <string name="permlab_bluetooth" msgid="6127769336339276828">"parear com dispositivos Bluetooth"</string> + <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Permite que o app acesse a configuração do Bluetooth no tablet, além de fazer e aceitar conexões com dispositivos pareados."</string> + <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Permite que o app veja a configuração do Bluetooth na TV, faça e aceite conexões com dispositivos pareados."</string> + <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Permite que o app acesse a configuração do Bluetooth no telefone, além de fazer e aceitar conexões com dispositivos pareados."</string> + <string name="permlab_nfc" msgid="4423351274757876953">"controlar a comunicação a curta distância"</string> + <string name="permdesc_nfc" msgid="7120611819401789907">"Permite que o app se comunique com leitores, cartões e etiqueta NFC (Comunicação a curta distância)."</string> + <string name="permlab_disableKeyguard" msgid="3598496301486439258">"desativar o bloqueio de tela"</string> + <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Permite que o app desative o bloqueio de teclas e qualquer segurança por senha associada. Por exemplo, o telefone desativa o bloqueio de telas ao receber uma chamada e o reativa quando a chamada é finalizada."</string> + <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gerenciar hardware de impressão digital"</string> + <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Permite que o app execute métodos para adicionar e excluir modelos de impressão digital para uso."</string> + <string name="permlab_useFingerprint" msgid="3150478619915124905">"usar hardware de impressão digital"</string> + <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Permite que o app use hardware de impressão digital para autenticação."</string> + <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Impressão digital parcial detectada. Tente novamente."</string> + <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Não foi possível processar a impressão digital. Tente novamente."</string> + <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"O sensor de impressão digital está sujo. Limpe-o e tente novamente."</string> + <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"O dedo foi retirado rápido demais. Tente novamente."</string> + <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"O movimento do dedo está muito lento. Tente novamente."</string> + <string-array name="fingerprint_acquired_vendor"> + </string-array> + <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardware de impressão digital não disponível."</string> + <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Não foi possível armazenar a impressão digital. Remova uma impressão digital já existente."</string> + <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tempo máximo para captura da impressão digital atingido. Tente novamente."</string> + <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operação de impressão digital cancelada."</string> + <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Excesso de tentativas. Tente novamente mais tarde."</string> + <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Tente novamente."</string> + <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string-array name="fingerprint_error_vendor"> + </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ícone de impressão digital"</string> + <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler as configurações de sincronização"</string> + <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite que o app leia as configurações de sincronização de uma conta. Por exemplo, pode determinar se o app People está sincronizado com uma conta."</string> + <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ativar e desativar sincronização"</string> + <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_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> + <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Permite que o app leia o conteúdo do cartão SD."</string> + <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"modificar ou excluir conteúdo do armazenamento USB"</string> + <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"modificar ou excluir o conteúdo do cartão SD"</string> + <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permite gravar no armaz. USB."</string> + <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permite que o app grave em seu cartão SD."</string> + <string name="permlab_use_sip" msgid="2052499390128979920">"fazer/receber chamadas SIP"</string> + <string name="permdesc_use_sip" msgid="2297804849860225257">"Permite que o app faça e receba chamadas SIP."</string> + <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"registrar novas conexões SIM de telecomunicações"</string> + <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"Permite que o app registre novas conexões SIM de telecomunicações."</string> + <string name="permlab_register_call_provider" msgid="108102120289029841">"registrar novas conexões de telecomunicações"</string> + <string name="permdesc_register_call_provider" msgid="7034310263521081388">"Permite que o app registre novas conexões de telecomunicações."</string> + <string name="permlab_connection_manager" msgid="1116193254522105375">"gerenciar conexões de telecomunicações"</string> + <string name="permdesc_connection_manager" msgid="5925480810356483565">"Permite que o app gerencie conexões de telecomunicações."</string> + <string name="permlab_bind_incall_service" msgid="6773648341975287125">"interagir com chamada na tela"</string> + <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Permite que o app controle quando e como o usuário visualiza a chamada na tela."</string> + <string name="permlab_bind_connection_service" msgid="3557341439297014940">"interagir com os serviços de telefonia"</string> + <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Permite ao app interagir com os serviços de telefonia para fazer/receber chamadas."</string> + <string name="permlab_control_incall_experience" msgid="9061024437607777619">"fornecer uma experiência de usuário em chamada"</string> + <string name="permdesc_control_incall_experience" msgid="915159066039828124">"Permite ao app fornecer uma experiência de usuário em chamada."</string> + <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"ler histórico de uso da rede"</string> + <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Permite que o app leia o histórico de uso da rede para redes e apps específicos."</string> + <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"gerenciar a política de rede"</string> + <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Permite que o app gerencie políticas de rede e definia regras específicas para o app."</string> + <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"modificar contagem de uso da rede"</string> + <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite que o app modifique como o uso da rede é contabilizado em relação aos apps. Não deve ser usado em apps normais."</string> + <string name="permlab_accessNotifications" msgid="7673416487873432268">"acessar notificações"</string> + <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite que o app recupere, examine e limpe notificações, inclusive as postadas por outros apps."</string> + <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"sujeitar a um serviço ouvinte de notificações"</string> + <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permite que o proprietário sujeite a interface de nível superior a um serviço ouvinte de notificações. Não deve ser necessário para apps comuns."</string> + <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"associar a um serviço provedor de condições"</string> + <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Permite que o proprietário use a interface de nível superior de um serviço provedor de condições. Não deve ser necessário para apps comuns."</string> + <string name="permlab_bindDreamService" msgid="4153646965978563462">"conectar-se a um serviço de sonho"</string> + <string name="permdesc_bindDreamService" msgid="7325825272223347863">"Permite que o sistema autorizado se conecte à interface de nível superior de um serviço de sonho. Não deve ser necessário para apps comuns."</string> + <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"invocar o app de configuração fornecido pela operadora"</string> + <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite que o proprietário invoque o app de configuração fornecido pela operadora. Não deve ser necessário para apps comuns."</string> + <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"detectar observações nas condições da rede"</string> + <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que o app detecte observações nas condições da rede. Não deve ser necessário para apps comuns."</string> + <string name="permlab_setInputCalibration" msgid="4902620118878467615">"alterar calibragem do dispositivo de entrada"</string> + <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que o app modifique os parâmetros de calibragem da tela sensível ao toque. Não deve ser necessário para apps normais."</string> + <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"acessar certificados de DRM"</string> + <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Permite que o app provisione e use certificados de DRM. Não deve ser necessário para apps comuns."</string> + <string name="permlab_handoverStatus" msgid="1159132046126626731">"Receber status de transferência do Android Beam"</string> + <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Permite que este app receba informações sobre as atuais transferências do Android Beam"</string> + <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"remover certificados de DRM"</string> + <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Permite que um app remova certificados de DRM. Não deve ser necessário para apps comuns."</string> + <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"vincular a um serviço de mensagens de operadora"</string> + <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Permite que o proprietário use a interface de nível superior de um serviço de mensagens de operadora. Não deve ser necessária para apps comuns."</string> + <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"vincular a serviços de operadora"</string> + <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Permite que o proprietário use serviços de operadora. Não deve ser necessário para apps comuns."</string> + <string name="permlab_access_notification_policy" msgid="4247510821662059671">"acessar \"Não perturbe\""</string> + <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permitir que o app leia e grave a configuração \"Não perturbe\"."</string> + <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string> + <string name="policydesc_limitPassword" msgid="2502021457917874968">"Controla o tamanho e os caracteres permitidos nos PINs e nas senhas do bloqueio de tela."</string> + <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorar tentativas de desbloqueio da tela"</string> + <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Monitorar quantas vezes a senha foi digitada incorretamente ao desbloquear a tela e bloquear o tablet ou apagar todos os dados do tablet se a senha for digitada incorretamente muitas vezes."</string> + <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Monitora o número de senhas incorretas digitadas ao desbloquear a tela e bloqueia a TV ou apagar todos os dados dela se muitas senhas incorretas forem digitadas."</string> + <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Monitorar quantas vezes a senha foi digitada incorretamente ao desbloquear a tela e bloquear o telefone ou apagar todos os dados do telefone se a senha for digitada incorretamente muitas vezes."</string> + <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Monitora o número de senhas incorretas digitadas ao desbloquear a tela e bloqueia o tablet ou limpa todos os dados do usuário se muitas senhas incorretas forem digitadas."</string> + <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Monitora o número de senhas incorretas digitadas ao desbloquear a tela e bloqueia a TV ou limpa todos os dados do usuário se muitas senhas incorretas forem digitadas."</string> + <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Monitora o número de senhas incorretas digitadas ao desbloquear a tela e bloqueia o smartphone ou limpa todos os dados do usuário se muitas senhas incorretas forem digitadas."</string> + <string name="policylab_resetPassword" msgid="4934707632423915395">"Alterar o bloqueio de tela"</string> + <string name="policydesc_resetPassword" msgid="1278323891710619128">"Altera o bloqueio de tela."</string> + <string name="policylab_forceLock" msgid="2274085384704248431">"Bloquear a tela"</string> + <string name="policydesc_forceLock" msgid="1141797588403827138">"Controlar como e quando a tela é bloqueada."</string> + <string name="policylab_wipeData" msgid="3910545446758639713">"Apagar todos os dados"</string> + <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Apague os dados do tablet sem aviso redefinindo a configuração original."</string> + <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Apaga dados da TV sem aviso, fazendo uma redefinição para configuração original."</string> + <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Apagar os dados do telefone sem aviso redefinindo a configuração original."</string> + <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Limpar dados do usuário"</string> + <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Limpa os dados do usuário neste tablet sem aviso prévio."</string> + <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Limpa os dados do usuário nesta TV sem aviso prévio."</string> + <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"Limpa os dados do usuário neste smartphone sem aviso prévio."</string> + <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir o proxy global do dispositivo"</string> + <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Configura o proxy global do dispositivo para ser usado enquanto a política está ativada. Somente o proprietário do dispositivo pode definir o proxy global."</string> + <string name="policylab_expirePassword" msgid="5610055012328825874">"Definir expiração da senha de bloqueio de tela"</string> + <string name="policydesc_expirePassword" msgid="5367525762204416046">"Altera a frequência com que o PIN, a senha ou o padrão do bloqueio de tela deve ser alterado."</string> + <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Definir criptografia de armazenamento"</string> + <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Exija que os dados armazenados do app sejam criptografados."</string> + <string name="policylab_disableCamera" msgid="6395301023152297826">"Desativar câmeras"</string> + <string name="policydesc_disableCamera" msgid="2306349042834754597">"Impeça o uso de todas as câmeras do dispositivo."</string> + <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Desat. recursos bloq. de tela"</string> + <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Impede o uso de alguns recursos do bloqueio de tela."</string> + <string-array name="phoneTypes"> + <item msgid="8901098336658710359">"Residencial"</item> + <item msgid="869923650527136615">"Celular"</item> + <item msgid="7897544654242874543">"Trabalho"</item> + <item msgid="1103601433382158155">"Fax do trabalho"</item> + <item msgid="1735177144948329370">"Fax doméstico"</item> + <item msgid="603878674477207394">"Pager"</item> + <item msgid="1650824275177931637">"Outros"</item> + <item msgid="9192514806975898961">"Personalizado"</item> + </string-array> + <string-array name="emailAddressTypes"> + <item msgid="8073994352956129127">"Residencial"</item> + <item msgid="7084237356602625604">"Trabalho"</item> + <item msgid="1112044410659011023">"Outros"</item> + <item msgid="2374913952870110618">"Personalizado"</item> + </string-array> + <string-array name="postalAddressTypes"> + <item msgid="6880257626740047286">"Residencial"</item> + <item msgid="5629153956045109251">"Trabalho"</item> + <item msgid="4966604264500343469">"Outros"</item> + <item msgid="4932682847595299369">"Personalizado"</item> + </string-array> + <string-array name="imAddressTypes"> + <item msgid="1738585194601476694">"Residencial"</item> + <item msgid="1359644565647383708">"Trabalho"</item> + <item msgid="7868549401053615677">"Outros"</item> + <item msgid="3145118944639869809">"Personalizado"</item> + </string-array> + <string-array name="organizationTypes"> + <item msgid="7546335612189115615">"Trabalho"</item> + <item msgid="4378074129049520373">"Outros"</item> + <item msgid="3455047468583965104">"Personalizado"</item> + </string-array> + <string-array name="imProtocols"> + <item msgid="8595261363518459565">"AIM"</item> + <item msgid="7390473628275490700">"Windows Live"</item> + <item msgid="7882877134931458217">"Yahoo"</item> + <item msgid="5035376313200585242">"Skype"</item> + <item msgid="7532363178459444943">"QQ"</item> + <item msgid="3713441034299660749">"Google Talk"</item> + <item msgid="2506857312718630823">"ICQ"</item> + <item msgid="1648797903785279353">"Jabber"</item> + </string-array> + <string name="phoneTypeCustom" msgid="1644738059053355820">"Personalizado"</string> + <string name="phoneTypeHome" msgid="2570923463033985887">"Residencial"</string> + <string name="phoneTypeMobile" msgid="6501463557754751037">"Celular"</string> + <string name="phoneTypeWork" msgid="8863939667059911633">"Comercial"</string> + <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Fax comercial"</string> + <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Fax residencial"</string> + <string name="phoneTypePager" msgid="7582359955394921732">"Pager"</string> + <string name="phoneTypeOther" msgid="1544425847868765990">"Outros"</string> + <string name="phoneTypeCallback" msgid="2712175203065678206">"Retorno de chamada"</string> + <string name="phoneTypeCar" msgid="8738360689616716982">"Carro"</string> + <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Empresa (principal)"</string> + <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string> + <string name="phoneTypeMain" msgid="6766137010628326916">"Principal"</string> + <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Outro fax"</string> + <string name="phoneTypeRadio" msgid="4093738079908667513">"Rádio"</string> + <string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string> + <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string> + <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Celular comercial"</string> + <string name="phoneTypeWorkPager" msgid="649938731231157056">"Pager comercial"</string> + <string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistente"</string> + <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> + <string name="eventTypeCustom" msgid="7837586198458073404">"Personalizado"</string> + <string name="eventTypeBirthday" msgid="2813379844211390740">"Aniversário"</string> + <string name="eventTypeAnniversary" msgid="3876779744518284000">"Data comemorativa"</string> + <string name="eventTypeOther" msgid="7388178939010143077">"Outros"</string> + <string name="emailTypeCustom" msgid="8525960257804213846">"Personalizado"</string> + <string name="emailTypeHome" msgid="449227236140433919">"Residencial"</string> + <string name="emailTypeWork" msgid="3548058059601149973">"Comercial"</string> + <string name="emailTypeOther" msgid="2923008695272639549">"Outros"</string> + <string name="emailTypeMobile" msgid="119919005321166205">"Celular"</string> + <string name="postalTypeCustom" msgid="8903206903060479902">"Personalizado"</string> + <string name="postalTypeHome" msgid="8165756977184483097">"Residencial"</string> + <string name="postalTypeWork" msgid="5268172772387694495">"Comercial"</string> + <string name="postalTypeOther" msgid="2726111966623584341">"Outros"</string> + <string name="imTypeCustom" msgid="2074028755527826046">"Personalizado"</string> + <string name="imTypeHome" msgid="6241181032954263892">"Residencial"</string> + <string name="imTypeWork" msgid="1371489290242433090">"Comercial"</string> + <string name="imTypeOther" msgid="5377007495735915478">"Outros"</string> + <string name="imProtocolCustom" msgid="6919453836618749992">"Personalizado"</string> + <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string> + <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string> + <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string> + <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string> + <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string> + <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Hangouts"</string> + <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string> + <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string> + <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string> + <string name="orgTypeWork" msgid="29268870505363872">"Comercial"</string> + <string name="orgTypeOther" msgid="3951781131570124082">"Outros"</string> + <string name="orgTypeCustom" msgid="225523415372088322">"Personalizado"</string> + <string name="relationTypeCustom" msgid="3542403679827297300">"Personalizado"</string> + <string name="relationTypeAssistant" msgid="6274334825195379076">"Assistente"</string> + <string name="relationTypeBrother" msgid="8757913506784067713">"Irmão"</string> + <string name="relationTypeChild" msgid="1890746277276881626">"Filho(a)"</string> + <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Parceiro doméstico"</string> + <string name="relationTypeFather" msgid="5228034687082050725">"Pai"</string> + <string name="relationTypeFriend" msgid="7313106762483391262">"Amigo(a)"</string> + <string name="relationTypeManager" msgid="6365677861610137895">"Gerente"</string> + <string name="relationTypeMother" msgid="4578571352962758304">"Mãe"</string> + <string name="relationTypeParent" msgid="4755635567562925226">"Pai/Mãe"</string> + <string name="relationTypePartner" msgid="7266490285120262781">"Parceiro"</string> + <string name="relationTypeReferredBy" msgid="101573059844135524">"Indicado por"</string> + <string name="relationTypeRelative" msgid="1799819930085610271">"Parente"</string> + <string name="relationTypeSister" msgid="1735983554479076481">"Irmã"</string> + <string name="relationTypeSpouse" msgid="394136939428698117">"Cônjuge"</string> + <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Personalizado"</string> + <string name="sipAddressTypeHome" msgid="6093598181069359295">"Página inicial"</string> + <string name="sipAddressTypeWork" msgid="6920725730797099047">"Comercial"</string> + <string name="sipAddressTypeOther" msgid="4408436162950119849">"Outros"</string> + <string name="quick_contacts_not_available" msgid="746098007828579688">"Nenhum app encontrado para visualizar este contato."</string> + <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Insira o código PIN"</string> + <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Insira o PUK e o novo código PIN"</string> + <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Código PUK"</string> + <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Novo código PIN"</string> + <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Toque para inserir a senha"</font></string> + <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Digite a senha para desbloquear"</string> + <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Insira o PIN para desbloquear"</string> + <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Código PIN incorreto."</string> + <string name="keyguard_label_text" msgid="861796461028298424">"Para desbloquear, pressione Menu e, em seguida, 0."</string> + <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Número de emergência"</string> + <string name="lockscreen_carrier_default" msgid="8963839242565653192">"Sem serviço."</string> + <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Tela bloqueada."</string> + <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Pressione Menu para desbloquear ou fazer uma chamada de emergência."</string> + <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Pressione Menu para desbloquear."</string> + <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Desenhe o padrão para desbloquear"</string> + <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Emergência"</string> + <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Retornar à chamada"</string> + <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Correto!"</string> + <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Tente novamente"</string> + <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Tente novamente"</string> + <string name="faceunlock_multiple_failures" msgid="754137583022792429">"O número máximo de tentativas de Desbloqueio por reconhecimento facial foi excedido"</string> + <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Sem cartão SIM"</string> + <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Não há um cartão SIM no tablet."</string> + <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Nenhum cartão SIM na TV."</string> + <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Não há um cartão SIM no telefone."</string> + <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Insera um cartão SIM."</string> + <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"O cartão SIM não foi inserido ou não é possível lê-lo. Insira um cartão SIM."</string> + <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Cartão SIM inutilizável."</string> + <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"O cartão SIM foi desativado permanentemente.\nEntre em contato com seu provedor de serviços sem fio para obter outro cartão SIM."</string> + <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Faixa anterior"</string> + <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Próxima faixa"</string> + <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"Pausar"</string> + <string name="lockscreen_transport_play_description" msgid="1901258823643886401">"Reproduzir"</string> + <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"Parar"</string> + <string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Retroceder"</string> + <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Avançar"</string> + <string name="emergency_calls_only" msgid="6733978304386365407">"Só chamadas de emergência"</string> + <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Rede bloqueada"</string> + <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"O cartão SIM está bloqueado pelo PUK."</string> + <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Consulte o Guia do usuário ou entre em contato com o Serviço de atendimento ao cliente."</string> + <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"O cartão SIM está bloqueado."</string> + <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Desbloqueando o cartão SIM…"</string> + <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string> + <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string> + <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes.\n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, será pedido que você desbloqueie sua TV usando seu login do Google.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> + <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string> + <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, a TV será redefinida para os padrões de fábrica e todos os dados do usuário serão perdidos."</string> + <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string> + <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O tablet será redefinido para o padrão de fábrica."</string> + <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER">%d</xliff:g> vezes. A TV será redefinida agora para os padrões de fábrica."</string> + <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER">%d</xliff:g> vezes. O telefone será redefinido para o padrão de fábrica."</string> + <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Tente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string> + <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Esqueceu o padrão?"</string> + <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Desbloqueio de conta"</string> + <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Muitas tentativas de padrão"</string> + <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Para desbloquear, faça login com sua Conta do Google."</string> + <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nome de usuário (e-mail)"</string> + <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Senha"</string> + <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Fazer login"</string> + <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nome de usuário ou senha inválidos."</string> + <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Esqueceu seu nome de usuário ou senha?\nAcesse "<b>"google.com.br/accounts/recovery"</b>"."</string> + <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Verificando…"</string> + <string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string> + <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Som ativado"</string> + <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Som desativado"</string> + <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Padrão iniciado"</string> + <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Padrão apagado"</string> + <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Célula adicionada"</string> + <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Célula <xliff:g id="CELL_INDEX">%1$s</xliff:g> adicionada"</string> + <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Padrão concluído"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Área do padrão."</string> + <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string> + <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adicionar widget"</string> + <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vazio"</string> + <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Área de desbloqueio expandida."</string> + <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Área de desbloqueio recolhida."</string> + <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget de <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string> + <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Seletor de usuários"</string> + <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string> + <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Câmera"</string> + <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controles de mídia"</string> + <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Reordenação de widgets iniciada."</string> + <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Reordenação de widgets concluída."</string> + <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> excluído."</string> + <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expandir a área de desbloqueio."</string> + <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Desbloqueio com deslize."</string> + <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Desbloqueio com padrão."</string> + <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Desbloqueio facial."</string> + <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Desbloqueio com PIN."</string> + <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Desbloqueio com senha."</string> + <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Área do padrão."</string> + <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Área de deslize."</string> + <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string> + <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string> + <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string> + <string name="granularity_label_character" msgid="7336470535385009523">"caractere"</string> + <string name="granularity_label_word" msgid="7075570328374918660">"palavra"</string> + <string name="granularity_label_link" msgid="5815508880782488267">"link"</string> + <string name="granularity_label_line" msgid="5764267235026120888">"linha"</string> + <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string> + <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string> + <string name="factorytest_failed" msgid="5410270329114212041">"Falha no teste de fábrica"</string> + <string name="factorytest_not_system" msgid="4435201656767276723">"A ação FACTORY_TEST é suportada apenas para pacotes instalados em /system/app."</string> + <string name="factorytest_no_action" msgid="872991874799998561">"Nenhum pacote que forneça a ação FACTORY_TEST foi encontrado."</string> + <string name="factorytest_reboot" msgid="6320168203050791643">"Reiniciar"</string> + <string name="js_dialog_title" msgid="1987483977834603872">"A página em \"<xliff:g id="TITLE">%s</xliff:g>\" diz:"</string> + <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string> + <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Confirmar navegação"</string> + <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Sair desta página"</string> + <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Permanecer nesta página"</string> + <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nTem certeza de que deseja sair desta página?"</string> + <string name="save_password_label" msgid="6860261758665825069">"Confirmar"</string> + <string name="double_tap_toast" msgid="4595046515400268881">"Dica: toque duas vezes para aumentar e diminuir o zoom."</string> + <string name="autofill_this_form" msgid="4616758841157816676">"Preench. aut."</string> + <string name="setup_autofill" msgid="7103495070180590814">"Conf. preench. aut."</string> + <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string> + <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string> + <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string> + <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string> + <string name="autofill_province" msgid="2231806553863422300">"Distrito"</string> + <string name="autofill_postal_code" msgid="4696430407689377108">"Código Postal"</string> + <string name="autofill_state" msgid="6988894195520044613">"Estado"</string> + <string name="autofill_zip_code" msgid="8697544592627322946">"CEP"</string> + <string name="autofill_county" msgid="237073771020362891">"Condado"</string> + <string name="autofill_island" msgid="4020100875984667025">"Ilha"</string> + <string name="autofill_district" msgid="8400735073392267672">"Distrito"</string> + <string name="autofill_department" msgid="5343279462564453309">"Departamento"</string> + <string name="autofill_prefecture" msgid="2028499485065800419">"Município"</string> + <string name="autofill_parish" msgid="8202206105468820057">"Paróquia"</string> + <string name="autofill_area" msgid="3547409050889952423">"Área"</string> + <string name="autofill_emirate" msgid="2893880978835698818">"Emirado"</string> + <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"ler seu histórico e seus favoritos da web"</string> + <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Permite que o app leia o histórico de todos os URLs acessados no navegador e todos os favoritos do navegador. Observação: pode não ser aplicável a navegadores de terceiros e outros apps com capacidade de navegação na web."</string> + <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"gravar seu histórico e seus favoritos da web"</string> + <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Permite que o app modifique o histórico ou os favoritos do navegador armazenados no tablet. Pode permitir que o app apague ou modifique os dados do navegador. Observação: pode não ser aplicável a navegadores de terceiros e outros apps com capacidade de navegação na web."</string> + <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Permite que o app modifique o histórico ou os favoritos do navegador armazenados na sua TV. Isso pode permitir que o app apague ou modifique os dados do navegador. Observação: essa autorização pode ser aplicada por navegadores de terceiros ou outros apps com recursos de navegação na Web."</string> + <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite que o app modifique o histórico ou os favoritos do navegador armazenados no telefone. Pode permitir que o app apague ou modifique os dados do navegador. Observação: pode não ser aplicável a navegadores de terceiros e outros apps com capacidade de navegação na web."</string> + <string name="permlab_setAlarm" msgid="1379294556362091814">"definir um alarme"</string> + <string name="permdesc_setAlarm" msgid="316392039157473848">"Permite que o app defina um alarme em um app despertador instalado. Alguns apps despertador podem não implementar este recurso."</string> + <string name="permlab_addVoicemail" msgid="5525660026090959044">"adicionar correio de voz"</string> + <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite que o app adicione mensagens a sua caixa de entrada do correio de voz."</string> + <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Modifique as permissões de geolocalização de seu navegador"</string> + <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permite que o app modifique as permissões de geolocalização do navegador. Apps maliciosos podem usar isso para permitir o envio de informações locais para sites arbitrários."</string> + <string name="save_password_message" msgid="767344687139195790">"Deseja que o navegador lembre desta senha?"</string> + <string name="save_password_notnow" msgid="6389675316706699758">"Agora não"</string> + <string name="save_password_remember" msgid="6491879678996749466">"Lembrar"</string> + <string name="save_password_never" msgid="8274330296785855105">"Nunca"</string> + <string name="open_permission_deny" msgid="7374036708316629800">"Você não tem permissão para abrir esta página."</string> + <string name="text_copied" msgid="4985729524670131385">"Texto copiado para a área de transferência."</string> + <string name="more_item_label" msgid="4650918923083320495">"Mais"</string> + <string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string> + <string name="menu_space_shortcut_label" msgid="2410328639272162537">"espaço"</string> + <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"enter"</string> + <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"excluir"</string> + <string name="search_go" msgid="8298016669822141719">"Pesquisar"</string> + <string name="search_hint" msgid="1733947260773056054">"Pesquisar..."</string> + <string name="searchview_description_search" msgid="6749826639098512120">"Pesquisar"</string> + <string name="searchview_description_query" msgid="5911778593125355124">"Consulta de pesquisa"</string> + <string name="searchview_description_clear" msgid="1330281990951833033">"Limpar consulta"</string> + <string name="searchview_description_submit" msgid="2688450133297983542">"Enviar consulta"</string> + <string name="searchview_description_voice" msgid="2453203695674994440">"Pesquisa por voz"</string> + <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Ativar exploração pelo toque?"</string> + <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> quer ativar a exploração pelo toque. Com ela, você pode ouvir ou ver descrições do que está sob seu dedo e interagir com o tablet através de gestos."</string> + <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> quer ativar a exploração pelo toque. Com ela, você pode ouvir ou ver descrições do que está sob seu dedo e interagir com o telefone através de gestos."</string> + <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 mês atrás"</string> + <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Antes de 1 mês atrás"</string> + <plurals name="last_num_days" formatted="false" msgid="5104533550723932025"> + <item quantity="one">Últimos <xliff:g id="COUNT_1">%d</xliff:g> dias</item> + <item quantity="other">Últimos <xliff:g id="COUNT_1">%d</xliff:g> dias</item> + </plurals> + <string name="last_month" msgid="3959346739979055432">"Mês passado"</string> + <string name="older" msgid="5211975022815554840">"Mais antigos"</string> + <string name="preposition_for_date" msgid="9093949757757445117">"em <xliff:g id="DATE">%s</xliff:g>"</string> + <string name="preposition_for_time" msgid="5506831244263083793">"às <xliff:g id="TIME">%s</xliff:g>"</string> + <string name="preposition_for_year" msgid="5040395640711867177">"em <xliff:g id="YEAR">%s</xliff:g>"</string> + <string name="day" msgid="8144195776058119424">"dia"</string> + <string name="days" msgid="4774547661021344602">"dias"</string> + <string name="hour" msgid="2126771916426189481">"hora"</string> + <string name="hours" msgid="894424005266852993">"horas"</string> + <string name="minute" msgid="9148878657703769868">"min."</string> + <string name="minutes" msgid="5646001005827034509">"min."</string> + <string name="second" msgid="3184235808021478">"seg."</string> + <string name="seconds" msgid="3161515347216589235">"segundos"</string> + <string name="week" msgid="5617961537173061583">"semana"</string> + <string name="weeks" msgid="6509623834583944518">"semanas"</string> + <string name="year" msgid="4001118221013892076">"ano"</string> + <string name="years" msgid="6881577717993213522">"anos"</string> + <plurals name="duration_seconds" formatted="false" msgid="4527986939729687805"> + <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> segundos</item> + <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> segundos</item> + </plurals> + <plurals name="duration_minutes" formatted="false" msgid="643786953939956125"> + <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> minutos</item> + <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> minutos</item> + </plurals> + <plurals name="duration_hours" formatted="false" msgid="6826233369186668274"> + <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> horas</item> + <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> horas</item> + </plurals> + <string name="VideoView_error_title" msgid="3534509135438353077">"Problema com o vídeo"</string> + <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Este vídeo não é válido para transmissão neste dispositivo."</string> + <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Não é possível reproduzir este vídeo."</string> + <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</string> + <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="noon" msgid="7245353528818587908">"meio-dia"</string> + <string name="Noon" msgid="3342127745230013127">"Meio-dia"</string> + <string name="midnight" msgid="7166259508850457595">"meia-noite"</string> + <string name="Midnight" msgid="5630806906897892201">"Meia-noite"</string> + <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string> + <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string> + <string name="selectAll" msgid="6876518925844129331">"Selecionar tudo"</string> + <string name="cut" msgid="3092569408438626261">"Recortar"</string> + <string name="copy" msgid="2681946229533511987">"Copiar"</string> + <string name="paste" msgid="5629880836805036433">"Colar"</string> + <string name="replace" msgid="5781686059063148930">"Substituir..."</string> + <string name="delete" msgid="6098684844021697789">"Excluir"</string> + <string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string> + <string name="selectTextMode" msgid="1018691815143165326">"Selecionar texto"</string> + <string name="textSelectionCABTitle" msgid="5236850394370820357">"Seleção de texto"</string> + <string name="addToDictionary" msgid="4352161534510057874">"Adicionar ao dicionário"</string> + <string name="deleteText" msgid="6979668428458199034">"Excluir"</string> + <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string> + <string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string> + <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Pouco espaço de armazenamento"</string> + <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema podem não funcionar"</string> + <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Não há armazenamento suficiente para o sistema. Certifique-se de ter 250 MB de espaço livre e reinicie."</string> + <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> está em execução"</string> + <string name="app_running_notification_text" msgid="4653586947747330058">"Toque para mais informações ou para parar o app."</string> + <string name="ok" msgid="5970060430562524910">"OK"</string> + <string name="cancel" msgid="6442560571259935130">"Cancelar"</string> + <string name="yes" msgid="5362982303337969312">"OK"</string> + <string name="no" msgid="5141531044935541497">"Cancelar"</string> + <string name="dialog_alert_title" msgid="2049658708609043103">"Atenção"</string> + <string name="loading" msgid="7933681260296021180">"Carregando…"</string> + <string name="capital_on" msgid="1544682755514494298">"LIG"</string> + <string name="capital_off" msgid="6815870386972805832">"DESL"</string> + <string name="whichApplication" msgid="4533185947064773386">"Complete a ação usando"</string> + <string name="whichApplicationNamed" msgid="8260158865936942783">"Concluir a ação usando %1$s"</string> + <string name="whichViewApplication" msgid="3272778576700572102">"Abrir com"</string> + <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Abrir com %1$s"</string> + <string name="whichEditApplication" msgid="144727838241402655">"Editar com"</string> + <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editar com %1$s"</string> + <string name="whichSendApplication" msgid="6902512414057341668">"Compartilhar com"</string> + <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Compartilhar com %1$s"</string> + <string name="whichHomeApplication" msgid="4307587691506919691">"Selecione um app de Página inicial"</string> + <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Usar %1$s como Página inicial"</string> + <string name="alwaysUse" msgid="4583018368000610438">"Usar como padrão para esta ação."</string> + <string name="use_a_different_app" msgid="8134926230585710243">"Usar outro app"</string> + <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Padrão claro em Configurações do sistema > Apps > Baixado."</string> + <string name="chooseActivity" msgid="7486876147751803333">"Escolher uma ação"</string> + <string name="chooseUsbActivity" msgid="6894748416073583509">"Selecione um app para o dispositivo USB"</string> + <string name="noApplications" msgid="2991814273936504689">"Nenhum app pode realizar esta ação."</string> + <string name="aerr_title" msgid="1905800560317137752"></string> + <string name="aerr_application" msgid="932628488013092776">"O <xliff:g id="APPLICATION">%1$s</xliff:g> parou."</string> + <string name="aerr_process" msgid="4507058997035697579">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> parou."</string> + <string name="anr_title" msgid="4351948481459135709"></string> + <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> não está respondendo.\n\nDeseja fechá-lo?"</string> + <string name="anr_activity_process" msgid="5776209883299089767">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> não está respondendo.\n\nDeseja fechá-la?"</string> + <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> não está respondendo. Deseja encerrar o app?"</string> + <string name="anr_process" msgid="6513209874880517125">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> não está respondendo.\n\nDeseja fechá-lo?"</string> + <string name="force_close" msgid="8346072094521265605">"OK"</string> + <string name="report" msgid="4060218260984795706">"Informar"</string> + <string name="wait" msgid="7147118217226317732">"Aguardar"</string> + <string name="webpage_unresponsive" msgid="3272758351138122503">"A página não responde.\n\nDeseja fechá-la?"</string> + <string name="launch_warning_title" msgid="1547997780506713581">"App redirecionado"</string> + <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> não está em execução."</string> + <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> foi iniciado."</string> + <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Escala"</string> + <string name="screen_compat_mode_show" msgid="4013878876486655892">"Mostrar sempre"</string> + <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Reativar isso em Configurações do sistema > Apps > Transferidos."</string> + <string name="smv_application" msgid="3307209192155442829">"O app <xliff:g id="APPLICATION">%1$s</xliff:g>, processo <xliff:g id="PROCESS">%2$s</xliff:g>, violou a política StrictMode imposta automaticamente."</string> + <string name="smv_process" msgid="5120397012047462446">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> violou a política StrictMode imposta automaticamente."</string> + <string name="android_upgrading_title" msgid="1584192285441405746">"O Android está sendo atualizado..."</string> + <string name="android_start_title" msgid="8418054686415318207">"O Android está iniciando..."</string> + <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Otimizando o armazenamento."</string> + <string name="android_upgrading_apk" msgid="7904042682111526169">"Otimizando app <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string> + <string name="android_preparing_apk" msgid="8162599310274079154">"Preparando <xliff:g id="APPNAME">%1$s</xliff:g>."</string> + <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando apps."</string> + <string name="android_upgrading_complete" msgid="1405954754112999229">"Concluindo a inicialização."</string> + <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> em execução"</string> + <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Toque para alternar para o app"</string> + <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Alternar entre apps?"</string> + <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Outro app já está em execução e deve ser interrompido antes que você inicie um novo app."</string> + <string name="old_app_action" msgid="493129172238566282">"Voltar para <xliff:g id="OLD_APP">%1$s</xliff:g>"</string> + <string name="old_app_description" msgid="2082094275580358049">"Não inicie o novo app."</string> + <string name="new_app_action" msgid="5472756926945440706">"Iniciar <xliff:g id="OLD_APP">%1$s</xliff:g>"</string> + <string name="new_app_description" msgid="1932143598371537340">"Parar o app antigo sem salvar."</string> + <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> excedeu o limite de memória"</string> + <string name="dump_heap_notification_detail" msgid="2075673362317481664">"O despejo de heap foi coletado. Toque para compartilhar"</string> + <string name="dump_heap_title" msgid="5864292264307651673">"Compartilhar despejo de heap?"</string> + <string name="dump_heap_text" msgid="4809417337240334941">"O processo <xliff:g id="PROC">%1$s</xliff:g> excedeu seu limite de memória de <xliff:g id="SIZE">%2$s</xliff:g>. Um despejo de heap está disponível para compartilhamento com o desenvolvedor. Tenha cuidado: esse despejo de heap pode conter informações pessoais às quais o aplicativo tem acesso."</string> + <string name="sendText" msgid="5209874571959469142">"Escolha uma ação para o texto"</string> + <string name="volume_ringtone" msgid="6885421406845734650">"Volume da campainha"</string> + <string name="volume_music" msgid="5421651157138628171">"Volume da mídia"</string> + <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Reproduzindo por meio de Bluetooth"</string> + <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Toque silencioso definido"</string> + <string name="volume_call" msgid="3941680041282788711">"Volume na chamada"</string> + <string name="volume_bluetooth_call" msgid="2002891926351151534">"Volume de chamada Bluetooth"</string> + <string name="volume_alarm" msgid="1985191616042689100">"Volume do alarme"</string> + <string name="volume_notification" msgid="2422265656744276715">"Volume da notificação"</string> + <string name="volume_unknown" msgid="1400219669770445902">"Volume"</string> + <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Volume de Bluetooth"</string> + <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Volume do toque"</string> + <string name="volume_icon_description_incall" msgid="8890073218154543397">"Volume de chamadas"</string> + <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume da mídia"</string> + <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume da notificação"</string> + <string name="ringtone_default" msgid="3789758980357696936">"Toque padrão"</string> + <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Toque padrão (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <string name="ringtone_silent" msgid="7937634392408977062">"Nenhum"</string> + <string name="ringtone_picker_title" msgid="3515143939175119094">"Toques"</string> + <string name="ringtone_unknown" msgid="5477919988701784788">"Toque desconhecido"</string> + <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> + <item quantity="one">Redes Wi-Fi disponíveis</item> + <item quantity="other">Redes Wi-Fi disponíveis</item> + </plurals> + <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606"> + <item quantity="one">Abrir redes Wi-Fi disponíveis</item> + <item quantity="other">Abrir redes Wi-Fi disponíveis</item> + </plurals> + <string name="wifi_available_sign_in" msgid="9157196203958866662">"Fazer login na rede Wi-Fi"</string> + <string name="network_available_sign_in" msgid="1848877297365446605">"Fazer login na rede"</string> + <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> + <skip /> + <string name="wifi_no_internet" msgid="8451173622563841546">"O Wi-Fi não tem acesso à Internet"</string> + <string name="wifi_no_internet_detailed" msgid="7593858887662270131">"Toque para ver as opções"</string> + <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Não foi possível se conectar a redes Wi-Fi"</string> + <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" tem uma conexão de baixa qualidade com a Internet."</string> + <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Permitir conexão?"</string> + <string name="wifi_connect_alert_message" msgid="6451273376815958922">"O app %1$s deseja se conectar à rede Wi-Fi %2$s"</string> + <string name="wifi_connect_default_application" msgid="7143109390475484319">"Um app"</string> + <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string> + <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Iniciar o Wi-Fi Direct. Isso desativará o ponto de acesso/cliente Wi-Fi."</string> + <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Não foi possível iniciar o Wi-Fi Direct."</string> + <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct ativado"</string> + <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Tocar para acessar configurações"</string> + <string name="accept" msgid="1645267259272829559">"Aceitar"</string> + <string name="decline" msgid="2112225451706137894">"Recusar"</string> + <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Convite enviado"</string> + <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Convite para se conectar"</string> + <string name="wifi_p2p_from_message" msgid="570389174731951769">"De:"</string> + <string name="wifi_p2p_to_message" msgid="248968974522044099">"Para:"</string> + <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Digite o PIN obrigatório:"</string> + <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string> + <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"O tablet desconectará temporariamente da rede Wi-Fi enquanto estiver conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> + <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"A TV desconectará o Wi-Fi temporariamente enquanto estiver conectada ao <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> + <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"O telefone desconectará temporariamente da rede Wi-Fi enquanto estiver conectado a <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> + <string name="select_character" msgid="3365550120617701745">"Inserir caractere"</string> + <string name="sms_control_title" msgid="7296612781128917719">"Enviando mensagens SMS"</string> + <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> envia uma grande quantidade de mensagens SMS. Deseja permitir que este app continue enviando mensagens?"</string> + <string name="sms_control_yes" msgid="3663725993855816807">"Permitir"</string> + <string name="sms_control_no" msgid="625438561395534982">"Negar"</string> + <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> deseja enviar uma mensagem para <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string> + <string name="sms_short_code_details" msgid="5873295990846059400">"Isso "<b>"pode resultar em cobranças"</b>" na conta de seu dispositivo móvel."</string> + <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Isso resultará em cobranças na conta de seu dispositivo móvel."</b></string> + <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Enviar"</string> + <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Cancelar"</string> + <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Lembrar minha escolha"</string> + <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"P/ alterar: Configurações > Apps"</string> + <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Sempre permitir"</string> + <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nunca permitir"</string> + <string name="sim_removed_title" msgid="6227712319223226185">"Cartão SIM removido"</string> + <string name="sim_removed_message" msgid="5450336489923274918">"A rede celular ficará indisponível até que você reinicie com um cartão SIM válido inserido."</string> + <string name="sim_done_button" msgid="827949989369963775">"Concluído"</string> + <string name="sim_added_title" msgid="3719670512889674693">"Cartão SIM adicionado"</string> + <string name="sim_added_message" msgid="7797975656153714319">"Reinicie o dispositivo para acessar a rede celular."</string> + <string name="sim_restart_button" msgid="4722407842815232347">"Reiniciar"</string> + <string name="time_picker_dialog_title" msgid="8349362623068819295">"Definir hora"</string> + <string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string> + <string name="date_time_set" msgid="5777075614321087758">"Definir"</string> + <string name="date_time_done" msgid="2507683751759308828">"Concluído"</string> + <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NOVO: "</font></string> + <string name="perms_description_app" msgid="5139836143293299417">"Fornecido por <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> + <string name="no_permissions" msgid="7283357728219338112">"Nenhuma permissão necessária"</string> + <string name="perm_costs_money" msgid="4902470324142151116">"isso pode lhe custar dinheiro"</string> + <string name="usb_storage_activity_title" msgid="4465055157209648641">"Armazenamento USB em massa"</string> + <string name="usb_storage_title" msgid="5901459041398751495">"Conectado por USB"</string> + <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Você se conectou ao computador via USB. Toque no botão abaixo se quiser copiar arquivos entre o computador e o armazenamento USB de seu Android."</string> + <string name="usb_storage_message" product="default" msgid="805351000446037811">"Você se conectou ao computador via USB. Toque no botão abaixo se quiser copiar arquivos entre o computador e o cartão SD de seu Android."</string> + <string name="usb_storage_button_mount" msgid="1052259930369508235">"Ativar o armazenamento USB"</string> + <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Há um problema com o uso do seu armazenamento USB para armazenamento USB em massa."</string> + <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Há um problema com o uso do seu cartão SD para armazenamento USB em massa."</string> + <string name="usb_storage_notification_title" msgid="8175892554757216525">"Conectado por USB"</string> + <string name="usb_storage_notification_message" msgid="939822783828183763">"Toque para copiar arquivos para/de seu computador."</string> + <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Desativar o armazenamento USB"</string> + <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Toque para desativar o armazenamento USB."</string> + <string name="usb_storage_stop_title" msgid="660129851708775853">"Armazenamento USB em uso"</string> + <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Antes de desativar o armazenamento USB, desconecte (“ejete”) o armazenamento USB do Android de seu computador."</string> + <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Antes de desativar o armazenamento USB, desconecte (“ejete”) o cartão SD do Android de seu computador."</string> + <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Desativar o armazenamento USB"</string> + <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Ocorreu um problema ao desativar o armazenamento USB. Verifique se você desconectou o host USB e tente novamente."</string> + <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Ativar o armazenamento USB"</string> + <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Se você ativar o armazenamento USB, alguns apps que estão em uso serão interrompidos e poderão ficar indisponíveis até você desativar o armazenamento USB."</string> + <string name="dlg_error_title" msgid="7323658469626514207">"Falha na operação do USB"</string> + <string name="dlg_ok" msgid="7376953167039865701">"OK"</string> + <string name="usb_charging_notification_title" msgid="4004114449249406402">"USB para carregamento"</string> + <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB para transferência de arquivos"</string> + <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB para transferência de fotos"</string> + <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB para MIDI"</string> + <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a um acessório USB"</string> + <string name="usb_notification_message" msgid="7347368030849048437">"Toque para ver mais opções."</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string> + <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração do USB."</string> + <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string> + <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string> + <string name="show_ime" msgid="9157568568695230830">"Mostrar método de entrada"</string> + <string name="hardware" msgid="7517821086888990278">"Hardware"</string> + <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecione o layout de teclado"</string> + <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toque para selecionar um layout de teclado."</string> + <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> + <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> + <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> + <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparando <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Procurando erros"</string> + <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Novo <xliff:g id="NAME">%s</xliff:g> detectado"</string> + <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Para transferir fotos e mídia"</string> + <string name="ext_media_unmountable_notification_title" msgid="8295123366236989588">"<xliff:g id="NAME">%s</xliff:g> corrompido"</string> + <string name="ext_media_unmountable_notification_message" msgid="1586311304430052169">"<xliff:g id="NAME">%s</xliff:g> está corrompida. Toque para corrigir."</string> + <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> não compatível"</string> + <string name="ext_media_unsupported_notification_message" msgid="8789610369456474891">"Este dispositivo não é compatível com o <xliff:g id="NAME">%s</xliff:g>. Toque para configurar em um formato compatível."</string> + <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> foi removido inesperadamente"</string> + <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"Desconecte <xliff:g id="NAME">%s</xliff:g> antes da remoção para evitar a perda de dados"</string> + <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"Mídia <xliff:g id="NAME">%s</xliff:g> removida."</string> + <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"Mídia <xliff:g id="NAME">%s</xliff:g> removida. Insira uma nova"</string> + <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"Ainda ejetando <xliff:g id="NAME">%s</xliff:g>..."</string> + <string name="ext_media_unmounting_notification_message" msgid="4182843895023357756">"Não remova"</string> + <string name="ext_media_init_action" msgid="7952885510091978278">"Configurar"</string> + <string name="ext_media_unmount_action" msgid="1121883233103278199">"Ejetar"</string> + <string name="ext_media_browse_action" msgid="8322172381028546087">"Explorar"</string> + <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ausente"</string> + <string name="ext_media_missing_message" msgid="5761133583368750174">"Reinserir este dispositivo"</string> + <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Movendo <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_title" msgid="1022809140035962662">"Movendo dados"</string> + <string name="ext_media_move_success_title" msgid="8575300932957954671">"Transferência concluída"</string> + <string name="ext_media_move_success_message" msgid="4199002148206265426">"Dados movidos para <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Não foi possível mover os dados"</string> + <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Dados deixados no local original"</string> + <string name="ext_media_status_removed" msgid="6576172423185918739">"Removida"</string> + <string name="ext_media_status_unmounted" msgid="2551560878416417752">"Ejetada"</string> + <string name="ext_media_status_checking" msgid="6193921557423194949">"Verificando..."</string> + <string name="ext_media_status_mounted" msgid="7253821726503179202">"Pronto"</string> + <string name="ext_media_status_mounted_ro" msgid="8020978752406021015">"Somente leitura"</string> + <string name="ext_media_status_bad_removal" msgid="8395398567890329422">"Removido de forma não segura"</string> + <string name="ext_media_status_unmountable" msgid="805594039236667894">"Corrompida"</string> + <string name="ext_media_status_unsupported" msgid="4691436711745681828">"Incompatível"</string> + <string name="ext_media_status_ejecting" msgid="5463887263101234174">"Ejetando…"</string> + <string name="ext_media_status_formatting" msgid="1085079556538644861">"Formatando..."</string> + <string name="ext_media_status_missing" msgid="5638633895221670766">"Não inserida"</string> + <string name="activity_list_empty" msgid="1675388330786841066">"Nenhum atividade correspondente foi encontrada."</string> + <string name="permlab_route_media_output" msgid="1642024455750414694">"Rotear saída de mídia"</string> + <string name="permdesc_route_media_output" msgid="4932818749547244346">"Permite que um app faça o roteamento de saída de mídia para outros dispositivos externos."</string> + <string name="permlab_readInstallSessions" msgid="6165432407628065939">"Ler sessões de instalação"</string> + <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"Permite que um app leia sessões de instalação. Isso permite que ele veja detalhes sobre as instalações de pacote ativas."</string> + <string name="permlab_requestInstallPackages" msgid="1772330282283082214">"Solicitar instalação de pacotes"</string> + <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Permite que um app solicite a instalação de pacotes."</string> + <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Toque duas vezes para controlar o zoom"</string> + <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Não foi possível adicionar widget."</string> + <string name="ime_action_go" msgid="8320845651737369027">"Ir"</string> + <string name="ime_action_search" msgid="658110271822807811">"Pesquisar"</string> + <string name="ime_action_send" msgid="2316166556349314424">"Enviar"</string> + <string name="ime_action_next" msgid="3138843904009813834">"Avançar"</string> + <string name="ime_action_done" msgid="8971516117910934605">"Concluído"</string> + <string name="ime_action_previous" msgid="1443550039250105948">"Anter."</string> + <string name="ime_action_default" msgid="2840921885558045721">"Executar"</string> + <string name="dial_number_using" msgid="5789176425167573586">"Discar número\nusando <xliff:g id="NUMBER">%s</xliff:g>"</string> + <string name="create_contact_using" msgid="4947405226788104538">"Criar contato \nusando <xliff:g id="NUMBER">%s</xliff:g>"</string> + <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"O app a seguir ou outros apps solicitam permissão para acessar sua conta, agora e no futuro."</string> + <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Deseja permitir essa solicitação?"</string> + <string name="grant_permissions_header_text" msgid="6874497408201826708">"Solicitação de acesso"</string> + <string name="allow" msgid="7225948811296386551">"Permitir"</string> + <string name="deny" msgid="2081879885755434506">"Negar"</string> + <string name="permission_request_notification_title" msgid="6486759795926237907">"Permissão solicitada"</string> + <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Permissão solicitada\npara a conta <xliff:g id="ACCOUNT">%s</xliff:g>."</string> + <string name="forward_intent_to_owner" msgid="1207197447013960896">"Este app está sendo usado fora de seu perfil de trabalho"</string> + <string name="forward_intent_to_work" msgid="621480743856004612">"Você está usando este app em seu perfil de trabalho"</string> + <string name="input_method_binding_label" msgid="1283557179944992649">"Método de entrada"</string> + <string name="sync_binding_label" msgid="3687969138375092423">"Sincronizar"</string> + <string name="accessibility_binding_label" msgid="4148120742096474641">"Acessibilidade"</string> + <string name="wallpaper_binding_label" msgid="1240087844304687662">"Plano de fundo"</string> + <string name="chooser_wallpaper" msgid="7873476199295190279">"Alterar plano de fundo"</string> + <string name="notification_listener_binding_label" msgid="2014162835481906429">"Ouvinte de notificações"</string> + <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Provedor de condições"</string> + <string name="vpn_title" msgid="19615213552042827">"VPN ativada"</string> + <string name="vpn_title_long" msgid="6400714798049252294">"A VPN está ativada por <xliff:g id="APP">%s</xliff:g>"</string> + <string name="vpn_text" msgid="3011306607126450322">"Toque para gerenciar a rede."</string> + <string name="vpn_text_long" msgid="6407351006249174473">"Conectado a <xliff:g id="SESSION">%s</xliff:g>. Toque para gerenciar a rede."</string> + <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"VPN sempre ativa conectando..."</string> + <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN sempre ativa conectada"</string> + <string name="vpn_lockdown_error" msgid="6009249814034708175">"Erro na VPN sempre ativa"</string> + <string name="vpn_lockdown_config" msgid="6415899150671537970">"Toque para configurar"</string> + <string name="upload_file" msgid="2897957172366730416">"Escolher arquivo"</string> + <string name="no_file_chosen" msgid="6363648562170759465">"Nenhum arquivo escolhido"</string> + <string name="reset" msgid="2448168080964209908">"Redefinir"</string> + <string name="submit" msgid="1602335572089911941">"Enviar"</string> + <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Modo carro ativado"</string> + <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Toque para sair do modo Carro."</string> + <string name="tethered_notification_title" msgid="3146694234398202601">"Vínculo ou ponto de acesso ativo"</string> + <string name="tethered_notification_message" msgid="6857031760103062982">"Toque para configurar."</string> + <string name="back_button_label" msgid="2300470004503343439">"Voltar"</string> + <string name="next_button_label" msgid="1080555104677992408">"Avançar"</string> + <string name="skip_button_label" msgid="1275362299471631819">"Ignorar"</string> + <string name="no_matches" msgid="8129421908915840737">"Não encontrado"</string> + <string name="find_on_page" msgid="1946799233822820384">"Localizar na página"</string> + <plurals name="matches_found" formatted="false" msgid="1210884353962081884"> + <item quantity="one"><xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g></item> + <item quantity="other"><xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g></item> + </plurals> + <string name="action_mode_done" msgid="7217581640461922289">"Concluído"</string> + <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Apagando o armazenamento USB..."</string> + <string name="progress_erasing" product="default" msgid="6596988875507043042">"Apagando cartão SD..."</string> + <string name="share" msgid="1778686618230011964">"Compartilhar"</string> + <string name="find" msgid="4808270900322985960">"Localizar"</string> + <string name="websearch" msgid="4337157977400211589">"Pesquisa na web do Google"</string> + <string name="find_next" msgid="5742124618942193978">"Localizar próximo"</string> + <string name="find_previous" msgid="2196723669388360506">"Localizar anterior"</string> + <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitação de local de <xliff:g id="NAME">%s</xliff:g>"</string> + <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitação de local"</string> + <string name="gpsNotifMessage" msgid="1374718023224000702">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string> + <string name="gpsVerifYes" msgid="2346566072867213563">"Sim"</string> + <string name="gpsVerifNo" msgid="1146564937346454865">"Não"</string> + <string name="sync_too_many_deletes" msgid="5296321850662746890">"Limite de exclusão excedido"</string> + <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Há <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> itens excluídos para <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, conta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. O que você deseja fazer?"</string> + <string name="sync_really_delete" msgid="2572600103122596243">"Excluir os itens"</string> + <string name="sync_undo_deletes" msgid="2941317360600338602">"Desfazer as exclusões"</string> + <string name="sync_do_nothing" msgid="3743764740430821845">"Não fazer nada por enquanto"</string> + <string name="choose_account_label" msgid="5655203089746423927">"Escolha uma conta"</string> + <string name="add_account_label" msgid="2935267344849993553">"Adicionar uma conta"</string> + <string name="add_account_button_label" msgid="3611982894853435874">"Adicionar conta"</string> + <string name="number_picker_increment_button" msgid="2412072272832284313">"Aumentar"</string> + <string name="number_picker_decrement_button" msgid="476050778386779067">"Diminuir"</string> + <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> toque e mantenha pressionado."</string> + <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Deslize para cima para aumentar e para baixo para diminuir."</string> + <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Aumentar minuto"</string> + <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Diminuir minuto"</string> + <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Aumentar hora"</string> + <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Diminuir hora"</string> + <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Configurar valor PM"</string> + <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Configurar valor AM"</string> + <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Aumentar mês"</string> + <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Diminuir mês"</string> + <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Aumentar dia"</string> + <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Diminuir dia"</string> + <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Aumentar ano"</string> + <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Diminuir ano"</string> + <string name="date_picker_prev_month_button" msgid="2858244643992056505">"Mês passado"</string> + <string name="date_picker_next_month_button" msgid="5559507736887605055">"Próximo mês"</string> + <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string> + <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Cancelar"</string> + <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Excluir"</string> + <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Concluído"</string> + <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Alteração do modo"</string> + <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string> + <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string> + <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Selecione um app"</string> + <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Não foi possível iniciar o <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> + <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartilhar com"</string> + <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string> + <string name="content_description_sliding_handle" msgid="415975056159262248">"Recurso deslizante. Toque e segure."</string> + <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Deslize para desbloquear."</string> + <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conecte um fone de ouvido para ouvir as teclas da senha."</string> + <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Ponto final."</string> + <string name="action_bar_home_description" msgid="5293600496601490216">"Navegar na página inicial"</string> + <string name="action_bar_up_description" msgid="2237496562952152589">"Navegar para cima"</string> + <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string> + <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string> + <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string> + <string name="storage_internal" msgid="4891916833657929263">"Armazenamento interno"</string> + <string name="storage_sd_card" msgid="3282948861378286745">"Cartão SD"</string> + <string name="storage_sd_card_label" msgid="6347111320774379257">"Cartão SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string> + <string name="storage_usb_drive" msgid="6261899683292244209">"Drive USB"</string> + <string name="storage_usb_drive_label" msgid="4501418548927759953">"Drive USB <xliff:g id="MANUFACTURER">%s</xliff:g>"</string> + <string name="storage_usb" msgid="3017954059538517278">"Armazenamento USB"</string> + <string name="data_usage_warning_title" msgid="1955638862122232342">"Aviso sobre uso de dados"</string> + <string name="data_usage_warning_body" msgid="2814673551471969954">"Toque p/ ver uso e config."</string> + <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Limite de dados 2G-3G atingido"</string> + <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Limite de dados 4G atingido"</string> + <string name="data_usage_mobile_limit_title" msgid="557158376602636112">"Limite de dados celular atingido"</string> + <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Limite de dados Wi-Fi atingido"</string> + <string name="data_usage_limit_body" msgid="291731708279614081">"Dados pausados no resto do ciclo"</string> + <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Limite de dados 2G-3G excedido"</string> + <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Limite de dados 4G excedido"</string> + <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Lim. de dados rede cel. excedido"</string> + <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Limite de dados Wi-Fi excedido"</string> + <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> acima do limite especificado."</string> + <string name="data_usage_restricted_title" msgid="5965157361036321914">"Dados de segundo plano restritos"</string> + <string name="data_usage_restricted_body" msgid="6741521330997452990">"Toque para remover a restrição."</string> + <string name="ssl_certificate" msgid="6510040486049237639">"Certificado de segurança"</string> + <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Este certificado é válido."</string> + <string name="issued_to" msgid="454239480274921032">"Emitido para:"</string> + <string name="common_name" msgid="2233209299434172646">"Nome comum:"</string> + <string name="org_name" msgid="6973561190762085236">"Organização:"</string> + <string name="org_unit" msgid="7265981890422070383">"Unidade organizacional:"</string> + <string name="issued_by" msgid="2647584988057481566">"Emitido por:"</string> + <string name="validity_period" msgid="8818886137545983110">"Validade:"</string> + <string name="issued_on" msgid="5895017404361397232">"Emitido em:"</string> + <string name="expires_on" msgid="3676242949915959821">"Expira em:"</string> + <string name="serial_number" msgid="758814067660862493">"Número de série:"</string> + <string name="fingerprints" msgid="4516019619850763049">"Impressões digitais"</string> + <string name="sha256_fingerprint" msgid="4391271286477279263">"Impressão digital SHA-256"</string> + <string name="sha1_fingerprint" msgid="7930330235269404581">"Impressão digital SHA-1"</string> + <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Ver tudo"</string> + <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Selecione a atividade"</string> + <string name="share_action_provider_share_with" msgid="5247684435979149216">"Compartilhar com"</string> + <string name="list_delimeter" msgid="3975117572185494152">", "</string> + <string name="sending" msgid="3245653681008218030">"Enviando..."</string> + <string name="launchBrowserDefault" msgid="2057951947297614725">"Abrir Navegador?"</string> + <string name="SetupCallDefault" msgid="5834948469253758575">"Aceitar chamada?"</string> + <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string> + <string name="activity_resolver_use_once" msgid="2404644797149173758">"Só uma vez"</string> + <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s não aceita perfis de trabalho"</string> + <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string> + <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string> + <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefone"</string> + <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Fones de ouvido"</string> + <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes da dock"</string> + <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string> + <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string> + <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string> + <string name="wireless_display_route_description" msgid="9070346425023979651">"Display sem fio"</string> + <string name="media_route_button_content_description" msgid="591703006349356016">"Transmitir"</string> + <string name="media_route_chooser_title" msgid="1751618554539087622">"Conectar ao dispositivo"</string> + <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Transmitir tela para dispositivo"</string> + <string name="media_route_chooser_searching" msgid="4776236202610828706">"Procurando dispositivos…"</string> + <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Configurações"</string> + <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Desconectar"</string> + <string name="media_route_status_scanning" msgid="7279908761758293783">"Verificando..."</string> + <string name="media_route_status_connecting" msgid="6422571716007825440">"Conectando..."</string> + <string name="media_route_status_available" msgid="6983258067194649391">"Disponível"</string> + <string name="media_route_status_not_available" msgid="6739899962681886401">"Não disponível"</string> + <string name="media_route_status_in_use" msgid="4533786031090198063">"Em uso"</string> + <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Tela integrada"</string> + <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Tela HDMI"</string> + <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Sobreposição nº <xliff:g id="ID">%1$d</xliff:g>"</string> + <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string> + <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", seguro"</string> + <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueci o padrão"</string> + <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão incorreto"</string> + <string name="kg_wrong_password" msgid="2333281762128113157">"Senha incorreta"</string> + <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN incorreto"</string> + <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Tente novamente em <xliff:g id="NUMBER">%1$d</xliff:g> segundos."</string> + <string name="kg_pattern_instructions" msgid="398978611683075868">"Desenhe seu padrão"</string> + <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Digite o PIN do cartão SIM"</string> + <string name="kg_pin_instructions" msgid="2377242233495111557">"Digite o PIN"</string> + <string name="kg_password_instructions" msgid="5753646556186936819">"Digite a senha"</string> + <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"O SIM foi desativado. Insira o código PUK para continuar. Entre em contato com a operadora para obter mais detalhes."</string> + <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Digite o código PIN desejado"</string> + <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirme o código PIN desejado"</string> + <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando o cartão SIM…"</string> + <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorreto."</string> + <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Digite um PIN com quatro a oito números."</string> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"O código PUK deve ter oito números."</string> + <string name="kg_invalid_puk" msgid="3638289409676051243">"Introduza novamente o código PUK correto. Muitas tentativas malsucedidas desativarão permanentemente o SIM."</string> + <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Os códigos PIN não coincidem"</string> + <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Muitas tentativas de padrão"</string> + <string name="kg_login_instructions" msgid="1100551261265506448">"Para desbloquear, faça login usando sua Conta do Google."</string> + <string name="kg_login_username_hint" msgid="5718534272070920364">"Nome de usuário (e-mail)"</string> + <string name="kg_login_password_hint" msgid="9057289103827298549">"Senha"</string> + <string name="kg_login_submit_button" msgid="5355904582674054702">"Fazer login"</string> + <string name="kg_login_invalid_input" msgid="5754664119319872197">"Nome de usuário ou senha inválidos."</string> + <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Esqueceu seu nome de usuário ou senha?\nAcesse "<b>"google.com.br/accounts/recovery"</b>"."</string> + <string name="kg_login_checking_password" msgid="1052685197710252395">"Verificando a conta..."</string> + <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Você digitou seu PIN incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string> + <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Você digitou sua senha incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string> + <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. \n\nTente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string> + <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o tablet será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string> + <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, a TV será redefinida para os padrões de fábrica e todos os dados do usuário serão perdidos."</string> + <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas malsucedidas, o telefone será redefinido para o padrão de fábrica e todos os dados do usuário serão perdidos."</string> + <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Você tentou desbloquear incorretamente o tablet <xliff:g id="NUMBER">%d</xliff:g> vezes. O tablet será redefinido para o padrão de fábrica."</string> + <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Você tentou desbloquear a TV de forma incorreta <xliff:g id="NUMBER">%d</xliff:g> vezes. A TV será redefinida agora para os padrões de fábrica."</string> + <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Você tentou desbloquear incorretamente o telefone <xliff:g id="NUMBER">%d</xliff:g> vezes. O telefone será redefinido para o padrão de fábrica."</string> + <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> + <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, será pedido que você desbloqueie sua TV usando uma conta de e-mail.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> + <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear.\n\n Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string> + <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string> + <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Remover"</string> + <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Aumentar o volume acima do nível recomendado?\n\nOuvir em volume alto por longos períodos pode danificar sua audição."</string> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantenha pressionado com dois dedos para ativar a acessibilidade."</string> + <string name="accessibility_enabled" msgid="1381972048564547685">"Acessibilidade ativada."</string> + <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Acessibilidade cancelada."</string> + <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string> + <string name="user_switching_message" msgid="2871009331809089783">"Alternando para <xliff:g id="NAME">%1$s</xliff:g>…"</string> + <string name="owner_name" msgid="2716755460376028154">"Proprietário"</string> + <string name="error_message_title" msgid="4510373083082500195">"Erro"</string> + <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Esta alteração não é permitida pelo administrador"</string> + <string name="app_not_found" msgid="3429141853498927379">"Nenhum app encontrado para executar a ação"</string> + <string name="revoke" msgid="5404479185228271586">"Revogar"</string> + <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string> + <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string> + <string name="mediasize_iso_a2" msgid="3097535991925798280">"ISO A2"</string> + <string name="mediasize_iso_a3" msgid="3023213259314236123">"ISO A3"</string> + <string name="mediasize_iso_a4" msgid="231745325296873764">"ISO A4"</string> + <string name="mediasize_iso_a5" msgid="3484327407340865411">"ISO A5"</string> + <string name="mediasize_iso_a6" msgid="4861908487129577530">"ISO A6"</string> + <string name="mediasize_iso_a7" msgid="5890208588072936130">"ISO A7"</string> + <string name="mediasize_iso_a8" msgid="4319425041085816612">"ISO A8"</string> + <string name="mediasize_iso_a9" msgid="4882220529506432008">"ISO A9"</string> + <string name="mediasize_iso_a10" msgid="2382866026365359391">"ISO A10"</string> + <string name="mediasize_iso_b0" msgid="3651827147402009675">"ISO B0"</string> + <string name="mediasize_iso_b1" msgid="6072859628278739957">"ISO B1"</string> + <string name="mediasize_iso_b2" msgid="1348731852150380378">"ISO B2"</string> + <string name="mediasize_iso_b3" msgid="2612510181259261379">"ISO B3"</string> + <string name="mediasize_iso_b4" msgid="695151378838115434">"ISO B4"</string> + <string name="mediasize_iso_b5" msgid="4863754285582212487">"ISO B5"</string> + <string name="mediasize_iso_b6" msgid="5305816292139647241">"ISO B6"</string> + <string name="mediasize_iso_b7" msgid="531673542602786624">"ISO B7"</string> + <string name="mediasize_iso_b8" msgid="9164474595708850034">"ISO B8"</string> + <string name="mediasize_iso_b9" msgid="282102976764774160">"ISO B9"</string> + <string name="mediasize_iso_b10" msgid="4517141714407898976">"ISO B10"</string> + <string name="mediasize_iso_c0" msgid="3103521357901591100">"ISO C0"</string> + <string name="mediasize_iso_c1" msgid="1231954105985048595">"ISO C1"</string> + <string name="mediasize_iso_c2" msgid="927702816980087462">"ISO C2"</string> + <string name="mediasize_iso_c3" msgid="835154173518304159">"ISO C3"</string> + <string name="mediasize_iso_c4" msgid="5095951985108194011">"ISO C4"</string> + <string name="mediasize_iso_c5" msgid="1985397450332305739">"ISO C5"</string> + <string name="mediasize_iso_c6" msgid="8147421924174693013">"ISO C6"</string> + <string name="mediasize_iso_c7" msgid="8993994925276122950">"ISO C7"</string> + <string name="mediasize_iso_c8" msgid="6871178104139598957">"ISO C8"</string> + <string name="mediasize_iso_c9" msgid="7983532635227561362">"ISO C9"</string> + <string name="mediasize_iso_c10" msgid="5040764293406765584">"ISO C10"</string> + <string name="mediasize_na_letter" msgid="2841414839888344296">"Carta"</string> + <string name="mediasize_na_gvrnmt_letter" msgid="5295836838862962809">"Government Letter"</string> + <string name="mediasize_na_legal" msgid="8621364037680465666">"Ofício"</string> + <string name="mediasize_na_junior_legal" msgid="3309324162155085904">"Junior Legal"</string> + <string name="mediasize_na_ledger" msgid="5567030340509075333">"Ledger"</string> + <string name="mediasize_na_tabloid" msgid="4571735038501661757">"Tabloide"</string> + <string name="mediasize_na_index_3x5" msgid="5182901917818625126">"Index Card 3x5"</string> + <string name="mediasize_na_index_4x6" msgid="7687620625422312396">"Index Card 4x6"</string> + <string name="mediasize_na_index_5x8" msgid="8834215284646872800">"Index Card 5x8"</string> + <string name="mediasize_na_monarch" msgid="213639906956550754">"Monarch"</string> + <string name="mediasize_na_quarto" msgid="835778493593023223">"Quarto"</string> + <string name="mediasize_na_foolscap" msgid="1573911237983677138">"Foolscap"</string> + <string name="mediasize_chinese_roc_8k" msgid="3626855847189438896">"ROC 8K"</string> + <string name="mediasize_chinese_roc_16k" msgid="9182191577022943355">"ROC 16K"</string> + <string name="mediasize_chinese_prc_1" msgid="4793232644980170500">"PRC 1"</string> + <string name="mediasize_chinese_prc_2" msgid="5404109730975720670">"PRC 2"</string> + <string name="mediasize_chinese_prc_3" msgid="1335092253339363526">"PRC 3"</string> + <string name="mediasize_chinese_prc_4" msgid="9167997800486569834">"PRC 4"</string> + <string name="mediasize_chinese_prc_5" msgid="845875168823541497">"PRC 5"</string> + <string name="mediasize_chinese_prc_6" msgid="3220325667692648789">"PRC 6"</string> + <string name="mediasize_chinese_prc_7" msgid="1776792138507038527">"PRC 7"</string> + <string name="mediasize_chinese_prc_8" msgid="1417176642687456692">"PRC 8"</string> + <string name="mediasize_chinese_prc_9" msgid="4785983473123798365">"PRC 9"</string> + <string name="mediasize_chinese_prc_10" msgid="7847982299391851899">"PRC 10"</string> + <string name="mediasize_chinese_prc_16k" msgid="262793383539980677">"PRC 16K"</string> + <string name="mediasize_chinese_om_pa_kai" msgid="5256815579447959814">"Pa Kai"</string> + <string name="mediasize_chinese_om_dai_pa_kai" msgid="7336412963441354407">"Dai Pa Kai"</string> + <string name="mediasize_chinese_om_jurro_ku_kai" msgid="6324465444100490742">"Jurro Ku Kai"</string> + <string name="mediasize_japanese_jis_b10" msgid="1787262845627694376">"JIS B10"</string> + <string name="mediasize_japanese_jis_b9" msgid="3336035783663287470">"JIS B9"</string> + <string name="mediasize_japanese_jis_b8" msgid="6195398299104345731">"JIS B8"</string> + <string name="mediasize_japanese_jis_b7" msgid="1674621886902828884">"JIS B7"</string> + <string name="mediasize_japanese_jis_b6" msgid="4170576286062657435">"JIS B6"</string> + <string name="mediasize_japanese_jis_b5" msgid="4899297958100032533">"JIS B5"</string> + <string name="mediasize_japanese_jis_b4" msgid="4213158129126666847">"JIS B4"</string> + <string name="mediasize_japanese_jis_b3" msgid="8513715307410310696">"JIS B3"</string> + <string name="mediasize_japanese_jis_b2" msgid="4777690211897131190">"JIS B2"</string> + <string name="mediasize_japanese_jis_b1" msgid="4608142385457034603">"JIS B1"</string> + <string name="mediasize_japanese_jis_b0" msgid="7587108366572243991">"JIS B0"</string> + <string name="mediasize_japanese_jis_exec" msgid="5244075432263649068">"JIS Exec"</string> + <string name="mediasize_japanese_chou4" msgid="4941652015032631361">"Chou4"</string> + <string name="mediasize_japanese_chou3" msgid="6387319169263957010">"Chou3"</string> + <string name="mediasize_japanese_chou2" msgid="1299112025415343982">"Chou2"</string> + <string name="mediasize_japanese_hagaki" msgid="8070115620644254565">"Hagaki"</string> + <string name="mediasize_japanese_oufuku" msgid="6049065587307896564">"Oufuku"</string> + <string name="mediasize_japanese_kahu" msgid="6872696027560065173">"Kahu"</string> + <string name="mediasize_japanese_kaku2" msgid="2359077233775455405">"Kaku2"</string> + <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string> + <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"Retrato desconhecido"</string> + <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"Paisagem desconhecido"</string> + <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelado"</string> + <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erro ao gravar o conteúdo"</string> + <string name="reason_unknown" msgid="6048913880184628119">"desconhecido"</string> + <string name="reason_service_unavailable" msgid="7824008732243903268">"Serviço de impressão não ativado"</string> + <string name="print_service_installed_title" msgid="2246317169444081628">"Serviço <xliff:g id="NAME">%s</xliff:g> instalado"</string> + <string name="print_service_installed_message" msgid="5897362931070459152">"Toque para ativar"</string> + <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Inserir PIN do administrador"</string> + <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Insira o PIN"</string> + <string name="restr_pin_incorrect" msgid="8571512003955077924">"Incorreto"</string> + <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN atual"</string> + <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novo PIN"</string> + <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Confirme o novo PIN"</string> + <string name="restr_pin_create_pin" msgid="8017600000263450337">"Crie um PIN para modificar restrições"</string> + <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"Os PINs não coincidem. Tente novamente."</string> + <string name="restr_pin_error_too_short" msgid="8173982756265777792">"O PIN é curto demais. Deve ter pelo menos 4 dígitos."</string> + <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688"> + <item quantity="one">Tente novamente em <xliff:g id="COUNT">%d</xliff:g> segundos</item> + <item quantity="other">Tente novamente em <xliff:g id="COUNT">%d</xliff:g> segundos</item> + </plurals> + <string name="restr_pin_try_later" msgid="973144472490532377">"Tente novamente mais tarde"</string> + <string name="immersive_cling_title" msgid="8394201622932303336">"Visualização em tela cheia"</string> + <string name="immersive_cling_description" msgid="3482371193207536040">"Para sair, deslize de cima para baixo."</string> + <string name="immersive_cling_positive" msgid="5016839404568297683">"Entendi"</string> + <string name="done_label" msgid="2093726099505892398">"Concluído"</string> + <string name="hour_picker_description" msgid="6698199186859736512">"Controle deslizante circular das horas"</string> + <string name="minute_picker_description" msgid="8606010966873791190">"Controle deslizante circular dos minutos"</string> + <string name="select_hours" msgid="6043079511766008245">"Selecione as horas"</string> + <string name="select_minutes" msgid="3974345615920336087">"Selecione os minutos"</string> + <string name="select_day" msgid="7774759604701773332">"Selecione o mês e o dia"</string> + <string name="select_year" msgid="7952052866994196170">"Selecione o ano"</string> + <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> excluído"</string> + <string name="managed_profile_label_badge" msgid="2355652472854327647">"Trabalho: <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Para liberar esta tela, toque e mantenha pressionados \"Voltar\" e \"Visão geral\" ao mesmo tempo."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Para liberar esta tela, toque e mantenha pressionado \"Visão geral\"."</string> + <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"O app está fixado. A liberação não é permitida neste dispositivo."</string> + <string name="lock_to_app_start" msgid="6643342070839862795">"Tela fixada"</string> + <string name="lock_to_app_exit" msgid="8598219838213787430">"Tela liberada"</string> + <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pedir PIN antes de liberar"</string> + <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pedir padrão de desbloqueio antes de liberar"</string> + <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pedir senha antes de liberar"</string> + <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalado pelo seu administrador"</string> + <string name="package_updated_device_owner" msgid="8856631322440187071">"Atualizado pelo administrador"</string> + <string name="package_deleted_device_owner" msgid="7650577387493101353">"Excluído pelo seu administrador"</string> + <string name="battery_saver_description" msgid="1960431123816253034">"Para ajudar a melhorar a duração da bateria, o economizador de bateria reduz o desempenho e os limites de vibração do dispositivo, os serviços de localização e a maioria dos dados de segundo plano. E-mail, mensagens e outros aplicativos que dependem de sincronização não podem ser atualizados, a não ser que você os abra.\n\nO economizador de bateria é desligado automaticamente quando o dispositivo está sendo carregado."</string> + <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> + <item quantity="one">Por %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="other">Por %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + </plurals> + <plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="6830154222366042597"> + <item quantity="one">Por %1$d min (até <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="other">Por %1$d min (até <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + </plurals> + <plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862"> + <item quantity="one">Por %1$d horas (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="other">Por %1$d horas (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + </plurals> + <plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="4787552595253082371"> + <item quantity="one">Por %1$d horas (até <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + <item quantity="other">Por %1$d horas (até <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> + </plurals> + <plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571"> + <item quantity="one">Por %d minutos</item> + <item quantity="other">Por %d minutos</item> + </plurals> + <plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2199350154433426128"> + <item quantity="one">Por %d min</item> + <item quantity="other">Por %d min</item> + </plurals> + <plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854"> + <item quantity="one">Por %d horas</item> + <item quantity="other">Por %d horas</item> + </plurals> + <plurals name="zen_mode_duration_hours_short" formatted="false" msgid="6748277774662434217"> + <item quantity="one">Por %d horas</item> + <item quantity="other">Por %d horas</item> + </plurals> + <string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> + <string name="zen_mode_forever" msgid="7420011936770086993">"Até você desativar"</string> + <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Até que você desative \"Não perturbe\""</string> + <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> + <string name="toolbar_collapse_description" msgid="2821479483960330739">"Recolher"</string> + <string name="zen_mode_feature_name" msgid="5254089399895895004">"Não perturbe"</string> + <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Tempo de inatividade"</string> + <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Durante a semana à noite"</string> + <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Fim de semana"</string> + <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Evento"</string> + <string name="muted_by" msgid="6147073845094180001">"Som desativado por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string> + <string name="system_error_wipe_data" msgid="6608165524785354962">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string> + <string name="system_error_manufacturer" msgid="8086872414744210668">"Há um problema interno com seu dispositivo. Entre em contato com o fabricante para saber mais detalhes."</string> + <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"A solicitação USSD foi modificada para a solicitação DIAL."</string> + <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"A solicitação USSD foi modificada para a solicitação SS."</string> + <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"A solicitação USSD foi modificada para a nova solicitação USSD."</string> + <string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"A solicitação SS foi modificada para a solicitação DIAL."</string> + <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"A solicitação SS foi modificada para a solicitação USSD."</string> + <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"A solicitação SS foi modificada para a nova solicitação SS."</string> + <string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabalho"</string> + <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Porta USB periférica Android"</string> + <string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string> + <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Porta USB periférica"</string> + <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Mais opções"</string> + <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Fechar barra flutuante"</string> + <plurals name="selected_count" formatted="false" msgid="7187339492915744615"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> + </plurals> +</resources> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 659d31d6cc3b..ff41c14be627 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ícone de impressão digital"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler definições de sincronização"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite que a aplicação leia as definições de sincronização de uma conta. Por exemplo, pode determinar se a aplicação Pessoas está sincronizada com uma conta."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ativar e desativar a sincronização"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Célula adicionada"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Célula <xliff:g id="CELL_INDEX">%1$s</xliff:g> adicionada"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Sequência concluída"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Área da sequência."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adicionar widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vazio"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 9e8bb892f748..4972ce97e8f8 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -229,17 +229,17 @@ <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="permgroupdesc_location" msgid="1346617465127855033">"acesse o local do dispositivo"</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="permgroupdesc_storage" msgid="637758554581589203">"acesse fotos, mídia e arquivos do seu dispositivo"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"Microfone"</string> - <string name="permgroupdesc_microphone" msgid="4988812113943554584">"gravar áudio"</string> + <string name="permgroupdesc_microphone" msgid="4988812113943554584">"grave á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="permgroupdesc_camera" msgid="3250611594678347720">"tire fotos e grave 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="416037179223226722">"Sensores corporais"</string> @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ícone de impressão digital"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler as configurações de sincronização"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite que o app leia as configurações de sincronização de uma conta. Por exemplo, pode determinar se o app People está sincronizado com uma conta."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ativar e desativar sincronização"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Célula adicionada"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Célula <xliff:g id="CELL_INDEX">%1$s</xliff:g> adicionada"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Padrão concluído"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Área do padrão."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adicionar widget"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Vazio"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 7ea0e531e635..9eaf6d6400a1 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -181,10 +181,10 @@ <string name="power_dialog" product="tv" msgid="6153888706430556356">"Opțiuni TV"</string> <string name="power_dialog" product="default" msgid="1319919075463988638">"Opţiuni telefon"</string> <string name="silent_mode" msgid="7167703389802618663">"Mod Silenţios"</string> - <string name="turn_on_radio" msgid="3912793092339962371">"Activaţi funcţia wireless"</string> + <string name="turn_on_radio" msgid="3912793092339962371">"Activați funcţia wireless"</string> <string name="turn_off_radio" msgid="8198784949987062346">"Dezactivaţi funcţia wireless"</string> - <string name="screen_lock" msgid="799094655496098153">"Blocaţi ecranul"</string> - <string name="power_off" msgid="4266614107412865048">"Opriţi alimentarea"</string> + <string name="screen_lock" msgid="799094655496098153">"Blocați ecranul"</string> + <string name="power_off" msgid="4266614107412865048">"Opriți alimentarea"</string> <string name="silent_mode_silent" msgid="319298163018473078">"Sonerie dezactivată"</string> <string name="silent_mode_vibrate" msgid="7072043388581551395">"Vibrare sonerie"</string> <string name="silent_mode_ring" msgid="8592241816194074353">"Sonerie activată"</string> @@ -207,8 +207,8 @@ <string name="global_actions" product="tablet" msgid="408477140088053665">"Opţiuni tablet PC"</string> <string name="global_actions" product="tv" msgid="7240386462508182976">"Opțiuni TV"</string> <string name="global_actions" product="default" msgid="2406416831541615258">"Opţiuni telefon"</string> - <string name="global_action_lock" msgid="2844945191792119712">"Blocaţi ecranul"</string> - <string name="global_action_power_off" msgid="4471879440839879722">"Opriţi alimentarea"</string> + <string name="global_action_lock" msgid="2844945191792119712">"Blocați ecranul"</string> + <string name="global_action_power_off" msgid="4471879440839879722">"Opriți alimentarea"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"Raport despre erori"</string> <string name="bugreport_title" msgid="2667494803742548533">"Executaţi un raport despre erori"</string> <string name="bugreport_message" msgid="398447048750350456">"Acest raport va colecta informaţii despre starea actuală a dispozitivului, pentru a le trimite într-un e-mail. Aveți răbdare după pornirea raportului despre erori până când va fi gata de trimis."</string> @@ -228,21 +228,21 @@ <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="permgroupdesc_contacts" msgid="6951499528303668046">"acceseze 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="permgroupdesc_location" msgid="1346617465127855033">"acceseze locația acestui dispozitiv"</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="permgroupdesc_storage" msgid="637758554581589203">"acceseze fotografiile, conținutul media și fișierele de pe dispozitiv"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"Microfonul"</string> - <string name="permgroupdesc_microphone" msgid="4988812113943554584">"înregistrează conținut audio"</string> + <string name="permgroupdesc_microphone" msgid="4988812113943554584">"înregistreze 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="permgroupdesc_camera" msgid="3250611594678347720">"fotografieze și să înregistreze 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="permgroupdesc_phone" msgid="6234224354060641055">"inițieze și să gestioneze apeluri telefonice"</string> <string name="permgrouplab_sensors" msgid="416037179223226722">"Senzori corporali"</string> <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> @@ -435,6 +435,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Pictograma amprentă"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"citire setări sincronizare"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permite aplicației să citească setările de sincronizare ale unui cont. De exemplu, cu această permisiune aplicația poate determina dacă aplicația Persoane este sincronizată cu un anumit cont."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activează/dezactivează sincronizarea"</string> @@ -495,19 +496,19 @@ <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Permite aplicației să se conecteze la serviciile operatorului. Nu ar trebui să fie niciodată necesară pentru aplicațiile obișnuite."</string> <string name="permlab_access_notification_policy" msgid="4247510821662059671">"accesează Nu deranja"</string> <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite aplicației să citească și să scrie configurația Nu deranja."</string> - <string name="policylab_limitPassword" msgid="4497420728857585791">"Setaţi reguli pentru parolă"</string> + <string name="policylab_limitPassword" msgid="4497420728857585791">"Setați reguli pentru parolă"</string> <string name="policydesc_limitPassword" msgid="2502021457917874968">"Stabiliți lungimea și tipul de caractere permise pentru parolele și codurile PIN de blocare a ecranului."</string> - <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizaţi încercările de deblocare a ecranului"</string> + <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizați încercările de deblocare a ecranului"</string> <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Monitorizaţi numărul de parole incorecte introduse la deblocarea ecranului și blocaţi tableta sau ştergeţi datele acesteia dacă sunt introduse prea multe parole incorecte."</string> <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați televizorul sau ștergeți toate datele acestuia dacă sunt introduse prea multe parole incorecte."</string> - <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Monitorizaţi numărul de parole incorecte introduse la deblocarea ecranului și blocaţi telefonul sau ştergeţi toate datele acestuia dacă sunt introduse prea multe parole incorecte."</string> + <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați telefonul sau ștergeți toate datele acestuia dacă sunt introduse prea multe parole incorecte."</string> <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați tableta sau ștergeți toate datele acestui utilizator dacă se introduc prea multe parole incorecte."</string> <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați televizorul sau ștergeți toate datele acestui utilizator dacă se introduc prea multe parole incorecte."</string> <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Monitorizați numărul de parole incorecte introduse la deblocarea ecranului și blocați telefonul sau ștergeți toate datele acestui utilizator dacă se introduc prea multe parole incorecte."</string> <string name="policylab_resetPassword" msgid="4934707632423915395">"Schimbarea setărilor de blocare a ecranului"</string> <string name="policydesc_resetPassword" msgid="1278323891710619128">"Modificați blocarea ecranului."</string> - <string name="policylab_forceLock" msgid="2274085384704248431">"Blocaţi ecranul"</string> - <string name="policydesc_forceLock" msgid="1141797588403827138">"Stabiliţi modul și timpul în care se blochează ecranul."</string> + <string name="policylab_forceLock" msgid="2274085384704248431">"Blocați ecranul"</string> + <string name="policydesc_forceLock" msgid="1141797588403827138">"Stabiliți modul și timpul în care se blochează ecranul."</string> <string name="policylab_wipeData" msgid="3910545446758639713">"Ștergere integrală date"</string> <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Ștergeţi datele de pe tabletă fără avertisment, efectuând resetarea configurării din fabrică."</string> <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Ștergeți datele de pe televizor fără avertisment, prin revenirea la setările din fabrică."</string> @@ -516,14 +517,14 @@ <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Ștergeți datele acestui utilizator de pe această tabletă fără avertisment."</string> <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Ștergeți datele acestui utilizator de pe acest televizor fără avertisment."</string> <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"Ștergeți datele acestui utilizator de pe acest telefon fără avertisment."</string> - <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Setaţi serverul proxy global pentru dispozitiv"</string> + <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Setați serverul proxy global pentru dispozitiv"</string> <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Setați serverul proxy global pentru dispozitiv, care să fie utilizat cât timp politica este activă. Numai proprietarul dispozitivului poate seta serverul proxy global."</string> <string name="policylab_expirePassword" msgid="5610055012328825874">"Setați expirarea parolei pentru blocarea ecranului"</string> <string name="policydesc_expirePassword" msgid="5367525762204416046">"Modificați frecvența cu care trebuie să se schimbe parola, codul PIN sau modelul pentru blocarea ecranului."</string> - <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Setaţi criptarea stocării"</string> + <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Setați criptarea stocării"</string> <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Necesită ca datele aplicației stocate să fie criptate."</string> - <string name="policylab_disableCamera" msgid="6395301023152297826">"Dezactivaţi camerele foto"</string> - <string name="policydesc_disableCamera" msgid="2306349042834754597">"Împiedicaţi utilizarea camerelor foto de pe dispozitiv."</string> + <string name="policylab_disableCamera" msgid="6395301023152297826">"Dezactivați camerele foto"</string> + <string name="policydesc_disableCamera" msgid="2306349042834754597">"Împiedicați utilizarea camerelor foto de pe dispozitiv."</string> <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Opriți funcții de blocare ecran"</string> <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Împiedicați folosirea unor funcții de blocare a ecranului."</string> <string-array name="phoneTypes"> @@ -713,6 +714,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celulă adăugată"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Celula <xliff:g id="CELL_INDEX">%1$s</xliff:g> a fost adăugată"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Modelul a fost desenat"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zonă model."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d din %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Adăugaţi un widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Gol"</string> @@ -932,7 +934,7 @@ <string name="old_app_action" msgid="493129172238566282">"Reveniţi la <xliff:g id="OLD_APP">%1$s</xliff:g>"</string> <string name="old_app_description" msgid="2082094275580358049">"Nu porniţi aplicația nouă."</string> <string name="new_app_action" msgid="5472756926945440706">"Porniţi <xliff:g id="OLD_APP">%1$s</xliff:g>"</string> - <string name="new_app_description" msgid="1932143598371537340">"Opriţi vechea aplicație fără să salvaţi."</string> + <string name="new_app_description" msgid="1932143598371537340">"Opriți vechea aplicație fără să salvaţi."</string> <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> a depășit limita de memorie"</string> <string name="dump_heap_notification_detail" msgid="2075673362317481664">"Datele privind memoria au fost culese; atingeți pentru a trimite"</string> <string name="dump_heap_title" msgid="5864292264307651673">"Trimiteți datele privind memoria?"</string> @@ -1026,19 +1028,19 @@ <string name="usb_storage_title" msgid="5901459041398751495">"USB conectat"</string> <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"V-aţi conectat la computer prin USB. Atingeţi butonul de mai jos dacă doriţi să copiaţi fişiere de pe computer pe stocarea USB Android sau invers."</string> <string name="usb_storage_message" product="default" msgid="805351000446037811">"V-aţi conectat la computer prin USB. Atingeţi butonul de mai jos dacă doriţi să copiaţi fişiere de pe computer pe cardul SD Android sau invers."</string> - <string name="usb_storage_button_mount" msgid="1052259930369508235">"Activaţi stocarea USB"</string> + <string name="usb_storage_button_mount" msgid="1052259930369508235">"Activați stocarea USB"</string> <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"A apărut o problemă la utilizarea stocării USB pentru stocarea masivă USB."</string> <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"A apărut o problemă la utilizarea cardului SD pentru stocarea masivă USB."</string> <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB conectat"</string> <string name="usb_storage_notification_message" msgid="939822783828183763">"Atingeţi pentru a copia fişiere în/din computerul dvs."</string> - <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Dezactivaţi stocarea USB"</string> + <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Dezactivați stocarea USB"</string> <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Atingeţi pentru a dezactiva stocarea USB."</string> <string name="usb_storage_stop_title" msgid="660129851708775853">"Stocarea USB este în curs de utilizare"</string> <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Înainte de a dezactiva stocarea USB, demontaţi („extrageţi”) din computer stocarea USB Android."</string> <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Înainte de a dezactiva stocarea USB, demontaţi („extrageţi”) din computer cardul SD Android."</string> <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Dezactivaţi stocarea USB"</string> <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Problemă la dezactivarea stocării USB. Verificaţi dacă aţi demontat dispozitivul gazdă USB, apoi încercaţi din nou."</string> - <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Activaţi stocarea USB"</string> + <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Activați stocarea USB"</string> <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Dacă activaţi stocarea USB, unele aplicații pe care le utilizaţi în prezent se vor opri și pot să nu fie disponibile până când dezactivaţi stocarea USB."</string> <string name="dlg_error_title" msgid="7323658469626514207">"Operaţie USB nereuşită"</string> <string name="dlg_ok" msgid="7376953167039865701">"OK"</string> @@ -1238,7 +1240,7 @@ <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certificatul este valid."</string> <string name="issued_to" msgid="454239480274921032">"Emis către:"</string> <string name="common_name" msgid="2233209299434172646">"Nume comun:"</string> - <string name="org_name" msgid="6973561190762085236">"Organizaţie:"</string> + <string name="org_name" msgid="6973561190762085236">"Organizație:"</string> <string name="org_unit" msgid="7265981890422070383">"Unitate organizatorică:"</string> <string name="issued_by" msgid="2647584988057481566">"Emis de:"</string> <string name="validity_period" msgid="8818886137545983110">"Validitate:"</string> @@ -1254,7 +1256,7 @@ <string name="list_delimeter" msgid="3975117572185494152">", "</string> <string name="sending" msgid="3245653681008218030">"Se trimite..."</string> <string name="launchBrowserDefault" msgid="2057951947297614725">"Lansaţi browserul?"</string> - <string name="SetupCallDefault" msgid="5834948469253758575">"Acceptaţi apelul?"</string> + <string name="SetupCallDefault" msgid="5834948469253758575">"Acceptați apelul?"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"Întotdeauna"</string> <string name="activity_resolver_use_once" msgid="2404644797149173758">"Numai o dată"</string> <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s nu acceptă profilul de serviciu"</string> @@ -1294,7 +1296,7 @@ <string name="kg_password_instructions" msgid="5753646556186936819">"Introduceţi parola"</string> <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Cardul SIM este acum dezactivat. Introduceţi codul PUK pentru a continua. Contactaţi operatorul pentru mai multe detalii."</string> <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introduceţi codul PIN dorit"</string> - <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmaţi codul PIN dorit"</string> + <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmați codul PIN dorit"</string> <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Se deblochează cardul SIM..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Cod PIN incorect."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduceţi un cod PIN format din 4 până la 8 cifre."</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 519401780fe4..73e10334445a 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -436,6 +436,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Значок отпечатка пальца"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"Просмотр настроек синхронизации"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Приложение сможет просматривать настройки синхронизации аккаунта, например определять, включена ли синхронизация для приложения \"Контакты\"."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"Включение/выключение синхронизации"</string> @@ -714,6 +715,7 @@ <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_detected" msgid="4988730895554057058">"Графический ключ введен"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Область ввода графического ключа"</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Пусто"</string> @@ -1060,7 +1062,7 @@ <string name="select_input_method" msgid="8547250819326693584">"Выбор раскладки"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Выбрать раскладку"</string> <string name="show_ime" msgid="9157568568695230830">"Показать способ ввода"</string> - <string name="hardware" msgid="7517821086888990278">"Аппаратура"</string> + <string name="hardware" msgid="7517821086888990278">"Аппаратная"</string> <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Выберите раскладку клавиатуры"</string> <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Нажмите, чтобы выбрать раскладку клавиатуры."</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> @@ -1342,87 +1344,87 @@ <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Это действие запрещено администратором"</string> <string name="app_not_found" msgid="3429141853498927379">"Невозможно обработать это действие"</string> <string name="revoke" msgid="5404479185228271586">"Отменить"</string> - <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0 (841х1189 мм)"</string> - <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1 (594х841 мм)"</string> - <string name="mediasize_iso_a2" msgid="3097535991925798280">"ISO A2 (420х594 мм)"</string> - <string name="mediasize_iso_a3" msgid="3023213259314236123">"ISO A3 (297х420 мм)"</string> - <string name="mediasize_iso_a4" msgid="231745325296873764">"ISO A4 (210х297 мм)"</string> - <string name="mediasize_iso_a5" msgid="3484327407340865411">"ISO A5 (148х210 мм)"</string> - <string name="mediasize_iso_a6" msgid="4861908487129577530">"ISO A6 (105х148 мм)"</string> - <string name="mediasize_iso_a7" msgid="5890208588072936130">"ISO A7 (74х105 мм)"</string> - <string name="mediasize_iso_a8" msgid="4319425041085816612">"ISO A8 (52х74 мм)"</string> - <string name="mediasize_iso_a9" msgid="4882220529506432008">"ISO A9 (37х52 мм)"</string> - <string name="mediasize_iso_a10" msgid="2382866026365359391">"ISO A10 (26х37 мм)"</string> - <string name="mediasize_iso_b0" msgid="3651827147402009675">"ISO B0 (1000х1414 мм)"</string> - <string name="mediasize_iso_b1" msgid="6072859628278739957">"ISO B1 (707х1000 мм)"</string> - <string name="mediasize_iso_b2" msgid="1348731852150380378">"ISO B2 (500х707 мм)"</string> - <string name="mediasize_iso_b3" msgid="2612510181259261379">"ISO B3 (353х500 мм)"</string> - <string name="mediasize_iso_b4" msgid="695151378838115434">"ISO B4 (250х353 мм)"</string> - <string name="mediasize_iso_b5" msgid="4863754285582212487">"ISO B5 (176х250 мм)"</string> - <string name="mediasize_iso_b6" msgid="5305816292139647241">"ISO B6 (125х176 мм)"</string> - <string name="mediasize_iso_b7" msgid="531673542602786624">"ISO B7 (88х125 мм)"</string> - <string name="mediasize_iso_b8" msgid="9164474595708850034">"ISO B8 (62х88 мм)"</string> - <string name="mediasize_iso_b9" msgid="282102976764774160">"ISO B9 (44х62 мм)"</string> - <string name="mediasize_iso_b10" msgid="4517141714407898976">"ISO B10 (31х44 мм)"</string> - <string name="mediasize_iso_c0" msgid="3103521357901591100">"ISO C0 (917х1297 мм)"</string> - <string name="mediasize_iso_c1" msgid="1231954105985048595">"ISO C1 (648х917 мм)"</string> - <string name="mediasize_iso_c2" msgid="927702816980087462">"ISO C2 (458х648 мм)"</string> - <string name="mediasize_iso_c3" msgid="835154173518304159">"ISO C3 (324х458 мм)"</string> - <string name="mediasize_iso_c4" msgid="5095951985108194011">"ISO C4 (229х324 мм)"</string> - <string name="mediasize_iso_c5" msgid="1985397450332305739">"ISO C5 (162х229 мм)"</string> - <string name="mediasize_iso_c6" msgid="8147421924174693013">"ISO C6 (114х162 мм)"</string> - <string name="mediasize_iso_c7" msgid="8993994925276122950">"ISO C7 (81х114 мм)"</string> - <string name="mediasize_iso_c8" msgid="6871178104139598957">"ISO C8 (57х81 мм)"</string> - <string name="mediasize_iso_c9" msgid="7983532635227561362">"ISO C9 (40х57 мм)"</string> - <string name="mediasize_iso_c10" msgid="5040764293406765584">"ISO C10 (28х40 мм)"</string> - <string name="mediasize_na_letter" msgid="2841414839888344296">"Letter (216х279 мм)"</string> - <string name="mediasize_na_gvrnmt_letter" msgid="5295836838862962809">"Government Letter (203х267 мм)"</string> - <string name="mediasize_na_legal" msgid="8621364037680465666">"Legal (216х356 мм)"</string> - <string name="mediasize_na_junior_legal" msgid="3309324162155085904">"Junior Legal (203 х 127 мм)"</string> - <string name="mediasize_na_ledger" msgid="5567030340509075333">"Ledger (432х279 мм)"</string> - <string name="mediasize_na_tabloid" msgid="4571735038501661757">"Tabloid (279х432 мм)"</string> - <string name="mediasize_na_index_3x5" msgid="5182901917818625126">"Index Card 3x5 (76x127 мм)"</string> - <string name="mediasize_na_index_4x6" msgid="7687620625422312396">"Index Card 4x6 (102x152 мм)"</string> - <string name="mediasize_na_index_5x8" msgid="8834215284646872800">"Index Card 5x8 (127x203 мм)"</string> - <string name="mediasize_na_monarch" msgid="213639906956550754">"Monarch (184x267 мм)"</string> - <string name="mediasize_na_quarto" msgid="835778493593023223">"Quarto (203x254 мм)"</string> - <string name="mediasize_na_foolscap" msgid="1573911237983677138">"Foolscap (203x330 мм)"</string> - <string name="mediasize_chinese_roc_8k" msgid="3626855847189438896">"ROC 8K (270x390 мм)"</string> - <string name="mediasize_chinese_roc_16k" msgid="9182191577022943355">"ROC 16K (195x270 мм)"</string> - <string name="mediasize_chinese_prc_1" msgid="4793232644980170500">"PRC 1 (102x165 мм)"</string> - <string name="mediasize_chinese_prc_2" msgid="5404109730975720670">"PRC 2 (102x176 мм)"</string> - <string name="mediasize_chinese_prc_3" msgid="1335092253339363526">"PRC 3 (125x176 мм)"</string> - <string name="mediasize_chinese_prc_4" msgid="9167997800486569834">"PRC 4 (110x208 мм)"</string> - <string name="mediasize_chinese_prc_5" msgid="845875168823541497">"PRC 5 (110x220 мм)"</string> - <string name="mediasize_chinese_prc_6" msgid="3220325667692648789">"PRC 6 (120x320 мм)"</string> - <string name="mediasize_chinese_prc_7" msgid="1776792138507038527">"PRC 7 (160x230 мм)"</string> - <string name="mediasize_chinese_prc_8" msgid="1417176642687456692">"PRC 8 (120x309 мм)"</string> - <string name="mediasize_chinese_prc_9" msgid="4785983473123798365">"PRC 9 (229x324 мм)"</string> - <string name="mediasize_chinese_prc_10" msgid="7847982299391851899">"PRC 10 (324x458 мм)"</string> - <string name="mediasize_chinese_prc_16k" msgid="262793383539980677">"PRC 16K (146x215 мм)"</string> - <string name="mediasize_chinese_om_pa_kai" msgid="5256815579447959814">"Pa Kai (146x215 мм)"</string> - <string name="mediasize_chinese_om_dai_pa_kai" msgid="7336412963441354407">"Dai Pa Kai (275х395 мм)"</string> - <string name="mediasize_chinese_om_jurro_ku_kai" msgid="6324465444100490742">"Jurro Ku Kai (275x395 мм)"</string> - <string name="mediasize_japanese_jis_b10" msgid="1787262845627694376">"JIS B10 (32x45 мм)"</string> - <string name="mediasize_japanese_jis_b9" msgid="3336035783663287470">"JIS B9 (45x64 мм)"</string> - <string name="mediasize_japanese_jis_b8" msgid="6195398299104345731">"JIS B8 (64x91 мм)"</string> - <string name="mediasize_japanese_jis_b7" msgid="1674621886902828884">"JIS B7 (91x128 мм)"</string> - <string name="mediasize_japanese_jis_b6" msgid="4170576286062657435">"JIS B6 (128x182 мм)"</string> - <string name="mediasize_japanese_jis_b5" msgid="4899297958100032533">"JIS B5 (182x257 мм)"</string> - <string name="mediasize_japanese_jis_b4" msgid="4213158129126666847">"JIS B4 (257x364 мм)"</string> - <string name="mediasize_japanese_jis_b3" msgid="8513715307410310696">"JIS B3 (364x515 мм)"</string> - <string name="mediasize_japanese_jis_b2" msgid="4777690211897131190">"JIS B2 (515x728 мм)"</string> - <string name="mediasize_japanese_jis_b1" msgid="4608142385457034603">"JIS B1 (728x1030 мм)"</string> - <string name="mediasize_japanese_jis_b0" msgid="7587108366572243991">"JIS B0 (1030x1456 мм)"</string> - <string name="mediasize_japanese_jis_exec" msgid="5244075432263649068">"JIS Exec (216x330 мм)"</string> - <string name="mediasize_japanese_chou4" msgid="4941652015032631361">"Chou4 (90x205 мм)"</string> - <string name="mediasize_japanese_chou3" msgid="6387319169263957010">"Chou3 (120x235 мм)"</string> - <string name="mediasize_japanese_chou2" msgid="1299112025415343982">"Chou2 (111,1x146 мм)"</string> - <string name="mediasize_japanese_hagaki" msgid="8070115620644254565">"Hagaki (100x148 мм)"</string> - <string name="mediasize_japanese_oufuku" msgid="6049065587307896564">"Oufuku (148x200 мм)"</string> - <string name="mediasize_japanese_kahu" msgid="6872696027560065173">"Kaku (240x322,1 мм)"</string> - <string name="mediasize_japanese_kaku2" msgid="2359077233775455405">"Kaku2 (240x332 мм)"</string> - <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4 (105x235 мм)"</string> + <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string> + <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string> + <string name="mediasize_iso_a2" msgid="3097535991925798280">"ISO A2"</string> + <string name="mediasize_iso_a3" msgid="3023213259314236123">"ISO A3"</string> + <string name="mediasize_iso_a4" msgid="231745325296873764">"ISO A4"</string> + <string name="mediasize_iso_a5" msgid="3484327407340865411">"ISO A5"</string> + <string name="mediasize_iso_a6" msgid="4861908487129577530">"ISO A6"</string> + <string name="mediasize_iso_a7" msgid="5890208588072936130">"ISO A7"</string> + <string name="mediasize_iso_a8" msgid="4319425041085816612">"ISO A8"</string> + <string name="mediasize_iso_a9" msgid="4882220529506432008">"ISO A9"</string> + <string name="mediasize_iso_a10" msgid="2382866026365359391">"ISO A10"</string> + <string name="mediasize_iso_b0" msgid="3651827147402009675">"ISO B0"</string> + <string name="mediasize_iso_b1" msgid="6072859628278739957">"ISO B1"</string> + <string name="mediasize_iso_b2" msgid="1348731852150380378">"ISO B2"</string> + <string name="mediasize_iso_b3" msgid="2612510181259261379">"ISO B3"</string> + <string name="mediasize_iso_b4" msgid="695151378838115434">"ISO B4"</string> + <string name="mediasize_iso_b5" msgid="4863754285582212487">"ISO B5"</string> + <string name="mediasize_iso_b6" msgid="5305816292139647241">"ISO B6"</string> + <string name="mediasize_iso_b7" msgid="531673542602786624">"ISO B7"</string> + <string name="mediasize_iso_b8" msgid="9164474595708850034">"ISO B8"</string> + <string name="mediasize_iso_b9" msgid="282102976764774160">"ISO B9"</string> + <string name="mediasize_iso_b10" msgid="4517141714407898976">"ISO B10"</string> + <string name="mediasize_iso_c0" msgid="3103521357901591100">"ISO C0"</string> + <string name="mediasize_iso_c1" msgid="1231954105985048595">"ISO C1"</string> + <string name="mediasize_iso_c2" msgid="927702816980087462">"ISO C2"</string> + <string name="mediasize_iso_c3" msgid="835154173518304159">"ISO C3"</string> + <string name="mediasize_iso_c4" msgid="5095951985108194011">"ISO C4"</string> + <string name="mediasize_iso_c5" msgid="1985397450332305739">"ISO C5"</string> + <string name="mediasize_iso_c6" msgid="8147421924174693013">"ISO C6"</string> + <string name="mediasize_iso_c7" msgid="8993994925276122950">"ISO C7"</string> + <string name="mediasize_iso_c8" msgid="6871178104139598957">"ISO C8"</string> + <string name="mediasize_iso_c9" msgid="7983532635227561362">"ISO C9"</string> + <string name="mediasize_iso_c10" msgid="5040764293406765584">"ISO C10"</string> + <string name="mediasize_na_letter" msgid="2841414839888344296">"Letter"</string> + <string name="mediasize_na_gvrnmt_letter" msgid="5295836838862962809">"Government Letter"</string> + <string name="mediasize_na_legal" msgid="8621364037680465666">"Legal"</string> + <string name="mediasize_na_junior_legal" msgid="3309324162155085904">"Junior Legal"</string> + <string name="mediasize_na_ledger" msgid="5567030340509075333">"Ledger"</string> + <string name="mediasize_na_tabloid" msgid="4571735038501661757">"Tabloid"</string> + <string name="mediasize_na_index_3x5" msgid="5182901917818625126">"Index Card 3x5"</string> + <string name="mediasize_na_index_4x6" msgid="7687620625422312396">"Index Card 4x6"</string> + <string name="mediasize_na_index_5x8" msgid="8834215284646872800">"Index Card 5x8"</string> + <string name="mediasize_na_monarch" msgid="213639906956550754">"Monarch"</string> + <string name="mediasize_na_quarto" msgid="835778493593023223">"Quarto"</string> + <string name="mediasize_na_foolscap" msgid="1573911237983677138">"Foolscap"</string> + <string name="mediasize_chinese_roc_8k" msgid="3626855847189438896">"ROC 8K"</string> + <string name="mediasize_chinese_roc_16k" msgid="9182191577022943355">"ROC 16K"</string> + <string name="mediasize_chinese_prc_1" msgid="4793232644980170500">"PRC 1"</string> + <string name="mediasize_chinese_prc_2" msgid="5404109730975720670">"PRC 2"</string> + <string name="mediasize_chinese_prc_3" msgid="1335092253339363526">"PRC 3"</string> + <string name="mediasize_chinese_prc_4" msgid="9167997800486569834">"PRC 4"</string> + <string name="mediasize_chinese_prc_5" msgid="845875168823541497">"PRC 5"</string> + <string name="mediasize_chinese_prc_6" msgid="3220325667692648789">"PRC 6"</string> + <string name="mediasize_chinese_prc_7" msgid="1776792138507038527">"PRC 7"</string> + <string name="mediasize_chinese_prc_8" msgid="1417176642687456692">"PRC 8"</string> + <string name="mediasize_chinese_prc_9" msgid="4785983473123798365">"PRC 9"</string> + <string name="mediasize_chinese_prc_10" msgid="7847982299391851899">"PRC 10"</string> + <string name="mediasize_chinese_prc_16k" msgid="262793383539980677">"PRC 16K"</string> + <string name="mediasize_chinese_om_pa_kai" msgid="5256815579447959814">"Pa Kai"</string> + <string name="mediasize_chinese_om_dai_pa_kai" msgid="7336412963441354407">"Dai Pa Kai"</string> + <string name="mediasize_chinese_om_jurro_ku_kai" msgid="6324465444100490742">"Jurro Ku Kai"</string> + <string name="mediasize_japanese_jis_b10" msgid="1787262845627694376">"JIS B10"</string> + <string name="mediasize_japanese_jis_b9" msgid="3336035783663287470">"JIS B9"</string> + <string name="mediasize_japanese_jis_b8" msgid="6195398299104345731">"JIS B8"</string> + <string name="mediasize_japanese_jis_b7" msgid="1674621886902828884">"JIS B7"</string> + <string name="mediasize_japanese_jis_b6" msgid="4170576286062657435">"JIS B6"</string> + <string name="mediasize_japanese_jis_b5" msgid="4899297958100032533">"JIS B5"</string> + <string name="mediasize_japanese_jis_b4" msgid="4213158129126666847">"JIS B4"</string> + <string name="mediasize_japanese_jis_b3" msgid="8513715307410310696">"JIS B3"</string> + <string name="mediasize_japanese_jis_b2" msgid="4777690211897131190">"JIS B2"</string> + <string name="mediasize_japanese_jis_b1" msgid="4608142385457034603">"JIS B1"</string> + <string name="mediasize_japanese_jis_b0" msgid="7587108366572243991">"JIS B0"</string> + <string name="mediasize_japanese_jis_exec" msgid="5244075432263649068">"JIS Exec"</string> + <string name="mediasize_japanese_chou4" msgid="4941652015032631361">"Chou4"</string> + <string name="mediasize_japanese_chou3" msgid="6387319169263957010">"Chou3"</string> + <string name="mediasize_japanese_chou2" msgid="1299112025415343982">"Chou2"</string> + <string name="mediasize_japanese_hagaki" msgid="8070115620644254565">"Hagaki"</string> + <string name="mediasize_japanese_oufuku" msgid="6049065587307896564">"Oufuku"</string> + <string name="mediasize_japanese_kahu" msgid="6872696027560065173">"Kaku"</string> + <string name="mediasize_japanese_kaku2" msgid="2359077233775455405">"Kaku2"</string> + <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string> <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"Неизвестный вертикальный формат"</string> <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"Неизвестный горизонтальный формат"</string> <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Печать отменена"</string> diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml index f0186dfed71f..81e90d252d41 100644 --- a/core/res/res/values-si-rLK/strings.xml +++ b/core/res/res/values-si-rLK/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ඇඟිලි සලකුණු නිරූපකය"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"සමමුහුර්ත සැකසීම් කියවන්න"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ගිණුම සඳහා සමමුහුර්ත සැකසීම් කියවීමට යෙදුමට අවසර දෙන්න. උදාහරණයක් ලෙස, ගිණුමක් සමඟ පුද්ගල යෙදුම සමමුහුර්ත දැයි මෙයට හඳුනා ගත හැක."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"සමමුහුර්ත කිරීම සක්රිය කරන්න සහ අක්රිය කරන්න"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"රටාව සම්පූර්ණයි"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"රටා ප්රදේශය."</string> <!-- String.format failed for translation --> <!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) --> <skip /> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 5aa214d4ca57..cbff7d5d6b6a 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -436,6 +436,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona odtlačku prsta"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"čítať nastavenia synchronizácie"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Umožňuje aplikácii čítať nastavenia synchronizácie v účte. Môže napríklad určiť, či je s účtom synchronizovaná aplikácia Ľudia."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"zapnúť alebo vypnúť synchronizáciu"</string> @@ -714,6 +715,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Bunka bola pridaná"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Bola pridaná bunka <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Bezpečnostný vzor bol dokončený"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Oblasť na zadanie bezpečnostného vzoru."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Miniaplikácia %2$d z %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Pridať miniaplikáciu."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prázdne"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 0c003ff42942..ddeff80a238e 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -436,6 +436,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona prstnih odtisov"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"branje nastavitev sinhronizacije"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Aplikaciji omogoča branje nastavitev sinhronizacije za račun. S tem lahko aplikacija na primer ugotovi, ali je aplikacija Ljudje sinhronizirana z računom."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"vklop in izklop sinhronizacije"</string> @@ -714,6 +715,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Celica je dodana"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Dodana <xliff:g id="CELL_INDEX">%1$s</xliff:g>. celica"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Vzorec je končan"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Območje vzorca."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Pripomoček %2$d za %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodajanje pripomočka."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prazno"</string> diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml index 549c5ef79c98..508e88e02b8c 100644 --- a/core/res/res/values-sq-rAL/strings.xml +++ b/core/res/res/values-sq-rAL/strings.xml @@ -21,7 +21,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"B"</string> - <string name="kilobyteShort" msgid="5973789783504771878">"kilobajt"</string> + <string name="kilobyteShort" msgid="5973789783504771878">"KB"</string> <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> <string name="terabyteShort" msgid="231613018159186962">"terabajt"</string> @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona e gjurmës së gishtit"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lexo cilësimet e sinkronizimit"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Lejon aplikacionin të lexojë cilësimet e sinkronizimit për një llogari. Për shembull, kjo mund të përcaktojë nëse aplikacioni \"Kontaktet\" është i sinkronizuar me një llogari."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ndiz ose fik sinkronizimin"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Qeliza u shtua"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Qeliza <xliff:g id="CELL_INDEX">%1$s</xliff:g> u shtua"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Modeli përfundoi"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Zona e motivit."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Miniaplikacioni %2$d nga %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Shto miniaplikacion."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Bosh"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 112549a16d85..b283250985c4 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -228,15 +228,15 @@ <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="permgroupdesc_contacts" msgid="6951499528303668046">"приступи контактима"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"приступ локацији овог уређаја"</string> <string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string> - <string name="permgroupdesc_calendar" msgid="3889615280211184106">"приступ календару"</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="permgroupdesc_sms" msgid="4656988620100940350">"шаље и прегледа SMS поруке"</string> <string name="permgrouplab_storage" msgid="1971118770546336966">"Складиште"</string> - <string name="permgroupdesc_storage" msgid="637758554581589203">"приступ сликама, медијима и датотекама на уређају"</string> + <string name="permgroupdesc_storage" msgid="637758554581589203">"приступи сликама, медијима и датотекама на уређају"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string> <string name="permgroupdesc_microphone" msgid="4988812113943554584">"снимање аудио снимака"</string> <string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string> @@ -435,6 +435,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Икона отиска прста"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"читање подешавања синхронизације"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Дозвољава апликацији да чита подешавања синхронизације за налог. На пример, овако може да се утврди да ли је апликација Људи синхронизована са налогом."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"укључивање и искључивање синхронизације"</string> @@ -713,6 +714,7 @@ <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_detected" msgid="4988730895554057058">"Образац је довршен"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Област шаблона."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Празно"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 4c2f319c7d38..b293655998f6 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon för fingeravtryck"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"läsa synkroniseringsinställningar"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Tillåter att appen läser synkroniseringsinställningarna för ett konto. Detta kan användas till exempel för att avgöra om appen Personer är synkroniserad med ett konto."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"aktivera/inaktivera synkronisering"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"En cell har lagts till"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Cell <xliff:g id="CELL_INDEX">%1$s</xliff:g> har lagts till"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Grafiskt lösenord har slutförts"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Fält för grafiskt lösenord."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d av %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Lägg till en widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tom"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 6e98a29eb926..3800c92dbd9c 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -436,6 +436,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Kitambulisho <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Aikoni ya kitambulisho"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"kusoma mipangilio ya usawazishaji"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Inaruhusu programu kusoma mipangilio ya upatanishi wa akaunti. Kwa mfano, huku kunaweza kuamua kama programu ya Watu imepatanishwa na akaunti."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"kuwasha na kuzima usawazishaji"</string> @@ -714,6 +715,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Kiini kimeongezwa"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Kisanduku <xliff:g id="CELL_INDEX">%1$s</xliff:g> kimeongezwa"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Ruwaza imekamilika"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Eneo la ruwaza."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Wijeti %2$d ya %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ongeza wijeti."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tupu"</string> diff --git a/core/res/res/values-sw600dp/dimens_material.xml b/core/res/res/values-sw600dp/dimens_material.xml index dffe8e7e88bd..3bbb352bca8e 100644 --- a/core/res/res/values-sw600dp/dimens_material.xml +++ b/core/res/res/values-sw600dp/dimens_material.xml @@ -21,13 +21,11 @@ <dimen name="text_size_subtitle_material_toolbar">16dp</dimen> <!-- Default height of an action bar. --> <dimen name="action_bar_default_height_material">64dp</dimen> - <!-- Default padding of an action bar. --> - <dimen name="action_bar_default_padding_material">4dp</dimen> <!-- Default content inset of an action bar. --> <dimen name="action_bar_content_inset_material">24dp</dimen> - <!-- Padding to add to the start of the overflow action button. --> - <dimen name="action_bar_navigation_padding_start_material">8dp</dimen> - <!-- Padding to add to the end of the overflow action button. --> - <dimen name="action_bar_overflow_padding_end_material">18dp</dimen> + <!-- Default start padding of an action bar. --> + <dimen name="action_bar_default_padding_start_material">8dp</dimen> + <!-- Default end padding of an action bar. --> + <dimen name="action_bar_default_padding_end_material">8dp</dimen> </resources> diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml index 7cde55ebc4c8..ae9be638c0a7 100644 --- a/core/res/res/values-ta-rIN/strings.xml +++ b/core/res/res/values-ta-rIN/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"கைரேகை ஐகான்"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ஒத்திசைவு அமைப்புகளைப் படித்தல்"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"கணக்கிற்கான ஒத்திசைவு அமைப்புகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது. எடுத்துக்காட்டாக, பீப்பிள் பயன்பாடு கணக்குடன் ஒத்திசைக்கப்பட்டுள்ளதா என்பதை இது தீர்மானிக்கலாம்."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"ஒத்திசைவை இயக்குவதையும், முடக்குவதையும் மாற்றுதல்"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"வடிவம் நிறைவடைந்தது"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"வடிவப் பகுதி."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"காலியானது"</string> diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml index c26397125c3d..7eca8eee401d 100644 --- a/core/res/res/values-te-rIN/strings.xml +++ b/core/res/res/values-te-rIN/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"వేలిముద్ర చిహ్నం"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"సమకాలీకరణ సెట్టింగ్లను చదవడం"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ఖాతా యొక్క సమకాలీకరణ సెట్టింగ్లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఉదాహరణకు, వ్యక్తుల అనువర్తనం ఖాతాతో సమకాలీకరించబడాలా లేదా అనే విషయాన్ని ఇది నిశ్చయించవచ్చు."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"సమకాలీకరణను ఆన్ మరియు ఆఫ్కు టోగుల్ చేయడం"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"నమూనా పూర్తయింది"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"నమూనా ప్రాంతం."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. %3$dలో విడ్జెట్ %2$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"విడ్జెట్ను జోడించండి."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ఖాళీ"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index d1983ed560ee..549e75588d3f 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ไอคอนลายนิ้วมือ"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"อ่านการตั้งค่าการซิงค์แล้ว"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"อนุญาตให้แอปพลิเคชันอ่านการตั้งค่าการซิงค์ของบัญชี ตัวอย่างเช่น การอนุญาตนี้สามารถระบุได้ว่าแอปพลิเคชัน People ซิงค์กับบัญชีหรือไม่"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"สลับระหว่างเปิดและปิดการซิงค์"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"วาดรูปแบบเสร็จสิ้น"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"พื้นที่สำหรับรูปแบบ"</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"ว่าง"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 2625a4103698..004b3f807ad3 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icon ng fingerprint"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"basahin ang mga setting ng sync"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Pinapayagan ang app na basahin ang mga setting ng pag-sync para sa isang account. Halimbawa, matutukoy nito kung naka-sync ang app na Mga Tao sa isang account."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"I-toggle on at off ang pag-sync"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Idinagdag ang cell"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Idinagdag ang cell <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Nakumpleto ang pattern"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Bahagi ng pattern."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d ng %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Magdagdag ng widget."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Walang laman"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index a5b2ab24f285..72cbf87c2bc6 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Parmak izi simgesi"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"senk. ayarlarını okuma"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Uygulamaya bir hesaba ait senkronizasyon ayarlarını okuma izni verir. Örneğin, bu izne sahip bir uygulama Kişiler uygulamasının bir hesapla senkronize olup olmadığını belirleyebilir."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"senkronizasyonu açma/kapatma"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Hücre eklendi"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"<xliff:g id="CELL_INDEX">%1$s</xliff:g>. hücre eklendi"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Desen tamamlandı"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Desen alanı."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d / %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Widget ekleyin."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Boş"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 5ebd0bf0d830..ea3c94171600 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -436,6 +436,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Значок відбитка пальця"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"читати налаштування синхронізації"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Дозволяє програмі читати налаштування синхронізації для облікового запису, наприклад, визначати, чи програма Люди синхронізується з обліковим записом."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"вмикати й вимикати синхронізацію"</string> @@ -714,6 +715,7 @@ <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_detected" msgid="4988730895554057058">"Малювання ключа закінчено"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Область ключа."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Порожня область"</string> diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml index a1b614e188ff..76495e1ed8d8 100644 --- a/core/res/res/values-ur-rPK/strings.xml +++ b/core/res/res/values-ur-rPK/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"فنگر پرنٹ آئیکن"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"مطابقت پذیری کی ترتیبات پڑھیں"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ایپ کو کسی اکاؤنٹ کیلئے مطابقت پذیری کی ترتیبات پڑھنے کی اجازت دیتا ہے۔ مثلا، یہ تعین کرسکتا ہے کہ آیا People ایپ کسی اکاؤنٹ کے ساتھ مطابقت پذیر ہے۔"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"مطابقت پذیری آن اور آف ٹوگل کریں"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"پیٹرن مکمل ہو گیا"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"پیٹرن کا علاقہ۔"</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"خالی"</string> diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml index 0404e98ea07c..cb1fc6fdf54f 100644 --- a/core/res/res/values-uz-rUZ/strings.xml +++ b/core/res/res/values-uz-rUZ/strings.xml @@ -130,7 +130,7 @@ </string-array> <string name="wfcSpnFormat" msgid="8211621332478306568">"%s"</string> <string name="wfcDataSpnFormat" msgid="1118052028767666883">"%s"</string> - <string name="wifi_calling_off_summary" msgid="8720659586041656098">"O‘chirilgan"</string> + <string name="wifi_calling_off_summary" msgid="8720659586041656098">"O‘chiq"</string> <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi afzal ko‘rilsin"</string> <string name="wfc_mode_cellular_preferred_summary" msgid="5920549484600758786">"Mobil tarmoq afzal ko‘rilsin"</string> <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Faqat Wi-Fi"</string> @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Barmoq izi belgisi"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"sinx-sh sozlamalarini o‘qish"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Ilovaga hisobning sinxronlash sozlamalarini o‘qish uchun ruxsat beradi. Masalan, bu \"Odamlar\" ilovasi hisob bilan sinxronlangan yoki aksini aniqlay oladi."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"sinx.ni yoqish/o‘chirish"</string> @@ -673,8 +674,8 @@ <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"To‘xtatib turish"</string> <string name="lockscreen_transport_play_description" msgid="1901258823643886401">"Ijro qilish"</string> <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"To‘xtatish"</string> - <string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Tezkor orqaga qaytarish"</string> - <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Tezkor oldinga o‘tkazish"</string> + <string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Orqaga o‘tkazish"</string> + <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Oldinga o‘tkazish"</string> <string name="emergency_calls_only" msgid="6733978304386365407">"Faqat favqulodda chaqiruvlar"</string> <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Tarmoq qulflangan"</string> <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-karta PUK kod bilan qulflangan."</string> @@ -712,6 +713,7 @@ <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> katak qo‘shildi"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Chizma namunasi tugatildi"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Chizmali qulf maydoni."</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Bo‘sh"</string> @@ -813,7 +815,7 @@ </plurals> <string name="last_month" msgid="3959346739979055432">"O‘tgan oy"</string> <string name="older" msgid="5211975022815554840">"Eskiroq"</string> - <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g>da"</string> + <string name="preposition_for_date" msgid="9093949757757445117">"<xliff:g id="DATE">%s</xliff:g>"</string> <string name="preposition_for_time" msgid="5506831244263083793">"<xliff:g id="TIME">%s</xliff:g>da"</string> <string name="preposition_for_year" msgid="5040395640711867177">"<xliff:g id="YEAR">%s</xliff:g>da"</string> <string name="day" msgid="8144195776058119424">"kun"</string> @@ -875,8 +877,8 @@ <string name="no" msgid="5141531044935541497">"Bekor qilish"</string> <string name="dialog_alert_title" msgid="2049658708609043103">"Diqqat"</string> <string name="loading" msgid="7933681260296021180">"Yuklanmoqda…"</string> - <string name="capital_on" msgid="1544682755514494298">"YONIQ"</string> - <string name="capital_off" msgid="6815870386972805832">"O‘CHIQ"</string> + <string name="capital_on" msgid="1544682755514494298">"I"</string> + <string name="capital_off" msgid="6815870386972805832">"O"</string> <string name="whichApplication" msgid="4533185947064773386">"Ushbudan foydalanib amalni tugatish:"</string> <string name="whichApplicationNamed" msgid="8260158865936942783">"“%1$s” ilovasi yordamida bajarish"</string> <string name="whichViewApplication" msgid="3272778576700572102">"Ochish…"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 5f477d5f6306..45a147e44eed 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Biểu tượng vân tay"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"đọc cài đặt đồng bộ hóa"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Cho phép ứng dụng đọc cài đặt đồng bộ hóa cho tài khoản. Ví dụ: việc này có thể xác định liệu ứng dụng Mọi người đã được đồng bộ hóa với tài khoản chưa."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"chuyển đổi bật và tắt đồng bộ hóa"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Đã thêm ô"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Đã thêm ô <xliff:g id="CELL_INDEX">%1$s</xliff:g>"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Đã vẽ xong hình"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Khu vực hình."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Tiện ích %2$d trong số %3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Thêm tiện ích."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Trống"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index e61ee70fa5c9..3ffb555c0e99 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指纹图标"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"读取同步设置"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允许该应用读取某个帐户的同步设置。例如,此权限可确定“联系人”应用是否与某个帐户同步。"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"启用和停用同步"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"图案绘制完成"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"图案区域。"</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s。%3$d的小部件%2$d。"</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"添加小部件。"</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"空白"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 05073a316fda..ffa6fb19a1d5 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指紋圖示"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"讀取同步處理設定"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允許應用程式讀取帳戶的同步設定,例如確定「通訊錄」應用程式是否和某個帳戶保持同步。"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"開啟和關閉同步功能"</string> @@ -712,6 +713,7 @@ <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_detected" msgid="4988730895554057058">"已畫出解鎖圖案"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"圖案區域。"</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"空白"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 58902d768dad..fb139cd4c6f7 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指紋圖示"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"讀取同步處理設定"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"允許應用程式讀取帳戶的同步處理設定,例如判斷「使用者」應用程式是否和某個帳戶進行同步處理。"</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"開啟及關閉同步功能"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"已加入 1 格"</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="lockscreen_access_pattern_area" msgid="400813207572953209">"圖形區域。"</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> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"空白"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 2003d17c9bcc..f29e9f90e0ef 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -434,6 +434,7 @@ <string name="fingerprint_name_template" msgid="5870957565512716938">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string> <string-array name="fingerprint_error_vendor"> </string-array> + <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Isithonjana sezigxivizo zeminwe"</string> <string name="permlab_readSyncSettings" msgid="6201810008230503052">"funda izilungiselelo zokuvumelanisa"</string> <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Ivumela uhlelo lokusebenza ukufunda izilungiselelo zokuvumelanisa ze-akhawunti. Isibonelo, lokhu kungacacisa ukuthi noma ngabe uhlelo lokusebenza le-People livumelanisiwe ne-akhawunti."</string> <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"shintsha phakathi kokuvula kanye nokucisha ukuvumelanisa"</string> @@ -712,6 +713,7 @@ <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Kwengezwe"</string> <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Iseli <xliff:g id="CELL_INDEX">%1$s</xliff:g> lingeziwe"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Iphethini isiphelile"</string> + <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Indawo yephethini."</string> <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. iwijethi %2$d ye-%3$d."</string> <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Engeza iwijethi."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Akunalutho"</string> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 1515703ec08b..de16f203da4c 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -219,7 +219,7 @@ <flag name="appop" value="0x40" /> <!-- Additional flag from base permission type: this permission can be automatically granted to apps that target API levels below - {@link android.os.Build.VERSION_CODES#MNC} (before runtime permissions + {@link android.os.Build.VERSION_CODES#M} (before runtime permissions were introduced). --> <flag name="pre23" value="0x80" /> <!-- Additional flag from base permission type: this permission can be automatically @@ -1059,7 +1059,7 @@ at the same time. <p>The default value is <code>false</code> for applications with - <code>targetSdkVersion</code> lesser than {@link android.os.Build.VERSION_CODES#MNC} and + <code>targetSdkVersion</code> lesser than {@link android.os.Build.VERSION_CODES#M} and <code>true</code> otherwise. <p>NOTE: A task's root activity value is applied to all additional activities launched in diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml index 1cb39f0de592..7399fa9d58ce 100644 --- a/core/res/res/values/colors_material.xml +++ b/core/res/res/values/colors_material.xml @@ -41,9 +41,6 @@ <color name="switch_thumb_disabled_material_dark">#ff616161</color> <color name="switch_thumb_disabled_material_light">#ffbdbdbd</color> - <color name="link_text_material_light">@color/material_deep_teal_500</color> - <color name="link_text_material_dark">@color/material_deep_teal_200</color> - <!-- Text & foreground colors --> <eat-comment /> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 82eb2c44bc8f..b1bde0e8009e 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -408,6 +408,7 @@ <integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_24">24</integer> <integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_5">36</integer> <string translatable="false" name="config_wifi_random_mac_oui">DA-A1-19</string> + <string translatable="false" name="config_wifi_framework_sap_2G_channel_list">1,6,11</string> <bool translatable="false" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment">true</bool> @@ -480,9 +481,6 @@ <!-- Integer indicating how to handle beacons with uninitialized RSSI value of 0 --> <integer translatable="false" name="config_wifi_framework_scan_result_rssi_level_patchup_value">-85</integer> - <!-- Boolean indicating associated scan are allowed --> - <bool translatable="false" name="config_wifi_framework_enable_associated_autojoin_scan">true</bool> - <!-- Boolean indicating associated network selection is allowed --> <bool translatable="false" name="config_wifi_framework_enable_associated_network_selection">true</bool> @@ -1477,7 +1475,7 @@ <!-- Remote server that can provide NTP responses. --> <string translatable="false" name="config_ntpServer">2.android.pool.ntp.org</string> <!-- Normal polling frequency in milliseconds --> - <integer name="config_ntpPollingInterval">864000000</integer> + <integer name="config_ntpPollingInterval">86400000</integer> <!-- Try-again polling interval in milliseconds, in case the network request failed --> <integer name="config_ntpPollingIntervalShorter">60000</integer> <!-- Number of times to try again with the shorter interval, before backing @@ -2264,4 +2262,12 @@ <!-- How long history of previous vibrations should be kept for the dumpsys. --> <integer name="config_previousVibrationsDumpLimit">20</integer> + + <!-- Number of retries Cell Data should attempt for a given error code before + restarting the modem. + Error codes not listed will not lead to modem restarts. + Array of "code#,retry#" --> + <string-array name="config_cell_retries_per_error_code"> + </string-array> + </resources> diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml index b9807770f9fb..55bea9e38291 100644 --- a/core/res/res/values/dimens_material.xml +++ b/core/res/res/values/dimens_material.xml @@ -35,8 +35,10 @@ <!-- Default height of an action bar. --> <dimen name="action_bar_default_height_material">56dp</dimen> - <!-- Default padding of an action bar. --> - <dimen name="action_bar_default_padding_material">4dp</dimen> + <!-- Default start padding of an action bar. --> + <dimen name="action_bar_default_padding_start_material">0dp</dimen> + <!-- Default end padding of an action bar. --> + <dimen name="action_bar_default_padding_end_material">0dp</dimen> <!-- Default content inset of an action bar. --> <dimen name="action_bar_content_inset_material">16dp</dimen> <!-- Vertical padding around action bar icons. --> @@ -51,8 +53,6 @@ <dimen name="list_item_padding_horizontal_material">@dimen/action_bar_content_inset_material</dimen> <!-- Padding to add to the start of the overflow action button. --> - <dimen name="action_bar_navigation_padding_start_material">0dp</dimen> - <!-- Padding to add to the start of the overflow action button. --> <dimen name="action_bar_overflow_padding_start_material">6dp</dimen> <!-- Padding to add to the end of the overflow action button. --> <dimen name="action_bar_overflow_padding_end_material">10dp</dimen> @@ -127,7 +127,7 @@ <!-- Text size for the time picker header HH:MM label. This value is large enough that we don't need to use scaled pixels, dp is fine. --> <dimen name="timepicker_time_label_size">60dp</dimen> - <dimen name="timepicker_ampm_label_size">16sp</dimen> + <dimen name="timepicker_ampm_label_size">16dp</dimen> <dimen name="timepicker_ampm_horizontal_padding">16dp</dimen> <dimen name="timepicker_am_top_padding">4dp</dimen> <dimen name="timepicker_pm_top_padding">4dp</dimen> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 568e61e3e2e1..bc831da096f2 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2604,7 +2604,7 @@ <public type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" /> <!-- =============================================================== - Resources added in version MNC of the platform + Resources added in version M of the platform =============================================================== --> <eat-comment /> @@ -2652,4 +2652,6 @@ <public type="id" name="accessibilityActionScrollDown" id="0x0102003a" /> <public type="id" name="accessibilityActionScrollRight" id="0x0102003b" /> <public type="id" name="accessibilityActionContextClick" id="0x0102003c" /> + + <public type="string" name="fingerprint_icon_content_description" /> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 35c1f0e5066f..d9fa287361c0 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1221,6 +1221,9 @@ <string-array name="fingerprint_error_vendor"> </string-array> + <!-- Content description which should be used for the fingerprint icon. --> + <string name="fingerprint_icon_content_description">Fingerprint icon</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_readSyncSettings">read sync settings</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> @@ -1916,6 +1919,8 @@ Cell <xliff:g id="cell_index" example="3">%1$s</xliff:g> added</string> <!-- Accessibility description sent when user completes drawing a pattern. [CHAR LIMIT=NONE] --> <string name="lockscreen_access_pattern_detected">Pattern completed</string> + <!-- Accessibility description of the unlock pattern area. [CHAR_LIMIT=none] --> + <string name="lockscreen_access_pattern_area" msgid="">Pattern area.</string> <!-- Accessibility description sent when user changes the current lock screen widget. [CHAR_LIMIT=none] --> <string name="keyguard_accessibility_widget_changed">%1$s. Widget %2$d of %3$d.</string> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index 1b9c4091af35..1e202e4c132a 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -809,13 +809,14 @@ please see styles_device_defaults.xml. <item name="navigationButtonStyle">@style/Widget.Material.Toolbar.Button.Navigation</item> <item name="titleTextAppearance">@style/TextAppearance.Material.Widget.Toolbar.Title</item> <item name="subtitleTextAppearance">@style/TextAppearance.Material.Widget.Toolbar.Subtitle</item> + <item name="paddingStart">@dimen/action_bar_default_padding_start_material</item> + <item name="paddingEnd">@dimen/action_bar_default_padding_end_material</item> </style> <style name="Widget.Material.Toolbar.Button.Navigation" parent="Widget.Material"> <item name="background">@drawable/control_background_40dp_material</item> <item name="minWidth">56dp</item> <item name="scaleType">center</item> - <item name="paddingStart">@dimen/action_bar_navigation_padding_start_material</item> </style> <style name="Widget.Material.WebTextView" parent="Widget.WebTextView"/> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index b3304233ab83..ee61944e75bb 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -297,7 +297,6 @@ <java-symbol type="bool" name="config_hasRecents" /> <java-symbol type="bool" name="config_windowShowCircularMask" /> <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" /> - <java-symbol type="bool" name="config_wifi_framework_enable_associated_autojoin_scan" /> <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" /> <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" /> <java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" /> @@ -338,6 +337,7 @@ <java-symbol type="integer" name="config_wifi_active_rx_cur_ma" /> <java-symbol type="integer" name="config_wifi_tx_cur_ma" /> <java-symbol type="integer" name="config_wifi_operating_voltage_mv" /> + <java-symbol type="string" name="config_wifi_framework_sap_2G_channel_list" /> <java-symbol type="bool" name="editable_voicemailnumber" /> @@ -2310,6 +2310,12 @@ <java-symbol type="plurals" name="selected_count" /> <java-symbol type="drawable" name="ic_dialog_alert_material" /> + <java-symbol type="string" name="lockscreen_access_pattern_area" /> + <java-symbol type="bool" name="allow_stacked_button_bar" /> <java-symbol type="bool" name="config_eap_sim_based_auth_supported" /> + + <java-symbol type="array" name="config_cell_retries_per_error_code" /> + <java-symbol type="drawable" name="ic_more_items" /> + </resources> diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml index 9d3a7ef3e9fd..e88a4fba5c9a 100644 --- a/core/res/res/values/themes_material.xml +++ b/core/res/res/values/themes_material.xml @@ -67,8 +67,8 @@ please see themes_device_defaults.xml. <item name="textColorHintInverse">@color/hint_foreground_material_light</item> <item name="textColorHighlight">@color/highlighted_text_material</item> <item name="textColorHighlightInverse">@color/highlighted_text_material</item> - <item name="textColorLink">@color/link_text_material_dark</item> - <item name="textColorLinkInverse">@color/link_text_material_light</item> + <item name="textColorLink">?attr/colorAccent</item> + <item name="textColorLinkInverse">?attr/colorAccent</item> <item name="textColorSearchUrl">@color/search_url_text_material_dark</item> <item name="textColorAlertDialogListItem">@color/primary_text_material_dark</item> @@ -422,8 +422,8 @@ please see themes_device_defaults.xml. <item name="textColorHintInverse">@color/hint_foreground_material_dark</item> <item name="textColorHighlight">@color/highlighted_text_material</item> <item name="textColorHighlightInverse">@color/highlighted_text_material</item> - <item name="textColorLink">@color/link_text_material_light</item> - <item name="textColorLinkInverse">@color/link_text_material_dark</item> + <item name="textColorLink">?attr/colorAccent</item> + <item name="textColorLinkInverse">?attr/colorAccent</item> <item name="textColorSearchUrl">@color/search_url_text_material_light</item> <item name="textColorAlertDialogListItem">@color/primary_text_material_light</item> @@ -793,8 +793,6 @@ please see themes_device_defaults.xml. <item name="textColorHintInverse">@color/hint_foreground_material_dark</item> <item name="textColorHighlight">@color/highlighted_text_material</item> <item name="textColorHighlightInverse">@color/highlighted_text_material</item> - <item name="textColorLink">@color/link_text_material_light</item> - <item name="textColorLinkInverse">@color/link_text_material_dark</item> <item name="textColorSearchUrl">@color/search_url_text_material_light</item> <item name="textColorAlertDialogListItem">@color/primary_text_material_light</item> @@ -827,8 +825,6 @@ please see themes_device_defaults.xml. <item name="textColorHintInverse">@color/hint_foreground_material_light</item> <item name="textColorHighlight">@color/highlighted_text_material</item> <item name="textColorHighlightInverse">@color/highlighted_text_material</item> - <item name="textColorLink">@color/link_text_material_dark</item> - <item name="textColorLinkInverse">@color/link_text_material_light</item> <item name="textColorSearchUrl">@color/search_url_text_material_dark</item> <item name="textColorAlertDialogListItem">@color/primary_text_material_dark</item> diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk index 3181017a2e5a..39458f913abe 100644 --- a/data/fonts/Android.mk +++ b/data/fonts/Android.mk @@ -17,10 +17,13 @@ LOCAL_PATH := $(call my-dir) -# Use full Noto Sans Japanese font on non-smaller footprints +# Use full Noto Sans Japanese font on the normal footprints, but +# exclude it from SMALLER and use a subset on the CONSTRAINED ones. ifneq ($(SMALLER_FONT_FOOTPRINT),true) +ifneq ($(CONSTRAINED_FONT_FOOTPRINT),true) FONT_NOTOSANS_JP_FULL := true endif +endif ########################################## # create symlink for given font @@ -82,19 +85,32 @@ include $(BUILD_PREBUILT) extra_font_files := ################################ -# Include the DroidSansFallback subset on SMALLER_FONT_FOOTPRINT build +# Include the DroidSansFallback subset on SMALLER_FONT_FOOTPRINT builds, +# and the full font on CONSTRAINED_FONT_FOOTPRINT ones. ifeq ($(SMALLER_FONT_FOOTPRINT),true) +droidsans_fallback_src := DroidSansFallback.ttf +build_droidsans_fallback := true +endif # SMALLER_FONT_FOOTPRINT + +ifeq ($(CONSTRAINED_FONT_FOOTPRINT),true) +droidsans_fallback_src := DroidSansFallbackFull.ttf +build_droidsans_fallback := true +endif # CONSTRAINED_FONT_FOOTPRINT + +ifeq ($(build_droidsans_fallback),true) include $(CLEAR_VARS) LOCAL_MODULE := DroidSansFallback.ttf -LOCAL_SRC_FILES := $(LOCAL_MODULE) +LOCAL_SRC_FILES := $(droidsans_fallback_src) LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_TAGS := optional LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts include $(BUILD_PREBUILT) droidsans_fallback_src := -endif # SMALLER_FONT_FOOTPRINT +endif # build_droidsans_fallback + +build_droidsans_fallback := ################################ # Build the rest of font files as prebuilt. diff --git a/docs/html/design/wear/structure.jd b/docs/html/design/wear/structure.jd index c1d9ef9dc925..768aa7fc4399 100644 --- a/docs/html/design/wear/structure.jd +++ b/docs/html/design/wear/structure.jd @@ -166,8 +166,11 @@ href="#2DPicker">2D picker</a> is always available.</p> <li>A map that asks the user to drop a pin should exit when the pin is dropped.</li> <li>A short game can exit when the game finishes.</li> <li>A drawing app can finish after 5 seconds of inactivity.</li> + + <p class="note">An app generally should not exit in {@link android.app.Activity#onPause onPause()}. This is because events such as <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#Heads-up">Heads-up Notifications</a> can trigger the {@link android.app.Activity#onPause() onPause()} callback.</p> </ul> + <h3>Manually exiting</h3> <p>Even with logical exit points like these, some cases may exist where the user may want to diff --git a/docs/html/preview/behavior-changes.jd b/docs/html/preview/behavior-changes.jd index 6ee0af0d09c1..5c8ef413fc8d 100644 --- a/docs/html/preview/behavior-changes.jd +++ b/docs/html/preview/behavior-changes.jd @@ -373,7 +373,7 @@ consideration that the interaction must be explicitly enabled. <h2 id="behavior-afw">Android for Work Changes</h2> <p>This preview includes the following behavior changes for Android for Work:</p> <ul> -<li><strong>Work contacts in personal contexts.</strong> The Google Dialer + <li><strong>Work contacts in personal contexts.</strong> The Google Dialer Call Log now displays work contacts when the user views past calls. Setting {@link android.app.admin.DevicePolicyManager#setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean) setCrossProfileCallerIdDisabled()} @@ -381,21 +381,19 @@ to {@code true} hides the work profile contacts in the Google Dialer Call Log. W displayed along with personal contacts to devices over Bluetooth only if you set {@code DevicePolicyManager.setBluetoothContactSharingDisabled()} to {@code false}. By default, it is set to {@code true}. -</li> -<li><strong>WiFi configuration removal:</strong> WiFi configurations added by a Profile Owner + </li> + <li><strong>WiFi configuration removal:</strong> WiFi configurations added by a Profile Owner (for example, through calls to the {@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration) -addNetwork()} method) are now removed if that work profile is deleted.</li> - -<li><strong>WiFi configuration lockdown:</strong> Any WiFi configuration created by +addNetwork()} method) are now removed if that work profile is deleted. + </li> + <li><strong>WiFi configuration lockdown:</strong> Any WiFi configuration created by an active Device Owner can no longer be modified or deleted by the user if <code>Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN</code> is non-zero. The user can still create and modify their own WiFi configurations. Active Device Owners have the privilege of editing/removing any WiFi configurations, including those not created by them. -</li> - -</li> + </li> <li><strong>Download Work Policy Controller via Google account addition:</strong> When a Google account that requires management via a Work Policy Controller (WPC) app is added to a device outside of a managed context, the add account flow now prompts the user to install the @@ -408,7 +406,7 @@ method affects the camera for the calling user only; calling it from the managed affect camera apps running on the primary user. </li> <li>In addition, the {@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()} - method is now available for Profile Owners, in addition to Device Owners. </li> + method is now available for Profile Owners, as well as to Device Owners. </li> <li>A Profile Owner can set these keyguard restrictions: <ul> <li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} and @@ -422,9 +420,19 @@ affect camera apps running on the primary user. </li> <li>The {@link android.app.admin.DevicePolicyManager#setScreenCaptureDisabled(android.content.ComponentName, boolean) setScreenCaptureDisabled()} method now also blocks the assist structure when an app of the given user is in the foreground. </li> <li><code>EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM</code> now defaults to SHA-256. SHA-1 is still supported for backwards compatibility but will be removed in future. <code>EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM</code> now only accepts SHA-256.</li> <li>Device initializer APIs which existed in the MNC preview are now removed. They will not appear in the final M release.</li> - <li>Android for Work APIs are optimized for M runtime permissions, including Work profiles, assist layer, and others. New DevicePolicyManager permission APIs don't affect pre-M apps.</li> - </ul> - <li><strong>Changes to global settings</strong> — the settings below can no longer be set via {@link android.app.admin.DevicePolicyManager#setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String) setGlobalSettings()}</code>: + <li><code>EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS</code> is removed so NFC bump provisioning cannot programmatically unlock a factory reset protected device.</li> + <li>Android for Work APIs are optimized for M runtime permissions, including Work profiles, assist layer, and others. New <code>DevicePolicyManager</code> permission APIs don't affect pre-M apps.</li> + </ul></li> + +<li><strong>Changes to other APIs</strong>: +<ul> + <li>Data Usage: The {@code android.app.usage.NetworkUsageStats} class has been renamed {@code android.app.usage.NetworkStats}.</li> +</ul> + </li> + + <li><strong>Changes to global settings</strong>: + <ul> + <li>These settings can no longer be set via {@link android.app.admin.DevicePolicyManager#setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String) setGlobalSettings()}</code>: <ul> <li><code>BLUETOOTH_ON</code></li> <li><code>DEVELOPMENT_SETTINGS_ENABLED</code></li> @@ -433,4 +441,10 @@ affect camera apps running on the primary user. </li> <li><code>WIFI_ON</code></li> </ul> </li> + <li>These global settings can now be set via <code><a href="/reference/android/app/admin/DevicePolicyManager.html#setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String)">setGlobalSettings()</a></code>: + <ul> + <li><code>WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN</code></li> + </ul> + </li> + </ul> </ul> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes.html b/docs/html/sdk/support_api_diff/22.2.1/changes.html new file mode 100644 index 000000000000..2c452aa69323 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<!-- on Tue Jul 21 09:52:42 BST 2015 --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Support Library API Differences Report +</TITLE> +<link href="../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</head> +<frameset cols="242,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9"> +<frameset rows="174,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9"> + <frame src="changes/jdiff_topleftframe.html" scrolling="no" name="topleftframe" frameborder="1"> + <frame src="changes/alldiffs_index_all.html" scrolling="auto" name="bottomleftframe" frameborder="1"> + </frameset> + <frame src="changes/changes-summary.html" scrolling="auto" name="rightframe" frameborder="1"> +</frameset> +<noframes> +<h2> +Frame Alert +</h2> + +<p> +This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. +<br> +Link to <a href="changes/changes-summary.html" target="_top">Non-frame version.</A> +</noframes> +</html> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_additions.html b/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_additions.html new file mode 100644 index 000000000000..3374ffdea113 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_additions.html @@ -0,0 +1,674 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +All Additions Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for All Differences" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="alldiffs_index_all.html" xclass="hiddenlink">All Differences</a> + <br> +<A HREF="alldiffs_index_removals.html" xclass="hiddenlink">Removals</A> + <br> +<b>Additions</b> + <br> +<A HREF="alldiffs_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<!-- Field action0 --> +<A NAME="A"></A> +<br><font size="+2">A</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.action0" class="hiddenlink" target="rightframe">action0</A> +</nobr><br> +<!-- Field action_divider --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.action_divider" class="hiddenlink" target="rightframe">action_divider</A> +</nobr><br> +<!-- Method addAll --> +<i>addAll</i><br> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(T...)" class="hiddenlink" target="rightframe">type <b> +()</b> in android.support.v7.util.SortedList +</A></nobr><br> +<!-- Method addAll --> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(T[], boolean)" class="hiddenlink" target="rightframe">type <b> +(<code>T[], boolean</code>)</b> in android.support.v7.util.SortedList +</A></nobr><br> +<!-- Method addAll --> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(java.util.Collection<T>)" class="hiddenlink" target="rightframe">type <b> +(<code>Collection<T></code>)</b> in android.support.v7.util.SortedList +</A></nobr><br> +<!-- Package android.support.v17.leanback.system --> +<A HREF="changes-summary.html#android.support.v17.leanback.system" class="hiddenlink" target="rightframe"><b>android.support.v17.leanback.system</b></A><br> +<!-- Field Base_V12_Widget_AppCompat_AutoCompleteTextView --> +<A NAME="B"></A> +<br><font size="+2">B</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V12_Widget_AppCompat_AutoCompleteTextView" class="hiddenlink" target="rightframe">Base_V12_Widget_AppCompat_AutoCompleteTextView</A> +</nobr><br> +<!-- Field Base_V12_Widget_AppCompat_EditText --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V12_Widget_AppCompat_EditText" class="hiddenlink" target="rightframe">Base_V12_Widget_AppCompat_EditText</A> +</nobr><br> +<!-- Field Base_V7_Widget_AppCompat_AutoCompleteTextView --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V7_Widget_AppCompat_AutoCompleteTextView" class="hiddenlink" target="rightframe">Base_V7_Widget_AppCompat_AutoCompleteTextView</A> +</nobr><br> +<!-- Field Base_V7_Widget_AppCompat_EditText --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V7_Widget_AppCompat_EditText" class="hiddenlink" target="rightframe">Base_V7_Widget_AppCompat_EditText</A> +</nobr><br> +<!-- Field borderlessButtonStyle --> +<nobr><A HREF="android.support.v7.appcompat.R.attr.html#android.support.v7.appcompat.R.attr.borderlessButtonStyle" class="hiddenlink" target="rightframe">borderlessButtonStyle</A> +</nobr><br> +<!-- Field cancel_action --> +<A NAME="C"></A> +<br><font size="+2">C</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.cancel_action" class="hiddenlink" target="rightframe">cancel_action</A> +</nobr><br> +<!-- Field cancel_button_image_alpha --> +<nobr><A HREF="android.support.v7.appcompat.R.integer.html#android.support.v7.appcompat.R.integer.cancel_button_image_alpha" class="hiddenlink" target="rightframe">cancel_button_image_alpha</A> +</nobr><br> +<!-- Field chronometer --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.chronometer" class="hiddenlink" target="rightframe">chronometer</A> +</nobr><br> +<!-- Class DetailsOverviewLogoPresenter --> +<A NAME="D"></A> +<br><font size="+2">D</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewLogoPresenter" class="hiddenlink" target="rightframe"><b>DetailsOverviewLogoPresenter</b></A><br> +<!-- Class DetailsOverviewLogoPresenter.ViewHolder --> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewLogoPresenter.ViewHolder" class="hiddenlink" target="rightframe"><b>DetailsOverviewLogoPresenter.ViewHolder</b></A><br> +<!-- Class DetailsOverviewRow.Listener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewRow.Listener" class="hiddenlink" target="rightframe"><b>DetailsOverviewRow.Listener</b></A><br> +<!-- Field end_padder --> +<A NAME="E"></A> +<br><font size="+2">E</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.end_padder" class="hiddenlink" target="rightframe">end_padder</A> +</nobr><br> +<!-- Class FacetProvider --> +<A NAME="F"></A> +<br><font size="+2">F</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#FacetProvider" class="hiddenlink" target="rightframe"><b><i>FacetProvider</i></b></A><br> +<!-- Class FacetProviderAdapter --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FacetProviderAdapter" class="hiddenlink" target="rightframe"><b><i>FacetProviderAdapter</i></b></A><br> +<!-- Class FullWidthDetailsOverviewRowPresenter --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter</b></A><br> +<!-- Class FullWidthDetailsOverviewRowPresenter.Listener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.Listener" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.Listener</b></A><br> +<!-- Class FullWidthDetailsOverviewRowPresenter.ViewHolder --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.ViewHolder" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.ViewHolder</b></A><br> +<!-- Class FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener</b></A><br> +<!-- Class FullWidthDetailsOverviewSharedElementHelper --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewSharedElementHelper" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewSharedElementHelper</b></A><br> +<!-- Method getFacet --> +<A NAME="G"></A> +<br><font size="+2">G</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>getFacet</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html#android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder +</A></nobr><br> +<!-- Method getFacet --> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.html#android.support.v17.leanback.widget.Presenter.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.Presenter +</A></nobr><br> +<!-- Method getFacet --> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html#android.support.v17.leanback.widget.Presenter.ViewHolder.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.Presenter.ViewHolder +</A></nobr><br> +<!-- Method getFacetProvider --> +<nobr><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.html#android.support.v17.leanback.widget.ItemBridgeAdapter.getFacetProvider_added(int)" class="hiddenlink" target="rightframe"><b>getFacetProvider</b> +(<code>int</code>)</A></nobr><br> +<!-- Method getPresenters --> +<nobr><A HREF="android.support.v17.leanback.widget.PresenterSelector.html#android.support.v17.leanback.widget.PresenterSelector.getPresenters_added()" class="hiddenlink" target="rightframe"><b>getPresenters</b> +()</A></nobr><br> +<!-- Method getSelectedTabPosition --> +<nobr><A HREF="android.support.design.widget.TabLayout.html#android.support.design.widget.TabLayout.getSelectedTabPosition_added()" class="hiddenlink" target="rightframe"><b>getSelectedTabPosition</b> +()</A></nobr><br> +<!-- Method getShadowType --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.getShadowType_added()" class="hiddenlink" target="rightframe"><b>getShadowType</b> +()</A></nobr><br> +<!-- Method getWrappedView --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.getWrappedView_added()" class="hiddenlink" target="rightframe"><b>getWrappedView</b> +()</A></nobr><br> +<!-- Method hide --> +<A NAME="H"></A> +<br><font size="+2">H</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.html#android.support.design.widget.FloatingActionButton.hide_added()" class="hiddenlink" target="rightframe"><b>hide</b> +()</A></nobr><br> +<!-- Method inflateTitle --> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>inflateTitle</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.inflateTitle_added(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)" class="hiddenlink" target="rightframe">type <b> +(<code>LayoutInflater, ViewGroup, Bundle</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> +<!-- Method inflateTitle --> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.inflateTitle_added(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)" class="hiddenlink" target="rightframe">type <b> +(<code>LayoutInflater, ViewGroup, Bundle</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<!-- Field info --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.info" class="hiddenlink" target="rightframe">info</A> +</nobr><br> +<!-- Method isClippingChildren --> +<nobr><A HREF="android.support.v17.leanback.widget.RowPresenter.html#android.support.v17.leanback.widget.RowPresenter.isClippingChildren_added()" class="hiddenlink" target="rightframe"><b>isClippingChildren</b> +()</A></nobr><br> +<!-- Method isSelected --> +<nobr><A HREF="android.support.design.widget.TabLayout.Tab.html#android.support.design.widget.TabLayout.Tab.isSelected_added()" class="hiddenlink" target="rightframe"><b>isSelected</b> +()</A></nobr><br> +<!-- Class ItemAlignmentFacet --> +<A HREF="pkg_android.support.v17.leanback.widget.html#ItemAlignmentFacet" class="hiddenlink" target="rightframe"><b>ItemAlignmentFacet</b></A><br> +<!-- Class ItemAlignmentFacet.ItemAlignmentDef --> +<A HREF="pkg_android.support.v17.leanback.widget.html#ItemAlignmentFacet.ItemAlignmentDef" class="hiddenlink" target="rightframe"><b>ItemAlignmentFacet.ItemAlignmentDef</b></A><br> +<!-- Field LENGTH_INDEFINITE --> +<A NAME="L"></A> +<br><font size="+2">L</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.LENGTH_INDEFINITE" class="hiddenlink" target="rightframe">LENGTH_INDEFINITE</A> +</nobr><br> +<!-- Field line1 --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.line1" class="hiddenlink" target="rightframe">line1</A> +</nobr><br> +<!-- Field line3 --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.line3" class="hiddenlink" target="rightframe">line3</A> +</nobr><br> +<!-- Field media_actions --> +<A NAME="M"></A> +<br><font size="+2">M</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.media_actions" class="hiddenlink" target="rightframe">media_actions</A> +</nobr><br> +<!-- Field notification_large_icon_height --> +<A NAME="N"></A> +<br><font size="+2">N</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_large_icon_height" class="hiddenlink" target="rightframe">notification_large_icon_height</A> +</nobr><br> +<!-- Field notification_large_icon_width --> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_large_icon_width" class="hiddenlink" target="rightframe">notification_large_icon_width</A> +</nobr><br> +<!-- Field notification_media_action --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_media_action" class="hiddenlink" target="rightframe">notification_media_action</A> +</nobr><br> +<!-- Field notification_media_cancel_action --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_media_cancel_action" class="hiddenlink" target="rightframe">notification_media_cancel_action</A> +</nobr><br> +<!-- Field notification_subtext_size --> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_subtext_size" class="hiddenlink" target="rightframe">notification_subtext_size</A> +</nobr><br> +<!-- Field notification_template_big_media --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_big_media" class="hiddenlink" target="rightframe">notification_template_big_media</A> +</nobr><br> +<!-- Field notification_template_big_media_narrow --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_big_media_narrow" class="hiddenlink" target="rightframe">notification_template_big_media_narrow</A> +</nobr><br> +<!-- Field notification_template_icon_bg --> +<nobr><A HREF="android.support.v7.appcompat.R.drawable.html#android.support.v7.appcompat.R.drawable.notification_template_icon_bg" class="hiddenlink" target="rightframe">notification_template_icon_bg</A> +</nobr><br> +<!-- Field notification_template_lines --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_lines" class="hiddenlink" target="rightframe">notification_template_lines</A> +</nobr><br> +<!-- Field notification_template_media --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_media" class="hiddenlink" target="rightframe">notification_template_media</A> +</nobr><br> +<!-- Field notification_template_part_chronometer --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_part_chronometer" class="hiddenlink" target="rightframe">notification_template_part_chronometer</A> +</nobr><br> +<!-- Field notification_template_part_time --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_part_time" class="hiddenlink" target="rightframe">notification_template_part_time</A> +</nobr><br> +<!-- Class NotificationCompat --> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat" class="hiddenlink" target="rightframe"><b>NotificationCompat</b></A><br> +<!-- Class NotificationCompat.Builder --> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat.Builder" class="hiddenlink" target="rightframe"><b>NotificationCompat.Builder</b></A><br> +<!-- Class NotificationCompat.MediaStyle --> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat.MediaStyle" class="hiddenlink" target="rightframe"><b>NotificationCompat.MediaStyle</b></A><br> +<!-- Constructor NotificationCompatBase --> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.html#android.support.v4.app.NotificationCompatBase.ctor_added()" class="hiddenlink" target="rightframe"><b>NotificationCompatBase</b> +()</A></nobr> constructor<br> +<!-- Class OnChildViewHolderSelectedListener --> +<A NAME="O"></A> +<br><font size="+2">O</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#OnChildViewHolderSelectedListener" class="hiddenlink" target="rightframe"><b>OnChildViewHolderSelectedListener</b></A><br> +<!-- Method onDependentViewRemoved --> +<i>onDependentViewRemoved</i><br> + <nobr><A HREF="android.support.design.widget.CoordinatorLayout.Behavior.html#android.support.design.widget.CoordinatorLayout.Behavior.onDependentViewRemoved_added(android.support.design.widget.CoordinatorLayout, V, android.view.View)" class="hiddenlink" target="rightframe">type <b> +(<code>CoordinatorLayout, V, View</code>)</b> in android.support.design.widget.CoordinatorLayout.Behavior +</A></nobr><br> +<!-- Method onDependentViewRemoved --> + <nobr><A HREF="android.support.design.widget.FloatingActionButton.Behavior.html#android.support.design.widget.FloatingActionButton.Behavior.onDependentViewRemoved_added(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.view.View)" class="hiddenlink" target="rightframe">type <b> +(<code>CoordinatorLayout, FloatingActionButton, View</code>)</b> in android.support.design.widget.FloatingActionButton.Behavior +</A></nobr><br> +<!-- Method onLayoutChild --> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.Behavior.html#android.support.design.widget.FloatingActionButton.Behavior.onLayoutChild_added(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, int)" class="hiddenlink" target="rightframe"><b>onLayoutChild</b> +(<code>CoordinatorLayout, FloatingActionButton, int</code>)</A></nobr><br> +<!-- Method onSetDetailsOverviewRowStatus --> +<i>onSetDetailsOverviewRowStatus</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.onSetDetailsOverviewRowStatus_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> +<!-- Method onSetDetailsOverviewRowStatus --> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.onSetDetailsOverviewRowStatus_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<!-- Method onSetRowStatus --> +<i>onSetRowStatus</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.onSetRowStatus_added(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>RowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> +<!-- Method onSetRowStatus --> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.onSetRowStatus_added(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>RowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<!-- Method setActionTextColor --> +<A NAME="S"></A> +<br><font size="+2">S</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>setActionTextColor</i><br> + <nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.setActionTextColor_added(android.content.res.ColorStateList)" class="hiddenlink" target="rightframe">type <b> +(<code>ColorStateList</code>)</b> in android.support.design.widget.Snackbar +</A></nobr><br> +<!-- Method setActionTextColor --> + <nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.setActionTextColor_added(int)" class="hiddenlink" target="rightframe">type <b> +(<code>int</code>)</b> in android.support.design.widget.Snackbar +</A></nobr><br> +<!-- Method setFacet --> +<i>setFacet</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.html#android.support.v17.leanback.widget.Presenter.setFacet_added(java.lang.Class<?>, java.lang.Object)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?>, Object</code>)</b> in android.support.v17.leanback.widget.Presenter +</A></nobr><br> +<!-- Method setFacet --> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html#android.support.v17.leanback.widget.Presenter.ViewHolder.setFacet_added(java.lang.Class<?>, java.lang.Object)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?>, Object</code>)</b> in android.support.v17.leanback.widget.Presenter.ViewHolder +</A></nobr><br> +<!-- Method setupDetailsOverviewRowPresenter --> +<i>setupDetailsOverviewRowPresenter</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.setupDetailsOverviewRowPresenter_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> +<!-- Method setupDetailsOverviewRowPresenter --> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.setupDetailsOverviewRowPresenter_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<!-- Method setupPresenter --> +<i>setupPresenter</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.setupPresenter_added(android.support.v17.leanback.widget.Presenter)" class="hiddenlink" target="rightframe">type <b> +(<code>Presenter</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> +<!-- Method setupPresenter --> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.setupPresenter_added(android.support.v17.leanback.widget.Presenter)" class="hiddenlink" target="rightframe">type <b> +(<code>Presenter</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<!-- Field SHADOW_DYNAMIC --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_DYNAMIC" class="hiddenlink" target="rightframe">SHADOW_DYNAMIC</A> +</nobr><br> +<!-- Field SHADOW_NONE --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_NONE" class="hiddenlink" target="rightframe">SHADOW_NONE</A> +</nobr><br> +<!-- Field SHADOW_STATIC --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_STATIC" class="hiddenlink" target="rightframe">SHADOW_STATIC</A> +</nobr><br> +<!-- Method show --> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.html#android.support.design.widget.FloatingActionButton.show_added()" class="hiddenlink" target="rightframe"><b>show</b> +()</A></nobr><br> +<!-- Field status_bar_latest_event_content --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.status_bar_latest_event_content" class="hiddenlink" target="rightframe">status_bar_latest_event_content</A> +</nobr><br> +<!-- Field status_bar_notification_info_maxnum --> +<nobr><A HREF="android.support.v7.appcompat.R.integer.html#android.support.v7.appcompat.R.integer.status_bar_notification_info_maxnum" class="hiddenlink" target="rightframe">status_bar_notification_info_maxnum</A> +</nobr><br> +<!-- Field status_bar_notification_info_overflow --> +<nobr><A HREF="android.support.v7.appcompat.R.string.html#android.support.v7.appcompat.R.string.status_bar_notification_info_overflow" class="hiddenlink" target="rightframe">status_bar_notification_info_overflow</A> +</nobr><br> +<!-- Method supportsDynamicShadow --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.supportsDynamicShadow_added()" class="hiddenlink" target="rightframe"><b>supportsDynamicShadow</b> +()</A></nobr><br> +<!-- Field text --> +<A NAME="T"></A> +<br><font size="+2">T</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.text" class="hiddenlink" target="rightframe">text</A> +</nobr><br> +<!-- Field text2 --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.text2" class="hiddenlink" target="rightframe">text2</A> +</nobr><br> +<!-- Field TextAppearance_StatusBar_EventContent --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent</A> +</nobr><br> +<!-- Field TextAppearance_StatusBar_EventContent_Info --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Info" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Info</A> +</nobr><br> +<!-- Field TextAppearance_StatusBar_EventContent_Line2 --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Line2" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Line2</A> +</nobr><br> +<!-- Field TextAppearance_StatusBar_EventContent_Time --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Time" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Time</A> +</nobr><br> +<!-- Field TextAppearance_StatusBar_EventContent_Title --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Title" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Title</A> +</nobr><br> +<!-- Field Theme_borderlessButtonStyle --> +<nobr><A HREF="android.support.v7.appcompat.R.styleable.html#android.support.v7.appcompat.R.styleable.Theme_borderlessButtonStyle" class="hiddenlink" target="rightframe">Theme_borderlessButtonStyle</A> +</nobr><br> +<!-- Field time --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.time" class="hiddenlink" target="rightframe">time</A> +</nobr><br> +<!-- Method useDynamicShadow --> +<A NAME="U"></A> +<br><font size="+2">U</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>useDynamicShadow</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useDynamicShadow_added()" class="hiddenlink" target="rightframe">type <b> +()</b> in android.support.v17.leanback.widget.ShadowOverlayContainer +</A></nobr><br> +<!-- Method useDynamicShadow --> + <nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useDynamicShadow_added(float, float)" class="hiddenlink" target="rightframe">type <b> +(<code>float, float</code>)</b> in android.support.v17.leanback.widget.ShadowOverlayContainer +</A></nobr><br> +<!-- Method useStaticShadow --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useStaticShadow_added()" class="hiddenlink" target="rightframe"><b>useStaticShadow</b> +()</A></nobr><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_all.html b/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_all.html new file mode 100644 index 000000000000..bb24c2944fa6 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_all.html @@ -0,0 +1,927 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +All Differences Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for All Differences" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<b>All Differences</b> + <br> +<A HREF="alldiffs_index_removals.html" xclass="hiddenlink">Removals</A> + <br> +<A HREF="alldiffs_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<A HREF="alldiffs_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<!-- Field action0 --> +<A NAME="A"></A> +<br><font size="+2">A</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.action0" class="hiddenlink" target="rightframe">action0</A> +</nobr><br> +<!-- Field action_divider --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.action_divider" class="hiddenlink" target="rightframe">action_divider</A> +</nobr><br> +<!-- Method addAll --> +<i>addAll</i><br> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(T...)" class="hiddenlink" target="rightframe">type <b> +()</b> in android.support.v7.util.SortedList +</A></nobr><br> +<!-- Method addAll --> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(T[], boolean)" class="hiddenlink" target="rightframe">type <b> +(<code>T[], boolean</code>)</b> in android.support.v7.util.SortedList +</A></nobr><br> +<!-- Method addAll --> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(java.util.Collection<T>)" class="hiddenlink" target="rightframe">type <b> +(<code>Collection<T></code>)</b> in android.support.v7.util.SortedList +</A></nobr><br> +<!-- Package android.support.design.widget --> +<A HREF="pkg_android.support.design.widget.html" class="hiddenlink" target="rightframe">android.support.design.widget</A><br> +<!-- Package android.support.v17.leanback.app --> +<A HREF="pkg_android.support.v17.leanback.app.html" class="hiddenlink" target="rightframe">android.support.v17.leanback.app</A><br> +<!-- Package android.support.v17.leanback.system --> +<A HREF="changes-summary.html#android.support.v17.leanback.system" class="hiddenlink" target="rightframe"><b>android.support.v17.leanback.system</b></A><br> +<!-- Package android.support.v17.leanback.widget --> +<A HREF="pkg_android.support.v17.leanback.widget.html" class="hiddenlink" target="rightframe">android.support.v17.leanback.widget</A><br> +<!-- Package android.support.v4.app --> +<A HREF="pkg_android.support.v4.app.html" class="hiddenlink" target="rightframe">android.support.v4.app</A><br> +<!-- Package android.support.v7.app --> +<A HREF="pkg_android.support.v7.app.html" class="hiddenlink" target="rightframe">android.support.v7.app</A><br> +<!-- Package android.support.v7.appcompat --> +<A HREF="pkg_android.support.v7.appcompat.html" class="hiddenlink" target="rightframe">android.support.v7.appcompat</A><br> +<!-- Package android.support.v7.util --> +<A HREF="pkg_android.support.v7.util.html" class="hiddenlink" target="rightframe">android.support.v7.util</A><br> +<!-- Field Base_V12_Widget_AppCompat_AutoCompleteTextView --> +<A NAME="B"></A> +<br><font size="+2">B</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V12_Widget_AppCompat_AutoCompleteTextView" class="hiddenlink" target="rightframe">Base_V12_Widget_AppCompat_AutoCompleteTextView</A> +</nobr><br> +<!-- Field Base_V12_Widget_AppCompat_EditText --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V12_Widget_AppCompat_EditText" class="hiddenlink" target="rightframe">Base_V12_Widget_AppCompat_EditText</A> +</nobr><br> +<!-- Field Base_V7_Widget_AppCompat_AutoCompleteTextView --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V7_Widget_AppCompat_AutoCompleteTextView" class="hiddenlink" target="rightframe">Base_V7_Widget_AppCompat_AutoCompleteTextView</A> +</nobr><br> +<!-- Field Base_V7_Widget_AppCompat_EditText --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V7_Widget_AppCompat_EditText" class="hiddenlink" target="rightframe">Base_V7_Widget_AppCompat_EditText</A> +</nobr><br> +<!-- Class BaseGridView --> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView" class="hiddenlink" target="rightframe"><strike>BaseGridView</strike></A><br> +<!-- Class BaseGridView.OnKeyInterceptListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnKeyInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnKeyInterceptListener</strike></A><br> +<!-- Class BaseGridView.OnMotionInterceptListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnMotionInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnMotionInterceptListener</strike></A><br> +<!-- Class BaseGridView.OnTouchInterceptListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnTouchInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnTouchInterceptListener</strike></A><br> +<!-- Class BaseGridView.OnUnhandledKeyListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnUnhandledKeyListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnUnhandledKeyListener</strike></A><br> +<!-- Field borderlessButtonStyle --> +<nobr><A HREF="android.support.v7.appcompat.R.attr.html#android.support.v7.appcompat.R.attr.borderlessButtonStyle" class="hiddenlink" target="rightframe">borderlessButtonStyle</A> +</nobr><br> +<!-- Field cancel_action --> +<A NAME="C"></A> +<br><font size="+2">C</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.cancel_action" class="hiddenlink" target="rightframe">cancel_action</A> +</nobr><br> +<!-- Field cancel_button_image_alpha --> +<nobr><A HREF="android.support.v7.appcompat.R.integer.html#android.support.v7.appcompat.R.integer.cancel_button_image_alpha" class="hiddenlink" target="rightframe">cancel_button_image_alpha</A> +</nobr><br> +<!-- Field chronometer --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.chronometer" class="hiddenlink" target="rightframe">chronometer</A> +</nobr><br> +<!-- Class CoordinatorLayout.Behavior --> +<A HREF="android.support.design.widget.CoordinatorLayout.Behavior.html" class="hiddenlink" target="rightframe">CoordinatorLayout.Behavior</A><br> +<!-- Class DetailsFragment --> +<A NAME="D"></A> +<br><font size="+2">D</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.app.DetailsFragment.html" class="hiddenlink" target="rightframe">DetailsFragment</A><br> +<!-- Class DetailsOverviewLogoPresenter --> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewLogoPresenter" class="hiddenlink" target="rightframe"><b>DetailsOverviewLogoPresenter</b></A><br> +<!-- Class DetailsOverviewLogoPresenter.ViewHolder --> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewLogoPresenter.ViewHolder" class="hiddenlink" target="rightframe"><b>DetailsOverviewLogoPresenter.ViewHolder</b></A><br> +<!-- Class DetailsOverviewRow.Listener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewRow.Listener" class="hiddenlink" target="rightframe"><b>DetailsOverviewRow.Listener</b></A><br> +<!-- Class DetailsOverviewRowPresenter --> +<A HREF="android.support.v17.leanback.widget.DetailsOverviewRowPresenter.html" class="hiddenlink" target="rightframe">DetailsOverviewRowPresenter</A><br> +<!-- Class DetailsSupportFragment --> +<A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html" class="hiddenlink" target="rightframe">DetailsSupportFragment</A><br> +<!-- Field end_padder --> +<A NAME="E"></A> +<br><font size="+2">E</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.end_padder" class="hiddenlink" target="rightframe">end_padder</A> +</nobr><br> +<!-- Class FacetProvider --> +<A NAME="F"></A> +<br><font size="+2">F</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#FacetProvider" class="hiddenlink" target="rightframe"><b><i>FacetProvider</i></b></A><br> +<!-- Class FacetProviderAdapter --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FacetProviderAdapter" class="hiddenlink" target="rightframe"><b><i>FacetProviderAdapter</i></b></A><br> +<!-- Class FloatingActionButton --> +<A HREF="android.support.design.widget.FloatingActionButton.html" class="hiddenlink" target="rightframe">FloatingActionButton</A><br> +<!-- Class FloatingActionButton.Behavior --> +<A HREF="android.support.design.widget.FloatingActionButton.Behavior.html" class="hiddenlink" target="rightframe">FloatingActionButton.Behavior</A><br> +<!-- Class FullWidthDetailsOverviewRowPresenter --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter</b></A><br> +<!-- Class FullWidthDetailsOverviewRowPresenter.Listener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.Listener" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.Listener</b></A><br> +<!-- Class FullWidthDetailsOverviewRowPresenter.ViewHolder --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.ViewHolder" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.ViewHolder</b></A><br> +<!-- Class FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener</b></A><br> +<!-- Class FullWidthDetailsOverviewSharedElementHelper --> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewSharedElementHelper" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewSharedElementHelper</b></A><br> +<!-- Method getActionIntent --> +<A NAME="G"></A> +<br><font size="+2">G</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>getActionIntent</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getActionIntent_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> +<!-- Method getActionIntent --> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getActionIntent_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<!-- Method getExtras --> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getExtras_changed()" class="hiddenlink" target="rightframe">getExtras +()</A></nobr><br> +<!-- Method getFacet --> +<i>getFacet</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html#android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder +</A></nobr><br> +<!-- Method getFacet --> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.html#android.support.v17.leanback.widget.Presenter.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.Presenter +</A></nobr><br> +<!-- Method getFacet --> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html#android.support.v17.leanback.widget.Presenter.ViewHolder.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.Presenter.ViewHolder +</A></nobr><br> +<!-- Method getFacetProvider --> +<nobr><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.html#android.support.v17.leanback.widget.ItemBridgeAdapter.getFacetProvider_added(int)" class="hiddenlink" target="rightframe"><b>getFacetProvider</b> +(<code>int</code>)</A></nobr><br> +<!-- Method getIcon --> +<i>getIcon</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getIcon_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> +<!-- Method getIcon --> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getIcon_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<!-- Method getPresenters --> +<nobr><A HREF="android.support.v17.leanback.widget.PresenterSelector.html#android.support.v17.leanback.widget.PresenterSelector.getPresenters_added()" class="hiddenlink" target="rightframe"><b>getPresenters</b> +()</A></nobr><br> +<!-- Method getRemoteInputs --> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getRemoteInputs_changed()" class="hiddenlink" target="rightframe">getRemoteInputs +()</A></nobr><br> +<!-- Method getSelectedTabPosition --> +<nobr><A HREF="android.support.design.widget.TabLayout.html#android.support.design.widget.TabLayout.getSelectedTabPosition_added()" class="hiddenlink" target="rightframe"><b>getSelectedTabPosition</b> +()</A></nobr><br> +<!-- Method getShadowType --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.getShadowType_added()" class="hiddenlink" target="rightframe"><b>getShadowType</b> +()</A></nobr><br> +<!-- Method getTitle --> +<i>getTitle</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getTitle_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> +<!-- Method getTitle --> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getTitle_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<!-- Method getWrappedView --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.getWrappedView_added()" class="hiddenlink" target="rightframe"><b>getWrappedView</b> +()</A></nobr><br> +<!-- Class GridLayoutManager --> +<A HREF="pkg_android.support.v17.leanback.widget.html#GridLayoutManager" class="hiddenlink" target="rightframe"><strike>GridLayoutManager</strike></A><br> +<!-- Method hide --> +<A NAME="H"></A> +<br><font size="+2">H</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.html#android.support.design.widget.FloatingActionButton.hide_added()" class="hiddenlink" target="rightframe"><b>hide</b> +()</A></nobr><br> +<!-- Method inflateTitle --> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>inflateTitle</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.inflateTitle_added(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)" class="hiddenlink" target="rightframe">type <b> +(<code>LayoutInflater, ViewGroup, Bundle</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> +<!-- Method inflateTitle --> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.inflateTitle_added(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)" class="hiddenlink" target="rightframe">type <b> +(<code>LayoutInflater, ViewGroup, Bundle</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<!-- Field info --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.info" class="hiddenlink" target="rightframe">info</A> +</nobr><br> +<!-- Method isClippingChildren --> +<nobr><A HREF="android.support.v17.leanback.widget.RowPresenter.html#android.support.v17.leanback.widget.RowPresenter.isClippingChildren_added()" class="hiddenlink" target="rightframe"><b>isClippingChildren</b> +()</A></nobr><br> +<!-- Method isSelected --> +<nobr><A HREF="android.support.design.widget.TabLayout.Tab.html#android.support.design.widget.TabLayout.Tab.isSelected_added()" class="hiddenlink" target="rightframe"><b>isSelected</b> +()</A></nobr><br> +<!-- Method isUsingZOrder --> +<i>isUsingZOrder</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ListRowPresenter.html#android.support.v17.leanback.widget.ListRowPresenter.isUsingZOrder_changed(android.content.Context)" class="hiddenlink" target="rightframe">type +(<code>Context</code>) in android.support.v17.leanback.widget.ListRowPresenter +</A></nobr><br> +<!-- Method isUsingZOrder --> + <nobr><A HREF="android.support.v17.leanback.widget.VerticalGridPresenter.html#android.support.v17.leanback.widget.VerticalGridPresenter.isUsingZOrder_changed(android.content.Context)" class="hiddenlink" target="rightframe">type +(<code>Context</code>) in android.support.v17.leanback.widget.VerticalGridPresenter +</A></nobr><br> +<!-- Class ItemAlignmentFacet --> +<A HREF="pkg_android.support.v17.leanback.widget.html#ItemAlignmentFacet" class="hiddenlink" target="rightframe"><b>ItemAlignmentFacet</b></A><br> +<!-- Class ItemAlignmentFacet.ItemAlignmentDef --> +<A HREF="pkg_android.support.v17.leanback.widget.html#ItemAlignmentFacet.ItemAlignmentDef" class="hiddenlink" target="rightframe"><b>ItemAlignmentFacet.ItemAlignmentDef</b></A><br> +<!-- Class ItemBridgeAdapter --> +<A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.html" class="hiddenlink" target="rightframe">ItemBridgeAdapter</A><br> +<!-- Class ItemBridgeAdapter.ViewHolder --> +<A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html" class="hiddenlink" target="rightframe">ItemBridgeAdapter.ViewHolder</A><br> +<!-- Field LENGTH_INDEFINITE --> +<A NAME="L"></A> +<br><font size="+2">L</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.LENGTH_INDEFINITE" class="hiddenlink" target="rightframe">LENGTH_INDEFINITE</A> +</nobr><br> +<!-- Field line1 --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.line1" class="hiddenlink" target="rightframe">line1</A> +</nobr><br> +<!-- Field line3 --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.line3" class="hiddenlink" target="rightframe">line3</A> +</nobr><br> +<!-- Class ListRowPresenter --> +<A HREF="android.support.v17.leanback.widget.ListRowPresenter.html" class="hiddenlink" target="rightframe">ListRowPresenter</A><br> +<!-- Field media_actions --> +<A NAME="M"></A> +<br><font size="+2">M</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.media_actions" class="hiddenlink" target="rightframe">media_actions</A> +</nobr><br> +<!-- Field notification_large_icon_height --> +<A NAME="N"></A> +<br><font size="+2">N</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_large_icon_height" class="hiddenlink" target="rightframe">notification_large_icon_height</A> +</nobr><br> +<!-- Field notification_large_icon_width --> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_large_icon_width" class="hiddenlink" target="rightframe">notification_large_icon_width</A> +</nobr><br> +<!-- Field notification_media_action --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_media_action" class="hiddenlink" target="rightframe">notification_media_action</A> +</nobr><br> +<!-- Field notification_media_cancel_action --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_media_cancel_action" class="hiddenlink" target="rightframe">notification_media_cancel_action</A> +</nobr><br> +<!-- Field notification_subtext_size --> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_subtext_size" class="hiddenlink" target="rightframe">notification_subtext_size</A> +</nobr><br> +<!-- Field notification_template_big_media --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_big_media" class="hiddenlink" target="rightframe">notification_template_big_media</A> +</nobr><br> +<!-- Field notification_template_big_media_narrow --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_big_media_narrow" class="hiddenlink" target="rightframe">notification_template_big_media_narrow</A> +</nobr><br> +<!-- Field notification_template_icon_bg --> +<nobr><A HREF="android.support.v7.appcompat.R.drawable.html#android.support.v7.appcompat.R.drawable.notification_template_icon_bg" class="hiddenlink" target="rightframe">notification_template_icon_bg</A> +</nobr><br> +<!-- Field notification_template_lines --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_lines" class="hiddenlink" target="rightframe">notification_template_lines</A> +</nobr><br> +<!-- Field notification_template_media --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_media" class="hiddenlink" target="rightframe">notification_template_media</A> +</nobr><br> +<!-- Field notification_template_part_chronometer --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_part_chronometer" class="hiddenlink" target="rightframe">notification_template_part_chronometer</A> +</nobr><br> +<!-- Field notification_template_part_time --> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_part_time" class="hiddenlink" target="rightframe">notification_template_part_time</A> +</nobr><br> +<!-- Class NotificationCompat --> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat" class="hiddenlink" target="rightframe"><b>NotificationCompat</b></A><br> +<!-- Class NotificationCompat.Action --> +<A HREF="android.support.v4.app.NotificationCompat.Action.html" class="hiddenlink" target="rightframe">NotificationCompat.Action</A><br> +<!-- Class NotificationCompat.Builder --> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat.Builder" class="hiddenlink" target="rightframe"><b>NotificationCompat.Builder</b></A><br> +<!-- Class NotificationCompat.MediaStyle --> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat.MediaStyle" class="hiddenlink" target="rightframe"><b>NotificationCompat.MediaStyle</b></A><br> +<!-- Class NotificationCompatBase --> +<i>NotificationCompatBase</i><br> + <A HREF="android.support.v4.app.NotificationCompatBase.html" class="hiddenlink" target="rightframe">android.support.v4.app</A><br> +<!-- Constructor NotificationCompatBase --> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.html#android.support.v4.app.NotificationCompatBase.ctor_added()" class="hiddenlink" target="rightframe"><b>NotificationCompatBase</b> +()</A></nobr> constructor<br> +<!-- Class NotificationCompatBase.Action --> +<A HREF="android.support.v4.app.NotificationCompatBase.Action.html" class="hiddenlink" target="rightframe">NotificationCompatBase.Action</A><br> +<!-- Class OnChildSelectedListener --> +<A NAME="O"></A> +<br><font size="+2">O</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.OnChildSelectedListener.html" class="hiddenlink" target="rightframe"><i>OnChildSelectedListener</i></A><br> +<!-- Class OnChildViewHolderSelectedListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#OnChildViewHolderSelectedListener" class="hiddenlink" target="rightframe"><b>OnChildViewHolderSelectedListener</b></A><br> +<!-- Method onDependentViewRemoved --> +<i>onDependentViewRemoved</i><br> + <nobr><A HREF="android.support.design.widget.CoordinatorLayout.Behavior.html#android.support.design.widget.CoordinatorLayout.Behavior.onDependentViewRemoved_added(android.support.design.widget.CoordinatorLayout, V, android.view.View)" class="hiddenlink" target="rightframe">type <b> +(<code>CoordinatorLayout, V, View</code>)</b> in android.support.design.widget.CoordinatorLayout.Behavior +</A></nobr><br> +<!-- Method onDependentViewRemoved --> + <nobr><A HREF="android.support.design.widget.FloatingActionButton.Behavior.html#android.support.design.widget.FloatingActionButton.Behavior.onDependentViewRemoved_added(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.view.View)" class="hiddenlink" target="rightframe">type <b> +(<code>CoordinatorLayout, FloatingActionButton, View</code>)</b> in android.support.design.widget.FloatingActionButton.Behavior +</A></nobr><br> +<!-- Method onLayoutChild --> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.Behavior.html#android.support.design.widget.FloatingActionButton.Behavior.onLayoutChild_added(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, int)" class="hiddenlink" target="rightframe"><b>onLayoutChild</b> +(<code>CoordinatorLayout, FloatingActionButton, int</code>)</A></nobr><br> +<!-- Method onSetDetailsOverviewRowStatus --> +<i>onSetDetailsOverviewRowStatus</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.onSetDetailsOverviewRowStatus_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> +<!-- Method onSetDetailsOverviewRowStatus --> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.onSetDetailsOverviewRowStatus_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<!-- Method onSetRowStatus --> +<i>onSetRowStatus</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.onSetRowStatus_added(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>RowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> +<!-- Method onSetRowStatus --> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.onSetRowStatus_added(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>RowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<!-- Field Platform_V12_AppCompat --> +<A NAME="P"></A> +<br><font size="+2">P</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Platform_V12_AppCompat" class="hiddenlink" target="rightframe"><strike>Platform_V12_AppCompat</strike></A> +</nobr><br> +<!-- Field Platform_V12_AppCompat_Light --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Platform_V12_AppCompat_Light" class="hiddenlink" target="rightframe"><strike>Platform_V12_AppCompat_Light</strike></A> +</nobr><br> +<!-- Class Presenter --> +<A HREF="android.support.v17.leanback.widget.Presenter.html" class="hiddenlink" target="rightframe">Presenter</A><br> +<!-- Class Presenter.ViewHolder --> +<A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html" class="hiddenlink" target="rightframe">Presenter.ViewHolder</A><br> +<!-- Class PresenterSelector --> +<A HREF="android.support.v17.leanback.widget.PresenterSelector.html" class="hiddenlink" target="rightframe">PresenterSelector</A><br> +<!-- Class R.attr --> +<A NAME="R"></A> +<br><font size="+2">R</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v7.appcompat.R.attr.html" class="hiddenlink" target="rightframe">R.attr</A><br> +<!-- Class R.dimen --> +<A HREF="android.support.v7.appcompat.R.dimen.html" class="hiddenlink" target="rightframe">R.dimen</A><br> +<!-- Class R.drawable --> +<A HREF="android.support.v7.appcompat.R.drawable.html" class="hiddenlink" target="rightframe">R.drawable</A><br> +<!-- Class R.id --> +<A HREF="android.support.v7.appcompat.R.id.html" class="hiddenlink" target="rightframe">R.id</A><br> +<!-- Class R.integer --> +<A HREF="android.support.v7.appcompat.R.integer.html" class="hiddenlink" target="rightframe">R.integer</A><br> +<!-- Class R.layout --> +<A HREF="android.support.v7.appcompat.R.layout.html" class="hiddenlink" target="rightframe">R.layout</A><br> +<!-- Class R.string --> +<A HREF="android.support.v7.appcompat.R.string.html" class="hiddenlink" target="rightframe">R.string</A><br> +<!-- Class R.style --> +<A HREF="android.support.v7.appcompat.R.style.html" class="hiddenlink" target="rightframe">R.style</A><br> +<!-- Class R.styleable --> +<A HREF="android.support.v7.appcompat.R.styleable.html" class="hiddenlink" target="rightframe">R.styleable</A><br> +<!-- Class RowPresenter --> +<A HREF="android.support.v17.leanback.widget.RowPresenter.html" class="hiddenlink" target="rightframe">RowPresenter</A><br> +<!-- Method setActionTextColor --> +<A NAME="S"></A> +<br><font size="+2">S</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>setActionTextColor</i><br> + <nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.setActionTextColor_added(android.content.res.ColorStateList)" class="hiddenlink" target="rightframe">type <b> +(<code>ColorStateList</code>)</b> in android.support.design.widget.Snackbar +</A></nobr><br> +<!-- Method setActionTextColor --> + <nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.setActionTextColor_added(int)" class="hiddenlink" target="rightframe">type <b> +(<code>int</code>)</b> in android.support.design.widget.Snackbar +</A></nobr><br> +<!-- Method setFacet --> +<i>setFacet</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.html#android.support.v17.leanback.widget.Presenter.setFacet_added(java.lang.Class<?>, java.lang.Object)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?>, Object</code>)</b> in android.support.v17.leanback.widget.Presenter +</A></nobr><br> +<!-- Method setFacet --> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html#android.support.v17.leanback.widget.Presenter.ViewHolder.setFacet_added(java.lang.Class<?>, java.lang.Object)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?>, Object</code>)</b> in android.support.v17.leanback.widget.Presenter.ViewHolder +</A></nobr><br> +<!-- Method setupDetailsOverviewRowPresenter --> +<i>setupDetailsOverviewRowPresenter</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.setupDetailsOverviewRowPresenter_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> +<!-- Method setupDetailsOverviewRowPresenter --> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.setupDetailsOverviewRowPresenter_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<!-- Method setupPresenter --> +<i>setupPresenter</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.setupPresenter_added(android.support.v17.leanback.widget.Presenter)" class="hiddenlink" target="rightframe">type <b> +(<code>Presenter</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> +<!-- Method setupPresenter --> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.setupPresenter_added(android.support.v17.leanback.widget.Presenter)" class="hiddenlink" target="rightframe">type <b> +(<code>Presenter</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<!-- Field SHADOW_DYNAMIC --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_DYNAMIC" class="hiddenlink" target="rightframe">SHADOW_DYNAMIC</A> +</nobr><br> +<!-- Field SHADOW_NONE --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_NONE" class="hiddenlink" target="rightframe">SHADOW_NONE</A> +</nobr><br> +<!-- Field SHADOW_STATIC --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_STATIC" class="hiddenlink" target="rightframe">SHADOW_STATIC</A> +</nobr><br> +<!-- Class ShadowOverlayContainer --> +<A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html" class="hiddenlink" target="rightframe">ShadowOverlayContainer</A><br> +<!-- Method show --> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.html#android.support.design.widget.FloatingActionButton.show_added()" class="hiddenlink" target="rightframe"><b>show</b> +()</A></nobr><br> +<!-- Class Snackbar --> +<A HREF="android.support.design.widget.Snackbar.html" class="hiddenlink" target="rightframe">Snackbar</A><br> +<!-- Class SortedList --> +<A HREF="android.support.v7.util.SortedList.html" class="hiddenlink" target="rightframe">SortedList</A><br> +<!-- Field status_bar_latest_event_content --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.status_bar_latest_event_content" class="hiddenlink" target="rightframe">status_bar_latest_event_content</A> +</nobr><br> +<!-- Field status_bar_notification_info_maxnum --> +<nobr><A HREF="android.support.v7.appcompat.R.integer.html#android.support.v7.appcompat.R.integer.status_bar_notification_info_maxnum" class="hiddenlink" target="rightframe">status_bar_notification_info_maxnum</A> +</nobr><br> +<!-- Field status_bar_notification_info_overflow --> +<nobr><A HREF="android.support.v7.appcompat.R.string.html#android.support.v7.appcompat.R.string.status_bar_notification_info_overflow" class="hiddenlink" target="rightframe">status_bar_notification_info_overflow</A> +</nobr><br> +<!-- Method supportsDynamicShadow --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.supportsDynamicShadow_added()" class="hiddenlink" target="rightframe"><b>supportsDynamicShadow</b> +()</A></nobr><br> +<!-- Class TabLayout --> +<A NAME="T"></A> +<br><font size="+2">T</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.design.widget.TabLayout.html" class="hiddenlink" target="rightframe">TabLayout</A><br> +<!-- Class TabLayout.Tab --> +<A HREF="android.support.design.widget.TabLayout.Tab.html" class="hiddenlink" target="rightframe">TabLayout.Tab</A><br> +<!-- Field text --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.text" class="hiddenlink" target="rightframe">text</A> +</nobr><br> +<!-- Field text2 --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.text2" class="hiddenlink" target="rightframe">text2</A> +</nobr><br> +<!-- Field TextAppearance_StatusBar_EventContent --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent</A> +</nobr><br> +<!-- Field TextAppearance_StatusBar_EventContent_Info --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Info" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Info</A> +</nobr><br> +<!-- Field TextAppearance_StatusBar_EventContent_Line2 --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Line2" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Line2</A> +</nobr><br> +<!-- Field TextAppearance_StatusBar_EventContent_Time --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Time" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Time</A> +</nobr><br> +<!-- Field TextAppearance_StatusBar_EventContent_Title --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Title" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Title</A> +</nobr><br> +<!-- Field Theme_borderlessButtonStyle --> +<nobr><A HREF="android.support.v7.appcompat.R.styleable.html#android.support.v7.appcompat.R.styleable.Theme_borderlessButtonStyle" class="hiddenlink" target="rightframe">Theme_borderlessButtonStyle</A> +</nobr><br> +<!-- Field time --> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.time" class="hiddenlink" target="rightframe">time</A> +</nobr><br> +<!-- Method useDynamicShadow --> +<A NAME="U"></A> +<br><font size="+2">U</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>useDynamicShadow</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useDynamicShadow_added()" class="hiddenlink" target="rightframe">type <b> +()</b> in android.support.v17.leanback.widget.ShadowOverlayContainer +</A></nobr><br> +<!-- Method useDynamicShadow --> + <nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useDynamicShadow_added(float, float)" class="hiddenlink" target="rightframe">type <b> +(<code>float, float</code>)</b> in android.support.v17.leanback.widget.ShadowOverlayContainer +</A></nobr><br> +<!-- Method useStaticShadow --> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useStaticShadow_added()" class="hiddenlink" target="rightframe"><b>useStaticShadow</b> +()</A></nobr><br> +<!-- Class VerticalGridPresenter --> +<A NAME="V"></A> +<br><font size="+2">V</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.VerticalGridPresenter.html" class="hiddenlink" target="rightframe">VerticalGridPresenter</A><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_changes.html b/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_changes.html new file mode 100644 index 000000000000..83407498dffe --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_changes.html @@ -0,0 +1,403 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +All Changes Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for All Differences" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="alldiffs_index_all.html" xclass="hiddenlink">All Differences</a> + <br> +<A HREF="alldiffs_index_removals.html" xclass="hiddenlink">Removals</A> + <br> +<A HREF="alldiffs_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<b>Changes</b> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<!-- Package android.support.design.widget --> +<A NAME="A"></A> +<A HREF="pkg_android.support.design.widget.html" class="hiddenlink" target="rightframe">android.support.design.widget</A><br> +<!-- Package android.support.v17.leanback.app --> +<A HREF="pkg_android.support.v17.leanback.app.html" class="hiddenlink" target="rightframe">android.support.v17.leanback.app</A><br> +<!-- Package android.support.v17.leanback.widget --> +<A HREF="pkg_android.support.v17.leanback.widget.html" class="hiddenlink" target="rightframe">android.support.v17.leanback.widget</A><br> +<!-- Package android.support.v4.app --> +<A HREF="pkg_android.support.v4.app.html" class="hiddenlink" target="rightframe">android.support.v4.app</A><br> +<!-- Package android.support.v7.app --> +<A HREF="pkg_android.support.v7.app.html" class="hiddenlink" target="rightframe">android.support.v7.app</A><br> +<!-- Package android.support.v7.appcompat --> +<A HREF="pkg_android.support.v7.appcompat.html" class="hiddenlink" target="rightframe">android.support.v7.appcompat</A><br> +<!-- Package android.support.v7.util --> +<A HREF="pkg_android.support.v7.util.html" class="hiddenlink" target="rightframe">android.support.v7.util</A><br> +<!-- Class CoordinatorLayout.Behavior --> +<A NAME="C"></A> +<br><font size="+2">C</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.design.widget.CoordinatorLayout.Behavior.html" class="hiddenlink" target="rightframe">CoordinatorLayout.Behavior</A><br> +<!-- Class DetailsFragment --> +<A NAME="D"></A> +<br><font size="+2">D</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.app.DetailsFragment.html" class="hiddenlink" target="rightframe">DetailsFragment</A><br> +<!-- Class DetailsOverviewRowPresenter --> +<A HREF="android.support.v17.leanback.widget.DetailsOverviewRowPresenter.html" class="hiddenlink" target="rightframe">DetailsOverviewRowPresenter</A><br> +<!-- Class DetailsSupportFragment --> +<A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html" class="hiddenlink" target="rightframe">DetailsSupportFragment</A><br> +<!-- Class FloatingActionButton --> +<A NAME="F"></A> +<br><font size="+2">F</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.design.widget.FloatingActionButton.html" class="hiddenlink" target="rightframe">FloatingActionButton</A><br> +<!-- Class FloatingActionButton.Behavior --> +<A HREF="android.support.design.widget.FloatingActionButton.Behavior.html" class="hiddenlink" target="rightframe">FloatingActionButton.Behavior</A><br> +<!-- Method getActionIntent --> +<A NAME="G"></A> +<br><font size="+2">G</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>getActionIntent</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getActionIntent_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> +<!-- Method getActionIntent --> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getActionIntent_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<!-- Method getExtras --> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getExtras_changed()" class="hiddenlink" target="rightframe">getExtras +()</A></nobr><br> +<!-- Method getIcon --> +<i>getIcon</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getIcon_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> +<!-- Method getIcon --> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getIcon_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<!-- Method getRemoteInputs --> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getRemoteInputs_changed()" class="hiddenlink" target="rightframe">getRemoteInputs +()</A></nobr><br> +<!-- Method getTitle --> +<i>getTitle</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getTitle_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> +<!-- Method getTitle --> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getTitle_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<!-- Method isUsingZOrder --> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>isUsingZOrder</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ListRowPresenter.html#android.support.v17.leanback.widget.ListRowPresenter.isUsingZOrder_changed(android.content.Context)" class="hiddenlink" target="rightframe">type +(<code>Context</code>) in android.support.v17.leanback.widget.ListRowPresenter +</A></nobr><br> +<!-- Method isUsingZOrder --> + <nobr><A HREF="android.support.v17.leanback.widget.VerticalGridPresenter.html#android.support.v17.leanback.widget.VerticalGridPresenter.isUsingZOrder_changed(android.content.Context)" class="hiddenlink" target="rightframe">type +(<code>Context</code>) in android.support.v17.leanback.widget.VerticalGridPresenter +</A></nobr><br> +<!-- Class ItemBridgeAdapter --> +<A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.html" class="hiddenlink" target="rightframe">ItemBridgeAdapter</A><br> +<!-- Class ItemBridgeAdapter.ViewHolder --> +<A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html" class="hiddenlink" target="rightframe">ItemBridgeAdapter.ViewHolder</A><br> +<!-- Class ListRowPresenter --> +<A NAME="L"></A> +<br><font size="+2">L</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.ListRowPresenter.html" class="hiddenlink" target="rightframe">ListRowPresenter</A><br> +<!-- Class NotificationCompat.Action --> +<A NAME="N"></A> +<br><font size="+2">N</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v4.app.NotificationCompat.Action.html" class="hiddenlink" target="rightframe">NotificationCompat.Action</A><br> +<!-- Class NotificationCompatBase --> +<A HREF="android.support.v4.app.NotificationCompatBase.html" class="hiddenlink" target="rightframe">NotificationCompatBase</A><br> +<!-- Class NotificationCompatBase.Action --> +<A HREF="android.support.v4.app.NotificationCompatBase.Action.html" class="hiddenlink" target="rightframe">NotificationCompatBase.Action</A><br> +<!-- Class OnChildSelectedListener --> +<A NAME="O"></A> +<br><font size="+2">O</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.OnChildSelectedListener.html" class="hiddenlink" target="rightframe"><i>OnChildSelectedListener</i></A><br> +<!-- Class Presenter --> +<A NAME="P"></A> +<br><font size="+2">P</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.Presenter.html" class="hiddenlink" target="rightframe">Presenter</A><br> +<!-- Class Presenter.ViewHolder --> +<A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html" class="hiddenlink" target="rightframe">Presenter.ViewHolder</A><br> +<!-- Class PresenterSelector --> +<A HREF="android.support.v17.leanback.widget.PresenterSelector.html" class="hiddenlink" target="rightframe">PresenterSelector</A><br> +<!-- Class R.attr --> +<A NAME="R"></A> +<br><font size="+2">R</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v7.appcompat.R.attr.html" class="hiddenlink" target="rightframe">R.attr</A><br> +<!-- Class R.dimen --> +<A HREF="android.support.v7.appcompat.R.dimen.html" class="hiddenlink" target="rightframe">R.dimen</A><br> +<!-- Class R.drawable --> +<A HREF="android.support.v7.appcompat.R.drawable.html" class="hiddenlink" target="rightframe">R.drawable</A><br> +<!-- Class R.id --> +<A HREF="android.support.v7.appcompat.R.id.html" class="hiddenlink" target="rightframe">R.id</A><br> +<!-- Class R.integer --> +<A HREF="android.support.v7.appcompat.R.integer.html" class="hiddenlink" target="rightframe">R.integer</A><br> +<!-- Class R.layout --> +<A HREF="android.support.v7.appcompat.R.layout.html" class="hiddenlink" target="rightframe">R.layout</A><br> +<!-- Class R.string --> +<A HREF="android.support.v7.appcompat.R.string.html" class="hiddenlink" target="rightframe">R.string</A><br> +<!-- Class R.style --> +<A HREF="android.support.v7.appcompat.R.style.html" class="hiddenlink" target="rightframe">R.style</A><br> +<!-- Class R.styleable --> +<A HREF="android.support.v7.appcompat.R.styleable.html" class="hiddenlink" target="rightframe">R.styleable</A><br> +<!-- Class RowPresenter --> +<A HREF="android.support.v17.leanback.widget.RowPresenter.html" class="hiddenlink" target="rightframe">RowPresenter</A><br> +<!-- Class ShadowOverlayContainer --> +<A NAME="S"></A> +<br><font size="+2">S</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html" class="hiddenlink" target="rightframe">ShadowOverlayContainer</A><br> +<!-- Class Snackbar --> +<A HREF="android.support.design.widget.Snackbar.html" class="hiddenlink" target="rightframe">Snackbar</A><br> +<!-- Class SortedList --> +<A HREF="android.support.v7.util.SortedList.html" class="hiddenlink" target="rightframe">SortedList</A><br> +<!-- Class TabLayout --> +<A NAME="T"></A> +<br><font size="+2">T</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.design.widget.TabLayout.html" class="hiddenlink" target="rightframe">TabLayout</A><br> +<!-- Class TabLayout.Tab --> +<A HREF="android.support.design.widget.TabLayout.Tab.html" class="hiddenlink" target="rightframe">TabLayout.Tab</A><br> +<!-- Class VerticalGridPresenter --> +<A NAME="V"></A> +<br><font size="+2">V</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.VerticalGridPresenter.html" class="hiddenlink" target="rightframe">VerticalGridPresenter</A><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_removals.html b/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_removals.html new file mode 100644 index 000000000000..0d670c0ec8fe --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/alldiffs_index_removals.html @@ -0,0 +1,97 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +All Removals Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for All Differences" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="alldiffs_index_all.html" xclass="hiddenlink">All Differences</a> + <br> +<b>Removals</b> + <br> +<A HREF="alldiffs_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<A HREF="alldiffs_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<!-- Class BaseGridView --> +<A NAME="B"></A> +<br><font size="+2">B</font> +<a href="#G"><font size="-2">G</font></a> +<a href="#P"><font size="-2">P</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView" class="hiddenlink" target="rightframe"><strike>BaseGridView</strike></A><br> +<!-- Class BaseGridView.OnKeyInterceptListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnKeyInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnKeyInterceptListener</strike></A><br> +<!-- Class BaseGridView.OnMotionInterceptListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnMotionInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnMotionInterceptListener</strike></A><br> +<!-- Class BaseGridView.OnTouchInterceptListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnTouchInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnTouchInterceptListener</strike></A><br> +<!-- Class BaseGridView.OnUnhandledKeyListener --> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnUnhandledKeyListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnUnhandledKeyListener</strike></A><br> +<!-- Class GridLayoutManager --> +<A NAME="G"></A> +<br><font size="+2">G</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#P"><font size="-2">P</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#GridLayoutManager" class="hiddenlink" target="rightframe"><strike>GridLayoutManager</strike></A><br> +<!-- Field Platform_V12_AppCompat --> +<A NAME="P"></A> +<br><font size="+2">P</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#G"><font size="-2">G</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Platform_V12_AppCompat" class="hiddenlink" target="rightframe"><strike>Platform_V12_AppCompat</strike></A> +</nobr><br> +<!-- Field Platform_V12_AppCompat_Light --> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Platform_V12_AppCompat_Light" class="hiddenlink" target="rightframe"><strike>Platform_V12_AppCompat_Light</strike></A> +</nobr><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.CoordinatorLayout.Behavior.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.CoordinatorLayout.Behavior.html new file mode 100644 index 000000000000..78392f44b554 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.CoordinatorLayout.Behavior.html @@ -0,0 +1,122 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.design.widget.CoordinatorLayout.Behavior +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.design.widget.<A HREF="../../../../reference/android/support/design/widget/CoordinatorLayout.Behavior.html" target="_top"><font size="+2"><code>CoordinatorLayout.Behavior</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget.CoordinatorLayout.Behavior.onDependentViewRemoved_added(android.support.design.widget.CoordinatorLayout, V, android.view.View)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/design/widget/CoordinatorLayout.Behavior.html#onDependentViewRemoved(android.support.design.widget.CoordinatorLayout, V, android.view.View)" target="_top"><code>onDependentViewRemoved</code></A>(<code>CoordinatorLayout,</nobr> V<nobr>,</nobr> View<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.FloatingActionButton.Behavior.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.FloatingActionButton.Behavior.html new file mode 100644 index 000000000000..6d689765168e --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.FloatingActionButton.Behavior.html @@ -0,0 +1,129 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.design.widget.FloatingActionButton.Behavior +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.design.widget.<A HREF="../../../../reference/android/support/design/widget/FloatingActionButton.Behavior.html" target="_top"><font size="+2"><code>FloatingActionButton.Behavior</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget.FloatingActionButton.Behavior.onDependentViewRemoved_added(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.view.View)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/design/widget/FloatingActionButton.Behavior.html#onDependentViewRemoved(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.view.View)" target="_top"><code>onDependentViewRemoved</code></A>(<code>CoordinatorLayout,</nobr> FloatingActionButton<nobr>,</nobr> View<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget.FloatingActionButton.Behavior.onLayoutChild_added(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, int)"></A> + <nobr><code>boolean</code> <A HREF="../../../../reference/android/support/design/widget/FloatingActionButton.Behavior.html#onLayoutChild(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, int)" target="_top"><code>onLayoutChild</code></A>(<code>CoordinatorLayout,</nobr> FloatingActionButton<nobr>,</nobr> int<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.FloatingActionButton.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.FloatingActionButton.html new file mode 100644 index 000000000000..21b55c097928 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.FloatingActionButton.html @@ -0,0 +1,129 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.design.widget.FloatingActionButton +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.design.widget.<A HREF="../../../../reference/android/support/design/widget/FloatingActionButton.html" target="_top"><font size="+2"><code>FloatingActionButton</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget.FloatingActionButton.hide_added()"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/design/widget/FloatingActionButton.html#hide()" target="_top"><code>hide</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget.FloatingActionButton.show_added()"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/design/widget/FloatingActionButton.html#show()" target="_top"><code>show</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.Snackbar.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.Snackbar.html new file mode 100644 index 000000000000..028df735a423 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.Snackbar.html @@ -0,0 +1,144 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.design.widget.Snackbar +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.design.widget.<A HREF="../../../../reference/android/support/design/widget/Snackbar.html" target="_top"><font size="+2"><code>Snackbar</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget.Snackbar.setActionTextColor_added(android.content.res.ColorStateList)"></A> + <nobr><code>Snackbar</code> <A HREF="../../../../reference/android/support/design/widget/Snackbar.html#setActionTextColor(android.content.res.ColorStateList)" target="_top"><code>setActionTextColor</code></A>(<code>ColorStateList</code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget.Snackbar.setActionTextColor_added(int)"></A> + <nobr><code>Snackbar</code> <A HREF="../../../../reference/android/support/design/widget/Snackbar.html#setActionTextColor(int)" target="_top"><code>setActionTextColor</code></A>(<code>int</code>)</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget.Snackbar.LENGTH_INDEFINITE"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/design/widget/Snackbar.html#LENGTH_INDEFINITE" target="_top"><code>LENGTH_INDEFINITE</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.TabLayout.Tab.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.TabLayout.Tab.html new file mode 100644 index 000000000000..2acf995d48ea --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.TabLayout.Tab.html @@ -0,0 +1,122 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.design.widget.TabLayout.Tab +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.design.widget.<A HREF="../../../../reference/android/support/design/widget/TabLayout.Tab.html" target="_top"><font size="+2"><code>TabLayout.Tab</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget.TabLayout.Tab.isSelected_added()"></A> + <nobr><code>boolean</code> <A HREF="../../../../reference/android/support/design/widget/TabLayout.Tab.html#isSelected()" target="_top"><code>isSelected</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.TabLayout.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.TabLayout.html new file mode 100644 index 000000000000..22a5ff5e1648 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.design.widget.TabLayout.html @@ -0,0 +1,122 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.design.widget.TabLayout +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.design.widget.<A HREF="../../../../reference/android/support/design/widget/TabLayout.html" target="_top"><font size="+2"><code>TabLayout</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget.TabLayout.getSelectedTabPosition_added()"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/design/widget/TabLayout.html#getSelectedTabPosition()" target="_top"><code>getSelectedTabPosition</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.app.DetailsFragment.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.app.DetailsFragment.html new file mode 100644 index 000000000000..16e57980d564 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.app.DetailsFragment.html @@ -0,0 +1,150 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.app.DetailsFragment +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.app.<A HREF="../../../../reference/android/support/v17/leanback/app/DetailsFragment.html" target="_top"><font size="+2"><code>DetailsFragment</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app.DetailsFragment.inflateTitle_added(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)"></A> + <nobr><code>View</code> <A HREF="../../../../reference/android/support/v17/leanback/app/DetailsFragment.html#inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)" target="_top"><code>inflateTitle</code></A>(<code>LayoutInflater,</nobr> ViewGroup<nobr>,</nobr> Bundle<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app.DetailsFragment.onSetDetailsOverviewRowStatus_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/app/DetailsFragment.html#onSetDetailsOverviewRowStatus(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)" target="_top"><code>onSetDetailsOverviewRowStatus</code></A>(<code>FullWidthDetailsOverviewRowPresenter,</nobr> ViewHolder<nobr>,</nobr> int<nobr>,</nobr> int<nobr>,</nobr> int<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app.DetailsFragment.onSetRowStatus_added(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/app/DetailsFragment.html#onSetRowStatus(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)" target="_top"><code>onSetRowStatus</code></A>(<code>RowPresenter,</nobr> ViewHolder<nobr>,</nobr> int<nobr>,</nobr> int<nobr>,</nobr> int<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app.DetailsFragment.setupDetailsOverviewRowPresenter_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/app/DetailsFragment.html#setupDetailsOverviewRowPresenter(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)" target="_top"><code>setupDetailsOverviewRowPresenter</code></A>(<code>FullWidthDetailsOverviewRowPresenter</code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app.DetailsFragment.setupPresenter_added(android.support.v17.leanback.widget.Presenter)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/app/DetailsFragment.html#setupPresenter(android.support.v17.leanback.widget.Presenter)" target="_top"><code>setupPresenter</code></A>(<code>Presenter</code>)</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.app.DetailsSupportFragment.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.app.DetailsSupportFragment.html new file mode 100644 index 000000000000..78252928e212 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.app.DetailsSupportFragment.html @@ -0,0 +1,150 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.app.DetailsSupportFragment +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.app.<A HREF="../../../../reference/android/support/v17/leanback/app/DetailsSupportFragment.html" target="_top"><font size="+2"><code>DetailsSupportFragment</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app.DetailsSupportFragment.inflateTitle_added(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)"></A> + <nobr><code>View</code> <A HREF="../../../../reference/android/support/v17/leanback/app/DetailsSupportFragment.html#inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)" target="_top"><code>inflateTitle</code></A>(<code>LayoutInflater,</nobr> ViewGroup<nobr>,</nobr> Bundle<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app.DetailsSupportFragment.onSetDetailsOverviewRowStatus_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/app/DetailsSupportFragment.html#onSetDetailsOverviewRowStatus(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)" target="_top"><code>onSetDetailsOverviewRowStatus</code></A>(<code>FullWidthDetailsOverviewRowPresenter,</nobr> ViewHolder<nobr>,</nobr> int<nobr>,</nobr> int<nobr>,</nobr> int<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app.DetailsSupportFragment.onSetRowStatus_added(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/app/DetailsSupportFragment.html#onSetRowStatus(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)" target="_top"><code>onSetRowStatus</code></A>(<code>RowPresenter,</nobr> ViewHolder<nobr>,</nobr> int<nobr>,</nobr> int<nobr>,</nobr> int<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app.DetailsSupportFragment.setupDetailsOverviewRowPresenter_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/app/DetailsSupportFragment.html#setupDetailsOverviewRowPresenter(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)" target="_top"><code>setupDetailsOverviewRowPresenter</code></A>(<code>FullWidthDetailsOverviewRowPresenter</code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app.DetailsSupportFragment.setupPresenter_added(android.support.v17.leanback.widget.Presenter)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/app/DetailsSupportFragment.html#setupPresenter(android.support.v17.leanback.widget.Presenter)" target="_top"><code>setupPresenter</code></A>(<code>Presenter</code>)</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.DetailsOverviewRowPresenter.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.DetailsOverviewRowPresenter.html new file mode 100644 index 000000000000..ba8e6afc75dc --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.DetailsOverviewRowPresenter.html @@ -0,0 +1,108 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.DetailsOverviewRowPresenter +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/DetailsOverviewRowPresenter.html" target="_top"><font size="+2"><code>DetailsOverviewRowPresenter</code></font></A> +</H2> +<p><b>Now deprecated</b>.<br> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html new file mode 100644 index 000000000000..25f1b48ce80d --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html @@ -0,0 +1,123 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/ItemBridgeAdapter.ViewHolder.html" target="_top"><font size="+2"><code>ItemBridgeAdapter.ViewHolder</code></font></A> +</H2> +<p><font xsize="+1">Added interface <code>android.support.v17.leanback.widget.FacetProvider</code>.<br></font> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.getFacet_added(java.lang.Class<?>)"></A> + <nobr><code>Object</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ItemBridgeAdapter.ViewHolder.html#getFacet(java.lang.Class<?>)" target="_top"><code>getFacet</code></A>(<code>Class<?></code>)</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ItemBridgeAdapter.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ItemBridgeAdapter.html new file mode 100644 index 000000000000..a88f69462e37 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ItemBridgeAdapter.html @@ -0,0 +1,123 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.ItemBridgeAdapter +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/ItemBridgeAdapter.html" target="_top"><font size="+2"><code>ItemBridgeAdapter</code></font></A> +</H2> +<p><font xsize="+1">Added interface <code>android.support.v17.leanback.widget.FacetProviderAdapter</code>.<br></font> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ItemBridgeAdapter.getFacetProvider_added(int)"></A> + <nobr><code>FacetProvider</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ItemBridgeAdapter.html#getFacetProvider(int)" target="_top"><code>getFacetProvider</code></A>(<code>int</code>)</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ListRowPresenter.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ListRowPresenter.html new file mode 100644 index 000000000000..5d71011a5238 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ListRowPresenter.html @@ -0,0 +1,125 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.ListRowPresenter +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/ListRowPresenter.html" target="_top"><font size="+2"><code>ListRowPresenter</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=3>Changed Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ListRowPresenter.isUsingZOrder_changed(android.content.Context)"></A> + <nobr><code>boolean</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ListRowPresenter.html#isUsingZOrder(android.content.Context)" target="_top"><code>isUsingZOrder</code></A>(<code>Context</code>) </nobr> + </TD> + <TD VALIGN="TOP" WIDTH="30%"> +Change in signature from <code>void</code> to <code>Context</code>.<br> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.OnChildSelectedListener.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.OnChildSelectedListener.html new file mode 100644 index 000000000000..eb8a563acfc2 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.OnChildSelectedListener.html @@ -0,0 +1,108 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.OnChildSelectedListener +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Interface android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/OnChildSelectedListener.html" target="_top"><font size="+2"><code>OnChildSelectedListener</code></font></A> +</H2> +<p><b>Now deprecated</b>.<br> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.Presenter.ViewHolder.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.Presenter.ViewHolder.html new file mode 100644 index 000000000000..a94d9f542243 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.Presenter.ViewHolder.html @@ -0,0 +1,130 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.Presenter.ViewHolder +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/Presenter.ViewHolder.html" target="_top"><font size="+2"><code>Presenter.ViewHolder</code></font></A> +</H2> +<p><font xsize="+1">Added interface <code>android.support.v17.leanback.widget.FacetProvider</code>.<br></font> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.Presenter.ViewHolder.getFacet_added(java.lang.Class<?>)"></A> + <nobr><code>Object</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/Presenter.ViewHolder.html#getFacet(java.lang.Class<?>)" target="_top"><code>getFacet</code></A>(<code>Class<?></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.Presenter.ViewHolder.setFacet_added(java.lang.Class<?>, java.lang.Object)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/Presenter.ViewHolder.html#setFacet(java.lang.Class<?>, java.lang.Object)" target="_top"><code>setFacet</code></A>(<code>Class<?>,</nobr> Object<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.Presenter.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.Presenter.html new file mode 100644 index 000000000000..fde5e4b1eab4 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.Presenter.html @@ -0,0 +1,130 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.Presenter +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/Presenter.html" target="_top"><font size="+2"><code>Presenter</code></font></A> +</H2> +<p><font xsize="+1">Added interface <code>android.support.v17.leanback.widget.FacetProvider</code>.<br></font> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.Presenter.getFacet_added(java.lang.Class<?>)"></A> + <nobr><code>Object</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/Presenter.html#getFacet(java.lang.Class<?>)" target="_top"><code>getFacet</code></A>(<code>Class<?></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.Presenter.setFacet_added(java.lang.Class<?>, java.lang.Object)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/Presenter.html#setFacet(java.lang.Class<?>, java.lang.Object)" target="_top"><code>setFacet</code></A>(<code>Class<?>,</nobr> Object<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.PresenterSelector.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.PresenterSelector.html new file mode 100644 index 000000000000..06a0a791f60e --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.PresenterSelector.html @@ -0,0 +1,122 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.PresenterSelector +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/PresenterSelector.html" target="_top"><font size="+2"><code>PresenterSelector</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.PresenterSelector.getPresenters_added()"></A> + <nobr><code>Presenter[]</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/PresenterSelector.html#getPresenters()" target="_top"><code>getPresenters</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.RowPresenter.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.RowPresenter.html new file mode 100644 index 000000000000..6da5f9b8cbf9 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.RowPresenter.html @@ -0,0 +1,122 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.RowPresenter +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/RowPresenter.html" target="_top"><font size="+2"><code>RowPresenter</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.RowPresenter.isClippingChildren_added()"></A> + <nobr><code>boolean</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/RowPresenter.html#isClippingChildren()" target="_top"><code>isClippingChildren</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ShadowOverlayContainer.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ShadowOverlayContainer.html new file mode 100644 index 000000000000..ac3ac3a2c96b --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.ShadowOverlayContainer.html @@ -0,0 +1,186 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.ShadowOverlayContainer +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/ShadowOverlayContainer.html" target="_top"><font size="+2"><code>ShadowOverlayContainer</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ShadowOverlayContainer.getShadowType_added()"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ShadowOverlayContainer.html#getShadowType()" target="_top"><code>getShadowType</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ShadowOverlayContainer.getWrappedView_added()"></A> + <nobr><code>View</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ShadowOverlayContainer.html#getWrappedView()" target="_top"><code>getWrappedView</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ShadowOverlayContainer.supportsDynamicShadow_added()"></A> + <nobr><code>boolean</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ShadowOverlayContainer.html#supportsDynamicShadow()" target="_top"><code>supportsDynamicShadow</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ShadowOverlayContainer.useDynamicShadow_added()"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ShadowOverlayContainer.html#useDynamicShadow()" target="_top"><code>useDynamicShadow</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ShadowOverlayContainer.useDynamicShadow_added(float, float)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ShadowOverlayContainer.html#useDynamicShadow(float, float)" target="_top"><code>useDynamicShadow</code></A>(<code>float,</nobr> float<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ShadowOverlayContainer.useStaticShadow_added()"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ShadowOverlayContainer.html#useStaticShadow()" target="_top"><code>useStaticShadow</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_DYNAMIC"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ShadowOverlayContainer.html#SHADOW_DYNAMIC" target="_top"><code>SHADOW_DYNAMIC</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_NONE"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ShadowOverlayContainer.html#SHADOW_NONE" target="_top"><code>SHADOW_NONE</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_STATIC"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/ShadowOverlayContainer.html#SHADOW_STATIC" target="_top"><code>SHADOW_STATIC</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.VerticalGridPresenter.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.VerticalGridPresenter.html new file mode 100644 index 000000000000..ab9ce07ab436 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v17.leanback.widget.VerticalGridPresenter.html @@ -0,0 +1,125 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget.VerticalGridPresenter +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v17.leanback.widget.<A HREF="../../../../reference/android/support/v17/leanback/widget/VerticalGridPresenter.html" target="_top"><font size="+2"><code>VerticalGridPresenter</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=3>Changed Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget.VerticalGridPresenter.isUsingZOrder_changed(android.content.Context)"></A> + <nobr><code>boolean</code> <A HREF="../../../../reference/android/support/v17/leanback/widget/VerticalGridPresenter.html#isUsingZOrder(android.content.Context)" target="_top"><code>isUsingZOrder</code></A>(<code>Context</code>) </nobr> + </TD> + <TD VALIGN="TOP" WIDTH="30%"> +Change in signature from <code>void</code> to <code>Context</code>.<br> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v4.app.NotificationCompat.Action.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v4.app.NotificationCompat.Action.html new file mode 100644 index 000000000000..85196101ca94 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v4.app.NotificationCompat.Action.html @@ -0,0 +1,145 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v4.app.NotificationCompat.Action +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v4.app.<A HREF="../../../../reference/android/support/v4/app/NotificationCompat.Action.html" target="_top"><font size="+2"><code>NotificationCompat.Action</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=3>Changed Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v4.app.NotificationCompat.Action.getActionIntent_changed()"></A> + <nobr><code>PendingIntent</code> <A HREF="../../../../reference/android/support/v4/app/NotificationCompat.Action.html#getActionIntent()" target="_top"><code>getActionIntent</code></A>() </nobr> + </TD> + <TD VALIGN="TOP" WIDTH="30%"> +Change of visibility from protected to public.<br> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v4.app.NotificationCompat.Action.getIcon_changed()"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v4/app/NotificationCompat.Action.html#getIcon()" target="_top"><code>getIcon</code></A>() </nobr> + </TD> + <TD VALIGN="TOP" WIDTH="30%"> +Change of visibility from protected to public.<br> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v4.app.NotificationCompat.Action.getTitle_changed()"></A> + <nobr><code>CharSequence</code> <A HREF="../../../../reference/android/support/v4/app/NotificationCompat.Action.html#getTitle()" target="_top"><code>getTitle</code></A>() </nobr> + </TD> + <TD VALIGN="TOP" WIDTH="30%"> +Change of visibility from protected to public.<br> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v4.app.NotificationCompatBase.Action.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v4.app.NotificationCompatBase.Action.html new file mode 100644 index 000000000000..498374e358fc --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v4.app.NotificationCompatBase.Action.html @@ -0,0 +1,165 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v4.app.NotificationCompatBase.Action +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v4.app.<A HREF="../../../../reference/android/support/v4/app/NotificationCompatBase.Action.html" target="_top"><font size="+2"><code>NotificationCompatBase.Action</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=3>Changed Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v4.app.NotificationCompatBase.Action.getActionIntent_changed()"></A> + <nobr><code>PendingIntent</code> <A HREF="../../../../reference/android/support/v4/app/NotificationCompatBase.Action.html#getActionIntent()" target="_top"><code>getActionIntent</code></A>() </nobr> + </TD> + <TD VALIGN="TOP" WIDTH="30%"> +Change of visibility from protected to public.<br> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v4.app.NotificationCompatBase.Action.getExtras_changed()"></A> + <nobr><code>Bundle</code> <A HREF="../../../../reference/android/support/v4/app/NotificationCompatBase.Action.html#getExtras()" target="_top"><code>getExtras</code></A>() </nobr> + </TD> + <TD VALIGN="TOP" WIDTH="30%"> +Change of visibility from protected to public.<br> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v4.app.NotificationCompatBase.Action.getIcon_changed()"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v4/app/NotificationCompatBase.Action.html#getIcon()" target="_top"><code>getIcon</code></A>() </nobr> + </TD> + <TD VALIGN="TOP" WIDTH="30%"> +Change of visibility from protected to public.<br> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v4.app.NotificationCompatBase.Action.getRemoteInputs_changed()"></A> + <nobr><code>RemoteInput[]</code> <A HREF="../../../../reference/android/support/v4/app/NotificationCompatBase.Action.html#getRemoteInputs()" target="_top"><code>getRemoteInputs</code></A>() </nobr> + </TD> + <TD VALIGN="TOP" WIDTH="30%"> +Change of visibility from protected to public.<br> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v4.app.NotificationCompatBase.Action.getTitle_changed()"></A> + <nobr><code>CharSequence</code> <A HREF="../../../../reference/android/support/v4/app/NotificationCompatBase.Action.html#getTitle()" target="_top"><code>getTitle</code></A>() </nobr> + </TD> + <TD VALIGN="TOP" WIDTH="30%"> +Change of visibility from protected to public.<br> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v4.app.NotificationCompatBase.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v4.app.NotificationCompatBase.html new file mode 100644 index 000000000000..309d7b6b45a1 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v4.app.NotificationCompatBase.html @@ -0,0 +1,123 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v4.app.NotificationCompatBase +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v4.app.<A HREF="../../../../reference/android/support/v4/app/NotificationCompatBase.html" target="_top"><font size="+2"><code>NotificationCompatBase</code></font></A> +</H2> +<p>Change of visibility from to public.<br> +<a NAME="constructors"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Constructors" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Constructors</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v4.app.NotificationCompatBase.ctor_added()"></A> + <nobr><A HREF="../../../../reference/android/support/v4/app/NotificationCompatBase.html#NotificationCompatBase()" target="_top"><code>NotificationCompatBase</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="methods"></a> +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.attr.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.attr.html new file mode 100644 index 000000000000..229289c399c9 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.attr.html @@ -0,0 +1,122 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.appcompat.R.attr +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v7.appcompat.<A HREF="../../../../reference/android/support/v7/appcompat/R.attr.html" target="_top"><font size="+2"><code>R.attr</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.attr.borderlessButtonStyle"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.attr.html#borderlessButtonStyle" target="_top"><code>borderlessButtonStyle</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.dimen.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.dimen.html new file mode 100644 index 000000000000..a253e59320f9 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.dimen.html @@ -0,0 +1,136 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.appcompat.R.dimen +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v7.appcompat.<A HREF="../../../../reference/android/support/v7/appcompat/R.dimen.html" target="_top"><font size="+2"><code>R.dimen</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.dimen.notification_large_icon_height"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.dimen.html#notification_large_icon_height" target="_top"><code>notification_large_icon_height</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.dimen.notification_large_icon_width"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.dimen.html#notification_large_icon_width" target="_top"><code>notification_large_icon_width</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.dimen.notification_subtext_size"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.dimen.html#notification_subtext_size" target="_top"><code>notification_subtext_size</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.drawable.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.drawable.html new file mode 100644 index 000000000000..4f8712752126 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.drawable.html @@ -0,0 +1,122 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.appcompat.R.drawable +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v7.appcompat.<A HREF="../../../../reference/android/support/v7/appcompat/R.drawable.html" target="_top"><font size="+2"><code>R.drawable</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.drawable.notification_template_icon_bg"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.drawable.html#notification_template_icon_bg" target="_top"><code>notification_template_icon_bg</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.id.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.id.html new file mode 100644 index 000000000000..e856c8b9608b --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.id.html @@ -0,0 +1,206 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.appcompat.R.id +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v7.appcompat.<A HREF="../../../../reference/android/support/v7/appcompat/R.id.html" target="_top"><font size="+2"><code>R.id</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.action0"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#action0" target="_top"><code>action0</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.action_divider"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#action_divider" target="_top"><code>action_divider</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.cancel_action"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#cancel_action" target="_top"><code>cancel_action</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.chronometer"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#chronometer" target="_top"><code>chronometer</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.end_padder"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#end_padder" target="_top"><code>end_padder</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.info"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#info" target="_top"><code>info</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.line1"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#line1" target="_top"><code>line1</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.line3"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#line3" target="_top"><code>line3</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.media_actions"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#media_actions" target="_top"><code>media_actions</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.status_bar_latest_event_content"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#status_bar_latest_event_content" target="_top"><code>status_bar_latest_event_content</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.text"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#text" target="_top"><code>text</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.text2"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#text2" target="_top"><code>text2</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.id.time"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.id.html#time" target="_top"><code>time</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.integer.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.integer.html new file mode 100644 index 000000000000..70585a799bbf --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.integer.html @@ -0,0 +1,129 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.appcompat.R.integer +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v7.appcompat.<A HREF="../../../../reference/android/support/v7/appcompat/R.integer.html" target="_top"><font size="+2"><code>R.integer</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.integer.cancel_button_image_alpha"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.integer.html#cancel_button_image_alpha" target="_top"><code>cancel_button_image_alpha</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.integer.status_bar_notification_info_maxnum"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.integer.html#status_bar_notification_info_maxnum" target="_top"><code>status_bar_notification_info_maxnum</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.layout.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.layout.html new file mode 100644 index 000000000000..8130707a294e --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.layout.html @@ -0,0 +1,171 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.appcompat.R.layout +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v7.appcompat.<A HREF="../../../../reference/android/support/v7/appcompat/R.layout.html" target="_top"><font size="+2"><code>R.layout</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.layout.notification_media_action"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.layout.html#notification_media_action" target="_top"><code>notification_media_action</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.layout.notification_media_cancel_action"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.layout.html#notification_media_cancel_action" target="_top"><code>notification_media_cancel_action</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.layout.notification_template_big_media"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.layout.html#notification_template_big_media" target="_top"><code>notification_template_big_media</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.layout.notification_template_big_media_narrow"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.layout.html#notification_template_big_media_narrow" target="_top"><code>notification_template_big_media_narrow</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.layout.notification_template_lines"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.layout.html#notification_template_lines" target="_top"><code>notification_template_lines</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.layout.notification_template_media"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.layout.html#notification_template_media" target="_top"><code>notification_template_media</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.layout.notification_template_part_chronometer"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.layout.html#notification_template_part_chronometer" target="_top"><code>notification_template_part_chronometer</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.layout.notification_template_part_time"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.layout.html#notification_template_part_time" target="_top"><code>notification_template_part_time</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.string.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.string.html new file mode 100644 index 000000000000..6a01b20fe62d --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.string.html @@ -0,0 +1,122 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.appcompat.R.string +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v7.appcompat.<A HREF="../../../../reference/android/support/v7/appcompat/R.string.html" target="_top"><font size="+2"><code>R.string</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.string.status_bar_notification_info_overflow"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.string.html#status_bar_notification_info_overflow" target="_top"><code>status_bar_notification_info_overflow</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.style.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.style.html new file mode 100644 index 000000000000..886f2ce2b8d6 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.style.html @@ -0,0 +1,200 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.appcompat.R.style +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v7.appcompat.<A HREF="../../../../reference/android/support/v7/appcompat/R.style.html" target="_top"><font size="+2"><code>R.style</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> +<p> +<a NAME="Removed"></a> +<TABLE summary="Removed Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Removed Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.Platform_V12_AppCompat"></A> + <code>int</code> Platform_V12_AppCompat + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.Platform_V12_AppCompat_Light"></A> + <code>int</code> Platform_V12_AppCompat_Light + </TD> + <TD> </TD> +</TR> +</TABLE> + +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.Base_V12_Widget_AppCompat_AutoCompleteTextView"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.style.html#Base_V12_Widget_AppCompat_AutoCompleteTextView" target="_top"><code>Base_V12_Widget_AppCompat_AutoCompleteTextView</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.Base_V12_Widget_AppCompat_EditText"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.style.html#Base_V12_Widget_AppCompat_EditText" target="_top"><code>Base_V12_Widget_AppCompat_EditText</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.Base_V7_Widget_AppCompat_AutoCompleteTextView"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.style.html#Base_V7_Widget_AppCompat_AutoCompleteTextView" target="_top"><code>Base_V7_Widget_AppCompat_AutoCompleteTextView</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.Base_V7_Widget_AppCompat_EditText"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.style.html#Base_V7_Widget_AppCompat_EditText" target="_top"><code>Base_V7_Widget_AppCompat_EditText</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.style.html#TextAppearance_StatusBar_EventContent" target="_top"><code>TextAppearance_StatusBar_EventContent</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Info"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.style.html#TextAppearance_StatusBar_EventContent_Info" target="_top"><code>TextAppearance_StatusBar_EventContent_Info</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Line2"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.style.html#TextAppearance_StatusBar_EventContent_Line2" target="_top"><code>TextAppearance_StatusBar_EventContent_Line2</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Time"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.style.html#TextAppearance_StatusBar_EventContent_Time" target="_top"><code>TextAppearance_StatusBar_EventContent_Time</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Title"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.style.html#TextAppearance_StatusBar_EventContent_Title" target="_top"><code>TextAppearance_StatusBar_EventContent_Title</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.styleable.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.styleable.html new file mode 100644 index 000000000000..cd9cd60f45ac --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.appcompat.R.styleable.html @@ -0,0 +1,122 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.appcompat.R.styleable +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v7.appcompat.<A HREF="../../../../reference/android/support/v7/appcompat/R.styleable.html" target="_top"><font size="+2"><code>R.styleable</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<a NAME="fields"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Fields" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat.R.styleable.Theme_borderlessButtonStyle"></A> + <nobr><code>int</code> <A HREF="../../../../reference/android/support/v7/appcompat/R.styleable.html#Theme_borderlessButtonStyle" target="_top"><code>Theme_borderlessButtonStyle</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.util.SortedList.html b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.util.SortedList.html new file mode 100644 index 000000000000..b38c6320a597 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/android.support.v7.util.SortedList.html @@ -0,0 +1,136 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.util.SortedList +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Class android.support.v7.util.<A HREF="../../../../reference/android/support/v7/util/SortedList.html" target="_top"><font size="+2"><code>SortedList</code></font></A> +</H2> +<a NAME="constructors"></a> +<a NAME="methods"></a> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Methods" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.util.SortedList.addAll_added(T...)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v7/util/SortedList.html#addAll(T...)" target="_top"><code>addAll</code></A>()</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.util.SortedList.addAll_added(T[], boolean)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v7/util/SortedList.html#addAll(T[], boolean)" target="_top"><code>addAll</code></A>(<code>T[],</nobr> boolean<nobr><nobr></code>)</nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.util.SortedList.addAll_added(java.util.Collection<T>)"></A> + <nobr><code>void</code> <A HREF="../../../../reference/android/support/v7/util/SortedList.html#addAll(java.util.Collection<T>)" target="_top"><code>addAll</code></A>(<code>Collection<T></code>)</nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<a NAME="fields"></a> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/changes-summary.html b/docs/html/sdk/support_api_diff/22.2.1/changes/changes-summary.html new file mode 100644 index 000000000000..e05b67d92b9a --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/changes-summary.html @@ -0,0 +1,191 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Support Library API Differences Report +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<body class="gc-documentation"> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> + <div id="docTitleContainer"> + <h1>Support Library API Differences Report</h1> +<p>This report details the changes in the Android Support Library API between two versions. +It shows additions, modifications, and removals for packages, classes, methods, and fields. +The report also includes general statistics that characterize the extent and type of the differences.</p> +<p>This report is based a comparison of the Support Library API specifications +whose version level identifiers are given in the upper-right corner of this page. It compares a +newer "to" version's API to an older "from" version's API, noting all changes relative to the +older API. So, for example, API elements marked as removed are no longer present in the "to" +API specification.</p> +<p>To navigate the report, use the "Select a Diffs Index" and "Filter the Index" +controls on the left. The report uses text formatting to indicate <em>interface names</em>, +<a href= ><code>links to reference documentation</code></a>, and <a href= >links to change +description</a>. The statistics are accessible from the "Statistics" link in the upper-right corner.</p> +<p>For more information about the Android API and SDK, +see the <a href="http://developer.android.com/index.html" target="_top">Android Developers site</a>.</p> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Packages" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Packages</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.system"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/system/package-summary.html" target="_top"><code>android.support.v17.leanback.system</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Packages" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=3>Changed Packages</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.design.widget"></A> + <nobr><A HREF="pkg_android.support.design.widget.html">android.support.design.widget</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.app"></A> + <nobr><A HREF="pkg_android.support.v17.leanback.app.html">android.support.v17.leanback.app</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v17.leanback.widget"></A> + <nobr><A HREF="pkg_android.support.v17.leanback.widget.html">android.support.v17.leanback.widget</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v4.app"></A> + <nobr><A HREF="pkg_android.support.v4.app.html">android.support.v4.app</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.app"></A> + <nobr><A HREF="pkg_android.support.v7.app.html">android.support.v7.app</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.appcompat"></A> + <nobr><A HREF="pkg_android.support.v7.appcompat.html">android.support.v7.appcompat</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="android.support.v7.util"></A> + <nobr><A HREF="pkg_android.support.v7.util.html">android.support.v7.util</A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<!-- End of API section --> +<!-- Start of packages section --> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_additions.html b/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_additions.html new file mode 100644 index 000000000000..52b4ab7023f2 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_additions.html @@ -0,0 +1,117 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Class Additions Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Classes" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="classes_index_all.html" class="staysblack">All Classes</a> + <br> +<A HREF="classes_index_removals.html" xclass="hiddenlink">Removals</A> + <br> +<b>Additions</b> + <br> +<A HREF="classes_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="D"></A> +<br><font size="+2">D</font> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewLogoPresenter" class="hiddenlink" target="rightframe"><b>DetailsOverviewLogoPresenter</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewLogoPresenter.ViewHolder" class="hiddenlink" target="rightframe"><b>DetailsOverviewLogoPresenter.ViewHolder</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewRow.Listener" class="hiddenlink" target="rightframe"><b>DetailsOverviewRow.Listener</b></A><br> +<A NAME="F"></A> +<br><font size="+2">F</font> +<a href="#D"><font size="-2">D</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#FacetProvider" class="hiddenlink" target="rightframe"><b><i>FacetProvider</i></b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FacetProviderAdapter" class="hiddenlink" target="rightframe"><b><i>FacetProviderAdapter</i></b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.Listener" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.Listener</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.ViewHolder" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.ViewHolder</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewSharedElementHelper" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewSharedElementHelper</b></A><br> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#ItemAlignmentFacet" class="hiddenlink" target="rightframe"><b>ItemAlignmentFacet</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#ItemAlignmentFacet.ItemAlignmentDef" class="hiddenlink" target="rightframe"><b>ItemAlignmentFacet.ItemAlignmentDef</b></A><br> +<A NAME="N"></A> +<br><font size="+2">N</font> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat" class="hiddenlink" target="rightframe"><b>NotificationCompat</b></A><br> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat.Builder" class="hiddenlink" target="rightframe"><b>NotificationCompat.Builder</b></A><br> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat.MediaStyle" class="hiddenlink" target="rightframe"><b>NotificationCompat.MediaStyle</b></A><br> +<A NAME="O"></A> +<br><font size="+2">O</font> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#N"><font size="-2">N</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#OnChildViewHolderSelectedListener" class="hiddenlink" target="rightframe"><b>OnChildViewHolderSelectedListener</b></A><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_all.html b/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_all.html new file mode 100644 index 000000000000..1edab7ace945 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_all.html @@ -0,0 +1,353 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Class Differences Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Classes" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<b>Classes</b> + <br> +<A HREF="classes_index_removals.html" xclass="hiddenlink">Removals</A> + <br> +<A HREF="classes_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<A HREF="classes_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="B"></A> +<br><font size="+2">B</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView" class="hiddenlink" target="rightframe"><strike>BaseGridView</strike></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnKeyInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnKeyInterceptListener</strike></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnMotionInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnMotionInterceptListener</strike></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnTouchInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnTouchInterceptListener</strike></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnUnhandledKeyListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnUnhandledKeyListener</strike></A><br> +<A NAME="C"></A> +<br><font size="+2">C</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.design.widget.CoordinatorLayout.Behavior.html" class="hiddenlink" target="rightframe">CoordinatorLayout.Behavior</A><br> +<A NAME="D"></A> +<br><font size="+2">D</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.app.DetailsFragment.html" class="hiddenlink" target="rightframe">DetailsFragment</A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewLogoPresenter" class="hiddenlink" target="rightframe"><b>DetailsOverviewLogoPresenter</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewLogoPresenter.ViewHolder" class="hiddenlink" target="rightframe"><b>DetailsOverviewLogoPresenter.ViewHolder</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#DetailsOverviewRow.Listener" class="hiddenlink" target="rightframe"><b>DetailsOverviewRow.Listener</b></A><br> +<A HREF="android.support.v17.leanback.widget.DetailsOverviewRowPresenter.html" class="hiddenlink" target="rightframe">DetailsOverviewRowPresenter</A><br> +<A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html" class="hiddenlink" target="rightframe">DetailsSupportFragment</A><br> +<A NAME="F"></A> +<br><font size="+2">F</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#FacetProvider" class="hiddenlink" target="rightframe"><b><i>FacetProvider</i></b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FacetProviderAdapter" class="hiddenlink" target="rightframe"><b><i>FacetProviderAdapter</i></b></A><br> +<A HREF="android.support.design.widget.FloatingActionButton.html" class="hiddenlink" target="rightframe">FloatingActionButton</A><br> +<A HREF="android.support.design.widget.FloatingActionButton.Behavior.html" class="hiddenlink" target="rightframe">FloatingActionButton.Behavior</A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.Listener" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.Listener</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.ViewHolder" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.ViewHolder</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#FullWidthDetailsOverviewSharedElementHelper" class="hiddenlink" target="rightframe"><b>FullWidthDetailsOverviewSharedElementHelper</b></A><br> +<A NAME="G"></A> +<br><font size="+2">G</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#GridLayoutManager" class="hiddenlink" target="rightframe"><strike>GridLayoutManager</strike></A><br> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#ItemAlignmentFacet" class="hiddenlink" target="rightframe"><b>ItemAlignmentFacet</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#ItemAlignmentFacet.ItemAlignmentDef" class="hiddenlink" target="rightframe"><b>ItemAlignmentFacet.ItemAlignmentDef</b></A><br> +<A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.html" class="hiddenlink" target="rightframe">ItemBridgeAdapter</A><br> +<A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html" class="hiddenlink" target="rightframe">ItemBridgeAdapter.ViewHolder</A><br> +<A NAME="L"></A> +<br><font size="+2">L</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.ListRowPresenter.html" class="hiddenlink" target="rightframe">ListRowPresenter</A><br> +<A NAME="N"></A> +<br><font size="+2">N</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat" class="hiddenlink" target="rightframe"><b>NotificationCompat</b></A><br> +<A HREF="android.support.v4.app.NotificationCompat.Action.html" class="hiddenlink" target="rightframe">NotificationCompat.Action</A><br> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat.Builder" class="hiddenlink" target="rightframe"><b>NotificationCompat.Builder</b></A><br> +<A HREF="pkg_android.support.v7.app.html#NotificationCompat.MediaStyle" class="hiddenlink" target="rightframe"><b>NotificationCompat.MediaStyle</b></A><br> +<A HREF="android.support.v4.app.NotificationCompatBase.html" class="hiddenlink" target="rightframe">NotificationCompatBase</A><br> +<A HREF="android.support.v4.app.NotificationCompatBase.Action.html" class="hiddenlink" target="rightframe">NotificationCompatBase.Action</A><br> +<A NAME="O"></A> +<br><font size="+2">O</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.OnChildSelectedListener.html" class="hiddenlink" target="rightframe"><i>OnChildSelectedListener</i></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#OnChildViewHolderSelectedListener" class="hiddenlink" target="rightframe"><b>OnChildViewHolderSelectedListener</b></A><br> +<A NAME="P"></A> +<br><font size="+2">P</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.Presenter.html" class="hiddenlink" target="rightframe">Presenter</A><br> +<A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html" class="hiddenlink" target="rightframe">Presenter.ViewHolder</A><br> +<A HREF="android.support.v17.leanback.widget.PresenterSelector.html" class="hiddenlink" target="rightframe">PresenterSelector</A><br> +<A NAME="R"></A> +<br><font size="+2">R</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v7.appcompat.R.attr.html" class="hiddenlink" target="rightframe">R.attr</A><br> +<A HREF="android.support.v7.appcompat.R.dimen.html" class="hiddenlink" target="rightframe">R.dimen</A><br> +<A HREF="android.support.v7.appcompat.R.drawable.html" class="hiddenlink" target="rightframe">R.drawable</A><br> +<A HREF="android.support.v7.appcompat.R.id.html" class="hiddenlink" target="rightframe">R.id</A><br> +<A HREF="android.support.v7.appcompat.R.integer.html" class="hiddenlink" target="rightframe">R.integer</A><br> +<A HREF="android.support.v7.appcompat.R.layout.html" class="hiddenlink" target="rightframe">R.layout</A><br> +<A HREF="android.support.v7.appcompat.R.string.html" class="hiddenlink" target="rightframe">R.string</A><br> +<A HREF="android.support.v7.appcompat.R.style.html" class="hiddenlink" target="rightframe">R.style</A><br> +<A HREF="android.support.v7.appcompat.R.styleable.html" class="hiddenlink" target="rightframe">R.styleable</A><br> +<A HREF="android.support.v17.leanback.widget.RowPresenter.html" class="hiddenlink" target="rightframe">RowPresenter</A><br> +<A NAME="S"></A> +<br><font size="+2">S</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html" class="hiddenlink" target="rightframe">ShadowOverlayContainer</A><br> +<A HREF="android.support.design.widget.Snackbar.html" class="hiddenlink" target="rightframe">Snackbar</A><br> +<A HREF="android.support.v7.util.SortedList.html" class="hiddenlink" target="rightframe">SortedList</A><br> +<A NAME="T"></A> +<br><font size="+2">T</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.design.widget.TabLayout.html" class="hiddenlink" target="rightframe">TabLayout</A><br> +<A HREF="android.support.design.widget.TabLayout.Tab.html" class="hiddenlink" target="rightframe">TabLayout.Tab</A><br> +<A NAME="V"></A> +<br><font size="+2">V</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.VerticalGridPresenter.html" class="hiddenlink" target="rightframe">VerticalGridPresenter</A><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_changes.html b/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_changes.html new file mode 100644 index 000000000000..f46bc674d12a --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_changes.html @@ -0,0 +1,273 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Class Changes Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Classes" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="classes_index_all.html" class="staysblack">All Classes</a> + <br> +<A HREF="classes_index_removals.html" xclass="hiddenlink">Removals</A> + <br> +<A HREF="classes_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<b>Changes</b> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="C"></A> +<br><font size="+2">C</font> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.design.widget.CoordinatorLayout.Behavior.html" class="hiddenlink" target="rightframe">CoordinatorLayout.Behavior</A><br> +<A NAME="D"></A> +<br><font size="+2">D</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.app.DetailsFragment.html" class="hiddenlink" target="rightframe">DetailsFragment</A><br> +<A HREF="android.support.v17.leanback.widget.DetailsOverviewRowPresenter.html" class="hiddenlink" target="rightframe">DetailsOverviewRowPresenter</A><br> +<A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html" class="hiddenlink" target="rightframe">DetailsSupportFragment</A><br> +<A NAME="F"></A> +<br><font size="+2">F</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.design.widget.FloatingActionButton.html" class="hiddenlink" target="rightframe">FloatingActionButton</A><br> +<A HREF="android.support.design.widget.FloatingActionButton.Behavior.html" class="hiddenlink" target="rightframe">FloatingActionButton.Behavior</A><br> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.html" class="hiddenlink" target="rightframe">ItemBridgeAdapter</A><br> +<A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html" class="hiddenlink" target="rightframe">ItemBridgeAdapter.ViewHolder</A><br> +<A NAME="L"></A> +<br><font size="+2">L</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.ListRowPresenter.html" class="hiddenlink" target="rightframe">ListRowPresenter</A><br> +<A NAME="N"></A> +<br><font size="+2">N</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v4.app.NotificationCompat.Action.html" class="hiddenlink" target="rightframe">NotificationCompat.Action</A><br> +<A HREF="android.support.v4.app.NotificationCompatBase.html" class="hiddenlink" target="rightframe">NotificationCompatBase</A><br> +<A HREF="android.support.v4.app.NotificationCompatBase.Action.html" class="hiddenlink" target="rightframe">NotificationCompatBase.Action</A><br> +<A NAME="O"></A> +<br><font size="+2">O</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.OnChildSelectedListener.html" class="hiddenlink" target="rightframe"><i>OnChildSelectedListener</i></A><br> +<A NAME="P"></A> +<br><font size="+2">P</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.Presenter.html" class="hiddenlink" target="rightframe">Presenter</A><br> +<A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html" class="hiddenlink" target="rightframe">Presenter.ViewHolder</A><br> +<A HREF="android.support.v17.leanback.widget.PresenterSelector.html" class="hiddenlink" target="rightframe">PresenterSelector</A><br> +<A NAME="R"></A> +<br><font size="+2">R</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v7.appcompat.R.attr.html" class="hiddenlink" target="rightframe">R.attr</A><br> +<A HREF="android.support.v7.appcompat.R.dimen.html" class="hiddenlink" target="rightframe">R.dimen</A><br> +<A HREF="android.support.v7.appcompat.R.drawable.html" class="hiddenlink" target="rightframe">R.drawable</A><br> +<A HREF="android.support.v7.appcompat.R.id.html" class="hiddenlink" target="rightframe">R.id</A><br> +<A HREF="android.support.v7.appcompat.R.integer.html" class="hiddenlink" target="rightframe">R.integer</A><br> +<A HREF="android.support.v7.appcompat.R.layout.html" class="hiddenlink" target="rightframe">R.layout</A><br> +<A HREF="android.support.v7.appcompat.R.string.html" class="hiddenlink" target="rightframe">R.string</A><br> +<A HREF="android.support.v7.appcompat.R.style.html" class="hiddenlink" target="rightframe">R.style</A><br> +<A HREF="android.support.v7.appcompat.R.styleable.html" class="hiddenlink" target="rightframe">R.styleable</A><br> +<A HREF="android.support.v17.leanback.widget.RowPresenter.html" class="hiddenlink" target="rightframe">RowPresenter</A><br> +<A NAME="S"></A> +<br><font size="+2">S</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#T"><font size="-2">T</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html" class="hiddenlink" target="rightframe">ShadowOverlayContainer</A><br> +<A HREF="android.support.design.widget.Snackbar.html" class="hiddenlink" target="rightframe">Snackbar</A><br> +<A HREF="android.support.v7.util.SortedList.html" class="hiddenlink" target="rightframe">SortedList</A><br> +<A NAME="T"></A> +<br><font size="+2">T</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#V"><font size="-2">V</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.design.widget.TabLayout.html" class="hiddenlink" target="rightframe">TabLayout</A><br> +<A HREF="android.support.design.widget.TabLayout.Tab.html" class="hiddenlink" target="rightframe">TabLayout.Tab</A><br> +<A NAME="V"></A> +<br><font size="+2">V</font> +<a href="#C"><font size="-2">C</font></a> +<a href="#D"><font size="-2">D</font></a> +<a href="#F"><font size="-2">F</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#R"><font size="-2">R</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="android.support.v17.leanback.widget.VerticalGridPresenter.html" class="hiddenlink" target="rightframe">VerticalGridPresenter</A><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_removals.html b/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_removals.html new file mode 100644 index 000000000000..09c0d19ca6ba --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/classes_index_removals.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Class Removals Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Classes" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="classes_index_all.html" class="staysblack">All Classes</a> + <br> +<b>Removals</b> + <br> +<A HREF="classes_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<A HREF="classes_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="B"></A> +<br><font size="+2">B</font> +<a href="#G"><font size="-2">G</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView" class="hiddenlink" target="rightframe"><strike>BaseGridView</strike></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnKeyInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnKeyInterceptListener</strike></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnMotionInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnMotionInterceptListener</strike></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnTouchInterceptListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnTouchInterceptListener</strike></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html#BaseGridView.OnUnhandledKeyListener" class="hiddenlink" target="rightframe"><strike>BaseGridView.OnUnhandledKeyListener</strike></A><br> +<A NAME="G"></A> +<br><font size="+2">G</font> +<a href="#B"><font size="-2">B</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<A HREF="pkg_android.support.v17.leanback.widget.html#GridLayoutManager" class="hiddenlink" target="rightframe"><strike>GridLayoutManager</strike></A><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_additions.html b/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_additions.html new file mode 100644 index 000000000000..e694216ea6d0 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_additions.html @@ -0,0 +1,67 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Constructor Additions Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Constructors" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="constructors_index_all.html" class="staysblack">All Constructors</a> + <br> +<font color="#999999">Removals</font> + <br> +<b>Additions</b> + <br> +<font color="#999999">Changes</font> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="N"></A> +<br><font size="+2">N</font> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.html#android.support.v4.app.NotificationCompatBase.ctor_added()" class="hiddenlink" target="rightframe"><b>NotificationCompatBase</b> +()</A></nobr> constructor<br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_all.html b/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_all.html new file mode 100644 index 000000000000..27d7557f9a15 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_all.html @@ -0,0 +1,67 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Constructor Differences Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Constructors" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<b>Constructors</b> + <br> +<font color="#999999">Removals</font> + <br> +<A HREF="constructors_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<font color="#999999">Changes</font> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="N"></A> +<br><font size="+2">N</font> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.html#android.support.v4.app.NotificationCompatBase.ctor_added()" class="hiddenlink" target="rightframe"><b>NotificationCompatBase</b> +()</A></nobr> constructor<br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_changes.html b/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_changes.html new file mode 100644 index 000000000000..a5ca2efd88f9 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_changes.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Constructor Changes Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Constructors" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="constructors_index_all.html" class="staysblack">All Constructors</a> + <br> +<font color="#999999">Removals</font> + <br> +<A HREF="constructors_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<font color="#999999">Changes</font> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_removals.html b/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_removals.html new file mode 100644 index 000000000000..74a09badbd99 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/constructors_index_removals.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Constructor Removals Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Constructors" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="constructors_index_all.html" class="staysblack">All Constructors</a> + <br> +<font color="#999999">Removals</font> + <br> +<A HREF="constructors_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<font color="#999999">Changes</font> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_additions.html b/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_additions.html new file mode 100644 index 000000000000..2ae52377ed25 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_additions.html @@ -0,0 +1,277 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Field Additions Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Fields" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="fields_index_all.html" class="staysblack">All Fields</a> + <br> +<A HREF="fields_index_removals.html" xclass="hiddenlink">Removals</A> + <br> +<b>Additions</b> + <br> +<font color="#999999">Changes</font> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="A"></A> +<br><font size="+2">A</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.action0" class="hiddenlink" target="rightframe">action0</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.action_divider" class="hiddenlink" target="rightframe">action_divider</A> +</nobr><br> +<A NAME="B"></A> +<br><font size="+2">B</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V12_Widget_AppCompat_AutoCompleteTextView" class="hiddenlink" target="rightframe">Base_V12_Widget_AppCompat_AutoCompleteTextView</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V12_Widget_AppCompat_EditText" class="hiddenlink" target="rightframe">Base_V12_Widget_AppCompat_EditText</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V7_Widget_AppCompat_AutoCompleteTextView" class="hiddenlink" target="rightframe">Base_V7_Widget_AppCompat_AutoCompleteTextView</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V7_Widget_AppCompat_EditText" class="hiddenlink" target="rightframe">Base_V7_Widget_AppCompat_EditText</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.attr.html#android.support.v7.appcompat.R.attr.borderlessButtonStyle" class="hiddenlink" target="rightframe">borderlessButtonStyle</A> +</nobr><br> +<A NAME="C"></A> +<br><font size="+2">C</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.cancel_action" class="hiddenlink" target="rightframe">cancel_action</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.integer.html#android.support.v7.appcompat.R.integer.cancel_button_image_alpha" class="hiddenlink" target="rightframe">cancel_button_image_alpha</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.chronometer" class="hiddenlink" target="rightframe">chronometer</A> +</nobr><br> +<A NAME="E"></A> +<br><font size="+2">E</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.end_padder" class="hiddenlink" target="rightframe">end_padder</A> +</nobr><br> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.info" class="hiddenlink" target="rightframe">info</A> +</nobr><br> +<A NAME="L"></A> +<br><font size="+2">L</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.LENGTH_INDEFINITE" class="hiddenlink" target="rightframe">LENGTH_INDEFINITE</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.line1" class="hiddenlink" target="rightframe">line1</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.line3" class="hiddenlink" target="rightframe">line3</A> +</nobr><br> +<A NAME="M"></A> +<br><font size="+2">M</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.media_actions" class="hiddenlink" target="rightframe">media_actions</A> +</nobr><br> +<A NAME="N"></A> +<br><font size="+2">N</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_large_icon_height" class="hiddenlink" target="rightframe">notification_large_icon_height</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_large_icon_width" class="hiddenlink" target="rightframe">notification_large_icon_width</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_media_action" class="hiddenlink" target="rightframe">notification_media_action</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_media_cancel_action" class="hiddenlink" target="rightframe">notification_media_cancel_action</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_subtext_size" class="hiddenlink" target="rightframe">notification_subtext_size</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_big_media" class="hiddenlink" target="rightframe">notification_template_big_media</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_big_media_narrow" class="hiddenlink" target="rightframe">notification_template_big_media_narrow</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.drawable.html#android.support.v7.appcompat.R.drawable.notification_template_icon_bg" class="hiddenlink" target="rightframe">notification_template_icon_bg</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_lines" class="hiddenlink" target="rightframe">notification_template_lines</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_media" class="hiddenlink" target="rightframe">notification_template_media</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_part_chronometer" class="hiddenlink" target="rightframe">notification_template_part_chronometer</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_part_time" class="hiddenlink" target="rightframe">notification_template_part_time</A> +</nobr><br> +<A NAME="S"></A> +<br><font size="+2">S</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_DYNAMIC" class="hiddenlink" target="rightframe">SHADOW_DYNAMIC</A> +</nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_NONE" class="hiddenlink" target="rightframe">SHADOW_NONE</A> +</nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_STATIC" class="hiddenlink" target="rightframe">SHADOW_STATIC</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.status_bar_latest_event_content" class="hiddenlink" target="rightframe">status_bar_latest_event_content</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.integer.html#android.support.v7.appcompat.R.integer.status_bar_notification_info_maxnum" class="hiddenlink" target="rightframe">status_bar_notification_info_maxnum</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.string.html#android.support.v7.appcompat.R.string.status_bar_notification_info_overflow" class="hiddenlink" target="rightframe">status_bar_notification_info_overflow</A> +</nobr><br> +<A NAME="T"></A> +<br><font size="+2">T</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#S"><font size="-2">S</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.text" class="hiddenlink" target="rightframe">text</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.text2" class="hiddenlink" target="rightframe">text2</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Info" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Info</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Line2" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Line2</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Time" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Time</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Title" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Title</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.styleable.html#android.support.v7.appcompat.R.styleable.Theme_borderlessButtonStyle" class="hiddenlink" target="rightframe">Theme_borderlessButtonStyle</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.time" class="hiddenlink" target="rightframe">time</A> +</nobr><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_all.html b/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_all.html new file mode 100644 index 000000000000..4a9194d4ee65 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_all.html @@ -0,0 +1,305 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Field Differences Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Fields" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<b>Fields</b> + <br> +<A HREF="fields_index_removals.html" xclass="hiddenlink">Removals</A> + <br> +<A HREF="fields_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<font color="#999999">Changes</font> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="A"></A> +<br><font size="+2">A</font> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.action0" class="hiddenlink" target="rightframe">action0</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.action_divider" class="hiddenlink" target="rightframe">action_divider</A> +</nobr><br> +<A NAME="B"></A> +<br><font size="+2">B</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V12_Widget_AppCompat_AutoCompleteTextView" class="hiddenlink" target="rightframe">Base_V12_Widget_AppCompat_AutoCompleteTextView</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V12_Widget_AppCompat_EditText" class="hiddenlink" target="rightframe">Base_V12_Widget_AppCompat_EditText</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V7_Widget_AppCompat_AutoCompleteTextView" class="hiddenlink" target="rightframe">Base_V7_Widget_AppCompat_AutoCompleteTextView</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Base_V7_Widget_AppCompat_EditText" class="hiddenlink" target="rightframe">Base_V7_Widget_AppCompat_EditText</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.attr.html#android.support.v7.appcompat.R.attr.borderlessButtonStyle" class="hiddenlink" target="rightframe">borderlessButtonStyle</A> +</nobr><br> +<A NAME="C"></A> +<br><font size="+2">C</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.cancel_action" class="hiddenlink" target="rightframe">cancel_action</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.integer.html#android.support.v7.appcompat.R.integer.cancel_button_image_alpha" class="hiddenlink" target="rightframe">cancel_button_image_alpha</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.chronometer" class="hiddenlink" target="rightframe">chronometer</A> +</nobr><br> +<A NAME="E"></A> +<br><font size="+2">E</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.end_padder" class="hiddenlink" target="rightframe">end_padder</A> +</nobr><br> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.info" class="hiddenlink" target="rightframe">info</A> +</nobr><br> +<A NAME="L"></A> +<br><font size="+2">L</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.LENGTH_INDEFINITE" class="hiddenlink" target="rightframe">LENGTH_INDEFINITE</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.line1" class="hiddenlink" target="rightframe">line1</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.line3" class="hiddenlink" target="rightframe">line3</A> +</nobr><br> +<A NAME="M"></A> +<br><font size="+2">M</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.media_actions" class="hiddenlink" target="rightframe">media_actions</A> +</nobr><br> +<A NAME="N"></A> +<br><font size="+2">N</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_large_icon_height" class="hiddenlink" target="rightframe">notification_large_icon_height</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_large_icon_width" class="hiddenlink" target="rightframe">notification_large_icon_width</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_media_action" class="hiddenlink" target="rightframe">notification_media_action</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_media_cancel_action" class="hiddenlink" target="rightframe">notification_media_cancel_action</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.dimen.html#android.support.v7.appcompat.R.dimen.notification_subtext_size" class="hiddenlink" target="rightframe">notification_subtext_size</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_big_media" class="hiddenlink" target="rightframe">notification_template_big_media</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_big_media_narrow" class="hiddenlink" target="rightframe">notification_template_big_media_narrow</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.drawable.html#android.support.v7.appcompat.R.drawable.notification_template_icon_bg" class="hiddenlink" target="rightframe">notification_template_icon_bg</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_lines" class="hiddenlink" target="rightframe">notification_template_lines</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_media" class="hiddenlink" target="rightframe">notification_template_media</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_part_chronometer" class="hiddenlink" target="rightframe">notification_template_part_chronometer</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.layout.html#android.support.v7.appcompat.R.layout.notification_template_part_time" class="hiddenlink" target="rightframe">notification_template_part_time</A> +</nobr><br> +<A NAME="P"></A> +<br><font size="+2">P</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Platform_V12_AppCompat" class="hiddenlink" target="rightframe"><strike>Platform_V12_AppCompat</strike></A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Platform_V12_AppCompat_Light" class="hiddenlink" target="rightframe"><strike>Platform_V12_AppCompat_Light</strike></A> +</nobr><br> +<A NAME="S"></A> +<br><font size="+2">S</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#T"><font size="-2">T</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_DYNAMIC" class="hiddenlink" target="rightframe">SHADOW_DYNAMIC</A> +</nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_NONE" class="hiddenlink" target="rightframe">SHADOW_NONE</A> +</nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.SHADOW_STATIC" class="hiddenlink" target="rightframe">SHADOW_STATIC</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.status_bar_latest_event_content" class="hiddenlink" target="rightframe">status_bar_latest_event_content</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.integer.html#android.support.v7.appcompat.R.integer.status_bar_notification_info_maxnum" class="hiddenlink" target="rightframe">status_bar_notification_info_maxnum</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.string.html#android.support.v7.appcompat.R.string.status_bar_notification_info_overflow" class="hiddenlink" target="rightframe">status_bar_notification_info_overflow</A> +</nobr><br> +<A NAME="T"></A> +<br><font size="+2">T</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#B"><font size="-2">B</font></a> +<a href="#C"><font size="-2">C</font></a> +<a href="#E"><font size="-2">E</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#L"><font size="-2">L</font></a> +<a href="#M"><font size="-2">M</font></a> +<a href="#N"><font size="-2">N</font></a> +<a href="#P"><font size="-2">P</font></a> +<a href="#S"><font size="-2">S</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.text" class="hiddenlink" target="rightframe">text</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.text2" class="hiddenlink" target="rightframe">text2</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Info" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Info</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Line2" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Line2</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Time" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Time</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.TextAppearance_StatusBar_EventContent_Title" class="hiddenlink" target="rightframe">TextAppearance_StatusBar_EventContent_Title</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.styleable.html#android.support.v7.appcompat.R.styleable.Theme_borderlessButtonStyle" class="hiddenlink" target="rightframe">Theme_borderlessButtonStyle</A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.id.html#android.support.v7.appcompat.R.id.time" class="hiddenlink" target="rightframe">time</A> +</nobr><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_changes.html b/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_changes.html new file mode 100644 index 000000000000..0e2ccff6c01b --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_changes.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Field Changes Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Fields" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="fields_index_all.html" class="staysblack">All Fields</a> + <br> +<A HREF="fields_index_removals.html" xclass="hiddenlink">Removals</A> + <br> +<A HREF="fields_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<font color="#999999">Changes</font> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_removals.html b/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_removals.html new file mode 100644 index 000000000000..6245b05ff2e6 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/fields_index_removals.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Field Removals Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Fields" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="fields_index_all.html" class="staysblack">All Fields</a> + <br> +<b>Removals</b> + <br> +<A HREF="fields_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<font color="#999999">Changes</font> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="P"></A> +<br><font size="+2">P</font> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Platform_V12_AppCompat" class="hiddenlink" target="rightframe"><strike>Platform_V12_AppCompat</strike></A> +</nobr><br> +<nobr><A HREF="android.support.v7.appcompat.R.style.html#android.support.v7.appcompat.R.style.Platform_V12_AppCompat_Light" class="hiddenlink" target="rightframe"><strike>Platform_V12_AppCompat_Light</strike></A> +</nobr><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/jdiff_help.html b/docs/html/sdk/support_api_diff/22.2.1/changes/jdiff_help.html new file mode 100644 index 000000000000..25acfbe5cb92 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/jdiff_help.html @@ -0,0 +1,134 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +JDiff Help +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<TABLE summary="Navigation bar" BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0"> +<TR> +<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> + <TABLE summary="Navigation bar" BORDER="0" CELLPADDING="0" CELLSPACING="3"> + <TR ALIGN="center" VALIGN="top"> + <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../reference/index.html" target="_top"><FONT CLASS="NavBarFont1"><B><code>22.2.1</code></B></FONT></A> </TD> + <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="changes-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD> + <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD> + <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD> + <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="jdiff_statistics.html"><FONT CLASS="NavBarFont1"><B>Statistics</B></FONT></A> </TD> + <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT> </TD> + </TR> + </TABLE> +</TD> +<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM><b>Generated by<br><a href="http://www.jdiff.org" class="staysblack" target="_top">JDiff</a></b></EM></TD> +</TR> +<TR> + <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell2"><FONT SIZE="-2"></FONT> +</TD> + <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell2"><FONT SIZE="-2"> + <A HREF="../changes.html" TARGET="_top"><B>FRAMES</B></A> + <A HREF="jdiff_help.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD> +</TR> +</TABLE> +<HR> +<!-- End of nav bar --> +<center> +<H1>JDiff Documentation</H1> +</center> +<BLOCKQUOTE> +JDiff is a <a href="http://java.sun.com/j2se/javadoc/" target="_top">Javadoc</a> doclet which generates a report of the API differences between two versions of a product. It does not report changes in Javadoc comments, or changes in what a class or method does. +This help page describes the different parts of the output from JDiff. +</BLOCKQUOTE> +<BLOCKQUOTE> + See the reference page in the <a href="http://www.jdiff.org">source for JDiff</a> for information about how to generate a report like this one. +</BLOCKQUOTE> +<BLOCKQUOTE> +The indexes shown in the top-left frame help show each type of change in more detail. The index "All Differences" contains all the differences between the APIs, in alphabetical order. +These indexes all use the same format: +<ul> +<li>Removed packages, classes, constructors, methods and fields are <strike>struck through</strike>.</li> +<li>Added packages, classes, constructors, methods and fields appear in <b>bold</b>.</li> +<li>Changed packages, classes, constructors, methods and fields appear in normal text.</li> +</ul> +</BLOCKQUOTE> +<BLOCKQUOTE> +You can always tell when you are reading a JDiff page, rather than a Javadoc page, by the color of the index bar and the color of the background. +Links which take you to a Javadoc page are always in a <code>typewriter</code> font. +Just like Javadoc, all interface names are in <i>italic</i>, and class names are not italicized. Where there are multiple entries in an index with the same name, the heading for them is also in italics, but is not a link. +</BLOCKQUOTE> +<BLOCKQUOTE> +<H3><b><code>Javadoc</code></b></H3> +This is a link to the <a href="../../../../reference/index.html" target="_top">top-level</a> Javadoc page for the new version of the product. +</BLOCKQUOTE> +<BLOCKQUOTE> +<H3>Overview</H3> +The <a href="changes-summary.html">overview</a> is the top-level summary of what was removed, added and changed between versions. +</BLOCKQUOTE> +<BLOCKQUOTE> +<H3>Package</H3> +This is a link to the package containing the current changed class or interface. +</BLOCKQUOTE> +<BLOCKQUOTE> +<H3>Class</H3> +This is highlighted when you are looking at the changed class or interface. +</BLOCKQUOTE> +<BLOCKQUOTE> +<H3>Text Changes</H3> +This is a link to the top-level index of all documentation changes for the current package or class. +If it is not present, then there are no documentation changes for the current package or class. +This link can be removed entirely by not using the <code>-docchanges</code> option. +</BLOCKQUOTE> +<BLOCKQUOTE> +<H3>Statistics</H3> +This is a link to a page which shows statistics about the changes between the two APIs. +This link can be removed entirely by not using the <code>-stats</code> option. +</BLOCKQUOTE> +<BLOCKQUOTE> +<H3>Help</H3> +A link to this Help page for JDiff. +</BLOCKQUOTE> +<BLOCKQUOTE> +<H3>Prev/Next</H3> +These links take you to the previous and next changed package or class. +</BLOCKQUOTE> +<BLOCKQUOTE> +<H3>Frames/No Frames</H3> +These links show and hide the HTML frames. All pages are available with or without frames. +</BLOCKQUOTE> +<BLOCKQUOTE> +<H2>Complex Changes</H2> +There are some complex changes which can occur between versions, for example, when two or more methods with the same name change simultaneously, or when a method or field is moved into or from a superclass. +In these cases, the change will be seen as a removal and an addition, rather than as a change. Unexpected removals or additions are often part of one of these type of changes. +</BLOCKQUOTE> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/jdiff_statistics.html b/docs/html/sdk/support_api_diff/22.2.1/changes/jdiff_statistics.html new file mode 100644 index 000000000000..0f4805f54fc3 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/jdiff_statistics.html @@ -0,0 +1,381 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +API Change Statistics +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<body class="gc-documentation"> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;xborder-bottom:none;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="../changes.html" target="_top">Top of Report</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<h1>API Change Statistics</h1> +<p>The overall difference between API Levels 22.2.0 and 22.2.1 is approximately <span style="color:222;font-weight:bold;">2.17%</span>. +</p> +<br> +<a name="numbers"></a> +<h2>Total of Differences, by Number and Type</h2> +<p> +The table below lists the numbers of program elements (packages, classes, constructors, methods, and fields) that were added, changed, or removed. The table includes only the highest-level program elements — that is, if a class with two methods was added, the number of methods added does not include those two methods, but the number of classes added does include that class. +</p> +<TABLE summary="Number of differences" WIDTH="100%"> +<TR> + <th>Type</th> + <TH ALIGN="center"><b>Additions</b></TH> + <TH ALIGN="center"><b>Changes</b></TH> + <TH ALIGN="center">Removals</TH> + <TH ALIGN="center"><b>Total</b></TH> +</TR> +<TR> + <TD>Packages</TD> + <TD ALIGN="right">1</TD> + <TD ALIGN="right">7</TD> + <TD ALIGN="right">0</TD> + <TD ALIGN="right">8</TD> +</TR> +<TR> + <TD>Classes and <i>Interfaces</i></TD> + <TD ALIGN="right">16</TD> + <TD ALIGN="right">32</TD> + <TD ALIGN="right">6</TD> + <TD ALIGN="right">54</TD> +</TR> +<TR> + <TD>Constructors</TD> + <TD ALIGN="right">1</TD> + <TD ALIGN="right">0</TD> + <TD ALIGN="right">0</TD> + <TD ALIGN="right">1</TD> +</TR> +<TR> + <TD>Methods</TD> + <TD ALIGN="right">36</TD> + <TD ALIGN="right">10</TD> + <TD ALIGN="right">0</TD> + <TD ALIGN="right">46</TD> +</TR> +<TR> + <TD>Fields</TD> + <TD ALIGN="right">43</TD> + <TD ALIGN="right">0</TD> + <TD ALIGN="right">2</TD> + <TD ALIGN="right">45</TD> +</TR> +<TR> + <TD style="background-color:#FAFAFA"><b>Total</b></TD> + <TD style="background-color:#FAFAFA" ALIGN="right"><strong>97</strong></TD> + <TD style="background-color:#FAFAFA" ALIGN="right"><strong>49</strong></TD> + <TD style="background-color:#FAFAFA" ALIGN="right"><strong>8</strong></TD> + <TD style="background-color:#FAFAFA" ALIGN="right"><strong>154</strong></TD> +</TR> +</TABLE> +<br> +<a name="packages"></a> +<h2>Changed Packages, Sorted by Percentage Difference</h2> +<TABLE summary="Packages sorted by percentage difference" WIDTH="100%"> +<TR> + <TH WIDTH="10%">Percentage Difference*</TH> + <TH>Package</TH> +</TR> +<TR> + <TD ALIGN="center">11</TD> + <TD><A HREF="pkg_android.support.v17.leanback.widget.html">android.support.v17.leanback.widget</A></TD> +</TR> +<TR> + <TD ALIGN="center">8</TD> + <TD><A HREF="pkg_android.support.v7.app.html">android.support.v7.app</A></TD> +</TR> +<TR> + <TD ALIGN="center">3</TD> + <TD><A HREF="pkg_android.support.v7.appcompat.html">android.support.v7.appcompat</A></TD> +</TR> +<TR> + <TD ALIGN="center">3</TD> + <TD><A HREF="pkg_android.support.v7.util.html">android.support.v7.util</A></TD> +</TR> +<TR> + <TD ALIGN="center">2</TD> + <TD><A HREF="pkg_android.support.v4.app.html">android.support.v4.app</A></TD> +</TR> +<TR> + <TD ALIGN="center">2</TD> + <TD><A HREF="pkg_android.support.design.widget.html">android.support.design.widget</A></TD> +</TR> +<TR> + <TD ALIGN="center">1</TD> + <TD><A HREF="pkg_android.support.v17.leanback.app.html">android.support.v17.leanback.app</A></TD> +</TR> +</TABLE> +<p style="font-size:10px">* See <a href="#calculation">Calculation of Change Percentages</a>, below.</p> +<br> +<a name="classes"></a> +<h2>Changed Classes and <i>Interfaces</i>, Sorted by Percentage Difference</h2> +<TABLE summary="Classes sorted by percentage difference" WIDTH="100%"> +<TR WIDTH="20%"> + <TH WIDTH="10%">Percentage<br>Difference*</TH> + <TH><b>Class or <i>Interface</i></b></TH> +</TR> +<TR> + <TD ALIGN="center">100</TD> + <TD><A HREF="android.support.v4.app.NotificationCompatBase.html"> +android.support.v4.app.NotificationCompatBase</A></TD> +</TR> +<TR> + <TD ALIGN="center">50</TD> + <TD><A HREF="android.support.v17.leanback.widget.OnChildSelectedListener.html"> +<i>android.support.v17.leanback.widget.OnChildSelectedListener</i></A></TD> +</TR> +<TR> + <TD ALIGN="center">41</TD> + <TD><A HREF="android.support.v4.app.NotificationCompatBase.Action.html"> +android.support.v4.app.NotificationCompatBase.Action</A></TD> +</TR> +<TR> + <TD ALIGN="center">33</TD> + <TD><A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html"> +android.support.v17.leanback.widget.Presenter.ViewHolder</A></TD> +</TR> +<TR> + <TD ALIGN="center">29</TD> + <TD><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html"> +android.support.v17.leanback.widget.ShadowOverlayContainer</A></TD> +</TR> +<TR> + <TD ALIGN="center">25</TD> + <TD><A HREF="android.support.design.widget.FloatingActionButton.Behavior.html"> +android.support.design.widget.FloatingActionButton.Behavior</A></TD> +</TR> +<TR> + <TD ALIGN="center">23</TD> + <TD><A HREF="android.support.v17.leanback.app.DetailsFragment.html"> +android.support.v17.leanback.app.DetailsFragment</A></TD> +</TR> +<TR> + <TD ALIGN="center">23</TD> + <TD><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html"> +android.support.v17.leanback.app.DetailsSupportFragment</A></TD> +</TR> +<TR> + <TD ALIGN="center">20</TD> + <TD><A HREF="android.support.design.widget.FloatingActionButton.html"> +android.support.design.widget.FloatingActionButton</A></TD> +</TR> +<TR> + <TD ALIGN="center">20</TD> + <TD><A HREF="android.support.v17.leanback.widget.PresenterSelector.html"> +android.support.v17.leanback.widget.PresenterSelector</A></TD> +</TR> +<TR> + <TD ALIGN="center">20</TD> + <TD><A HREF="android.support.v7.appcompat.R.integer.html"> +android.support.v7.appcompat.R.integer</A></TD> +</TR> +<TR> + <TD ALIGN="center">16</TD> + <TD><A HREF="android.support.v4.app.NotificationCompat.Action.html"> +android.support.v4.app.NotificationCompat.Action</A></TD> +</TR> +<TR> + <TD ALIGN="center">11</TD> + <TD><A HREF="android.support.v7.appcompat.R.layout.html"> +android.support.v7.appcompat.R.layout</A></TD> +</TR> +<TR> + <TD ALIGN="center">11</TD> + <TD><A HREF="android.support.v17.leanback.widget.Presenter.html"> +android.support.v17.leanback.widget.Presenter</A></TD> +</TR> +<TR> + <TD ALIGN="center">10</TD> + <TD><A HREF="android.support.design.widget.Snackbar.html"> +android.support.design.widget.Snackbar</A></TD> +</TR> +<TR> + <TD ALIGN="center">9</TD> + <TD><A HREF="android.support.v7.util.SortedList.html"> +android.support.v7.util.SortedList</A></TD> +</TR> +<TR> + <TD ALIGN="center">9</TD> + <TD><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html"> +android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder</A></TD> +</TR> +<TR> + <TD ALIGN="center">7</TD> + <TD><A HREF="android.support.v7.appcompat.R.id.html"> +android.support.v7.appcompat.R.id</A></TD> +</TR> +<TR> + <TD ALIGN="center">4</TD> + <TD><A HREF="android.support.v17.leanback.widget.DetailsOverviewRowPresenter.html"> +android.support.v17.leanback.widget.DetailsOverviewRowPresenter</A></TD> +</TR> +<TR> + <TD ALIGN="center">3</TD> + <TD><A HREF="android.support.design.widget.TabLayout.Tab.html"> +android.support.design.widget.TabLayout.Tab</A></TD> +</TR> +<TR> + <TD ALIGN="center">2</TD> + <TD><A HREF="android.support.v7.appcompat.R.string.html"> +android.support.v7.appcompat.R.string</A></TD> +</TR> +<TR> + <TD ALIGN="center">2</TD> + <TD><A HREF="android.support.v17.leanback.widget.VerticalGridPresenter.html"> +android.support.v17.leanback.widget.VerticalGridPresenter</A></TD> +</TR> +<TR> + <TD ALIGN="center">2</TD> + <TD><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.html"> +android.support.v17.leanback.widget.ItemBridgeAdapter</A></TD> +</TR> +<TR> + <TD ALIGN="center">2</TD> + <TD><A HREF="android.support.v7.appcompat.R.dimen.html"> +android.support.v7.appcompat.R.dimen</A></TD> +</TR> +<TR> + <TD ALIGN="center">2</TD> + <TD><A HREF="android.support.v17.leanback.widget.ListRowPresenter.html"> +android.support.v17.leanback.widget.ListRowPresenter</A></TD> +</TR> +<TR> + <TD ALIGN="center">2</TD> + <TD><A HREF="android.support.design.widget.CoordinatorLayout.Behavior.html"> +android.support.design.widget.CoordinatorLayout.Behavior</A></TD> +</TR> +<TR> + <TD ALIGN="center">1</TD> + <TD><A HREF="android.support.v7.appcompat.R.style.html"> +android.support.v7.appcompat.R.style</A></TD> +</TR> +<TR> + <TD ALIGN="center">1</TD> + <TD><A HREF="android.support.design.widget.TabLayout.html"> +android.support.design.widget.TabLayout</A></TD> +</TR> +<TR> + <TD ALIGN="center">1</TD> + <TD><A HREF="android.support.v17.leanback.widget.RowPresenter.html"> +android.support.v17.leanback.widget.RowPresenter</A></TD> +</TR> +<TR> + <TD ALIGN="center"><1</TD> + <TD><A HREF="android.support.v7.appcompat.R.drawable.html"> +android.support.v7.appcompat.R.drawable</A></TD> +</TR> +<TR> + <TD ALIGN="center"><1</TD> + <TD><A HREF="android.support.v7.appcompat.R.attr.html"> +android.support.v7.appcompat.R.attr</A></TD> +</TR> +<TR> + <TD ALIGN="center"><1</TD> + <TD><A HREF="android.support.v7.appcompat.R.styleable.html"> +android.support.v7.appcompat.R.styleable</A></TD> +</TR> +</TABLE> +<p style="font-size:10px">* See <a href="#calculation">Calculation of Change Percentages</a>, below.</p> +<br> +<h2 id="calculation">Calculation of Change Percentages</h2> +<p> +The percent change statistic reported for all elements in the "to" API Level specification is defined recursively as follows:</p> +<pre> +Percentage difference = 100 * (added + removed + 2*changed) + ----------------------------------- + sum of public elements in BOTH APIs +</pre> +<p>where <code>added</code> is the number of packages added, <code>removed</code> is the number of packages removed, and <code>changed</code> is the number of packages changed. +This definition is applied recursively for the classes and their program elements, so the value for a changed package will be less than 1, unless every class in that package has changed. +The definition ensures that if all packages are removed and all new packages are +added, the change will be 100%.</p> + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY></HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/jdiff_topleftframe.html b/docs/html/sdk/support_api_diff/22.2.1/changes/jdiff_topleftframe.html new file mode 100644 index 000000000000..36f9836e4478 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/jdiff_topleftframe.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Android API Version Differences +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<table class="jdiffIndex" summary="Links to diff index files" BORDER="0" WIDTH="100%" cellspacing="0" cellpadding="0" style="margin:0"> +<TR> + <th class="indexHeader" nowrap> + Select a Diffs Index:</th> +</TR> +<TR> + <TD><FONT CLASS="indexText" size="-2"><A HREF="alldiffs_index_all.html" TARGET="bottomleftframe">All Differences</A></FONT><br></TD> +</TR> +<TR> + <TD NOWRAP><FONT CLASS="indexText" size="-2"><A HREF="packages_index_all.html" TARGET="bottomleftframe">By Package</A></FONT><br></TD> +</TR> +<TR> + <TD NOWRAP><FONT CLASS="indexText" size="-2"><A HREF="classes_index_all.html" TARGET="bottomleftframe">By Class</A></FONT><br></TD> +</TR> +<TR> + <TD NOWRAP><FONT CLASS="indexText" size="-2"><A HREF="constructors_index_all.html" TARGET="bottomleftframe">By Constructor</A></FONT><br></TD> +</TR> +<TR> + <TD NOWRAP><FONT CLASS="indexText" size="-2"><A HREF="methods_index_all.html" TARGET="bottomleftframe">By Method</A></FONT><br></TD> +</TR> +<TR> + <TD NOWRAP><FONT CLASS="indexText" size="-2"><A HREF="fields_index_all.html" TARGET="bottomleftframe">By Field</A></FONT><br></TD> +</TR> +</TABLE> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_additions.html b/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_additions.html new file mode 100644 index 000000000000..33a155f71bb0 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_additions.html @@ -0,0 +1,238 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Method Additions Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Methods" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="methods_index_all.html" class="staysblack">All Methods</a> + <br> +<font color="#999999">Removals</font> + <br> +<b>Additions</b> + <br> +<A HREF="methods_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="A"></A> +<br><font size="+2">A</font> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>addAll</i><br> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(T...)" class="hiddenlink" target="rightframe">type <b> +()</b> in android.support.v7.util.SortedList +</A></nobr><br> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(T[], boolean)" class="hiddenlink" target="rightframe">type <b> +(<code>T[], boolean</code>)</b> in android.support.v7.util.SortedList +</A></nobr><br> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(java.util.Collection<T>)" class="hiddenlink" target="rightframe">type <b> +(<code>Collection<T></code>)</b> in android.support.v7.util.SortedList +</A></nobr><br> +<A NAME="G"></A> +<br><font size="+2">G</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>getFacet</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html#android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.html#android.support.v17.leanback.widget.Presenter.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.Presenter +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html#android.support.v17.leanback.widget.Presenter.ViewHolder.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.Presenter.ViewHolder +</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.html#android.support.v17.leanback.widget.ItemBridgeAdapter.getFacetProvider_added(int)" class="hiddenlink" target="rightframe"><b>getFacetProvider</b> +(<code>int</code>)</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.PresenterSelector.html#android.support.v17.leanback.widget.PresenterSelector.getPresenters_added()" class="hiddenlink" target="rightframe"><b>getPresenters</b> +()</A></nobr><br> +<nobr><A HREF="android.support.design.widget.TabLayout.html#android.support.design.widget.TabLayout.getSelectedTabPosition_added()" class="hiddenlink" target="rightframe"><b>getSelectedTabPosition</b> +()</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.getShadowType_added()" class="hiddenlink" target="rightframe"><b>getShadowType</b> +()</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.getWrappedView_added()" class="hiddenlink" target="rightframe"><b>getWrappedView</b> +()</A></nobr><br> +<A NAME="H"></A> +<br><font size="+2">H</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.html#android.support.design.widget.FloatingActionButton.hide_added()" class="hiddenlink" target="rightframe"><b>hide</b> +()</A></nobr><br> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>inflateTitle</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.inflateTitle_added(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)" class="hiddenlink" target="rightframe">type <b> +(<code>LayoutInflater, ViewGroup, Bundle</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.inflateTitle_added(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)" class="hiddenlink" target="rightframe">type <b> +(<code>LayoutInflater, ViewGroup, Bundle</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.RowPresenter.html#android.support.v17.leanback.widget.RowPresenter.isClippingChildren_added()" class="hiddenlink" target="rightframe"><b>isClippingChildren</b> +()</A></nobr><br> +<nobr><A HREF="android.support.design.widget.TabLayout.Tab.html#android.support.design.widget.TabLayout.Tab.isSelected_added()" class="hiddenlink" target="rightframe"><b>isSelected</b> +()</A></nobr><br> +<A NAME="O"></A> +<br><font size="+2">O</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>onDependentViewRemoved</i><br> + <nobr><A HREF="android.support.design.widget.CoordinatorLayout.Behavior.html#android.support.design.widget.CoordinatorLayout.Behavior.onDependentViewRemoved_added(android.support.design.widget.CoordinatorLayout, V, android.view.View)" class="hiddenlink" target="rightframe">type <b> +(<code>CoordinatorLayout, V, View</code>)</b> in android.support.design.widget.CoordinatorLayout.Behavior +</A></nobr><br> + <nobr><A HREF="android.support.design.widget.FloatingActionButton.Behavior.html#android.support.design.widget.FloatingActionButton.Behavior.onDependentViewRemoved_added(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.view.View)" class="hiddenlink" target="rightframe">type <b> +(<code>CoordinatorLayout, FloatingActionButton, View</code>)</b> in android.support.design.widget.FloatingActionButton.Behavior +</A></nobr><br> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.Behavior.html#android.support.design.widget.FloatingActionButton.Behavior.onLayoutChild_added(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, int)" class="hiddenlink" target="rightframe"><b>onLayoutChild</b> +(<code>CoordinatorLayout, FloatingActionButton, int</code>)</A></nobr><br> +<i>onSetDetailsOverviewRowStatus</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.onSetDetailsOverviewRowStatus_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.onSetDetailsOverviewRowStatus_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<i>onSetRowStatus</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.onSetRowStatus_added(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>RowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.onSetRowStatus_added(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>RowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<A NAME="S"></A> +<br><font size="+2">S</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>setActionTextColor</i><br> + <nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.setActionTextColor_added(android.content.res.ColorStateList)" class="hiddenlink" target="rightframe">type <b> +(<code>ColorStateList</code>)</b> in android.support.design.widget.Snackbar +</A></nobr><br> + <nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.setActionTextColor_added(int)" class="hiddenlink" target="rightframe">type <b> +(<code>int</code>)</b> in android.support.design.widget.Snackbar +</A></nobr><br> +<i>setFacet</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.html#android.support.v17.leanback.widget.Presenter.setFacet_added(java.lang.Class<?>, java.lang.Object)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?>, Object</code>)</b> in android.support.v17.leanback.widget.Presenter +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html#android.support.v17.leanback.widget.Presenter.ViewHolder.setFacet_added(java.lang.Class<?>, java.lang.Object)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?>, Object</code>)</b> in android.support.v17.leanback.widget.Presenter.ViewHolder +</A></nobr><br> +<i>setupDetailsOverviewRowPresenter</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.setupDetailsOverviewRowPresenter_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.setupDetailsOverviewRowPresenter_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<i>setupPresenter</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.setupPresenter_added(android.support.v17.leanback.widget.Presenter)" class="hiddenlink" target="rightframe">type <b> +(<code>Presenter</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.setupPresenter_added(android.support.v17.leanback.widget.Presenter)" class="hiddenlink" target="rightframe">type <b> +(<code>Presenter</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.html#android.support.design.widget.FloatingActionButton.show_added()" class="hiddenlink" target="rightframe"><b>show</b> +()</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.supportsDynamicShadow_added()" class="hiddenlink" target="rightframe"><b>supportsDynamicShadow</b> +()</A></nobr><br> +<A NAME="U"></A> +<br><font size="+2">U</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>useDynamicShadow</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useDynamicShadow_added()" class="hiddenlink" target="rightframe">type <b> +()</b> in android.support.v17.leanback.widget.ShadowOverlayContainer +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useDynamicShadow_added(float, float)" class="hiddenlink" target="rightframe">type <b> +(<code>float, float</code>)</b> in android.support.v17.leanback.widget.ShadowOverlayContainer +</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useStaticShadow_added()" class="hiddenlink" target="rightframe"><b>useStaticShadow</b> +()</A></nobr><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_all.html b/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_all.html new file mode 100644 index 000000000000..b9cf858ec933 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_all.html @@ -0,0 +1,270 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Method Differences Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Methods" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<b>Methods</b> + <br> +<font color="#999999">Removals</font> + <br> +<A HREF="methods_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<A HREF="methods_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="A"></A> +<br><font size="+2">A</font> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>addAll</i><br> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(T...)" class="hiddenlink" target="rightframe">type <b> +()</b> in android.support.v7.util.SortedList +</A></nobr><br> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(T[], boolean)" class="hiddenlink" target="rightframe">type <b> +(<code>T[], boolean</code>)</b> in android.support.v7.util.SortedList +</A></nobr><br> + <nobr><A HREF="android.support.v7.util.SortedList.html#android.support.v7.util.SortedList.addAll_added(java.util.Collection<T>)" class="hiddenlink" target="rightframe">type <b> +(<code>Collection<T></code>)</b> in android.support.v7.util.SortedList +</A></nobr><br> +<A NAME="G"></A> +<br><font size="+2">G</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>getActionIntent</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getActionIntent_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getActionIntent_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getExtras_changed()" class="hiddenlink" target="rightframe">getExtras +()</A></nobr><br> +<i>getFacet</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html#android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.html#android.support.v17.leanback.widget.Presenter.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.Presenter +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html#android.support.v17.leanback.widget.Presenter.ViewHolder.getFacet_added(java.lang.Class<?>)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?></code>)</b> in android.support.v17.leanback.widget.Presenter.ViewHolder +</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.html#android.support.v17.leanback.widget.ItemBridgeAdapter.getFacetProvider_added(int)" class="hiddenlink" target="rightframe"><b>getFacetProvider</b> +(<code>int</code>)</A></nobr><br> +<i>getIcon</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getIcon_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getIcon_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.PresenterSelector.html#android.support.v17.leanback.widget.PresenterSelector.getPresenters_added()" class="hiddenlink" target="rightframe"><b>getPresenters</b> +()</A></nobr><br> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getRemoteInputs_changed()" class="hiddenlink" target="rightframe">getRemoteInputs +()</A></nobr><br> +<nobr><A HREF="android.support.design.widget.TabLayout.html#android.support.design.widget.TabLayout.getSelectedTabPosition_added()" class="hiddenlink" target="rightframe"><b>getSelectedTabPosition</b> +()</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.getShadowType_added()" class="hiddenlink" target="rightframe"><b>getShadowType</b> +()</A></nobr><br> +<i>getTitle</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getTitle_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getTitle_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.getWrappedView_added()" class="hiddenlink" target="rightframe"><b>getWrappedView</b> +()</A></nobr><br> +<A NAME="H"></A> +<br><font size="+2">H</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.html#android.support.design.widget.FloatingActionButton.hide_added()" class="hiddenlink" target="rightframe"><b>hide</b> +()</A></nobr><br> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>inflateTitle</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.inflateTitle_added(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)" class="hiddenlink" target="rightframe">type <b> +(<code>LayoutInflater, ViewGroup, Bundle</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.inflateTitle_added(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)" class="hiddenlink" target="rightframe">type <b> +(<code>LayoutInflater, ViewGroup, Bundle</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.RowPresenter.html#android.support.v17.leanback.widget.RowPresenter.isClippingChildren_added()" class="hiddenlink" target="rightframe"><b>isClippingChildren</b> +()</A></nobr><br> +<nobr><A HREF="android.support.design.widget.TabLayout.Tab.html#android.support.design.widget.TabLayout.Tab.isSelected_added()" class="hiddenlink" target="rightframe"><b>isSelected</b> +()</A></nobr><br> +<i>isUsingZOrder</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ListRowPresenter.html#android.support.v17.leanback.widget.ListRowPresenter.isUsingZOrder_changed(android.content.Context)" class="hiddenlink" target="rightframe">type +(<code>Context</code>) in android.support.v17.leanback.widget.ListRowPresenter +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.widget.VerticalGridPresenter.html#android.support.v17.leanback.widget.VerticalGridPresenter.isUsingZOrder_changed(android.content.Context)" class="hiddenlink" target="rightframe">type +(<code>Context</code>) in android.support.v17.leanback.widget.VerticalGridPresenter +</A></nobr><br> +<A NAME="O"></A> +<br><font size="+2">O</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#S"><font size="-2">S</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>onDependentViewRemoved</i><br> + <nobr><A HREF="android.support.design.widget.CoordinatorLayout.Behavior.html#android.support.design.widget.CoordinatorLayout.Behavior.onDependentViewRemoved_added(android.support.design.widget.CoordinatorLayout, V, android.view.View)" class="hiddenlink" target="rightframe">type <b> +(<code>CoordinatorLayout, V, View</code>)</b> in android.support.design.widget.CoordinatorLayout.Behavior +</A></nobr><br> + <nobr><A HREF="android.support.design.widget.FloatingActionButton.Behavior.html#android.support.design.widget.FloatingActionButton.Behavior.onDependentViewRemoved_added(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.view.View)" class="hiddenlink" target="rightframe">type <b> +(<code>CoordinatorLayout, FloatingActionButton, View</code>)</b> in android.support.design.widget.FloatingActionButton.Behavior +</A></nobr><br> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.Behavior.html#android.support.design.widget.FloatingActionButton.Behavior.onLayoutChild_added(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, int)" class="hiddenlink" target="rightframe"><b>onLayoutChild</b> +(<code>CoordinatorLayout, FloatingActionButton, int</code>)</A></nobr><br> +<i>onSetDetailsOverviewRowStatus</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.onSetDetailsOverviewRowStatus_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.onSetDetailsOverviewRowStatus_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<i>onSetRowStatus</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.onSetRowStatus_added(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>RowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.onSetRowStatus_added(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int)" class="hiddenlink" target="rightframe">type <b> +(<code>RowPresenter, ViewHolder, int, int, int</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<A NAME="S"></A> +<br><font size="+2">S</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#U"><font size="-2">U</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>setActionTextColor</i><br> + <nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.setActionTextColor_added(android.content.res.ColorStateList)" class="hiddenlink" target="rightframe">type <b> +(<code>ColorStateList</code>)</b> in android.support.design.widget.Snackbar +</A></nobr><br> + <nobr><A HREF="android.support.design.widget.Snackbar.html#android.support.design.widget.Snackbar.setActionTextColor_added(int)" class="hiddenlink" target="rightframe">type <b> +(<code>int</code>)</b> in android.support.design.widget.Snackbar +</A></nobr><br> +<i>setFacet</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.html#android.support.v17.leanback.widget.Presenter.setFacet_added(java.lang.Class<?>, java.lang.Object)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?>, Object</code>)</b> in android.support.v17.leanback.widget.Presenter +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html#android.support.v17.leanback.widget.Presenter.ViewHolder.setFacet_added(java.lang.Class<?>, java.lang.Object)" class="hiddenlink" target="rightframe">type <b> +(<code>Class<?>, Object</code>)</b> in android.support.v17.leanback.widget.Presenter.ViewHolder +</A></nobr><br> +<i>setupDetailsOverviewRowPresenter</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.setupDetailsOverviewRowPresenter_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.setupDetailsOverviewRowPresenter_added(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter)" class="hiddenlink" target="rightframe">type <b> +(<code>FullWidthDetailsOverviewRowPresenter</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<i>setupPresenter</i><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html#android.support.v17.leanback.app.DetailsFragment.setupPresenter_added(android.support.v17.leanback.widget.Presenter)" class="hiddenlink" target="rightframe">type <b> +(<code>Presenter</code>)</b> in android.support.v17.leanback.app.DetailsFragment +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html#android.support.v17.leanback.app.DetailsSupportFragment.setupPresenter_added(android.support.v17.leanback.widget.Presenter)" class="hiddenlink" target="rightframe">type <b> +(<code>Presenter</code>)</b> in android.support.v17.leanback.app.DetailsSupportFragment +</A></nobr><br> +<nobr><A HREF="android.support.design.widget.FloatingActionButton.html#android.support.design.widget.FloatingActionButton.show_added()" class="hiddenlink" target="rightframe"><b>show</b> +()</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.supportsDynamicShadow_added()" class="hiddenlink" target="rightframe"><b>supportsDynamicShadow</b> +()</A></nobr><br> +<A NAME="U"></A> +<br><font size="+2">U</font> +<a href="#A"><font size="-2">A</font></a> +<a href="#G"><font size="-2">G</font></a> +<a href="#H"><font size="-2">H</font></a> +<a href="#I"><font size="-2">I</font></a> +<a href="#O"><font size="-2">O</font></a> +<a href="#S"><font size="-2">S</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>useDynamicShadow</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useDynamicShadow_added()" class="hiddenlink" target="rightframe">type <b> +()</b> in android.support.v17.leanback.widget.ShadowOverlayContainer +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useDynamicShadow_added(float, float)" class="hiddenlink" target="rightframe">type <b> +(<code>float, float</code>)</b> in android.support.v17.leanback.widget.ShadowOverlayContainer +</A></nobr><br> +<nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html#android.support.v17.leanback.widget.ShadowOverlayContainer.useStaticShadow_added()" class="hiddenlink" target="rightframe"><b>useStaticShadow</b> +()</A></nobr><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_changes.html b/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_changes.html new file mode 100644 index 000000000000..4e2d32950a49 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_changes.html @@ -0,0 +1,103 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Method Changes Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Methods" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="methods_index_all.html" class="staysblack">All Methods</a> + <br> +<font color="#999999">Removals</font> + <br> +<A HREF="methods_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<b>Changes</b> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<A NAME="G"></A> +<br><font size="+2">G</font> +<a href="#I"><font size="-2">I</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>getActionIntent</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getActionIntent_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getActionIntent_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getExtras_changed()" class="hiddenlink" target="rightframe">getExtras +()</A></nobr><br> +<i>getIcon</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getIcon_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getIcon_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getRemoteInputs_changed()" class="hiddenlink" target="rightframe">getRemoteInputs +()</A></nobr><br> +<i>getTitle</i><br> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html#android.support.v4.app.NotificationCompat.Action.getTitle_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompat.Action +</A></nobr><br> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html#android.support.v4.app.NotificationCompatBase.Action.getTitle_changed()" class="hiddenlink" target="rightframe">type +() in android.support.v4.app.NotificationCompatBase.Action +</A></nobr><br> +<A NAME="I"></A> +<br><font size="+2">I</font> +<a href="#G"><font size="-2">G</font></a> + <a href="#topheader"><font size="-2">TOP</font></a> +<p><div style="line-height:1.5em;color:black"> +<i>isUsingZOrder</i><br> + <nobr><A HREF="android.support.v17.leanback.widget.ListRowPresenter.html#android.support.v17.leanback.widget.ListRowPresenter.isUsingZOrder_changed(android.content.Context)" class="hiddenlink" target="rightframe">type +(<code>Context</code>) in android.support.v17.leanback.widget.ListRowPresenter +</A></nobr><br> + <nobr><A HREF="android.support.v17.leanback.widget.VerticalGridPresenter.html#android.support.v17.leanback.widget.VerticalGridPresenter.isUsingZOrder_changed(android.content.Context)" class="hiddenlink" target="rightframe">type +(<code>Context</code>) in android.support.v17.leanback.widget.VerticalGridPresenter +</A></nobr><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_removals.html b/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_removals.html new file mode 100644 index 000000000000..b5aea4f9d673 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/methods_index_removals.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Method Removals Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Methods" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="methods_index_all.html" class="staysblack">All Methods</a> + <br> +<font color="#999999">Removals</font> + <br> +<A HREF="methods_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<A HREF="methods_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_additions.html b/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_additions.html new file mode 100644 index 000000000000..6311752b72ae --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_additions.html @@ -0,0 +1,65 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Package Additions Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Packages" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="packages_index_all.html" class="staysblack">All Packages</a> + <br> +<font color="#999999">Removals</font> + <br> +<b>Additions</b> + <br> +<A HREF="packages_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<br> +<div id="indexTableEntries"> +<A NAME="A"></A> +<A HREF="changes-summary.html#android.support.v17.leanback.system" class="hiddenlink" target="rightframe"><b>android.support.v17.leanback.system</b></A><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_all.html b/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_all.html new file mode 100644 index 000000000000..3f5ee1306b9e --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_all.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Package Differences Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Packages" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<b>Packages</b> + <br> +<font color="#999999">Removals</font> + <br> +<A HREF="packages_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<A HREF="packages_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<br> +<div id="indexTableEntries"> +<A NAME="A"></A> +<A HREF="pkg_android.support.design.widget.html" class="hiddenlink" target="rightframe">android.support.design.widget</A><br> +<A HREF="pkg_android.support.v17.leanback.app.html" class="hiddenlink" target="rightframe">android.support.v17.leanback.app</A><br> +<A HREF="changes-summary.html#android.support.v17.leanback.system" class="hiddenlink" target="rightframe"><b>android.support.v17.leanback.system</b></A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html" class="hiddenlink" target="rightframe">android.support.v17.leanback.widget</A><br> +<A HREF="pkg_android.support.v4.app.html" class="hiddenlink" target="rightframe">android.support.v4.app</A><br> +<A HREF="pkg_android.support.v7.app.html" class="hiddenlink" target="rightframe">android.support.v7.app</A><br> +<A HREF="pkg_android.support.v7.appcompat.html" class="hiddenlink" target="rightframe">android.support.v7.appcompat</A><br> +<A HREF="pkg_android.support.v7.util.html" class="hiddenlink" target="rightframe">android.support.v7.util</A><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_changes.html b/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_changes.html new file mode 100644 index 000000000000..a4637a774082 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_changes.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Package Changes Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Packages" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="packages_index_all.html" class="staysblack">All Packages</a> + <br> +<font color="#999999">Removals</font> + <br> +<A HREF="packages_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<b>Changes</b> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<br> +<div id="indexTableEntries"> +<A NAME="A"></A> +<A HREF="pkg_android.support.design.widget.html" class="hiddenlink" target="rightframe">android.support.design.widget</A><br> +<A HREF="pkg_android.support.v17.leanback.app.html" class="hiddenlink" target="rightframe">android.support.v17.leanback.app</A><br> +<A HREF="pkg_android.support.v17.leanback.widget.html" class="hiddenlink" target="rightframe">android.support.v17.leanback.widget</A><br> +<A HREF="pkg_android.support.v4.app.html" class="hiddenlink" target="rightframe">android.support.v4.app</A><br> +<A HREF="pkg_android.support.v7.app.html" class="hiddenlink" target="rightframe">android.support.v7.app</A><br> +<A HREF="pkg_android.support.v7.appcompat.html" class="hiddenlink" target="rightframe">android.support.v7.appcompat</A><br> +<A HREF="pkg_android.support.v7.util.html" class="hiddenlink" target="rightframe">android.support.v7.util</A><br> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_removals.html b/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_removals.html new file mode 100644 index 000000000000..d0ffabcf3c5b --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/packages_index_removals.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +Package Removals Index +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY class="gc-documentation" style="padding:12px;"> +<a NAME="topheader"></a> +<table summary="Index for Packages" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;"> + <tr> + <th class="indexHeader"> + Filter the Index: + </th> + </tr> + <tr> + <td class="indexText" style="line-height:1.3em;padding-left:2em;"> +<a href="packages_index_all.html" class="staysblack">All Packages</a> + <br> +<font color="#999999">Removals</font> + <br> +<A HREF="packages_index_additions.html"xclass="hiddenlink">Additions</A> + <br> +<A HREF="packages_index_changes.html"xclass="hiddenlink">Changes</A> + </td> + </tr> +</table> +<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;"> +Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font> +</div> +<br> +<div id="indexTableEntries"> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.design.widget.html b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.design.widget.html new file mode 100644 index 000000000000..345f33b8d346 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.design.widget.html @@ -0,0 +1,154 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.design.widget +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Package <A HREF="../../../../reference/android/support/design/widget/package-summary.html" target="_top"><font size="+1"><code>android.support.design.widget</code></font></A> +</H2> +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Classes" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="CoordinatorLayout.Behavior"></A> + <nobr><A HREF="android.support.design.widget.CoordinatorLayout.Behavior.html">CoordinatorLayout.Behavior</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="FloatingActionButton"></A> + <nobr><A HREF="android.support.design.widget.FloatingActionButton.html">FloatingActionButton</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="FloatingActionButton.Behavior"></A> + <nobr><A HREF="android.support.design.widget.FloatingActionButton.Behavior.html">FloatingActionButton.Behavior</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="Snackbar"></A> + <nobr><A HREF="android.support.design.widget.Snackbar.html">Snackbar</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="TabLayout"></A> + <nobr><A HREF="android.support.design.widget.TabLayout.html">TabLayout</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="TabLayout.Tab"></A> + <nobr><A HREF="android.support.design.widget.TabLayout.Tab.html">TabLayout.Tab</A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v17.leanback.app.html b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v17.leanback.app.html new file mode 100644 index 000000000000..873bc6b8ef2f --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v17.leanback.app.html @@ -0,0 +1,126 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.app +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Package <A HREF="../../../../reference/android/support/v17/leanback/app/package-summary.html" target="_top"><font size="+1"><code>android.support.v17.leanback.app</code></font></A> +</H2> +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Classes" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="DetailsFragment"></A> + <nobr><A HREF="android.support.v17.leanback.app.DetailsFragment.html">DetailsFragment</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="DetailsSupportFragment"></A> + <nobr><A HREF="android.support.v17.leanback.app.DetailsSupportFragment.html">DetailsSupportFragment</A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v17.leanback.widget.html b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v17.leanback.widget.html new file mode 100644 index 000000000000..7197d3a3210d --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v17.leanback.widget.html @@ -0,0 +1,338 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v17.leanback.widget +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Package <A HREF="../../../../reference/android/support/v17/leanback/widget/package-summary.html" target="_top"><font size="+1"><code>android.support.v17.leanback.widget</code></font></A> +</H2> +<p> +<a NAME="Removed"></a> +<TABLE summary="Removed Classes and Interfaces" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Removed Classes and Interfaces</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="BaseGridView"></A> + BaseGridView + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="BaseGridView.OnKeyInterceptListener"></A> + <I>BaseGridView.OnKeyInterceptListener</I> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="BaseGridView.OnMotionInterceptListener"></A> + <I>BaseGridView.OnMotionInterceptListener</I> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="BaseGridView.OnTouchInterceptListener"></A> + <I>BaseGridView.OnTouchInterceptListener</I> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="BaseGridView.OnUnhandledKeyListener"></A> + <I>BaseGridView.OnUnhandledKeyListener</I> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="GridLayoutManager"></A> + GridLayoutManager + </TD> + <TD> </TD> +</TR> +</TABLE> + +<p> +<a NAME="Added"></a> +<TABLE summary="Added Classes and Interfaces" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Classes and Interfaces</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="DetailsOverviewLogoPresenter"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/DetailsOverviewLogoPresenter.html" target="_top"><code>DetailsOverviewLogoPresenter</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="DetailsOverviewLogoPresenter.ViewHolder"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/DetailsOverviewLogoPresenter.ViewHolder.html" target="_top"><code>DetailsOverviewLogoPresenter.<br>ViewHolder</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="DetailsOverviewRow.Listener"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/DetailsOverviewRow.Listener.html" target="_top"><code>DetailsOverviewRow.Listener</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="FacetProvider"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/FacetProvider.html" target="_top"><code><I>FacetProvider</I></code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="FacetProviderAdapter"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/FacetProviderAdapter.html" target="_top"><code><I>FacetProviderAdapter</I></code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="FullWidthDetailsOverviewRowPresenter"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/FullWidthDetailsOverviewRowPresenter.html" target="_top"><code>FullWidthDetailsOverviewRowPresenter</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="FullWidthDetailsOverviewRowPresenter.Listener"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/FullWidthDetailsOverviewRowPresenter.Listener.html" target="_top"><code>FullWidthDetailsOverviewRowPresenter.<br>Listener</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="FullWidthDetailsOverviewRowPresenter.ViewHolder"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/FullWidthDetailsOverviewRowPresenter.ViewHolder.html" target="_top"><code>FullWidthDetailsOverviewRowPresenter.<br>ViewHolder</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener.html" target="_top"><code>FullWidthDetailsOverviewRowPresenter.<br>ViewHolder.DetailsOverviewRowListener</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="FullWidthDetailsOverviewSharedElementHelper"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/FullWidthDetailsOverviewSharedElementHelper.html" target="_top"><code>FullWidthDetailsOverviewSharedElementHelper</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="ItemAlignmentFacet"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/ItemAlignmentFacet.html" target="_top"><code>ItemAlignmentFacet</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="ItemAlignmentFacet.ItemAlignmentDef"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/ItemAlignmentFacet.ItemAlignmentDef.html" target="_top"><code>ItemAlignmentFacet.ItemAlignmentDef</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="OnChildViewHolderSelectedListener"></A> + <nobr><A HREF="../../../../reference/android/support/v17/leanback/widget/OnChildViewHolderSelectedListener.html" target="_top"><code>OnChildViewHolderSelectedListener</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Classes and Interfaces" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Changed Classes and Interfaces</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="DetailsOverviewRowPresenter"></A> + <nobr><A HREF="android.support.v17.leanback.widget.DetailsOverviewRowPresenter.html">DetailsOverviewRowPresenter</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="ItemBridgeAdapter"></A> + <nobr><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.html">ItemBridgeAdapter</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="ItemBridgeAdapter.ViewHolder"></A> + <nobr><A HREF="android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder.html">ItemBridgeAdapter.ViewHolder</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="ListRowPresenter"></A> + <nobr><A HREF="android.support.v17.leanback.widget.ListRowPresenter.html">ListRowPresenter</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="OnChildSelectedListener"></A> + <nobr><A HREF="android.support.v17.leanback.widget.OnChildSelectedListener.html"><I>OnChildSelectedListener</I></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="Presenter"></A> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.html">Presenter</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="Presenter.ViewHolder"></A> + <nobr><A HREF="android.support.v17.leanback.widget.Presenter.ViewHolder.html">Presenter.ViewHolder</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="PresenterSelector"></A> + <nobr><A HREF="android.support.v17.leanback.widget.PresenterSelector.html">PresenterSelector</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="RowPresenter"></A> + <nobr><A HREF="android.support.v17.leanback.widget.RowPresenter.html">RowPresenter</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="ShadowOverlayContainer"></A> + <nobr><A HREF="android.support.v17.leanback.widget.ShadowOverlayContainer.html">ShadowOverlayContainer</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="VerticalGridPresenter"></A> + <nobr><A HREF="android.support.v17.leanback.widget.VerticalGridPresenter.html">VerticalGridPresenter</A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v4.app.html b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v4.app.html new file mode 100644 index 000000000000..1d15399bf085 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v4.app.html @@ -0,0 +1,133 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v4.app +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Package <A HREF="../../../../reference/android/support/v4/app/package-summary.html" target="_top"><font size="+1"><code>android.support.v4.app</code></font></A> +</H2> +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Classes" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="NotificationCompat.Action"></A> + <nobr><A HREF="android.support.v4.app.NotificationCompat.Action.html">NotificationCompat.Action</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="NotificationCompatBase"></A> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.html">NotificationCompatBase</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="NotificationCompatBase.Action"></A> + <nobr><A HREF="android.support.v4.app.NotificationCompatBase.Action.html">NotificationCompatBase.Action</A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v7.app.html b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v7.app.html new file mode 100644 index 000000000000..47c0894c18fe --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v7.app.html @@ -0,0 +1,133 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.app +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Package <A HREF="../../../../reference/android/support/v7/app/package-summary.html" target="_top"><font size="+1"><code>android.support.v7.app</code></font></A> +</H2> +<p> +<a NAME="Added"></a> +<TABLE summary="Added Classes" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Added Classes</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="NotificationCompat"></A> + <nobr><A HREF="../../../../reference/android/support/v7/app/NotificationCompat.html" target="_top"><code>NotificationCompat</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="NotificationCompat.Builder"></A> + <nobr><A HREF="../../../../reference/android/support/v7/app/NotificationCompat.Builder.html" target="_top"><code>NotificationCompat.Builder</code></A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="NotificationCompat.MediaStyle"></A> + <nobr><A HREF="../../../../reference/android/support/v7/app/NotificationCompat.MediaStyle.html" target="_top"><code>NotificationCompat.MediaStyle</code></A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v7.appcompat.html b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v7.appcompat.html new file mode 100644 index 000000000000..4c562aecfbce --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v7.appcompat.html @@ -0,0 +1,175 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.appcompat +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Package <A HREF="../../../../reference/android/support/v7/appcompat/package-summary.html" target="_top"><font size="+1"><code>android.support.v7.appcompat</code></font></A> +</H2> +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Classes" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="R.attr"></A> + <nobr><A HREF="android.support.v7.appcompat.R.attr.html">R.attr</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="R.dimen"></A> + <nobr><A HREF="android.support.v7.appcompat.R.dimen.html">R.dimen</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="R.drawable"></A> + <nobr><A HREF="android.support.v7.appcompat.R.drawable.html">R.drawable</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="R.id"></A> + <nobr><A HREF="android.support.v7.appcompat.R.id.html">R.id</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="R.integer"></A> + <nobr><A HREF="android.support.v7.appcompat.R.integer.html">R.integer</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="R.layout"></A> + <nobr><A HREF="android.support.v7.appcompat.R.layout.html">R.layout</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="R.string"></A> + <nobr><A HREF="android.support.v7.appcompat.R.string.html">R.string</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="R.style"></A> + <nobr><A HREF="android.support.v7.appcompat.R.style.html">R.style</A></nobr> + </TD> + <TD> </TD> +</TR> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="R.styleable"></A> + <nobr><A HREF="android.support.v7.appcompat.R.styleable.html">R.styleable</A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v7.util.html b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v7.util.html new file mode 100644 index 000000000000..bac03139c313 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/changes/pkg_android.support.v7.util.html @@ -0,0 +1,119 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<HTML style="overflow:auto;"> +<HEAD> +<meta name="generator" content="JDiff v1.1.0"> +<!-- Generated by the JDiff Javadoc doclet --> +<!-- (http://www.jdiff.org) --> +<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared."> +<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet"> +<TITLE> +android.support.v7.util +</TITLE> +<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" /> +<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" /> +<noscript> +<style type="text/css"> +body{overflow:auto;} +#body-content{position:relative; top:0;} +#doc-content{overflow:visible;border-left:3px solid #666;} +#side-nav{padding:0;} +#side-nav .toggle-list ul {display:block;} +#resize-packages-nav{border-bottom:3px solid #666;} +</style> +</noscript> +<style type="text/css"> +</style> +</HEAD> +<BODY> +<!-- Start of nav bar --> +<a name="top"></a> +<div id="header" style="margin-bottom:0;padding-bottom:0;"> +<div id="headerLeft"> +<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a> +</div> + <div id="headerRight"> + <div id="headerLinks"> +<!-- <img src="/assets/images/icon_world.jpg" alt="" /> --> +<span class="text"> +<!-- <a href="#">English</a> | --> +<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr> +</span> +</div> + <div class="and-diff-id" style="margin-top:6px;margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td colspan="2" class="diffspechead">API Diff Specification</td> + </tr> + <tr> + <td class="diffspec" style="padding-top:.25em">To Level:</td> + <td class="diffvaluenew" style="padding-top:.25em">22.2.1</td> + </tr> + <tr> + <td class="diffspec">From Level:</td> + <td class="diffvalueold">22.2.0</td> + </tr> + <tr> + <td class="diffspec">Generated</td> + <td class="diffvalue">2015.07.21 09:52</td> + </tr> + </table> + </div><!-- End and-diff-id --> + <div class="and-diff-id" style="margin-right:8px;"> + <table class="diffspectable"> + <tr> + <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a> + </tr> + </table> + </div> <!-- End and-diff-id --> + </div> <!-- End headerRight --> + </div> <!-- End header --> +<div id="body-content" xstyle="padding:12px;padding-right:18px;"> +<div id="doc-content" style="position:relative;"> +<div id="mainBodyFluid"> +<H2> +Package <A HREF="../../../../reference/android/support/v7/util/package-summary.html" target="_top"><font size="+1"><code>android.support.v7.util</code></font></A> +</H2> +<p> +<a NAME="Changed"></a> +<TABLE summary="Changed Classes" WIDTH="100%"> +<TR> + <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD> +</TH> +<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor"> + <TD VALIGN="TOP" WIDTH="25%"> + <A NAME="SortedList"></A> + <nobr><A HREF="android.support.v7.util.SortedList.html">SortedList</A></nobr> + </TD> + <TD> </TD> +</TR> +</TABLE> + + </div> + <div id="footer"> + <div id="copyright"> + Except as noted, this content is licensed under + <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>. + For details and restrictions, see the <a href="/license.html">Content License</a>. + </div> + <div id="footerlinks"> + <p> + <a href="http://www.android.com/terms.html">Site Terms of Service</a> - + <a href="http://www.android.com/privacy.html">Privacy Policy</a> - + <a href="http://www.android.com/branding.html">Brand Guidelines</a> + </p> + </div> + </div> <!-- end footer --> + </div><!-- end doc-content --> + </div> <!-- end body-content --> +<script src="http://www.google-analytics.com/ga.js" type="text/javascript"> +</script> +<script type="text/javascript"> + try { + var pageTracker = _gat._getTracker("UA-5831155-1"); + pageTracker._setAllowAnchor(true); + pageTracker._initData(); + pageTracker._trackPageview(); + } catch(e) {} +</script> +</BODY> +</HTML> diff --git a/docs/html/sdk/support_api_diff/22.2.1/missingSinces.txt b/docs/html/sdk/support_api_diff/22.2.1/missingSinces.txt new file mode 100644 index 000000000000..c61ba0d4fe74 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/missingSinces.txt @@ -0,0 +1,96 @@ +NO DOC BLOCK: android.support.v17.leanback.widget.DetailsOverviewLogoPresenter Class +NO DOC BLOCK: android.support.v17.leanback.widget.DetailsOverviewLogoPresenter.ViewHolder Class +NO DOC BLOCK: android.support.v17.leanback.widget.DetailsOverviewRow.Listener Class +NO DOC BLOCK: android.support.v17.leanback.widget.FacetProvider Interface +NO DOC BLOCK: android.support.v17.leanback.widget.FacetProviderAdapter Interface +NO DOC BLOCK: android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter Class +NO DOC BLOCK: android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.Listener Class +NO DOC BLOCK: android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder Class +NO DOC BLOCK: android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder.DetailsOverviewRowListener Class +NO DOC BLOCK: android.support.v17.leanback.widget.FullWidthDetailsOverviewSharedElementHelper Class +NO DOC BLOCK: android.support.v17.leanback.widget.ItemAlignmentFacet Class +NO DOC BLOCK: android.support.v17.leanback.widget.ItemAlignmentFacet.ItemAlignmentDef Class +NO DOC BLOCK: android.support.v7.app.NotificationCompat Class +NO DOC BLOCK: android.support.v7.app.NotificationCompat.Builder Class +NO DOC BLOCK: android.support.v7.app.NotificationCompat.MediaStyle Class +NO DOC BLOCK: android.support.v17.leanback.widget.OnChildViewHolderSelectedListener Class +NO DOC BLOCK: android.support.v4.app.NotificationCompatBase Constructor () +NO DOC BLOCK: android.support.v7.util.SortedList Method addAll(T...) +NO DOC BLOCK: android.support.v7.util.SortedList Method addAll(T[], boolean) +NO DOC BLOCK: android.support.v7.util.SortedList Method addAll(java.util.Collection<T>) +NO DOC BLOCK: android.support.v17.leanback.widget.ItemBridgeAdapter.ViewHolder Method getFacet(java.lang.Class<?>) +NO DOC BLOCK: android.support.v17.leanback.widget.Presenter Method getFacet(java.lang.Class<?>) +NO DOC BLOCK: android.support.v17.leanback.widget.Presenter.ViewHolder Method getFacet(java.lang.Class<?>) +NO DOC BLOCK: android.support.v17.leanback.widget.ItemBridgeAdapter Method getFacetProvider(int) +NO DOC BLOCK: android.support.v17.leanback.widget.PresenterSelector Method getPresenters() +NO DOC BLOCK: android.support.design.widget.TabLayout Method getSelectedTabPosition() +NO DOC BLOCK: android.support.v17.leanback.widget.ShadowOverlayContainer Method getShadowType() +NO DOC BLOCK: android.support.v17.leanback.widget.ShadowOverlayContainer Method getWrappedView() +NO DOC BLOCK: android.support.design.widget.FloatingActionButton Method hide() +NO DOC BLOCK: android.support.v17.leanback.app.DetailsFragment Method inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) +NO DOC BLOCK: android.support.v17.leanback.app.DetailsSupportFragment Method inflateTitle(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) +NO DOC BLOCK: android.support.v17.leanback.widget.RowPresenter Method isClippingChildren() +NO DOC BLOCK: android.support.design.widget.TabLayout.Tab Method isSelected() +NO DOC BLOCK: android.support.design.widget.CoordinatorLayout.Behavior Method onDependentViewRemoved(android.support.design.widget.CoordinatorLayout, V, android.view.View) +NO DOC BLOCK: android.support.design.widget.FloatingActionButton.Behavior Method onDependentViewRemoved(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, android.view.View) +NO DOC BLOCK: android.support.design.widget.FloatingActionButton.Behavior Method onLayoutChild(android.support.design.widget.CoordinatorLayout, android.support.design.widget.FloatingActionButton, int) +NO DOC BLOCK: android.support.v17.leanback.app.DetailsFragment Method onSetDetailsOverviewRowStatus(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int) +NO DOC BLOCK: android.support.v17.leanback.app.DetailsSupportFragment Method onSetDetailsOverviewRowStatus(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter, android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter.ViewHolder, int, int, int) +NO DOC BLOCK: android.support.v17.leanback.app.DetailsFragment Method onSetRowStatus(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int) +NO DOC BLOCK: android.support.v17.leanback.app.DetailsSupportFragment Method onSetRowStatus(android.support.v17.leanback.widget.RowPresenter, android.support.v17.leanback.widget.RowPresenter.ViewHolder, int, int, int) +NO DOC BLOCK: android.support.design.widget.Snackbar Method setActionTextColor(android.content.res.ColorStateList) +NO DOC BLOCK: android.support.design.widget.Snackbar Method setActionTextColor(int) +NO DOC BLOCK: android.support.v17.leanback.widget.Presenter Method setFacet(java.lang.Class<?>, java.lang.Object) +NO DOC BLOCK: android.support.v17.leanback.widget.Presenter.ViewHolder Method setFacet(java.lang.Class<?>, java.lang.Object) +NO DOC BLOCK: android.support.v17.leanback.app.DetailsFragment Method setupDetailsOverviewRowPresenter(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter) +NO DOC BLOCK: android.support.v17.leanback.app.DetailsSupportFragment Method setupDetailsOverviewRowPresenter(android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter) +NO DOC BLOCK: android.support.v17.leanback.app.DetailsFragment Method setupPresenter(android.support.v17.leanback.widget.Presenter) +NO DOC BLOCK: android.support.v17.leanback.app.DetailsSupportFragment Method setupPresenter(android.support.v17.leanback.widget.Presenter) +NO DOC BLOCK: android.support.design.widget.FloatingActionButton Method show() +NO DOC BLOCK: android.support.v17.leanback.widget.ShadowOverlayContainer Method supportsDynamicShadow() +NO DOC BLOCK: android.support.v17.leanback.widget.ShadowOverlayContainer Method useDynamicShadow() +NO DOC BLOCK: android.support.v17.leanback.widget.ShadowOverlayContainer Method useDynamicShadow(float, float) +NO DOC BLOCK: android.support.v17.leanback.widget.ShadowOverlayContainer Method useStaticShadow() +NO DOC BLOCK: android.support.v7.appcompat.R.id Field action0 +NO DOC BLOCK: android.support.v7.appcompat.R.id Field action_divider +NO DOC BLOCK: android.support.v7.appcompat.R.style Field Base_V12_Widget_AppCompat_AutoCompleteTextView +NO DOC BLOCK: android.support.v7.appcompat.R.style Field Base_V12_Widget_AppCompat_EditText +NO DOC BLOCK: android.support.v7.appcompat.R.style Field Base_V7_Widget_AppCompat_AutoCompleteTextView +NO DOC BLOCK: android.support.v7.appcompat.R.style Field Base_V7_Widget_AppCompat_EditText +NO DOC BLOCK: android.support.v7.appcompat.R.attr Field borderlessButtonStyle +NO DOC BLOCK: android.support.v7.appcompat.R.id Field cancel_action +NO DOC BLOCK: android.support.v7.appcompat.R.integer Field cancel_button_image_alpha +NO DOC BLOCK: android.support.v7.appcompat.R.id Field chronometer +NO DOC BLOCK: android.support.v7.appcompat.R.id Field end_padder +NO DOC BLOCK: android.support.v7.appcompat.R.id Field info +NO DOC BLOCK: android.support.design.widget.Snackbar Field LENGTH_INDEFINITE +NO DOC BLOCK: android.support.v7.appcompat.R.id Field line1 +NO DOC BLOCK: android.support.v7.appcompat.R.id Field line3 +NO DOC BLOCK: android.support.v7.appcompat.R.id Field media_actions +NO DOC BLOCK: android.support.v7.appcompat.R.dimen Field notification_large_icon_height +NO DOC BLOCK: android.support.v7.appcompat.R.dimen Field notification_large_icon_width +NO DOC BLOCK: android.support.v7.appcompat.R.layout Field notification_media_action +NO DOC BLOCK: android.support.v7.appcompat.R.layout Field notification_media_cancel_action +NO DOC BLOCK: android.support.v7.appcompat.R.dimen Field notification_subtext_size +NO DOC BLOCK: android.support.v7.appcompat.R.layout Field notification_template_big_media +NO DOC BLOCK: android.support.v7.appcompat.R.layout Field notification_template_big_media_narrow +NO DOC BLOCK: android.support.v7.appcompat.R.drawable Field notification_template_icon_bg +NO DOC BLOCK: android.support.v7.appcompat.R.layout Field notification_template_lines +NO DOC BLOCK: android.support.v7.appcompat.R.layout Field notification_template_media +NO DOC BLOCK: android.support.v7.appcompat.R.layout Field notification_template_part_chronometer +NO DOC BLOCK: android.support.v7.appcompat.R.layout Field notification_template_part_time +NO DOC BLOCK: android.support.v17.leanback.widget.ShadowOverlayContainer Field SHADOW_DYNAMIC +NO DOC BLOCK: android.support.v17.leanback.widget.ShadowOverlayContainer Field SHADOW_NONE +NO DOC BLOCK: android.support.v17.leanback.widget.ShadowOverlayContainer Field SHADOW_STATIC +NO DOC BLOCK: android.support.v7.appcompat.R.id Field status_bar_latest_event_content +NO DOC BLOCK: android.support.v7.appcompat.R.integer Field status_bar_notification_info_maxnum +NO DOC BLOCK: android.support.v7.appcompat.R.string Field status_bar_notification_info_overflow +NO DOC BLOCK: android.support.v7.appcompat.R.id Field text +NO DOC BLOCK: android.support.v7.appcompat.R.id Field text2 +NO DOC BLOCK: android.support.v7.appcompat.R.style Field TextAppearance_StatusBar_EventContent +NO DOC BLOCK: android.support.v7.appcompat.R.style Field TextAppearance_StatusBar_EventContent_Info +NO DOC BLOCK: android.support.v7.appcompat.R.style Field TextAppearance_StatusBar_EventContent_Line2 +NO DOC BLOCK: android.support.v7.appcompat.R.style Field TextAppearance_StatusBar_EventContent_Time +NO DOC BLOCK: android.support.v7.appcompat.R.style Field TextAppearance_StatusBar_EventContent_Title +NO DOC BLOCK: android.support.v7.appcompat.R.styleable Field Theme_borderlessButtonStyle +NO DOC BLOCK: android.support.v7.appcompat.R.id Field time diff --git a/docs/html/sdk/support_api_diff/22.2.1/stylesheet-jdiff.css b/docs/html/sdk/support_api_diff/22.2.1/stylesheet-jdiff.css new file mode 100644 index 000000000000..edafaa3da3e5 --- /dev/null +++ b/docs/html/sdk/support_api_diff/22.2.1/stylesheet-jdiff.css @@ -0,0 +1,44 @@ + +/* (http://www.jdiff.org) */ + +div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;} +table.diffspectable {border:1px;padding:0px;margin:0px;} +.diffspechead {background-color:#eee;} +.diffspectable tr {border:0px;padding:0px;} +.diffspectable td {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;} +td.diffvalueold {color:orange;background-color:white;border:0px;font-size:80%;font-style:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;} +td.diffvaluenew {color:green;background-color:white;border:0px;font-size:80%;font-weight:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;} +td.diffvalue {color:444;background-color:white;border:0px;font-size:80%;font-weight:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;} +td.diffspec {background-color:white;border:0px;font-size:80%;font-weight:normal;padding:1px;color:444;text-align:right;padding-right:.5em;line-height:.95em;} +tt {font-size:11pt;font-family:monospace;} +.indexHeader { + font-size:96%; + line-height:.8em;} +.jdiffIndex td { + font-size:96%; + xline-height:.8em; + padding:2px; + padding-left:1em;} +.indexText { + font-size:100%; + padding-left:1em;} +#indexTableCaption { + font-size:96%; + margin-top:.25em; + margin-bottom:0; + } +.hiddenlink { + font-size:96%; + line-height:.8em; + text-decoration:none;} +a { + text-decoration:none;} +a:hover { + text-decoration:underline;} +.indexBox { + border: 1px solid red; + margin:1em 0 0 0;} +.letterIndexHead { + font-size: 1.5em;font-weight:9; + margin:0 0 0em 0; + border: 1px solid red;} diff --git a/docs/html/tools/data-binding/guide.jd b/docs/html/tools/data-binding/guide.jd index 7c4c15a1be43..2de5bc209d55 100644 --- a/docs/html/tools/data-binding/guide.jd +++ b/docs/html/tools/data-binding/guide.jd @@ -28,6 +28,10 @@ page.tags="databinding", "layouts" <li> <a href="#binding_data">Binding Data</a> </li> + + <li> + <a href="#binding_events">Binding Events</a> + </li> </ol> </li> @@ -141,7 +145,7 @@ page.tags="databinding", "layouts" — it's a support library, so you can use it with all Android platform versions back to <strong>Android 2.1</strong> (API level 7+).</p> -<p>To use data binding, Android Plugin for Gradle <strong>1.3.0-beta1</strong> +<p>To use data binding, Android Plugin for Gradle <strong>1.3.0-beta4</strong> or higher is required.</p> <h4>Beta release</h4> @@ -187,9 +191,9 @@ or higher is required.</p> <p>To get started with Data Binding, download the library from the Support repository in the Android SDK manager. </p> -<p>The Data Binding plugin requires Android Plugin for Gradle <strong>1.3.0-beta1 -or higher</strong>, so update your build dependencies (in -<code>build.gradle</code>) as needed.</p> +<p>The Data Binding plugin requires Android Plugin for Gradle <strong>1.3.0-beta4 +or higher</strong>, so update your build dependencies (in the top-level +<code>build.gradle</code> file) as needed.</p> <p>Also, make sure you are using a compatible version of Android Studio. <strong>Android Studio 1.3</strong> adds the code-completion and layout-preview @@ -201,18 +205,18 @@ support for data binding.</p> <p> To set up your application to use data binding, add data binding to the class - path of your <code>build.gradle</code> file, right below "android". + path of your top-level <code>build.gradle</code> file, right below "android". </p> <pre> dependencies { - classpath <strong>"com.android.tools.build:gradle:1.3.0-beta1" - </strong>classpath <strong>"com.android.databinding:dataBinder:</strong>1.0-rc0" + classpath <strong>"com.android.tools.build:gradle:1.3.0-beta4"</strong> + classpath <strong>"com.android.databinding:dataBinder:1.0-rc1"</strong> } -} </pre> <p> - Then make sure jcenter is in the repositories list for your sub projects. + Then make sure jcenter is in the repositories list for your projects in the top-level + <code>build.gradle</code> file. </p> <pre> @@ -228,8 +232,8 @@ allprojects { </p> <pre> -apply plugin: ‘com.android.application' -apply plugin: '<strong>com.android.databinding</strong>' +apply plugin: 'com.android.application' +apply plugin: 'com.android.databinding' </pre> <p> The data binding plugin is going to add necessary <strong>provided</strong> @@ -252,23 +256,23 @@ apply plugin: '<strong>com.android.databinding</strong>' </p> <pre> -<em><?</em><strong>xml version="1.0" encoding="utf-8"</strong><em>?> -</em><<strong>layout xmlns:android="http://schemas.android.com/apk/res/android"</strong>> - <<strong>data</strong>> - <<strong>variable name="user" type="com.example.User"</strong>/> - </<strong>data</strong>> - <<strong>LinearLayout +<?xml version="1.0" encoding="utf-8"?> +<layout xmlns:android="http://schemas.android.com/apk/res/android"> + <data> + <variable name="user" type="com.example.User"/> + </data> + <LinearLayout android:orientation="vertical" android:layout_width="match_parent" - android:layout_height="match_parent"</strong>> - <<strong>TextView android:layout_width="wrap_content" + android:layout_height="match_parent"> + <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@{user.firstName}"</strong>/> - <<strong>TextView android:layout_width="wrap_content" + android:text="@{user.firstName}"/> + <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@{user.lastName}"</strong>/> - </<strong>LinearLayout</strong>> -</<strong>layout</strong>> + android:text="@{user.lastName}"/> + </LinearLayout> +</layout> </pre> <p> The user <strong>variable</strong> within <strong>data</strong> describes a @@ -285,9 +289,9 @@ apply plugin: '<strong>com.android.databinding</strong>' </p> <pre> -<<strong>TextView android:layout_width="wrap_content" +<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@{user.firstName}"</strong>/> + android:text="@{user.firstName}"/> </pre> <h3 id="data_object"> Data Object @@ -298,12 +302,12 @@ apply plugin: '<strong>com.android.databinding</strong>' </p> <pre> -<strong>public class </strong>User { - <strong>public final </strong>String <strong>firstName</strong>; - <strong>public final </strong>String <strong>lastName</strong>; - <strong>public </strong>User(String firstName, String lastName) { - <strong>this</strong>.<strong>firstName </strong>= firstName; - <strong>this</strong>.<strong>lastName </strong>= lastName; +public class User { + public final String firstName; + public final String lastName; + public User(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; } } </pre> @@ -314,18 +318,18 @@ apply plugin: '<strong>com.android.databinding</strong>' </p> <pre> -<strong>public class </strong>User { - <strong>private final </strong>String <strong>firstName</strong>; - <strong>private final </strong>String <strong>lastName</strong>; - <strong>public </strong>User(String firstName, String lastName) { - <strong>this</strong>.<strong>firstName </strong>= firstName; - <strong>this</strong>.<strong>lastName </strong>= lastName; +public class User { + private final String firstName; + private final String lastName; + public User(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; } - <strong>public </strong>String getFirstName() { - <strong>return this</strong>.<strong>firstName</strong>; + public String getFirstName() { + return this.firstName; } - <strong>public </strong>String getLastName() { - <strong>return this</strong>.<strong>lastName</strong>; + public String getLastName() { + return this.lastName; } } </pre> @@ -334,7 +338,8 @@ apply plugin: '<strong>com.android.databinding</strong>' expression <strong><code>@{user.firstName}</code></strong> used for the TextView’s <strong><code>android:text</code></strong> attribute will access the <strong><code>firstName</code></strong> field in the former class - and the <code>getFirstName()</code> method in the latter class. + and the <code>getFirstName()</code> method in the latter class. Alternatively, it + will also be resolved to <code>firstName()</code> if that method exists. </p> <h3 id="binding_data"> @@ -344,8 +349,8 @@ apply plugin: '<strong>com.android.databinding</strong>' <p> By default, a Binding class will be generated based on the name of the layout file, converting it to Pascal case and suffixing “Binding” to it. The above - layout file was <code>activity_main.xml</code> so the generate class was - <code>ActivityMainBinding</code>. This class holds all the bindings from the + layout file was <code>main_activity.xml</code> so the generate class was + <code>MainActivityBinding</code>. This class holds all the bindings from the layout properties (e.g. the <code>user</code> variable) to the layout’s Views and knows how to assign values for the binding expressions.The easiest means for creating the bindings is to do it while inflating: @@ -353,10 +358,10 @@ apply plugin: '<strong>com.android.databinding</strong>' <pre> @Override -<strong>protected void </strong>onCreate(Bundle savedInstanceState) { - <strong>super</strong>.onCreate(savedInstanceState); - ActivityMainBinding binding = DataBindingUtil.<em>setContentView</em>(<strong>this</strong>, R.layout.<em><strong>main_activity</strong></em>); - User user = <strong>new </strong>User(<strong>"Test"</strong>, <strong>"User"</strong>); +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity); + User user = new User("Test", "User"); binding.setUser(user); } </pre> @@ -374,11 +379,55 @@ MainActivityBinding binding = MainActivityBinding.<em>inflate</em>(getLayoutInfl </p> <pre> -ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, -false); +ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); //or ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.layout.<em><strong>list_item</strong></em>, viewGroup, <strong>false</strong>); </pre> + +<h3 id="binding_events"> + Binding Events +</h3> +<p> + Events may be bound to handler methods directly, similar to the way + <strong><code>android:onClick</code></strong> can be assigned to a method in the Activity. + Event attribute names are governed by the name of the listener method with a few exceptions. + For example, {@link android.view.View.OnLongClickListener} has a method {@link android.view.View.OnLongClickListener#onLongClick onLongClick()}, + so the attribute for this event is <code>android:onLongClick</code>. +</p> +<p> + To assign an event to its handler, use a normal binding expression, with the value + being the method name to call. For example, if your data object has two methods: +</p> +<pre>public class MyHandlers { + public void onClickFriend(View view) { ... } + public void onClickEnemy(View view) { ... } +} +</pre> +<p> + The binding expression can assign the click listener for a View: +</p> +<pre> +<?xml version="1.0" encoding="utf-8"?> +<layout xmlns:android="http://schemas.android.com/apk/res/android"> + <data> + <variable name="handlers" type="com.example.Handlers"/> + <variable name="user" type="com.example.User"/> + </data> + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@{user.firstName}" + android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/> + <TextView android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@{user.lastName}" + android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/> + </LinearLayout> +</layout> +</pre> <h2 id="layout_details"> Layout Details </h2> @@ -394,20 +443,20 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<<strong>data</strong>> - <<strong>import type="android.view.View"</strong>/> -</<strong>data</strong>> +<data> + <import type="android.view.View"/> +</data> </pre> <p> Now, View may be used within your binding expression: </p> <pre> -<<strong>TextView +<TextView android:text="@{user.lastName}" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"</strong>/> + android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"/> </pre> <p> When there are class name conflicts, one of the classes may be renamed to an @@ -415,9 +464,9 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<<strong>import type="android.view.View"</strong>/> -<<strong>import type="com.example.real.estate.View" - alias="Vista"</strong>/> +<import type="android.view.View"/> +<import type="com.example.real.estate.View" + alias="Vista"/> </pre> <p> Now, <strong><code>Vista</code></strong> may be used to reference the @@ -428,12 +477,12 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<<strong>data</strong>> - <<strong>import type="com.example.User"</strong>/> - <<strong>import type="java.util.List"</strong>/> - <<strong>variable name="user" type="User"</strong>/> - <<strong>variable name="userList" type="List&lt;User>"</strong>/> - </<strong>data</strong>> +<data> + <import type="com.example.User"/> + <import type="java.util.List"/> + <variable name="user" type="User"/> + <variable name="userList" type="List&lt;User>"/> +</data> </pre> <p class="caution"> <strong>Note</strong>: Android Studio does not yet handle imports so the @@ -443,10 +492,10 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<<strong>TextView +<TextView android:text="@{((User)(user.connection)).lastName}" android:layout_width="wrap_content" - android:layout_height="wrap_content"</strong>/> + android:layout_height="wrap_content"/> </pre> <p> Imported types may also be used when referencing static fields and methods in @@ -454,15 +503,15 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<<strong>data</strong>> - <<strong>import type="com.example.MyStringUtils"</strong>/> - <<strong>variable name="user" type="com.example.User"</strong>/> -</<strong>data</strong>> +<data> + <import type="com.example.MyStringUtils"/> + <variable name="user" type="com.example.User"/> +</data> … -<<strong>TextView +<TextView android:text="@{MyStringUtils.capitalize(user.lastName)}" android:layout_width="wrap_content" - android:layout_height="wrap_content"</strong>/> + android:layout_height="wrap_content"/> </pre> <p> Just as in Java, <code>java.lang.*</code> is imported automatically. @@ -481,16 +530,16 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<<strong>data</strong>> - <<strong>import type="android.graphics.drawable.Drawable"</strong>/> - <<strong>variable name="user" type="com.example.User"</strong>/> - <<strong>variable name="image" type="Drawable"</strong>/> - <<strong>variable name="note" type="String"</strong>/> -</<strong>data</strong>> +<data> + <import type="android.graphics.drawable.Drawable"/> + <variable name="user" type="com.example.User"/> + <variable name="image" type="Drawable"/> + <variable name="note" type="String"/> +</data> </pre> <p> The variable types are inspected at compile time, so if a variable implements - <a href="#observable_objects">Observable</a> or is an <a href= + {@link android.databinding.Observable} or is an <a href= "#observable_collections">observable collection</a>, that should be reflected in the type. If the variable is a base class or interface that does not implement the Observable* interface, the variables will <strong>not @@ -533,9 +582,9 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<<strong>data class="ContactItem"</strong>> +<data class="ContactItem"> ... -</<strong>data</strong>> +</data> </pre> <p> This generates the binding class as <code>ContactItem</code> in the @@ -545,9 +594,9 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<<strong>data class=".ContactItem"</strong>> +<data class=".ContactItem"> ... -</<strong>data</strong>> +</data> </pre> <p> In this case, <code>ContactItem</code> is generated in the module package @@ -555,9 +604,9 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<<strong>data class="com.example.ContactItem"</strong>> +<data class="com.example.ContactItem"> ... -</<strong>data</strong>> +</data> </pre> <h3 id="includes"> Includes @@ -570,28 +619,46 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<em><?</em><strong>xml version="1.0" encoding="utf-8"</strong><em>?> -</em><<strong>layout xmlns:android="http://schemas.android.com/apk/res/android" -</strong> <strong> xmlns:bind="http://schemas.android.com/apk/res-auto"</strong>> - <<strong>data</strong>> - <<strong>variable name="user" type="com.example.User"</strong>/> - </<strong>data</strong>> - <<strong>LinearLayout +<?xml version="1.0" encoding="utf-8"?> +<layout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:bind="http://schemas.android.com/apk/res-auto"> + <data> + <variable name="user" type="com.example.User"/> + </data> + <LinearLayout android:orientation="vertical" android:layout_width="match_parent" - android:layout_height="match_parent"</strong>> - <<strong>include layout="@layout/name" - bind:user="@{user}"</strong>/> - <<strong>include layout="@layout/contact" - bind:user="@{user}"</strong>/> - </<strong>LinearLayout</strong>> -</<strong>layout</strong>> + android:layout_height="match_parent"> + <include layout="@layout/name" + bind:user="@{user}"/> + <include layout="@layout/contact" + bind:user="@{user}"/> + </LinearLayout> +</layout> </pre> <p> Here, there must be a <code>user</code> variable in both the <code>name.xml</code> and <code>contact.xml</code> layout files. </p> - +<p> + Data binding does not support include as a direct child of a merge element. For example, + <strong>the following layout is not supported:</strong> +</p> +<pre> +<?xml version="1.0" encoding="utf-8"?> +<layout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:bind="http://schemas.android.com/apk/res-auto"> + <data> + <variable name="user" type="com.example.User"/> + </data> + <merge> + <include layout="@layout/name" + bind:user="@{user}"/> + <include layout="@layout/contact" + bind:user="@{user}"/> + </merge> +</layout> +</pre> <h3 id="expression_language"> Expression Language </h3> @@ -613,10 +680,10 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </li> <li> - <code>L</code>ogical <strong><code>&& ||</code></strong> + Logical <strong><code>&& ||</code></strong> </li> - <li>Binary <strong><code>&</code> <code>|</code> <code>^</code></strong> + <li>Binary <strong><code>& | ^</code></strong> </li> <li>Unary <strong><code>+ - ! ~</code></strong> @@ -659,9 +726,9 @@ ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.lay </p> <pre> -<strong>android:text="@{String.valueOf(index + 1)}" +android:text="@{String.valueOf(index + 1)}" android:visibility="@{age &lt; 13 ? View.GONE : View.VISIBLE}" -android:transitionName='@{"image_" + id}'</strong> +android:transitionName='@{"image_" + id}' </pre> <h4 id="missing_operations"> Missing Operations @@ -746,23 +813,23 @@ android:transitionName='@{"image_" + id}'</strong> </p> <pre> -<<strong>data</strong>> - <<strong>import type="android.util.SparseArray"</strong>/> - <<strong>import type="java.util.Map"</strong>/> - <<strong>import type="java.util.List"</strong>/> - <<strong>variable name="list" type="List<String>"</strong>/> - <<strong>variable name="sparse" type="SparseArray&lt;String>"</strong>/> - <<strong>variable name="map" type="Map&lt;String, String>"</strong>/> - <<strong>variable name="index" type="int"</strong>/> - <<strong>variable name="key" type="String"</strong>/> -</<strong>data</strong>> +<data> + <import type="android.util.SparseArray"/> + <import type="java.util.Map"/> + <import type="java.util.List"/> + <variable name="list" type="List&lt;String>"/> + <variable name="sparse" type="SparseArray&lt;String>"/> + <variable name="map" type="Map&lt;String, String>"/> + <variable name="index" type="int"/> + <variable name="key" type="String"/> +</data> +… +android:text="@{list[index]}" … -<strong>android:text="@{list[index]}" -</strong>… -<strong>android:text="@{sparse[index]}" -</strong>… -<strong>android:text="@{map[key]}" -</strong> +android:text="@{sparse[index]}" +… +android:text="@{map[key]}" + </pre> <h4 id="string_literals"> String Literals @@ -774,7 +841,7 @@ android:transitionName='@{"image_" + id}'</strong> </p> <pre> -<strong>android:text='@{map["firstName"]}'</strong> +android:text='@{map["firstName"]}' </pre> <p> It is also possible to use double quotes to surround the attribute value. @@ -783,8 +850,8 @@ android:transitionName='@{"image_" + id}'</strong> </p> <pre> -<strong>android:text="@{map[`firstName`}" -android:text="@{map[&quot;firstName&quot;]}"</strong> +android:text="@{map[`firstName`}" +android:text="@{map[&quot;firstName&quot;]}" </pre> <h4 id="resources"> Resources @@ -796,15 +863,15 @@ android:text="@{map[&quot;firstName&quot;]}"</strong> </p> <pre> -<strong>android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"</strong> +android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}" </pre> <p> Format strings and plurals may be evaluated by providing parameters: </p> <pre> -<strong>android:text="@{@string/nameFormat(firstName, lastName)}" -android:text="@{@plurals/banana(bananaCount)}"</strong> +android:text="@{@string/nameFormat(firstName, lastName)}" +android:text="@{@plurals/banana(bananaCount)}" </pre> <p> When a plural takes multiple parameters, all parameters should be passed: @@ -815,7 +882,7 @@ android:text="@{@plurals/banana(bananaCount)}"</strong> Have an orange Have %d oranges -android:text="<strong>@{@plurals/orange(orangeCount, orangeCount)}</strong>" +android:text="@{@plurals/orange(orangeCount, orangeCount)}" </pre> <p> Some resources require explicit type evaluation. @@ -836,9 +903,7 @@ android:text="<strong>@{@plurals/orange(orangeCount, orangeCount)} <tr> <td> - <pre> -String[] -</pre> + String[] </td> <td> @array @@ -901,9 +966,7 @@ String[] color <code>int</code> </td> <td> - <pre> -@color -</pre> + @color </td> <td> @color @@ -932,8 +995,9 @@ String[] a POJO will not cause the UI to update. The real power of data binding can be used by giving your data objects the ability to notify when data changes. There are three different data change notification mechanisms, - <code>Observable</code> objects, <code>ObservableField</code>s, and - <code>observable collections</code>. + <a href="#observable_objects">Observable objects</a>, + <a href="#observablefields">observable fields</a>, and + <a href="#observable_collections">observable collection</a>s. </p> <p> @@ -946,49 +1010,49 @@ String[] </h3> <p> - A class implementing <code>android.databinding.Observable</code> interface + A class implementing the {@link android.databinding.Observable} interface will allow the binding to attach a single listener to a bound object to listen for changes of all properties on that object. </p> <p> - The <code>Observable</code> interface has a mechanism to add and remove + The {@link android.databinding.Observable} interface has a mechanism to add and remove listeners, but notifying is up to the developer. To make development easier, - a base class, <code>BaseObservable,</code> was created to implement the + a base class, {@link android.databinding.BaseObservable}, was created to implement the listener registration mechanism. The data class implementer is still responsible for notifying when the properties change. This is done by - assigning a <code>Bindable</code> annotation to the getter and notifying in + assigning a {@link android.databinding.Bindable} annotation to the getter and notifying in the setter. </p> <pre> -<strong>private static class </strong>User <strong>extends </strong>BaseObservable { - <strong>private </strong>String <strong>firstName</strong>; - <strong>private </strong>String <strong>lastName</strong>; +private static class User extends BaseObservable { + private String firstName; + private String lastName; @Bindable - <strong>public </strong>String getFirstName() { - <strong>return this</strong>.<strong>firstName</strong>; + public String getFirstName() { + return this.firstName; } @Bindable - <strong>public </strong>String getFirstName() { - <strong>return this</strong>.<strong>lastName</strong>; + public String getLastName() { + return this.lastName; } - <strong>public void </strong>setFirstName(String firstName) { - <strong>this</strong>.<strong>firstName </strong>= firstName; + public void setFirstName(String firstName) { + this.firstName = firstName; notifyPropertyChanged(BR.firstName); } - <strong>public void </strong>setLastName(String lastName) { - <strong>this</strong>.<strong>lastName </strong>= lastName; + public void setLastName(String lastName) { + this.lastName = lastName; notifyPropertyChanged(BR.lastName); } } </pre> <p> - The <code>Bindable</code> annotation generates an entry in the BR class file + The {@link android.databinding.Bindable} annotation generates an entry in the BR class file during compilation. The BR class file will be generated in the module - package.If the base class for data classes cannot be changed, the - <code>Observable</code> interface may be implemented using the convenient - <code>PropertyChangeRegistry</code> to store and notify listeners + package. If the base class for data classes cannot be changed, the + {@link android.databinding.Observable} interface may be implemented using the convenient + {@link android.databinding.PropertyChangeRegistry} to store and notify listeners efficiently. </p> @@ -997,20 +1061,30 @@ String[] </h3> <p> - A little work is involved in creating Observable classes, so developers who - want to save time or have few properties may use ObservableFields. - ObservableFields are self-contained observable objects that have a single - field. There are versions for all primitive types and one for reference - types. To use, create a public final field in the data class: + A little work is involved in creating {@link android.databinding.Observable} classes, so + developers who want to save time or have few properties may use + {@link android.databinding.ObservableField} and its siblings + {@link android.databinding.ObservableBoolean}, + {@link android.databinding.ObservableByte}, + {@link android.databinding.ObservableChar}, + {@link android.databinding.ObservableShort}, + {@link android.databinding.ObservableInt}, + {@link android.databinding.ObservableLong}, + {@link android.databinding.ObservableFloat}, + {@link android.databinding.ObservableDouble}, and + {@link android.databinding.ObservableParcelable}. + <code>ObservableFields</code> are self-contained observable objects that have a single + field. The primitive versions avoid boxing and unboxing during access operations. + To use, create a public final field in the data class: </p> <pre> -<strong>private static class </strong>User <strong>extends </strong>BaseObservable { - <strong>public final </strong>ObservableField<String> <strong>firstName </strong>= - <strong>new </strong>ObservableField<>(); - <strong>public final </strong>ObservableField<String> <strong>lastName </strong>= - <strong>new </strong>ObservableField<>(); - <strong>public final </strong>ObservableInt <strong>age </strong>= <strong>new </strong>ObservableInt(); +private static class User { + public final ObservableField<String> firstName = + new ObservableField<>(); + public final ObservableField<String> lastName = + new ObservableField<>(); + public final ObservableInt age = new ObservableInt(); } </pre> <p> @@ -1018,8 +1092,8 @@ String[] </p> <pre> -user.<strong>firstName</strong>.set(<strong>"Google"</strong>); -<strong>int </strong>age = user.<strong>age</strong>.get(); +user.firstName.set("Google"); +int age = user.age.get(); </pre> <h3 id="observable_collections"> Observable Collections @@ -1027,43 +1101,44 @@ user.<strong>firstName</strong>.set(<strong>"Google"</strong>); <p> Some applications use more dynamic structures to hold data. Observable - collections allow keyed access to these data objects.ObservableArrayMap is + collections allow keyed access to these data objects. + {@link android.databinding.ObservableArrayMap} is useful when the key is a reference type, such as String. </p> <pre> -ObservableArrayMap<String, Object> user = <strong>new </strong>ObservableArrayMap<>(); -user.put(<strong>"firstName"</strong>, <strong>"Google"</strong>); -user.put(<strong>"lastName"</strong>, <strong>"Inc."</strong>); -user.put(<strong>"age"</strong>, 17); +ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); +user.put("firstName", "Google"); +user.put("lastName", "Inc."); +user.put("age", 17); </pre> <p> In the layout, the map may be accessed through the String keys: </p> <pre> -<<strong>data</strong>> - <<strong>import type="android.databinding.ObservableMap"</strong>/> - <<strong>variable name="user" type="ObservableMap&lt;String, Object>"</strong>/> -</<strong>data</strong>> +<data> + <import type="android.databinding.ObservableMap"/> + <variable name="user" type="ObservableMap&lt;String, Object>"/> +</data> … -<<strong>TextView +<TextView android:text='@{user["lastName"]}' android:layout_width="wrap_content" - android:layout_height="wrap_content"</strong>/> -<<strong>TextView + android:layout_height="wrap_content"/> +<TextView android:text='@{String.valueOf(1 + (Integer)user["age"])}' android:layout_width="wrap_content" - android:layout_height="wrap_content"</strong>/> + android:layout_height="wrap_content"/> </pre> <p> - ObservableArrayList is useful when the key is an integer: + {@link android.databinding.ObservableArrayList} is useful when the key is an integer: </p> <pre> -ObservableArrayList<Object> user = <strong>new </strong>ObservableArrayList<>(); -user.add(<strong>"Google"</strong>); -user.add(<strong>"Inc."</strong>); +ObservableArrayList<Object> user = new ObservableArrayList<>(); +user.add("Google"); +user.add("Inc."); user.add(17); </pre> <p> @@ -1071,20 +1146,20 @@ user.add(17); </p> <pre> -<<strong>data</strong>> - <<strong>import type="android.databinding.ObservableList"</strong>/> - <<strong>import type="com.example.my.app.Fields"</strong>/> - <<strong>variable name="user" type="ObservableList&lt;Object>"</strong>/> -</<strong>data</strong>> +<data> + <import type="android.databinding.ObservableList"/> + <import type="com.example.my.app.Fields"/> + <variable name="user" type="ObservableList&lt;Object>"/> +</data> … -<<strong>TextView +<TextView android:text='@{user[Fields.LAST_NAME]}' android:layout_width="wrap_content" - android:layout_height="wrap_content"</strong>/> -<<strong>TextView + android:layout_height="wrap_content"/> +<TextView android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}' android:layout_width="wrap_content" - android:layout_height="wrap_content"</strong>/> + android:layout_height="wrap_content"/> </pre> <h2 id="generated_binding"> Generated Binding @@ -1094,7 +1169,7 @@ user.add(17); The generated binding class links the layout variables with the Views within the layout. As discussed earlier, the name and package of the Binding may be <a href="#custom_binding_class_names">customized</a>. The Generated binding - classes all extend <code>android.databinding.ViewDataBinding</code>. + classes all extend {@link android.databinding.ViewDataBinding}. </p> <h3 id="creating"> @@ -1107,13 +1182,13 @@ user.add(17); within the layout. There are a few ways to bind to a layout. The most common is to use the static methods on the Binding class.The inflate method inflates the View hierarchy and binds to it all it one step. There is a simpler - version that only takes a <code>LayoutInflater</code> and one that takes a - <code>ViewGroup</code> as well: + version that only takes a {@link android.view.LayoutInflater} and one that takes a + {@link android.view.ViewGroup} as well: </p> <pre> -MyLayoutBinding binding = MyLayoutBinding.<em>inflate</em>(<strong>layoutInflater</strong>); -MyLayoutBinding binding = MyLayoutBinding.<em>inflate</em>(LayoutInflater, viewGroup, false); +MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater); +MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater, viewGroup, false); </pre> <p> If the layout was inflated using a different mechanism, it may be bound @@ -1121,17 +1196,17 @@ MyLayoutBinding binding = MyLayoutBinding.<em>inflate</em>(LayoutInflater, viewG </p> <pre> -MyLayoutBinding binding = MyLayoutBinding.<em>bind</em>(viewRoot); +MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot); </pre> <p> Sometimes the binding cannot be known in advance. In such cases, the binding - can be created using the DataBindingUtil class: + can be created using the {@link android.databinding.DataBindingUtil} class: </p> <pre> -ViewDataBinding binding = DataBindingUtil.<em>inflate</em>(LayoutInflater, layoutId, +ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater, layoutId, parent, attachToParent); -ViewDataBinding binding = DataBindingUtil.<em>bindTo</em>(viewRoot, layoutId); +ViewDataBinding binding = DataBindingUtil.bindTo(viewRoot, layoutId); </pre> <h3 id="views_with_ids"> Views With IDs @@ -1145,32 +1220,32 @@ ViewDataBinding binding = DataBindingUtil.<em>bindTo</em>(viewRoot, layoutId); </p> <pre> -<<strong>layout xmlns:android="http://schemas.android.com/apk/res/android"</strong>> - <<strong>data</strong>> - <<strong>variable name="user" type="com.example.User"</strong>/> - </<strong>data</strong>> - <<strong>LinearLayout +<layout xmlns:android="http://schemas.android.com/apk/res/android"> + <data> + <variable name="user" type="com.example.User"/> + </data> + <LinearLayout android:orientation="vertical" android:layout_width="match_parent" - android:layout_height="match_parent"</strong>> - <<strong>TextView android:layout_width="wrap_content" + android:layout_height="match_parent"> + <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@{user.firstName}"</strong> - <strong>android:id="@+id/firstName"</strong>/> - <<strong>TextView android:layout_width="wrap_content" + android:text="@{user.firstName}" + android:id="@+id/firstName"/> + <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="@{user.lastName}"</strong> - <strong>android:id="@+id/lastName"</strong>/> - </<strong>LinearLayout</strong>> -</<strong>layout</strong>> + android:text="@{user.lastName}" + android:id="@+id/lastName"/> + </LinearLayout> +</layout> </pre> <p> Will generate a binding class with: </p> <pre> -<strong>public final </strong>TextView <strong>firstName</strong>; -<strong>public final </strong>TextView <strong>lastName</strong>; +public final TextView firstName; +public final TextView lastName; </pre> <p> IDs are not nearly as necessary as without data binding, but there are still @@ -1186,49 +1261,49 @@ ViewDataBinding binding = DataBindingUtil.<em>bindTo</em>(viewRoot, layoutId); </p> <pre> -<<strong>data</strong>> - <<strong>import type="android.graphics.drawable.Drawable"</strong>/> - <<strong>variable name="user" type="com.example.User"</strong>/> - <<strong>variable name="image" type="Drawable"</strong>/> - <<strong>variable name="note" type="String"</strong>/> -</<strong>data</strong>> +<data> + <import type="android.graphics.drawable.Drawable"/> + <variable name="user" type="com.example.User"/> + <variable name="image" type="Drawable"/> + <variable name="note" type="String"/> +</data> </pre> <p> will generate setters and getters in the binding: </p> <pre> -<strong>public abstract </strong>com.example.User getUser(); -<strong>public abstract void </strong>setUser(com.example.User user); -<strong>public abstract </strong>Drawable getImage(); -<strong>public abstract void </strong>setImage(Drawable image); -<strong>public abstract </strong>String getNote(); -<strong>public abstract void </strong>setNote(String note); +public abstract com.example.User getUser(); +public abstract void setUser(com.example.User user); +public abstract Drawable getImage(); +public abstract void setImage(Drawable image); +public abstract String getNote(); +public abstract void setNote(String note); </pre> <h3 id="viewstubs"> ViewStubs </h3> <p> - ViewStubs are a little different from normal Views. They start off invisible + {@link android.view.ViewStub}s are a little different from normal Views. They start off invisible and when they either are made visible or are explicitly told to inflate, they replace themselves in the layout by inflating another layout. </p> <p> - Because the ViewStub essentially disappears from the View hierarchy, the View + Because the <code>ViewStub</code> essentially disappears from the View hierarchy, the View in the binding object must also disappear to allow collection. Because the - Views are final, a ViewStubProxy object takes the place of the ViewStub, - giving the developer access to the ViewStub when it exists and also access to - the inflated View hierarchy when the ViewStub has been inflated. + Views are final, a {@link android.databinding.ViewStubProxy} object takes the place of the + <code>ViewStub</code>, giving the developer access to the ViewStub when it exists and also + access to the inflated View hierarchy when the <code>ViewStub</code> has been inflated. </p> <p> When inflating another layout, a binding must be established for the new - layout. Therefore, the ViewStubProxy must listen to the ViewStub's - OnInflateListener and establish the binding at that time. Since only one can - exist, the ViewStubProxy allows the developer to set an OnInflateListener on - it that it will call after establishing the binding. + layout. Therefore, the <code>ViewStubProxy</code> must listen to the <code>ViewStub</code>'s + {@link android.view.ViewStub.OnInflateListener} and establish the binding at that time. Since + only one can exist, the <code>ViewStubProxy</code> allows the developer to set an + <code>OnInflateListener</code> on it that it will call after establishing the binding. </p> <h3 id="advanced_binding"> @@ -1241,20 +1316,20 @@ ViewDataBinding binding = DataBindingUtil.<em>bindTo</em>(viewRoot, layoutId); <p> At times, the specific binding class won't be known. For example, a - RecyclerView Adapter operating against arbitrary layouts won't know the - specific binding class. It still must assign the binding value during the - onBindViewHolder. + {@link android.support.v7.widget.RecyclerView.Adapter} operating against arbitrary layouts + won't know the specific binding class. It still must assign the binding value during the + {@link android.support.v7.widget.RecyclerView.Adapter#onBindViewHolder}. </p> <p> In this example, all layouts that the RecyclerView binds to have an "item" - variable. The BindingHolder has a getBinding method returning the - <code>ViewDataBinding</code> base. + variable. The <code>BindingHolder</code> has a <code>getBinding</code> method returning the + {@link android.databinding.ViewDataBinding} base. </p> <pre> -<strong>public void </strong>onBindViewHolder(BindingHolder holder, <strong>int </strong>position) { - <strong>final </strong>T item = <strong>mItems</strong>.get(position); +public void onBindViewHolder(BindingHolder holder, int position) { + final T item = mItems.get(position); holder.getBinding().setVariable(BR.item, item); holder.getBinding().executePendingBindings(); } @@ -1267,7 +1342,7 @@ ViewDataBinding binding = DataBindingUtil.<em>bindTo</em>(viewRoot, layoutId); When a variable or observable changes, the binding will be scheduled to change before the next frame. There are times, however, when binding must be executed immediately. To force execution, use the - <code>executePendingBindings()</code> method. + {@link android.databinding.ViewDataBinding#executePendingBindings()} method. </p> <h4> @@ -1321,17 +1396,18 @@ namespace for the attribute does not matter, only the attribute name itself. <p> Some attributes have setters that don't match by name. For these methods, an attribute may be associated with the setter through - BindingMethods annotation. This must be associated with a class and contains - BindingMethod annotations, one for each renamed method. For example, the - <strong><code>android:tint</code></strong> attribute is really associated - with setImageTintList, not setTint. + {@link android.databinding.BindingMethods} annotation. This must be associated with + a class and contains {@link android.databinding.BindingMethod} annotations, one for + each renamed method. For example, the <strong><code>android:tint</code></strong> attribute + is really associated with {@link android.widget.ImageView#setImageTintList}, not + <code>setTint</code>. </p> <pre> @BindingMethods({ - @BindingMethod(type = <strong>"android.widget.ImageView"</strong>, - attribute = <strong>"android:tint"</strong>, - method = <strong>"setImageTintList"</strong>), + @BindingMethod(type = "android.widget.ImageView", + attribute = "android:tint", + method = "setImageTintList"), }) </pre> <p> @@ -1347,7 +1423,7 @@ namespace for the attribute does not matter, only the attribute name itself. Some attributes need custom binding logic. For example, there is no associated setter for the <strong><code>android:paddingLeft</code></strong> attribute. Instead, <code>setPadding(left, top, right, bottom)</code> exists. - A static binding adapter method with the <code>BindingAdapter</code> + A static binding adapter method with the {@link android.databinding.BindingAdapter} annotation allows the developer to customize how a setter for an attribute is called. </p> @@ -1358,9 +1434,8 @@ namespace for the attribute does not matter, only the attribute name itself. </p> <pre> - -@BindingAdapter(<strong>"android:paddingLeft"</strong>) -<strong>public static void </strong>setPaddingLeft(View view, <strong>int </strong>padding) { +@BindingAdapter("android:paddingLeft") +public static void setPaddingLeft(View view, int padding) { view.setPadding(padding, view.getPaddingTop(), view.getPaddingRight(), @@ -1382,9 +1457,9 @@ namespace for the attribute does not matter, only the attribute name itself. </p> <pre> -@BindingAdapter({<strong>"bind:imageUrl"</strong>, <strong>"bind:error"</strong>}) -<strong>public static void </strong>loadImage(ImageView view, String url, Drawable error) { - Picasso.<em>with</em>(view.getContext()).load(url).error(error).into(view); +@BindingAdapter({"bind:imageUrl", "bind:error"}) +public static void loadImage(ImageView view, String url, Drawable error) { + Picasso.with(view.getContext()).load(url).error(error).into(view); } </pre> <pre> @@ -1406,6 +1481,123 @@ app:error=“@{@drawable/venueError}”/> </li> </ul> +<p> + Binding adapter methods may optionally take the old values in their handlers. A method + taking old and new values should have all old values for the attributes come first, followed + by the new values: +</p> +<pre> +@BindingAdapter("android:paddingLeft") +public static void setPaddingLeft(View view, int oldPadding, int newPadding) { + if (oldPadding != newPadding) { + view.setPadding(newPadding, + view.getPaddingTop(), + view.getPaddingRight(), + view.getPaddingBottom()); + } +} +</pre> +<p> + Event handlers may only be used with interfaces or abstract classes with one abstract method. + For example: +</p> +<pre> +@BindingAdapter("android:onLayoutChange") +public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue, + View.OnLayoutChangeListener newValue) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + if (oldValue != null) { + view.removeOnLayoutChangeListener(oldValue); + } + if (newValue != null) { + view.addOnLayoutChangeListener(newValue); + } + } +} +</pre> +<p> + When a listener has multiple methods, it must be split into multiple listeners. For example, + {@link android.view.View.OnAttachStateChangeListener} has two methods: + {@link android.view.View.OnAttachStateChangeListener#onViewAttachedToWindow onViewAttachedToWindow()} and + {@link android.view.View.OnAttachStateChangeListener#onViewDetachedFromWindow onViewDetachedFromWindow()}. + We must then create two interfaces to differentiate the attributes and handlers for them. +</p> + +<pre> +@TargetApi(VERSION_CODES.HONEYCOMB_MR1) +public interface OnViewDetachedFromWindow { + void onViewDetachedFromWindow(View v); +} + +@TargetApi(VERSION_CODES.HONEYCOMB_MR1) +public interface OnViewAttachedToWindow { + void onViewAttachedToWindow(View v); +} +</pre> +<p> + Because changing one listener will also affect the other, we must have three different + binding adapters, one for each attribute and one for both, should they both be set. +</p> +<pre> +@BindingAdapter("android:onViewAttachedToWindow") +public static void setListener(View view, OnViewAttachedToWindow attached) { + setListener(view, null, attached); +} + +@BindingAdapter("android:onViewDetachedFromWindow") +public static void setListener(View view, OnViewDetachedFromWindow detached) { + setListener(view, detached, null); +} + +@BindingAdapter({"android:onViewDetachedFromWindow", "android:onViewAttachedToWindow"}) +public static void setListener(View view, final OnViewDetachedFromWindow detach, + final OnViewAttachedToWindow attach) { + if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1) { + final OnAttachStateChangeListener newListener; + if (detach == null && attach == null) { + newListener = null; + } else { + newListener = new OnAttachStateChangeListener() { + @Override + public void onViewAttachedToWindow(View v) { + if (attach != null) { + attach.onViewAttachedToWindow(v); + } + } + + @Override + public void onViewDetachedFromWindow(View v) { + if (detach != null) { + detach.onViewDetachedFromWindow(v); + } + } + }; + } + final OnAttachStateChangeListener oldListener = ListenerUtil.trackListener(view, + newListener, R.id.onAttachStateChangeListener); + if (oldListener != null) { + view.removeOnAttachStateChangeListener(oldListener); + } + if (newListener != null) { + view.addOnAttachStateChangeListener(newListener); + } + } +} +</pre> +<p> + The above example is slightly more complicated than normal because View uses add and remove + for the listener instead of a set method for {@link android.view.View.OnAttachStateChangeListener}. + The <code>android.databinding.adapters.ListenerUtil</code> class helps keep track of the previous + listeners so that they may be removed in the Binding Adaper. +</p> +<p> + By annotating the interfaces <code>OnViewDetachedFromWindow</code> and + <code>OnViewAttachedToWindow</code> with + <code>@TargetApi(VERSION_CODES.HONEYCOMB_MR1)</code>, the data binding code + generator knows that the listener should only be generated when running on Honeycomb MR1 + and new devices, the same version supported by + {@link android.view.View#addOnAttachStateChangeListener}. +</p> <h2 id="converters"> Converters </h2> @@ -1426,10 +1618,10 @@ app:error=“@{@drawable/venueError}”/> </p> <pre> -<<strong>TextView +<TextView android:text='@{userMap["lastName"]}' android:layout_width="wrap_content" - android:layout_height="wrap_content"</strong>/> + android:layout_height="wrap_content"/> </pre> <p> @@ -1447,10 +1639,10 @@ The <code>userMap</code> returns an Object and that Object will be automatically </p> <pre> -<<strong>View +<View android:background="@{isError ? @color/red : @color/white}" android:layout_width="wrap_content" - android:layout_height="wrap_content"</strong>/> + android:layout_height="wrap_content"/> </pre> <p> Here, the background takes a <code>Drawable</code>, but the color is an @@ -1462,8 +1654,8 @@ The <code>userMap</code> returns an Object and that Object will be automatically <pre> @BindingConversion -<strong>public static </strong>ColorDrawable convertColorToDrawable(<strong>int </strong>color) { - <strong>return new </strong>ColorDrawable(color); +public static ColorDrawable convertColorToDrawable(int color) { + return new ColorDrawable(color); } </pre> <p> @@ -1472,8 +1664,8 @@ The <code>userMap</code> returns an Object and that Object will be automatically </p> <pre> -<<strong>View +<View android:background="@{isError ? @drawable/error : @color/white}" android:layout_width="wrap_content" - android:layout_height="wrap_content"</strong>/> + android:layout_height="wrap_content"/> </pre> diff --git a/docs/html/training/articles/keystore.jd b/docs/html/training/articles/keystore.jd index 52cb13eb5a03..aa1ed0acb3a7 100644 --- a/docs/html/training/articles/keystore.jd +++ b/docs/html/training/articles/keystore.jd @@ -7,14 +7,15 @@ page.title=Android Keystore System <ol> <li><a href="#SecurityFeatures">Security Features</a></li> <li><a href="#WhichShouldIUse">Choosing Between a Keychain or the Android Keystore Provider</a></li> - <li><a href="#UsingAndroidKeyStore">Using Android Keystore Provider - </a></li> + <li><a href="#UsingAndroidKeyStore">Using Android Keystore Provider</a> <ol> <li><a href="#GeneratingANewPrivateKey">Generating a New Private Key</a></li> <li><a href="#WorkingWithKeyStoreEntries">Working with Keystore Entries</a></li> <li><a href="#ListingEntries">Listing Entries</a></li> <li><a href="#SigningAndVerifyingData">Signing and Verifying Data</a></li> </ol> + </li> + <li><a href="#SupportedAlgorithms">Supported Algorithms</a></li> </ol> <h2>Blog articles</h2> @@ -27,6 +28,14 @@ page.title=Android Keystore System </div> </div> +<style type="text/css"> + tr.deprecated { + background-color: #ccc; + color: #999; + font-style: italic; + } +</style> + <p>The Android Keystore system lets you store cryptographic keys in a container to make it more difficult to extract from the device. Once keys are in the keystore, they can be used for cryptographic operations with the key material @@ -213,4 +222,456 @@ operate in one of the two modes: {@link android.hardware.fingerprint.FingerprintManager#hasEnrolledFingerprints() FingerprintManager.hasEnrolledFingerprints}). These keys become permanently invalidated once a new fingerprint is enrolled or all fingerprints are unenrolled.</li> -</ul>
\ No newline at end of file +</ul> + +<h2 id="SupportedAlgorithms">Supported Algorithms</h2> + +<ul> + <li><a href="#SupportedCiphers">{@code Cipher}</a></li> + <li><a href="#SupportedKeyGenerators">{@code KeyGenerator}</a></li> + <li><a href="#SupportedKeyFactories">{@code KeyFactory}</a></li> + <li><a href="#SupportedKeyPairGenerators">{@code KeyPairGenerator}</a></li> + <li><a href="#SupportedMacs">{@code Mac}</a></li> + <li><a href="#SupportedSignatures">{@code Signature}</a></li> + <li><a href="#SupportedSecretKeyFactories">{@code SecretKeyFactory}</a></li> +</ul> + +<h3 id="SupportedCiphers">Cipher</h3> +<table> + <thead> + <tr> + <th>Algorithm</th> + <th>Supported (API Levels)</th> + <th>Notes</th> + </tr> + </thead> + <tbody> + <tr> + <td>AES/CBC/NoPadding</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>AES/CBC/PKCS7Padding</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>AES/CTR/NoPadding</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>AES/ECB/NoPadding</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>AES/ECB/PKCS7Padding</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>AES/GCM/NoPadding</td> + <td>23+</td> + <td>Only 12-byte long IVs supported.</td> + </tr> + <tr> + <td>RSA/ECB/NoPadding</td> + <td>18+</td> + <td></td> + </tr> + <tr> + <td>RSA/ECB/PKCS1Padding</td> + <td>18+</td> + <td></td> + </tr> + <tr> + <td>RSA/ECB/OAEPWithSHA-1AndMGF1Padding</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>RSA/ECB/OAEPWithSHA-224AndMGF1Padding</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>RSA/ECB/OAEPWithSHA-256AndMGF1Padding</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>RSA/ECB/OAEPWithSHA-384AndMGF1Padding</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>RSA/ECB/OAEPWithSHA-512AndMGF1Padding</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>RSA/ECB/OAEPPadding</td> + <td>23+</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="SupportedKeyGenerators">KeyGenerator</h3> +<table> + <thead> + <tr> + <th>Algorithm</th> + <th>Supported (API Levels)</th> + <th>Notes</th> + </tr> + </thead> + <tbody> + <tr> + <td>AES</td> + <td>23+</td> + <td>Supported sizes: 128, 192, 256</td> + </tr> + <tr> + <td>HmacSHA1</td> + <td>23+</td> + <td> + <ul> + <li>Supported sizes: 8--1024 (inclusive), must be multiple of 8</li> + <li>Default size: 160</li> + <ul> + </td> + </tr> + <tr> + <td>HmacSHA224</td> + <td>23+</td> + <td> + <ul> + <li>Supported sizes: 8--1024 (inclusive), must be multiple of 8</li> + <li>Default size: 224</li> + <ul> + </td> + </tr> + <tr> + <td>HmacSHA256</td> + <td>23+</td> + <td> + <ul> + <li>Supported sizes: 8--1024 (inclusive), must be multiple of 8</li> + <li>Default size: 256</li> + <ul> + </td> + </tr> + <tr> + <td>HmacSHA384</td> + <td>23+</td> + <td> + <ul> + <li>Supported sizes: 8--1024 (inclusive), must be multiple of 8</li> + <li>Default size: 384</li> + <ul> + </td> + </tr> + <tr> + <td>HmacSHA512</td> + <td>23+</td> + <td> + <ul> + <li>Supported sizes: 8--1024 (inclusive), must be multiple of 8</li> + <li>Default size: 512</li> + <ul> + </td> + </tr> + </tbody> +</table> + +<h3 id="SupportedKeyFactories">KeyFactory</h3> +<table> + <thead> + <tr> + <th>Algorithm</th> + <th>Supported (API Levels)</th> + <th>Notes</th> + </tr> + </thead> + <tbody> + <tr> + <td>EC</td> + <td>23+</td> + <td>Supported key specs: {@link android.security.keystore.KeyInfo} (private key only), + {@link java.security.spec.ECPublicKeySpec} (public key only), + {@link java.security.spec.X509EncodedKeySpec} (public key only) + </td> + </tr> + <tr> + <td>RSA</td> + <td>23+</td> + <td>Supported key specs: {@link android.security.keystore.KeyInfo} (private key only), + {@link java.security.spec.RSAPublicKeySpec} (public key only), + {@link java.security.spec.X509EncodedKeySpec} (public key only) + </td> + </tr> + </tbody> +</table> + +<h3 id="SupportedKeyStoreKeys">KeyStore</h3> +KeyStore supports the same key types as +<a href="#SupportedKeyPairGenerators">{@code KeyPairGenerator}</a> and +<a href="#SupportedKeyGenerators">{@code KeyGenerator}</a>. + +<h3 id="SupportedKeyPairGenerators">KeyPairGenerator</h3> +<table> + <thead> + <tr> + <th>Algorithm</th> + <th>Supported (API Levels)</th> + <th>Notes</th> + </tr> + </thead> + <tbody> + <tr class="deprecated"> + <td>DSA</td> + <td>19–22</td> + <td></td> + </tr> + <tr> + <td>EC</td> + <td>23+</td> + <td> + <ul> + <li>Supported sizes: 224, 256, 384, 521</li> + <li>Supported named curves: P-224 (secp256r1), P-256 (aka secp256r1 and prime256v1), P-384 + (aka secp384r1), P-521 (aka secp521r1)</li> + </ul> + + <p>Prior to API Level 23, EC keys can be generated using KeyPairGenerator of algorithm "RSA" + initialized {@link android.security.KeyPairGeneratorSpec} whose key type is set to "EC" + using {@link android.security.KeyPairGeneratorSpec.Builder#setKeyType(String)}. EC curve + name cannot be specified using this method -- a NIST P-curve is automatically chosen based + on the requested key size. + </td> + </tr> + <tr> + <td>RSA</td> + <td>18+</td> + <td> + <ul> + <li>Supported sizes: 512, 768, 1024, 2048, 3072, 4096</li> + <li>Supported public exponents: 3, 65537</li> + <li>Default public exponent: 65537</li> + </ul> + </td> + </tr> + </tbody> +</table> + +<h3 id="SupportedMacs">Mac</h3> +<table> + <thead> + <tr> + <th>Algorithm</th> + <th>Supported (API Levels)</th> + <th>Notes</th> + </tr> + </thead> + <tbody> + <tr> + <td>HmacSHA1</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>HmacSHA224</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>HmacSHA256</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>HmacSHA384</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>HmacSHA512</td> + <td>23+</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="SupportedSignatures">Signature</h3> +<table> + <thead> + <tr> + <th>Algorithm</th> + <th>Supported (API Levels)</th> + <th>Notes</th> + </tr> + </thead> + <tbody> + <tr> + <td>MD5withRSA</td> + <td>18+</td> + <td></td> + </tr> + <tr> + <td>NONEwithECDSA</td> + <td>23+</td> + <td></td> + </tr> + <tr> + <td>NONEwithRSA</td> + <td>18+</td> + <td></td> + </tr> + <tr class="deprecated"> + <td>SHA1withDSA</td> + <td>19–22</td> + <td></td> + </tr> + <tr> + <td>SHA1withECDSA</td> + <td>19+</td> + <td></td> + </tr> + <tr> + <td>SHA1withRSA</td> + <td>18+</td> + <td></td> + </tr> + <tr> + <td>SHA1withRSA/PSS</td> + <td>23+</td> + <td></td> + </tr> + <tr class="deprecated"> + <td>SHA224withDSA</td> + <td>20–22</td> + <td></td> + </tr> + <tr> + <td>SHA224withECDSA</td> + <td>20+</td> + <td></td> + </tr> + <tr> + <td>SHA224withRSA</td> + <td>20+</td> + <td></td> + </tr> + <tr> + <td>SHA224withRSA/PSS</td> + <td>23+</td> + <td></td> + </tr> + <tr class="deprecated"> + <td>SHA256withDSA</td> + <td>19–22</td> + <td></td> + </tr> + <tr> + <td>SHA256withECDSA</td> + <td>19+</td> + <td></td> + </tr> + <tr> + <td>SHA256withRSA</td> + <td>18+</td> + <td></td> + </tr> + <tr> + <td>SHA256withRSA/PSS</td> + <td>23+</td> + <td></td> + </tr> + <tr class="deprecated"> + <td>SHA384withDSA</td> + <td>19–22</td> + <td></td> + </tr> + <tr> + <td>SHA384withECDSA</td> + <td>19+</td> + <td></td> + </tr> + <tr> + <td>SHA384withRSA</td> + <td>18+</td> + <td></td> + </tr> + <tr> + <td>SHA384withRSA/PSS</td> + <td>23+</td> + <td></td> + </tr> + <tr class="deprecated"> + <td>SHA512withDSA</td> + <td>19–22</td> + <td></td> + </tr> + <tr> + <td>SHA512withECDSA</td> + <td>19+</td> + <td></td> + </tr> + <tr> + <td>SHA512withRSA</td> + <td>18+</td> + <td></td> + </tr> + <tr> + <td>SHA512withRSA/PSS</td> + <td>23+</td> + <td></td> + </tr> + </tbody> +</table> + +<h3 id="SupportedSecretKeyFactories">SecretKeyFactory</h3> +<table> + <thead> + <tr> + <th>Algorithm</th> + <th>Supported (API Levels)</th> + <th>Notes</th> + </tr> + </thead> + <tbody> + <tr> + <td>AES</td> + <td>23+</td> + <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td> + </tr> + <tr> + <td>HmacSHA1</td> + <td>23+</td> + <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td> + </tr> + <tr> + <td>HmacSHA224</td> + <td>23+</td> + <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td> + </tr> + <tr> + <td>HmacSHA256</td> + <td>23+</td> + <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td> + </tr> + <tr> + <td>HmacSHA384</td> + <td>23+</td> + <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td> + </tr> + <tr> + <td>HmacSHA512</td> + <td>23+</td> + <td>Supported key specs: {@link android.security.keystore.KeyInfo}</td> + </tr> + </tbody> +</table>
\ No newline at end of file diff --git a/docs/html/training/tv/start/hardware.jd b/docs/html/training/tv/start/hardware.jd index 57651e66e411..5747b569ed41 100644 --- a/docs/html/training/tv/start/hardware.jd +++ b/docs/html/training/tv/start/hardware.jd @@ -163,7 +163,7 @@ if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION) android:required="false"/> <uses-feature android:name="android.hardware.nfc" android:required="false"/> -<uses-feature android:name="android.hardware.gps" +<uses-feature android:name="android.hardware.location.gps" android:required="false"/> <uses-feature android:name="android.hardware.microphone" android:required="false"/> diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 8ad7c12c342e..3e4d93bb3df9 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -23,6 +23,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.Trace; import android.util.DisplayMetrics; +import android.util.Log; import dalvik.system.VMRuntime; @@ -33,6 +34,8 @@ import java.nio.IntBuffer; import java.nio.ShortBuffer; public final class Bitmap implements Parcelable { + private static final String TAG = "Bitmap"; + /** * Indicates that the bitmap was created for an unknown pixel density. * @@ -159,6 +162,9 @@ public final class Bitmap implements Parcelable { * @see #DENSITY_NONE */ public int getDensity() { + if (mRecycled) { + Log.w(TAG, "Called getDensity() on a recycle()'d bitmap! This is undefined behavior!"); + } return mDensity; } @@ -330,7 +336,9 @@ public final class Bitmap implements Parcelable { * @return The current generation ID for this bitmap. */ public int getGenerationId() { - if (mRecycled) return 0; + if (mRecycled) { + Log.w(TAG, "Called getGenerationId() on a recycle()'d bitmap! This is undefined behavior!"); + } return nativeGenerationId(mFinalizer.mNativeBitmap); } @@ -1057,7 +1065,9 @@ public final class Bitmap implements Parcelable { * @see BitmapFactory.Options#inPremultiplied */ public final boolean isPremultiplied() { - if (mRecycled) return false; + if (mRecycled) { + Log.w(TAG, "Called isPremultiplied() on a recycle()'d bitmap! This is undefined behavior!"); + } return nativeIsPremultiplied(mFinalizer.mNativeBitmap); } @@ -1089,11 +1099,17 @@ public final class Bitmap implements Parcelable { /** Returns the bitmap's width */ public final int getWidth() { + if (mRecycled) { + Log.w(TAG, "Called getWidth() on a recycle()'d bitmap! This is undefined behavior!"); + } return mWidth; } /** Returns the bitmap's height */ public final int getHeight() { + if (mRecycled) { + Log.w(TAG, "Called getHeight() on a recycle()'d bitmap! This is undefined behavior!"); + } return mHeight; } @@ -1176,7 +1192,9 @@ public final class Bitmap implements Parcelable { * @return number of bytes between rows of the native bitmap pixels. */ public final int getRowBytes() { - if (mRecycled) return 0; + if (mRecycled) { + Log.w(TAG, "Called getRowBytes() on a recycle()'d bitmap! This is undefined behavior!"); + } return nativeRowBytes(mFinalizer.mNativeBitmap); } @@ -1220,7 +1238,9 @@ public final class Bitmap implements Parcelable { * that config, otherwise return null. */ public final Config getConfig() { - if (mRecycled) return Config.ARGB_8888; + if (mRecycled) { + Log.w(TAG, "Called getConfig() on a recycle()'d bitmap! This is undefined behavior!"); + } return Config.nativeToConfig(nativeConfig(mFinalizer.mNativeBitmap)); } @@ -1233,7 +1253,9 @@ public final class Bitmap implements Parcelable { * it will return true by default. */ public final boolean hasAlpha() { - if (mRecycled) return false; + if (mRecycled) { + Log.w(TAG, "Called hasAlpha() on a recycle()'d bitmap! This is undefined behavior!"); + } return nativeHasAlpha(mFinalizer.mNativeBitmap); } @@ -1270,7 +1292,9 @@ public final class Bitmap implements Parcelable { * @see #setHasMipMap(boolean) */ public final boolean hasMipMap() { - if (mRecycled) return false; + if (mRecycled) { + Log.w(TAG, "Called hasMipMap() on a recycle()'d bitmap! This is undefined behavior!"); + } return nativeHasMipMap(mFinalizer.mNativeBitmap); } diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index 24cb0559f065..1cfccc458c88 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -200,6 +200,11 @@ public class VectorDrawable extends Drawable { private static final int LINEJOIN_ROUND = 1; private static final int LINEJOIN_BEVEL = 2; + // Cap the bitmap size, such that it won't hurt the performance too much + // and it won't crash due to a very large scale. + // The drawable will look blurry above this size. + private static final int MAX_CACHED_BITMAP_SIZE = 2048; + private static final boolean DBG_VECTOR_DRAWABLE = false; private VectorDrawableState mVectorState; @@ -219,6 +224,11 @@ public class VectorDrawable extends Drawable { private int mDpiScaledHeight = 0; private Insets mDpiScaleInsets = Insets.NONE; + // Temp variable, only for saving "new" operation at the draw() time. + private final float[] mTmpFloats = new float[9]; + private final Matrix mTmpMatrix = new Matrix(); + private final Rect mTmpBounds = new Rect(); + public VectorDrawable() { this(null, null); } @@ -262,44 +272,59 @@ public class VectorDrawable extends Drawable { @Override public void draw(Canvas canvas) { - final Rect bounds = getBounds(); - if (bounds.width() <= 0 || bounds.height() <= 0) { + // We will offset the bounds for drawBitmap, so copyBounds() here instead + // of getBounds(). + copyBounds(mTmpBounds); + if (mTmpBounds.width() <= 0 || mTmpBounds.height() <= 0) { // Nothing to draw return; } + // Color filters always override tint filters. + final ColorFilter colorFilter = (mColorFilter == null ? mTintFilter : mColorFilter); + + // The imageView can scale the canvas in different ways, in order to + // avoid blurry scaling, we have to draw into a bitmap with exact pixel + // size first. This bitmap size is determined by the bounds and the + // canvas scale. + canvas.getMatrix(mTmpMatrix); + mTmpMatrix.getValues(mTmpFloats); + float canvasScaleX = Math.abs(mTmpFloats[Matrix.MSCALE_X]); + float canvasScaleY = Math.abs(mTmpFloats[Matrix.MSCALE_Y]); + int scaledWidth = (int) (mTmpBounds.width() * canvasScaleX); + int scaledHeight = (int) (mTmpBounds.height() * canvasScaleY); + scaledWidth = Math.min(MAX_CACHED_BITMAP_SIZE, scaledWidth); + scaledHeight = Math.min(MAX_CACHED_BITMAP_SIZE, scaledHeight); + + if (scaledWidth <= 0 || scaledHeight <= 0) { + return; + } + final int saveCount = canvas.save(); - final boolean needMirroring = needMirroring(); + canvas.translate(mTmpBounds.left, mTmpBounds.top); - canvas.translate(bounds.left, bounds.top); + // Handle RTL mirroring. + final boolean needMirroring = needMirroring(); if (needMirroring) { - canvas.translate(bounds.width(), 0); + canvas.translate(mTmpBounds.width(), 0); canvas.scale(-1.0f, 1.0f); } - // Color filters always override tint filters. - final ColorFilter colorFilter = mColorFilter == null ? mTintFilter : mColorFilter; + // At this point, canvas has been translated to the right position. + // And we use this bound for the destination rect for the drawBitmap, so + // we offset to (0, 0); + mTmpBounds.offsetTo(0, 0); + mVectorState.createCachedBitmapIfNeeded(scaledWidth, scaledHeight); if (!mAllowCaching) { - // AnimatedVectorDrawable - if (!mVectorState.hasTranslucentRoot()) { - mVectorState.mVPathRenderer.draw( - canvas, bounds.width(), bounds.height(), colorFilter); - } else { - mVectorState.createCachedBitmapIfNeeded(bounds); - mVectorState.updateCachedBitmap(bounds); - mVectorState.drawCachedBitmapWithRootAlpha(canvas, colorFilter); - } + mVectorState.updateCachedBitmap(scaledWidth, scaledHeight); } else { - // Static Vector Drawable case. - mVectorState.createCachedBitmapIfNeeded(bounds); if (!mVectorState.canReuseCache()) { - mVectorState.updateCachedBitmap(bounds); + mVectorState.updateCachedBitmap(scaledWidth, scaledHeight); mVectorState.updateCacheStates(); } - mVectorState.drawCachedBitmapWithRootAlpha(canvas, colorFilter); } - + mVectorState.drawCachedBitmapWithRootAlpha(canvas, colorFilter, mTmpBounds); canvas.restoreToCount(saveCount); } @@ -770,10 +795,11 @@ public class VectorDrawable extends Drawable { } } - public void drawCachedBitmapWithRootAlpha(Canvas canvas, ColorFilter filter) { + public void drawCachedBitmapWithRootAlpha(Canvas canvas, ColorFilter filter, + Rect originalBounds) { // The bitmap's size is the same as the bounds. final Paint p = getPaint(filter); - canvas.drawBitmap(mCachedBitmap, 0, 0, p); + canvas.drawBitmap(mCachedBitmap, null, originalBounds, p); } public boolean hasTranslucentRoot() { @@ -797,16 +823,15 @@ public class VectorDrawable extends Drawable { return mTempPaint; } - public void updateCachedBitmap(Rect bounds) { + public void updateCachedBitmap(int width, int height) { mCachedBitmap.eraseColor(Color.TRANSPARENT); Canvas tmpCanvas = new Canvas(mCachedBitmap); - mVPathRenderer.draw(tmpCanvas, bounds.width(), bounds.height(), null); + mVPathRenderer.draw(tmpCanvas, width, height, null); } - public void createCachedBitmapIfNeeded(Rect bounds) { - if (mCachedBitmap == null || !canReuseBitmap(bounds.width(), - bounds.height())) { - mCachedBitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), + public void createCachedBitmapIfNeeded(int width, int height) { + if (mCachedBitmap == null || !canReuseBitmap(width, height)) { + mCachedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); mCacheDirty = true; } diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java index 5459bea88a19..441ee660b53a 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java @@ -51,7 +51,7 @@ import javax.crypto.spec.GCMParameterSpec; abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreCipherSpiBase { abstract static class GCM extends AndroidKeyStoreAuthenticatedAESCipherSpi { - private static final int MIN_SUPPORTED_TAG_LENGTH_BITS = 96; + static final int MIN_SUPPORTED_TAG_LENGTH_BITS = 96; private static final int MAX_SUPPORTED_TAG_LENGTH_BITS = 128; private static final int DEFAULT_TAG_LENGTH_BITS = 128; private static final int IV_LENGTH_BYTES = 12; diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java index 6a7930afa63f..4c174f13a27a 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java @@ -171,7 +171,7 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { "Key size must be positive: " + mKeySizeBits); } else if ((mKeySizeBits % 8) != 0) { throw new InvalidAlgorithmParameterException( - "Key size in must be a multiple of 8: " + mKeySizeBits); + "Key size must be a multiple of 8: " + mKeySizeBits); } try { @@ -197,48 +197,36 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { } } } - if (spec.isDigestsSpecified()) { - // Digest(s) explicitly specified in the spec - mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests()); - if (mKeymasterDigest != -1) { - // Key algorithm implies a digest -- ensure it's specified in the spec as - // first digest. - if (!com.android.internal.util.ArrayUtils.contains( - mKeymasterDigests, mKeymasterDigest)) { + + if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { + // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm + // implies SHA-256 digest). Because keymaster HMAC key is authorized only for + // one digest, we don't let algorithm parameter spec override the digest implied + // by the key. If the spec specifies digests at all, it must specify only one + // digest, the only implied by key algorithm. + mKeymasterDigests = new int[] {mKeymasterDigest}; + if (spec.isDigestsSpecified()) { + // Digest(s) explicitly specified in the spec. Check that the list + // consists of exactly one digest, the one implied by key algorithm. + int[] keymasterDigestsFromSpec = + KeyProperties.Digest.allToKeymaster(spec.getDigests()); + if ((keymasterDigestsFromSpec.length != 1) + || (keymasterDigestsFromSpec[0] != mKeymasterDigest)) { throw new InvalidAlgorithmParameterException( - "Digests specified in algorithm parameters (" - + Arrays.asList(spec.getDigests()) + ") must include " - + " the digest " + "Unsupported digests specification: " + + Arrays.asList(spec.getDigests()) + ". Only " + KeyProperties.Digest.fromKeymaster(mKeymasterDigest) - + " implied by key algorithm"); - } - if (mKeymasterDigests[0] != mKeymasterDigest) { - // The first digest is not the one implied by the key algorithm. - // Swap the implied digest with the first one. - for (int i = 0; i < mKeymasterDigests.length; i++) { - if (mKeymasterDigests[i] == mKeymasterDigest) { - mKeymasterDigests[i] = mKeymasterDigests[0]; - mKeymasterDigests[0] = mKeymasterDigest; - break; - } - } + + " supported for this HMAC key algorithm"); } } } else { - // No digest specified in the spec - if (mKeymasterDigest != -1) { - // Key algorithm implies a digest -- use that digest - mKeymasterDigests = new int[] {mKeymasterDigest}; + // Key algorithm does not imply a digest. + if (spec.isDigestsSpecified()) { + mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests()); } else { mKeymasterDigests = EmptyArray.INT; } } - if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { - if (mKeymasterDigests.length == 0) { - throw new InvalidAlgorithmParameterException( - "At least one digest algorithm must be specified"); - } - } // Check that user authentication related parameters are acceptable. This method // will throw an IllegalStateException if there are issues (e.g., secure lock screen @@ -284,6 +272,11 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { KeymasterUtils.addUserAuthArgs(args, spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds()); + KeymasterUtils.addMinMacLengthAuthorizationIfNecessary( + args, + mKeymasterAlgorithm, + mKeymasterBlockModes, + mKeymasterDigests); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, spec.getKeyValidityStart()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, spec.getKeyValidityForOriginationEnd()); diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java index 6b36a5846d95..79095f42cd06 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -63,7 +63,6 @@ import java.security.spec.ECGenParameterSpec; import java.security.spec.RSAKeyGenParameterSpec; import java.util.ArrayList; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -215,7 +214,14 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY); // Authorized to be used with any digest (including no digest). - specBuilder.setDigests(KeyProperties.DIGEST_NONE); + // MD5 was never offered for Android Keystore for ECDSA. + specBuilder.setDigests( + KeyProperties.DIGEST_NONE, + KeyProperties.DIGEST_SHA1, + KeyProperties.DIGEST_SHA224, + KeyProperties.DIGEST_SHA256, + KeyProperties.DIGEST_SHA384, + KeyProperties.DIGEST_SHA512); break; case KeymasterDefs.KM_ALGORITHM_RSA: specBuilder = new KeyGenParameterSpec.Builder( @@ -225,11 +231,23 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato | KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY); // Authorized to be used with any digest (including no digest). - specBuilder.setDigests(KeyProperties.DIGEST_NONE); + specBuilder.setDigests( + KeyProperties.DIGEST_NONE, + KeyProperties.DIGEST_MD5, + KeyProperties.DIGEST_SHA1, + KeyProperties.DIGEST_SHA224, + KeyProperties.DIGEST_SHA256, + KeyProperties.DIGEST_SHA384, + KeyProperties.DIGEST_SHA512); // Authorized to be used with any encryption and signature padding - // scheme (including no padding). + // schemes (including no padding). specBuilder.setEncryptionPaddings( - KeyProperties.ENCRYPTION_PADDING_NONE); + KeyProperties.ENCRYPTION_PADDING_NONE, + KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1, + KeyProperties.ENCRYPTION_PADDING_RSA_OAEP); + specBuilder.setSignaturePaddings( + KeyProperties.SIGNATURE_PADDING_RSA_PKCS1, + KeyProperties.SIGNATURE_PADDING_RSA_PSS); // Disable randomized encryption requirement to support encryption // padding NONE above. specBuilder.setRandomizedEncryptionRequired(false); @@ -724,27 +742,11 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato // We use Bouncy Castle to generate self-signed RSA certificates. Bouncy Castle // only supports RSA certificates signed using PKCS#1 padding scheme. The key needs // to be authorized for PKCS#1 padding or padding NONE which means any padding. - boolean pkcs1SignaturePaddingSupported = false; - for (int keymasterPadding : KeyProperties.SignaturePadding.allToKeymaster( - spec.getSignaturePaddings())) { - if ((keymasterPadding == KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN) - || (keymasterPadding == KeymasterDefs.KM_PAD_NONE)) { - pkcs1SignaturePaddingSupported = true; - break; - } - } - if (!pkcs1SignaturePaddingSupported) { - // Keymaster doesn't distinguish between encryption padding NONE and signature - // padding NONE. In the Android Keystore API only encryption padding NONE is - // exposed. - for (int keymasterPadding : KeyProperties.EncryptionPadding.allToKeymaster( - spec.getEncryptionPaddings())) { - if (keymasterPadding == KeymasterDefs.KM_PAD_NONE) { - pkcs1SignaturePaddingSupported = true; - break; - } - } - } + boolean pkcs1SignaturePaddingSupported = + com.android.internal.util.ArrayUtils.contains( + KeyProperties.SignaturePadding.allToKeymaster( + spec.getSignaturePaddings()), + KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN); if (!pkcs1SignaturePaddingSupported) { // Key not authorized for PKCS#1 signature padding -- can't sign return null; @@ -803,14 +805,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato : KeyProperties.Digest.allToKeymaster(supportedSignatureDigests)) { supportedKeymasterSignatureDigests.add(keymasterDigest); } - if (authorizedKeymasterKeyDigests.contains(KeymasterDefs.KM_DIGEST_NONE)) { - // Key is authorized to be used with any digest - return supportedKeymasterSignatureDigests; - } else { - // Key is authorized to be used only with specific digests. - Set<Integer> result = new HashSet<Integer>(supportedKeymasterSignatureDigests); - result.retainAll(authorizedKeymasterKeyDigests); - return result; - } + Set<Integer> result = new HashSet<Integer>(supportedKeymasterSignatureDigests); + result.retainAll(authorizedKeymasterKeyDigests); + return result; } } diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java index 94ed8b45d20a..56cc44cc7cc1 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java @@ -18,16 +18,11 @@ package android.security.keystore; import android.annotation.NonNull; import android.annotation.Nullable; -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.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -103,91 +98,6 @@ abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase protected final int getAdditionalEntropyAmountForFinish() { return 0; } - - @Override - @NonNull - protected KeyStoreCryptoOperationStreamer createMainDataStreamer( - KeyStore keyStore, IBinder operationToken) { - if (isEncrypting()) { - // KeyStore's RSA encryption without padding expects the input to be of the same - // length as the modulus. We thus have to buffer all input to pad it with leading - // zeros. - return new ZeroPaddingEncryptionStreamer( - super.createMainDataStreamer(keyStore, operationToken), - getModulusSizeBytes()); - } else { - return super.createMainDataStreamer(keyStore, operationToken); - } - } - - /** - * Streamer which buffers all plaintext input, then pads it with leading zeros to match - * modulus size, and then sends it into KeyStore to obtain ciphertext. - */ - private static class ZeroPaddingEncryptionStreamer - implements KeyStoreCryptoOperationStreamer { - - private final KeyStoreCryptoOperationStreamer mDelegate; - private final int mModulusSizeBytes; - private final ByteArrayOutputStream mInputBuffer = new ByteArrayOutputStream(); - private long mConsumedInputSizeBytes; - - private ZeroPaddingEncryptionStreamer( - KeyStoreCryptoOperationStreamer delegate, - int modulusSizeBytes) { - mDelegate = delegate; - mModulusSizeBytes = modulusSizeBytes; - } - - @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(); - byte[] paddedInput; - if (bufferedInput.length < mModulusSizeBytes) { - // Pad input with leading zeros - paddedInput = new byte[mModulusSizeBytes]; - System.arraycopy( - bufferedInput, 0, - paddedInput, - paddedInput.length - bufferedInput.length, - bufferedInput.length); - } else { - // RI throws BadPaddingException in this scenario. INVALID_ARGUMENT below will - // be translated into BadPaddingException. - throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_ARGUMENT, - "Message size (" + bufferedInput.length + " bytes) must be smaller than" - + " modulus (" + mModulusSizeBytes + " bytes)"); - } - return mDelegate.doFinal(paddedInput, 0, paddedInput.length, signature, - additionalEntropy); - } - - @Override - public long getConsumedInputSizeBytes() { - return mConsumedInputSizeBytes; - } - - @Override - public long getProducedOutputSizeBytes() { - return mDelegate.getProducedOutputSizeBytes(); - } - } } /** diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java index e9f19cd5aea2..d300a9297054 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java @@ -41,6 +41,7 @@ import java.security.KeyStoreException; import java.security.KeyStoreSpi; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; +import java.security.ProviderException; import java.security.PublicKey; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; @@ -291,7 +292,14 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { new KeyProtection.Builder( KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY); // Authorized to be used with any digest (including no digest). - specBuilder.setDigests(KeyProperties.DIGEST_NONE); + // MD5 was never offered for Android Keystore for ECDSA. + specBuilder.setDigests( + KeyProperties.DIGEST_NONE, + KeyProperties.DIGEST_SHA1, + KeyProperties.DIGEST_SHA224, + KeyProperties.DIGEST_SHA256, + KeyProperties.DIGEST_SHA384, + KeyProperties.DIGEST_SHA512); } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) { specBuilder = new KeyProtection.Builder( @@ -300,13 +308,25 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { | KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY); // Authorized to be used with any digest (including no digest). - specBuilder.setDigests(KeyProperties.DIGEST_NONE); - // Authorized to be used with any encryption and signature padding scheme (including no - // padding). + specBuilder.setDigests( + KeyProperties.DIGEST_NONE, + KeyProperties.DIGEST_MD5, + KeyProperties.DIGEST_SHA1, + KeyProperties.DIGEST_SHA224, + KeyProperties.DIGEST_SHA256, + KeyProperties.DIGEST_SHA384, + KeyProperties.DIGEST_SHA512); + // Authorized to be used with any encryption and signature padding + // schemes (including no padding). specBuilder.setEncryptionPaddings( - KeyProperties.ENCRYPTION_PADDING_NONE); - // Disable randomized encryption requirement to support encryption padding NONE - // above. + KeyProperties.ENCRYPTION_PADDING_NONE, + KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1, + KeyProperties.ENCRYPTION_PADDING_RSA_OAEP); + specBuilder.setSignaturePaddings( + KeyProperties.SIGNATURE_PADDING_RSA_PKCS1, + KeyProperties.SIGNATURE_PADDING_RSA_PSS); + // Disable randomized encryption requirement to support encryption + // padding NONE above. specBuilder.setRandomizedEncryptionRequired(false); } else { throw new KeyStoreException("Unsupported key algorithm: " + keyAlgorithm); @@ -605,50 +625,43 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm); int[] keymasterDigests; - int keymasterDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm()); - if (params.isDigestsSpecified()) { - // Digest(s) specified in parameters - keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); - if (keymasterDigest != -1) { - // Digest also specified in the JCA key algorithm name. - if (!com.android.internal.util.ArrayUtils.contains( - keymasterDigests, keymasterDigest)) { - throw new KeyStoreException("Digest specified in key algorithm " - + key.getAlgorithm() + " not specified in protection parameters: " - + Arrays.asList(params.getDigests())); - } - // When the key is read back from keystore we reconstruct the JCA key algorithm - // name from the KM_TAG_ALGORITHM and the first KM_TAG_DIGEST. Thus we need to - // ensure that the digest reflected in the JCA key algorithm name is the first - // KM_TAG_DIGEST tag. - if (keymasterDigests[0] != keymasterDigest) { - // The first digest is not the one implied by the JCA key algorithm name. - // Swap the implied digest with the first one. - for (int i = 0; i < keymasterDigests.length; i++) { - if (keymasterDigests[i] == keymasterDigest) { - keymasterDigests[i] = keymasterDigests[0]; - keymasterDigests[0] = keymasterDigest; - break; - } - } + if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { + // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm + // implies SHA-256 digest). Because keymaster HMAC key is authorized only for one + // digest, we don't let import parameters override the digest implied by the key. + // If the parameters specify digests at all, they must specify only one digest, the + // only implied by key algorithm. + int keymasterImpliedDigest = + KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm()); + if (keymasterImpliedDigest == -1) { + throw new ProviderException( + "HMAC key algorithm digest unknown for key algorithm " + + key.getAlgorithm()); + } + keymasterDigests = new int[] {keymasterImpliedDigest}; + if (params.isDigestsSpecified()) { + // Digest(s) explicitly specified in params -- check that the list consists of + // exactly one digest, the one implied by key algorithm. + int[] keymasterDigestsFromParams = + KeyProperties.Digest.allToKeymaster(params.getDigests()); + if ((keymasterDigestsFromParams.length != 1) + || (keymasterDigestsFromParams[0] != keymasterImpliedDigest)) { + throw new KeyStoreException( + "Unsupported digests specification: " + + Arrays.asList(params.getDigests()) + ". Only " + + KeyProperties.Digest.fromKeymaster(keymasterImpliedDigest) + + " supported for HMAC key algorithm " + key.getAlgorithm()); } } } else { - // No digest specified in parameters - if (keymasterDigest != -1) { - // Digest specified in the JCA key algorithm name. - keymasterDigests = new int[] {keymasterDigest}; + // Key algorithm does not imply a digest. + if (params.isDigestsSpecified()) { + keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); } else { keymasterDigests = EmptyArray.INT; } } 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" - + " for key algorithm " + key.getAlgorithm()); - } - } @KeyProperties.PurposeEnum int purposes = params.getPurposes(); int[] keymasterBlockModes = @@ -678,6 +691,11 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { KeymasterUtils.addUserAuthArgs(args, params.isUserAuthenticationRequired(), params.getUserAuthenticationValidityDurationSeconds()); + KeymasterUtils.addMinMacLengthAuthorizationIfNecessary( + args, + keymasterAlgorithm, + keymasterBlockModes, + keymasterDigests); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, params.getKeyValidityStart()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index 919dd489085f..7605231fa991 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -65,17 +65,16 @@ import javax.security.auth.x500.X500Principal; * * <p>NOTE: If a private key is not authorized to sign the self-signed certificate, then the * certificate will be created with an invalid signature which will not verify. Such a certificate - * is still useful because it provides access to the public key. To generate a valid - * signature for the certificate the key needs to be authorized for all of the following: + * is still useful because it provides access to the public key. To generate a valid signature for + * the certificate the key needs to be authorized for all of the following: * <ul> * <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> + * <li>suitable digest,</li> + * <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1}.</li> * </ul> * * <p>NOTE: The key material of the generated symmetric and private keys is not accessible. The key @@ -642,7 +641,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec { * <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}). + * {@code SHA-256} for key algorithm {@code HmacSHA256}). HMAC keys cannot be authorized + * for more than one digest. * * <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 @@ -667,7 +667,8 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec { * * <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it * is usually necessary to authorize the use of no/any padding - * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}). This is because RSA decryption is + * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}) and/or PKCS#1 encryption padding + * ({@link KeyProperties#ENCRYPTION_PADDING_RSA_PKCS1}). This is because RSA decryption is * required by some cipher suites, and some stacks request decryption using no padding * whereas others request PKCS#1 padding. * diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java index 2b49297841de..d6b1cf1da8a2 100644 --- a/keystore/java/android/security/keystore/KeyProperties.java +++ b/keystore/java/android/security/keystore/KeyProperties.java @@ -364,9 +364,6 @@ public abstract class KeyProperties { /** * No encryption padding. - * - * <p><b>NOTE</b>: If a key is authorized to be used with no padding, then it can be used with - * any padding scheme, both for encryption and signing. */ public static final String ENCRYPTION_PADDING_NONE = "NoPadding"; @@ -513,9 +510,6 @@ public abstract class KeyProperties { /** * No digest: sign/authenticate the raw message. - * - * <p><b>NOTE</b>: If a key is authorized to be used with no digest, then it can be used with - * any digest. */ public static final String DIGEST_NONE = "NONE"; diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java index 5b4b3e73cb01..b71dc8248a1c 100644 --- a/keystore/java/android/security/keystore/KeyProtection.java +++ b/keystore/java/android/security/keystore/KeyProtection.java @@ -386,7 +386,8 @@ public final class KeyProtection implements ProtectionParameter { * * <p>For RSA private keys used by TLS/SSL servers to authenticate themselves to clients it * is usually necessary to authorize the use of no/any padding - * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}). This is because RSA decryption is + * ({@link KeyProperties#ENCRYPTION_PADDING_NONE}) and/or PKCS#1 encryption padding + * ({@link KeyProperties#ENCRYPTION_PADDING_RSA_PKCS1}). This is because RSA decryption is * required by some cipher suites, and some stacks request decryption using no padding * whereas others request PKCS#1 padding. * @@ -423,7 +424,8 @@ public final class KeyProtection implements ProtectionParameter { * <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}). + * {@code SHA-256} for key algorithm {@code HmacSHA256}). HMAC keys cannot be authorized + * for more than one digest. * * <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 ea0f4b9cef09..dbb79bcd5aea 100644 --- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java +++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java @@ -19,12 +19,14 @@ package android.security.keystore; import android.os.IBinder; import android.security.KeyStore; import android.security.KeyStoreException; +import android.security.keymaster.KeymasterDefs; import android.security.keymaster.OperationResult; import libcore.util.EmptyArray; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.security.ProviderException; /** * Helper for streaming a crypto operation's input and output via {@link KeyStore} service's @@ -135,14 +137,15 @@ class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationS mBuffered = EmptyArray.BYTE; mBufferedOffset = 0; mBufferedLength = 0; - } else if (opResult.inputConsumed == 0) { + } else if (opResult.inputConsumed <= 0) { // Nothing was consumed. More input needed. if (inputLength > 0) { // More input is available, but it wasn't included into the previous chunk // because the chunk reached its maximum permitted size. // Shouldn't have happened. - throw new IllegalStateException("Nothing consumed from max-sized chunk: " - + chunk.length + " bytes"); + throw new KeyStoreException(KeymasterDefs.KM_ERROR_UNKNOWN_ERROR, + "Keystore consumed nothing from max-sized chunk: " + chunk.length + + " bytes"); } mBuffered = chunk; mBufferedOffset = 0; @@ -153,8 +156,9 @@ class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationS mBufferedOffset = opResult.inputConsumed; mBufferedLength = chunk.length - opResult.inputConsumed; } else { - throw new IllegalStateException("Consumed more than provided: " - + opResult.inputConsumed + ", provided: " + chunk.length); + throw new KeyStoreException(KeymasterDefs.KM_ERROR_UNKNOWN_ERROR, + "Keystore consumed more input than provided. Provided: " + chunk.length + + ", consumed: " + opResult.inputConsumed); } if ((opResult.output != null) && (opResult.output.length > 0)) { @@ -165,7 +169,7 @@ class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationS try { bufferedOutput.write(opResult.output); } catch (IOException e) { - throw new IllegalStateException("Failed to buffer output", e); + throw new ProviderException("Failed to buffer output", e); } } } else { @@ -179,7 +183,7 @@ class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationS try { bufferedOutput.write(opResult.output); } catch (IOException e) { - throw new IllegalStateException("Failed to buffer output", e); + throw new ProviderException("Failed to buffer output", e); } result = bufferedOutput.toByteArray(); } @@ -229,27 +233,71 @@ class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationS return EmptyArray.BYTE; } - byte[] chunk = ArrayUtils.subarray(mBuffered, mBufferedOffset, mBufferedLength); - mBuffered = EmptyArray.BYTE; - mBufferedLength = 0; - mBufferedOffset = 0; + // Keep invoking the update operation with remaining buffered data until either all of the + // buffered data is consumed or until update fails to consume anything. + ByteArrayOutputStream bufferedOutput = null; + while (mBufferedLength > 0) { + byte[] chunk = ArrayUtils.subarray(mBuffered, mBufferedOffset, mBufferedLength); + OperationResult opResult = mKeyStoreStream.update(chunk); + if (opResult == null) { + throw new KeyStoreConnectException(); + } else if (opResult.resultCode != KeyStore.NO_ERROR) { + throw KeyStore.getKeyStoreException(opResult.resultCode); + } - OperationResult opResult = mKeyStoreStream.update(chunk); - if (opResult == null) { - throw new KeyStoreConnectException(); - } else if (opResult.resultCode != KeyStore.NO_ERROR) { - throw KeyStore.getKeyStoreException(opResult.resultCode); + if (opResult.inputConsumed <= 0) { + // Nothing was consumed. Break out of the loop to avoid an infinite loop. + break; + } + + if (opResult.inputConsumed >= chunk.length) { + // All of the input was consumed + mBuffered = EmptyArray.BYTE; + mBufferedOffset = 0; + mBufferedLength = 0; + } else { + // Some of the input was not consumed + mBuffered = chunk; + mBufferedOffset = opResult.inputConsumed; + mBufferedLength = chunk.length - opResult.inputConsumed; + } + + if (opResult.inputConsumed > chunk.length) { + throw new KeyStoreException(KeymasterDefs.KM_ERROR_UNKNOWN_ERROR, + "Keystore consumed more input than provided. Provided: " + + chunk.length + ", consumed: " + opResult.inputConsumed); + } + + if ((opResult.output != null) && (opResult.output.length > 0)) { + // Some output was produced by this update operation + if (bufferedOutput == null) { + // No output buffered yet. + if (mBufferedLength == 0) { + // No more output will be produced by this flush operation + mProducedOutputSizeBytes += opResult.output.length; + return opResult.output; + } else { + // More output might be produced by this flush operation -- buffer output. + bufferedOutput = new ByteArrayOutputStream(); + } + } + // Buffer the output from this update operation + try { + bufferedOutput.write(opResult.output); + } catch (IOException e) { + throw new ProviderException("Failed to buffer output", e); + } + } } - if (opResult.inputConsumed < chunk.length) { - throw new IllegalStateException("Keystore failed to consume all input. Provided: " - + chunk.length + ", consumed: " + opResult.inputConsumed); - } else if (opResult.inputConsumed > chunk.length) { - throw new IllegalStateException("Keystore consumed more input than provided" - + " . Provided: " + chunk.length + ", consumed: " + opResult.inputConsumed); + if (mBufferedLength > 0) { + throw new KeyStoreException(KeymasterDefs.KM_ERROR_INVALID_INPUT_LENGTH, + "Keystore failed to consume last " + + ((mBufferedLength != 1) ? (mBufferedLength + " bytes") : "byte") + + " of input"); } - byte[] result = (opResult.output != null) ? opResult.output : EmptyArray.BYTE; + byte[] result = (bufferedOutput != null) ? bufferedOutput.toByteArray() : EmptyArray.BYTE; mProducedOutputSizeBytes += result.length; return result; } diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java index 92d636c0a4af..feafbfa65394 100644 --- a/keystore/java/android/security/keystore/KeymasterUtils.java +++ b/keystore/java/android/security/keystore/KeymasterUtils.java @@ -22,6 +22,8 @@ import android.security.KeyStore; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; +import java.security.ProviderException; + /** * @hide */ @@ -133,4 +135,45 @@ public abstract class KeymasterUtils { userAuthenticationValidityDurationSeconds); } } + + /** + * Adds {@code KM_TAG_MIN_MAC_LENGTH} tag, if necessary, to the keymaster arguments for + * generating or importing a key. This tag may only be needed for symmetric keys (e.g., HMAC, + * AES-GCM). + */ + public static void addMinMacLengthAuthorizationIfNecessary(KeymasterArguments args, + int keymasterAlgorithm, + int[] keymasterBlockModes, + int[] keymasterDigests) { + switch (keymasterAlgorithm) { + case KeymasterDefs.KM_ALGORITHM_AES: + if (com.android.internal.util.ArrayUtils.contains( + keymasterBlockModes, KeymasterDefs.KM_MODE_GCM)) { + // AES GCM key needs the minimum length of AEAD tag specified. + args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH, + AndroidKeyStoreAuthenticatedAESCipherSpi.GCM + .MIN_SUPPORTED_TAG_LENGTH_BITS); + } + break; + case KeymasterDefs.KM_ALGORITHM_HMAC: + // HMAC key needs the minimum length of MAC set to the output size of the associated + // digest. This is because we do not offer a way to generate shorter MACs and + // don't offer a way to verify MACs (other than by generating them). + if (keymasterDigests.length != 1) { + throw new ProviderException( + "Unsupported number of authorized digests for HMAC key: " + + keymasterDigests.length + + ". Exactly one digest must be authorized"); + } + int keymasterDigest = keymasterDigests[0]; + int digestOutputSizeBits = getDigestOutputSizeBits(keymasterDigest); + if (digestOutputSizeBits == -1) { + throw new ProviderException( + "HMAC key authorized for unsupported digest: " + + KeyProperties.Digest.fromKeymaster(keymasterDigest)); + } + args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH, digestOutputSizeBits); + break; + } + } } diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index a95db9faf72c..62aabb13858d 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -6758,7 +6758,13 @@ void ResTable::print(bool inclValues) const printf(" NON-INTEGER ResTable_type ADDRESS: %p\n", type); continue; } - String8 configStr = type->config.toString(); + + // Always copy the config, as fields get added and we need to + // set the defaults. + ResTable_config thisConfig; + thisConfig.copyFromDtoH(type->config); + + String8 configStr = thisConfig.toString(); printf(" config %s:\n", configStr.size() > 0 ? configStr.string() : "(default)"); size_t entryCount = dtohl(type->entryCount); diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp index 966959a8708e..0dababd774c1 100644 --- a/libs/hwui/AnimatorManager.cpp +++ b/libs/hwui/AnimatorManager.cpp @@ -117,7 +117,6 @@ uint32_t AnimatorManager::animate(TreeInfo& info) { uint32_t dirty = animateCommon(info); - mParent.mProperties.updateMatrix(); info.damageAccumulator->pushTransform(&mParent); mParent.damageSelf(info); @@ -136,6 +135,7 @@ uint32_t AnimatorManager::animateCommon(TreeInfo& info) { newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor); mAnimators.erase(newEnd, mAnimators.end()); mAnimationHandle->notifyAnimationsRan(); + mParent.mProperties.updateMatrix(); return functor.dirtyMask; } diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 10304517fff7..aa73d44af14b 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -248,11 +248,6 @@ void Caches::clearGarbage() { void Caches::flush(FlushMode mode) { FLUSH_LOGD("Flushing caches (mode %d)", mode); - // We must stop tasks before clearing caches - if (mode > kFlushMode_Layers) { - tasks.stop(); - } - switch (mode) { case kFlushMode_Full: textureCache.clear(); diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp index eb520b48a67a..b1a68447fc21 100644 --- a/libs/hwui/ClipArea.cpp +++ b/libs/hwui/ClipArea.cpp @@ -263,10 +263,11 @@ void ClipArea::enterRectangleMode() { bool ClipArea::rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op) { - // TODO: we should be able to handle kReplace_Op efficiently without - // going through RegionMode and later falling back into RectangleMode. - - if (op != SkRegion::kIntersect_Op) { + if (op == SkRegion::kReplace_Op && transform->rectToRect()) { + mClipRect = r; + transform->mapRect(mClipRect); + return true; + } else if (op != SkRegion::kIntersect_Op) { enterRegionMode(); return regionModeClipRectWithTransform(r, transform, op); } diff --git a/libs/hwui/ClipArea.h b/libs/hwui/ClipArea.h index e284af0b2e69..51ef27b4e9cc 100644 --- a/libs/hwui/ClipArea.h +++ b/libs/hwui/ClipArea.h @@ -153,6 +153,8 @@ private: } void regionFromPath(const SkPath& path, SkRegion& pathAsRegion) { + // TODO: this should not mask every path to the viewport - this makes it impossible to use + // paths to clip to larger areas (which is valid e.g. with SkRegion::kReplace_Op) pathAsRegion.setPath(path, createViewportRegion()); } diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 80f349aa19a2..0951fc158ace 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -214,10 +214,10 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { info.renderer->pushLayerUpdate(mLayer); } - if (CC_UNLIKELY(info.canvasContext)) { - // If canvasContext is not null that means there are prefetched layers - // that need to be accounted for. That might be us, so tell CanvasContext - // that this layer is in the tree and should not be destroyed. + if (info.canvasContext) { + // There might be prefetched layers that need to be accounted for. + // That might be us, so tell CanvasContext that this layer is in the + // tree and should not be destroyed. info.canvasContext->markLayerInUse(this); } } @@ -339,7 +339,8 @@ void RenderNode::prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayL TextureCache& cache = Caches::getInstance().textureCache; info.out.hasFunctors |= subtree->functors.size(); for (size_t i = 0; info.prepareTextures && i < subtree->bitmapResources.size(); i++) { - info.prepareTextures = cache.prefetchAndMarkInUse(subtree->bitmapResources[i]); + info.prepareTextures = cache.prefetchAndMarkInUse( + info.canvasContext, subtree->bitmapResources[i]); } for (size_t i = 0; i < subtree->children().size(); i++) { DrawRenderNodeOp* op = subtree->children()[i]; diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index a2aa2d103048..81d8516168dd 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -203,7 +203,13 @@ bool tryStoreBitmap(Caches& caches, const SkShader& shader, const Matrix4& model return false; } - outData->bitmapTexture = caches.textureCache.get(&bitmap); + /* + * Bypass the AssetAtlas, since those textures: + * 1) require UV mapping, which isn't implemented in matrix computation below + * 2) can't handle REPEAT simply + * 3) are safe to upload here (outside of sync stage), since they're static + */ + outData->bitmapTexture = caches.textureCache.getAndBypassAtlas(&bitmap); if (!outData->bitmapTexture) return false; outData->bitmapSampler = (*textureUnit)++; diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h index 7227ce0dd24c..4bcd96dd32f7 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -97,7 +97,7 @@ public: * Whether or not the Texture is marked in use and thus not evictable for * the current frame. This is reset at the start of a new frame. */ - bool isInUse = false; + void* isInUse = nullptr; private: /** diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index fe1b7fdbfbbf..fda009108aba 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -122,10 +122,12 @@ void TextureCache::setAssetAtlas(AssetAtlas* assetAtlas) { mAssetAtlas = assetAtlas; } -void TextureCache::resetMarkInUse() { +void TextureCache::resetMarkInUse(void* ownerToken) { LruCache<uint32_t, Texture*>::Iterator iter(mCache); while (iter.next()) { - iter.value()->isInUse = false; + if (iter.value()->isInUse == ownerToken) { + iter.value()->isInUse = nullptr; + } } } @@ -140,8 +142,8 @@ bool TextureCache::canMakeTextureFromBitmap(const SkBitmap* bitmap) { // Returns a prepared Texture* that either is already in the cache or can fit // in the cache (and is thus added to the cache) -Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) { - if (CC_LIKELY(mAssetAtlas)) { +Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap, AtlasUsageType atlasUsageType) { + if (CC_LIKELY(mAssetAtlas != nullptr) && atlasUsageType == AtlasUsageType::Use) { AssetAtlas::Entry* entry = mAssetAtlas->getEntry(bitmap); if (CC_UNLIKELY(entry)) { return entry->texture; @@ -189,16 +191,16 @@ Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) { return texture; } -bool TextureCache::prefetchAndMarkInUse(const SkBitmap* bitmap) { - Texture* texture = getCachedTexture(bitmap); +bool TextureCache::prefetchAndMarkInUse(void* ownerToken, const SkBitmap* bitmap) { + Texture* texture = getCachedTexture(bitmap, AtlasUsageType::Use); if (texture) { - texture->isInUse = true; + texture->isInUse = ownerToken; } return texture; } -Texture* TextureCache::get(const SkBitmap* bitmap) { - Texture* texture = getCachedTexture(bitmap); +Texture* TextureCache::get(const SkBitmap* bitmap, AtlasUsageType atlasUsageType) { + Texture* texture = getCachedTexture(bitmap, atlasUsageType); if (!texture) { if (!canMakeTextureFromBitmap(bitmap)) { diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index e7fc990a6588..7a7ee5aeb554 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -66,20 +66,30 @@ public: /** * Resets all Textures to not be marked as in use */ - void resetMarkInUse(); + void resetMarkInUse(void* ownerToken); /** * Attempts to precache the SkBitmap. Returns true if a Texture was successfully * acquired for the bitmap, false otherwise. If a Texture was acquired it is * marked as in use. */ - bool prefetchAndMarkInUse(const SkBitmap* bitmap); + bool prefetchAndMarkInUse(void* ownerToken, const SkBitmap* bitmap); /** - * Returns the texture associated with the specified bitmap. If the texture - * cannot be found in the cache, a new texture is generated. + * Returns the texture associated with the specified bitmap from either within the cache, or + * the AssetAtlas. If the texture cannot be found in the cache, a new texture is generated. */ - Texture* get(const SkBitmap* bitmap); + Texture* get(const SkBitmap* bitmap) { + return get(bitmap, AtlasUsageType::Use); + } + + /** + * Returns the texture associated with the specified bitmap. If the texture cannot be found in + * the cache, a new texture is generated, even if it resides in the AssetAtlas. + */ + Texture* getAndBypassAtlas(const SkBitmap* bitmap) { + return get(bitmap, AtlasUsageType::Bypass); + } /** * Removes the texture associated with the specified pixelRef. This is meant @@ -123,10 +133,15 @@ public: void setAssetAtlas(AssetAtlas* assetAtlas); private: + enum class AtlasUsageType { + Use, + Bypass, + }; bool canMakeTextureFromBitmap(const SkBitmap* bitmap); - Texture* getCachedTexture(const SkBitmap* bitmap); + Texture* get(const SkBitmap* bitmap, AtlasUsageType atlasUsageType); + Texture* getCachedTexture(const SkBitmap* bitmap, AtlasUsageType atlasUsageType); /** * Generates the texture from a bitmap into the specified texture structure. diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h index 0799c6c44da1..ed853f72539d 100644 --- a/libs/hwui/TreeInfo.h +++ b/libs/hwui/TreeInfo.h @@ -95,7 +95,7 @@ public: // layer updates or similar. May be NULL. OpenGLRenderer* renderer; ErrorHandler* errorHandler; - // TODO: Remove this? May be NULL + // May be NULL (TODO: can it really?) renderthread::CanvasContext* canvasContext; struct Out { diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp index 3ebd57b33c81..1e39bfa4b583 100644 --- a/libs/hwui/renderstate/RenderState.cpp +++ b/libs/hwui/renderstate/RenderState.cpp @@ -124,9 +124,15 @@ void RenderState::bindFramebuffer(GLuint fbo) { } void RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) { - interruptForFunctorInvoke(); - (*functor)(mode, info); - resumeFromFunctorInvoke(); + if (mode == DrawGlInfo::kModeProcessNoContext) { + // If there's no context we don't need to interrupt as there's + // no gl state to save/restore + (*functor)(mode, info); + } else { + interruptForFunctorInvoke(); + (*functor)(mode, info); + resumeFromFunctorInvoke(); + } } void RenderState::interruptForFunctorInvoke() { diff --git a/libs/hwui/renderstate/Stencil.cpp b/libs/hwui/renderstate/Stencil.cpp index 92a057d92c5d..319cfe4ba0d0 100644 --- a/libs/hwui/renderstate/Stencil.cpp +++ b/libs/hwui/renderstate/Stencil.cpp @@ -60,8 +60,14 @@ GLenum Stencil::getLayerStencilFormat() { } void Stencil::clear() { + glStencilMask(0xff); glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); + + if (mState == kTest) { + // reset to test state, with immutable stencil + glStencilMask(0); + } } void Stencil::enableTest(int incrementThreshold) { @@ -104,17 +110,17 @@ void Stencil::enableDebugTest(GLint value, bool greater) { // We only want to test, let's keep everything glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); mState = kTest; + glStencilMask(0); } void Stencil::enableDebugWrite() { - if (mState != kWrite) { - enable(); - glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff); - // The test always passes so the first two values are meaningless - glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - mState = kWrite; - } + enable(); + glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff); + // The test always passes so the first two values are meaningless + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + mState = kWrite; + glStencilMask(0xff); } void Stencil::enable() { diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 260fb6fc3373..6dfb6e811e60 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -145,7 +145,11 @@ void CanvasContext::setOpaque(bool opaque) { void CanvasContext::makeCurrent() { // TODO: Figure out why this workaround is needed, see b/13913604 // In the meantime this matches the behavior of GLRenderer, so it is not a regression - mHaveNewSurface |= mEglManager.makeCurrent(mEglSurface); + EGLint error = 0; + mHaveNewSurface |= mEglManager.makeCurrent(mEglSurface, &error); + if (error) { + setSurface(nullptr); + } } void CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater) { @@ -174,16 +178,13 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy info.damageAccumulator = &mDamageAccumulator; info.renderer = mCanvas; - if (mPrefetechedLayers.size() && info.mode == TreeInfo::MODE_FULL) { - info.canvasContext = this; - } + info.canvasContext = this; + mAnimationContext->startFrame(info.mode); mRootRenderNode->prepareTree(info); mAnimationContext->runRemainingAnimations(info); - if (info.canvasContext) { - freePrefetechedLayers(); - } + freePrefetechedLayers(); if (CC_UNLIKELY(!mNativeWindow.get())) { mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame); @@ -228,10 +229,11 @@ void CanvasContext::draw() { SkRect dirty; mDamageAccumulator.finish(&dirty); - if (dirty.isEmpty() && Properties::skipEmptyFrames) { - mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame); - return; - } + // TODO: Re-enable after figuring out cause of b/22592975 +// if (dirty.isEmpty() && Properties::skipEmptyFrames) { +// mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame); +// return; +// } mCurrentFrameInfo->markIssueDrawCommandsStart(); @@ -365,7 +367,11 @@ void CanvasContext::destroyHardwareResources() { if (mEglManager.hasEglContext()) { freePrefetechedLayers(); mRootRenderNode->destroyHardwareResources(); - Caches::getInstance().flush(Caches::kFlushMode_Layers); + Caches& caches = Caches::getInstance(); + // Make sure to release all the textures we were owning as there won't + // be another draw + caches.textureCache.resetMarkInUse(this); + caches.flush(Caches::kFlushMode_Layers); } } diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 6507ce824e03..a4ac13bb95a1 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -114,7 +114,7 @@ bool DrawFrameTask::syncFrameState(TreeInfo& info) { int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::Vsync)]; mRenderThread->timeLord().vsyncReceived(vsync); mContext->makeCurrent(); - Caches::getInstance().textureCache.resetMarkInUse(); + Caches::getInstance().textureCache.resetMarkInUse(mContext); for (size_t i = 0; i < mLayers.size(); i++) { mContext->processLayerUpdate(mLayers[i].get()); diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index cb34e0072545..eb332d59fee3 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -217,7 +217,7 @@ void EglManager::destroy() { mCurrentSurface = EGL_NO_SURFACE; } -bool EglManager::makeCurrent(EGLSurface surface) { +bool EglManager::makeCurrent(EGLSurface surface, EGLint* errOut) { if (isCurrent(surface)) return false; if (surface == EGL_NO_SURFACE) { @@ -225,8 +225,14 @@ bool EglManager::makeCurrent(EGLSurface surface) { surface = mPBufferSurface; } if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) { - LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s", - (void*)surface, egl_error_str()); + if (errOut) { + *errOut = eglGetError(); + ALOGW("Failed to make current on surface %p, error=%s", + (void*)surface, egl_error_str(*errOut)); + } else { + LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s", + (void*)surface, egl_error_str()); + } } mCurrentSurface = surface; return true; diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h index 8881de62a94d..0a8cfd30df71 100644 --- a/libs/hwui/renderthread/EglManager.h +++ b/libs/hwui/renderthread/EglManager.h @@ -44,7 +44,7 @@ public: bool isCurrent(EGLSurface surface) { return mCurrentSurface == surface; } // Returns true if the current surface changed, false if it was already current - bool makeCurrent(EGLSurface surface); + bool makeCurrent(EGLSurface surface, EGLint* errOut = nullptr); void beginFrame(EGLSurface surface, EGLint* width, EGLint* height); bool swapBuffers(EGLSurface surface, const SkRect& dirty, EGLint width, EGLint height); diff --git a/libs/hwui/unit_tests/ClipAreaTests.cpp b/libs/hwui/unit_tests/ClipAreaTests.cpp index 166d5b6e92f6..0c5e5e715dea 100644 --- a/libs/hwui/unit_tests/ClipAreaTests.cpp +++ b/libs/hwui/unit_tests/ClipAreaTests.cpp @@ -112,5 +112,16 @@ TEST(ClipArea, paths) { regionBounds.set(skRect); EXPECT_EQ(expected, regionBounds); } + +TEST(ClipArea, replaceNegative) { + ClipArea area(createClipArea()); + area.setClip(0, 0, 100, 100); + + Matrix4 transform; + transform.loadIdentity(); + Rect expected(-50, -50, 50, 50); + area.clipRectWithTransform(expected, &transform, SkRegion::kReplace_Op); + EXPECT_EQ(expected, area.getClipRect()); +} } } diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index c29ec0de355b..bde3d196c37c 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -54,7 +54,7 @@ import java.util.Arrays; * can be played on a device operating at a sample rate of 48000Hz; the sample rate conversion is * automatically handled by the platform, it will not play at 6x speed. * - * <p>As of API {@link android.os.Build.VERSION_CODES#MNC}, + * <p>As of API {@link android.os.Build.VERSION_CODES#M}, * sample rates up to 192kHz are supported * for <code>AudioRecord</code> and <code>AudioTrack</code>, with sample rate conversion * performed as needed. @@ -99,7 +99,7 @@ import java.util.Arrays; * Floats are efficiently manipulated by modern CPUs, * have greater precision than 24 bit signed integers, * and have greater dynamic range than 32 bit signed integers. - * <code>AudioRecord</code> as of API {@link android.os.Build.VERSION_CODES#MNC} and + * <code>AudioRecord</code> as of API {@link android.os.Build.VERSION_CODES#M} and * <code>AudioTrack</code> as of API {@link android.os.Build.VERSION_CODES#LOLLIPOP} * support <code>ENCODING_PCM_FLOAT</code>. * </li> @@ -123,7 +123,7 @@ import java.util.Arrays; * the samples and their arrangement in the audio frame. They are also used in the endpoint (e.g. * a USB audio interface, a DAC connected to headphones) to specify allowable configurations of a * particular device. - * <br>As of API {@link android.os.Build.VERSION_CODES#MNC}, there are two types of channel masks: + * <br>As of API {@link android.os.Build.VERSION_CODES#M}, there are two types of channel masks: * channel position masks and channel index masks. * * <h5 id="channelPositionMask">Channel position masks</h5> @@ -152,7 +152,7 @@ import java.util.Arrays; * {@link #CHANNEL_OUT_FRONT_RIGHT}. * * <h5 id="channelIndexMask">Channel index masks</h5> - * Channel index masks are introduced in API {@link android.os.Build.VERSION_CODES#MNC}. They allow + * Channel index masks are introduced in API {@link android.os.Build.VERSION_CODES#M}. They allow * the selection of a particular channel from the source or sink endpoint by number, i.e. the first * channel, the second channel, and so forth. This avoids problems with artificially assigning * positions to channels of an endpoint, or figuring what the i<sup>th</sup> position bit is within diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index acdadd76c6c8..e99a37a41d30 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -604,6 +604,10 @@ public class AudioSystem public static final int SYNC_EVENT_NONE = 0; public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 1; + /** + * @return command completion status, one of {@link #AUDIO_STATUS_OK}, + * {@link #AUDIO_STATUS_ERROR} or {@link #AUDIO_STATUS_SERVER_DIED} + */ public static native int setDeviceConnectionState(int device, int state, String device_address, String device_name); public static native int getDeviceConnectionState(int device, String device_address); diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 62810c6f8b5a..8880dad99270 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -27,7 +27,6 @@ import java.util.Collection; import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.SystemApi; import android.app.ActivityThread; import android.app.AppOpsManager; import android.content.Context; @@ -1174,9 +1173,12 @@ public class AudioTrack * Poll for a timestamp on demand. * <p> * If you need to track timestamps during initial warmup or after a routing or mode change, - * you should request a new timestamp once per second until the reported timestamps - * show that the audio clock is stable. - * Thereafter, query for a new timestamp approximately once every 10 seconds to once per minute. + * you should request a new timestamp periodically until the reported timestamps + * show that the frame position is advancing, or until it becomes clear that + * timestamps are unavailable for this route. + * <p> + * After the clock is advancing at a stable rate, + * query for a new timestamp approximately once every 10 seconds to once per minute. * Calling this method more often is inefficient. * It is also counter-productive to call this method more often than recommended, * because the short-term differences between successive timestamp reports are not meaningful. @@ -1199,6 +1201,11 @@ public class AudioTrack * In the case that no timestamp is available, any supplied instance is left unaltered. * A timestamp may be temporarily unavailable while the audio clock is stabilizing, * or during and immediately after a route change. + * A timestamp is permanently unavailable for a given route if the route does not support + * timestamps. In this case, the approximate frame position can be obtained + * using {@link #getPlaybackHeadPosition}. + * However, it may be useful to continue to query for + * timestamps occasionally, to recover after a route change. */ // Add this text when the "on new timestamp" API is added: // Use if you need to get the most recent timestamp outside of the event callback handler. @@ -1409,7 +1416,7 @@ public class AudioTrack * <br> * If looping is currently enabled and the new position is greater than or equal to the * loop end marker, the behavior varies by API level: - * as of {@link android.os.Build.VERSION_CODES#MNC}, + * as of {@link android.os.Build.VERSION_CODES#M}, * the looping is first disabled and then the position is set. * For earlier API levels, the behavior is unspecified. * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, @@ -1446,7 +1453,7 @@ public class AudioTrack * {@link #ERROR_BAD_VALUE} is returned. * The loop range is the interval [startInFrames, endInFrames). * <br> - * As of {@link android.os.Build.VERSION_CODES#MNC}, the position is left unchanged, + * As of {@link android.os.Build.VERSION_CODES#M}, the position is left unchanged, * unless it is greater than or equal to the loop end marker, in which case * it is forced to the loop start marker. * For earlier API levels, the effect on position is unspecified. @@ -2077,7 +2084,7 @@ public class AudioTrack * The track must be stopped or paused, and * the track's creation mode must be {@link #MODE_STATIC}. * <p> - * As of {@link android.os.Build.VERSION_CODES#MNC}, also resets the value returned by + * As of {@link android.os.Build.VERSION_CODES#M}, also resets the value returned by * {@link #getPlaybackHeadPosition()} to zero. * For earlier API levels, the reset behavior is unspecified. * <p> diff --git a/media/java/android/media/IRingtonePlayer.aidl b/media/java/android/media/IRingtonePlayer.aidl index aa5fde3d2fc0..809142125031 100644 --- a/media/java/android/media/IRingtonePlayer.aidl +++ b/media/java/android/media/IRingtonePlayer.aidl @@ -33,4 +33,7 @@ interface IRingtonePlayer { /** Used for Notification sound playback. */ void playAsync(in Uri uri, in UserHandle user, boolean looping, in AudioAttributes aa); void stopAsync(); + + /** Return the title of the media. */ + String getTitle(in Uri uri); } diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 5f60891cef51..6c224e5c35e6 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -21,12 +21,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.ImageFormat; import android.graphics.Rect; -import android.media.Image; -import android.media.MediaCodecInfo; +import android.graphics.SurfaceTexture; import android.media.MediaCodecInfo.CodecCapabilities; -import android.media.MediaCodecList; -import android.media.MediaCrypto; -import android.media.MediaFormat; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -37,6 +33,7 @@ import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.ReadOnlyBufferException; import java.util.Arrays; import java.util.HashMap; @@ -233,8 +230,9 @@ import java.util.Map; data and submit it as a single codec-config buffer. <p> Android uses the following codec-specific data buffers. These are also required to be set in - the track format for proper {@link MediaMuxer} track configuration. Each parameter set and - codec-specific-data must start with a start code of {@code "\x00\x00\x00\x01"}. + the track format for proper {@link MediaMuxer} track configuration. Each parameter set and the + codec-specific-data sections marked with (<sup>*</sup>) must start with a start code of + {@code "\x00\x00\x00\x01"}. <p> <style>td.NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style> <table> @@ -242,28 +240,48 @@ import java.util.Map; <th>Format</th> <th>CSD buffer #0</th> <th>CSD buffer #1</th> + <th>CSD buffer #2</th> </thead> <tbody class=mid> <tr> <td>AAC</td> - <td>Decoder-specific information from ESDS</td> + <td>Decoder-specific information from ESDS<sup>*</sup></td> <td class=NA>Not Used</td> + <td class=NA>Not Used</td> + </tr> + <tr> + <td>VORBIS</td> + <td>Identification header</td> + <td>Setup header</td> + <td class=NA>Not Used</td> + </tr> + <tr> + <td>OPUS</td> + <td>Identification header</td> + <td>Pre-skip in nanosecs<br> + (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)<br> + This overrides the pre-skip value in the identification header.</td> + <td>Seek Pre-roll in nanosecs<br> + (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)</td> </tr> <tr> <td>MPEG-4</td> - <td>Decoder-specific information from ESDS</td> + <td>Decoder-specific information from ESDS<sup>*</sup></td> + <td class=NA>Not Used</td> <td class=NA>Not Used</td> </tr> <tr> <td>H.264 AVC</td> - <td>SPS (Sequence Parameter Sets)</td> - <td>PPS (Picture Parameter Sets)</td> + <td>SPS (Sequence Parameter Sets<sup>*</sup>)</td> + <td>PPS (Picture Parameter Sets<sup>*</sup>)</td> + <td class=NA>Not Used</td> </tr> <tr> <td>H.265 HEVC</td> - <td>VPS (Video Parameter Sets) +<br> - SPS (Sequence Parameter Sets) +<br> - PPS (Picture Parameter Sets)</td> + <td>VPS (Video Parameter Sets<sup>*</sup>) +<br> + SPS (Sequence Parameter Sets<sup>*</sup>) +<br> + PPS (Picture Parameter Sets<sup>*</sup>)</td> + <td class=NA>Not Used</td> <td class=NA>Not Used</td> </tr> </tbody> @@ -302,10 +320,10 @@ import java.util.Map; releaseOutputBuffer} methods to return the buffer to the codec. <p> While you are not required to resubmit/release buffers immediately to the codec, holding onto - input and/or output buffers may stall the codec, and this behavior is device dependent. E.g. it - is possible that a codec may hold off on generating output buffers until all outstanding buffers - have been released/resubmitted. Therefore, try to hold onto to available buffers as little as - possible. + input and/or output buffers may stall the codec, and this behavior is device dependent. + <strong>Specifically, it is possible that a codec may hold off on generating output buffers until + <em>all</em> outstanding buffers have been released/resubmitted.</strong> Therefore, try to + hold onto to available buffers as little as possible. <p> Depending on the API version, you can process data in three ways: <table> @@ -351,7 +369,7 @@ import java.util.Map; <p> MediaCodec is typically used like this in asynchronous mode: <pre class=prettyprint> - MediaCodec codec = MediaCodec.createCodecByName(name); + MediaCodec codec = MediaCodec.createByCodecName(name); MediaFormat mOutputFormat; // member variable codec.setCallback(new MediaCodec.Callback() { {@literal @Override} @@ -408,7 +426,7 @@ import java.util.Map; <p> MediaCodec is typically used like this in synchronous mode: <pre> - MediaCodec codec = MediaCodec.createCodecByName(name); + MediaCodec codec = MediaCodec.createByCodecName(name); codec.configure(format, …); MediaFormat outputFormat = codec.getOutputFormat(); // option B codec.start(); @@ -447,7 +465,7 @@ import java.util.Map; between the size of the arrays and the number of input and output buffers used by the system, although the array size provides an upper bound. <pre> - MediaCodec codec = MediaCodec.createCodecByName(name); + MediaCodec codec = MediaCodec.createByCodecName(name); codec.configure(format, …); codec.start(); ByteBuffer[] inputBuffers = codec.getInputBuffers(); @@ -510,11 +528,11 @@ import java.util.Map; #releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)}.</li> </ul> <p> - Since {@link android.os.Build.VERSION_CODES#MNC}, the default timestamp is the {@linkplain + Since {@link android.os.Build.VERSION_CODES#M}, the default timestamp is the {@linkplain BufferInfo#presentationTimeUs presentation timestamp} of the buffer (converted to nanoseconds). It was not defined prior to that. <p> - Also since {@link android.os.Build.VERSION_CODES#MNC}, you can change the output Surface + Also since {@link android.os.Build.VERSION_CODES#M}, you can change the output Surface dynamically using {@link #setOutputSurface setOutputSurface}. <h4>Using an Input Surface</h4> @@ -648,10 +666,10 @@ import java.util.Map; class. For API version numbers, see {@link android.os.Build.VERSION_CODES}. <style> - .api > tr > th, td { text-align: center; padding: 4px 4px; } + .api > tr > th, .api > tr > td { text-align: center; padding: 4px 4px; } .api > tr > th { vertical-align: bottom; } .api > tr > td { vertical-align: middle; } - .sml > tr > th, td { text-align: center; padding: 2px 4px; } + .sml > tr > th, .sml > tr > td { text-align: center; padding: 2px 4px; } .fn { text-align: left; } .fn > code > a { font: 14px/19px Roboto Condensed, sans-serif; } .deg45 { @@ -1566,7 +1584,7 @@ final public class MediaCodec { private boolean mHasSurface = false; /** - * Instantiate a decoder supporting input data of the given mime type. + * Instantiate the preferred decoder supporting input data of the given mime type. * * The following is a partial list of defined mime types and their semantics: * <ul> @@ -1585,6 +1603,10 @@ final public class MediaCodec { * <li>"audio/g711-mlaw" - G.711 ulaw audio * </ul> * + * <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findDecoderForFormat} + * and {@link #createByCodecName} to ensure that the resulting codec can handle a + * given format. + * * @param type The mime type of the input data. * @throws IOException if the codec cannot be created. * @throws IllegalArgumentException if type is not a valid mime type. @@ -1597,7 +1619,12 @@ final public class MediaCodec { } /** - * Instantiate an encoder supporting output data of the given mime type. + * Instantiate the preferred encoder supporting output data of the given mime type. + * + * <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findEncoderForFormat} + * and {@link #createByCodecName} to ensure that the resulting codec can handle a + * given format. + * * @param type The desired mime type of the output data. * @throws IOException if the codec cannot be created. * @throws IllegalArgumentException if type is not a valid mime type. @@ -1666,6 +1693,8 @@ final public class MediaCodec { private native final void native_reset(); /** + * Free up resources used by the codec instance. + * * Make sure you call this when you're done to free up any opened * component instance instead of relying on the garbage collector * to do this for you at some point in the future. @@ -1886,17 +1915,25 @@ final public class MediaCodec { private native final void native_stop(); /** - * Flush both input and output ports of the component, all indices - * previously returned in calls to {@link #dequeueInputBuffer} and - * {@link #dequeueOutputBuffer} become invalid. + * Flush both input and output ports of the component. * <p> - * If codec is configured in asynchronous mode, call {@link #start} - * after {@code flush} has returned to resume codec operations. The - * codec will not request input buffers until this has happened. + * Upon return, all indices previously returned in calls to {@link #dequeueInputBuffer + * dequeueInputBuffer} and {@link #dequeueOutputBuffer dequeueOutputBuffer} — or obtained + * via {@link Callback#onInputBufferAvailable onInputBufferAvailable} or + * {@link Callback#onOutputBufferAvailable onOutputBufferAvailable} callbacks — become + * invalid, and all buffers are owned by the codec. * <p> - * If codec is configured in synchronous mode, codec will resume - * automatically if an input surface was created. Otherwise, it - * will resume when {@link #dequeueInputBuffer} is called. + * If the codec is configured in asynchronous mode, call {@link #start} + * after {@code flush} has returned to resume codec operations. The codec + * will not request input buffers until this has happened. + * <strong>Note, however, that there may still be outstanding {@code onOutputBufferAvailable} + * callbacks that were not handled prior to calling {@code flush}. + * The indices returned via these callbacks also become invalid upon calling {@code flush} and + * should be discarded.</strong> + * <p> + * If the codec is configured in synchronous mode, codec will resume + * automatically if it is configured with an input surface. Otherwise, it + * will resume when {@link #dequeueInputBuffer dequeueInputBuffer} is called. * * @throws IllegalStateException if not in the Executing state. * @throws MediaCodec.CodecException upon codec error. @@ -2087,6 +2124,15 @@ final public class MediaCodec { * To indicate that this is the final piece of input data (or rather that * no more input data follows unless the decoder is subsequently flushed) * specify the flag {@link #BUFFER_FLAG_END_OF_STREAM}. + * <p class=note> + * <strong>Note:</strong> Prior to {@link android.os.Build.VERSION_CODES#M}, + * {@code presentationTimeUs} was not propagated to the frame timestamp of (rendered) + * Surface output buffers, and the resulting frame timestamp was undefined. + * Use {@link #releaseOutputBuffer(int, long)} to ensure a specific frame timestamp is set. + * Similarly, since frame timestamps can be used by the destination surface for rendering + * synchronization, <strong>care must be taken to normalize presentationTimeUs so as to not be + * mistaken for a system time. (See {@linkplain #releaseOutputBuffer(int, long) + * SurfaceView specifics}).</strong> * * @param index The index of a client-owned input buffer previously returned * in a call to {@link #dequeueInputBuffer}. @@ -2094,7 +2140,10 @@ final public class MediaCodec { * @param size The number of bytes of valid input data. * @param presentationTimeUs The presentation timestamp in microseconds for this * buffer. This is normally the media time at which this - * buffer should be presented (rendered). + * buffer should be presented (rendered). When using an output + * surface, this will be propagated as the {@link + * SurfaceTexture#getTimestamp timestamp} for the frame (after + * conversion to nanoseconds). * @param flags A bitmask of flags * {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}. * While not prohibited, most codecs do not use the @@ -2207,8 +2256,10 @@ final public class MediaCodec { }; /** - * Similar to {@link #queueInputBuffer} but submits a buffer that is + * Similar to {@link #queueInputBuffer queueInputBuffer} but submits a buffer that is * potentially encrypted. + * <strong>Check out further notes at {@link #queueInputBuffer queueInputBuffer}.</strong> + * * @param index The index of a client-owned input buffer previously returned * in a call to {@link #dequeueInputBuffer}. * @param offset The byte offset into the input buffer at which the data starts. @@ -2315,7 +2366,7 @@ final public class MediaCodec { /** * Dequeue an output buffer, block at most "timeoutUs" microseconds. * Returns the index of an output buffer that has been successfully - * decoded or one of the INFO_* constants below. + * decoded or one of the INFO_* constants. * @param info Will be filled with buffer meta data. * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite". * @throws IllegalStateException if not in the Executing state, @@ -2343,9 +2394,11 @@ final public class MediaCodec { @NonNull BufferInfo info, long timeoutUs); /** - * If you are done with a buffer, use this call to return the buffer to - * the codec. If you previously specified a surface when configuring this - * video decoder you can optionally render the buffer. + * If you are done with a buffer, use this call to return the buffer to the codec + * or to render it on the output surface. If you configured the codec with an + * output surface, setting {@code render} to {@code true} will first send the buffer + * to that output surface. The surface will release the buffer back to the codec once + * it is no longer used/displayed. * * Once an output buffer is released to the codec, it MUST NOT * be used until it is later retrieved by {@link #getOutputBuffer} in response @@ -2679,6 +2732,8 @@ final public class MediaCodec { * <b>Note:</b> As of API 21, dequeued input buffers are * automatically {@link java.nio.Buffer#clear cleared}. * + * <em>Do not use this method if using an input surface.</em> + * * @throws IllegalStateException if not in the Executing state, * or codec is configured in asynchronous mode. * @throws MediaCodec.CodecException upon codec error. @@ -2708,6 +2763,8 @@ final public class MediaCodec { * buffers that are dequeued will be set to the valid data * range. * + * <em>Do not use this method if using an output surface.</em> + * * @throws IllegalStateException if not in the Executing state, * or codec is configured in asynchronous mode. * @throws MediaCodec.CodecException upon codec error. @@ -2993,6 +3050,10 @@ final public class MediaCodec { /** * Called when an output frame has rendered on the output surface. + * <p> + * <strong>Note:</strong> This callback is for informational purposes only: to get precise + * render timing samples, and can be significantly delayed and batched. Some frames may have + * been rendered even if there was no callback generated. * * @param codec the MediaCodec instance * @param presentationTimeUs the presentation time (media time) of the frame rendered. @@ -3009,10 +3070,14 @@ final public class MediaCodec { } /** - * Register a callback to be invoked when an output frame is rendered on the output surface. + * Registers a callback to be invoked when an output frame is rendered on the output surface. * <p> * This method can be called in any codec state, but will only have an effect in the * Executing state for codecs that render buffers to the output surface. + * <p> + * <strong>Note:</strong> This callback is for informational purposes only: to get precise + * render timing samples, and can be significantly delayed and batched. Some frames may have + * been rendered even if there was no callback generated. * * @param listener the callback that will be run * @param handler the callback will be run on the handler's thread. If {@code null}, diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 76d36a09b592..41019357a0e4 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -525,6 +525,14 @@ public final class MediaCodecInfo { /** * Query whether codec supports a given {@link MediaFormat}. + * + * <p class=note> + * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP}, + * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE + * frame rate}. Use + * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code> + * to clear any existing frame rate setting in the format. + * * @param format media format with optional feature directives. * @throws IllegalArgumentException if format is not a valid media format. * @return whether the codec capabilities support the given format @@ -1198,15 +1206,20 @@ public final class MediaCodecInfo { (double) mFrameRateRange.getUpper())); } + private int getBlockCount(int width, int height) { + return Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight); + } + @NonNull private Size findClosestSize(int width, int height) { - int targetPixels = width * height; + int targetBlockCount = getBlockCount(width, height); Size closestSize = null; - int mimPixelsDiff = Integer.MAX_VALUE; + int minDiff = Integer.MAX_VALUE; for (Size size : mMeasuredFrameRates.keySet()) { - int pixelsDiff = Math.abs(targetPixels - size.getWidth() * size.getHeight()); - if (pixelsDiff < mimPixelsDiff) { - mimPixelsDiff = pixelsDiff; + int diff = Math.abs(targetBlockCount - + getBlockCount(size.getWidth(), size.getHeight())); + if (diff < minDiff) { + minDiff = diff; closestSize = size; } } @@ -1216,7 +1229,7 @@ public final class MediaCodecInfo { private Range<Double> estimateFrameRatesFor(int width, int height) { Size size = findClosestSize(width, height); Range<Long> range = mMeasuredFrameRates.get(size); - Double ratio = (double)(width * height) / (size.getWidth() * size.getHeight()); + Double ratio = (double)(size.getWidth() * size.getHeight()) / (width * height); return Range.create(range.getLower() * ratio, range.getUpper() * ratio); } @@ -1225,8 +1238,22 @@ public final class MediaCodecInfo { * May return {@code null}, if the codec did not publish any measurement * data. * <p> - * This is a performance estimate, based on full-speed decoding - * and encoding measurements of common video sizes supported by the codec. + * This is a performance estimate provided by the device manufacturer + * based on full-speed decoding and encoding measurements in various configurations + * of common video sizes supported by the codec. As such it should only be used to + * compare individual codecs on the device. The value is not suitable for comparing + * different devices or even different android releases for the same device. + * <p> + * The returned range corresponds to the fastest frame rates achieved in the tested + * configurations. It is interpolated from the nearest frame size(s) tested. Codec + * performance is severely impacted by other activity on the device, and can vary + * significantly. + * <p class=note> + * Use this method in cases where only codec performance matters, e.g. to evaluate if + * a codec has any chance of meeting a performance target. Codecs are listed + * in {@link MediaCodecList} in the preferred order as defined by the device + * manufacturer. As such, applications should use the first suitable codec in the + * list to achieve the best balance between power use and performance. * * @param width the width of the video * @param height the height of the video diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java index f44e048397d4..cd7b3d35a590 100644 --- a/media/java/android/media/MediaCodecList.java +++ b/media/java/android/media/MediaCodecList.java @@ -190,6 +190,13 @@ final public class MediaCodecList { * Find a decoder supporting a given {@link MediaFormat} in the list * of media-codecs. * + * <p class=note> + * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP}, + * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE + * frame rate}. Use + * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code> + * to clear any existing frame rate setting in the format. + * * @param format A decoder media format with optional feature directives. * @throws IllegalArgumentException if format is not a valid media format. * @throws NullPointerException if format is null. @@ -204,6 +211,13 @@ final public class MediaCodecList { * Find an encoder supporting a given {@link MediaFormat} in the list * of media-codecs. * + * <p class=note> + * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP}, + * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE + * frame rate}. Use + * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code> + * to clear any existing frame rate setting in the format. + * * @param format An encoder media format with optional feature directives. * @throws IllegalArgumentException if format is not a valid media format. * @throws NullPointerException if format is null. diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 6dd855d4dc41..13b2878ab420 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -1017,16 +1017,14 @@ public class MediaPlayer implements SubtitleController.Listener setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getDeclaredLength()); } return; - } catch (SecurityException ex) { - } catch (IOException ex) { + } catch (SecurityException | IOException ex) { + Log.w(TAG, "Couldn't open file on client side; trying server side: " + ex); } finally { if (fd != null) { fd.close(); } } - Log.d(TAG, "Couldn't open file on client side, trying server side"); - setDataSource(uri.toString(), headers); } @@ -2294,7 +2292,7 @@ public class MediaPlayer implements SubtitleController.Listener private void scanInternalSubtitleTracks() { if (mSubtitleController == null) { - Log.w(TAG, "setSubtitleAnchor in MediaPlayer"); + Log.d(TAG, "setSubtitleAnchor in MediaPlayer"); setSubtitleAnchor(); } diff --git a/media/java/android/media/MediaSync.java b/media/java/android/media/MediaSync.java index b07931d87f1e..b37e02c1e219 100644 --- a/media/java/android/media/MediaSync.java +++ b/media/java/android/media/MediaSync.java @@ -24,6 +24,7 @@ import android.media.PlaybackParams; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.util.Log; import android.view.Surface; import java.lang.annotation.Retention; @@ -82,7 +83,7 @@ import java.util.List; * codec.releaseOutputBuffer(bufferId, 1000 * info.presentationTime); * } else { * ByteBuffer audioByteBuffer = codec.getOutputBuffer(bufferId); - * sync.queueByteBuffer(audioByteBuffer, bufferId, info.size, info.presentationTime); + * sync.queueAudio(audioByteBuffer, bufferId, info.presentationTime); * } * // ... * } @@ -427,6 +428,11 @@ public final class MediaSync { /** * Flushes all buffers from the sync object. * <p> + * All pending unprocessed audio and video buffers are discarded. If an audio track was + * configured, it is flushed and stopped. If a video output surface was configured, the + * last frame queued to it is left on the frame. Queue a blank video frame to clear the + * surface, + * <p> * No callbacks are received for the flushed buffers. * * @throws IllegalStateException if the internal player engine has not been @@ -437,10 +443,19 @@ public final class MediaSync { mAudioBuffers.clear(); mCallbackHandler.removeCallbacksAndMessages(null); } - // TODO implement this for surface buffers. + if (mAudioTrack != null) { + mAudioTrack.pause(); + mAudioTrack.flush(); + // Call stop() to signal to the AudioSink to completely fill the + // internal buffer before resuming playback. + mAudioTrack.stop(); + } + native_flush(); } - /** + private native final void native_flush(); + + /** * Get current playback position. * <p> * The MediaTimestamp represents how the media time correlates to the system time in @@ -478,6 +493,7 @@ public final class MediaSync { /** * Queues the audio data asynchronously for playback (AudioTrack must be in streaming mode). + * If the audio track was flushed as a result of {@link #flush}, it will be restarted. * @param audioData the buffer that holds the data to play. This buffer will be returned * to the client via registered callback. * @param bufferId an integer used to identify audioData. It will be returned to @@ -519,6 +535,14 @@ public final class MediaSync { AudioBuffer audioBuffer = mAudioBuffers.get(0); int size = audioBuffer.mByteBuffer.remaining(); + // restart audio track after flush + if (size > 0 && mAudioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) { + try { + mAudioTrack.play(); + } catch (IllegalStateException e) { + Log.w(TAG, "could not start audio track"); + } + } int sizeWritten = mAudioTrack.write( audioBuffer.mByteBuffer, size, @@ -558,17 +582,19 @@ public final class MediaSync { final MediaSync sync = this; mCallbackHandler.post(new Runnable() { public void run() { + Callback callback; synchronized(mCallbackLock) { + callback = mCallback; if (mCallbackHandler == null || mCallbackHandler.getLooper().getThread() != Thread.currentThread()) { // callback handler has been changed. return; } - if (mCallback != null) { - mCallback.onAudioBufferConsumed(sync, audioBuffer.mByteBuffer, - audioBuffer.mBufferIndex); - } + } + if (callback != null) { + callback.onAudioBufferConsumed(sync, audioBuffer.mByteBuffer, + audioBuffer.mBufferIndex); } } }); diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java index faeebe6ee425..c2bcd930dd29 100644 --- a/media/java/android/media/Ringtone.java +++ b/media/java/android/media/Ringtone.java @@ -27,6 +27,7 @@ import android.os.Binder; import android.os.RemoteException; import android.provider.MediaStore; import android.provider.Settings; +import android.provider.MediaStore.MediaColumns; import android.util.Log; import java.io.IOException; @@ -50,6 +51,9 @@ public class Ringtone { MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.TITLE }; + /** Selection that limits query results to just audio files */ + private static final String MEDIA_SELECTION = MediaColumns.MIME_TYPE + " LIKE 'audio/%' OR " + + MediaColumns.MIME_TYPE + " IN ('application/ogg', 'application/x-flac')"; // keep references on active Ringtones until stopped or completion listener called. private static final ArrayList<Ringtone> sActiveRingtones = new ArrayList<Ringtone>(); @@ -193,11 +197,14 @@ public class Ringtone { */ public String getTitle(Context context) { if (mTitle != null) return mTitle; - return mTitle = getTitle(context, mUri, true); + return mTitle = getTitle(context, mUri, true /*followSettingsUri*/, mAllowRemote); } - private static String getTitle(Context context, Uri uri, boolean followSettingsUri) { - Cursor cursor = null; + /** + * @hide + */ + public static String getTitle( + Context context, Uri uri, boolean followSettingsUri, boolean allowRemote) { ContentResolver res = context.getContentResolver(); String title = null; @@ -209,31 +216,45 @@ public class Ringtone { if (followSettingsUri) { Uri actualUri = RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.getDefaultType(uri)); - String actualTitle = getTitle(context, actualUri, false); + String actualTitle = getTitle( + context, actualUri, false /*followSettingsUri*/, allowRemote); title = context .getString(com.android.internal.R.string.ringtone_default_with_actual, actualTitle); } } else { + Cursor cursor = null; try { if (MediaStore.AUTHORITY.equals(authority)) { - cursor = res.query(uri, MEDIA_COLUMNS, null, null, null); + final String mediaSelection = allowRemote ? null : MEDIA_SELECTION; + cursor = res.query(uri, MEDIA_COLUMNS, mediaSelection, null, null); + if (cursor != null && cursor.getCount() == 1) { + cursor.moveToFirst(); + return cursor.getString(2); + } + // missing cursor is handled below } } catch (SecurityException e) { - // missing cursor is handled below - } - - try { - if (cursor != null && cursor.getCount() == 1) { - cursor.moveToFirst(); - return cursor.getString(2); - } else { - title = uri.getLastPathSegment(); + IRingtonePlayer mRemotePlayer = null; + if (allowRemote) { + AudioManager audioManager = + (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + mRemotePlayer = audioManager.getRingtonePlayer(); + } + if (mRemotePlayer != null) { + try { + title = mRemotePlayer.getTitle(uri); + } catch (RemoteException re) { + } } } finally { if (cursor != null) { cursor.close(); } + cursor = null; + } + if (title == null) { + title = uri.getLastPathSegment(); } } } diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index a1b8a3b6b1a8..025029e75ec1 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -23,9 +23,11 @@ import android.annotation.SdkConstant.SdkConstantType; import android.app.Activity; import android.content.ContentUris; import android.content.Context; +import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Environment; +import android.os.Process; import android.provider.MediaStore; import android.provider.Settings; import android.provider.Settings.System; @@ -359,7 +361,10 @@ public class RingtoneManager { * If {@link RingtoneManager#RingtoneManager(Activity)} was not used, the * caller should manage the returned cursor through its activity's life * cycle to prevent leaking the cursor. - * + * <p> + * Note that the list of ringtones available will differ depending on whether the caller + * has the {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission. + * * @return A {@link Cursor} of all the ringtones available. * @see #ID_COLUMN_INDEX * @see #TITLE_COLUMN_INDEX @@ -455,8 +460,10 @@ public class RingtoneManager { /** * Returns a valid ringtone URI. No guarantees on which it returns. If it - * cannot find one, returns null. - * + * cannot find one, returns null. If it can only find one on external storage and the caller + * doesn't have the {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission, + * returns null. + * * @param context The context to use for querying. * @return A ringtone URI, or null if one cannot be found. */ @@ -495,6 +502,12 @@ public class RingtoneManager { } private Cursor getMediaRingtones() { + if (PackageManager.PERMISSION_GRANTED != mContext.checkPermission( + android.Manifest.permission.READ_EXTERNAL_STORAGE, + Process.myPid(), Process.myUid())) { + Log.w(TAG, "No READ_EXTERNAL_STORAGE permission, ignoring ringtones on ext storage"); + return null; + } // Get the external media cursor. First check to see if it is mounted. final String status = Environment.getExternalStorageState(); diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java index 93fb6d2960da..e1990cd6fbbb 100644 --- a/media/java/android/media/midi/MidiDevice.java +++ b/media/java/android/media/midi/MidiDevice.java @@ -113,8 +113,13 @@ public final class MidiDevice implements Closeable { /** * Called to open a {@link MidiInputPort} for the specified port number. * + * An input port can only be used by one sender at a time. + * Opening an input port will fail if another application has already opened it for use. + * A {@link MidiDeviceStatus} can be used to determine if an input port is already open. + * * @param portNumber the number of the input port to open - * @return the {@link MidiInputPort} + * @return the {@link MidiInputPort} if the open is successful, + * or null in case of failure. */ public MidiInputPort openInputPort(int portNumber) { try { @@ -133,8 +138,11 @@ public final class MidiDevice implements Closeable { /** * Called to open a {@link MidiOutputPort} for the specified port number. * + * An output port may be opened by multiple applications. + * * @param portNumber the number of the output port to open - * @return the {@link MidiOutputPort} + * @return the {@link MidiOutputPort} if the open is successful, + * or null in case of failure. */ public MidiOutputPort openOutputPort(int portNumber) { try { diff --git a/media/java/android/media/midi/package.html b/media/java/android/media/midi/package.html index 673c4ba9bfeb..7baa5bc42bd2 100644 --- a/media/java/android/media/midi/package.html +++ b/media/java/android/media/midi/package.html @@ -31,7 +31,7 @@ capabilities, etc.</li> <li> Timestamps to avoid jitter.</li> <li> Support creation of <em>virtual MIDI devices</em> that can be connected to other devices. An example might be a synthesizer app that can be controlled by a composing app.</li> - <li> Support direction connection or “patching” of devices for lower latency.</li> + <li> Support direct connection or “patching” of devices for lower latency.</li> </ul> <h2 id=transports_supported>Transports Supported</h2> @@ -75,6 +75,18 @@ Then the app will not appear in the Play Store for old devices that do not suppo <uses-feature android:name="android.software.midi" android:required="true"/> </pre> +<h2 id=check_feature>Check for Feature Support</h2> + +<p>An app can also check at run-time whether the MIDI feature is supported on a platform. +This is particularly useful during development when you install apps directly on a device. +</p> + +<pre class=prettyprint> +if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI)) { + // do MIDI stuff +} +</pre> + <h2 id=the_midimanager>The MidiManager</h2> @@ -338,5 +350,54 @@ public class MidiSynthDeviceService extends MidiDeviceService { } } </pre> + +<h1 id=using_midi_btle>Using MIDI Over Bluetooth LE</h1> + +<p>MIDI devices can be connected to Android using Bluetooth LE.</p> + +<p>Before using the device, the app must scan for available BTLE devices and then allow +the user to connect. An example program +will be provided so look for it on the Android developer website.</p> + +<h2 id=btle_location_permissions>Request Location Permission for BTLE</h2> + +<p>Applications that scan for Bluetooth devices must request permission in the +manifest file. This LOCATION permission is required because it may be possible to +guess the location of an Android device by seeing which BTLE devices are nearby.</p> + +<pre class=prettyprint> +<uses-permission android:name="android.permission.BLUETOOTH"/> +<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> +<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> +</pre> + +<p>Apps must also request location permission from the user at run-time. +See the documentation for <code>Activity.requestPermissions()</code> for details and an example. +</p> + +<h2 id=btle_scan_devices>Scan for MIDI Devices</h2> + +<p>The app will only want to see MIDI devices and not mice or other non-MIDI devices. +So construct a ScanFilter using the UUID for standard MIDI over BTLE.</p> + +<pre class=prettyprint> +MIDI over BTLE UUID = "03B80E5A-EDE8-4B33-A751-6CE34EC4C700" +</pre> + +<h2 id=btle_open_device>Open a MIDI Bluetooth Device</h2> + +<p>See the documentation for <code>android.bluetooth.le.BluetoothLeScanner.startScan()</code> +method for details. When the user selects a MIDI/BTLE device then you can open it +using the MidiManager.</p> + +<pre class=prettyprint> +m.openBluetoothDevice(bluetoothDevice, callback, handler); +</pre> + +<p>Once the MIDI/BTLE device has been opened by one app then it will also become available to other +apps using the +<a href="#get_list_of_already_plugged_in_entities">MIDI device discovery calls described above</a>. +</p> + </body> </html> diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java index ce72c2fa4a25..a3d748efafd2 100644 --- a/media/java/android/media/tv/TvInputInfo.java +++ b/media/java/android/media/tv/TvInputInfo.java @@ -49,6 +49,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.HashSet; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -611,7 +612,7 @@ public final class TvInputInfo implements Parcelable { String format = DELIMITER_INFO_IN_ID + PREFIX_HDMI_DEVICE + "%0" + LENGTH_HDMI_PHYSICAL_ADDRESS + "X" + "%0" + LENGTH_HDMI_DEVICE_ID + "X"; - return name.flattenToShortString() + String.format(format, + return name.flattenToShortString() + String.format(Locale.ENGLISH, format, deviceInfo.getPhysicalAddress(), deviceInfo.getId()); } diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 35037bbe18f4..053d43b6b69b 100644 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -20,6 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.SystemApi; +import android.app.ActivityManager; import android.app.Service; import android.content.Context; import android.content.Intent; @@ -385,13 +386,14 @@ public abstract class TvInputService extends Service { trackIdSet.clear(); // TODO: Validate the track list. + final List<TvTrackInfo> tracksCopy = new ArrayList<>(tracks); executeOrPostRunnable(new Runnable() { @Override public void run() { try { if (DEBUG) Log.d(TAG, "notifyTracksChanged"); if (mSessionCallback != null) { - mSessionCallback.onTracksChanged(tracks); + mSessionCallback.onTracksChanged(tracksCopy); } } catch (RemoteException e) { Log.w(TAG, "error in notifyTracksChanged", e); @@ -1199,12 +1201,15 @@ public abstract class TvInputService extends Service { // We make the overlay view non-focusable and non-touchable so that // the application that owns the window token can decide whether to consume or // dispatch the input events. - int flag = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; + int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE + | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; + if (ActivityManager.isHighEndGfx()) { + flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; + } mWindowParams = new WindowManager.LayoutParams( frame.right - frame.left, frame.bottom - frame.top, - frame.left, frame.top, type, flag, PixelFormat.TRANSPARENT); + frame.left, frame.top, type, flags, PixelFormat.TRANSPARENT); mWindowParams.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; mWindowParams.gravity = Gravity.START | Gravity.TOP; diff --git a/media/jni/android_media_MediaSync.cpp b/media/jni/android_media_MediaSync.cpp index 8e0ed641eb0d..893c41472e07 100644 --- a/media/jni/android_media_MediaSync.cpp +++ b/media/jni/android_media_MediaSync.cpp @@ -102,6 +102,10 @@ float JMediaSync::getVideoFrameRate() { return mSync->getVideoFrameRate(); } +void JMediaSync::flush() { + mSync->flush(); +} + status_t JMediaSync::updateQueuedAudioData( int sizeInBytes, int64_t presentationTimeUs) { return mSync->updateQueuedAudioData(sizeInBytes, presentationTimeUs); @@ -464,6 +468,16 @@ static jobject android_media_MediaSync_getSyncParams(JNIEnv *env, jobject thiz) return scs.asJobject(env, gSyncParamsFields); } +static void android_media_MediaSync_native_flush(JNIEnv *env, jobject thiz) { + sp<JMediaSync> sync = getMediaSync(env, thiz); + if (sync == NULL) { + throwExceptionAsNecessary(env, INVALID_OPERATION); + return; + } + + sync->flush(); +} + static void android_media_MediaSync_native_init(JNIEnv *env) { ScopedLocalRef<jclass> clazz(env, env->FindClass("android/media/MediaSync")); CHECK(clazz.get() != NULL); @@ -524,6 +538,8 @@ static JNINativeMethod gMethods[] = { "()J", (void *)android_media_MediaSync_native_getPlayTimeForPendingAudioFrames }, + { "native_flush", "()V", (void *)android_media_MediaSync_native_flush }, + { "native_init", "()V", (void *)android_media_MediaSync_native_init }, { "native_setup", "()V", (void *)android_media_MediaSync_native_setup }, diff --git a/media/jni/android_media_MediaSync.h b/media/jni/android_media_MediaSync.h index 22c77c766247..6f808858a0c2 100644 --- a/media/jni/android_media_MediaSync.h +++ b/media/jni/android_media_MediaSync.h @@ -49,6 +49,8 @@ struct JMediaSync : public RefBase { status_t setVideoFrameRateHint(float rate); float getVideoFrameRate(); + void flush(); + sp<const MediaClock> getMediaClock(); protected: diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java index a489f94ea698..0fe5509b95ce 100644 --- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java @@ -56,7 +56,7 @@ import java.util.Random; public class CaptivePortalLoginActivity extends Activity { private static final String TAG = "CaptivePortalLogin"; - private static final String DEFAULT_SERVER = "connectivitycheck.android.com"; + private static final String DEFAULT_SERVER = "connectivitycheck.gstatic.com"; private static final int SOCKET_TIMEOUT_MS = 10000; private enum Result { DISMISSED, UNWANTED, WANTED_AS_IS }; diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index 4f0c6a414c39..393771a9b447 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -162,7 +162,11 @@ public class ExternalStorageProvider extends DocumentsProvider { if (volume.getType() == VolumeInfo.TYPE_PUBLIC) { root.flags |= Root.FLAG_HAS_SETTINGS; } - root.visiblePath = volume.getPathForUser(userId); + if (volume.isVisibleForRead(userId)) { + root.visiblePath = volume.getPathForUser(userId); + } else { + root.visiblePath = null; + } root.path = volume.getInternalPathForUser(userId); root.docId = getDocIdForFile(root.path); diff --git a/packages/Keyguard/res/layout/keyguard_password_view.xml b/packages/Keyguard/res/layout/keyguard_password_view.xml index 7dcaf6d004e7..7d4501749c44 100644 --- a/packages/Keyguard/res/layout/keyguard_password_view.xml +++ b/packages/Keyguard/res/layout/keyguard_password_view.xml @@ -57,6 +57,7 @@ android:textSize="16sp" android:textAppearance="?android:attr/textAppearanceMedium" android:imeOptions="flagForceAscii|actionDone" + android:maxLength="500" /> <ImageView android:id="@+id/switch_ime_button" diff --git a/packages/Keyguard/res/layout/keyguard_pattern_view.xml b/packages/Keyguard/res/layout/keyguard_pattern_view.xml index 09c01de8d477..ccb9af9ff731 100644 --- a/packages/Keyguard/res/layout/keyguard_pattern_view.xml +++ b/packages/Keyguard/res/layout/keyguard_pattern_view.xml @@ -63,9 +63,6 @@ android:layout_marginStart="8dip" android:layout_gravity="center_horizontal" android:gravity="center" - android:contentDescription="@string/keyguard_accessibility_pattern_area" - android:focusable="true" - android:focusableInTouchMode="true" android:clipChildren="false" android:clipToPadding="false" /> diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml index 748129c3c2fd..cba122f3c8bd 100644 --- a/packages/Keyguard/res/values/strings.xml +++ b/packages/Keyguard/res/values/strings.xml @@ -101,7 +101,7 @@ <!-- Accessibility description of the password lock. [CHAR_LIMIT=none] --> <string name="keyguard_accessibility_password_unlock">Password unlock.</string> <!-- Accessibility description of the unlock pattern area. [CHAR_LIMIT=none] --> - <string name="keyguard_accessibility_pattern_area">Pattern area.</string> + <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">Pattern area.</string> <!-- Accessibility description of the unlock slide area. [CHAR_LIMIT=none] --> <string name="keyguard_accessibility_slide_area">Slide area.</string> <!-- Accessibility description of the PIN password view. [CHAR_LIMIT=none] --> diff --git a/packages/Keyguard/src/com/android/keyguard/CarrierText.java b/packages/Keyguard/src/com/android/keyguard/CarrierText.java index e89caf776955..159ac4cc6cbd 100644 --- a/packages/Keyguard/src/com/android/keyguard/CarrierText.java +++ b/packages/Keyguard/src/com/android/keyguard/CarrierText.java @@ -23,7 +23,6 @@ import java.util.Objects; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.res.Resources; import android.content.res.TypedArray; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; @@ -59,11 +58,11 @@ public class CarrierText extends TextView { updateCarrierText(); } - public void onScreenTurnedOff(int why) { + public void onFinishedGoingToSleep(int why) { setSelected(false); }; - public void onScreenTurnedOn() { + public void onStartedWakingUp() { setSelected(true); }; }; @@ -193,8 +192,8 @@ public class CarrierText extends TextView { super.onFinishInflate(); mSeparator = getResources().getString( com.android.internal.R.string.kg_text_message_separator); - final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn(); - setSelected(screenOn); // Allow marquee to work. + boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive(); + setSelected(shouldMarquee); // Allow marquee to work. } @Override diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java index 0c6837fcc60c..8f792de32db9 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -53,15 +53,18 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout super(context, attrs); } + @Override public void setKeyguardCallback(KeyguardSecurityCallback callback) { mCallback = callback; } + @Override public void setLockPatternUtils(LockPatternUtils utils) { mLockPatternUtils = utils; mEnableHaptics = mLockPatternUtils.isTactileFeedbackEnabled(); } + @Override public void reset() { // start fresh resetPasswordText(false /* animate */); @@ -95,6 +98,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout } } + @Override public void onEmergencyButtonClickedWhenInCall() { mCallback.reset(); } @@ -115,11 +119,11 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout mPendingLockCheck.cancel(false); } - if (entry.length() < MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT) { + if (entry.length() <= MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT) { // to avoid accidental lockout, only count attempts that are long enough to be a // real password. This may require some tweaking. setPasswordEntryInputEnabled(true); - onPasswordChecked(entry, false, 0); + onPasswordChecked(false /* matched */, 0, false /* not valid - too short */); return; } @@ -132,24 +136,27 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout public void onChecked(boolean matched, int timeoutMs) { setPasswordEntryInputEnabled(true); mPendingLockCheck = null; - onPasswordChecked(entry, matched, timeoutMs); + onPasswordChecked(matched, timeoutMs, true /* isValidPassword */); } }); } - private void onPasswordChecked(String entry, boolean matched, int timeoutMs) { + private void onPasswordChecked(boolean matched, int timeoutMs, boolean isValidPassword) { if (matched) { mCallback.reportUnlockAttempt(true, 0); mCallback.dismiss(true); } else { - mCallback.reportUnlockAttempt(false, timeoutMs); - int attempts = KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(); - if (timeoutMs > 0) { - long deadline = mLockPatternUtils.setLockoutAttemptDeadline( - KeyguardUpdateMonitor.getCurrentUser(), timeoutMs); - handleAttemptLockout(deadline); + if (isValidPassword) { + mCallback.reportUnlockAttempt(false, timeoutMs); + if (timeoutMs > 0) { + long deadline = mLockPatternUtils.setLockoutAttemptDeadline( + KeyguardUpdateMonitor.getCurrentUser(), timeoutMs); + handleAttemptLockout(deadline); + } + } + if (timeoutMs == 0) { + mSecurityMessageDisplay.setMessage(getWrongPasswordStringId(), true); } - mSecurityMessageDisplay.setMessage(getWrongPasswordStringId(), true); } resetPasswordText(true /* animate */); } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java b/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java index e5f3dc9d52bb..39271224d943 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardConstants.java @@ -27,4 +27,5 @@ public class KeyguardConstants { */ public static final boolean DEBUG = false; public static final boolean DEBUG_SIM_STATES = false; + public static final boolean DEBUG_FP_WAKELOCK = true; } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java index 301b171c2fe5..2951af915ff8 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java @@ -58,10 +58,10 @@ class KeyguardMessageArea extends TextView implements SecurityMessageDisplay { }; private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { - public void onScreenTurnedOff(int why) { + public void onFinishedGoingToSleep(int why) { setSelected(false); }; - public void onScreenTurnedOn() { + public void onStartedWakingUp() { setSelected(true); }; }; @@ -126,8 +126,8 @@ class KeyguardMessageArea extends TextView implements SecurityMessageDisplay { @Override protected void onFinishInflate() { - final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn(); - setSelected(screenOn); // This is required to ensure marquee works + boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive(); + setSelected(shouldMarquee); // This is required to ensure marquee works } private void securityMessageChanged(CharSequence message) { diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java index d265e0dc8b81..4abb795b267b 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java @@ -16,8 +16,12 @@ package com.android.keyguard; +import android.animation.Animator; +import android.animation.ObjectAnimator; import android.content.Context; import android.util.AttributeSet; +import android.view.RenderNode; +import android.view.RenderNodeAnimator; import android.view.View; import android.view.ViewGroup; import android.view.animation.AnimationUtils; @@ -114,10 +118,8 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { enableClipping(false); setAlpha(1f); setTranslationY(mAppearAnimationUtils.getStartTranslation()); - animate() - .setDuration(500) - .setInterpolator(mAppearAnimationUtils.getInterpolator()) - .translationY(0); + AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */, + 0, mAppearAnimationUtils.getInterpolator()); mAppearAnimationUtils.startAnimation2d(mViews, new Runnable() { @Override @@ -131,10 +133,8 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { public boolean startDisappearAnimation(final Runnable finishRunnable) { enableClipping(false); setTranslationY(0); - animate() - .setDuration(280) - .setInterpolator(mDisappearAnimationUtils.getInterpolator()) - .translationY(mDisappearYTranslation); + AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 280 /* duration */, + mDisappearYTranslation, mDisappearAnimationUtils.getInterpolator()); mDisappearAnimationUtils.startAnimation2d(mViews, new Runnable() { @Override diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java index 356842974cdc..4bd1a2ed29fc 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java @@ -17,6 +17,7 @@ package com.android.keyguard; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Rect; @@ -27,6 +28,7 @@ import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; +import android.view.RenderNodeAnimator; import android.view.View; import android.view.ViewGroup; import android.view.animation.AnimationUtils; @@ -80,6 +82,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit * Useful for clearing out the wrong pattern after a delay */ private Runnable mCancelPatternRunnable = new Runnable() { + @Override public void run() { mLockPatternView.clearPattern(); } @@ -115,10 +118,12 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit R.dimen.disappear_y_translation); } + @Override public void setKeyguardCallback(KeyguardSecurityCallback callback) { mCallback = callback; } + @Override public void setLockPatternUtils(LockPatternUtils utils) { mLockPatternUtils = utils; } @@ -151,6 +156,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit } } + @Override public void onEmergencyButtonClickedWhenInCall() { mCallback.reset(); } @@ -172,6 +178,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit return result; } + @Override public void reset() { // reset lock pattern mLockPatternView.enableInput(); @@ -205,18 +212,22 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit private class UnlockPatternListener implements LockPatternView.OnPatternListener { + @Override public void onPatternStart() { mLockPatternView.removeCallbacks(mCancelPatternRunnable); mSecurityMessageDisplay.setMessage("", false); } + @Override public void onPatternCleared() { } + @Override public void onPatternCellAdded(List<LockPatternView.Cell> pattern) { mCallback.userActivity(); } + @Override public void onPatternDetected(final List<LockPatternView.Cell> pattern) { mLockPatternView.disableInput(); if (mPendingLockCheck != null) { @@ -225,7 +236,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) { mLockPatternView.enableInput(); - onPatternChecked(pattern, false, 0); + onPatternChecked(false, 0, false /* not valid - too short */); return; } @@ -238,29 +249,30 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit public void onChecked(boolean matched, int timeoutMs) { mLockPatternView.enableInput(); mPendingLockCheck = null; - onPatternChecked(pattern, matched, timeoutMs); + onPatternChecked(matched, timeoutMs, true); } }); + if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) { + mCallback.userActivity(); + } } - private void onPatternChecked(List<LockPatternView.Cell> pattern, boolean matched, - int timeoutMs) { + private void onPatternChecked(boolean matched, int timeoutMs, boolean isValidPattern) { if (matched) { mCallback.reportUnlockAttempt(true, 0); mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct); mCallback.dismiss(true); } else { - if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) { - mCallback.userActivity(); - } mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong); - mCallback.reportUnlockAttempt(false, timeoutMs); - int attempts = mKeyguardUpdateMonitor.getFailedUnlockAttempts(); - if (timeoutMs > 0) { - long deadline = mLockPatternUtils.setLockoutAttemptDeadline( - KeyguardUpdateMonitor.getCurrentUser(), timeoutMs); - handleAttemptLockout(deadline); - } else { + if (isValidPattern) { + mCallback.reportUnlockAttempt(false, timeoutMs); + if (timeoutMs > 0) { + long deadline = mLockPatternUtils.setLockoutAttemptDeadline( + KeyguardUpdateMonitor.getCurrentUser(), timeoutMs); + handleAttemptLockout(deadline); + } + } + if (timeoutMs == 0) { mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern, true); mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS); } @@ -334,10 +346,8 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit enableClipping(false); setAlpha(1f); setTranslationY(mAppearAnimationUtils.getStartTranslation()); - animate() - .setDuration(500) - .setInterpolator(mAppearAnimationUtils.getInterpolator()) - .translationY(0); + AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */, + 0, mAppearAnimationUtils.getInterpolator()); mAppearAnimationUtils.startAnimation2d( mLockPatternView.getCellStates(), new Runnable() { @@ -362,10 +372,9 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit mLockPatternView.clearPattern(); enableClipping(false); setTranslationY(0); - animate() - .setDuration(300) - .setInterpolator(mDisappearAnimationUtils.getInterpolator()) - .translationY(-mDisappearAnimationUtils.getStartTranslation()); + AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 300 /* duration */, + -mDisappearAnimationUtils.getStartTranslation(), + mDisappearAnimationUtils.getInterpolator()); mDisappearAnimationUtils.startAnimation2d(mLockPatternView.getCellStates(), new Runnable() { @Override @@ -398,43 +407,16 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit long duration, float translationY, final boolean appearing, Interpolator interpolator, final Runnable finishListener) { - if (appearing) { - animatedCell.scale = 0.0f; - animatedCell.alpha = 1.0f; - } - animatedCell.translateY = appearing ? translationY : 0; - ValueAnimator animator = ValueAnimator.ofFloat(animatedCell.translateY, - appearing ? 0 : translationY); - animator.setInterpolator(interpolator); - animator.setDuration(duration); - animator.setStartDelay(delay); - animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float animatedFraction = animation.getAnimatedFraction(); - if (appearing) { - animatedCell.scale = animatedFraction; - } else { - animatedCell.alpha = 1 - animatedFraction; - } - animatedCell.translateY = (float) animation.getAnimatedValue(); - mLockPatternView.invalidate(); - } - }); + mLockPatternView.startCellStateAnimation(animatedCell, + 1f, appearing ? 1f : 0f, /* alpha */ + appearing ? translationY : 0f, appearing ? 0f : translationY, /* translation */ + appearing ? 0f : 1f, 1f /* scale */, + delay, duration, interpolator, finishListener); if (finishListener != null) { - animator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - finishListener.run(); - } - }); - // Also animate the Emergency call mAppearAnimationUtils.createAnimation(mEcaView, delay, duration, translationY, appearing, interpolator, null); } - animator.start(); - mLockPatternView.invalidate(); } @Override diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java index 23bd238f559e..85da29837f54 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -308,7 +308,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe boolean showNextSecurityScreenOrFinish(boolean authenticated) { if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")"); boolean finish = false; - if (mUpdateMonitor.getUserHasTrust(KeyguardUpdateMonitor.getCurrentUser())) { + if (mUpdateMonitor.getUserCanSkipBouncer( + KeyguardUpdateMonitor.getCurrentUser())) { finish = true; } else if (SecurityMode.None == mCurrentSecuritySelection) { SecurityMode securityMode = mSecurityModel.getSecurityMode(); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java index 4e9621af0876..f95b0aebfd70 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java @@ -67,12 +67,12 @@ public class KeyguardStatusView extends GridLayout { } @Override - public void onScreenTurnedOn() { + public void onStartedWakingUp() { setEnableMarquee(true); } @Override - public void onScreenTurnedOff(int why) { + public void onFinishedGoingToSleep(int why) { setEnableMarquee(false); } @@ -113,8 +113,8 @@ public class KeyguardStatusView extends GridLayout { mClockView.setShowCurrentUserTime(true); mOwnerInfo = (TextView) findViewById(R.id.owner_info); - final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn(); - setEnableMarquee(screenOn); + boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive(); + setEnableMarquee(shouldMarquee); refresh(); updateOwnerInfo(); diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java index 6574e4e2ffb4..c7adc986565f 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -44,7 +44,9 @@ import android.os.CancellationSignal; import android.os.Handler; import android.os.IRemoteCallback; import android.os.Message; +import android.os.PowerManager; import android.os.RemoteException; +import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; @@ -90,12 +92,32 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private static final String TAG = "KeyguardUpdateMonitor"; private static final boolean DEBUG = KeyguardConstants.DEBUG; private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES; + private static final boolean DEBUG_FP_WAKELOCK = KeyguardConstants.DEBUG_FP_WAKELOCK; private static final int LOW_BATTERY_THRESHOLD = 20; + private static final long FINGERPRINT_WAKELOCK_TIMEOUT_MS = 15 * 1000; private static final String ACTION_FACE_UNLOCK_STARTED = "com.android.facelock.FACE_UNLOCK_STARTED"; private static final String ACTION_FACE_UNLOCK_STOPPED = "com.android.facelock.FACE_UNLOCK_STOPPED"; + private static final String FINGERPRINT_WAKE_LOCK_NAME = "wake-and-unlock wakelock"; + + /** + * Mode in which we don't need to wake up the device when we get a fingerprint. + */ + private static final int FP_WAKE_NONE = 0; + + /** + * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire + * a fingerprint while the screen is off and the device was sleeping. + */ + private static final int FP_WAKE_DIRECT_UNLOCK = 1; + + /** + * Mode in which we wake up the device, but play the normal dismiss animation. Active when we + * acquire a fingerprint pulsing in doze mode. + * */ + private static final int FP_WAKE_WAKE_TO_BOUNCER = 2; // Callback messages private static final int MSG_TIME_UPDATE = 301; @@ -106,18 +128,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private static final int MSG_DEVICE_PROVISIONED = 308; private static final int MSG_DPM_STATE_CHANGED = 309; private static final int MSG_USER_SWITCHING = 310; - private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312; + private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 311; + private static final int MSG_KEYGUARD_RESET = 312; private static final int MSG_BOOT_COMPLETED = 313; private static final int MSG_USER_SWITCH_COMPLETE = 314; private static final int MSG_USER_INFO_CHANGED = 317; private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318; - private static final int MSG_SCREEN_TURNED_ON = 319; - private static final int MSG_SCREEN_TURNED_OFF = 320; + private static final int MSG_STARTED_WAKING_UP = 319; + private static final int MSG_FINISHED_GOING_TO_SLEEP = 320; private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322; - private static final int MSG_FINGERPRINT_AUTHENTICATED = 323; - private static final int MSG_FINGERPRINT_ERROR = 324; - private static final int MSG_FINGERPRINT_HELP = 325; - private static final int MSG_FINGERPRINT_AUTH_FAILED = 326; private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327; private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328; private static final int MSG_AIRPLANE_MODE_CHANGED = 329; @@ -134,6 +153,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private boolean mKeyguardIsVisible; private boolean mBouncer; private boolean mBootCompleted; + private boolean mUserHasAuthenticatedSinceBoot; // Device provisioning state private boolean mDeviceProvisioned; @@ -152,11 +172,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private boolean mSwitchingUser; + private boolean mDeviceInteractive; private boolean mScreenOn; private SubscriptionManager mSubscriptionManager; private List<SubscriptionInfo> mSubscriptionInfo; private boolean mFingerprintDetectionRunning; private TrustManager mTrustManager; + private PowerManager mPowerManager; private final Handler mHandler = new Handler() { @Override @@ -192,6 +214,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { case MSG_KEYGUARD_VISIBILITY_CHANGED: handleKeyguardVisibilityChanged(msg.arg1); break; + case MSG_KEYGUARD_RESET: + handleKeyguardReset(); + break; case MSG_KEYGUARD_BOUNCER_CHANGED: handleKeyguardBouncerChanged(msg.arg1); break; @@ -204,23 +229,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { case MSG_REPORT_EMERGENCY_CALL_ACTION: handleReportEmergencyCallAction(); break; - case MSG_SCREEN_TURNED_OFF: - handleScreenTurnedOff(msg.arg1); - break; - case MSG_SCREEN_TURNED_ON: - handleScreenTurnedOn(); - break; - case MSG_FINGERPRINT_AUTHENTICATED: - handleFingerprintAuthenticated(); + case MSG_FINISHED_GOING_TO_SLEEP: + handleFinishedGoingToSleep(msg.arg1); break; - case MSG_FINGERPRINT_HELP: - handleFingerprintHelp(msg.arg1 /* msgId */, (String) msg.obj /* errString */); - break; - case MSG_FINGERPRINT_ERROR: - handleFingerprintError(msg.arg1 /* msgId */, (String) msg.obj /* errString */); - break; - case MSG_FINGERPRINT_AUTH_FAILED: - handleFingerprintAuthFailed(); + case MSG_STARTED_WAKING_UP: + handleStartedWakingUp(); break; case MSG_FACE_UNLOCK_STATE_CHANGED: handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2); @@ -253,6 +266,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private static int sCurrentUser; + private int mFpWakeMode; + public synchronized static void setCurrentUser(int currentUser) { sCurrentUser = currentUser; } @@ -353,23 +368,72 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } } - private void onFingerprintAuthenticated(int userId) { + private void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { mUserFingerprintAuthenticated.put(userId, true); for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { - cb.onFingerprintAuthenticated(userId); + cb.onFingerprintAuthenticated(userId, wakeAndUnlocking); } } } private void handleFingerprintAuthFailed() { - stopListeningForFingerprint(); + releaseFingerprintWakeLock(); handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized)); - updateFingerprintListeningState(); + } + + private void handleFingerprintAcquired(int acquireInfo) { + if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) { + return; + } + if (!mDeviceInteractive && !mScreenOn) { + releaseFingerprintWakeLock(); + mWakeLock = mPowerManager.newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, FINGERPRINT_WAKE_LOCK_NAME); + mWakeLock.acquire(); + mFpWakeMode = FP_WAKE_DIRECT_UNLOCK; + if (DEBUG_FP_WAKELOCK) { + Log.i(TAG, "fingerprint acquired, grabbing fp wakelock"); + } + mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable, + FINGERPRINT_WAKELOCK_TIMEOUT_MS); + } else if (!mDeviceInteractive) { + mFpWakeMode = FP_WAKE_WAKE_TO_BOUNCER; + } else { + mFpWakeMode = FP_WAKE_NONE; + } + } + + private final Runnable mReleaseFingerprintWakeLockRunnable = new Runnable() { + @Override + public void run() { + if (DEBUG_FP_WAKELOCK) { + Log.i(TAG, "fp wakelock: TIMEOUT!!"); + } + releaseFingerprintWakeLock(); + } + }; + + private void releaseFingerprintWakeLock() { + if (mWakeLock != null) { + mHandler.removeCallbacks(mReleaseFingerprintWakeLockRunnable); + if (DEBUG_FP_WAKELOCK) { + Log.i(TAG, "releasing fp wakelock"); + } + mWakeLock.release(); + mWakeLock = null; + } } private void handleFingerprintAuthenticated() { + if (mFpWakeMode == FP_WAKE_WAKE_TO_BOUNCER || mFpWakeMode == FP_WAKE_DIRECT_UNLOCK) { + if (DEBUG_FP_WAKELOCK) { + Log.i(TAG, "fp wakelock: Authenticated, waking up..."); + } + mPowerManager.wakeUp(SystemClock.uptimeMillis()); + } + releaseFingerprintWakeLock(); try { final int userId; try { @@ -382,7 +446,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId); return; } - onFingerprintAuthenticated(userId); + onFingerprintAuthenticated(userId, mFpWakeMode == FP_WAKE_DIRECT_UNLOCK); } finally { setFingerprintRunningDetectionRunning(false); } @@ -455,15 +519,23 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0; } + public boolean getUserCanSkipBouncer(int userId) { + return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId) + && isUnlockingWithFingerprintAllowed()); + } + public boolean getUserHasTrust(int userId) { - return !isTrustDisabled(userId) && mUserHasTrust.get(userId) - || mUserFingerprintAuthenticated.get(userId); + return !isTrustDisabled(userId) && mUserHasTrust.get(userId); } public boolean getUserTrustIsManaged(int userId) { return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId); } + public boolean isUnlockingWithFingerprintAllowed() { + return mUserHasAuthenticatedSinceBoot; + } + static class DisplayClientState { public int clientGeneration; public boolean clearing; @@ -552,26 +624,32 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { @Override public void onAuthenticationFailed() { - mHandler.obtainMessage(MSG_FINGERPRINT_AUTH_FAILED).sendToTarget(); + handleFingerprintAuthFailed(); }; @Override public void onAuthenticationSucceeded(AuthenticationResult result) { - mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED).sendToTarget(); + handleFingerprintAuthenticated(); } @Override public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { - mHandler.obtainMessage(MSG_FINGERPRINT_HELP, helpMsgId, 0, helpString).sendToTarget(); + handleFingerprintHelp(helpMsgId, helpString.toString()); } @Override public void onAuthenticationError(int errMsgId, CharSequence errString) { - mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, errMsgId, 0, errString).sendToTarget(); + handleFingerprintError(errMsgId, errString.toString()); + } + + @Override + public void onAuthenticationAcquired(int acquireInfo) { + handleFingerprintAcquired(acquireInfo); } }; private CancellationSignal mFingerprintCancelSignal; private FingerprintManager mFpm; + private PowerManager.WakeLock mWakeLock; /** * When we receive a @@ -689,24 +767,24 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { return sInstance; } - protected void handleScreenTurnedOn() { + protected void handleStartedWakingUp() { updateFingerprintListeningState(); final int count = mCallbacks.size(); for (int i = 0; i < count; i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { - cb.onScreenTurnedOn(); + cb.onStartedWakingUp(); } } } - protected void handleScreenTurnedOff(int arg1) { + protected void handleFinishedGoingToSleep(int arg1) { clearFingerprintRecognized(); final int count = mCallbacks.size(); for (int i = 0; i < count; i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { - cb.onScreenTurnedOff(arg1); + cb.onFinishedGoingToSleep(arg1); } } updateFingerprintListeningState(); @@ -738,6 +816,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private KeyguardUpdateMonitor(Context context) { mContext = context; mSubscriptionManager = SubscriptionManager.from(context); + mPowerManager = context.getSystemService(PowerManager.class); mDeviceProvisioned = isDeviceProvisionedInSettingsDb(); // Since device can't be un-provisioned, we only need to register a content observer // to update mDeviceProvisioned when we are... @@ -816,14 +895,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } private boolean shouldListenForFingerprint() { - return mScreenOn && mKeyguardIsVisible && !mSwitchingUser - && mTrustManager.hasUserAuthenticatedSinceBoot(ActivityManager.getCurrentUser()); + return mKeyguardIsVisible && !mSwitchingUser; } private void startListeningForFingerprint() { if (DEBUG) Log.v(TAG, "startListeningForFingerprint()"); int userId = ActivityManager.getCurrentUser(); if (isUnlockWithFingerPrintPossible(userId)) { + mUserHasAuthenticatedSinceBoot = mTrustManager.hasUserAuthenticatedSinceBoot( + ActivityManager.getCurrentUser()); if (mFingerprintCancelSignal != null) { mFingerprintCancelSignal.cancel(); } @@ -1117,6 +1197,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } /** + * Handle {@link #MSG_KEYGUARD_RESET} + */ + private void handleKeyguardReset() { + if (DEBUG) Log.d(TAG, "handleKeyguardReset"); + if (!isUnlockingWithFingerprintAllowed()) { + updateFingerprintListeningState(); + } + } + + /** * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED} * @see #sendKeyguardBouncerChanged(boolean) */ @@ -1223,6 +1313,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { message.sendToTarget(); } + public void sendKeyguardReset() { + mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget(); + } + /** * @see #handleKeyguardBouncerChanged(int) */ @@ -1352,22 +1446,34 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { // TODO: use these callbacks elsewhere in place of the existing notifyScreen*() // (KeyguardViewMediator, KeyguardHostView) + public void dispatchStartedWakingUp() { + synchronized (this) { + mDeviceInteractive = true; + } + mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP); + } + + public void dispatchFinishedGoingToSleep(int why) { + synchronized(this) { + mDeviceInteractive = false; + } + mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0)); + } + public void dispatchScreenTurnedOn() { synchronized (this) { mScreenOn = true; } - mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON); } - public void dispatchScreenTurnedOff(int why) { + public void dispatchScreenTurnedOff() { synchronized(this) { mScreenOn = false; } - mHandler.sendMessage(mHandler.obtainMessage(MSG_SCREEN_TURNED_OFF, why, 0)); } - public boolean isScreenOn() { - return mScreenOn; + public boolean isDeviceInteractive() { + return mDeviceInteractive; } /** diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index 26e69731a319..0cdf99999bb9 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -148,17 +148,17 @@ public class KeyguardUpdateMonitorCallback { } /** - * Called when the screen turns on + * Called when the device has started waking up. */ - public void onScreenTurnedOn() { } + public void onStartedWakingUp() { } /** - * Called when the screen turns off + * Called when the device has finished going to sleep. * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_ADMIN}, * {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER}, or * {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT}. */ - public void onScreenTurnedOff(int why) { } + public void onFinishedGoingToSleep(int why) { } /** * Called when trust changes for a user. @@ -178,8 +178,10 @@ public class KeyguardUpdateMonitorCallback { /** * Called when a fingerprint is recognized. * @param userId the user id for which the fingerprint was authenticated + * @param wakeAndUnlocking whether the authentication woke the device up and thus we'd like to + * dismiss the lockscreen before turning on the screen */ - public void onFingerprintAuthenticated(int userId) { } + public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { } /** * Called when fingerprint provides help string (e.g. "Try again") diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java index 49e67408c420..bafccaee749e 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java @@ -46,6 +46,7 @@ import android.util.Log; import android.util.Slog; import android.util.Xml; +import com.android.internal.logging.MetricsLogger; import com.android.internal.os.HandlerCaller; import com.android.internal.util.FastXmlSerializer; import com.android.printspooler.R; @@ -493,6 +494,7 @@ public final class PrintSpoolerService extends Service { Slog.i(LOG_TAG, "[STATE CHANGED] " + printJob); } + MetricsLogger.histogram(this, "print_job_state", state); switch (state) { case PrintJobInfo.STATE_COMPLETED: case PrintJobInfo.STATE_CANCELED: diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index 3c5dae3eda36..e8a5e43ce874 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -72,6 +72,7 @@ import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; +import com.android.internal.logging.MetricsLogger; import com.android.printspooler.R; import com.android.printspooler.model.MutexFileProvider; import com.android.printspooler.model.PrintSpoolerProvider; @@ -325,6 +326,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (mState != STATE_INITIALIZING && mCurrentPrinter != null) { mPrinterRegistry.setTrackedPrinter(mCurrentPrinter.getId()); } + MetricsLogger.count(this, "print_preview", 1); } @Override @@ -679,7 +681,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (resolvedActivities.get(0).activityInfo.exported) { intent.putExtra(PrintService.EXTRA_PRINT_JOB_INFO, mPrintJob); intent.putExtra(PrintService.EXTRA_PRINTER_INFO, printer); - intent.putExtra(PrintService.EXTRA_PRINT_JOB_INFO, + intent.putExtra(PrintService.EXTRA_PRINT_DOCUMENT_INFO, mPrintedDocument.getDocumentInfo().info); // This is external activity and may not be there. @@ -1074,6 +1076,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat private void confirmPrint() { setState(STATE_PRINT_CONFIRMED); + MetricsLogger.count(this, "print_confirmed", 1); + updateOptionsUi(); addCurrentPrinterToHistory(); diff --git a/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationUtils.java b/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationUtils.java index 441474d7fc32..df76125a99f2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationUtils.java @@ -16,11 +16,18 @@ package com.android.settingslib.animation; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; import android.content.Context; +import android.view.RenderNodeAnimator; import android.view.View; +import android.view.ViewPropertyAnimator; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; +import com.android.internal.widget.LockPatternView; import com.android.settingslib.R; /** @@ -174,24 +181,63 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> { } @Override - public void createAnimation(View view, long delay, long duration, float translationY, - boolean appearing, Interpolator interpolator, Runnable endRunnable) { + public void createAnimation(final View view, long delay, long duration, float translationY, + boolean appearing, Interpolator interpolator, final Runnable endRunnable) { if (view != null) { view.setAlpha(appearing ? 0f : 1.0f); view.setTranslationY(appearing ? translationY : 0); - view.animate() - .alpha(appearing ? 1f : 0f) - .translationY(appearing ? 0 : translationY) - .setInterpolator(interpolator) - .setDuration(duration) - .setStartDelay(delay); + Animator alphaAnim; + float targetAlpha = appearing ? 1f : 0f; + if (view.isHardwareAccelerated()) { + RenderNodeAnimator alphaAnimRt = new RenderNodeAnimator(RenderNodeAnimator.ALPHA, + targetAlpha); + alphaAnimRt.setTarget(view); + alphaAnim = alphaAnimRt; + } else { + alphaAnim = ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), targetAlpha); + } + alphaAnim.setInterpolator(interpolator); + alphaAnim.setDuration(duration); + alphaAnim.setStartDelay(delay); if (view.hasOverlappingRendering()) { - view.animate().withLayer(); + view.setLayerType(View.LAYER_TYPE_HARDWARE, null); + alphaAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + view.setLayerType(View.LAYER_TYPE_NONE, null); + } + }); } if (endRunnable != null) { - view.animate().withEndAction(endRunnable); + alphaAnim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + endRunnable.run(); + } + }); } + alphaAnim.start(); + startTranslationYAnimation(view, delay, duration, appearing ? 0 : translationY, + interpolator); + } + } + + public static void startTranslationYAnimation(View view, long delay, long duration, + float endTranslationY, Interpolator interpolator) { + Animator translationAnim; + if (view.isHardwareAccelerated()) { + RenderNodeAnimator translationAnimRt = new RenderNodeAnimator( + RenderNodeAnimator.TRANSLATION_Y, endTranslationY); + translationAnimRt.setTarget(view); + translationAnim = translationAnimRt; + } else { + translationAnim = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, + view.getTranslationY(), endTranslationY); } + translationAnim.setInterpolator(interpolator); + translationAnim.setDuration(duration); + translationAnim.setStartDelay(delay); + translationAnim.start(); } public class AppearAnimationProperties { diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java index 40d5437b0a72..9eb7d0ebfcc3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java @@ -1239,6 +1239,21 @@ public class ApplicationsState { } }; + public static final AppFilter FILTER_PERSONAL_WITHOUT_DISABLED_UNTIL_USED = new AppFilter() { + private int mCurrentUser; + + public void init() { + mCurrentUser = ActivityManager.getCurrentUser(); + } + + @Override + public boolean filterApp(AppEntry entry) { + return UserHandle.getUserId(entry.info.uid) == mCurrentUser && + entry.info.enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; + } + }; + + public static final AppFilter FILTER_WORK = new AppFilter() { private int mCurrentUser; diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 249eaa5d44d3..b0429ef43cf9 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 @@ public final class CachedBluetoothDevice implements Comparable<CachedBluetoothDe // 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_REJECTED); + setPhonebookPermissionChoice(CachedBluetoothDevice.ACCESS_ALLOWED); } } } diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index 3f0d71c1d43b..1cd2908e77e9 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -210,4 +210,6 @@ <!-- Default state of tap to wake --> <bool name="def_double_tap_to_wake">true</bool> + <!-- Default for Settings.Secure.NFC_PAYMENT_COMPONENT --> + <string name="def_nfc_payment_component"></string> </resources> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 8d9f3fd4e9fd..73971adaca0c 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -42,6 +42,9 @@ import android.os.Build; import android.os.Bundle; import android.os.DropBoxManager; import android.os.Environment; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.SystemProperties; @@ -204,9 +207,6 @@ public class SettingsProvider extends ContentProvider { // We have to call in the user manager with no lock held, private volatile UserManager mUserManager; - // We have to call in the app ops manager with no lock held, - private volatile AppOpsManager mAppOpsManager; - // We have to call in the package manager with no lock held, private volatile PackageManager mPackageManager; @@ -214,7 +214,6 @@ public class SettingsProvider extends ContentProvider { public boolean onCreate() { synchronized (mLock) { mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); - mAppOpsManager = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE); mPackageManager = getContext().getPackageManager(); mSettingsRegistry = new SettingsRegistry(); } @@ -532,7 +531,7 @@ public class SettingsProvider extends ContentProvider { } while (cursor.moveToNext()); } - private static final String toDumpString(String s) { + private static String toDumpString(String s) { if (s != null) { return s; } @@ -643,11 +642,6 @@ public class SettingsProvider extends ContentProvider { // Make sure the caller can change the settings - treated as secure. enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); - // Verify whether this operation is allowed for the calling package. - if (!isAppOpWriteSettingsAllowedForCallingPackage()) { - return false; - } - // Resolve the userId on whose behalf the call is made. final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId); @@ -773,11 +767,6 @@ public class SettingsProvider extends ContentProvider { // Make sure the caller can change the settings. enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); - // Verify whether this operation is allowed for the calling package. - if (!isAppOpWriteSettingsAllowedForCallingPackage()) { - return false; - } - // Resolve the userId on whose behalf the call is made. final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId); @@ -904,14 +893,13 @@ public class SettingsProvider extends ContentProvider { private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation) { - // Check for permissions first. - if (!hasPermissionsToMutateSystemSettings()) { - return false; - } - - // Verify whether this operation is allowed for the calling package. - if (!isAppOpWriteSettingsAllowedForCallingPackage()) { - return false; + if (!hasWriteSecureSettingsPermission()) { + // If the caller doesn't hold WRITE_SECURE_SETTINGS, we verify whether this + // operation is allowed for the calling package through appops. + if (!Settings.checkAndNoteWriteSettingsOperation(getContext(), + Binder.getCallingUid(), getCallingPackage(), true)) { + return false; + } } // Enforce what the calling package can mutate the system settings. @@ -956,25 +944,13 @@ public class SettingsProvider extends ContentProvider { } } - private boolean hasPermissionsToMutateSystemSettings() { + private boolean hasWriteSecureSettingsPermission() { // 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; } @@ -1102,15 +1078,6 @@ public class SettingsProvider extends ContentProvider { } } - private boolean isAppOpWriteSettingsAllowedForCallingPackage() { - final int callingUid = Binder.getCallingUid(); - - mAppOpsManager.checkPackage(Binder.getCallingUid(), getCallingPackage()); - - return mAppOpsManager.noteOp(AppOpsManager.OP_WRITE_SETTINGS, callingUid, - getCallingPackage()) == AppOpsManager.MODE_ALLOWED; - } - private void enforceWritePermission(String permission) { if (getContext().checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { @@ -1190,18 +1157,6 @@ public class SettingsProvider extends ContentProvider { getCallingPackage()); } - private void sendNotify(Uri uri, int userId) { - final long identity = Binder.clearCallingIdentity(); - try { - getContext().getContentResolver().notifyChange(uri, null, true, userId); - if (DEBUG) { - Slog.v(LOG_TAG, "Notifying for " + userId + ": " + uri); - } - } finally { - Binder.restoreCallingIdentity(identity); - } - } - private static void warnOrThrowForUndesiredSecureSettingsMutationForTargetSdk( int targetSdkVersion, String name) { // If the app targets Lollipop MR1 or older SDK we warn, otherwise crash. @@ -1422,8 +1377,11 @@ public class SettingsProvider extends ContentProvider { private final BackupManager mBackupManager; + private final Handler mHandler; + public SettingsRegistry() { mBackupManager = new BackupManager(getContext()); + mHandler = new MyHandler(getContext().getMainLooper()); migrateAllLegacySettingsIfNeeded(); } @@ -1765,7 +1723,7 @@ public class SettingsProvider extends ContentProvider { // Inform the backup manager about a data change if (backedUpDataChanged) { - mBackupManager.dataChanged(); + mHandler.obtainMessage(MyHandler.MSG_NOTIFY_DATA_CHANGED).sendToTarget(); } // Now send the notification through the content framework. @@ -1773,7 +1731,9 @@ public class SettingsProvider extends ContentProvider { final int userId = getUserIdFromKey(key); Uri uri = getNotificationUriFor(key, name); - sendNotify(uri, userId); + mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, + userId, 0, uri).sendToTarget(); + if (isSecureSettingsKey(key)) { maybeNotifyProfiles(userId, uri, name, sSecureCloneToManagedSettings); } else if (isSystemSettingsKey(key)) { @@ -1790,7 +1750,8 @@ public class SettingsProvider extends ContentProvider { UserInfo profile = profiles.get(i); // the notification for userId has already been sent. if (profile.id != userId) { - sendNotify(uri, profile.id); + mHandler.obtainMessage(MyHandler.MSG_NOTIFY_URI_CHANGED, + profile.id, 0, uri).sendToTarget(); } } } @@ -1866,8 +1827,35 @@ public class SettingsProvider extends ContentProvider { } } + private final class MyHandler extends Handler { + private static final int MSG_NOTIFY_URI_CHANGED = 1; + private static final int MSG_NOTIFY_DATA_CHANGED = 2; + + public MyHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_NOTIFY_URI_CHANGED: { + final int userId = msg.arg1; + Uri uri = (Uri) msg.obj; + getContext().getContentResolver().notifyChange(uri, null, true, userId); + if (DEBUG) { + Slog.v(LOG_TAG, "Notifying for " + userId + ": " + uri); + } + } break; + + case MSG_NOTIFY_DATA_CHANGED: { + mBackupManager.dataChanged(); + } break; + } + } + } + private final class UpgradeController { - private static final int SETTINGS_VERSION = 121; + private static final int SETTINGS_VERSION = 122; private final int mUserId; @@ -1995,10 +1983,30 @@ public class SettingsProvider extends ContentProvider { 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; + if (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; + } + if (currentVersion == 121) { + // Version 122: allow OEMs to set a default payment component in resources. + // Note that we only write the default if no default has been set; + // if there is, we just leave the default at whatever it currently is. + final SettingsState secureSettings = getSecureSettingsLocked(userId); + String defaultComponent = (getContext().getResources().getString( + R.string.def_nfc_payment_component)); + Setting currentSetting = secureSettings.getSettingLocked( + Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT); + if (defaultComponent != null && !defaultComponent.isEmpty() && + currentSetting == null) { + secureSettings.insertSettingLocked( + Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT, + defaultComponent, + SettingsState.SYSTEM_PACKAGE_NAME); + } + currentVersion = 122; + } // vXXX: Add new settings above this point. // Return the current version. diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 9832b45d8ab3..c00fdf3f0480 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -76,7 +76,9 @@ <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" /> <uses-permission android:name="android.permission.STOP_APP_SWITCHES" /> <uses-permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" /> - <uses-permission android:name="android.permission.GRANT_REVOKE_PERMISSIONS" /> + <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" /> + <uses-permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS" /> + <uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" /> <uses-permission android:name="android.permission.SET_KEYBOARD_LAYOUT" /> <uses-permission android:name="android.permission.GET_DETAILED_TASKS" /> <uses-permission android:name="android.permission.SET_SCREEN_COMPATIBILITY" /> diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 6e5dc3fabd83..bbef25951172 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -49,6 +49,7 @@ <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> @@ -59,7 +60,7 @@ <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" /> <uses-permission android:name="android.permission.CONTROL_VPN" /> - + <uses-permission android:name="android.permission.PEERS_MAC_ADDRESS"/> <!-- Physical hardware --> <uses-permission android:name="android.permission.MANAGE_USB" /> <uses-permission android:name="android.permission.DEVICE_POWER" /> @@ -125,6 +126,11 @@ <!-- Assist --> <uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" /> + <!-- Self permission for internal broadcasts. --> + <permission android:name="com.android.systemui.permission.SELF" + android:protectionLevel="signature" /> + <uses-permission android:name="com.android.systemui.permission.SELF" /> + <application android:name=".SystemUIApplication" android:persistent="true" @@ -405,5 +411,13 @@ android:exported="true" android:singleUser="true" android:permission="android.permission.BIND_DREAM_SERVICE" /> + + <receiver + android:name=".tuner.TunerService$ClearReceiver" + android:exported="false"> + <intent-filter> + <action android:name="com.android.systemui.action.CLEAR_TUNER" /> + </intent-filter> + </receiver> </application> </manifest> diff --git a/packages/SystemUI/res/anim/navbar_fade_in.xml b/packages/SystemUI/res/anim/navbar_fade_in.xml new file mode 100644 index 000000000000..e3429e68dd13 --- /dev/null +++ b/packages/SystemUI/res/anim/navbar_fade_in.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 + --> + +<alpha xmlns:android="http://schemas.android.com/apk/res/android" + android:fromAlpha="0.0" + android:toAlpha="1.0" + android:interpolator="@android:interpolator/linear_out_slow_in" + android:duration="200"/> diff --git a/packages/SystemUI/res/drawable-nodpi/tuner.xml b/packages/SystemUI/res/drawable-nodpi/tuner.xml index e27423f275e1..0596aa4ed14f 100644 --- a/packages/SystemUI/res/drawable-nodpi/tuner.xml +++ b/packages/SystemUI/res/drawable-nodpi/tuner.xml @@ -1,7 +1,7 @@ <!-- - 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"); + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -14,14 +14,11 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="48.0dp" - android:height="48.0dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> <path - android:fillColor="#FF000000" - android:pathData="M29.9,24.8c0.0,-0.3 0.1,-0.5 0.1,-0.8s0.0,-0.5 -0.1,-0.8l1.7,-1.3c0.2,-0.1 0.2,-0.3 0.1,-0.5l-1.6,-2.8c-0.1,-0.2 -0.3,-0.2 -0.5,-0.2l-2.0,0.8c-0.4,-0.3 -0.9,-0.6 -1.4,-0.8L26.0,16.3c0.0,-0.2 -0.2,-0.3 -0.4,-0.3l-3.2,0.0c-0.2,0.0 -0.4,0.1 -0.4,0.3l-0.3,2.1c-0.5,0.2 -0.9,0.5 -1.4,0.8l-2.0,-0.8c-0.2,-0.1 -0.4,0.0 -0.5,0.2l-1.6,2.8c-0.1,0.2 -0.1,0.4 0.1,0.5l1.7,1.3c0.0,0.3 -0.1,0.5 -0.1,0.8s0.0,0.5 0.1,0.8l-1.7,1.3c-0.2,0.1 -0.2,0.3 -0.1,0.5l1.6,2.8c0.1,0.2 0.3,0.2 0.5,0.2l2.0,-0.8c0.4,0.3 0.9,0.6 1.4,0.8l0.3,2.1c0.0,0.2 0.2,0.3 0.4,0.3l3.2,0.0c0.2,0.0 0.4,-0.1 0.4,-0.3l0.3,-2.1c0.5,-0.2 0.9,-0.5 1.4,-0.8l2.0,0.8c0.2,0.1 0.4,0.0 0.5,-0.2l1.6,-2.8c0.1,-0.2 0.1,-0.4 -0.1,-0.5L29.9,24.8zM24.0,26.8c-1.5,0.0 -2.8,-1.3 -2.8,-2.8s1.3,-2.8 2.8,-2.8s2.8,1.3 2.8,2.8S25.5,26.8 24.0,26.8z"/> - <path - android:fillColor="#FF000000" - android:pathData="M18.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S18.6,38.0 18.0,38.0zM24.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S24.6,38.0 24.0,38.0zM30.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S30.6,38.0 30.0,38.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,28.0c0.0,2.2 1.8,4.0 4.0,4.0l36.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM42.0,34.0L6.0,34.0L6.0,14.0l36.0,0.0L42.0,34.0zM9.0,12.0L7.0,12.0l0.0,-2.0l2.0,0.0L9.0,12.0zM13.0,12.0l-2.0,0.0l0.0,-2.0l2.0,0.0L13.0,12.0zM17.0,12.0l-2.0,0.0l0.0,-2.0l2.0,0.0L17.0,12.0z"/> + android:fillColor="#FFFFFFFF" + android:pathData="M22.7,19.0l-9.1,-9.1c0.9,-2.0 0.4,-5.0 -1.5,-6.9 -2.0,-2.0 -5.0,-2.4 -7.4,-1.3L9.0,6.0 6.0,9.0 1.6,4.7C0.4,7.0 0.9,10.1 2.9,12.1c1.9,1.9 4.6,2.4 6.9,1.5l9.1,9.1c0.4,0.4 1.0,0.4 1.4,0.0l2.3,-2.3c0.5,-0.4 0.5,-1.0 0.1,-1.4z"/> </vector> diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml index 1488ad6342bc..444f0f016b85 100644 --- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml +++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml @@ -26,7 +26,7 @@ <com.android.systemui.statusbar.phone.KeyguardIndicationTextView android:id="@+id/keyguard_indication_text" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom" android:layout_gravity="bottom|center_horizontal" diff --git a/packages/SystemUI/res/layout/split_clock_view.xml b/packages/SystemUI/res/layout/split_clock_view.xml index 808460a88f46..d1269dabf286 100644 --- a/packages/SystemUI/res/layout/split_clock_view.xml +++ b/packages/SystemUI/res/layout/split_clock_view.xml @@ -35,6 +35,7 @@ android:singleLine="true" android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" android:textSize="@dimen/qs_time_collapsed_size" + android:importantForAccessibility="no" /> <!-- Empty text view so we have the same height when expanded/collapsed--> @@ -46,4 +47,4 @@ android:singleLine="true" android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock" /> -</com.android.systemui.statusbar.policy.SplitClockView>
\ No newline at end of file +</com.android.systemui.statusbar.policy.SplitClockView> diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml index 3118d0871c52..a5b3a8344465 100644 --- a/packages/SystemUI/res/layout/status_bar.xml +++ b/packages/SystemUI/res/layout/status_bar.xml @@ -25,7 +25,7 @@ android:id="@+id/status_bar" android:background="@drawable/system_bar_background" android:orientation="vertical" - android:focusable="true" + android:focusable="false" android:descendantFocusability="afterDescendants" > diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml index 7262ed2be054..5eca47106a1d 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml @@ -44,14 +44,31 @@ android:scaleType="centerInside"/> </com.android.systemui.statusbar.phone.MultiUserSwitch> - <com.android.keyguard.AlphaOptimizedImageButton android:id="@+id/settings_button" - style="@android:style/Widget.Material.Button.Borderless" - android:layout_toStartOf="@id/multi_user_switch" + <com.android.systemui.statusbar.AlphaOptimizedFrameLayout + android:id="@+id/settings_button_container" android:layout_width="48dp" android:layout_height="@dimen/status_bar_header_height" - android:background="@drawable/ripple_drawable" - android:src="@drawable/ic_settings" - android:contentDescription="@string/accessibility_desc_settings" /> + android:clipChildren="false" + android:clipToPadding="false" + android:layout_toStartOf="@id/multi_user_switch"> + + <com.android.systemui.statusbar.phone.SettingsButton android:id="@+id/settings_button" + style="@android:style/Widget.Material.Button.Borderless" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/ripple_drawable" + android:src="@drawable/ic_settings" + android:contentDescription="@string/accessibility_desc_settings" /> + <com.android.systemui.statusbar.AlphaOptimizedImageView android:id="@+id/tuner_icon" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingStart="36dp" + android:tint="#4DFFFFFF" + android:tintMode="src_in" + android:visibility="invisible" + android:src="@drawable/tuner" /> + + </com.android.systemui.statusbar.AlphaOptimizedFrameLayout> <LinearLayout android:id="@+id/system_icons_super_container" android:layout_width="wrap_content" diff --git a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml index 4526af53afaa..f699fce27043 100644 --- a/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml +++ b/packages/SystemUI/res/layout/status_bar_notification_keyguard_overflow.xml @@ -31,7 +31,7 @@ android:layout_height="match_parent" /> - <LinearLayout + <com.android.keyguard.AlphaOptimizedLinearLayout android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -63,6 +63,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> - </LinearLayout> + </com.android.keyguard.AlphaOptimizedLinearLayout> </com.android.systemui.statusbar.NotificationOverflowContainer> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 472e0450c724..f58ae7338d37 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is die volumedialoog"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Raak om die oorspronklike terug te stel."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Jy gebruik tans jou werkprofiel"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Stelsel-UI-ontvanger"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Stelsel-UI-ontvanger"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Wys persentasie van ingebedde battery"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Wys batteryvlakpersentasie binne die statusbalkikoon wanneer dit nie laai nie"</string> <string name="quick_settings" msgid="10042998191725428">"Kitsinstellings"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Kitsinstellings, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Warmkol"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Werkprofiel"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Pret vir party mense, maar nie vir almal nie"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Stelsel-UI-ontvanger gee jou ekstra maniere om die Android-gebruikerkoppelvlak in te stel en te pasmaak. Hierdie eksperimentele kenmerke kan in toekomstige uitreikings verander, breek of verdwyn. Gaan versigtig voort."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Hierdie eksperimentele kenmerke kan in toekomstige weergawes verander, breek of verdwyn. Gaan versigtig voort."</string> + <string name="got_it" msgid="2239653834387972602">"Het dit"</string> + <string name="tuner_toast" msgid="603429811084428439">"Geluk! Stelsel-UI-ontvanger is by Instellings gevoeg"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Verwyder uit Instellings"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Verwyder Stelsel-UI-ontvanger uit Instellings en staak die gebruik van al sy kenmerke?"</string> </resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index e55d48b08fcb..07c780b2792b 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> የድምጽ መጠን መገናኛው ነው"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"የመጀመሪያውን ወደነበረበት ለመመለስ ይንኩ።"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"የስራ መገለጫዎን እየተጠቀሙ ነው"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"የስርዓት በይነገጽ መቃኛ"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"የስርዓት በይነገጽ መቃኛ"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"የተቀላቀለ የባትሪ አጠቃቀም መቶኛ አሳይ"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ኃይል በማይሞላበት ጊዜ በሁነታ አሞሌ አዶ ውስጥ የባትሪ ደረጃ መቶኛን አሳይ"</string> <string name="quick_settings" msgid="10042998191725428">"ፈጣን ቅንብሮች"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"ፈጣን ቅንብሮች፣ <xliff:g id="TITLE">%s</xliff:g>።"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"መገናኛ ነጥብ"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"የስራ መገለጫ"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"ለአንዳንዶች አስደሳች ቢሆንም ለሁሉም አይደለም"</string> + <string name="tuner_warning" msgid="8730648121973575701">"የስርዓት በይነገጽ መቃኛ የAndroid ተጠቃሚ በይነገጹን የሚነካኩበት እና የሚያበጁበት ተጨማሪ መንገዶች ይሰጠዎታል። እነዚህ የሙከራ ባህሪዎች ወደፊት በሚኖሩ ልቀቶች ላይ ሊለወጡ፣ ሊሰበሩ ወይም ሊጠፉ ይችላሉ። ከጥንቃቄ ጋር ወደፊት ይቀጥሉ።"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"እነዚህ የሙከራ ባህሪዎች ወደፊት በሚኖሩ ልቀቶች ላይ ሊለወጡ፣ ሊሰበሩ ወይም ሊጠፉ ይችላሉ። ከጥንቃቄ ጋር ወደፊት ይቀጥሉ።"</string> + <string name="got_it" msgid="2239653834387972602">"ገባኝ"</string> + <string name="tuner_toast" msgid="603429811084428439">"እንኳን ደስ ያለዎት! የስርዓት በይነገጽ መቃኛ ወደ ቅንብሮች ታክሏል"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"ከቅንብሮች አስወግድ"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"ከቅንብሮች ላይ የስርዓት በይነገጽ መቃኛ ተወግዶ ሁሉም ባህሪዎቹን መጠቀም ይቁም?"</string> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 94eaccc48862..dac9b01b01c8 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -402,7 +402,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> هو مربع حوار مستوى الصوت"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"المس لاستعادة الإعداد الأصلي."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"أنت تستخدم ملفك الشخصي للعمل"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"أداة ضبط واجهة مستخدم النظام"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"أداة ضبط واجهة مستخدم النظام"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"عرض نسبة البطارية المدمجة"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"عرض نسبة مستوى البطارية داخل رمز شريط الحالة أثناء عدم الشحن"</string> <string name="quick_settings" msgid="10042998191725428">"الإعدادات السريعة"</string> @@ -423,4 +423,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"الإعدادات السريعة، <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"نقطة اتصال"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"الملف الشخصي للعمل"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"متعة للبعض وليس للجميع"</string> + <string name="tuner_warning" msgid="8730648121973575701">"توفر لك أداة ضبط واجهة مستخدم النظام طرقًا إضافية لتعديل واجهة مستخدم Android وتخصيصها. ويمكن أن تطرأ تغييرات على هذه الميزات التجريبية أو يمكن أن تتعطل هذه الميزات أو تختفي في الإصدارات المستقبلية. عليك متابعة الاستخدام مع توخي الحذر."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"يمكن أن تطرأ تغييرات على هذه الميزات التجريبية أو يمكن أن تتعطل هذه الميزات أو تختفي في الإصدارات المستقبلية. عليك متابعة الاستخدام مع توخي الحذر."</string> + <string name="got_it" msgid="2239653834387972602">"حسنًا"</string> + <string name="tuner_toast" msgid="603429811084428439">"تهانينا! تمت إضافة أداة ضبط واجهة مستخدم النظام إلى الإعدادات"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"إزالة من الإعدادات"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"هل تريد إزالة أداة ضبط واجهة مستخدم النظام من الإعدادات وإيقاف استخدام كل ميزاتها؟"</string> </resources> diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml index c9397c615460..41a6e26bb744 100644 --- a/packages/SystemUI/res/values-az-rAZ/strings.xml +++ b/packages/SystemUI/res/values-az-rAZ/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> proqramı səs səviyyəsi dialoqudur"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Orijinalı bərpa etmək üçün toxun."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"İş profilinizi istifadə edirsiniz"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Sistem UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Daxil batareya faizini göstərin"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Elektrik şəbəsinə qoşulu olmayan zaman batareya səviyyəsini status paneli ikonası daxilində göstərin"</string> <string name="quick_settings" msgid="10042998191725428">"Sürətli Ayarlar"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Sürətli Ayarlar, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"İş profili"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Hamı üçün deyil, bəziləri üçün əyləncəli"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner Android istifadəçi interfeysini dəyişdirmək və fərdiləşdirmək üçün Sizə ekstra yollar təklif edir."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Bu eksperimental funksiyalar gələcək buraxılışlarda dəyişə, məhv ola və ya yoxa çıxa bilər. Ehtiyatlı olun."</string> + <string name="got_it" msgid="2239653834387972602">"Anladım"</string> + <string name="tuner_toast" msgid="603429811084428439">"Təbriklər! System UI Tuner Ayarlara əlavə edildi"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Ayarlardan Silin"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner Ayarlardan silinsin və onun bütün funksiyalarından istifadə dayandırılsın?"</string> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 1db1917b3d5c..f3d93fc5d8e8 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> изпълнява ролята на диалоговия прозорец за силата на звука"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Докоснете, за да възстановите оригинала."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Използвате служебния си потребителски профил"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Тунер на системния ПИ"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Тунер на системния потребителски интерфейс"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Показване на процента на вградената батерия"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Показване на процента на нивото на батерията в иконата на лентата на състоянието, когато не се зарежда"</string> <string name="quick_settings" msgid="10042998191725428">"Бързи настройки"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Бързи настройки (<xliff:g id="TITLE">%s</xliff:g>)."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Точка за достъп"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Потребителски профил в Work"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Забавно – но не за всички"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Тунерът на системния потребителски интерфейс ви предоставя допълнителни възможности за прецизиране и персонализиране на практическата работа с Android. Тези експериментални функции може да се променят, повредят или да изчезнат в бъдещите версии. Действайте внимателно."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Тези експериментални функции може да се променят, повредят или да изчезнат в бъдещите версии. Действайте внимателно."</string> + <string name="got_it" msgid="2239653834387972602">"Разбрах"</string> + <string name="tuner_toast" msgid="603429811084428439">"Поздравления! Тунерът на системния потребителски интерфейс е добавен към „Настройки“"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Премахване от „Настройки“"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Да се премахне ли от „Настройки“ тунерът на системния потребителски интерфейс и да се спре ли използването на всичките му функции?"</string> </resources> diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml index 4605b7c2708f..0c1847912435 100644 --- a/packages/SystemUI/res/values-bn-rBD/strings.xml +++ b/packages/SystemUI/res/values-bn-rBD/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> হল ভলিউম ডায়লগ"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"আসলটি পুনঃস্থাপন করতে স্পর্শ করুন৷"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"আপনি আপনার কাজের প্রোফাইল ব্যবহার করছেন"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"সিস্টেম UI টিউনার"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"সিস্টেম UI টিউনার"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"এম্বেড করা ব্যাটারির শতকরা হার দেখায়"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"যখন চার্জ করা হবে না তখন স্থিতি দন্ডের আইকনের ভিতরে ব্যাটারি স্তরের শতকার হার দেখায়"</string> <string name="quick_settings" msgid="10042998191725428">"দ্রুত সেটিংস"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"দ্রুত সেটিংস, <xliff:g id="TITLE">%s</xliff:g>৷"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"হটস্পট"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"কাজের প্রোফাইল"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"কিছু ব্যক্তির জন্য মজাদার কিন্তু সকলের জন্য নয়"</string> + <string name="tuner_warning" msgid="8730648121973575701">"এই পরীক্ষামূলক বৈশিষ্ট্যগুলি ভবিষ্যতের সংস্করণগুলির মধ্যে পরিবর্তিত, বিভাজিত এবং অদৃশ্য হয়ে যেতে পারে৷ সাবধানতার সাথে এগিয়ে যান৷ সিস্টেম UI টিউনার আপনাকে Android ব্যবহারকারী ইন্টারফেসের সূক্ষ্ম সমন্বয় এবং কাস্টমাইজ করার অতিরিক্ত উপায়গুলি প্রদান করে৷"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"এই পরীক্ষামূলক বৈশিষ্ট্যগুলি ভবিষ্যতের সংস্করণগুলির মধ্যে পরিবর্তিত, বিভাজিত এবং অদৃশ্য হয়ে যেতে পারে৷ সাবধানতার সাথে এগিয়ে যান৷"</string> + <string name="got_it" msgid="2239653834387972602">"বুঝেছি"</string> + <string name="tuner_toast" msgid="603429811084428439">"অভিনন্দন! সেটিংস -এ সিস্টেম UI টিউনার যোগ করা হয়েছে"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"সেটিংস থেকে সরান"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"সেটিংস থেকে সিস্টেম UI টিউনার সরাতে এবং এটির সমস্ত বৈশিষ্ট্য ব্যবহার করা বন্ধ করতে চান?"</string> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index b9edc4912abb..d534ab9ed199 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> és el diàleg de volum"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca per restaurar l\'original."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estàs utilitzant el perfil professional"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Configurador de la IU del sistema"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Configurador de la IU del sistema"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Mostra el percentatge de la bateria inserit"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostra el percentatge del nivell de bateria dins de la icona de la barra d\'estat quan no s\'estigui carregant"</string> <string name="quick_settings" msgid="10042998191725428">"Configuració ràpida"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Configuració ràpida, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Zona Wi-Fi"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Perfil professional"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Diversió per a uns quants, però no per a tothom"</string> + <string name="tuner_warning" msgid="8730648121973575701">"El Configurador de la IU del sistema presenta opcions addicionals per canviar i personalitzar la interfície d\'usuari d\'Android. És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string> + <string name="got_it" msgid="2239653834387972602">"D\'acord"</string> + <string name="tuner_toast" msgid="603429811084428439">"Enhorabona! El Configurador de la IU del sistema s\'ha afegit a Configuració."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Treu de Configuració"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vols treure el Configurador de la UI del sistema de Configuració i deixar d\'utilitzar-ne totes les funcions?"</string> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 3138892dd0b5..333050063ef4 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -402,7 +402,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dialog hlasitosti"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Klepnutím obnovíte originál."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Používáte pracovní profil"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Nástroj na ladění uživatelského rozhraní systému"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Nástroj na ladění uživatelského rozhraní systému"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Zobrazovat vložené procento nabití baterie"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Když neprobíhá nabíjení, zobrazit v ikoně na stavovém řádku procento nabití baterie"</string> <string name="quick_settings" msgid="10042998191725428">"Rychlé nastavení"</string> @@ -423,4 +423,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Rychlé nastavení <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Pracovní profil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Zábava, která není pro každého"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Nástroj na ladění uživatelského rozhraní systému vám nabízí další způsoby, jak si vyladit a přizpůsobit uživatelské rozhraní Android. Tyto experimentální funkce mohou v dalších verzích chybět, nefungovat nebo být změněny. Postupujte proto prosím opatrně."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Tyto experimentální funkce mohou v dalších verzích chybět, nefungovat nebo být změněny. Postupujte proto prosím opatrně."</string> + <string name="got_it" msgid="2239653834387972602">"Rozumím"</string> + <string name="tuner_toast" msgid="603429811084428439">"Úspěch! Do Nastavení byl přidán nástroj na ladění uživatelského rozhraní systému."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Odstranit z Nastavení"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Chcete nástroj na ladění uživatelského rozhraní systému odstranit z Nastavení a přestat používat všechny jeho funkce?"</string> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 2cc96daaee64..3c0c0b2046ba 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er dialogboksen for lydstyrke"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Tryk for at gendanne originalen."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du bruger din arbejdsprofil"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Vis procent for det indbyggede batteri"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Vis procenttallet for batteriniveauet i ikonet for statusbjælken, når der ikke oplades"</string> <string name="quick_settings" msgid="10042998191725428">"Hurtige indstillinger"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Hurtigindstillinger <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Arbejdsprofil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Sjovt for nogle, men ikke for alle"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner giver dig flere muligheder for at justere og tilpasse Android-brugerfladen. Disse eksperimentelle funktioner kan ændres, gå i stykker eller forsvinde i fremtidige udgivelser. Vær forsigtig, hvis du fortsætter."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Disse eksperimentelle funktioner kan ændres, gå i stykker eller forsvinde i fremtidige udgivelser. Vær forsigtig, hvis du fortsætter."</string> + <string name="got_it" msgid="2239653834387972602">"OK"</string> + <string name="tuner_toast" msgid="603429811084428439">"System UI Tuner blev føjet til Indstillinger"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Fjern fra Indstillinger"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vil du fjerne System UI Tuner fra Indstillinger og stoppe med at bruge alle dens funktioner?"</string> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 42ffb804c132..310436ae4298 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> regelt die Lautstärke."</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Zum Wiederherstellen des Originals hier tippen"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Sie verwenden Ihr Arbeitsprofil."</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"SystemUI-Tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Eingebettete Akku-Prozentzahl anzeigen"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prozentzahl für Akkustand in Statusleistensymbol anzeigen, wenn das Gerät nicht geladen wird"</string> <string name="quick_settings" msgid="10042998191725428">"Schnelleinstellungen"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Schnelleinstellungen (<xliff:g id="TITLE">%s</xliff:g>)"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Arbeitsprofil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Für einige ein Vergnügen, aber nicht für alle"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Mit System UI Tuner erhalten Sie zusätzliche Möglichkeiten, die Android-Benutzeroberfläche anzupassen. Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Achtung: Diese Testfunktionen können sich ändern, abstürzen oder in zukünftigen Versionen verschwinden."</string> + <string name="got_it" msgid="2239653834387972602">"OK"</string> + <string name="tuner_toast" msgid="603429811084428439">"Herzlichen Glückwunsch! System UI Tuner wurde \"Einstellungen\" hinzugefügt."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Aus \"Einstellungen\" entfernen"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner aus \"Einstellungen\" entfernen und die Verwendung von allen zugehörigen Funktionen beenden?"</string> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index f445321b817f..5efe87b8a61f 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> αποτελεί το παράθυρο διαλόγου ελέγχου έντασης"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Αγγίξτε για επαναφορά αρχικού."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Χρησιμοποιείτε το προφίλ εργασίας σας"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Δέκτης διεπαφής συστήματος"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Εμφάνιση ποσοστού ενσωματωμένης μπαταρίας"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Εμφάνιση ποσοστού επιπέδου μπαταρίας μέσα στο εικονίδιο της γραμμής κατάστασης όταν δεν γίνεται φόρτιση"</string> <string name="quick_settings" msgid="10042998191725428">"Γρήγορες ρυθμίσεις"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Γρήγορες ρυθμίσεις, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Σημείο πρόσβασης Wi-Fi"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Προφίλ εργασίας"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Διασκέδαση για ορισμένους, αλλά όχι για όλους"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Το System UI Tuner σάς προσφέρει επιπλέον τρόπους για να τροποποιήσετε και να προσαρμόσετε τη διεπαφή χρήστη Android. Αυτές οι πειραματικές λειτουργίες ενδέχεται να τροποποιηθούν, να παρουσιάσουν σφάλματα ή να καταργηθούν σε μελλοντικές εκδόσεις. Συνεχίστε με προσοχή."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Αυτές οι πειραματικές λειτουργίες ενδέχεται να τροποποιηθούν, να παρουσιάσουν σφάλματα ή να καταργηθούν σε μελλοντικές εκδόσεις. Συνεχίστε με προσοχή."</string> + <string name="got_it" msgid="2239653834387972602">"Το κατάλαβα"</string> + <string name="tuner_toast" msgid="603429811084428439">"Συγχαρητήρια! Το System UI Tuner προστέθηκε στις Ρυθμίσεις"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Κατάργηση από τις Ρυθμίσεις"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Κατάργηση System UI Tuner από τις Ρυθμίσεις και διακοπή χρήσης όλων των λειτουργιών του;"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 6ed7d7cc4b6a..d630e441e34e 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Show battery level percentage inside the status bar icon when not charging"</string> <string name="quick_settings" msgid="10042998191725428">"Quick Settings"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Quick Settings, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Work profile"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Fun for some but not for all"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"These experimental features may change, break or disappear in future releases. Proceed with caution."</string> + <string name="got_it" msgid="2239653834387972602">"Understood"</string> + <string name="tuner_toast" msgid="603429811084428439">"Congrats! System UI Tuner has been added to Settings"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Remove from settings"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remove System UI Tuner from Settings and stop using all of its features?"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 6ed7d7cc4b6a..d630e441e34e 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Show battery level percentage inside the status bar icon when not charging"</string> <string name="quick_settings" msgid="10042998191725428">"Quick Settings"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Quick Settings, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Work profile"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Fun for some but not for all"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"These experimental features may change, break or disappear in future releases. Proceed with caution."</string> + <string name="got_it" msgid="2239653834387972602">"Understood"</string> + <string name="tuner_toast" msgid="603429811084428439">"Congrats! System UI Tuner has been added to Settings"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Remove from settings"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remove System UI Tuner from Settings and stop using all of its features?"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 6ed7d7cc4b6a..d630e441e34e 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"You\'re using your work profile"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Show embedded battery percentage"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Show battery level percentage inside the status bar icon when not charging"</string> <string name="quick_settings" msgid="10042998191725428">"Quick Settings"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Quick Settings, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Work profile"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Fun for some but not for all"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner gives you extra ways to tweak and customise the Android user interface. These experimental features may change, break or disappear in future releases. Proceed with caution."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"These experimental features may change, break or disappear in future releases. Proceed with caution."</string> + <string name="got_it" msgid="2239653834387972602">"Understood"</string> + <string name="tuner_toast" msgid="603429811084428439">"Congrats! System UI Tuner has been added to Settings"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Remove from settings"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remove System UI Tuner from Settings and stop using all of its features?"</string> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index da0054d4f009..4a56237ba334 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> es el cuadro de diálogo de volumen."</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar el original."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando tu perfil de trabajo"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador de IU del sistema"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaje de la batería integrada"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar porcentaje del nivel de batería en el ícono de la barra de estado cuando no se está cargando"</string> <string name="quick_settings" msgid="10042998191725428">"Configuración rápida"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Configuración rápida: <xliff:g id="TITLE">%s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Perfil de trabajo"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Diversión para algunos, pero no para todos"</string> + <string name="tuner_warning" msgid="8730648121973575701">"El sintonizador de IU del sistema te brinda más formas para editar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, dejar de funcionar o no incluirse en futuras versiones. Procede con precaución."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Estas funciones experimentales pueden cambiar, dejar de funcionar o no incluirse en futuras versiones. Procede con precaución."</string> + <string name="got_it" msgid="2239653834387972602">"Entendido"</string> + <string name="tuner_toast" msgid="603429811084428439">"Se agregó el sintonizador de IU del sistema a Configuración"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Quitar de Configuración"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"¿Quieres quitar el sintonizador de IU del sistema de Configuración y dejar de utilizar todas sus funciones?"</string> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 99aabd982a19..7a8071531332 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> es el cuadro de diálogo de volumen"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar la versión original."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando tu perfil de trabajo"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Configurador de IU del sistema"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Configurador de IU del sistema"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaje de batería insertado"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar el porcentaje del nivel de batería en el icono de la barra de estado cuando no se esté cargando"</string> <string name="quick_settings" msgid="10042998191725428">"Ajustes rápidos"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Ajustes rápidos, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Zona Wi-Fi"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Perfil de trabajo"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Diversión solo para algunos"</string> + <string name="tuner_warning" msgid="8730648121973575701">"El configurador de IU del sistema te ofrece otras formas de modificar y personalizar la interfaz de usuario de Android. Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Estas funciones experimentales pueden cambiar, fallar o desaparecer en futuras versiones. Te recomendamos que tengas cuidado."</string> + <string name="got_it" msgid="2239653834387972602">"Entendido"</string> + <string name="tuner_toast" msgid="603429811084428439">"¡Enhorabuena! El configurador de IU del sistema se ha añadido a Ajustes"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Eliminar de Ajustes"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"¿Eliminar el configurador de IU del sistema de Ajustes y dejar de utilizar sus funciones?"</string> </resources> diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml index 2cdc4f7cb9f2..aec490673210 100644 --- a/packages/SystemUI/res/values-et-rEE/strings.xml +++ b/packages/SystemUI/res/values-et-rEE/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> on helitugevuse dialoog"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Originaali taastamiseks puudutage."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Kasutate oma tööprofiili"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Süsteemi kasutajaliidese tuuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Süsteemi kasutajaliidese tuuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Kuva lisatud akutaseme protsent"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Akutaseme protsendi kuvamine olekuriba ikoonil, kui akut ei laeta"</string> <string name="quick_settings" msgid="10042998191725428">"Kiirseaded"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Kiirseaded, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Leviala"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Tööprofiil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Kõik ei pruugi sellest rõõmu tunda"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Süsteemi kasutajaliidese tuuner pakub täiendavaid võimalusi Androidi kasutajaliidese muutmiseks ja kohandamiseks. Need katselised funktsioonid võivad muutuda, rikki minna või tulevastest versioonidest kaduda. Olge jätkamisel ettevaatlik."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Need katselised funktsioonid võivad muutuda, rikki minna või tulevastest versioonidest kaduda. Olge jätkamisel ettevaatlik."</string> + <string name="got_it" msgid="2239653834387972602">"Selge"</string> + <string name="tuner_toast" msgid="603429811084428439">"Õnnitleme! Süsteemi kasutajaliidese tuuner lisati seadetesse"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Eemalda seadetest"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Kas eemaldada seadetest süsteemi kasutajaliidese tuuner ja lõpetada kõikide selle funktsioonide kasutamine?"</string> </resources> diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml index 9de47f6053b1..c1967a38c7d2 100644 --- a/packages/SystemUI/res/values-eu-rES/strings.xml +++ b/packages/SystemUI/res/values-eu-rES/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> da bolumenaren leihoa"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Ukitu jatorrizkora leheneratzeko"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Work profila erabiltzen ari zara"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Sistemako erabiltzaile-interfazearen konfiguratzailea"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Sistemako erabiltzaile-interfazearen konfiguratzailea"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Erakutsi txertatutako bateriaren ehunekoa"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Erakutsi bateria-mailaren ehunekoa egoera-barraren ikonoan, kargatzen ari ez denean"</string> <string name="quick_settings" msgid="10042998191725428">"Ezarpen bizkorrak"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Ezarpen bizkorrak: <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Sare publikoa"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Work profila"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Dibertsioa batzuentzat, baina ez guztientzat"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Sistemako erabiltzaile-interfazearen konfiguratzaileak Android erabiltzaile-interfazea moldatzeko eta pertsonalizatzeko modu gehiago eskaintzen dizkizu. Baliteke eginbide esperimental horiek hurrengo kaleratzeetan aldatuta, etenda edo desagertuta egotea. Kontuz erabili."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Baliteke eginbide esperimental horiek hurrengo kaleratzeetan aldatuta, etenda edo desagertuta egotea. Kontuz erabili."</string> + <string name="got_it" msgid="2239653834387972602">"Ados"</string> + <string name="tuner_toast" msgid="603429811084428439">"Zorionak! Sistemako erabiltzaile-interfazearen konfiguratzailea Ezarpenak atalean gehitu da"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Kendu Ezarpenak ataletik"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Sistemako erabiltzaile-interfazearen konfiguratzailea ezarpenetatik kendu nahi duzu, eta haren eginbide guztiak erabiltzeari utzi nahi diozu?"</string> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 845ced53ea99..b5bd42393e8d 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -55,7 +55,7 @@ <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"به برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه میدهد تا به وسیله جانبی USB دسترسی داشته باشد؟"</string> <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"وقتی این دستگاه USB وصل است، <xliff:g id="ACTIVITY">%1$s</xliff:g> باز شود؟"</string> <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"وقتی این وسیله جانبی USB وصل است، <xliff:g id="ACTIVITY">%1$s</xliff:g> باز شود؟"</string> - <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"هیچ برنامهٔ کاربردی نصب شدهای با این وسیله جانبی USB کار نمیکند. در <xliff:g id="URL">%1$s</xliff:g> دربارهٔ این وسیله جانبی اطلاعات بیشتری کسب کنید"</string> + <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"هیچ برنامه نصب شدهای با این وسیله جانبی USB کار نمیکند. در <xliff:g id="URL">%1$s</xliff:g> دربارهٔ این وسیله جانبی اطلاعات بیشتری کسب کنید"</string> <string name="title_usb_accessory" msgid="4966265263465181372">"لوازم جانبی USB"</string> <string name="label_view" msgid="6304565553218192990">"مشاهده"</string> <string name="always_use_device" msgid="1450287437017315906">"استفاده به صورت پیشفرض برای این دستگاه USB"</string> @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> کنترلکننده صدا است"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"برای بازیابی کنترلکننده اصلی، لمس کنید."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"درحال استفاده از نمایه کاریتان هستید"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"تنظیمکننده واسط کاربری سیستم"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"تنظیمکننده واسط کاربری سیستم"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"نمایش درصد شارژ باتری جاسازی شده"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"نمایش درصد سطح باتری در نماد نوار وضعیت، هنگامی که باتری شارژ نمیشود"</string> <string name="quick_settings" msgid="10042998191725428">"تنظیمات سریع"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"تنظیمات سریع، <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"نقطه اتصال"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"نمایه کاری"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"برای بعضی افراد سرگرمکننده است اما نه برای همه"</string> + <string name="tuner_warning" msgid="8730648121973575701">"«تنظیمکننده واسط کاربری سیستم» روشهای بیشتری برای تنظیم دقیق و سفارشی کردن واسط کاربری Android در اختیار شما قرار میدهد. ممکن است این ویژگیهای آزمایشی تغییر کنند، خراب شوند یا در نسخههای آینده جود نداشته باشند. با احتیاط ادامه دهید."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ممکن است این ویژگیهای آزمایشی تغییر کنند، خراب شوند یا در نسخههای آینده وجود نداشته باشند. با احتیاط ادامه دهید."</string> + <string name="got_it" msgid="2239653834387972602">"متوجه شدم"</string> + <string name="tuner_toast" msgid="603429811084428439">"تبریک میگوییم! «تنظیمکننده واسط کاربری سیستم» به «تنظیمات» اضافه شد"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"حذف از تنظیمات"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"«تنظیمکننده واسط کاربری سیستم» از تنظیمات حذف شود و همه ویژگیهای آن متوقف شوند؟"</string> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 63d4ab4a30ed..5a540bcf1cb4 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> on äänenvoimakkuusvalinta."</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Palauta alkuperäinen koskettamalla."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Käytät työprofiilia."</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"SystemUI-viritin"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Näytä akun varaus kuvakkeessa"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Näyttää akun varausprosentin tilapalkin kuvakkeessa, kun laitetta ei ladata."</string> <string name="quick_settings" msgid="10042998191725428">"Pika-asetukset"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Pika-asetukset, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Työprofiili"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Ei sovellu kaikkien käyttöön"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner antaa lisämahdollisuuksia Android-käyttöliittymän muokkaamiseen. Nämä kokeelliset ominaisuudet voivat muuttua, lakata toimimasta tai kadota milloin tahansa. Jatka omalla vastuullasi."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Nämä kokeelliset ominaisuudet voivat muuttua, lakata toimimasta tai kadota milloin tahansa. Jatka omalla vastuullasi."</string> + <string name="got_it" msgid="2239653834387972602">"Selvä"</string> + <string name="tuner_toast" msgid="603429811084428439">"Hienoa! System UI Tuner on nyt lisätty Asetuksiin."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Poista Asetuksista"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Haluatko poistaa System UI Tunerin Asetuksista ja lopettaa sen ominaisuuksien käytön?"</string> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 9d7a7f09b226..5a46b10b0665 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> correspond à la boîte de dialogue du volume"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Touchez pour restaurer l\'original."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Vous utilisez votre profil professionnel."</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Paramètres SystemUI"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Afficher le pourcentage intégré de charge"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Afficher le pourcentage correspondant au niveau de la pile dans l\'icône de la barre d\'état lorsque l\'appareil n\'est pas en charge."</string> <string name="quick_settings" msgid="10042998191725428">"Paramètres rapides"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Configuration rapide – <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Point d\'accès sans fil"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profil professionnel"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Divertissant pour certains, mais pas pour tous"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner vous propose de nouvelles manières d\'adapter et de personnaliser l\'interface utilisateur d\'Android. Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string> + <string name="got_it" msgid="2239653834387972602">"J\'ai compris"</string> + <string name="tuner_toast" msgid="603429811084428439">"Félicitations! System UI Tuner a bien été ajouté aux paramètres."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Supprimer des paramètres"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Supprimer « System UI Tuner » des paramètres et arrêter d\'utiliser toutes ses fonctionnalités?"</string> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 09daca681187..6b81bde0c6f8 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> correspond à la boîte de dialogue du volume"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Appuyez pour restaurer l\'interface d\'origine."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Vous utilisez votre profil professionnel."</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Afficher le pourcentage intégré de la batterie"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Affichez le pourcentage correspondant au niveau de la batterie dans l\'icône de la barre d\'état lorsque l\'appareil n\'est pas en charge."</string> <string name="quick_settings" msgid="10042998191725428">"Configuration rapide"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Configuration rapide – <xliff:g id="TITLE">%s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Point d\'accès"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profil professionnel"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Divertissant pour certains, mais pas pour tous"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner vous propose de nouvelles manières d\'adapter et de personnaliser l\'interface utilisateur Android. Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou disparaître dans les versions futures. À utiliser avec prudence."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ces fonctionnalités expérimentales peuvent être modifiées, cesser de fonctionner ou ne plus être disponibles dans les versions futures. À utiliser avec prudence."</string> + <string name="got_it" msgid="2239653834387972602">"OK"</string> + <string name="tuner_toast" msgid="603429811084428439">"Félicitations ! System UI Tuner a bien été ajouté aux paramètres."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Supprimer l\'outil des paramètres"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Supprimer System UI Tuner des paramètres et arrêter d\'utiliser toutes ses fonctionnalités ?"</string> </resources> diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml index 631c74bd004a..a67f5a7e2d43 100644 --- a/packages/SystemUI/res/values-gl-rES/strings.xml +++ b/packages/SystemUI/res/values-gl-rES/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é o cadro de diálogo de volume"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar o orixinal."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Estás usando o perfil de traballo"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Sintonizador da interface de usuario do sistema"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Configurador da IU do sistema"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentaxe de batería inserida"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar porcentaxe do nivel de batería na icona da barra de estado cando non está en carga"</string> <string name="quick_settings" msgid="10042998191725428">"Configuración rápida"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Configuración rápida: <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Zona wifi"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Perfil de traballo"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Diversión só para algúns"</string> + <string name="tuner_warning" msgid="8730648121973575701">"O configurador da IU do sistema ofréceche formas adicionais de modificar e personalizar a interface de usuario de Android. Estas funcións experimentais poden cambiar, interromperse ou desaparecer en futuras versións. Continúa con precaución."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Estas funcións experimentais poden cambiar, interromperse ou desaparecer en futuras versións. Continúa con precaución."</string> + <string name="got_it" msgid="2239653834387972602">"De acordo"</string> + <string name="tuner_toast" msgid="603429811084428439">"Parabéns! O configurador da IU do sistema engadiuse a Configuración"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Eliminar da Configuración"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Queres eliminar o configurador da IU do sistema da Configuración e deixar de usar todas as súas funcións?"</string> </resources> diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml index ca40c90bce1d..fb71e6e00afb 100644 --- a/packages/SystemUI/res/values-gu-rIN/strings.xml +++ b/packages/SystemUI/res/values-gu-rIN/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> એ વૉલ્યૂમ સંવાદ છે"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"મૂળને પુનઃસ્થાપિત કરવા માટે ટચ કરો."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"તમે તમારી કાર્ય પ્રોફાઇલનો ઉપયોગ કરી રહ્યાં છો"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"સિસ્ટમ UI ટ્યૂનર"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"સિસ્ટમ UI ટ્યૂનર"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"એમ્બેડ કરેલ બૅટરી ટકા બતાવો"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"જ્યારે ચાર્જ ન થઈ રહ્યું હોય ત્યારે સ્થિતિ બાર આયકનની અંદર બૅટરી સ્તર ટકા બતાવો"</string> <string name="quick_settings" msgid="10042998191725428">"ઝડપી સેટિંગ્સ"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"ઝડપી સેટિંગ્સ, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"હોટસ્પોટ"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"કાર્ય પ્રોફાઇલ"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"કેટલાક માટે મજા પરંતુ બધા માટે નહીં"</string> + <string name="tuner_warning" msgid="8730648121973575701">"સિસ્ટમ UI ટ્યૂનર તમને Android વપરાશકર્તા ઇન્ટરફેસને ટ્વીક અને કસ્ટમાઇઝ કરવાની વધારાની રીતો આપે છે. ભાવિ રીલિઝેસમાં આ પ્રાયોગિક સુવિધાઓ બદલાઈ, ભંગ અથવા અદૃશ્ય થઈ શકે છે. સાવધાની સાથે આગળ વધો."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ભાવિ રીલિઝેસમાં આ પ્રાયોગિક સુવિધાઓ બદલાઈ, ભંગ અથવા અદૃશ્ય થઈ શકે છે. સાવધાની સાથે આગળ વધો."</string> + <string name="got_it" msgid="2239653834387972602">"સમજાઈ ગયું"</string> + <string name="tuner_toast" msgid="603429811084428439">"અભિનંદન! સિસ્ટમ UI ટ્યૂનરને સેટિંગ્સમાં ઉમેરવામાં આવ્યું છે"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"સેટિંગ્સમાંથી દૂર કરો"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"સેટિંગ્સમાંથી સિસ્ટમ UI ટ્યૂનર દૂર કરી અને તેની તમામ સુવિધાઓનો ઉપયોગ કરવાનું બંધ કરીએ?"</string> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index c2ff32ace2e5..aac17253f7b5 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -41,7 +41,7 @@ <string name="battery_low_why" msgid="4553600287639198111">"सेटिंग"</string> <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"बैटरी बचतकर्ता चालू करें?"</string> <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"चालू करें"</string> - <string name="battery_saver_start_action" msgid="5576697451677486320">"बैटरी बचतकर्ता को चालू करें"</string> + <string name="battery_saver_start_action" msgid="5576697451677486320">"बैटरी बचाएँ"</string> <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"सेटिंग"</string> <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"वाई-फ़ाई"</string> <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"स्क्रीन अपनेआप घुमाएं"</string> @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> वॉल्यूम संवाद है"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"मूल वॉल्यूम को फिर से लाने के लिए स्पर्श करें."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"आप अपनी कार्य प्रोफ़ाइल का उपयोग कर रहे हैं"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI ट्यूनर"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"सिस्टम UI ट्यूनर"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"एम्बेड किया गया बैटरी प्रतिशत दिखाएं"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"जब चार्ज नहीं किया जा रहा हो तब स्थिति बार आइकन में बैटरी स्तर का प्रतिशत दिखाएं"</string> <string name="quick_settings" msgid="10042998191725428">"तेज़ सेटिंग"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"तेज़ सेटिंग, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"हॉटस्पॉट"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"कार्य प्रोफ़ाइल"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"कुछ के लिए मज़ेदार लेकिन सबके लिए नहीं"</string> + <string name="tuner_warning" msgid="8730648121973575701">"सिस्टम UI ट्यूनर आपको Android उपयोगकर्ता इंटरफ़ेस में सुधार करने और उसे कस्टमाइज़ करने के अतिरिक्त तरीके प्रदान करता है. ये प्रयोगात्मक सुविधाएं आगामी रिलीज़ में बदल सकती हैं, रुक सकती हैं या दिखाई देना बंद हो सकती हैं. सावधानी से आगे बढ़ें."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ये प्रयोगात्मक सुविधाएं आगामी रिलीज़ में बदल सकती हैं, रुक सकती हैं या दिखाई देना बंद हो सकती हैं. सावधानी से आगे बढ़ें."</string> + <string name="got_it" msgid="2239653834387972602">"समझ लिया"</string> + <string name="tuner_toast" msgid="603429811084428439">"बधाई हो! सिस्टम UI ट्यूनर को सेटिंग में जोड़ दिया गया है"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"सेटिंग से निकालें"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"सेटिंग से सिस्टम UI ट्यूनर निकालें और इसकी सभी सुविधाओं का उपयोग रोक दें?"</string> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 468cdb752617..85e9eff7b575 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -399,7 +399,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> predstavlja dijaloški okvir za upravljanje glasnoćom"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Dodirnite da biste vratili izvorno."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Upotrebljavate radni profil"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Prijamnik korisničkog sučelja sustava"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Ugađanje korisničkog sučelja sustava"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Prikaži ugrađeni postotak baterije"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prikazivanje postotka razine baterije na ikoni trake statusa kada se ne puni"</string> <string name="quick_settings" msgid="10042998191725428">"Brze postavke"</string> @@ -420,4 +420,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Brze postavke, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Žarišna točka"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Radni profil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Zabava za neke, ali ne za sve"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Ugađanje korisničkog sučelja sustava pruža vam dodatne načine za prilagodbu korisničkog sučelja Androida. Te se eksperimentalne značajke mogu promijeniti, prekinuti ili nestati u budućim izdanjima. Nastavite uz oprez."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Te se eksperimentalne značajke mogu promijeniti, prekinuti ili nestati u budućim izdanjima. Nastavite uz oprez."</string> + <string name="got_it" msgid="2239653834387972602">"Shvaćam"</string> + <string name="tuner_toast" msgid="603429811084428439">"Čestitamo! Ugađanje korisničkog sučelja sustava dodano je u Postavke"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Ukloni iz Postavki"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Želite li ukloniti Ugađanje korisničkog sučelja sustava iz Postavki i prestati upotrebljavati njegove značajke?"</string> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index f72833f91647..3b34d19837b0 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás kezeli a hangerőt"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Érintse meg az eredeti érték visszaállításához."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"A munkaprofilt használja"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Kezelőfelület-hangoló"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Kezelőfelület-hangoló"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"A beépített akkumulátor töltöttségi szintjének megjelenítése"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Az akkumulátor töltöttségi szintjének megjelenítése az állapotsori ikonban, amikor az eszköz nem töltődik"</string> <string name="quick_settings" msgid="10042998191725428">"Gyorsbeállítások"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Gyorsbeállítások – <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Munkaprofil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Egyeseknek tetszik, másoknak nem"</string> + <string name="tuner_warning" msgid="8730648121973575701">"A Kezelőfelület-hangoló az Android felhasználói felületének szerkesztéséhez és testreszabásához nyújt további megoldásokat. Ezek a kísérleti funkciók változhatnak vagy megsérülhetnek a későbbi kiadásokban,illetve eltűnhetnek azokból. Körültekintően járjon el."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ezek a kísérleti funkciók változhatnak vagy megsérülhetnek a későbbi kiadásokban, illetve eltűnhetnek azokból. Körültekintően járjon el."</string> + <string name="got_it" msgid="2239653834387972602">"Értem"</string> + <string name="tuner_toast" msgid="603429811084428439">"Gratulálunk! A Kezelőfelület-hangolót hozzáadtuk a Beállításokhoz"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Eltávolítás a Beállítások közül"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Eltávolítja a Kezelőfelület-hangolót a Beállításokból, és nem használja tovább egyik funkcióját sem?"</string> </resources> diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml index 0a88ddef2b62..beefa8ec52b5 100644 --- a/packages/SystemUI/res/values-hy-rAM/strings.xml +++ b/packages/SystemUI/res/values-hy-rAM/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը ձայնի ուժգնության երկխոսության հավելված է"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Դիպչեք՝ սկզբնօրինակը վերականգնելու համար:"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Դուք օգտագործում եք ձեր աշխատանքային պրոֆիլը"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Համակարգի ՕՄ-ի կարգավորիչ"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Համակարգի ՕՄ-ի կարգավորիչ"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Ցուցադրել ներկառուցված մարտկոցի տոկոսայնությունը"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Ցուցադրել մարտկոցի լիցքավորման տոկոսայնությունը կարգավիճակի գոտու պատկերակի վրա, երբ այն չի լիցքավորվում"</string> <string name="quick_settings" msgid="10042998191725428">"Արագ կարգավորումներ"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Արագ կարգավորումներ, <xliff:g id="TITLE">%s</xliff:g>:"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Թեժ կետ"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Աշխատանքային պրոֆիլ"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Զվարճանք մեկ՝ որոշակի մարդու համար"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Համակարգի ՕՄ-ի կարգավորիչը հնարավորություն է տալիս հարմարեցնել Android-ի օգտվողի միջերեսը: Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Այս փորձնական գործառույթները կարող են հետագա թողարկումների մեջ փոփոխվել, խափանվել կամ ընդհանրապես չհայտնվել: Եթե շարունակում եք, զգուշացեք:"</string> + <string name="got_it" msgid="2239653834387972602">"Հասկանալի է"</string> + <string name="tuner_toast" msgid="603429811084428439">"Համակարգի ՕՄ-ի կարգավորիչը ավելացվել է կարգավորումներին"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Հեռացնել կարգավորումներից"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Հեռացնե՞լ Համակարգի ՕՄ-ի կարգավորիչը կարգավորումներից և չօգտվել այլևս նրա գործառույթներից:"</string> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index e8d3d43d9441..f1d2907ef613 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> adalah dialog volume"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Sentuh untuk memulihkan aslinya."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Anda menggunakan profil kerja"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Penyetel Antarmuka Sistem"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Penyetel Antarmuka Pengguna Sistem"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Tampilkan persentase baterai yang tersemat"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Tampilkan persentase tingkat baterai dalam ikon bilah status saat tidak mengisi daya"</string> <string name="quick_settings" msgid="10042998191725428">"Setelan Cepat"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Setelan Cepat, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profil kerja"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Tidak semua orang menganggapnya baik"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Penyetel Antarmuka Pengguna Sistem memberikan cara tambahan untuk mengubah dan menyesuaikan antarmuka pengguna Android. Fitur eksperimental ini dapat berubah, rusak, atau menghilang dalam rilis di masa mendatang. Lanjutkan dengan hati-hati."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Fitur eksperimental ini dapat berubah, rusak, atau menghilang dalam rilis di masa mendatang. Lanjutkan dengan hati-hati."</string> + <string name="got_it" msgid="2239653834387972602">"Mengerti"</string> + <string name="tuner_toast" msgid="603429811084428439">"Selamat! Penyetel Antarmuka Pengguna Sistem telah ditambahkan ke Setelan"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Hapus dari Setelan"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Hapus Penyetel Antarmuka Pengguna Sistem dari Setelan dan berhenti menggunakan semua fiturnya?"</string> </resources> diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml index 3d42bc70c499..b9867836017c 100644 --- a/packages/SystemUI/res/values-is-rIS/strings.xml +++ b/packages/SystemUI/res/values-is-rIS/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er hljóðstyrksvalmyndin"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Snertu til að færa í upprunalegt horf."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Þú ert að nota vinnusniðið"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Fínstillingar kerfisviðmóts"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Fínstillingar kerfisviðmóts"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Sýna innfellda rafhlöðustöðu"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Sýna rafhlöðustöðuna í stöðustikunni þegar tækið er ekki í hleðslu"</string> <string name="quick_settings" msgid="10042998191725428">"Flýtistillingar"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Flýtistillingar, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Heitur reitur"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Vinnusnið"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Þetta er ekki allra"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Fínstillingar kerfisviðmóts gera þér kleift að fínstilla og sérsníða notendaviðmót Android. Þessir tilraunaeiginleikar geta breyst, bilað eða horfið í síðari útgáfum. Gakktu því hægt um gleðinnar dyr."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Þessir tilraunaeiginleikar geta breyst, bilað eða horfið í síðari útgáfum. Gakktu því hægt um gleðinnar dyr."</string> + <string name="got_it" msgid="2239653834387972602">"Ég skil"</string> + <string name="tuner_toast" msgid="603429811084428439">"Til hamingju! Fínstillingum kerfisviðmóts hefur verið bætt við stillingar"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Fjarlægja úr stillingum"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Viltu fjarlægja fínstillingar kerfisviðmóts úr stillingum og hætta að nota eiginleika þeirra?"</string> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 26457f355f12..461db5381421 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> rappresenta la finestra di dialogo relativa al volume"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Tocca per ripristinare l\'originale."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Stai utilizzando il profilo di lavoro"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Sintonizzatore UI sistema"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Sintetizzatore interfaccia utente di sistema"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Mostra percentuale batteria incorporata"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostra la percentuale di carica della batteria nell\'icona della barra di stato quando non è in carica"</string> <string name="quick_settings" msgid="10042998191725428">"Impostazioni rapide"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Impostazioni rapide: <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profilo di lavoro"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Il divertimento riservato a pochi eletti"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Il sintetizzatore interfaccia utente di sistema mette a disposizione altri metodi per modificare e personalizzare l\'interfaccia utente di Android. Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Queste funzioni sperimentali potrebbero cambiare, interrompersi o scomparire nelle versioni successive. Procedi con cautela."</string> + <string name="got_it" msgid="2239653834387972602">"OK"</string> + <string name="tuner_toast" msgid="603429811084428439">"Complimenti! Il sintetizzatore interfaccia utente di sistema è stato aggiunto alle impostazioni."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Rimuovi dalle impostazioni"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vuoi rimuovere il sintetizzatore interfaccia utente di sistema dalle impostazioni e smettere di utilizzare tutte le sue funzioni?"</string> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 92adc90f6f47..8893bec55bf4 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> הוא תיבת הדו-שיח של עוצמת הקול"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"גע כדי לשחזר את עוצמת הקול המקורית."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"אתה משתמש בפרופיל העבודה שלך"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"SystemUI Tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"הצג בשורת הסטטוס את אחוז עוצמת הסוללה"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"הצג את אחוז עוצמת הסוללה בתוך הסמל שבשורת הסטטוס כשהמכשיר אינו בטעינה"</string> <string name="quick_settings" msgid="10042998191725428">"הגדרות מהירות"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"הגדרות מהירות, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"נקודה לשיתוף אינטרנט"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"פרופיל עבודה"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"מהנה בשביל חלק מהאנשים, אבל לא בשביל כולם"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner מספק לך דרכים נוספות להתאים אישית את ממשק המשתמש של Android. התכונות הניסיוניות האלה עשויות להשתנות, להתקלקל או להיעלם בגרסאות עתידיות. המשך בזהירות."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"התכונות הניסיוניות האלה עשויות להשתנות, להתקלקל או להיעלם בגרסאות עתידיות. המשך בזהירות."</string> + <string name="got_it" msgid="2239653834387972602">"הבנתי"</string> + <string name="tuner_toast" msgid="603429811084428439">"מזל טוב! System UI Tuner נוסף ל\'הגדרות\'"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"הסר מההגדרות"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"האם להסיר את System UI Tuner ולהפסיק להשתמש בכל התכונות שלו?"</string> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index b8b4d3b1b4b3..260a92b46173 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>を音量ダイアログとして使用"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"タップすると元の音量ダイアログが復元されます。"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"仕事用プロファイルを使用しています"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"システムUI調整ツール"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"内蔵電池の残量の割合を表示する"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"充電していないときには電池残量の割合をステータスバーアイコンに表示する"</string> <string name="quick_settings" msgid="10042998191725428">"クイック設定"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"クイック設定、<xliff:g id="TITLE">%s</xliff:g>。"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"アクセスポイント"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"仕事用プロファイル"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"一部の方のみお楽しみいただける限定公開ツール"</string> + <string name="tuner_warning" msgid="8730648121973575701">"システムUI調整ツールでは、Androidユーザーインターフェースの調整やカスタマイズを行えます。これらの試験運用機能は今後のリリースで変更となったり、中止となったり、削除されたりする可能性がありますのでご注意ください。"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"これらの試験運用機能は今後のリリースで変更となったり、中止となったり、削除されたりする可能性がありますのでご注意ください。"</string> + <string name="got_it" msgid="2239653834387972602">"OK"</string> + <string name="tuner_toast" msgid="603429811084428439">"システムUI調整ツールを設定に追加しました"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"設定から削除"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"設定からシステムUI調整ツールを削除して、全機能の使用を停止しますか?"</string> </resources> diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml index 8576371e8015..54f545d88b9a 100644 --- a/packages/SystemUI/res/values-ka-rGE/strings.xml +++ b/packages/SystemUI/res/values-ka-rGE/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ხმოვან დიალოგშია"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"ორიგინალის აღდგენისათვის, შეეხეთ."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"თქვენ სამსახურის პროფილს იყენებთ"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI ტუნერი"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"სისტემის UI ტუნერი"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"ჩამაგრებული ბატარეის პროცენტის ჩვენება"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ბატარეის დონის პროცენტის ჩვენება სტატუსის ზოლის ხატულას შიგნით, როდესაც არ იტენება"</string> <string name="quick_settings" msgid="10042998191725428">"სწრაფი პარამეტრები"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"სწრაფი პარამეტრები, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"წვდომის წერტილი"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"სამსახურის პროფილი"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"ზოგისთვის გასართობია, მაგრამ არა ყველასთვის"</string> + <string name="tuner_warning" msgid="8730648121973575701">"სისტემის UI ტუნერი გაძლევთ დამატებით გზებს Android-ის სამომხმარებლო ინტერფეისის პარამეტრების დაყენებისთვის. ეს ექსპერიმენტული მახასიათებლები შეიძლება შეიცვალოს, შეწყდეს ან გაქრეს მომავალ ვერსიებში. სიფრთხილით გააგრძელეთ."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ეს ექსპერიმენტული მახასიათებლები შეიძლება შეიცვალოს, შეწყდეს ან გაქრეს მომავალ ვერსიებში. სიფრთხილით გააგრძელეთ."</string> + <string name="got_it" msgid="2239653834387972602">"გასაგებია"</string> + <string name="tuner_toast" msgid="603429811084428439">"გილოცავთ! სისტემის UI ტუნერი დაემატა პარამეტრებს"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"პარამეტრებიდან წაშლა"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"გსურთ სისტემის UI ტუნერის პარამეტრებიდან წაშლა და მისი ყველა ფუნქციის გამოყენების შეწყვეტა?"</string> </resources> diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml index 43fa4dce6c53..e80c03ada277 100644 --- a/packages/SystemUI/res/values-kk-rKZ/strings.xml +++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> — көлем диалогтық терезесі"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Түпнұсқаны қалпына келтіру үшін түртіңіз."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Сіз жұмыс профиліңізді пайдаланып жатырсыз"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Жүйе интерфейсінің тюнері"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Жүйелік пайдаланушылық интерфейс тюнері"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Ендірілген батарея пайыздық шамасын көрсету"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Зарядталмай тұрғанда, күй жолағы белгішесінің ішінде батарея деңгейінің пайыздық шамасын көрсетеді"</string> <string name="quick_settings" msgid="10042998191725428">"Жылдам параметрлер"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Жылдам параметрлер, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Хот-спот"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Жұмыс профилі"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Кейбіреулерге қызық, бірақ барлығына емес"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Жүйелік пайдаланушылық интерфейс тюнері Android пайдаланушылық интерфейсін реттеудің қосымша жолдарын береді. Бұл эксперименттік мүмкіндіктер болашақ шығарылымдарда өзгеруі, бұзылуы немесе жоғалуы мүмкін. Сақтықпен жалғастырыңыз."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Бұл эксперименттік мүмкіндіктер болашақ шығарылымдарда өзгеруі, бұзылуы немесе жоғалуы мүмкін. Сақтықпен жалғастырыңыз."</string> + <string name="got_it" msgid="2239653834387972602">"Түсіндім"</string> + <string name="tuner_toast" msgid="603429811084428439">"Құттықтаймыз! Жүйелік пайдаланушылық интерфейс тюнері \"Параметрлер\" тармағына қосылды"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Параметрлерден жою"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Жүйелік пайдаланушылық интерфейс тюнерін \"Параметрлер\" тармағынан жойып, оның барлық мүмкіндіктерін пайдалануды тоқтату керек пе?"</string> </resources> diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml index 081fc4445d2c..df3dfb797485 100644 --- a/packages/SystemUI/res/values-km-rKH/strings.xml +++ b/packages/SystemUI/res/values-km-rKH/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> គឺជាប្រអប់សម្លេង"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"ប៉ះដើម្បីស្តារច្បាប់ដើម។"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"អ្នកកំពុងប្រើប្រវត្តិរូបការងាររបស់អ្នក"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"ឧបករណ៍ចាប់ SystemUI"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"កម្មវិធីសម្រួល UI ប្រព័ន្ធ"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"បង្ហាញភាគរយថាមពលថ្មដែលបានបង្កប់"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"បង្ហាញភាគរយនៃកម្រិតថាមពលថ្មនៅក្នុងរូបតំណាងរបារស្ថានភាពនៅពេលមិនសាកថ្ម"</string> <string name="quick_settings" msgid="10042998191725428">"ការកំណត់រហ័ស"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"ការកំណត់រហ័ស <xliff:g id="TITLE">%s</xliff:g>។"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ហតស្ប៉ត"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"ប្រវត្តិរូបការងារ"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"ល្អសម្រាប់អ្នកប្រើមួយចំនួន តែមិនសម្រាប់គ្រប់គ្នាទេ"</string> + <string name="tuner_warning" msgid="8730648121973575701">"កម្មវិធីសម្រួល UI ប្រព័ន្ធផ្តល់ជូនអ្នកនូវមធ្យោបាយបន្ថែមទៀតដើម្បីកែសម្រួល និងប្តូរចំណុចប្រទាក់អ្នកប្រើ Android តាមបំណង។ លក្ខណៈពិសេសសាកល្បងនេះអាចនឹងផ្លាស់ប្តូរ បំបែក ឬបាត់បង់បន្ទាប់ពីការចេញផ្សាយនាពេលអនាគត។ សូមបន្តដោយប្រុងប្រយ័ត្ន។"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"លក្ខណៈពិសេសសាកល្បងនេះអាចនឹងផ្លាស់ប្តូរ បំបែក ឬបាត់បង់បន្ទាប់ពីការចេញផ្សាយនាពេលអនាគត។ សូមបន្តដោយប្រុងប្រយ័ត្ន។"</string> + <string name="got_it" msgid="2239653834387972602">"យល់ហើយ"</string> + <string name="tuner_toast" msgid="603429811084428439">"សូមអបអរសាទរ! កម្មវិធីសម្រួល UI ប្រព័ន្ធត្រូវបានបន្ថែមទៅការកំណត់ហើយ"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"យកចេញពីការកំណត់"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"យកកម្មវិធីសម្រួល UI ប្រព័ន្ធចេញពីការកំណត់ ហើយឈប់ប្រើលក្ខណៈពិសេសរបស់វាទាំងអស់?"</string> </resources> diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml index 75a8c9135503..6033303593da 100644 --- a/packages/SystemUI/res/values-kn-rIN/strings.xml +++ b/packages/SystemUI/res/values-kn-rIN/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ವಾಲ್ಯೂಮ್ ಸಂವಾದವಾಗಿದೆ"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"ಮೂಲ ಮರುಸ್ಥಾಪಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ನಿಮ್ಮ ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ನೀವು ಬಳಸುತ್ತಿರುವಿರಿ"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"ಎಂಬೆಡ್ ಮಾಡಲಾದ ಬ್ಯಾಟರಿ ಶೇಕಡಾ ತೋರಿಸಿ"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ಚಾರ್ಜ್ ಮಾಡದಿರುವಾಗ ಸ್ಥಿತಿ ಪಟ್ಟಿ ಐಕಾನ್ ಒಳಗೆ ಬ್ಯಾಟರಿ ಮಟ್ಟದ ಶೇಕಡಾವನ್ನು ತೋರಿಸಿ"</string> <string name="quick_settings" msgid="10042998191725428">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳು, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ಹಾಟ್ಸ್ಪಾಟ್"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"ಕೆಲವರಿಗೆ ಮೋಜು ಆಗಿದೆ ಎಲ್ಲರಿಗೆ ಇಲ್ಲ"</string> + <string name="tuner_warning" msgid="8730648121973575701">"ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್ ನಿಮಗೆ Android ಬಳಕೆದಾರ ಅಂತರಸಂಪರ್ಕವನ್ನು ಸರಿಪಡಿಸಲು ಮತ್ತು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಹೆಚ್ಚುವರಿ ಮಾರ್ಗಗಳನ್ನು ನೀಡುತ್ತದೆ. ಈ ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯಗಳು ಭವಿಷ್ಯದ ಬಿಡುಗಡೆಗಳಲ್ಲಿ ಬದಲಾಗಬಹುದು, ವಿರಾಮವಾಗಬಹುದು ಅಥವಾ ಕಾಣಿಸಿಕೊಳ್ಳದಿರಬಹುದು. ಎಚ್ಚರಿಕೆಯಿಂದ ಮುಂದುವರಿಯಿರಿ."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ಈ ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯಗಳು ಭವಿಷ್ಯದ ಬಿಡುಗಡೆಗಳಲ್ಲಿ ಬದಲಾಗಬಹುದು, ವಿರಾಮವಾಗಬಹುದು ಅಥವಾ ಕಾಣಿಸಿಕೊಳ್ಳದಿರಬಹುದು. ಎಚ್ಚರಿಕೆಯಿಂದ ಮುಂದುವರಿಯಿರಿ."</string> + <string name="got_it" msgid="2239653834387972602">"ಅರ್ಥವಾಯಿತು"</string> + <string name="tuner_toast" msgid="603429811084428439">"ಅಭಿನಂದನೆಗಳು! ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್ ಅನ್ನು ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಸೇರಿಸಲಾಗಿದೆ"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"ಸೆಟ್ಟಿಂಗ್ಗಳಿಂದ ತೆಗೆದುಹಾಕಿ"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"ಸೆಟ್ಟಿಂಗ್ಗಳಿಂದ ಸಿಸ್ಟಮ್ UI ಟ್ಯೂನರ್ ತೆಗೆದುಹಾಕುವುದೇ ಮತ್ತು ಅದರ ಎಲ್ಲಾ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಬಳಸುವುದನ್ನು ನಿಲ್ಲಿಸುವುದೇ?"</string> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index ab299e8cd9cf..21796d0ae733 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>은(는) 볼륨 대화입니다."</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"원본을 복원하려면 터치하세요."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"직장 프로필을 사용하고 있습니다."</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"시스템 UI 튜너"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"시스템 UI 튜너"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"내장형 배터리 잔량 비율 표시"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"충전 중이 아닌 경우 상태 표시줄 아이콘 내에 배터리 잔량 비율 표시"</string> <string name="quick_settings" msgid="10042998191725428">"빠른 설정"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"빠른 설정하기, <xliff:g id="TITLE">%s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"핫스팟"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"직장 프로필"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"마음에 들지 않을 수도 있음"</string> + <string name="tuner_warning" msgid="8730648121973575701">"시스템 UI 튜너를 사용하면 Android 사용자 인터페이스를 변경 및 맞춤설정할 수 있습니다. 이러한 실험실 기능은 향후 출시 버전에서는 변경되거나 다운되거나 사라질 수 있습니다. 신중하게 진행하시기 바랍니다."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"이러한 실험실 기능은 향후 출시 버전에서는 변경되거나 다운되거나 사라질 수 있습니다. 신중하게 진행하시기 바랍니다."</string> + <string name="got_it" msgid="2239653834387972602">"확인"</string> + <string name="tuner_toast" msgid="603429811084428439">"축하합니다. 시스템 UI 튜너가 설정에 추가되었습니다."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"설정에서 삭제"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"시스템 UI 튜너를 설정에서 삭제하고 모든 관련 기능의 사용을 중지하시겠습니까?"</string> </resources> diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml index ce82331d95fa..44ccbac49aea 100644 --- a/packages/SystemUI/res/values-ky-rKG/strings.xml +++ b/packages/SystemUI/res/values-ky-rKG/strings.xml @@ -423,7 +423,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> үндү катуулатуу диалогу"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Түпнусканы калыбына келтирүү үчүн тийип коюңуз."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Жумуш профилиңизди колдонуп жатасыз"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"SystemUI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Батарянын кубатнын деңгээли пайыз менен көрсөтлсүн"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Түзмөк кубаттанбай турганда, батареянын деңгээли статус тилкесинде көрүнүп турат"</string> <string name="quick_settings" msgid="10042998191725428">"Ыкчам жөндөөлөр"</string> @@ -444,4 +444,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Ыкчам жөндөөлөр, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Туташуу чекити"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Жумуш профили"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Баарына эле жага бербейт"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner Android колдонуучу интерфейсин жөнгө салып жана ыңгайлаштыруунун кошумча ыкмаларын сунуштайт. Бул сынамык функциялар кийинки чыгарылыштарда өзгөрүлүп, бузулуп же жоголуп кетиши мүмкүн. Абайлап колдонуңуз."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Бул сынамык функциялар кийинки чыгарылыштарда өзгөрүлүп, бузулуп же жоголуп кетиши мүмкүн. Абайлап колдонуңуз."</string> + <string name="got_it" msgid="2239653834387972602">"Түшүндүм"</string> + <string name="tuner_toast" msgid="603429811084428439">"Куттуктайбыз! Жөндөөлөргө System UI Tuner кошулду"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Жөндөөлөрдөн алып салуу"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner Жөндөөлөрдөн алынып салынып, анын бардык функциялары токтотулсунбу?"</string> </resources> diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml index b76dc587fce8..0d33dcbd3539 100644 --- a/packages/SystemUI/res/values-lo-rLA/strings.xml +++ b/packages/SystemUI/res/values-lo-rLA/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ແມ່ນໜ້າຕ່າງລະດັບສຽງ"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"ສໍາຜັດເພື່ອກູ້ຄືນຕົ້ນສະບັບ."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ທ່ານກຳລັງໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານ"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"ຕົວປັບ UI ລະບົບ"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"ສະແດງເປີເຊັນແບັດເຕີຣີທີ່ຕິດມາ"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ສະແດງເປີເຊັນລະດັບແບັດເຕີຣີຢູ່ດ້ານໃນໄອຄອນແຖບສະຖານະ ເມື່ອບໍ່ສາກຢູ່"</string> <string name="quick_settings" msgid="10042998191725428">"ການຕັ້ງຄ່າດ່ວນ"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"ການຕັ້ງຄ່າດ່ວນ, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ຮັອດສະປອດ"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"ມ່ວນຊື່ນສຳລັບບາງຄົນ ແຕ່ບໍ່ແມ່ນສຳລັບທຸກຄົນ"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner ໃຫ້ທ່ານມີວິທີພິເສດຕື່ມອີກໃນການປັບປ່ຽນ ແລະຕົບແຕ່ງສ່ວນຕໍ່ປະສານຜູ້ໃຊ້ຂອງ Android. ຄຸນສົມບັດທົດລອງໃຊ້ເຫຼົ່ານີ້ອາດຈະປ່ຽນແປງ, ຢຸດເຊົາ ຫຼືຫາຍໄປໃນການວາງຈຳໜ່າຍໃນອະນາຄົດ. ຈົ່ງດຳເນີນຕໍ່ດ້ວຍຄວາມລະມັດລະວັງ."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ຄຸນສົມບັດທົດລອງໃຊ້ງານເຫຼົ່ານີ້ອາດຈະປ່ຽນແປງ, ຢຸດເຊົາ ຫຼືຫາຍໄປໃນການອອກຈຳໜ່າຍໃນອະນາຄົດ. ຈົ່ງສືບຕໍ່ດ້ວຍຄວາມລະມັດລະວັງ."</string> + <string name="got_it" msgid="2239653834387972602">"ໄດ້ແລ້ວ"</string> + <string name="tuner_toast" msgid="603429811084428439">"ຍິນດີດ້ວຍ! System UI Tuner ໄດ້ຖືກເພີ່ມໃສ່ການຕັ້ງຄ່າແລ້ວ"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"ເອົາອອກຈາກການຕັ້ງຄ່າ"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"ເອົາ System UI Tuner ອອກຈາກການຕັ້ງຄ່າ ແລະຢຸດການໃຊ້ທຸກຄຸນສົມບັດໃຊ້ງານຂອງມັນ?"</string> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 34f0ea0f6d68..54ee52ce7fe5 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ yra garsumo valdymo dialogo langas"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Palieskite, kad atkurtumėte originalą."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Naudojate darbo profilį"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Sistemos naudotojo sąsajos derinimo priemonė"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Sistemos naudotojo sąsajos derinimo priemonė"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Rodyti įterptą akumuliat. įkrovos procentinę vertę"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Rodyti akumuliatoriaus įkrovos lygio procentinę vertę būsenos juostos piktogramoje, kai įrenginys nėra įkraunamas"</string> <string name="quick_settings" msgid="10042998191725428">"Spartieji nustatymai"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Spartieji nustatymai, „<xliff:g id="TITLE">%s</xliff:g>“."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Viešosios interneto prieigos taškas"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Darbo profilis"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Smagu, bet ne visada"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Sistemos naudotojo sąsajos derinimo priemonė suteikia papildomų galimybių pagerinti ir tinkinti „Android“ naudotojo sąsają. Šios eksperimentinės funkcijos gali pasikeisti, nutrūkti ar išnykti iš būsimų laidų. Tęskite atsargiai."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Šios eksperimentinės funkcijos gali pasikeisti, nutrūkti ar išnykti iš būsimų laidų. Tęskite atsargiai."</string> + <string name="got_it" msgid="2239653834387972602">"Supratau"</string> + <string name="tuner_toast" msgid="603429811084428439">"Sveikiname! Sistemos naudotojo sąsajos derinimo priemonė pridėta prie nustatymų"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Pašalinti iš nustatymų"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Ar norite pašalinti sistemos naudotojo sąsajos derinimo priemonę iš nustatymų ir nebenaudoti jokių jos funkcijų?"</string> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 1fa26eda8487..4e699e3de152 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -399,7 +399,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ir skaļuma dialoglodziņš"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Pieskarieties, lai atjaunotu sākotnējo."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Jūs izmantojat darba profilu."</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Sistēmas saskarnes regulators"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Sistēmas saskarnes regulators"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Rādīt akumulatora uzlādes līmeni procentos"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Rādīt akumulatora uzlādes līmeni procentos statusa joslas ikonā, kad netiek veikta uzlāde"</string> <string name="quick_settings" msgid="10042998191725428">"Ātrie iestatījumi"</string> @@ -420,4 +420,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Ātrie iestatījumi: <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Tīklājs"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Darba profils"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Jautri dažiem, bet ne visiem"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Sistēmas saskarnes regulators sniedz papildu veidus, kā mainīt un pielāgot Android lietotāja saskarni. Nākamajās versijās šīs eksperimentālās funkcijas var tikt mainītas, bojātas vai to darbība var tikt pārtraukta. Turpinot esiet uzmanīgs."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Nākamajās versijās šīs eksperimentālās funkcijas var tikt mainītas, bojātas vai to darbība var tikt pārtraukta. Turpinot esiet uzmanīgs."</string> + <string name="got_it" msgid="2239653834387972602">"Labi"</string> + <string name="tuner_toast" msgid="603429811084428439">"Apsveicam! Sistēmas saskarnes regulators ir pievienots iestatījumiem."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Noņemt no iestatījumiem"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vai noņemt sistēmas saskarnes regulatoru no iestatījumiem un pārtraukt izmantot visas tā funkcijas?"</string> </resources> diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml index d09ced371251..6a855905082f 100644 --- a/packages/SystemUI/res/values-mk-rMK/strings.xml +++ b/packages/SystemUI/res/values-mk-rMK/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> е дијалог за јачина на звук"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Допрете за да го вратите оригиналот."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Го користите работниот профил"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Дотерување на кориснички интерфејс"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Адаптер на УИ на системот"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Прикажи вграден процент на батеријата"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Прикажи процент на ниво на батеријата во внатрешноста на иконата со статусна лента кога не се полни"</string> <string name="quick_settings" msgid="10042998191725428">"Брзи поставки"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Брзи поставки, <xliff:g id="TITLE">%s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Точка на пристап"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Работен профил"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Забава за некои, но не за сите"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Адаптерот на УИ на системот ви дава дополнителни начини за дотерување и приспособување на корисничкиот интерфејс на Android. Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Овие експериментални функции можеби ќе се изменат, расипат или ќе исчезнат во следните изданија. Продолжете со претпазливост."</string> + <string name="got_it" msgid="2239653834387972602">"Разбрав"</string> + <string name="tuner_toast" msgid="603429811084428439">"Честито! Го додадовте Адаптерот на УИ на системот на Поставки"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Отстрани од поставки"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Да се отстрани Адаптерот на УИ на системот од Поставки и да престанат да се користат сите негови функции?"</string> </resources> diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml index 17e0199c7829..eeb0106e7e5f 100644 --- a/packages/SystemUI/res/values-ml-rIN/strings.xml +++ b/packages/SystemUI/res/values-ml-rIN/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>, വോളിയം ഡയലോഗാണ്"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"ആദ്യത്തേത് പുനഃസ്ഥാപിക്കാൻ സ്പർശിക്കുക."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"നിങ്ങൾ ഉപയോഗിക്കുന്നത് ഔദ്യോഗിക പ്രൊഫൈലാണ്"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI ട്യൂണർ"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"സിസ്റ്റം UI ട്യൂണർ"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"എംബഡ് ചെയ്ത ബാറ്ററി ശതമാനം കാണിക്കുക"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ചാർജ്ജുചെയ്യാതിരിക്കുമ്പോൾ സ്റ്റാറ്റസ് ബാർ ഐക്കണിൽ ബാറ്ററി ലെവൽ ശതമാനം കാണിക്കുക"</string> <string name="quick_settings" msgid="10042998191725428">"ദ്രുത ക്രമീകരണം"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"ദ്രുത ക്രമീകരണം, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ഹോട്ട്സ്പോട്ട്"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"ചിലർക്ക് വിനോദം, എന്നാൽ എല്ലാവർക്കുമില്ല"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Android ഉപയോക്തൃ ഇന്റർഫേസ് ആവശ്യമുള്ള രീതിയിൽ മാറ്റുന്നതിനും ഇഷ്ടാനുസൃതമാക്കുന്നതിനും സിസ്റ്റം UI ട്യൂണർ നിങ്ങൾക്ക് അധിക വഴികൾ നൽകുന്നു. ഭാവി റിലീസുകളിൽ ഈ പരീക്ഷണാത്മക ഫീച്ചറുകൾ മാറ്റുകയോ നിർത്തുകയോ അപ്രത്യക്ഷമാവുകയോ ചെയ്തേക്കാം. ശ്രദ്ധയോടെ മുന്നോട്ടുപോകുക."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ഭാവി റിലീസുകളിൽ ഈ പരീക്ഷണാത്മക ഫീച്ചറുകൾ മാറ്റുകയോ നിർത്തുകയോ അപ്രത്യക്ഷമാവുകയോ ചെയ്തേക്കാം. ശ്രദ്ധയോടെ മുന്നോട്ടുപോകുക."</string> + <string name="got_it" msgid="2239653834387972602">"മനസ്സിലായി"</string> + <string name="tuner_toast" msgid="603429811084428439">"അഭിനന്ദനങ്ങൾ! ക്രമീകരണത്തിലേക്ക് സിസ്റ്റം UI ട്യൂണർ ചേർത്തിരിക്കുന്നു"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"ക്രമീകരണത്തിൽ നിന്ന് നീക്കംചെയ്യുക"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"ക്രമീകരണത്തിൽ നിന്ന് സിസ്റ്റം UI ട്യൂണർ നീക്കംചെയ്യുകയും അതിന്റെ ഫീച്ചറുകളെല്ലാം ഉപയോഗിക്കുന്നത് നിർത്തുകയും ചെയ്യണോ?"</string> </resources> diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml index 7c7aa06477da..5ac85ed99984 100644 --- a/packages/SystemUI/res/values-mn-rMN/strings.xml +++ b/packages/SystemUI/res/values-mn-rMN/strings.xml @@ -396,7 +396,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь дууны диалог юм."</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Анхны хувилбарыг эргүүлэн хадгалахыг хүсвэл хүрнэ үү."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Та өөрийн ажлын профайлыг ашиглаж байна"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Системийн UI Тохируулагч"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Залгаатай тэжээлийн хувийг харуулах"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Тэжээлийн хувийг цэнэглээгүй байх үед статусын хэсэгт харуулна уу"</string> <string name="quick_settings" msgid="10042998191725428">"Түргэвчилсэн Tохиргоо"</string> @@ -417,4 +417,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Түргэн Тохиргоо, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Сүлжээний цэг"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Ажлын профайл"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Зарим хүнд хөгжилтэй байж болох ч бүх хүнд тийм биш"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Системийн UI Tохируулагч нь Android хэрэглэгчийн интерфэйсийг тааруулах, өөрчлөх нэмэлт аргыг зааж өгөх болно. Эдгээр туршилтын тохиргоо нь цаашид өөрчлөгдөх, эвдрэх, алга болох магадлалтай. Үйлдлийг болгоомжтой хийнэ үү."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Эдгээр туршилтын тохиргоо нь цаашид өөрчлөгдөх, эвдрэх, алга болох магадлалтай. Үйлдлийг болгоомжтой хийнэ үү."</string> + <string name="got_it" msgid="2239653834387972602">"Ойлголоо"</string> + <string name="tuner_toast" msgid="603429811084428439">"Баяр хүргэе! Системийн UI Tохируулагчийг тохиргоонд нэмлээ"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Тохиргооноос устгах"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Системийн UI Тохируулагчийг тохиргооноос устгаж, үүнтэй холбоотой бүх тохиргоог ашиглахаа болих уу?"</string> </resources> diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml index e4773b7271c3..eb726eda3d79 100644 --- a/packages/SystemUI/res/values-mr-rIN/strings.xml +++ b/packages/SystemUI/res/values-mr-rIN/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> हा व्हॉल्यूम संवाद आहे"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"मूळ पुनर्संचयित करण्यासाठी स्पर्श करा."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"आपण आपले कार्य प्रोफाईल वापरत आहात"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"सिस्टीम UI ट्यूनर"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"सिस्टीम UI ट्यूनर"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"एम्बेडेड बॅटरी टक्केवारी दर्शवा"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"चार्ज होत नसताना स्टेटस बार चिन्हामध्ये बॅटरी पातळी टक्केवारी दर्शवा"</string> <string name="quick_settings" msgid="10042998191725428">"दृत सेटिंग्ज"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"द्रुत सेटिंग्ज, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"हॉटस्पॉट"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"कार्य प्रोफाईल"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"सर्वांसाठी नाही तर काहींसाठी मजेदार असू शकते"</string> + <string name="tuner_warning" msgid="8730648121973575701">"सिस्टीम UI ट्यूनर आपल्याला Android वापरकर्ता इंटरफेस ट्विक आणि सानुकूल करण्याचे अनेक प्रकार देते. ही प्रयोगात्मक वैशिष्ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्यातील रिलीझ मध्ये कदाचित दिसणार नाहीत. सावधगिरी बाळगून पुढे सुरु ठेवा."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ही प्रयोगात्मक वैशिष्ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्यातील रिलीझ मध्ये कदाचित दिसणार नाहीत."</string> + <string name="got_it" msgid="2239653834387972602">"समजले"</string> + <string name="tuner_toast" msgid="603429811084428439">"अभिनंदन! सिस्टीम UI ट्यूनर सेटिंग्जमध्ये जोडले गेले आहे"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"सेटिंग्ज मधून काढा"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"सेटिंग्ज मधून सिस्टीम UI ट्यूनर काढून त्याची सर्व वैशिष्ट्ये वापरणे थांबवायचे?"</string> </resources> diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml index 3547a724b07c..9caa935f8087 100644 --- a/packages/SystemUI/res/values-ms-rMY/strings.xml +++ b/packages/SystemUI/res/values-ms-rMY/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ialah dialog kelantangan"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Sentuh untuk memulihkan yang asal."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Anda sedang menggunakan profil kerja"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Penala Sistem UI"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Penala UI Sistem"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Tunjukkan peratusan bateri terbenam"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Tunjukkan peratusan aras bateri dalam ikon bar status semasa tidak mengecas"</string> <string name="quick_settings" msgid="10042998191725428">"Tetapan Pantas"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Tetapan Pantas, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Tempat liputan"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profil kerja"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Menarik untuk sesetengah orang tetapi bukan untuk semua"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Penala UI Sistem memberi anda cara tambahan untuk mengolah dan menyesuaikan antara muka Android. Ciri eksperimen ini boleh berubah, rosak atau hilang dalam keluaran masa hadapan. Teruskan dengan berhati-hati."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ciri eksperimen ini boleh berubah, rosak atau hilang dalam keluaran masa hadapan. Teruskan dengan berhati-hati."</string> + <string name="got_it" msgid="2239653834387972602">"Ok"</string> + <string name="tuner_toast" msgid="603429811084428439">"Tahniah! Penala UI Sistem telah ditambahkan pada Tetapan"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Alih keluar daripada Tetapan"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Alih keluar Penala UI Sistem daripada Tetapan dan berhenti menggunakan semua cirinya?"</string> </resources> diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml index 64460f1bb298..0e5622e70a73 100644 --- a/packages/SystemUI/res/values-my-rMM/strings.xml +++ b/packages/SystemUI/res/values-my-rMM/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် အသံဒိုင်ယာလော့ခ်ဖြစ်သည်"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"မူရင်းအားပြန်လည်သိမ်းဆည်းရန် ထိပါ။"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"သင်သည် အလုပ်ပရိုဖိုင်းအား သုံးနေသည်"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"စနစ် UI ဖမ်းစက်"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"မြုတ်ထားသည့် ဘတ်ထရီ ရာခိုင်နှုန်းကို ပြပါ"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"အားမသွင်းနေစဉ်တွင် ဘတ်ထရီအဆင့် ရာခိုင်နှုန်းကို အခြေနေပြဘား အိုင်ကွန်တွင် ပြပါ"</string> <string name="quick_settings" msgid="10042998191725428">"အမြန် ဆက်တင်များ"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"အမြန်ချိန်ညှိခြင်း၊ <xliff:g id="TITLE">%s</xliff:g>။"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ဟော့စပေါ့"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"အလုပ် ပရိုဖိုင်"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"အချို့သူများ အတွက် ပျော်စရာ ဖြစ်ပေမဲ့ အားလုံး အတွက် မဟုတ်ပါ"</string> + <string name="tuner_warning" msgid="8730648121973575701">"စနစ် UI ဖမ်းစက်က သင့်အတွက် Android အသုံးပြုသူ အင်တာဖေ့စ်ကို ပြောင်းကြည့်ရန် နှင့် စိတ်ကြိုက်ပြုလုပ်ရန် နည်းလမ်း အပိုများကို သင့်အတွက် စီစဉ်ပေးသည်။ ဤ စမ်းသပ်ရေး အင်္ဂါရပ်များမှာ ပြောင်းလဲ၊ ကျိုးပျက် သို့မဟုတ် ပျောက်ကွယ် သွားနိုင်သည်။ သတိထားလျက် ဆက်လက် ဆောင်ရွက်ပါ။"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ဤ စမ်းသပ်ရေး အင်္ဂါရပ်များမှာ ပြောင်းလဲ၊ ကျိုးပျက် သို့မဟုတ် ပျောက်ကွယ် သွားနိုင်သည်။ သတိထားလျက် ဆက်လက် ဆောင်ရွက်ပါ။"</string> + <string name="got_it" msgid="2239653834387972602">"ရပါပြီ"</string> + <string name="tuner_toast" msgid="603429811084428439">"ဂုဏ်ပြုပါရစေ! စနစ် UI ဖမ်းစက်ကို ဆက်တင်ထဲသို့ ထည့်ပြီးပြီ။"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"ဆက်တင် အထဲမှ ဖယ်ရှားရန်"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"ဆက်တင် အထဲမှ စနစ် UI ဖမ်းစက်ကို ဖယ်ရှားလျက် ၎င်း၏ အင်္ဂါရပ်များ အားလုံး အသုံးပြုမှု ရပ်တန့်ရမလား?"</string> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 5a0c8e32a332..4c55a9855241 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er volumdialogen"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Trykk for å gå tilbake til den opprinnelige volumdialogen."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du bruker jobbprofilen din"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"SystemUI Tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Vis prosent for det innebygde batteriet"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Vis batterinivåprosenten inni statusfeltikonet når du ikke lader"</string> <string name="quick_settings" msgid="10042998191725428">"Hurtiginnstillinger"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Hurtiginnstillinger, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Wi-Fi-sone"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Work-profil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Gøy for noen – ikke for alle"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Med System UI Tuner har du flere måter å justere og tilpasse Android-brukergrensesnittet på. Disse eksperimentelle funksjonene kan endres, avbrytes eller fjernes i fremtidige utgivelser. Fortsett med forbehold."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Disse eksperimentelle funksjonene kan endres, avbrytes eller fjernes i fremtidige utgivelser. Fortsett med forbehold."</string> + <string name="got_it" msgid="2239653834387972602">"Greit"</string> + <string name="tuner_toast" msgid="603429811084428439">"Gratulerer! System UI Tuner er lagt til i Innstillinger"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Fjern fra Innstillinger"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vil du fjerne System UI Tuner fra Innstillinger og slutte å bruke alle de tilknyttede funksjonene?"</string> </resources> diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml index 0f9d45a588c2..9d5a67995d9e 100644 --- a/packages/SystemUI/res/values-ne-rNP/strings.xml +++ b/packages/SystemUI/res/values-ne-rNP/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> भोल्यूम संवाद हो"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"मूल पुनर्स्थापना गर्न छुनुहोस्।"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"तपाईँले कार्य प्रोफाइल प्रयोग गर्दै हुनुहुन्छ"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"प्रणाली UI ट्युनर"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"प्रणाली UI ट्युनर"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"इम्बेड गरिएको ब्याट्री प्रतिशत देखाउनुहोस्"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"चार्ज नगरेको बेला वस्तुस्थिति पट्टी आइकन भित्र ब्याट्री प्रतिशत स्तर देखाउनुहोस्"</string> <string name="quick_settings" msgid="10042998191725428">"द्रुत सेटिङहरू"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"द्रुत सेटिङ, <xliff:g id="TITLE">%s</xliff:g>।"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"कार्य प्रोफाइल"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"केहीका लागि रमाइलो हुन्छ तर सबैका लागि होइन"</string> + <string name="tuner_warning" msgid="8730648121973575701">"प्रणाली UI ट्युनरले तपाईँलाई Android प्रयोगकर्ता इन्टरफेस अनुकूलन गर्न र ट्विक गर्न थप तरिकाहरू प्रदान गर्छ। यी प्रयोगात्मक सुविधाहरू भावी विमोचनमा परिवर्तन हुन, बिग्रिन वा हराउन सक्ने छन्। सावधानीपूर्वक अगाडि बढ्नुहोस्।"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"यी प्रयोगात्मक सुविधाहरू भावी विमोचनहरूमा परिवर्तन हुन, बिग्रन वा हराउन सक्छन्। सावधानीपूर्वक अगाडि बढ्नुहोस्।"</string> + <string name="got_it" msgid="2239653834387972602">"बुझेँ"</string> + <string name="tuner_toast" msgid="603429811084428439">"बधाईँ छ! सेटिङहरूमा प्रणाली UI ट्युनर थप गरिएको छ"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"सेटिङहरूबाट हटाउनुहोस्"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"प्रणाली UI ट्युनर सेटिङहरूबाट हटाउने र यसका सबै सुविधाहरू प्रयोग गर्न रोक्ने हो?"</string> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index de4ac48d3492..33a8bdf76c53 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is het volumedialoogvenster"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Tik hierop om het origineel te herstellen."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"U gebruikt uw werkprofiel"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Systeem-UI-tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Systeem-UI-tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Percentage ingebouwde accu weergeven"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Accupercentage weergeven in het pictogram op de statusbalk wanneer er niet wordt opgeladen"</string> <string name="quick_settings" msgid="10042998191725428">"Snelle instellingen"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Snelle instellingen, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Werkprofiel"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Leuk voor sommige gebruikers, maar niet voor iedereen"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Met Systeem-UI-tuner beschikt u over extra manieren om de Android-gebruikersinterface aan te passen. Deze experimentele functies kunnen veranderen, vastlopen of verdwijnen in toekomstige releases. Ga voorzichtig verder."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Deze experimentele functies kunnen veranderen, vastlopen of verdwijnen in toekomstige releases. Ga voorzichtig verder."</string> + <string name="got_it" msgid="2239653834387972602">"OK"</string> + <string name="tuner_toast" msgid="603429811084428439">"Systeem-UI-tuner is toegevoegd aan Instellingen"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Verwijderen uit Instellingen"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Systeem-UI-tuner uit Instellingen verwijderen en het gebruik van alle functies daarvan stopzetten?"</string> </resources> diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml index 0225cb4618b6..f33b44169959 100644 --- a/packages/SystemUI/res/values-pa-rIN/strings.xml +++ b/packages/SystemUI/res/values-pa-rIN/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੋਲਯੂਮ ਡਾਇਲੌਗ ਹੈ"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"ਅਸਲੀ ਨੂੰ ਰੀਸਟੋਰ ਕਰਨ ਲਈ ਛੋਹਵੋ।"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ਤੁਸੀਂ ਆਪਣੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਵਰਤ ਰਹੇ ਹੋ"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"SystemUI ਟਿਊਨਰ"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI ਟਿਊਨਰ"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"ਜੋਡ਼ੀ ਗਈ ਬੈਟਰੀ ਪ੍ਰਤਿਸ਼ਤਤਾ ਦਿਖਾਓ"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ਜਦੋਂ ਚਾਰਜ ਨਾ ਹੋ ਰਹੀ ਹੋਵੇ ਤਾਂ ਸਥਿਤੀ ਬਾਰ ਦੇ ਅੰਦਰ ਬੈਟਰੀ ਪੱਧਰ ਪ੍ਰਤਿਸ਼ਤਤਾ ਦਿਖਾਓ"</string> <string name="quick_settings" msgid="10042998191725428">"ਤਤਕਾਲ ਸੈੱਟਿੰਗਜ਼"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ, <xliff:g id="TITLE">%s</xliff:g>।"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ਹੌਟਸਪੌਟ"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"ਕੁਝ ਵਾਸਤੇ ਤਾਂ ਮਜ਼ੇਦਾਰ ਹੈ ਲੇਕਿਨ ਸਾਰਿਆਂ ਵਾਸਤੇ ਨਹੀਂ"</string> + <string name="tuner_warning" msgid="8730648121973575701">"ਸਿਸਟਮ UI ਟਿਊਨਰ ਤੁਹਾਨੂੰ Android ਉਪਭੋਗਤਾ ਇੰਟਰਫੇਸ ਤਬਦੀਲ ਕਰਨ ਅਤੇ ਅਨੁਕੂਲਿਤ ਕਰਨ ਲਈ ਵਾਧੂ ਤਰੀਕੇ ਦਿੰਦਾ ਹੈ। ਇਹ ਪ੍ਰਯੋਗਾਤਮਿਕ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਭਵਿੱਖ ਦੀ ਰੀਲੀਜ਼ ਵਿੱਚ ਬਦਲ ਸਕਦੀਆਂ ਹਨ, ਟੁੱਟ ਸਕਦੀਆਂ ਹਨ, ਜਾਂ ਅਲੋਪ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਸਾਵਧਾਨੀ ਨਾਲ ਅੱਗੇ ਵੱਧੋ।"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ਇਹ ਪ੍ਰਯੋਗਾਤਮਿਕ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਭਵਿੱਖ ਦੀ ਰੀਲੀਜ਼ ਵਿੱਚ ਬਦਲ ਸਕਦੀਆਂ ਹਨ, ਟੁੱਟ ਸਕਦੀਆਂ ਹਨ, ਜਾਂ ਅਲੋਪ ਹੋ ਸਕਦੀਆਂ ਹਨ। ਸਾਵਧਾਨੀ ਨਾਲ ਅੱਗੇ ਵੱਧੋ।"</string> + <string name="got_it" msgid="2239653834387972602">"ਸਮਝ ਗਿਆ"</string> + <string name="tuner_toast" msgid="603429811084428439">"ਵਧਾਈਆਂ! ਸਿਸਟਮ UI ਟਿਊਨਰ ਨੂੰ ਸੈਟਿੰਗਜ਼ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ ਹੈ"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"ਸੈਟਿੰਗਜ਼ ਤੋਂ ਹਟਾਓ"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"ਕੀ ਸੈਟਿੰਗਜ਼ ਤੋਂ ਸਿਸਟਮ UI ਟਿਊਨਰ ਨੂੰ ਹਟਾਉਣਾ ਹੈ ਅਤੇ ਇਸਦੀਆਂ ਸਾਰੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਉਪਯੋਗ ਕਰਨ ਤੋਂ ਰੋਕਣਾ ਹੈ?"</string> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 808056983296..7314c4214f4a 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> steruje głośnością"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Dotknij, by przywrócić pierwotną."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Używasz profilu do pracy"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Kalibrator System UI"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Kalibrator System UI"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Pokaż procent naładowania baterii"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Pokaż procent naładowania baterii w ikonie na pasku stanu, gdy telefon się nie ładuje"</string> <string name="quick_settings" msgid="10042998191725428">"Szybkie ustawienia"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Szybkie ustawienia, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profil do pracy"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Dobra zabawa, ale nie dla każdego"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Kalibrator System UI udostępnia dodatkowe sposoby dostrajania i dostosowywania interfejsu Androida. Te eksperymentalne funkcje mogą się zmienić, popsuć lub zniknąć w przyszłych wersjach. Zachowaj ostrożność."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Te eksperymentalne funkcje mogą się zmienić, popsuć lub zniknąć w przyszłych wersjach. Zachowaj ostrożność."</string> + <string name="got_it" msgid="2239653834387972602">"Rozumiem"</string> + <string name="tuner_toast" msgid="603429811084428439">"Gratulujemy, Kalibrator System UI został dodany do Ustawień"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Usuń z Ustawień"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Usunąć Kalibrator System UI z Ustawień i przestać używać wszystkich jego funkcji?"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000000..68f87e519e2a --- /dev/null +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -0,0 +1,431 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright (c) 2009, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="7164937344850004466">"Interf sist"</string> + <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string> + <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Remover da lista"</string> + <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informações do app"</string> + <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Suas telas recentes aparecem aqui"</string> + <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Dispensar apps recentes"</string> + <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759"> + <item quantity="one">%d telas em \"Visão geral\"</item> + <item quantity="other">%d telas em \"Visão geral\"</item> + </plurals> + <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string> + <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Em andamento"</string> + <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificações"</string> + <string name="battery_low_title" msgid="6456385927409742437">"Bateria fraca"</string> + <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> restantes"</string> + <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> restantes. A Economia de bateria está ativada."</string> + <string name="invalid_charger" msgid="4549105996740522523">"O carregamento via USB não é suportado.\nUse apenas o carregador fornecido."</string> + <string name="invalid_charger_title" msgid="3515740382572798460">"O carregamento via USB não é suportado."</string> + <string name="invalid_charger_text" msgid="5474997287953892710">"Use apenas o carregador fornecido."</string> + <string name="battery_low_why" msgid="4553600287639198111">"Configurações"</string> + <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Ativar a economia de bateria?"</string> + <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Ativar"</string> + <string name="battery_saver_start_action" msgid="5576697451677486320">"Ativar a economia de bateria"</string> + <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Configurações"</string> + <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string> + <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Girar automaticamente a tela"</string> + <string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUDO"</string> + <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string> + <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificações"</string> + <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth vinculado"</string> + <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de entrada"</string> + <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Teclado físico"</string> + <string name="usb_device_permission_prompt" msgid="834698001271562057">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse o dispositivo USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Permitir que o app <xliff:g id="APPLICATION">%1$s</xliff:g> acesse o acessório USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este dispositivo USB estiver conectado?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este acessório USB estiver conectado?"</string> + <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Nenhum apl. instalado funciona com o USB. Saiba mais sobre o acessório em <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Acessório USB"</string> + <string name="label_view" msgid="6304565553218192990">"Visualizar"</string> + <string name="always_use_device" msgid="1450287437017315906">"Usar por padrão para este dispositivo USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Usar por padrão para este acessório USB"</string> + <string name="usb_debugging_title" msgid="4513918393387141949">"Permitir a depuração USB?"</string> + <string name="usb_debugging_message" msgid="2220143855912376496">"A impressão digital da chave RSA deste computador é:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string> + <string name="usb_debugging_always" msgid="303335496705863070">"Sempre permitir a partir deste computador"</string> + <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Depuração USB não permitida"</string> + <string name="usb_debugging_secondary_user_message" msgid="6011931347142270156">"O usuário conectado a este dispositivo não pode ativar a depuração USB. Para usar esse recurso, mude para o usuário principal \"<xliff:g id="NAME">%s</xliff:g>\"."</string> + <string name="compat_mode_on" msgid="6623839244840638213">"Zoom p/ preencher a tela"</string> + <string name="compat_mode_off" msgid="4434467572461327898">"Ampliar p/ preencher tela"</string> + <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Salvando captura de tela..."</string> + <string name="screenshot_saving_title" msgid="8242282144535555697">"Salvando captura de tela..."</string> + <string name="screenshot_saving_text" msgid="2419718443411738818">"A captura de tela está sendo salva."</string> + <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura de tela obtida."</string> + <string name="screenshot_saved_text" msgid="1152839647677558815">"Toque para visualizar a captura de tela."</string> + <string name="screenshot_failed_title" msgid="705781116746922771">"Não foi possível obter a captura de tela."</string> + <string name="screenshot_failed_text" msgid="1260203058661337274">"Não é possível capturar a tela porque não há espaço suficiente ou o app ou organização não permite."</string> + <string name="usb_preference_title" msgid="6551050377388882787">"Opções transf. arq. por USB"</string> + <string name="use_mtp_button_title" msgid="4333504413563023626">"Conectar como media player (MTP)"</string> + <string name="use_ptp_button_title" msgid="7517127540301625751">"Montar como uma câmera (PTP)"</string> + <string name="installer_cd_button_title" msgid="2312667578562201583">"Instalar apl. de transf. arq. do Android para Mac"</string> + <string name="accessibility_back" msgid="567011538994429120">"Voltar"</string> + <string name="accessibility_home" msgid="8217216074895377641">"Página inicial"</string> + <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Visão geral"</string> + <string name="accessibility_search_light" msgid="1103867596330271848">"Pesquisar"</string> + <string name="accessibility_camera_button" msgid="8064671582820358152">"Câmera"</string> + <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> + <string name="camera_label" msgid="7261107956054836961">"abrir câmera"</string> + <string name="recents_caption_resize" msgid="3517056471774958200">"Selecionar novo layout da tarefa"</string> + <string name="cancel" msgid="6442560571259935130">"Cancelar"</string> + <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botão de zoom da compatibilidade."</string> + <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Aumentar a tela com zoom."</string> + <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado."</string> + <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth desconectado."</string> + <string name="accessibility_no_battery" msgid="358343022352820946">"Sem bateria."</string> + <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Uma barra de bateria."</string> + <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Duas barras de bateria."</string> + <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Três barras de bateria."</string> + <string name="accessibility_battery_full" msgid="8909122401720158582">"Bateria cheia."</string> + <string name="accessibility_no_phone" msgid="4894708937052611281">"Sem telefone."</string> + <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Uma barra de sinal do telefone."</string> + <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Duas barras de sinal do telefone."</string> + <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Três barras de sinal do telefone."</string> + <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Sinal do telefone cheio."</string> + <string name="accessibility_no_data" msgid="4791966295096867555">"Nenhum dado."</string> + <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Uma barra de sinal de dados."</string> + <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Duas barras de sinal de dados."</string> + <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Três barras do sinal de dados."</string> + <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Sinal de dados cheio."</string> + <string name="accessibility_wifi_name" msgid="7202151365171148501">"Conectado a <xliff:g id="WIFI">%s</xliff:g>."</string> + <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> + <string name="accessibility_no_wimax" msgid="4329180129727630368">"Sem WiMAX."</string> + <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Uma barra do WiMAX."</string> + <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Duas barras do WiMAX."</string> + <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Três barras do WiMAX."</string> + <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Sinal WiMAX completo."</string> + <string name="accessibility_ethernet_disconnected" msgid="5896059303377589469">"Ethernet desconectada."</string> + <string name="accessibility_ethernet_connected" msgid="2692130313069182636">"Ethernet conectada."</string> + <string name="accessibility_no_signal" msgid="7064645320782585167">"Sem sinal."</string> + <string name="accessibility_not_connected" msgid="6395326276213402883">"Sem conexão."</string> + <string name="accessibility_zero_bars" msgid="3806060224467027887">"Nenhuma barra."</string> + <string name="accessibility_one_bar" msgid="1685730113192081895">"Uma barra."</string> + <string name="accessibility_two_bars" msgid="6437363648385206679">"Duas barras."</string> + <string name="accessibility_three_bars" msgid="2648241415119396648">"Três barras."</string> + <string name="accessibility_signal_full" msgid="9122922886519676839">"Sinal cheio."</string> + <string name="accessibility_desc_on" msgid="2385254693624345265">"Ligado."</string> + <string name="accessibility_desc_off" msgid="6475508157786853157">"Desligado."</string> + <string name="accessibility_desc_connected" msgid="8366256693719499665">"Conectado."</string> + <string name="accessibility_desc_connecting" msgid="3812924520316280149">"Conectando."</string> + <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string> + <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string> + <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string> + <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string> + <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string> + <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string> + <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string> + <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string> + <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Roaming"</string> + <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string> + <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string> + <string name="accessibility_no_sim" msgid="8274017118472455155">"Sem SIM."</string> + <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Tethering Bluetooth."</string> + <string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo avião."</string> + <string name="accessibility_no_sims" msgid="3957997018324995781">"Sem cartão SIM."</string> + <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Alteração de rede de operadora."</string> + <!-- String.format failed for translation --> + <!-- no translation found for accessibility_battery_level (7451474187113371965) --> + <skip /> + <string name="accessibility_settings_button" msgid="799583911231893380">"Configurações do sistema"</string> + <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string> + <string name="accessibility_remove_notification" msgid="3603099514902182350">"Limpar notificação."</string> + <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ativado."</string> + <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Aquisição de GPS."</string> + <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTYpewriter ativado."</string> + <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibração da campainha."</string> + <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Campainha silenciosa."</string> + <!-- no translation found for accessibility_casting (6887382141726543668) --> + <skip /> + <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Descartar <xliff:g id="APP">%s</xliff:g>."</string> + <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> descartado."</string> + <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Todos os apps recentes foram dispensados."</string> + <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string> + <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> + <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação dispensada."</string> + <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Aba de notificações."</string> + <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configurações rápidas."</string> + <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Tela de bloqueio."</string> + <string name="accessibility_desc_settings" msgid="3417884241751434521">"Configurações"</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Visão geral."</string> + <string name="accessibility_desc_close" msgid="7479755364962766729">"Fechar"</string> + <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuário <xliff:g id="USER">%s</xliff:g>."</string> + <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> + <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"O Wi-Fi foi desativado."</string> + <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"O Wi-Fi foi ativado."</string> + <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Celular <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string> + <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Bateria <xliff:g id="STATE">%s</xliff:g>."</string> + <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Modo avião desativado."</string> + <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Modo avião ativado."</string> + <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"O modo avião foi desativado."</string> + <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"O modo avião foi ativado."</string> + <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"\"Não perturbe\" ativado, somente prioridade."</string> + <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"\"Não perturbe\" ativado, silêncio total."</string> + <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"\"Não perturbe\" ativado, somente alarmes."</string> + <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"\"Não perturbe\" desativado."</string> + <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"\"Não perturbe\" desativado."</string> + <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"\"Não perturbe\" ativado."</string> + <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth desativado."</string> + <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth ativado."</string> + <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"Conectando Bluetooth."</string> + <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"Bluetooth conectado."</string> + <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"O Bluetooth foi desativado."</string> + <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"O Bluetooth foi ativado."</string> + <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"Relatório de Localização desativado."</string> + <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"Relatório de Localização ativado."</string> + <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"O Relatório de Localização foi desativado."</string> + <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"O Relatório de Localização foi ativado."</string> + <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string> + <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"Fechar painel."</string> + <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"Mais tempo."</string> + <string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"Menos tempo."</string> + <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"Lanterna desativada."</string> + <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"Lanterna ativada."</string> + <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"A lanterna foi desativada."</string> + <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"A lanterna foi ativada."</string> + <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"A inversão de cores foi desativada."</string> + <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"A inversão de cores foi ativada."</string> + <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"O ponto de acesso móvel foi desativado."</string> + <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"O ponto de acesso móvel foi ativado."</string> + <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"A transmissão de tela foi interrompida."</string> + <string name="accessibility_brightness" msgid="8003681285547803095">"Brilho da tela"</string> + <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Os dados 2G e 3G foram pausados"</string> + <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Os dados 4G foram pausados"</string> + <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Os dados da rede celular foram pausados"</string> + <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Os dados foram pausados"</string> + <string name="data_usage_disabled_dialog" msgid="8453242888903772524">"Como seu limite de dados definido foi atingido, o dispositivo pausou o uso de dados para o restante deste ciclo.\n\nA retomada pode gerar cobranças por parte da sua operadora."</string> + <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Retomar"</string> + <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sem conexão à Internet"</string> + <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectado"</string> + <string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string> + <string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string> + <string name="accessibility_location_active" msgid="2427290146138169014">"Solicitações de localização ativas"</string> + <string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string> + <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configurações de notificação"</string> + <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configurações de <xliff:g id="APP_NAME">%s</xliff:g>"</string> + <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string> + <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"A tela está bloqueada na orientação paisagem."</string> + <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"A tela está bloqueada na orientação retrato."</string> + <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"Agora a tela vai girar automaticamente."</string> + <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"A tela está bloqueada na orientação cenário."</string> + <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"A tela está bloqueada na orientação retrato."</string> + <string name="dessert_case" msgid="1295161776223959221">"Mostruário de sobremesas"</string> + <string name="start_dreams" msgid="7219575858348719790">"Daydream"</string> + <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string> + <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Não perturbe"</string> + <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Só prioridade"</string> + <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Somente alarmes"</string> + <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Silêncio total"</string> + <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string> + <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> dispositivos)"</string> + <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth desativado"</string> + <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"Não há dispositivos pareados disponíveis"</string> + <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brilho"</string> + <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Rotação automática"</string> + <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotação bloqueada"</string> + <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Retrato"</string> + <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Paisagem"</string> + <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de entrada"</string> + <string name="quick_settings_location_label" msgid="5011327048748762257">"Localização"</string> + <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Localização desativada"</string> + <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Dispositivo de mídia"</string> + <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string> + <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Somente chamadas de emergência"</string> + <string name="quick_settings_settings_label" msgid="5326556592578065401">"Configurações"</string> + <string name="quick_settings_time_label" msgid="4635969182239736408">"Hora"</string> + <string name="quick_settings_user_label" msgid="5238995632130897840">"Eu"</string> + <string name="quick_settings_user_title" msgid="4467690427642392403">"Usuário"</string> + <string name="quick_settings_user_new_user" msgid="9030521362023479778">"Novo usuário"</string> + <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string> + <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Não conectado"</string> + <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Sem rede"</string> + <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desligado"</string> + <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nenhuma rede Wi-Fi disponível"</string> + <string name="quick_settings_cast_title" msgid="7709016546426454729">"Transmitir"</string> + <string name="quick_settings_casting" msgid="6601710681033353316">"Transmitindo"</string> + <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sem nome"</string> + <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Pronto para transmitir"</string> + <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Não há dispositivos disponíveis"</string> + <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brilho"</string> + <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string> + <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverter cores"</string> + <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string> + <string name="quick_settings_more_settings" msgid="326112621462813682">"Mais configurações"</string> + <string name="quick_settings_done" msgid="3402999958839153376">"Concluído"</string> + <string name="quick_settings_connected" msgid="1722253542984847487">"Conectado"</string> + <string name="quick_settings_connecting" msgid="47623027419264404">"Conectando..."</string> + <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string> + <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Ponto de acesso"</string> + <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notificações"</string> + <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Lanterna"</string> + <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Dados da rede celular"</string> + <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Uso de dados"</string> + <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Dados restantes"</string> + <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Limite excedido"</string> + <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Usados: <xliff:g id="DATA_USED">%s</xliff:g>"</string> + <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Limite: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> + <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Aviso de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> + <string name="recents_empty_message" msgid="8682129509540827999">"Suas telas recentes aparecem aqui"</string> + <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informações do app"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação de tela"</string> + <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string> + <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string> + <string name="recents_dismiss_all_message" msgid="8495275386693095768">"Dispensar todos os apps"</string> + <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string> + <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Divisão vertical"</string> + <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Divisão personalizada"</string> + <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Carregada"</string> + <string name="expanded_header_battery_charging" msgid="205623198487189724">"Carregando"</string> + <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> até concluir"</string> + <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"Não está carregando"</string> + <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode estar\nsob monitoração"</string> + <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string> + <string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string> + <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_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> + <string name="keyguard_unlock" msgid="8043466894212841998">"Deslize para cima para desbloquear"</string> + <string name="phone_hint" msgid="4872890986869209950">"Deslize a partir do ícone do telefone"</string> + <string name="voice_hint" msgid="8939888732119726665">"Deslize a partir do ícone de assistência de voz"</string> + <string name="camera_hint" msgid="7939688436797157483">"Deslize a partir do ícone da câmera"</string> + <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Silêncio total. Isso também silenciará os leitores de tela."</string> + <string name="interruption_level_none" msgid="6000083681244492992">"Silêncio total"</string> + <string name="interruption_level_priority" msgid="6426766465363855505">"Só prioridade"</string> + <string name="interruption_level_alarms" msgid="5226306993448328896">"Somente alarmes"</string> + <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silêncio\ntotal"</string> + <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Somente\nprioridade"</string> + <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Somente\nalarmes"</string> + <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até concluir)"</string> + <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Trocar usuário"</string> + <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Alternar usuário. Usuário atual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string> + <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Usuário atual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string> + <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Mostrar perfil"</string> + <string name="user_add_user" msgid="5110251524486079492">"Adicionar usuário"</string> + <string name="user_new_user_name" msgid="426540612051178753">"Novo usuário"</string> + <string name="guest_nickname" msgid="8059989128963789678">"Convidado"</string> + <string name="guest_new_guest" msgid="600537543078847803">"Adicionar convidado"</string> + <string name="guest_exit_guest" msgid="7187359342030096885">"Remover convidado"</string> + <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Remover convidado?"</string> + <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Todos os apps e dados nesta sessão serão excluídos."</string> + <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Remover"</string> + <string name="guest_wipe_session_title" msgid="6419439912885956132">"Bem-vindo, convidado."</string> + <string name="guest_wipe_session_message" msgid="8476238178270112811">"Deseja continuar a sessão?"</string> + <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Recomeçar"</string> + <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Sim, continuar"</string> + <string name="guest_notification_title" msgid="1585278533840603063">"Usuário convidado"</string> + <string name="guest_notification_text" msgid="335747957734796689">"Para excluir apps e dados, remova o usuário convidado"</string> + <string name="guest_notification_remove_action" msgid="8820670703892101990">"REMOVER CONVIDADO"</string> + <string name="user_add_user_title" msgid="4553596395824132638">"Adicionar novo usuário?"</string> + <string name="user_add_user_message_short" msgid="2161624834066214559">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string> + <string name="battery_saver_notification_title" msgid="237918726750955859">"A Economia de bateria está ativada"</string> + <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduz o desempenho e os dados em segundo plano"</string> + <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Desativar a economia de bateria"</string> + <string name="notification_hidden_text" msgid="1135169301897151909">"Conteúdo oculto"</string> + <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> começará a capturar tudo o que for exibido na tela."</string> + <string name="media_projection_remember_text" msgid="3103510882172746752">"Não mostrar novamente"</string> + <string name="clear_all_notifications_text" msgid="814192889771462828">"Limpar tudo"</string> + <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar agora"</string> + <string name="empty_shade_text" msgid="708135716272867002">"Sem notificações"</string> + <string name="device_owned_footer" msgid="3802752663326030053">"O dispositivo pode ser monitorado"</string> + <string name="profile_owned_footer" msgid="8021888108553696069">"O perfil pode ser monitorado"</string> + <string name="vpn_footer" msgid="2388611096129106812">"A rede pode ser monitorada"</string> + <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Monitoramento de dispositivos"</string> + <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Monitoramento de perfis"</string> + <string name="monitoring_title" msgid="169206259253048106">"Monitoramento de rede"</string> + <string name="disable_vpn" msgid="4435534311510272506">"Desativar VPN"</string> + <string name="disconnect_vpn" msgid="1324915059568548655">"Desconectar VPN"</string> + <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Seu dispositivo é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSeu administrador pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao dispositivo e informações sobre a localização do dispositivo. Para mais informações, entre em contato com o administrador."</string> + <string name="monitoring_description_vpn" msgid="4445150119515393526">"Você deu permissão para um app configurar uma conexão VPN.\n\nEsse app pode monitorar seu dispositivo e a atividade na rede, incluindo e-mails, apps e websites."</string> + <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Seu dispositivo é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSeu administrador pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao seu dispositivo e informações sobre localização do dispositivo.\n\nVocê está conectado a uma VPN, a qual pode monitorar suas atividades de rede, incluindo e-mails, apps e websites.\n\nPara mais informações, entre em contato com seu administrador."</string> + <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSeu administrador pode monitorar suas atividades de rede, incluindo e-mails, apps e websites.\n\nPara mais informações, entre em contato com seu administrador.\n\nVocê também está conectado a uma VPN, a qual pode monitorar suas atividades de rede."</string> + <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string> + <string name="monitoring_description_app" msgid="6259179342284742878">"Você está conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorar sua atividade na rede, incluindo e-mails, apps e websites."</string> + <string name="monitoring_description_app_personal" msgid="484599052118316268">"Você está conectado a <xliff:g id="APPLICATION">%1$s</xliff:g>, que pode monitorar sua atividade pessoal na rede, incluindo e-mails, apps e websites."</string> + <string name="monitoring_description_app_work" msgid="1754325860918060897">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ele está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorar sua atividade profissional na rede, incluindo e-mails, apps e websites.\n\nPara ver mais informações, entre em contato com seu administrador."</string> + <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Seu perfil de trabalho é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ele está conectado a <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, que pode monitorar sua atividade profissional na rede, incluindo e-mails, apps e websites.\n\nVocê também está conectado a <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, que pode monitorar sua atividade pessoal na rede."</string> + <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Seu dispositivo é gerenciado por <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSeu administrador pode monitorar e gerenciar configurações, acesso corporativo, apps, dados associados ao seu dispositivo e informações sobre localização do dispositivo.\n\nVocê está conectado a <xliff:g id="APPLICATION">%2$s</xliff:g>, que pode monitorar suas atividades de rede, incluindo e-mails, apps e websites.\n\nPara ver mais informações, entre em contato com seu administrador."</string> + <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"O dispositivo permanecerá bloqueado até que você o desbloqueie manualmente"</string> + <string name="hidden_notifications_title" msgid="7139628534207443290">"Receba notificações mais rápido"</string> + <string name="hidden_notifications_text" msgid="2326409389088668981">"Veja-as antes de desbloquear"</string> + <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Não, obrigado"</string> + <string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string> + <string name="notification_expand_button_text" msgid="1037425494153780718">"Ver tudo"</string> + <string name="notification_collapse_button_text" msgid="6883253262134328057">"Ocultar tudo"</string> + <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> + <string name="volume_zen_end_now" msgid="3179845345429841822">"Finalizar agora"</string> + <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string> + <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Recolher"</string> + <string name="screen_pinning_title" msgid="3273740381976175811">"A tela está fixada"</string> + <string name="screen_pinning_description" msgid="1346522416878235405">"Ela é mantida à vista até que seja liberada. Toque em \"Voltar\" e \"Visão Geral\" e mantenha essas opções pressionadas ao mesmo tempo para liberar."</string> + <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Ela é mantida à vista até que seja liberada. Toque em \"Visão geral\" e mantenha essa opção pressionada para liberar."</string> + <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendi"</string> + <string name="screen_pinning_negative" msgid="3741602308343880268">"Não, obrigado"</string> + <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Esconder <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string> + <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ela reaparecerá na próxima vez que você ativá-la nas configurações."</string> + <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ocultar"</string> + <string name="volumeui_prompt_message" msgid="918680947433389110">"<xliff:g id="APP_NAME">%1$s</xliff:g> deseja ser a caixa de diálogo referente ao volume."</string> + <string name="volumeui_prompt_allow" msgid="7954396902482228786">"Permitir"</string> + <string name="volumeui_prompt_deny" msgid="5720663643411696731">"Negar"</string> + <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo referente ao volume"</string> + <string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string> + <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Você está usando seu perfil de trabalho"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador System UI"</string> + <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentagem de bateria incorporada"</string> + <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar porcentagem de nível de bateria dentro do ícone da barra de status quando não estiver carregando"</string> + <string name="quick_settings" msgid="10042998191725428">"Configurações rápidas"</string> + <string name="status_bar" msgid="4877645476959324760">"Barra de status"</string> + <string name="demo_mode" msgid="2389163018533514619">"Modo de demonstração"</string> + <string name="enable_demo_mode" msgid="4844205668718636518">"Ativar modo de demonstração"</string> + <string name="show_demo_mode" msgid="2018336697782464029">"Mostrar modo de demonstração"</string> + <string name="status_bar_ethernet" msgid="5044290963549500128">"Ethernet"</string> + <string name="status_bar_alarm" msgid="8536256753575881818">"Alarme"</string> + <string name="status_bar_work" msgid="6022553324802866373">"Perfil de trabalho"</string> + <string name="status_bar_airplane" msgid="7057575501472249002">"Modo avião"</string> + <string name="add_tile" msgid="2995389510240786221">"Adicionar bloco"</string> + <string name="broadcast_tile" msgid="3894036511763289383">"Transmitir bloco"</string> + <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Você não ouvirá o próximo alarme às <xliff:g id="WHEN">%1$s</xliff:g>, a menos que desative essa opção antes desse horário"</string> + <string name="zen_alarm_warning" msgid="444533119582244293">"Você não ouvirá o próximo alarme às <xliff:g id="WHEN">%1$s</xliff:g>"</string> + <string name="alarm_template" msgid="3980063409350522735">"às <xliff:g id="WHEN">%1$s</xliff:g>"</string> + <string name="alarm_template_far" msgid="4242179982586714810">"<xliff:g id="WHEN">%1$s</xliff:g>"</string> + <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Configurações rápidas, <xliff:g id="TITLE">%s</xliff:g>."</string> + <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Ponto de acesso"</string> + <string name="accessibility_managed_profile" msgid="6613641363112584120">"Perfil de trabalho"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Diversão para alguns, mas não para todos"</string> + <string name="tuner_warning" msgid="8730648121973575701">"O sintonizador System UI fornece maneiras adicionais de ajustar e personalizar a interface do usuário do Android. Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string> + <string name="got_it" msgid="2239653834387972602">"Entendi"</string> + <string name="tuner_toast" msgid="603429811084428439">"Parabéns! O sintonizador System UI foi adicionado às configurações"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Remover das configurações"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remover sintonizador System UI das configurações e parar de usar todos os seus recursos?"</string> +</resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 2d518c68f284..a4016a5fc090 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo do volume"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Está a utilizar o seu perfil de trabalho"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Sintonizador da IU do sistema"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador da interface do sistema"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar percentagem da bateria incorporada"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar a percentagem do nível da bateria no ícone da barra de estado quando não estiver a carregar"</string> <string name="quick_settings" msgid="10042998191725428">"Definições rápidas"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Definições rápidas, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Zona Wi-Fi"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Perfil de trabalho"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Diversão para alguns, mas não para todos"</string> + <string name="tuner_warning" msgid="8730648121973575701">"O Sintonizador da interface do sistema disponibiliza-lhe formas adicionais ajustar e personalizar a interface do utilizador do Android. Estas funcionalidades experimentais podem ser alteradas, deixar de funcionar ou desaparecer em versões futuras. Prossiga com cuidado."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Estas funcionalidades experimentais podem ser alteradas, deixar de funcionar ou desaparecer em versões futuras. Prossiga com cuidado."</string> + <string name="got_it" msgid="2239653834387972602">"Compreendi"</string> + <string name="tuner_toast" msgid="603429811084428439">"Parabéns! O Sintonizador da interface do sistema foi adicionado às Definições"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Remover das Definições"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Pretende remover o Sintonizador da interface do sistema das Definições e deixar de utilizar todas as respetivas funcionalidades?"</string> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index a9017742e206..68f87e519e2a 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo referente ao volume"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Você está usando seu perfil de trabalho"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Sintonizador System UI"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizador System UI"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Mostrar porcentagem de bateria incorporada"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Mostrar porcentagem de nível de bateria dentro do ícone da barra de status quando não estiver carregando"</string> <string name="quick_settings" msgid="10042998191725428">"Configurações rápidas"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Configurações rápidas, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Ponto de acesso"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Perfil de trabalho"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Diversão para alguns, mas não para todos"</string> + <string name="tuner_warning" msgid="8730648121973575701">"O sintonizador System UI fornece maneiras adicionais de ajustar e personalizar a interface do usuário do Android. Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Esses recursos experimentais podem mudar, falhar ou desaparecer nas versões futuras. Prossiga com cuidado."</string> + <string name="got_it" msgid="2239653834387972602">"Entendi"</string> + <string name="tuner_toast" msgid="603429811084428439">"Parabéns! O sintonizador System UI foi adicionado às configurações"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Remover das configurações"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Remover sintonizador System UI das configurações e parar de usar todos os seus recursos?"</string> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 2349d2aac59a..874f51ab17fe 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -399,7 +399,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> afișează caseta de dialog pentru volum"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Atingeți pentru a reveni la setarea inițială."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Acum folosiți profilul de serviciu"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Afișați procentajul bateriei încorporat"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Afișați procentajul cu nivelul bateriei în interiorul pictogramei din bara de stare, atunci când nu se încarcă"</string> <string name="quick_settings" msgid="10042998191725428">"Setări rapide"</string> @@ -420,4 +420,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Setări rapide, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profil de serviciu"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Distractiv pentru unii, dar nu pentru toată lumea"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner vă oferă modalități suplimentare de a ajusta și a personaliza interfața de utilizare Android. Aceste funcții experimentale pot să se schimbe, să se blocheze sau să dispară din versiunile viitoare. Continuați cu prudență."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Aceste funcții experimentale pot să se schimbe, să se blocheze sau să dispară din versiunile viitoare. Continuați cu prudență."</string> + <string name="got_it" msgid="2239653834387972602">"Am înțeles"</string> + <string name="tuner_toast" msgid="603429811084428439">"Felicitări! System UI Tuner a fost adăugat în Setări"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Eliminați din Setări"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Eliminați System UI Tuner din Setări și încetați utilizarea tuturor funcțiilor sale?"</string> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 788a136ff1fa..49228d13b06a 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -402,7 +402,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> назначено регулятором громкости"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Нажмите, чтобы восстановить приложение по умолчанию."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Вы перешли в рабочий профиль"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"SystemUI Tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Показывать уровень заряда батареи в процентах"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Когда устройство работает в автономном режиме, процент заряда батареи показан в строке состояния"</string> <string name="quick_settings" msgid="10042998191725428">"Быстрые настройки"</string> @@ -423,4 +423,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Быстрые настройки, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Точка доступа"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Рабочий профиль"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Внимание!"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner позволяет настраивать интерфейс устройства Android по вашему вкусу. В будущем эта экспериментальная функция может измениться, перестать работать или исчезнуть."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Это экспериментальная функция. В будущем она может измениться, перестать работать или исчезнуть."</string> + <string name="got_it" msgid="2239653834387972602">"ОК"</string> + <string name="tuner_toast" msgid="603429811084428439">"Функция System UI Tuner добавлена в меню настроек"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Удалить из настроек"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Убрать функцию System UI Tuner из меню настроек и прекратить ее работу?"</string> </resources> diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml index 358441767c03..eb6d981a4166 100644 --- a/packages/SystemUI/res/values-si-rLK/strings.xml +++ b/packages/SystemUI/res/values-si-rLK/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ධාරිතා සංවාදයයි"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"මුල් තත්ත්වය නැවත ප්රතිසාධනය කිරීමට ස්පර්ශ කරන්න."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ඔබ ඔබේ කාර්යාල පැතිකඩ භාවිත කරමින් සිටී"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"පද්ධති UI Tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"පද්ධති UI සුසරකය"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"කාවද්දන ලද බැටරි ප්රතිශතය පෙන්වන්න"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ආරෝපණය නොවන විට තත්ත්ව තීරු නිරූපකය ඇතුළත බැටරි මට්ටම් ප්රතිශතය පෙන්වන්න"</string> <string name="quick_settings" msgid="10042998191725428">"ඉක්මන් සැකසීම්"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"ඉක්මන් සැකසුම්, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"හොට්ස්පොට්"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"කාර්යාල පැතිකඩ"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"සමහරක් දේවල් වලට විනෝදයි, නමුත් සියල්ලටම නොවේ"</string> + <string name="tuner_warning" msgid="8730648121973575701">"පද්ධති UI සුසරකය ඔබට Android පරිශීලක අතුරු මුහුණත වෙනස් කිරීමට හෝ අභිරුචිකරණය කිරීමට අමතර ක්රම ලබා දේ. මෙම පර්යේෂණාත්මක අංග ඉදිරි නිකුත් වීම් වල වෙනස් වීමට, වැඩ නොකිරීමට, හෝ නැතිවීමට හැක. ප්රවේශමෙන් ඉදිරියට යන්න."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"මෙම පර්යේෂණාත්මක අංග ඉදිරි නිකුත් වීම් වල වෙනස් වීමට, වැඩ නොකිරීමට, හෝ නැතිවීමට හැක. ප්රවේශමෙන් ඉදිරියට යන්න."</string> + <string name="got_it" msgid="2239653834387972602">"තේරුණා"</string> + <string name="tuner_toast" msgid="603429811084428439">"සුබ පැතුම්! පද්ධති UI සුසරකය සැකසීම් වෙත එක් කර ඇත"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"සැකසීම් වෙතින් ඉවත් කරන්න"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"සැකසීම් වෙතින් පද්ධති UI සුසරකය ඉවත් කර සහ එහි සියලු අංග භාවිතය නවත් වන්නද?"</string> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index db17b9cb2731..1eb5901b93f8 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -402,7 +402,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dialóg hlasitosti"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Klepnutím obnovíte originál."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Používate svoj pracovný profil."</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Tuner používateľského rozhrania systému"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Tuner používateľského rozhrania systému"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Zobraziť percentá vloženej batérie"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Percentuálne zobrazenie nabitia batérie vnútri ikony v stavovom riadku, keď neprebieha nabíjanie"</string> <string name="quick_settings" msgid="10042998191725428">"Rýchle nastavenia"</string> @@ -423,4 +423,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Rýchle nastavenia, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Pracovný profil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Pri používaní tuneru postupujte opatrne"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Tuner používateľského rozhrania systému poskytujte ďalšie spôsoby ladenia a prispôsobenia používateľského rozhrania Android. Tieto experimentálne funkcie sa môžu v budúcich verziách zmeniť, ich poskytovanie môže byť prerušené alebo môžu byť odstránené. Pokračujte opatrne."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Tieto experimentálne funkcie sa môžu v budúcich verziách zmeniť, ich poskytovanie môže byť prerušené alebo môžu byť odstránené. Pokračujte opatrne."</string> + <string name="got_it" msgid="2239653834387972602">"Dobre"</string> + <string name="tuner_toast" msgid="603429811084428439">"Výborne, tuner používateľského rozhrania systému bol pridaný do Nastavení"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Odstrániť z Nastavení"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Chcete odstrániť tuner používateľského rozhrania systému z Nastavení a prestať používať všetky jeho funkcie?"</string> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 7ccf8dac94b6..d9102a22b124 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je pogovorno okno glede prostornine"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Dotaknite se, če želite obnoviti izvirnik."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Uporabljate delovni profil"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Uglaševalnik uporabniškega vmesnika sistema"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Uglaševalnik uporabniškega vmesnika sistema"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Prikaži odstotek napolnjenosti vgraj. akumulatorja"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prikaz odstotka napolnjenosti akumulatorja znotraj ikone v vrstici stanja, ko se ne polni"</string> <string name="quick_settings" msgid="10042998191725428">"Hitre nastavitve"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Hitre nastavitve, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Dostopna točka"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Delovni profil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Zabavno za nekatere, a ne za vse"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Uglaševalnik uporabniškega vmesnika sistema vam omogoča dodatne načine za spreminjanje in prilagajanje uporabniškega vmesnika Android. Te poskusne funkcije lahko v prihodnjih izdajah kadar koli izginejo, se spremenijo ali pokvarijo. Bodite previdni."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Te poskusne funkcije lahko v prihodnjih izdajah kadar koli izginejo, se spremenijo ali pokvarijo. Bodite previdni."</string> + <string name="got_it" msgid="2239653834387972602">"Razumem"</string> + <string name="tuner_toast" msgid="603429811084428439">"Čestitke! Uglaševalnik uporabniškega vmesnika sistema je bil dodan v nastavitve."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Odstrani iz nastavitev"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Ali želite odstraniti Uglaševalnik uporabniškega vmesnika sistema iz nastavitev in prenehati uporabljati vse njegove funkcije?"</string> </resources> diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml index 8b3ff929e45a..cb8a50c1e3d3 100644 --- a/packages/SystemUI/res/values-sq-rAL/strings.xml +++ b/packages/SystemUI/res/values-sq-rAL/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> është dialogu i volumit"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Prek për të restauruar origjinalin."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Po përdor profilin tënd të punës"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Sintonizuesi SystemUI"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Shfaq përqindjen e baterisë së integruar"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Shfaq përqindjen e nivelit të baterisë brenda ikonës së shiritit të statusit kur nuk është duke u ngarkuar."</string> <string name="quick_settings" msgid="10042998191725428">"Cilësimet e shpejta"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Cilësimet e shpejta, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Zona e qasjes për internet"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profili i punës"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Argëtim për disa, por jo për të gjithë!"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit të jep mënyra shtesë për të tërhequr dhe personalizuar ndërfaqen Android të përdoruesit. Këto funksione eksperimentale mund të ndryshojnë, prishen ose zhduken në versionet e ardhshme. Vazhdo me kujdes."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Këto karakteristika eksperimentale mund të ndryshojnë, prishen ose të zhduken në versionet e ardhshme. Vazhdo me kujdes."</string> + <string name="got_it" msgid="2239653834387972602">"E kuptova"</string> + <string name="tuner_toast" msgid="603429811084428439">"Urime! Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit u shtua te Cilësimet"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Hiqe nga Cilësimet"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Të hiqet Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit nga Cilësimet dhe të ndërpritet përdorimi i të gjitha funksioneve të tij?"</string> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index dd91dd23f97f..181c136208f9 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -399,7 +399,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> је дијалог за јачину звука"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Додирните да бисте вратили оригинал."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Користите профил за Work"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Тјунер за кориснички интерфејс система"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Тјунер за кориснички интерфејс система"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Приказуј уграђени проценат батерије"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Приказивање нивоа напуњености батерије у процентима унутар иконе на статусној траци када се батерија не пуни"</string> <string name="quick_settings" msgid="10042998191725428">"Брза подешавања"</string> @@ -420,4 +420,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Брза подешавања, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Хотспот"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Профил за Work"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Забава за неке, али не за све"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Тјунер за кориснички интерфејс система вам пружа додатне начине за подешавање и прилагођавање Android корисничког интерфејса. Ове експерименталне функције могу да се промене, откажу или нестану у будућим издањима. Будите опрезни."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ове експерименталне функције могу да се промене, откажу или нестану у будућим издањима. Будите опрезни."</string> + <string name="got_it" msgid="2239653834387972602">"Важи"</string> + <string name="tuner_toast" msgid="603429811084428439">"Честитамо! Тјунер за кориснички интерфејс система је додат у Подешавања"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Уклони из Подешавања"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Желите ли да уклоните Тјунер за кориснички интерфејс система из Подешавања и да престанете да користите све његове функције?"</string> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 136ee9c6fbd4..61b3344adbb7 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> används som volymkontroll"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Tryck här om du vill återställa den ursprungliga appen."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du använder din jobbprofil"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Inställningar för systemgränssnitt"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Inställningar för systemgränssnitt"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Visa inbäddad batteriprocent"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Visa batterinivå i procent i statusfältsikonen när enheten inte laddas"</string> <string name="quick_settings" msgid="10042998191725428">"Snabbinställningar"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Snabbinställningar, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Trådlös surfzon"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Jobbprofil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Kul för vissa, inte för alla"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Du kan använda inställningarna för systemgränssnitt för att justera användargränssnittet i Android. Dessa experimentfunktioner kan när som helst ändras, sluta fungera eller försvinna. Använd med försiktighet."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Dessa experimentfunktioner kan när som helst ändras, sluta fungera eller försvinna. Använd med försiktighet."</string> + <string name="got_it" msgid="2239653834387972602">"OK"</string> + <string name="tuner_toast" msgid="603429811084428439">"Grattis! Inställningar för systemgränssnitt har lagts till i inställningarna."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Ta bort från inställningarna"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vill du ta bort inställningar för systemgränssnitt från inställningarna och sluta använda alla tillhörande funktioner?"</string> </resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 189ff0f0517b..2e15c6138572 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ni mazungumzo ya sauti"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Gusa ili urejeshe ya awali."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Unatumia wasifu wako wa kazini"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Kipokea ishara cha SystemUI"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Kipokea Ishara cha SystemUI"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Onyesha asilimia ya betri iliyopachikwa"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Onyesha asilimia ya kiwango cha betri ndani ya aikoni ya sehemu ya arifa inapokuwa haichaji"</string> <string name="quick_settings" msgid="10042998191725428">"Mipangilio ya Haraka"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Mipangilio ya Haraka, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Mtandao-hewa"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Wasifu wa kazini"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Kinafurahisha kwa baadhi ya watu lakini si wote"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Kipokea Ishara cha System UI kinakupa njia zaidi za kugeuza na kubadilisha kiolesura cha Android ili kikufae. Vipengele hivi vya majaribio vinaweza kubadilika, kuharibika, au kupotea katika matoleo ya siku zijazo. Endelea kwa uangalifu."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Vipengele hivi vya majaribio vinaweza kubadilika, kuharibika, au kupotea katika matoleo ya siku zijazo. Endelea kwa uangalifu."</string> + <string name="got_it" msgid="2239653834387972602">"Nimeelewa"</string> + <string name="tuner_toast" msgid="603429811084428439">"Hongera! Kipokea Ishara cha System UI kimeongezwa kwenye Mipangilio"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Ondoa kwenye Mipangilio"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Je, ungependa kuondoa Kipokea ishara cha SystemUI kwenye Mipangilio na uache kutumia vipengele vyake vyote?"</string> </resources> diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml index 24c59e1479f5..4ed5e029d0e6 100644 --- a/packages/SystemUI/res/values-ta-rIN/strings.xml +++ b/packages/SystemUI/res/values-ta-rIN/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"ஒலியளவு செய்தி: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"அசலை மீட்டமைக்கத் தொடவும்."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"பணி சுயவிவரத்தைப் பயன்படுத்துகிறீர்கள்"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"System UI ட்யூனர்"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"உள்ளிணைந்த பேட்டரி சதவீதத்தைக் காட்டு"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"சார்ஜ் செய்யாத போது, நிலைப் பட்டி ஐகானின் உள்ளே பேட்டரி அளவு சதவீதத்தைக் காட்டும்"</string> <string name="quick_settings" msgid="10042998191725428">"உடனடி அமைப்புகள்"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"விரைவு அமைப்புகள், <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ஹாட்ஸ்பாட்"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"பணி சுயவிவரம்"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"சில வேடிக்கையாக இருந்தாலும் கவனம் தேவை"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner, Android பயனர் இடைமுகத்தை மாற்றவும் தனிப்பயனாக்கவும் கூடுதல் வழிகளை வழங்குகிறது. இந்தப் பரிசோதனைக்குரிய அம்சங்கள் எதிர்கால வெளியீடுகளில் மாற்றப்படலாம், இடைநிறுத்தப்படலாம் அல்லது தோன்றாமல் போகலாம். கவனத்துடன் தொடரவும்."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"இந்தப் பரிசோதனைக்குரிய அம்சங்கள் எதிர்கால வெளியீடுகளில் மாற்றப்படலாம், இடைநிறுத்தப்படலாம் அல்லது தோன்றாமல் போகலாம். கவனத்துடன் தொடரவும்."</string> + <string name="got_it" msgid="2239653834387972602">"சரி"</string> + <string name="tuner_toast" msgid="603429811084428439">"வாழ்த்துகள்! அமைப்புகளில் System UI Tuner சேர்க்கப்பட்டது"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"அமைப்புகளிலிருந்து அகற்று"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"அமைப்புகளிலிருந்து System UI Tunerஐ அகற்றிவிட்டு, அதன் எல்லா அம்சங்களையும் பயன்படுத்துவதை நிறுத்தவா?"</string> </resources> diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml index c24be7375345..6b1c7620a503 100644 --- a/packages/SystemUI/res/values-te-rIN/strings.xml +++ b/packages/SystemUI/res/values-te-rIN/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> అనేది వాల్యూమ్ డైలాగ్"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"అసలుదాన్ని పునరుద్ధరించడానికి తాకండి."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"మీరు మీ కార్యాలయ ప్రొఫైల్ను ఉపయోగిస్తున్నారు"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"సిస్టమ్ UI ట్యూనర్"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"సిస్టమ్ UI ట్యూనర్"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"పొందుపరిచిన బ్యాటరీ శాతం చూపు"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"ఛార్జింగ్లో లేనప్పుడు స్థితి పట్టీ చిహ్నం లోపల బ్యాటరీ స్థాయి శాతం చూపుతుంది"</string> <string name="quick_settings" msgid="10042998191725428">"శీఘ్ర సెట్టింగ్లు"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"శీఘ్ర సెట్టింగ్లు, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"హాట్స్పాట్"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"కార్యాలయ ప్రొఫైల్"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"కొందరికి సరదాగా ఉంటుంది కానీ అందరికీ అలాగే ఉండదు"</string> + <string name="tuner_warning" msgid="8730648121973575701">"సిస్టమ్ UI ట్యూనర్ Android వినియోగదారు ఇంటర్ఫేస్ను మెరుగుపరచడానికి మరియు అనుకూలీకరించడానికి మీకు మరిన్ని మార్గాలను అందిస్తుంది. ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"ఈ ప్రయోగాత్మక లక్షణాలు భవిష్యత్తు విడుదలల్లో మార్పుకు లోనవ్వచ్చు, తాత్కాలికంగా లేదా పూర్తిగా నిలిపివేయవచ్చు. జాగ్రత్తగా కొనసాగండి."</string> + <string name="got_it" msgid="2239653834387972602">"అర్థమైంది"</string> + <string name="tuner_toast" msgid="603429811084428439">"అభినందనలు! సెట్టింగ్లకు సిస్టమ్ UI ట్యూనర్ జోడించబడింది"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"సెట్టింగ్ల నుండి తీసివేయి"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"సిస్టమ్ UI ట్యూనర్ను సెట్టింగ్ల నుండి తీసివేసి, దాని అన్ని లక్షణాలను ఉపయోగించడం ఆపివేయాలా?"</string> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index c5f715260fa8..29437c5bb169 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> เป็นช่องโต้ตอบระดับเสียง"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"แตะเพื่อคืนค่าดั้งเดิม"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"คุณกำลังใช้โปรไฟล์งานของคุณ"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"ตัวปรับ UI ระบบ"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"ตัวรับสัญญาณ UI ระบบ"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"แสดงเปอร์เซ็นต์ของแบตเตอรี่ในตัว"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"แสดงเปอร์เซ็นต์ของระดับแบตเตอรี่ภายในไอคอนแถบสถานะเมื่อไม่มีการชาร์จ"</string> <string name="quick_settings" msgid="10042998191725428">"การตั้งค่าด่วน"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"การตั้งค่าด่วน <xliff:g id="TITLE">%s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ฮอตสปอต"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"โปรไฟล์งาน"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"เพลิดเพลินกับบางส่วนแต่ไม่ใช่ทั้งหมด"</string> + <string name="tuner_warning" msgid="8730648121973575701">"ตัวรับสัญญาณ UI ระบบช่วยให้คุณมีวิธีพิเศษในการปรับแต่งและกำหนดค่าส่วนติดต่อผู้ใช้ Android คุณลักษณะรุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"คุณลักษณะรุ่นทดลองเหล่านี้อาจมีการเปลี่ยนแปลง ขัดข้อง หรือหายไปในเวอร์ชันอนาคต โปรดดำเนินการด้วยความระมัดระวัง"</string> + <string name="got_it" msgid="2239653834387972602">"รับทราบ"</string> + <string name="tuner_toast" msgid="603429811084428439">"ยินดีด้วย! เพิ่มตัวรับสัญญาณ UI ระบบไปยังการตั้งค่าแล้ว"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"นำออกจากการตั้งค่า"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"นำตัวรับสัญญาณ UI ระบบออกจากการตั้งค่าและหยุดใช้คุณลักษณะทั้งหมดของตัวรับสัญญาณใช่ไหม"</string> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 79c2aee79582..cde538c96414 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ang volume dialog"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Pindutin upang ibalik ang orihinal."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Ginagamit mo ang iyong profile sa trabaho"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Tuner ng System UI"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Tuner ng System UI"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Ipakita ang naka-embed na porsyento ng baterya"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Ipakita ang porsyento ng antas ng baterya na nasa icon ng status bar kapag nagcha-charge"</string> <string name="quick_settings" msgid="10042998191725428">"Mga Maikling Setting"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Mga Maikling Setting, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profile sa trabaho"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Masaya para sa ilan ngunit hindi para sa lahat"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Nagbibigay sa iyo ang Tuner ng System UI ng mga karagdagang paraan upang baguhin at i-customize ang user interface ng Android. Ang mga pang-eksperimentong feature na ito ay maaaring magbago, masira o mawala sa mga pagpapalabas sa hinaharap. Magpatuloy nang may pag-iingat."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ang mga pang-eksperimentong feature na ito ay maaaring magbago, masira o mawala sa mga pagpapalabas sa hinaharap. Magpatuloy nang may pag-iingat."</string> + <string name="got_it" msgid="2239653834387972602">"Naintindihan ko"</string> + <string name="tuner_toast" msgid="603429811084428439">"Binabati kita! Naidagdag na ang Tuner ng System UI sa Mga Setting"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Alisin sa Mga Setting"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Alisin ang Tuner ng System UI sa Mga Setting at ihinto ang paggamit ng lahat ng feature nito?"</string> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 2207bb2ed742..544a28defa35 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ses denetimi iletişim kutusu olarak ayarlandı"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Orijinali geri yüklemek için dokunun."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"İş profilinizi kullanıyorsunuz"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Sistem Arayüzü ayarlayıcısı"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Sistem Arayüzü Ayarlayıcısı"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Yerleşik pil yüzdesini göster"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Şarj olmazken durum çubuğu simgesinin içinde pil düzeyi yüzdesini göster"</string> <string name="quick_settings" msgid="10042998191725428">"Hızlı Ayarlar"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Hızlı Ayarlar, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"İş profili"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Bazıları için eğlenceliyken diğerleri için olmayabilir"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Sistem Kullanıcı Arayüzü Ayarlayıcı, Android kullanıcı arayüzünde değişiklikler yapmanız ve arayüzü özelleştirmeniz için ekstra yollar sağlar. Bu deneysel özellikler değişebilir, bozulabilir veya gelecekteki sürümlerde yer almayabilir. Dikkatli bir şekilde devam edin."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Bu deneysel özellikler değişebilir, bozulabilir veya gelecekteki sürümlerde yer almayabilir. Dikkatli bir şekilde devam edin."</string> + <string name="got_it" msgid="2239653834387972602">"Anladım"</string> + <string name="tuner_toast" msgid="603429811084428439">"Tebrikler! Sistem Kullanıcı Arayüzü Ayarlayıcı Ayarlar\'a eklendi"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Ayarlar\'dan kaldır"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Sistem Kullanıcı Arayüzü Ayarlayıcısı Ayarlar\'dan kaldırılsın ve tüm özelliklerinin kullanılması durdurulsun mu?"</string> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 85e7cf52cd47..4f507873bc7d 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> призначено регулятором гучності"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Торкніться, щоб відновити оригінал."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Ви в робочому профілі"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Тюнер System UI"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Показувати заряд акумулятора у відсотках"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Показувати заряд акумулятора у відсотках в рядку стану, коли пристрій не заряджається"</string> <string name="quick_settings" msgid="10042998191725428">"Швидкі налаштування"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Швидкі налаштування, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Точка доступу"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Робочий профіль"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Це цікаво, але будьте обачні"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner пропонує нові способи налаштувати та персоналізувати інтерфейс користувача Android. Ці експериментальні функції можуть змінюватися, не працювати чи зникати в майбутніх версіях. Будьте обачні."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ці експериментальні функції можуть змінюватися, не працювати чи зникати в майбутніх версіях. Будьте обачні."</string> + <string name="got_it" msgid="2239653834387972602">"Зрозуміло"</string> + <string name="tuner_toast" msgid="603429811084428439">"Вітаємо! System UI Tuner установлено в додатку Налаштування"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Видалити з додатка Налаштування"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Видалити інструмент System UI Tuner із додатка Налаштування та припинити користуватися всіма його функціями?"</string> </resources> diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml index de81fa92e22f..269bb1fc059b 100644 --- a/packages/SystemUI/res/values-ur-rPK/strings.xml +++ b/packages/SystemUI/res/values-ur-rPK/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> والیوم ڈائلاگ ہے"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"اصل کو بحال کرنے کیلئے ٹچ کریں۔"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"آپ اپنا دفتری پروفائل استعمال کر رہے ہیں۔"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"سسٹم UI ٹیونر"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"سسٹم UI ٹیونر"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"سرایت کردہ بیٹری کی فیصد دکھائیں"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"جب چارج نہ ہو رہا ہو تو بیٹری کی سطح کی فیصد اسٹیٹس بار آئیکن کے اندر دکھائیں"</string> <string name="quick_settings" msgid="10042998191725428">"فوری ترتیبات"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"فوری ترتیبات، <xliff:g id="TITLE">%s</xliff:g>۔"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"ہاٹ اسپاٹ"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"دفتری پروفائل"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"کچھ کیلئے دلچسپ لیکن سبھی کیلئے نہیں"</string> + <string name="tuner_warning" msgid="8730648121973575701">"سسٹم UI ٹیونر Android صارف انٹر فیس میں ردوبدل کرنے اور اسے حسب ضرورت بنانے کیلئے آپ کو اضافی طریقے دیتا ہے۔ یہ تجرباتی خصوصیات مستقبل کی ریلیزز میں تبدیل ہو سکتی، رک سکتی یا غائب ہو سکتی ہیں۔ احتیاط کے ساتھ آگے بڑھیں۔"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"یہ تجرباتی خصوصیات مستقبل کی ریلیزز میں تبدیل ہو سکتی، رک سکتی یا غائب ہو سکتی ہیں۔ احتیاط کے ساتھ آگے بڑھیں۔"</string> + <string name="got_it" msgid="2239653834387972602">"سمجھ آ گئی"</string> + <string name="tuner_toast" msgid="603429811084428439">"مبارک ہو! سسٹم UI ٹیونر کو ترتیبات میں شامل کر دیا گیا ہے"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"ترتیبات سے ہٹائیں"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"ترتیبات سے سسٹم UI ٹیونر کو ہٹائیں اور اس کی سبھی خصوصیات کا استعمال بند کریں؟"</string> </resources> diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml index 544713884f59..63248c3b6e77 100644 --- a/packages/SystemUI/res/values-uz-rUZ/strings.xml +++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml @@ -130,8 +130,8 @@ <string name="accessibility_two_bars" msgid="6437363648385206679">"Ikkita ustun."</string> <string name="accessibility_three_bars" msgid="2648241415119396648">"Uchta ustun."</string> <string name="accessibility_signal_full" msgid="9122922886519676839">"Signal to‘liq."</string> - <string name="accessibility_desc_on" msgid="2385254693624345265">"Yoqilgan."</string> - <string name="accessibility_desc_off" msgid="6475508157786853157">"O‘chirilgan."</string> + <string name="accessibility_desc_on" msgid="2385254693624345265">"Yoniq"</string> + <string name="accessibility_desc_off" msgid="6475508157786853157">"O‘chiq"</string> <string name="accessibility_desc_connected" msgid="8366256693719499665">"Ulangan."</string> <string name="accessibility_desc_connecting" msgid="3812924520316280149">"Ulanmoqda…"</string> <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string> @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ovoz balandligini boshqaradi"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Aslini tiklash uchun bosing."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Siz ishchi profildan foydalanmoqdasiz"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"SystemUI Tuner"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"SystemUI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Batareya foizi ko‘rsatilsin"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Batareya quvvat olmayotgan vaqtda uning foizi holat qatorida ko‘rsatilsin"</string> <string name="quick_settings" msgid="10042998191725428">"Tezkor sozlamalar"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Tezkor sozlamalar, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Ulanish nuqtasi"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Ishchi profil"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Diqqat!"</string> + <string name="tuner_warning" msgid="8730648121973575701">"System UI Tuner yordamida siz Android foydalanuvchi interfeysini tuzatish va o‘zingizga moslashtirishingiz mumkin. Ushbu tajribaviy funksiyalar o‘zgarishi, buzilishi yoki keyingi versiyalarda olib tashlanishi mumkin. Ehtiyot bo‘lib davom eting."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ushbu tajribaviy funksiyalar o‘zgarishi, buzilishi yoki keyingi versiyalarda olib tashlanishi mumkin. Ehtiyot bo‘lib davom eting."</string> + <string name="got_it" msgid="2239653834387972602">"OK"</string> + <string name="tuner_toast" msgid="603429811084428439">"Tabriklaymiz! System UI Tuner Sozlamalarga qo‘shildi."</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Sozlamalardan olib tashlash"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"System UI Tuner Sozlamalardan olib tashlanib, uning barcha funksiyalaridan foydalanish to‘xtatilsinmi?"</string> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index de121c4bd068..158d2a642746 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> là hộp thoại khối lượng"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Chạm để khôi phục bản gốc."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Bạn đang sử dụng hồ sơ công việc của mình"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Bộ điều hướng giao diện người dùng hệ thống"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Bộ điều hướng giao diện người dùng hệ thống"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Hiển thị tỷ lệ phần trăm pin được nhúng"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Hiển thị tỷ lệ phần trăm mức pin bên trong biểu tượng thanh trạng thái khi không sạc"</string> <string name="quick_settings" msgid="10042998191725428">"Cài đặt nhanh"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Cài đặt nhanh, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Điểm phát sóng"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Hồ sơ công việc"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Thú vị đối với một số người nhưng không phải tất cả"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Bộ điều hướng giao diện người dùng hệ thống cung cấp thêm cho bạn những cách chỉnh sửa và tùy chỉnh giao diện người dùng Android. Những tính năng thử nghiệm này có thể thay đổi, hỏng hoặc biến mất trong các phiên bản tương lai. Hãy thận trọng khi tiếp tục."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Những tính năng thử nghiệm này có thể thay đổi, hỏng hoặc biến mất trong các phiên bản tương lai. Hãy thận trọng khi tiếp tục."</string> + <string name="got_it" msgid="2239653834387972602">"OK"</string> + <string name="tuner_toast" msgid="603429811084428439">"Xin chúc mừng! Bộ điều hướng giao diện người dùng hệ thống đã được thêm vào Cài đặt"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Xóa khỏi Cài đặt"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Xóa Bộ điều hướng giao diện người dùng hệ thống khỏi Cài đặt và ngừng sử dụng tất cả tính năng của ứng dụng này?"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 24ada1b7c463..84e0eea3ddc5 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”已用作音量控制对话框"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"触摸即可恢复原始设置。"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您当前正在使用工作资料"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"系统界面调谐器"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"系统界面调谐器"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"嵌入式显示电池电量百分比 显示嵌入的电池电量百分比"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"未充电时在状态栏图标内显示电池电量百分比"</string> <string name="quick_settings" msgid="10042998191725428">"快速设置"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"快速设置,<xliff:g id="TITLE">%s</xliff:g>。"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"热点"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"工作资料"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"是否有趣完全取决于个人感觉"</string> + <string name="tuner_warning" msgid="8730648121973575701">"系统界面调谐器可让您通过其他方式调整及自定义 Android 用户界面。在日后推出的版本中,这些实验性功能可能会变更、损坏或消失。操作时请务必谨慎。"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"在日后推出的版本中,这些实验性功能可能会变更、损坏或消失。操作时请务必谨慎。"</string> + <string name="got_it" msgid="2239653834387972602">"知道了"</string> + <string name="tuner_toast" msgid="603429811084428439">"恭喜!系统界面调谐器已添加到“设置”中"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"从“设置”中移除"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"要将系统界面调谐器从“设置”中移除,并停止使用所有相关功能吗?"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 5bce61b7f576..aacdd0e30d39 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」為音量對話框"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"輕觸即可復原。"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您正在使用工作設定檔"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"系統使用者介面調諧器"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"系統使用者介面調諧器"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"顯示嵌入的電池百分比"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"非充電時,在狀態列圖示顯示電量百分比"</string> <string name="quick_settings" msgid="10042998191725428">"快速設定"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"<xliff:g id="TITLE">%s</xliff:g>的快速設定。"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"熱點"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"工作設定檔"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"這只是測試版本,並不包含完整功能"</string> + <string name="tuner_warning" msgid="8730648121973575701">"使用者介面調諧器讓您以更多方法修改和自訂 Android 使用者介面。但請小心,這些實驗功能可能會在日後發佈時更改、分拆或消失。"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"請小心,這些實驗功能可能會在日後發佈時更改、分拆或消失。"</string> + <string name="got_it" msgid="2239653834387972602">"知道了"</string> + <string name="tuner_toast" msgid="603429811084428439">"恭喜您!系統使用者介面調諧器已新增至「設定」中"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"從「設定」移除"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"要從「設定」移除系統使用者介面調諧器,並停止其所有功能嗎?"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 091d33d8eb13..e0464b73705c 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -400,7 +400,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」現在是預設的音量控制對話方塊。"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"輕觸這裡即可恢復原始設定。"</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您正在使用 Work 設定檔"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"系統使用者介面調整精靈"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"系統使用者介面調整精靈"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"顯示嵌入式電池百分比"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"未充電時在狀態列圖示中顯示電量百分比"</string> <string name="quick_settings" msgid="10042998191725428">"快速設定"</string> @@ -421,4 +421,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"快速設定,<xliff:g id="TITLE">%s</xliff:g>。"</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"無線基地台"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Work 設定檔"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"有趣與否,見仁見智"</string> + <string name="tuner_warning" msgid="8730648121973575701">"系統使用者介面調整精靈可讓您透過其他方式,調整及自訂 Android 使用者介面。這些實驗性功能隨著版本更新可能會變更、損壞或消失,執行時請務必謹慎。"</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"這些實驗性功能隨著版本更新可能會變更、損壞或消失,執行時請務必謹慎。"</string> + <string name="got_it" msgid="2239653834387972602">"知道了"</string> + <string name="tuner_toast" msgid="603429811084428439">"恭喜!系統使用者介面調整精靈已新增到設定中"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"從設定中移除"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"要將系統使用者介面調整精靈從設定中移除,並停止使用所有相關功能嗎?"</string> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index d86d583c8c7d..9b491bafaa26 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -398,7 +398,7 @@ <string name="volumeui_notification_title" msgid="4906770126345910955">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> yingxoxo yevolumu"</string> <string name="volumeui_notification_text" msgid="1826889705095768656">"Thinta ukuze ubuyisele kokwangempela."</string> <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Usebenzisa iphrofayela yakho yomsebenzi"</string> - <string name="system_ui_tuner" msgid="3442596010150119600">"Isishuni se-UI yesistimu"</string> + <string name="system_ui_tuner" msgid="708224127392452018">"Isishuni se-UI yesistimu"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Bonisa amaphesenti ebhethri elinamathiselwe"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Bonisa amaphesenti eleveli yebhethri ngaphakathi kwesithonjana sebha yesimo uma kungashajwa"</string> <string name="quick_settings" msgid="10042998191725428">"Izilungiselelo ezisheshayo"</string> @@ -419,4 +419,11 @@ <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Izilungiselelo ezisheshayo, <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"I-Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Iphrofayela yomsebenzi"</string> + <string name="tuner_warning_title" msgid="7094689930793031682">"Kuyajabulisa kwabanye kodwa hhayi bonke"</string> + <string name="tuner_warning" msgid="8730648121973575701">"Isishuni se-UI sesistimu sikunika izindlela ezingeziwe zokuhlobisa nokwenza ngezifiso isixhumanisi sokubona se-Android. Lezi zici zesilingo zingashintsha, zephuke, noma zinyamalale ekukhishweni kwangakusasa. Qhubeka ngokuqaphela."</string> + <string name="tuner_persistent_warning" msgid="8597333795565621795">"Lezi zici zesilingo zingashintsha, zephuke, noma zinyamalale ekukhishweni kwangakusasa. Qhubeka ngokuqaphela."</string> + <string name="got_it" msgid="2239653834387972602">"Ngiyezwa"</string> + <string name="tuner_toast" msgid="603429811084428439">"Siyakuhalalisela! Isishuni se-UI sesistimu singeziwe kuzilungiselelo"</string> + <string name="remove_from_settings" msgid="8389591916603406378">"Susa kusuka kuzilungiselelo"</string> + <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Susa isishuni se-UI yesistimu kusuka kuzilungiselelo futhi uyeke ukusebenzisa zonke izici zakhona?"</string> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 3210a24e536f..03ea73c262da 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -562,7 +562,7 @@ <!-- Padding to be used on the bottom of the fingerprint icon on Keyguard so it better aligns with the other icons. --> - <dimen name="fingerprint_icon_additional_padding">12dp</dimen> + <dimen name="fingerprint_icon_additional_padding">4dp</dimen> <!-- Minimum margin of the notification panel on the side, when being positioned dynamically --> <dimen name="notification_panel_min_side_margin">48dp</dimen> diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index 6d84727c2656..8eef23e3db52 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -49,5 +49,6 @@ <!-- For notification icons for which targetSdk < L, this caches whether the icon is grayscale --> <item type="id" name="icon_is_grayscale" /> + <item type="id" name="is_clicked_heads_up_tag" /> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index fcf7e3e90bbb..3eac84fd4dce 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -1032,7 +1032,7 @@ <string name="volume_stream_vibrate_dnd" translatable="false">%s vibrate — Priority only</string> <!-- Name of special SystemUI debug settings --> - <string name="system_ui_tuner">System UI tuner</string> + <string name="system_ui_tuner">System UI Tuner</string> <!-- Preference to show/hide embedded battery percentage [CHAR LIMIT=50] --> <string name="show_battery_percentage">Show embedded battery percentage</string> @@ -1099,4 +1099,25 @@ <!-- Accessibility label for managed profile icon (not shown on screen) [CHAR LIMIT=NONE] --> <string name="accessibility_managed_profile">Work profile</string> + <!-- Title of warning when entering System UI tuner for first time [CHAR LIMIT=NONE] --> + <string name="tuner_warning_title">Fun for some but not for all</string> + + <!-- Warning for users entering the System UI tuner for the first time [CHAR LIMIT=NONE]--> + <string name="tuner_warning">System UI Tuner gives you extra ways to tweak and customize the Android user interface. These experimental features may change, break, or disappear in future releases. Proceed with caution.</string> + + <!-- Warning for users entering the System UI tuner [CHAR LIMIT=NONE]--> + <string name="tuner_persistent_warning">These experimental features may change, break, or disappear in future releases. Proceed with caution.</string> + + <!-- Generic "got it" acceptance of dialog or cling [CHAR LIMIT=NONE] --> + <string name="got_it">Got it</string> + + <!-- Toast describing tuner has been enabled [CHAR LIMIT=NONE] --> + <string name="tuner_toast">Congrats! System UI Tuner has been added to Settings</string> + + <!-- Option to remove the tuner from settings [CHAR LIMIT=NONE] --> + <string name="remove_from_settings">Remove from Settings</string> + + <!-- Dialog asking if the tuner should really be removed from settings [CHAR LIMIT=NONE]--> + <string name="remove_from_settings_prompt">Remove System UI Tuner from Settings and stop using all of its features?"</string> + </resources> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 188986274e77..8241ddf6a378 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -206,6 +206,11 @@ <item name="android:windowExitAnimation">@*android:anim/shrink_fade_out_from_bottom</item> </style> + <style name="Animation.NavigationBarFadeIn"> + <item name="android:windowEnterAnimation">@anim/navbar_fade_in</item> + <item name="android:windowExitAnimation">@null</item> + </style> + <!-- Standard animations for hiding and showing the status bar. --> <style name="Animation.StatusBar"> </style> diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml index 8c1acc35955f..3a41c3c540bd 100644 --- a/packages/SystemUI/res/xml/tuner_prefs.xml +++ b/packages/SystemUI/res/xml/tuner_prefs.xml @@ -76,4 +76,8 @@ android:key="demo_mode" android:title="@string/demo_mode" /> + <Preference + android:summary="@string/tuner_persistent_warning" + android:selectable="false" /> + </PreferenceScreen> diff --git a/packages/SystemUI/src/com/android/systemui/DejankUtils.java b/packages/SystemUI/src/com/android/systemui/DejankUtils.java new file mode 100644 index 000000000000..fc98ec45debd --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/DejankUtils.java @@ -0,0 +1,80 @@ +/* + * 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; + +import android.os.Handler; +import android.os.Looper; +import android.os.StrictMode; +import android.view.Choreographer; + +import java.util.ArrayList; + +/** + * Utility class for methods used to dejank the UI. + */ +public class DejankUtils { + + private static final Choreographer sChoreographer = Choreographer.getInstance(); + private static final Handler sHandler = new Handler(); + + private static final ArrayList<Runnable> sPendingRunnables = new ArrayList<>(); + + private static final Runnable sAnimationCallbackRunnable = new Runnable() { + @Override + public void run() { + for (int i = 0; i < sPendingRunnables.size(); i++) { + sHandler.post(sPendingRunnables.get(i)); + } + sPendingRunnables.clear(); + } + }; + + /** + * Executes {@code r} after performTraversals. Use this do to CPU heavy work for which the + * timing is not critical for animation. The work is then scheduled at the same time + * RenderThread is doing its thing, leading to better parallelization. + * + * <p>Needs to be called from the main thread. + */ + public static void postAfterTraversal(Runnable r) { + throwIfNotCalledOnMainThread(); + sPendingRunnables.add(r); + postAnimationCallback(); + } + + /** + * Removes a previously scheduled runnable. + * + * <p>Needs to be called from the main thread. + */ + public static void removeCallbacks(Runnable r) { + throwIfNotCalledOnMainThread(); + sPendingRunnables.remove(r); + sHandler.removeCallbacks(r); + } + + private static void postAnimationCallback() { + sChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, sAnimationCallbackRunnable, + null); + } + + private static void throwIfNotCalledOnMainThread() { + if (!Looper.getMainLooper().isCurrentThread()) { + throw new IllegalStateException("should be called from the main thread."); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/DemoMode.java b/packages/SystemUI/src/com/android/systemui/DemoMode.java index d406f5b68f9a..11996d078bc3 100644 --- a/packages/SystemUI/src/com/android/systemui/DemoMode.java +++ b/packages/SystemUI/src/com/android/systemui/DemoMode.java @@ -20,6 +20,8 @@ import android.os.Bundle; public interface DemoMode { + public static final String DEMO_MODE_ALLOWED = "sysui_demo_allowed"; + void dispatchDemoCommand(String command, Bundle args); public static final String ACTION_DEMO = "com.android.systemui.demo"; diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index 9f6d8df1684b..8556afc30e9f 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -116,7 +116,6 @@ public class ImageWallpaper extends WallpaperService { private final DisplayInfo mTmpDisplayInfo = new DisplayInfo(); boolean mVisible = true; - boolean mRedrawNeeded; boolean mOffsetsChanged; int mLastXTranslation; int mLastYTranslation; @@ -153,6 +152,9 @@ public class ImageWallpaper extends WallpaperService { private int mDisplayWidthAtLastSurfaceSizeUpdate = -1; private int mDisplayHeightAtLastSurfaceSizeUpdate = -1; + private int mLastRequestedWidth = -1; + private int mLastRequestedHeight = -1; + public DrawableEngine() { super(); setFixedSizeAllowed(true); @@ -211,21 +213,13 @@ public class ImageWallpaper extends WallpaperService { int surfaceWidth = Math.max(displayInfo.logicalWidth, mBackgroundWidth); int surfaceHeight = Math.max(displayInfo.logicalHeight, mBackgroundHeight); - // If the surface dimensions haven't changed, then just return - final Rect frame = surfaceHolder.getSurfaceFrame(); - if (frame != null) { - final int dw = frame.width(); - final int dh = frame.height(); - if (surfaceWidth == dw && surfaceHeight == dh) { - return; - } - } - if (FIXED_SIZED_SURFACE) { // Used a fixed size surface, because we are special. We can do // this because we know the current design of window animations doesn't // cause this to break. surfaceHolder.setFixedSize(surfaceWidth, surfaceHeight); + mLastRequestedWidth = surfaceWidth; + mLastRequestedHeight = surfaceHeight; } else { surfaceHolder.setSizeFromLayout(); } @@ -387,7 +381,6 @@ public class ImageWallpaper extends WallpaperService { yPixels += (int) (availhUnscaled * (mYOffset - .5f) + .5f); mOffsetsChanged = false; - mRedrawNeeded = false; if (surfaceDimensionsChanged) { mLastSurfaceWidth = dw; mLastSurfaceHeight = dh; @@ -475,13 +468,15 @@ public class ImageWallpaper extends WallpaperService { out.print(" mYOffset="); out.println(mYOffset); out.print(prefix); out.print(" mVisible="); out.print(mVisible); - out.print(" mRedrawNeeded="); out.print(mRedrawNeeded); out.print(" mOffsetsChanged="); out.println(mOffsetsChanged); out.print(prefix); out.print(" mLastXTranslation="); out.print(mLastXTranslation); out.print(" mLastYTranslation="); out.print(mLastYTranslation); out.print(" mScale="); out.println(mScale); + out.print(prefix); out.print(" mLastRequestedWidth="); out.print(mLastRequestedWidth); + out.print(" mLastRequestedHeight="); out.println(mLastRequestedHeight); + out.print(prefix); out.println(" DisplayInfo at last updateSurfaceSize:"); out.print(prefix); out.print(" rotation="); out.print(mRotationAtLastSurfaceSizeUpdate); diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 0daa5c9f79d6..9265b631e486 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -18,6 +18,7 @@ import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; +import android.service.voice.VoiceInteractionSession; import android.util.Log; import android.view.Gravity; import android.view.HapticFeedbackConstants; @@ -218,7 +219,8 @@ public class AssistManager { } private void startVoiceInteractor(Bundle args) { - mAssistUtils.showSessionForActiveService(args, mShowCallback); + mAssistUtils.showSessionForActiveService(args, + VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE, mShowCallback, null); } public void launchVoiceAssistFromKeyguard() { @@ -302,4 +304,8 @@ public class AssistManager { public void onUserSwitched(int newUserId) { updateAssistInfo(); } + + public void onLockscreenShown() { + mAssistUtils.onLockscreenShown(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java index 3f721256a25d..9eb768c51851 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java @@ -244,12 +244,12 @@ public class DozeLog { } @Override - public void onScreenTurnedOn() { + public void onStartedWakingUp() { traceScreenOn(); } @Override - public void onScreenTurnedOff(int why) { + public void onFinishedGoingToSleep(int why) { traceScreenOff(why); } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java index 5d467124c0f0..887391c078b2 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java @@ -136,7 +136,7 @@ public class DozeService extends DreamService { mDozeParameters.getPulseOnPickup(), mDozeParameters.getVibrateOnPickup(), DozeLog.PULSE_REASON_SENSOR_PICKUP); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); - mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag); + mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock.setReferenceCounted(true); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); mDisplayStateSupported = mDozeParameters.getDisplayStateSupported(); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 98558b49bfd8..d78800ffe521 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -25,9 +25,9 @@ import android.os.IBinder; import android.os.Process; import android.util.Log; +import com.android.internal.policy.IKeyguardDrawnCallback; import com.android.internal.policy.IKeyguardExitCallback; import com.android.internal.policy.IKeyguardService; -import com.android.internal.policy.IKeyguardShowCallback; import com.android.internal.policy.IKeyguardStateCallback; import com.android.systemui.SystemUIApplication; @@ -120,9 +120,27 @@ public class KeyguardService extends Service { } @Override // Binder interface - public void onStartedWakingUp(IKeyguardShowCallback callback) { + public void onStartedWakingUp() { checkPermission(); - mKeyguardViewMediator.onStartedWakingUp(callback); + mKeyguardViewMediator.onStartedWakingUp(); + } + + @Override // Binder interface + public void onScreenTurningOn(IKeyguardDrawnCallback callback) { + checkPermission(); + mKeyguardViewMediator.onScreenTurningOn(callback); + } + + @Override // Binder interface + public void onScreenTurnedOn() { + checkPermission(); + mKeyguardViewMediator.onScreenTurnedOn(); + } + + @Override // Binder interface + public void onScreenTurnedOff() { + checkPermission(); + mKeyguardViewMediator.onScreenTurnedOff(); } @Override // Binder interface diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 009a0d629c94..9f86a52c20c1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -55,8 +55,9 @@ import android.view.WindowManagerGlobal; import android.view.WindowManagerPolicy; import android.view.animation.Animation; import android.view.animation.AnimationUtils; + +import com.android.internal.policy.IKeyguardDrawnCallback; import com.android.internal.policy.IKeyguardExitCallback; -import com.android.internal.policy.IKeyguardShowCallback; import com.android.internal.policy.IKeyguardStateCallback; import com.android.internal.telephony.IccCardConstants; import com.android.internal.widget.LockPatternUtils; @@ -77,7 +78,6 @@ import java.util.List; import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; - /** * Mediates requests related to the keyguard. This includes queries about the * state of the keyguard, power management events that effect whether the keyguard @@ -137,8 +137,8 @@ public class KeyguardViewMediator extends SystemUI { private static final int HIDE = 3; private static final int RESET = 4; private static final int VERIFY_UNLOCK = 5; - private static final int NOTIFY_SCREEN_OFF = 6; - private static final int NOTIFY_SCREEN_ON = 7; + private static final int NOTIFY_FINISHED_GOING_TO_SLEEP = 6; + private static final int NOTIFY_SCREEN_TURNING_ON = 7; private static final int KEYGUARD_DONE = 9; private static final int KEYGUARD_DONE_DRAWING = 10; private static final int KEYGUARD_DONE_AUTHENTICATING = 11; @@ -148,6 +148,9 @@ public class KeyguardViewMediator extends SystemUI { private static final int START_KEYGUARD_EXIT_ANIM = 18; private static final int ON_ACTIVITY_DRAWN = 19; private static final int KEYGUARD_DONE_PENDING_TIMEOUT = 20; + private static final int NOTIFY_STARTED_WAKING_UP = 21; + private static final int NOTIFY_SCREEN_TURNED_ON = 22; + private static final int NOTIFY_SCREEN_TURNED_OFF = 23; /** * The default amount of time we stay awake (used for all key input) @@ -311,11 +314,14 @@ public class KeyguardViewMediator extends SystemUI { private boolean mPendingReset; /** - * When starting goign to sleep, we figured out that we need to lock Keyguard and this should be + * When starting going to sleep, we figured out that we need to lock Keyguard and this should be * committed when finished going to sleep. */ private boolean mPendingLock; + private boolean mWakeAndUnlocking; + private IKeyguardDrawnCallback mDrawnCallback; + KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() { @Override @@ -454,12 +460,25 @@ public class KeyguardViewMediator extends SystemUI { } @Override - public void onFingerprintAuthenticated(int userId) { + public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { + boolean unlockingWithFingerprintAllowed = + mUpdateMonitor.isUnlockingWithFingerprintAllowed(); if (mStatusBarKeyguardViewManager.isBouncerShowing()) { - mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(); + if (unlockingWithFingerprintAllowed) { + mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(); + } } else { - mStatusBarKeyguardViewManager.animateCollapsePanels( - FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR); + if (wakeAndUnlocking && mShowing && unlockingWithFingerprintAllowed) { + mWakeAndUnlocking = true; + mStatusBarKeyguardViewManager.setWakeAndUnlocking(); + keyguardDone(true, true); + } else if (mShowing && mDeviceInteractive) { + if (wakeAndUnlocking) { + mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested(); + } + mStatusBarKeyguardViewManager.animateCollapsePanels( + FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR); + } } }; @@ -685,7 +704,7 @@ public class KeyguardViewMediator extends SystemUI { resetKeyguardDonePendingLocked(); mHideAnimationRun = false; - notifyScreenOffLocked(); + notifyFinishedGoingToSleep(); if (mPendingReset) { resetStateLocked(); @@ -696,7 +715,7 @@ public class KeyguardViewMediator extends SystemUI { mPendingLock = false; } } - KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurnedOff(why); + KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why); } private void doKeyguardLaterLocked() { @@ -752,21 +771,33 @@ public class KeyguardViewMediator extends SystemUI { /** * Let's us know when the device is waking up. */ - public void onStartedWakingUp(IKeyguardShowCallback callback) { + public void onStartedWakingUp() { // TODO: Rename all screen off/on references to interactive/sleeping synchronized (this) { mDeviceInteractive = true; cancelDoKeyguardLaterLocked(); if (DEBUG) Log.d(TAG, "onStartedWakingUp, seq = " + mDelayedShowingSequence); - if (callback != null) { - notifyScreenOnLocked(callback); - } + notifyStartedWakingUp(); } - KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurnedOn(); + KeyguardUpdateMonitor.getInstance(mContext).dispatchStartedWakingUp(); maybeSendUserPresentBroadcast(); } + public void onScreenTurningOn(IKeyguardDrawnCallback callback) { + notifyScreenOn(callback); + } + + public void onScreenTurnedOn() { + notifyScreenTurnedOn(); + mUpdateMonitor.dispatchScreenTurnedOn(); + } + + public void onScreenTurnedOff() { + notifyScreenTurnedOff(); + mUpdateMonitor.dispatchScreenTurnedOff(); + } + private void maybeSendUserPresentBroadcast() { if (mSystemReady && mLockPatternUtils.isLockScreenDisabled( KeyguardUpdateMonitor.getCurrentUser())) { @@ -1082,25 +1113,31 @@ public class KeyguardViewMediator extends SystemUI { mHandler.sendEmptyMessage(VERIFY_UNLOCK); } + private void notifyFinishedGoingToSleep() { + if (DEBUG) Log.d(TAG, "notifyFinishedGoingToSleep"); + mHandler.sendEmptyMessage(NOTIFY_FINISHED_GOING_TO_SLEEP); + } - /** - * Send a message to keyguard telling it the screen just turned on. - * @see #onScreenTurnedOff(int) - * @see #handleNotifyScreenOff - */ - private void notifyScreenOffLocked() { - if (DEBUG) Log.d(TAG, "notifyScreenOffLocked"); - mHandler.sendEmptyMessage(NOTIFY_SCREEN_OFF); + private void notifyStartedWakingUp() { + if (DEBUG) Log.d(TAG, "notifyStartedWakingUp"); + mHandler.sendEmptyMessage(NOTIFY_STARTED_WAKING_UP); } - /** - * Send a message to keyguard telling it the screen just turned on. - * @see #onScreenTurnedOn - * @see #handleNotifyScreenOn - */ - private void notifyScreenOnLocked(IKeyguardShowCallback result) { - if (DEBUG) Log.d(TAG, "notifyScreenOnLocked"); - Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, result); + private void notifyScreenOn(IKeyguardDrawnCallback callback) { + if (DEBUG) Log.d(TAG, "notifyScreenOn"); + Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNING_ON, callback); + mHandler.sendMessage(msg); + } + + private void notifyScreenTurnedOn() { + if (DEBUG) Log.d(TAG, "notifyScreenTurnedOn"); + Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNED_ON); + mHandler.sendMessage(msg); + } + + private void notifyScreenTurnedOff() { + if (DEBUG) Log.d(TAG, "notifyScreenTurnedOff"); + Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_TURNED_OFF); mHandler.sendMessage(msg); } @@ -1187,11 +1224,20 @@ public class KeyguardViewMediator extends SystemUI { case VERIFY_UNLOCK: handleVerifyUnlock(); break; - case NOTIFY_SCREEN_OFF: - handleNotifyScreenOff(); + case NOTIFY_FINISHED_GOING_TO_SLEEP: + handleNotifyFinishedGoingToSleep(); + break; + case NOTIFY_SCREEN_TURNING_ON: + handleNotifyScreenTurningOn((IKeyguardDrawnCallback) msg.obj); + break; + case NOTIFY_SCREEN_TURNED_ON: + handleNotifyScreenTurnedOn(); break; - case NOTIFY_SCREEN_ON: - handleNotifyScreenOn((IKeyguardShowCallback) msg.obj); + case NOTIFY_SCREEN_TURNED_OFF: + handleNotifyScreenTurnedOff(); + break; + case NOTIFY_STARTED_WAKING_UP: + handleNotifyStartedWakingUp(); break; case KEYGUARD_DONE: handleKeyguardDone(msg.arg1 != 0, msg.arg2 != 0); @@ -1354,6 +1400,7 @@ public class KeyguardViewMediator extends SystemUI { setShowingLocked(true); mStatusBarKeyguardViewManager.show(options); mHiding = false; + mWakeAndUnlocking = false; resetKeyguardDonePendingLocked(); mHideAnimationRun = false; updateActivityLockScreenState(); @@ -1375,7 +1422,8 @@ public class KeyguardViewMediator extends SystemUI { // manager until it tells us it's safe to do so with // startKeyguardExitAnimation. ActivityManagerNative.getDefault().keyguardGoingAway( - mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock(), + mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock() + || mWakeAndUnlocking, mStatusBarKeyguardViewManager.isGoingToNotificationShade()); } catch (RemoteException e) { Log.e(TAG, "Error while calling WindowManager", e); @@ -1437,6 +1485,9 @@ public class KeyguardViewMediator extends SystemUI { updateActivityLockScreenState(); adjustStatusBarLocked(); sendUserPresentBroadcast(); + if (mWakeAndUnlocking && mDrawnCallback != null) { + notifyDrawn(mDrawnCallback); + } } } @@ -1498,24 +1549,55 @@ public class KeyguardViewMediator extends SystemUI { } /** - * Handle message sent by {@link #notifyScreenOffLocked()} - * @see #NOTIFY_SCREEN_OFF + * Handle message sent by {@link #notifyFinishedGoingToSleep()} + * @see #NOTIFY_FINISHED_GOING_TO_SLEEP */ - private void handleNotifyScreenOff() { + private void handleNotifyFinishedGoingToSleep() { synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleNotifyScreenOff"); - mStatusBarKeyguardViewManager.onScreenTurnedOff(); + if (DEBUG) Log.d(TAG, "handleNotifyFinishedGoingToSleep"); + mStatusBarKeyguardViewManager.onFinishedGoingToSleep(); } } - /** - * Handle message sent by {@link #notifyScreenOnLocked} - * @see #NOTIFY_SCREEN_ON - */ - private void handleNotifyScreenOn(IKeyguardShowCallback callback) { + private void handleNotifyStartedWakingUp() { + synchronized (KeyguardViewMediator.this) { + if (DEBUG) Log.d(TAG, "handleNotifyWakingUp"); + mStatusBarKeyguardViewManager.onStartedWakingUp(); + } + } + + private void handleNotifyScreenTurningOn(IKeyguardDrawnCallback callback) { synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleNotifyScreenOn"); - mStatusBarKeyguardViewManager.onScreenTurnedOn(callback); + if (DEBUG) Log.d(TAG, "handleNotifyScreenTurningOn"); + if (callback != null) { + if (mWakeAndUnlocking) { + mDrawnCallback = callback; + } else { + notifyDrawn(callback); + } + } + } + } + + private void handleNotifyScreenTurnedOn() { + synchronized (this) { + if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOn"); + mStatusBarKeyguardViewManager.onScreenTurnedOn(); + } + } + + private void handleNotifyScreenTurnedOff() { + synchronized (this) { + if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOff"); + mStatusBarKeyguardViewManager.onScreenTurnedOff(); + } + } + + private void notifyDrawn(final IKeyguardDrawnCallback callback) { + try { + callback.onDrawn(); + } catch (RemoteException e) { + Slog.w(TAG, "Exception calling onDrawn():", e); } } diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java index e9a256c3d065..fe876d7a4d30 100644 --- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java +++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java @@ -171,6 +171,13 @@ public class RingtonePlayer extends SystemUI { } mAsyncPlayer.stop(); } + + @Override + public String getTitle(Uri uri) { + final UserHandle user = Binder.getCallingUserHandle(); + return Ringtone.getTitle(getContextForUser(user), uri, + false /*followSettingsUri*/, false /*allowRemote*/); + } }; private Context getContextForUser(UserHandle user) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index 937615a1fffa..61695b2db2d7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -92,7 +92,8 @@ public class CastTile extends QSTile<QSTile.BooleanState> { @Override protected void handleUpdateState(BooleanState state, Object arg) { - state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing() && !mKeyguard.isTrusted()); + state.visible = !mKeyguard.isSecure() || !mKeyguard.isShowing() + || mKeyguard.canSkipBouncer(); state.label = mContext.getString(R.string.quick_settings_cast_title); state.value = false; state.autoMirrorDrawable = false; 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 07406b98f8be..f3ad9d803394 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -45,6 +45,8 @@ public class CellularTile extends QSTile<QSTile.SignalState> { private final MobileDataController mDataController; private final CellularDetailAdapter mDetailAdapter; + private final CellSignalCallback mSignalCallback = new CellSignalCallback(); + public CellularTile(Host host) { super(host); mController = host.getNetworkController(); @@ -90,8 +92,10 @@ public class CellularTile extends QSTile<QSTile.SignalState> { protected void handleUpdateState(SignalState state, Object arg) { state.visible = mController.hasMobileDataFeature(); if (!state.visible) return; - final CallbackInfo cb = (CallbackInfo) arg; - if (cb == null) return; + CallbackInfo cb = (CallbackInfo) arg; + if (cb == null) { + cb = mSignalCallback.mInfo; + } final Resources r = mContext.getResources(); final int iconId = cb.noSim ? R.drawable.ic_qs_no_sim @@ -152,7 +156,7 @@ public class CellularTile extends QSTile<QSTile.SignalState> { boolean isDataTypeIconWide; } - private final SignalCallback mSignalCallback = new SignalCallbackAdapter() { + private final class CellSignalCallback extends SignalCallbackAdapter { private final CallbackInfo mInfo = new CallbackInfo(); @Override public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index 5d7460460a8b..21cbef21c22a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -79,6 +79,8 @@ public class FlashlightTile extends QSTile<QSTile.BooleanState> implements return; } state.value = value; + } else { + state.value = mFlashlightController.isEnabled(); } final AnimationIcon icon = state.value ? mEnable : mDisable; icon.setAllowAnimation(arg instanceof UserBoolean && ((UserBoolean) arg).userInitiated); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index ddde106a6074..7b83e6a9ca25 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -23,10 +23,9 @@ import android.content.Intent; import com.android.internal.logging.MetricsLogger; import com.android.systemui.Prefs; import com.android.systemui.R; -import com.android.systemui.qs.UsageTracker; import com.android.systemui.qs.QSTile; +import com.android.systemui.qs.UsageTracker; import com.android.systemui.statusbar.policy.HotspotController; -import com.android.systemui.statusbar.policy.KeyguardMonitor; /** Quick settings tile: Hotspot **/ public class HotspotTile extends QSTile<QSTile.BooleanState> { @@ -37,14 +36,12 @@ public class HotspotTile extends QSTile<QSTile.BooleanState> { private final HotspotController mController; private final Callback mCallback = new Callback(); private final UsageTracker mUsageTracker; - private final KeyguardMonitor mKeyguard; public HotspotTile(Host host) { super(host); mController = host.getHotspotController(); mUsageTracker = newUsageTracker(host.getContext()); mUsageTracker.setListening(true); - mKeyguard = host.getKeyguardMonitor(); } @Override @@ -97,7 +94,7 @@ public class HotspotTile extends QSTile<QSTile.BooleanState> { if (arg instanceof Boolean) { state.value = (boolean) arg; } else { - mController.isHotspotEnabled(); + state.value = mController.isHotspotEnabled(); } state.icon = state.visible && state.value ? mEnable : mDisable; } 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 f7f7acb8a072..3d0dc7b5c1a2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java @@ -45,6 +45,8 @@ public class IntentTile extends QSTile<QSTile.State> { private int mCurrentUserId; private String mIntentPackage; + private Intent mLastIntent; + private IntentTile(Host host, String action) { super(host); mContext.registerReceiver(mReceiver, new IntentFilter(action)); @@ -112,8 +114,16 @@ public class IntentTile extends QSTile<QSTile.State> { @Override protected void handleUpdateState(State state, Object arg) { - if (!(arg instanceof Intent)) return; - final Intent intent = (Intent) arg; + Intent intent = (Intent) arg; + if (intent == null) { + if (mLastIntent == null) { + return; + } + // No intent but need to refresh state, just use the last one. + intent = mLastIntent; + } + // Save the last one in case we need it later. + mLastIntent = intent; state.visible = intent.getBooleanExtra("visible", true); state.contentDescription = intent.getStringExtra("contentDescription"); state.label = intent.getStringExtra("label"); 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 3bfff2faba08..e654efd4dd2a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -35,7 +35,6 @@ import com.android.systemui.qs.SignalTileView; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.AccessPointController; import com.android.systemui.statusbar.policy.NetworkController.IconState; -import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; import com.android.systemui.statusbar.policy.SignalCallbackAdapter; import java.util.List; @@ -49,6 +48,8 @@ public class WifiTile extends QSTile<QSTile.SignalState> { private final WifiDetailAdapter mDetailAdapter; private final QSTile.SignalState mStateBeforeClick = newTileState(); + private final WifiSignalCallback mSignalCallback = new WifiSignalCallback(); + public WifiTile(Host host) { super(host); mController = host.getNetworkController(); @@ -118,8 +119,10 @@ public class WifiTile extends QSTile<QSTile.SignalState> { protected void handleUpdateState(SignalState state, Object arg) { state.visible = true; if (DEBUG) Log.d(TAG, "handleUpdateState arg=" + arg); - if (arg == null) return; CallbackInfo cb = (CallbackInfo) arg; + if (cb == null) { + cb = mSignalCallback.mInfo; + } boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.enabledDesc != null); boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.enabledDesc == null); @@ -213,20 +216,21 @@ public class WifiTile extends QSTile<QSTile.SignalState> { } } - private final SignalCallback mSignalCallback = new SignalCallbackAdapter() { + private final class WifiSignalCallback extends SignalCallbackAdapter { + final CallbackInfo mInfo = new CallbackInfo(); + @Override public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, boolean activityIn, boolean activityOut, String description) { if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled); - final CallbackInfo info = new CallbackInfo(); - info.enabled = enabled; - info.connected = qsIcon.visible; - info.wifiSignalIconId = qsIcon.icon; - info.enabledDesc = description; - info.activityIn = activityIn; - info.activityOut = activityOut; - info.wifiSignalContentDescription = qsIcon.contentDescription; - refreshState(info); + mInfo.enabled = enabled; + mInfo.connected = qsIcon.visible; + mInfo.wifiSignalIconId = qsIcon.icon; + mInfo.enabledDesc = description; + mInfo.activityIn = activityIn; + mInfo.activityOut = activityOut; + mInfo.wifiSignalContentDescription = qsIcon.contentDescription; + refreshState(mInfo); } }; 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 17db4718bd26..298a1cced3ff 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -48,6 +48,8 @@ import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.SystemProperties; @@ -85,6 +87,15 @@ public class SystemServicesProxy { final static String TAG = "SystemServicesProxy"; final static BitmapFactory.Options sBitmapOptions; + final static HandlerThread sBgThread; + + static { + sBgThread = new HandlerThread("Recents-SystemServicesProxy", + android.os.Process.THREAD_PRIORITY_BACKGROUND); + sBgThread.start(); + sBitmapOptions = new BitmapFactory.Options(); + sBitmapOptions.inMutable = true; + } AccessibilityManager mAccm; ActivityManager mAm; @@ -98,17 +109,14 @@ public class SystemServicesProxy { String mRecentsPackage; ComponentName mAssistComponent; + Handler mBgThreadHandler; + Bitmap mDummyIcon; int mDummyThumbnailWidth; int mDummyThumbnailHeight; Paint mBgProtectionPaint; Canvas mBgProtectionCanvas; - static { - sBitmapOptions = new BitmapFactory.Options(); - sBitmapOptions.inMutable = true; - } - /** Private constructor */ public SystemServicesProxy(Context context) { mAccm = AccessibilityManager.getInstance(context); @@ -121,6 +129,7 @@ public class SystemServicesProxy { mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mDisplay = mWm.getDefaultDisplay(); mRecentsPackage = context.getPackageName(); + mBgThreadHandler = new Handler(sBgThread.getLooper()); // Get the dummy thumbnail width/heights Resources res = context.getResources(); @@ -383,12 +392,17 @@ public class SystemServicesProxy { } /** Removes the task */ - public void removeTask(int taskId) { + public void removeTask(final int taskId) { if (mAm == null) return; if (Constants.DebugFlags.App.EnableSystemServicesProxy) return; // Remove the task. - mAm.removeTask(taskId); + mBgThreadHandler.post(new Runnable() { + @Override + public void run() { + mAm.removeTask(taskId); + } + }); } /** @@ -656,22 +670,6 @@ public class SystemServicesProxy { return windowRect; } - /** - * Takes a screenshot of the current surface. - */ - public Bitmap takeScreenshot() { - DisplayInfo di = new DisplayInfo(); - mDisplay.getDisplayInfo(di); - return SurfaceControl.screenshot(di.getNaturalWidth(), di.getNaturalHeight()); - } - - /** - * Takes a screenshot of the current app. - */ - public Bitmap takeAppScreenshot() { - return takeScreenshot(); - } - /** Starts an activity from recents. */ public boolean startActivityFromRecents(Context context, int taskId, String taskName, ActivityOptions options) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java index b2aa2b67c574..ad25c85860ed 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java @@ -343,11 +343,14 @@ public class RecentsTaskLoader { if (infoHandle.info != null) { label = ssp.getActivityLabel(infoHandle.info); mActivityLabelCache.put(taskKey, label); + return label; } else { Log.w(TAG, "Missing ActivityInfo for " + taskKey.baseIntent.getComponent() + " u=" + taskKey.userId); } - return label; + // If the activity info does not exist or fails to load, return an empty label for now, + // but do not cache it + return ""; } /** Returns the content description using as many cached values as we can. */ @@ -358,14 +361,22 @@ public class RecentsTaskLoader { if (label != null) { return label; } + // If the given activity label is empty, don't compute or cache the content description + if (activityLabel.isEmpty()) { + return ""; + } + label = ssp.getContentDescription(taskKey.baseIntent, taskKey.userId, activityLabel, res); if (label != null) { mContentDescriptionCache.put(taskKey, label); + return label; } else { Log.w(TAG, "Missing content description for " + taskKey.baseIntent.getComponent() + " u=" + taskKey.userId); } - return label; + // If the content description does not exist, return an empty label for now, but do not + // cache it + return ""; } /** Returns the activity icon using as many cached values as we can. */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java index 78b351279f6e..2e0b80a9a512 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java @@ -316,7 +316,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { overscrollRange); // Invalidate to kick off computeScroll mSv.invalidate(); - } else if (mScroller.isScrollOutOfBounds()) { + } else if (mIsScrolling && mScroller.isScrollOutOfBounds()) { // Animate the scroll back into bounds mScroller.animateBoundScroll(); } else if (mActiveTaskView == null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java index 7cde44c44487..403af7099c6c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java @@ -656,12 +656,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } private void setContentAlpha(float contentAlpha) { - int layerType = contentAlpha == 0.0f || contentAlpha == 1.0f ? LAYER_TYPE_NONE - : LAYER_TYPE_HARDWARE; View contentView = getContentView(); - int currentLayerType = contentView.getLayerType(); - if (currentLayerType != layerType) { - contentView.setLayerType(layerType, null); + if (contentView.hasOverlappingRendering()) { + int layerType = contentAlpha == 0.0f || contentAlpha == 1.0f ? LAYER_TYPE_NONE + : LAYER_TYPE_HARDWARE; + int currentLayerType = contentView.getLayerType(); + if (currentLayerType != layerType) { + contentView.setLayerType(layerType, null); + } } contentView.setAlpha(contentAlpha); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index f62dc5981e41..00fa65379026 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -729,11 +729,15 @@ public abstract class BaseStatusBar extends SystemUI implements } protected void setNotificationShown(StatusBarNotification n) { - mNotificationListener.setNotificationsShown(new String[] { n.getKey() }); + setNotificationsShown(new String[]{n.getKey()}); } protected void setNotificationsShown(String[] keys) { - mNotificationListener.setNotificationsShown(keys); + try { + mNotificationListener.setNotificationsShown(keys); + } catch (RuntimeException e) { + Log.d(TAG, "failed setNotificationsShown: ", e); + } } protected boolean isCurrentProfile(int userId) { @@ -1324,14 +1328,20 @@ public abstract class BaseStatusBar extends SystemUI implements View bigContentViewLocal = null; View headsUpContentViewLocal = null; try { - contentViewLocal = contentView.apply(mContext, contentContainer, + contentViewLocal = contentView.apply( + sbn.getPackageContext(mContext), + contentContainer, mOnClickHandler); if (bigContentView != null) { - bigContentViewLocal = bigContentView.apply(mContext, contentContainer, + bigContentViewLocal = bigContentView.apply( + sbn.getPackageContext(mContext), + contentContainer, mOnClickHandler); } if (headsUpContentView != null) { - headsUpContentViewLocal = headsUpContentView.apply(mContext, contentContainer, + headsUpContentViewLocal = headsUpContentView.apply( + sbn.getPackageContext(mContext), + contentContainer, mOnClickHandler); } } @@ -1358,7 +1368,8 @@ public abstract class BaseStatusBar extends SystemUI implements View publicViewLocal = null; if (publicNotification != null) { try { - publicViewLocal = publicNotification.contentView.apply(mContext, + publicViewLocal = publicNotification.contentView.apply( + sbn.getPackageContext(mContext), contentContainerPublic, mOnClickHandler); if (publicViewLocal != null) { @@ -1514,6 +1525,7 @@ public abstract class BaseStatusBar extends SystemUI implements // // In most cases, when FLAG_AUTO_CANCEL is set, the notification will // become canceled shortly by NoMan, but we can't assume that. + HeadsUpManager.setIsClickedNotification(row, true); mHeadsUpManager.releaseImmediately(notificationKey); } new Thread() { @@ -1833,7 +1845,7 @@ public abstract class BaseStatusBar extends SystemUI implements logUpdate(entry, n); } boolean applyInPlace = shouldApplyInPlace(entry, n); - boolean shouldInterrupt = shouldInterrupt(entry); + boolean shouldInterrupt = shouldInterrupt(entry, notification); boolean alertAgain = alertAgain(entry, n); entry.notification = notification; @@ -1977,15 +1989,18 @@ public abstract class BaseStatusBar extends SystemUI implements // Reapply the RemoteViews contentView.reapply(mContext, entry.getContentView(), mOnClickHandler); if (bigContentView != null && entry.getExpandedContentView() != null) { - bigContentView.reapply(mContext, entry.getExpandedContentView(), + bigContentView.reapply(notification.getPackageContext(mContext), + entry.getExpandedContentView(), mOnClickHandler); } View headsUpChild = entry.getHeadsUpContentView(); if (headsUpContentView != null && headsUpChild != null) { - headsUpContentView.reapply(mContext, headsUpChild, mOnClickHandler); + headsUpContentView.reapply(notification.getPackageContext(mContext), + headsUpChild, mOnClickHandler); } if (publicContentView != null && entry.getPublicContentView() != null) { - publicContentView.reapply(mContext, entry.getPublicContentView(), mOnClickHandler); + publicContentView.reapply(notification.getPackageContext(mContext), + entry.getPublicContentView(), mOnClickHandler); } // update the contentIntent mNotificationClicker.register(entry.row, notification); @@ -2005,7 +2020,10 @@ public abstract class BaseStatusBar extends SystemUI implements } protected boolean shouldInterrupt(Entry entry) { - StatusBarNotification sbn = entry.notification; + return shouldInterrupt(entry, entry.notification); + } + + protected boolean shouldInterrupt(Entry entry, StatusBarNotification sbn) { if (mNotificationData.shouldFilterOut(sbn)) { if (DEBUG) { Log.d(TAG, "Skipping HUN check for " + sbn.getKey() + " since it's filtered out."); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java index ccec759dec7f..71baf5782109 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java @@ -374,7 +374,11 @@ public abstract class ExpandableView extends FrameLayout { } private void updateClipping() { - mClipRect.set(0, mClipTopOptimization, getWidth(), getActualHeight()); + int top = mClipTopOptimization; + if (top >= getActualHeight()) { + top = getActualHeight() - 1; + } + mClipRect.set(0, top, getWidth(), getActualHeight()); setClipBounds(mClipRect); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java index 58fb2b1181ba..164c496ff19d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java @@ -69,7 +69,7 @@ public class KeyguardAffordanceView extends ImageView { private float mCircleStartValue; private boolean mCircleWillBeHidden; private int[] mTempPoint = new int[2]; - private float mImageScale; + private float mImageScale = 1f; private int mCircleColor; private boolean mIsLeft; private View mPreviewView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java index 6670ae0e7004..10019f91fc80 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java @@ -86,9 +86,9 @@ public class KeyguardAffordanceHelper { mContext = context; mCallback = callback; initIcons(); - updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false); - updateIcon(mCenterIcon, 0.0f, mCenterIcon.getRestingAlpha(), false, false); - updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false); + updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true); + updateIcon(mCenterIcon, 0.0f, mCenterIcon.getRestingAlpha(), false, false, true); + updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true); initDimens(); } @@ -387,15 +387,15 @@ public class KeyguardAffordanceHelper { boolean slowAnimation = isReset && isBelowFalsingThreshold(); if (!isReset) { updateIcon(targetView, radius, alpha + fadeOutAlpha * targetView.getRestingAlpha(), - false, false); + false, false, false); } else { updateIcon(targetView, 0.0f, fadeOutAlpha * targetView.getRestingAlpha(), - animateIcons, slowAnimation); + animateIcons, slowAnimation, false); } updateIcon(otherView, 0.0f, fadeOutAlpha * otherView.getRestingAlpha(), - animateIcons, slowAnimation); + animateIcons, slowAnimation, false); updateIcon(mCenterIcon, 0.0f, fadeOutAlpha * mCenterIcon.getRestingAlpha(), - animateIcons, slowAnimation); + animateIcons, slowAnimation, false); mTranslation = translation; } @@ -431,13 +431,13 @@ public class KeyguardAffordanceHelper { public void animateHideLeftRightIcon() { cancelAnimation(); - updateIcon(mRightIcon, 0f, 0f, true, false); - updateIcon(mLeftIcon, 0f, 0f, true, false); + updateIcon(mRightIcon, 0f, 0f, true, false, false); + updateIcon(mLeftIcon, 0f, 0f, true, false, false); } private void updateIcon(KeyguardAffordanceView view, float circleRadius, float alpha, - boolean animate, boolean slowRadiusAnimation) { - if (view.getVisibility() != View.VISIBLE) { + boolean animate, boolean slowRadiusAnimation, boolean force) { + if (view.getVisibility() != View.VISIBLE && !force) { return; } view.setCircleRadius(circleRadius, slowRadiusAnimation); 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 815e1235f854..6627360a641a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -18,7 +18,6 @@ package com.android.systemui.statusbar.phone; import android.app.ActivityManager; import android.app.ActivityManagerNative; -import android.app.Application; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -30,8 +29,6 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Configuration; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.InsetDrawable; import android.os.AsyncTask; import android.os.Bundle; import android.os.IBinder; @@ -109,6 +106,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private PhoneStatusBar mPhoneStatusBar; private final Interpolator mLinearOutSlowInInterpolator; + private boolean mUserSetupComplete; private boolean mPrewarmBound; private Messenger mPrewarmMessenger; private final ServiceConnection mPrewarmConnection = new ServiceConnection() { @@ -253,12 +251,18 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL updateCameraVisibility(); // in case onFinishInflate() was called too early } + public void setUserSetupComplete(boolean userSetupComplete) { + mUserSetupComplete = userSetupComplete; + updateCameraVisibility(); + updateLeftAffordanceIcon(); + } + private Intent getCameraIntent() { KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext); - boolean currentUserHasTrust = updateMonitor.getUserHasTrust( + boolean canSkipBouncer = updateMonitor.getUserCanSkipBouncer( KeyguardUpdateMonitor.getCurrentUser()); boolean secure = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser()); - return (secure && !currentUserHasTrust) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT; + return (secure && !canSkipBouncer) ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT; } private void updateCameraVisibility() { @@ -270,7 +274,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL PackageManager.MATCH_DEFAULT_ONLY, KeyguardUpdateMonitor.getCurrentUser()); boolean visible = !isCameraDisabledByDpm() && resolved != null - && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance); + && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance) + && mUserSetupComplete; mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE); } @@ -278,16 +283,16 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL mLeftIsVoiceAssist = canLaunchVoiceAssist(); int drawableId; int contentDescription; + boolean visible = mUserSetupComplete; if (mLeftIsVoiceAssist) { - mLeftAffordanceView.setVisibility(View.VISIBLE); drawableId = R.drawable.ic_mic_26dp; contentDescription = R.string.accessibility_voice_assist_button; } else { - boolean visible = isPhoneVisible(); - mLeftAffordanceView.setVisibility(visible ? View.VISIBLE : View.GONE); + visible &= isPhoneVisible(); drawableId = R.drawable.ic_phone_24dp; contentDescription = R.string.accessibility_phone_button; } + mLeftAffordanceView.setVisibility(visible ? View.VISIBLE : View.GONE); mLeftAffordanceView.setImageDrawable(mContext.getDrawable(drawableId)); mLeftAffordanceView.setContentDescription(mContext.getString(contentDescription)); } @@ -629,13 +634,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL } @Override - public void onScreenTurnedOn() { - mLockIcon.setScreenOn(true); + public void onStartedWakingUp() { + mLockIcon.setDeviceInteractive(true); } @Override - public void onScreenTurnedOff(int why) { - mLockIcon.setScreenOn(false); + public void onFinishedGoingToSleep(int why) { + mLockIcon.setDeviceInteractive(false); } @Override @@ -644,7 +649,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL } @Override - public void onFingerprintAuthenticated(int userId) { + public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { } @Override @@ -654,6 +659,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL @Override public void onFingerprintHelp(int msgId, String helpString) { + if (!KeyguardUpdateMonitor.getInstance(mContext).isUnlockingWithFingerprintAllowed()) { + return; + } mLockIcon.setTransientFpError(true); mIndicationController.showTransientIndication(helpString, getResources().getColor(R.color.system_warning_color, null)); @@ -663,6 +671,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL @Override public void onFingerprintError(int msgId, String errString) { + if (!KeyguardUpdateMonitor.getInstance(mContext).isUnlockingWithFingerprintAllowed()) { + return; + } // TODO: Go to bouncer if this is "too many attempts" (lockout) error. mIndicationController.showTransientIndication(errString, getResources().getColor(R.color.system_warning_color, null)); 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 a7afec4c3fc6..e9b2c611ae34 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -29,6 +29,7 @@ import com.android.keyguard.KeyguardHostView; import com.android.keyguard.KeyguardSecurityView; import com.android.keyguard.R; import com.android.keyguard.ViewMediatorCallback; +import com.android.systemui.DejankUtils; import static com.android.keyguard.KeyguardHostView.OnDismissAction; import static com.android.keyguard.KeyguardSecurityModel.SecurityMode; @@ -46,7 +47,6 @@ public class KeyguardBouncer { private KeyguardHostView mKeyguardView; private ViewGroup mRoot; private boolean mShowingSoon; - private Choreographer mChoreographer = Choreographer.getInstance(); private int mBouncerPromptReason; public KeyguardBouncer(Context context, ViewMediatorCallback callback, @@ -70,16 +70,13 @@ public class KeyguardBouncer { 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()) { mShowingSoon = true; // Split up the work over multiple frames. - mChoreographer.postCallbackDelayed(Choreographer.CALLBACK_ANIMATION, mShowRunnable, - null, 16); + DejankUtils.postAfterTraversal(mShowRunnable); } } @@ -107,7 +104,7 @@ public class KeyguardBouncer { } private void cancelShowRunnable() { - mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION, mShowRunnable, null); + DejankUtils.removeCallbacks(mShowRunnable); mShowingSoon = false; } @@ -165,6 +162,7 @@ public class KeyguardBouncer { if (wasInitialized) { mKeyguardView.showPrimarySecurityScreen(); } + mBouncerPromptReason = mCallback.getBouncerPromptReason(); } private void ensureView() { 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 6bcb7665b72d..06d2fca442f0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java @@ -47,9 +47,9 @@ public class LockIcon extends KeyguardAffordanceView { private static final int STATE_FINGERPRINT_ERROR = 4; private int mLastState = 0; - private boolean mLastScreenOn; + private boolean mLastDeviceInteractive; private boolean mTransientFpError; - private boolean mScreenOn; + private boolean mDeviceInteractive; private final TrustDrawable mTrustDrawable; private final UnlockMethodCache mUnlockMethodCache; private AccessibilityController mAccessibilityController; @@ -83,13 +83,14 @@ public class LockIcon extends KeyguardAffordanceView { update(); } - public void setScreenOn(boolean screenOn) { - mScreenOn = screenOn; + public void setDeviceInteractive(boolean deviceInteractive) { + mDeviceInteractive = deviceInteractive; update(); } public void update() { - boolean visible = isShown() && KeyguardUpdateMonitor.getInstance(mContext).isScreenOn(); + boolean visible = isShown() + && KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive(); if (visible) { mTrustDrawable.start(); } else { @@ -101,8 +102,9 @@ public class LockIcon extends KeyguardAffordanceView { // TODO: Real icon for facelock. int state = getState(); boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR; - if (state != mLastState || mScreenOn != mLastScreenOn) { - int iconRes = getAnimationResForTransition(mLastState, state, mLastScreenOn, mScreenOn); + if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive) { + int iconRes = getAnimationResForTransition(mLastState, state, mLastDeviceInteractive, + mDeviceInteractive); if (iconRes == R.drawable.lockscreen_fingerprint_draw_off_animation) { anyFingerprintIcon = true; } @@ -149,7 +151,7 @@ public class LockIcon extends KeyguardAffordanceView { } } mLastState = state; - mLastScreenOn = mScreenOn; + mLastDeviceInteractive = mDeviceInteractive; } // Hide trust circle when fingerprint is running. @@ -214,7 +216,7 @@ public class LockIcon extends KeyguardAffordanceView { } 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 - && !mUnlockMethodCache.isCurrentlyInsecure()) { + && !mUnlockMethodCache.isTrusted()) { return R.drawable.lockscreen_fingerprint_draw_off_animation; } else if (newState == STATE_FINGERPRINT && !oldScreenOn && screenOn) { return R.drawable.lockscreen_fingerprint_draw_on_animation; @@ -224,13 +226,14 @@ public class LockIcon extends KeyguardAffordanceView { } private int getState() { - boolean fingerprintRunning = - KeyguardUpdateMonitor.getInstance(mContext).isFingerprintDetectionRunning(); - if (mUnlockMethodCache.isCurrentlyInsecure()) { + KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext); + boolean fingerprintRunning = updateMonitor.isFingerprintDetectionRunning(); + boolean unlockingAllowed = updateMonitor.isUnlockingWithFingerprintAllowed(); + if (mUnlockMethodCache.canSkipBouncer()) { return STATE_LOCK_OPEN; } else if (mTransientFpError) { return STATE_FINGERPRINT_ERROR; - } else if (fingerprintRunning) { + } else if (fingerprintRunning && unlockingAllowed) { return STATE_FINGERPRINT; } else if (mUnlockMethodCache.isFaceUnlockRunning()) { return STATE_FACE_UNLOCK; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index f40f5016528b..59cf2bfaac9b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -40,6 +40,7 @@ import android.view.MotionEvent; import android.view.Surface; import android.view.View; import android.view.ViewGroup; +import android.view.ViewRootImpl; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.FrameLayout; @@ -90,6 +91,7 @@ public class NavigationBarView extends LinearLayout { private OnVerticalChangedListener mOnVerticalChangedListener; private boolean mIsLayoutRtl; + private boolean mLayoutTransitionsEnabled; private class NavTransitionListener implements TransitionListener { private boolean mBackTransitioning; @@ -184,6 +186,15 @@ public class NavigationBarView extends LinearLayout { mBarTransitions = new NavigationBarTransitions(this); } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + ViewRootImpl root = getViewRootImpl(); + if (root != null) { + root.setDrawDuringWindowsAnimating(true); + } + } + public BarTransitions getBarTransitions() { return mBarTransitions; } @@ -323,13 +334,6 @@ public class NavigationBarView extends LinearLayout { if (!lt.getTransitionListeners().contains(mTransitionListener)) { lt.addTransitionListener(mTransitionListener); } - if (!mScreenOn && mCurrentView != null) { - lt.disableTransitionType( - LayoutTransition.CHANGE_APPEARING | - LayoutTransition.CHANGE_DISAPPEARING | - LayoutTransition.APPEARING | - LayoutTransition.DISAPPEARING); - } } } if (inLockTask() && disableRecent && !disableHome) { @@ -357,6 +361,46 @@ public class NavigationBarView extends LinearLayout { } } + public void setWakeAndUnlocking(boolean wakeAndUnlocking) { + setUseFadingAnimations(wakeAndUnlocking); + setLayoutTransitionsEnabled(!wakeAndUnlocking); + } + + private void setLayoutTransitionsEnabled(boolean enabled) { + mLayoutTransitionsEnabled = enabled; + ViewGroup navButtons = (ViewGroup) mCurrentView.findViewById(R.id.nav_buttons); + LayoutTransition lt = navButtons.getLayoutTransition(); + if (lt != null) { + if (enabled) { + lt.enableTransitionType(LayoutTransition.APPEARING); + lt.enableTransitionType(LayoutTransition.DISAPPEARING); + lt.enableTransitionType(LayoutTransition.CHANGE_APPEARING); + lt.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING); + } else { + lt.disableTransitionType(LayoutTransition.APPEARING); + lt.disableTransitionType(LayoutTransition.DISAPPEARING); + lt.disableTransitionType(LayoutTransition.CHANGE_APPEARING); + lt.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING); + } + } + } + + private void setUseFadingAnimations(boolean useFadingAnimations) { + WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams(); + if (lp != null) { + boolean old = lp.windowAnimations != 0; + if (!old && useFadingAnimations) { + lp.windowAnimations = R.style.Animation_NavigationBarFadeIn; + } else if (old && !useFadingAnimations) { + lp.windowAnimations = 0; + } else { + return; + } + WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE); + wm.updateViewLayout(this, lp); + } + } + public void setSlippery(boolean newSlippery) { WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams(); if (lp != null) { @@ -415,6 +459,7 @@ public class NavigationBarView extends LinearLayout { } mCurrentView = mRotatedViews[rot]; mCurrentView.setVisibility(View.VISIBLE); + setLayoutTransitionsEnabled(mLayoutTransitionsEnabled); getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener); 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 094b9b563f91..17fd7a738ea9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -26,6 +26,7 @@ import android.content.res.Configuration; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; +import android.graphics.Rect; import android.util.AttributeSet; import android.util.MathUtils; import android.view.MotionEvent; @@ -42,6 +43,7 @@ import android.widget.TextView; import com.android.internal.logging.MetricsLogger; import com.android.keyguard.KeyguardStatusView; +import com.android.systemui.DejankUtils; import com.android.systemui.EventLogConstants; import com.android.systemui.EventLogTags; import com.android.systemui.R; @@ -79,6 +81,8 @@ public class NotificationPanelView extends PanelView implements private static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs"; private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek"; + private static final Rect mDummyDirtyRect = new Rect(0, 0, 1, 1); + public static final long DOZE_ANIMATION_DURATION = 700; private KeyguardAffordanceHelper mAfforanceHelper; @@ -198,10 +202,12 @@ public class NotificationPanelView extends PanelView implements private int mPositionMinSideMargin; private int mLastOrientation = -1; private boolean mClosingWithAlphaFadeOut; + private boolean mHeadsUpAnimatingAway; private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() { @Override public void run() { + mHeadsUpAnimatingAway = false; notifyBarPanelExpansionChanged(); } }; @@ -621,6 +627,7 @@ public class NotificationPanelView extends PanelView implements && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, h)) { mQsTracking = true; onQsExpansionStarted(); + notifyExpandingFinished(); mInitialHeightOnTouch = mQsExpansionHeight; mInitialTouchY = y; mInitialTouchX = x; @@ -773,14 +780,7 @@ public class NotificationPanelView extends PanelView implements && mQsExpansionEnabled) { mTwoFingerQsExpandPossible = true; } - final int pointerCount = event.getPointerCount(); - final boolean twoFingerDrag = action == MotionEvent.ACTION_POINTER_DOWN - && pointerCount == 2; - final boolean stylusClickDrag = action == MotionEvent.ACTION_DOWN - && pointerCount == 1 && event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS - && (event.isButtonPressed(MotionEvent.BUTTON_SECONDARY) - || event.isButtonPressed(MotionEvent.BUTTON_TERTIARY)); - if (mTwoFingerQsExpandPossible && (twoFingerDrag || stylusClickDrag) + if (mTwoFingerQsExpandPossible && isOpenQsEvent(event) && event.getY(event.getActionIndex()) < mStatusBarMinHeight) { MetricsLogger.count(mContext, COUNTER_PANEL_OPEN_QS, 1); mQsExpandImmediate = true; @@ -799,6 +799,24 @@ public class NotificationPanelView extends PanelView implements || y <= mQsContainer.getY() + mQsContainer.getHeight()); } + private boolean isOpenQsEvent(MotionEvent event) { + final int pointerCount = event.getPointerCount(); + final int action = event.getActionMasked(); + + final boolean twoFingerDrag = action == MotionEvent.ACTION_POINTER_DOWN + && pointerCount == 2; + + final boolean stylusButtonClickDrag = action == MotionEvent.ACTION_DOWN + && (event.isButtonPressed(MotionEvent.BUTTON_STYLUS_PRIMARY) + || event.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY)); + + final boolean mouseButtonClickDrag = action == MotionEvent.ACTION_DOWN + && (event.isButtonPressed(MotionEvent.BUTTON_SECONDARY) + || event.isButtonPressed(MotionEvent.BUTTON_TERTIARY)); + + return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag; + } + private void handleQsDown(MotionEvent event) { if (event.getActionMasked() == MotionEvent.ACTION_DOWN && shouldQuickSettingsIntercept(event.getX(), event.getY(), -1)) { @@ -809,9 +827,7 @@ public class NotificationPanelView extends PanelView implements mInitialTouchX = event.getY(); // If we interrupt an expansion gesture here, make sure to update the state correctly. - if (mIsExpanding) { - onExpandingFinished(); - } + notifyExpandingFinished(); } } @@ -1765,7 +1781,22 @@ public class NotificationPanelView extends PanelView implements mIsExpanding = false; mScrollYOverride = -1; if (isFullyCollapsed()) { - setListening(false); + DejankUtils.postAfterTraversal(new Runnable() { + @Override + public void run() { + setListening(false); + } + }); + + // Workaround b/22639032: Make sure we invalidate something because else RenderThread + // thinks we are actually drawing a frame put in reality we don't, so RT doesn't go + // ahead with rendering and we jank. + postOnAnimation(new Runnable() { + @Override + public void run() { + getParent().invalidateChild(NotificationPanelView.this, mDummyDirtyRect); + } + }); } else { setListening(true); } @@ -2262,6 +2293,7 @@ public class NotificationPanelView extends PanelView implements mHeadsUpExistenceChangedRunnable.run(); updateNotificationTranslucency(); } else { + mHeadsUpAnimatingAway = true; mNotificationStackScroller.runAfterAnimationFinished( mHeadsUpExistenceChangedRunnable); } @@ -2352,4 +2384,8 @@ public class NotificationPanelView extends PanelView implements public void clearNotificattonEffects() { mStatusBar.clearNotificationEffects(); } + + protected boolean isPanelVisibleBecauseOfHeadsUp() { + return mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway; + } } 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 889160dc2955..8b25e0814cb5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -111,7 +111,7 @@ public abstract class PanelView extends FrameLayout { */ private float mNextCollapseSpeedUpFactor = 1.0f; - private boolean mExpanding; + protected boolean mExpanding; private boolean mGestureWaitForTouchSlop; private boolean mIgnoreXTouchSlop; private Runnable mPeekRunnable = new Runnable() { @@ -137,7 +137,7 @@ public abstract class PanelView extends FrameLayout { } } - private void notifyExpandingFinished() { + protected final void notifyExpandingFinished() { if (mExpanding) { mExpanding = false; onExpandingFinished(); @@ -1009,10 +1009,12 @@ public abstract class PanelView extends FrameLayout { protected void notifyBarPanelExpansionChanged() { mBar.panelExpansionChanged(this, mExpandedFraction, mExpandedFraction > 0f || mPeekPending - || mPeekAnimator != null || mInstantExpanding || mHeadsUpManager.hasPinnedHeadsUp() + || mPeekAnimator != null || mInstantExpanding || isPanelVisibleBecauseOfHeadsUp() || mTracking || mHeightAnimator != null); } + protected abstract boolean isPanelVisibleBecauseOfHeadsUp(); + /** * Gets called when the user performs a click anywhere in the empty area of the panel. * 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 1e78f66e6ee8..86755d178e8c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -198,6 +198,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public static final boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true; + public static final String ACTION_FAKE_ARTWORK = "fake_artwork"; + private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000; private static final int MSG_CLOSE_PANELS = 1001; private static final int MSG_OPEN_SETTINGS_PANEL = 1002; @@ -364,6 +366,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mUserSetup = userSetup; if (!mUserSetup && mStatusBarView != null) animateCollapseQuickSettings(); + if (mKeyguardBottomArea != null) { + mKeyguardBottomArea.setUserSetupComplete(mUserSetup); + } } if (mIconPolicy != null) { mIconPolicy.setCurrentUserSetup(mUserSetup); @@ -434,6 +439,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void onPlaybackStateChanged(PlaybackState state) { super.onPlaybackStateChanged(state); if (DEBUG_MEDIA) Log.v(TAG, "DEBUG_MEDIA: onPlaybackStateChanged: " + state); + if (state != null) { + if (!isPlaybackActive(state.getState())) { + clearCurrentMediaNotification(); + updateMediaMetaData(true); + } + } } @Override @@ -591,7 +602,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, addNavigationBar(); // Lastly, call to the icon policy to install/update all the icons. - mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController); + mIconPolicy = new PhoneStatusBarPolicy(mContext, mCastController, mHotspotController, + mUserInfoController); mIconPolicy.setCurrentUserSetup(mUserSetup); mSettingsObserver.onChange(false); // set up @@ -834,12 +846,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mFlashlightController = new FlashlightController(mContext); mKeyguardBottomArea.setFlashlightController(mFlashlightController); mKeyguardBottomArea.setPhoneStatusBar(this); + mKeyguardBottomArea.setUserSetupComplete(mUserSetup); mAccessibilityController = new AccessibilityController(mContext); mKeyguardBottomArea.setAccessibilityController(mAccessibilityController); mNextAlarmController = new NextAlarmController(mContext); mKeyguardMonitor = new KeyguardMonitor(mContext); if (UserSwitcherController.isUserSwitcherAvailable(UserManager.get(mContext))) { - mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor); + mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor, + mHandler); } mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext, (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), @@ -890,11 +904,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); + context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); + + IntentFilter demoFilter = new IntentFilter(); if (DEBUG_MEDIA_FAKE_ARTWORK) { - filter.addAction("fake_artwork"); + demoFilter.addAction(ACTION_FAKE_ARTWORK); } - filter.addAction(ACTION_DEMO); - context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null); + demoFilter.addAction(ACTION_DEMO); + context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter, + android.Manifest.permission.DUMP, null); // listen for USER_SETUP_COMPLETE setting (per-user) resetUserSetupObserver(); @@ -1193,6 +1211,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (mHeadsUpManager.isHeadsUp(key)) { deferRemoval = !mHeadsUpManager.removeNotification(key); } + if (key.equals(mMediaNotificationKey)) { + clearCurrentMediaNotification(); + updateMediaMetaData(true); + } if (deferRemoval) { mLatestRankingMap = ranking; mHeadsUpEntriesToRemoveOnSwitch.add(mHeadsUpManager.getEntry(key)); @@ -1486,23 +1508,31 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, synchronized (mNotificationData) { ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications(); final int N = activeNotifications.size(); + + // Promote the media notification with a controller in 'playing' state, if any. Entry mediaNotification = null; MediaController controller = null; for (int i = 0; i < N; i++) { final Entry entry = activeNotifications.get(i); if (isMediaNotification(entry)) { - final MediaSession.Token token = entry.notification.getNotification().extras + final MediaSession.Token token = + entry.notification.getNotification().extras .getParcelable(Notification.EXTRA_MEDIA_SESSION); if (token != null) { - controller = new MediaController(mContext, token); - if (controller != null) { - // we've got a live one, here + MediaController aController = new MediaController(mContext, token); + if (PlaybackState.STATE_PLAYING == + getMediaControllerPlaybackState(aController)) { + if (DEBUG_MEDIA) { + Log.v(TAG, "DEBUG_MEDIA: found mediastyle controller matching " + + entry.notification.getKey()); + } mediaNotification = entry; + controller = aController; + break; } } } } - if (mediaNotification == null) { // Still nothing? OK, let's just look for live media sessions and see if they match // one of our notifications. This will catch apps that aren't (yet!) using media @@ -1515,83 +1545,88 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, UserHandle.USER_ALL); for (MediaController aController : sessions) { - if (aController == null) continue; - final PlaybackState state = aController.getPlaybackState(); - if (state == null) continue; - switch (state.getState()) { - case PlaybackState.STATE_STOPPED: - case PlaybackState.STATE_ERROR: - continue; - default: - // now to see if we have one like this - final String pkg = aController.getPackageName(); - - for (int i = 0; i < N; i++) { - final Entry entry = activeNotifications.get(i); - if (entry.notification.getPackageName().equals(pkg)) { - if (DEBUG_MEDIA) { - Log.v(TAG, "DEBUG_MEDIA: found controller matching " - + entry.notification.getKey()); - } - controller = aController; - mediaNotification = entry; - break; + if (PlaybackState.STATE_PLAYING == + getMediaControllerPlaybackState(aController)) { + // now to see if we have one like this + final String pkg = aController.getPackageName(); + + for (int i = 0; i < N; i++) { + final Entry entry = activeNotifications.get(i); + if (entry.notification.getPackageName().equals(pkg)) { + if (DEBUG_MEDIA) { + Log.v(TAG, "DEBUG_MEDIA: found controller matching " + + entry.notification.getKey()); } + controller = aController; + mediaNotification = entry; + break; } + } } } } } - if (!sameSessions(mMediaController, controller)) { + if (controller != null && !sameSessions(mMediaController, controller)) { // We have a new media session - - if (mMediaController != null) { - // something old was playing - Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: " - + mMediaController); - mMediaController.unregisterCallback(mMediaListener); - } + clearCurrentMediaNotification(); mMediaController = controller; + mMediaController.registerCallback(mMediaListener); + mMediaMetadata = mMediaController.getMetadata(); + if (DEBUG_MEDIA) { + Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: " + + mMediaMetadata); + } - if (mMediaController != null) { - mMediaController.registerCallback(mMediaListener); - mMediaMetadata = mMediaController.getMetadata(); + if (mediaNotification != null) { + mMediaNotificationKey = mediaNotification.notification.getKey(); if (DEBUG_MEDIA) { - Log.v(TAG, "DEBUG_MEDIA: insert listener, receive metadata: " - + mMediaMetadata); + Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key=" + + mMediaNotificationKey + " controller=" + mMediaController); } - - final String notificationKey = mediaNotification == null - ? null - : mediaNotification.notification.getKey(); - - if (notificationKey == null || !notificationKey.equals(mMediaNotificationKey)) { - // we have a new notification! - if (DEBUG_MEDIA) { - Log.v(TAG, "DEBUG_MEDIA: Found new media notification: key=" - + notificationKey + " controller=" + controller); - } - mMediaNotificationKey = notificationKey; - } - } else { - mMediaMetadata = null; - mMediaNotificationKey = null; } - metaDataChanged = true; - } else { - // Media session unchanged - - if (DEBUG_MEDIA) { - Log.v(TAG, "DEBUG_MEDIA: Continuing media notification: key=" + mMediaNotificationKey); - } } } + if (metaDataChanged) { + updateNotifications(); + } updateMediaMetaData(metaDataChanged); } + private int getMediaControllerPlaybackState(MediaController controller) { + if (controller != null) { + final PlaybackState playbackState = controller.getPlaybackState(); + if (playbackState != null) { + return playbackState.getState(); + } + } + return PlaybackState.STATE_NONE; + } + + private boolean isPlaybackActive(int state) { + if (state != PlaybackState.STATE_STOPPED + && state != PlaybackState.STATE_ERROR + && state != PlaybackState.STATE_NONE) { + return true; + } + return false; + } + + private void clearCurrentMediaNotification() { + mMediaNotificationKey = null; + mMediaMetadata = null; + if (mMediaController != null) { + if (DEBUG_MEDIA) { + Log.v(TAG, "DEBUG_MEDIA: Disconnecting from old controller: " + + mMediaController.getPackageName()); + } + mMediaController.unregisterCallback(mMediaListener); + } + mMediaController = null; + } + private boolean sameSessions(MediaController a, MediaController b) { if (a == b) return true; if (a == null) return false; @@ -1657,7 +1692,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } if (metaDataChanged) { if (mBackdropBack.getDrawable() != null) { - Drawable drawable = mBackdropBack.getDrawable(); + Drawable drawable = + mBackdropBack.getDrawable().getConstantState().newDrawable().mutate(); mBackdropFront.setImageDrawable(drawable); if (mScrimSrcModeEnabled) { mBackdropFront.getDrawable().mutate().setXfermode(mSrcOverXferMode); @@ -1730,7 +1766,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } private int adjustDisableFlags(int state) { - if (!mLaunchTransitionFadingAway + if (!mLaunchTransitionFadingAway && !mKeyguardFadingAway && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) { state |= StatusBarManager.DISABLE_NOTIFICATION_ICONS; state |= StatusBarManager.DISABLE_SYSTEM_INFO; @@ -2001,7 +2037,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } public boolean isKeyguardCurrentlySecure() { - return !mUnlockMethodCache.isCurrentlyInsecure(); + return !mUnlockMethodCache.canSkipBouncer(); } public void setPanelExpanded(boolean isExpanded) { @@ -2070,7 +2106,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Expand the window to encompass the full screen in anticipation of the drag. // This is only possible to do atomically because the status bar is at the top of the screen! mStatusBarWindowManager.setPanelVisible(true); - mStatusBarView.setFocusable(false); visibilityChanged(true); mWaitingForKeyguardExit = false; @@ -2202,7 +2237,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Shrink the window to the size of the status bar only mStatusBarWindowManager.setPanelVisible(false); mStatusBarWindowManager.setForceStatusBarVisible(false); - mStatusBarView.setFocusable(true); // Close any "App info" popups that might have snuck on-screen dismissPopups(); @@ -2679,6 +2713,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (mBluetoothController != null) { mBluetoothController.dump(fd, pw, args); } + if (mHotspotController != null) { + mHotspotController.dump(fd, pw, args); + } if (mCastController != null) { mCastController.dump(fd, pw, args); } @@ -2851,7 +2888,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mScreenOn = true; notifyNavigationBarScreenOn(true); } - else if (ACTION_DEMO.equals(action)) { + } + }; + + private BroadcastReceiver mDemoReceiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + if (DEBUG) Log.v(TAG, "onReceive: " + intent); + String action = intent.getAction(); + if (ACTION_DEMO.equals(action)) { Bundle bundle = intent.getExtras(); if (bundle != null) { String command = bundle.getString("command", "").trim().toLowerCase(); @@ -2863,7 +2907,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } } - } else if ("fake_artwork".equals(action)) { + } else if (ACTION_FAKE_ARTWORK.equals(action)) { if (DEBUG_MEDIA_FAKE_ARTWORK) { updateMediaMetaData(true); } @@ -2912,7 +2956,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, updateRowStates(); mIconController.updateResources(); mScreenPinningRequest.onConfigurationChanged(); - mNetworkController.handleConfigurationChanged(); + mNetworkController.onConfigurationChanged(); } @Override @@ -3051,20 +3095,20 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded(); boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing(); boolean isSecure = mUnlockMethodCache.isMethodSecure(); - boolean isCurrentlyInsecure = mUnlockMethodCache.isCurrentlyInsecure(); + boolean canSkipBouncer = mUnlockMethodCache.canSkipBouncer(); int stateFingerprint = getLoggingFingerprint(mState, isShowing, isOccluded, isBouncerShowing, isSecure, - isCurrentlyInsecure); + canSkipBouncer); if (stateFingerprint != mLastLoggedStateFingerprint) { EventLogTags.writeSysuiStatusBarState(mState, isShowing ? 1 : 0, isOccluded ? 1 : 0, isBouncerShowing ? 1 : 0, isSecure ? 1 : 0, - isCurrentlyInsecure ? 1 : 0); + canSkipBouncer ? 1 : 0); mLastLoggedStateFingerprint = stateFingerprint; } } @@ -3119,9 +3163,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, @Override public boolean shouldDisableNavbarGestures() { - return !isDeviceProvisioned() - || mExpandedVisible - || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0; + return !isDeviceProvisioned() || (mDisabled1 & StatusBarManager.DISABLE_SEARCH) != 0; } public void postStartActivityDismissingKeyguard(final Intent intent, int delay) { @@ -3187,6 +3229,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mHandlerThread = null; } mContext.unregisterReceiver(mBroadcastReceiver); + mContext.unregisterReceiver(mDemoReceiver); mAssistManager.destroy(); final SignalClusterView signalCluster = @@ -3210,7 +3253,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void dispatchDemoCommand(String command, Bundle args) { if (!mDemoModeAllowed) { mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(), - "sysui_demo_allowed", 0) != 0; + DEMO_MODE_ALLOWED, 0) != 0; } if (!mDemoModeAllowed) return; if (command.equals(COMMAND_ENTER)) { @@ -3310,6 +3353,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */); mDraggedDownRow = null; } + mAssistManager.onLockscreenShown(); } private void onLaunchTransitionFadingEnded() { @@ -3459,7 +3503,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, startTime + fadeoutDuration - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION, StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION); - disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */); + disable(mDisabledUnmodified1, mDisabledUnmodified2, fadeoutDuration > 0 /* animate */); } public boolean isKeyguardFadingAway() { @@ -3668,7 +3712,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void onTrackingStopped(boolean expand) { if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) { - if (!expand && !mUnlockMethodCache.isCurrentlyInsecure()) { + if (!expand && !mUnlockMethodCache.canSkipBouncer()) { showBouncer(); } } @@ -3911,7 +3955,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mScreenOnComingFromTouch = true; mScreenOnTouchLocation = new PointF(event.getX(), event.getY()); mNotificationPanel.setTouchDisabled(false); - mStatusBarKeyguardViewManager.notifyScreenWakeUpRequested(); + mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index b2a67bdbf313..53dae5cfca45 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -44,6 +44,7 @@ import com.android.systemui.qs.tiles.DndTile; import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.CastController.CastDevice; import com.android.systemui.statusbar.policy.HotspotController; +import com.android.systemui.statusbar.policy.UserInfoController; /** * This class contains all of the policy about which icons are installed in the status @@ -69,6 +70,7 @@ public class PhoneStatusBarPolicy { private final CastController mCast; private final HotspotController mHotspot; private final AlarmManager mAlarmManager; + private final UserInfoController mUserInfoController; // Assume it's all good unless we hear otherwise. We don't always seem // to get broadcasts that it *is* there. @@ -111,12 +113,14 @@ public class PhoneStatusBarPolicy { } }; - public PhoneStatusBarPolicy(Context context, CastController cast, HotspotController hotspot) { + public PhoneStatusBarPolicy(Context context, CastController cast, HotspotController hotspot, + UserInfoController userInfoController) { mContext = context; mCast = cast; mHotspot = hotspot; mService = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE); mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + mUserInfoController = userInfoController; // listen for broadcasts IntentFilter filter = new IntentFilter(); @@ -360,6 +364,7 @@ public class PhoneStatusBarPolicy { new IUserSwitchObserver.Stub() { @Override public void onUserSwitching(int newUserId, IRemoteCallback reply) { + mUserInfoController.reloadUserInfo(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 6d04b28183ce..c0887ca78b25 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -24,6 +24,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityEvent; +import com.android.systemui.DejankUtils; import com.android.systemui.EventLogTags; import com.android.systemui.R; @@ -117,12 +118,12 @@ public class PhoneStatusBarView extends PanelBar { public void onAllPanelsCollapsed() { super.onAllPanelsCollapsed(); // Close the status bar in the next frame so we can show the end of the animation. - postOnAnimation(mHideExpandedRunnable); + DejankUtils.postAfterTraversal(mHideExpandedRunnable); mLastFullyOpenedPanel = null; } public void removePendingHideExpandedRunnables() { - removeCallbacks(mHideExpandedRunnable); + DejankUtils.removeCallbacks(mHideExpandedRunnable); } @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 bacf89052a95..1a35500abac2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -22,11 +22,12 @@ import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Color; +import android.util.Log; import android.view.View; import android.view.ViewTreeObserver; -import android.view.animation.AnimationUtils; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; +import android.view.animation.PathInterpolator; import com.android.systemui.R; import com.android.systemui.statusbar.BackDropView; @@ -62,6 +63,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, private boolean mDarkenWhileDragging; private boolean mBouncerShowing; + private boolean mWakeAndUnlocking; private boolean mAnimateChange; private boolean mUpdatePending; private boolean mExpanding; @@ -71,7 +73,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, private Runnable mOnAnimationFinished; private boolean mAnimationStarted; private final Interpolator mInterpolator = new DecelerateInterpolator(); - private final Interpolator mLinearOutSlowInInterpolator; + private final Interpolator mKeyguardFadeOutInterpolator = new PathInterpolator(0f, 0, 0.7f, 1f); private BackDropView mBackDropView; private boolean mScrimSrcEnabled; private boolean mDozing; @@ -92,8 +94,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, mHeadsUpScrim = headsUpScrim; final Context context = scrimBehind.getContext(); mUnlockMethodCache = UnlockMethodCache.getInstance(context); - mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, - android.R.interpolator.linear_out_slow_in); mScrimSrcEnabled = scrimSrcEnabled; updateHeadsUpScrim(false); } @@ -105,7 +105,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, public void onTrackingStarted() { mExpanding = true; - mDarkenWhileDragging = !mUnlockMethodCache.isCurrentlyInsecure(); + mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer(); } public void onExpandingFinished() { @@ -128,7 +128,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, scheduleUpdate(); } + public void setWakeAndUnlocking() { + mWakeAndUnlocking = true; + scheduleUpdate(); + } + public void animateKeyguardFadingOut(long delay, long duration, Runnable onAnimationFinished) { + mWakeAndUnlocking = false; mAnimateKeyguardFadingOut = true; mDurationOverride = duration; mAnimationDelay = delay; @@ -151,8 +157,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, } public void setDozing(boolean dozing) { - mDozing = dozing; - scheduleUpdate(); + if (mDozing != dozing) { + mDozing = dozing; + scheduleUpdate(); + } } public void setDozeInFrontAlpha(float alpha) { @@ -186,6 +194,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, if (mAnimateKeyguardFadingOut || mForceHideScrims) { setScrimInFrontColor(0f); setScrimBehindColor(0f); + } else if (mWakeAndUnlocking) { + + // During wake and unlock, we first hide everything behind a black scrim, which then + // gets faded out from animateKeyguardFadingOut. + setScrimInFrontColor(1f); + setScrimBehindColor(0f); } else if (!mKeyguardShowing && !mBouncerShowing) { updateScrimNormal(); setScrimInFrontColor(0); @@ -319,7 +333,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, } private Interpolator getInterpolator() { - return mAnimateKeyguardFadingOut ? mLinearOutSlowInInterpolator : mInterpolator; + return mAnimateKeyguardFadingOut ? mKeyguardFadeOutInterpolator : mInterpolator; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java new file mode 100644 index 000000000000..a1e9ece5a783 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java @@ -0,0 +1,174 @@ +/* + * 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.statusbar.phone; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; + +import com.android.keyguard.AlphaOptimizedImageButton; + +public class SettingsButton extends AlphaOptimizedImageButton { + + private static final long LONG_PRESS_LENGTH = 1000; + private static final long ACCEL_LENGTH = 750; + private static final long FULL_SPEED_LENGTH = 375; + private static final long RUN_DURATION = 350; + + private boolean mUpToSpeed; + private ObjectAnimator mAnimator; + + private float mSlop; + + public SettingsButton(Context context, AttributeSet attrs) { + super(context, attrs); + mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); + } + + public boolean isAnimating() { + return mAnimator != null && mAnimator.isRunning(); + } + + public boolean isTunerClick() { + return mUpToSpeed; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + postDelayed(mLongPressCallback, LONG_PRESS_LENGTH); + break; + case MotionEvent.ACTION_UP: + if (mUpToSpeed) { + startExitAnimation(); + } else { + cancelLongClick(); + } + break; + case MotionEvent.ACTION_CANCEL: + cancelLongClick(); + break; + case MotionEvent.ACTION_MOVE: + float x = event.getX(); + float y = event.getY(); + if ((x < -mSlop) || (y < -mSlop) || (x > getWidth() + mSlop) + || (y > getHeight() + mSlop)) { + cancelLongClick(); + } + break; + } + return super.onTouchEvent(event); + } + + private void cancelLongClick() { + cancelAnimation(); + mUpToSpeed = false; + removeCallbacks(mLongPressCallback); + } + + private void cancelAnimation() { + if (mAnimator != null) { + mAnimator.removeAllListeners(); + mAnimator.cancel(); + mAnimator = null; + } + } + + private void startExitAnimation() { + animate() + .translationX(((View) getParent().getParent()).getWidth() - getX()) + .alpha(0) + .setDuration(RUN_DURATION) + .setInterpolator(AnimationUtils.loadInterpolator(mContext, + android.R.interpolator.accelerate_cubic)) + .setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + setAlpha(1f); + setTranslationX(0); + cancelLongClick(); + } + + @Override + public void onAnimationCancel(Animator animation) { + } + }) + .start(); + } + + protected void startAccelSpin() { + cancelAnimation(); + mAnimator = ObjectAnimator.ofFloat(this, View.ROTATION, 0, 360); + mAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext, + android.R.interpolator.accelerate_quad)); + mAnimator.setDuration(ACCEL_LENGTH); + mAnimator.addListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + startContinuousSpin(); + } + + @Override + public void onAnimationCancel(Animator animation) { + } + }); + mAnimator.start(); + } + + protected void startContinuousSpin() { + cancelAnimation(); + mUpToSpeed = true; + mAnimator = ObjectAnimator.ofFloat(this, View.ROTATION, 0, 360); + mAnimator.setInterpolator(AnimationUtils.loadInterpolator(mContext, + android.R.interpolator.linear)); + mAnimator.setDuration(FULL_SPEED_LENGTH); + mAnimator.setRepeatCount(Animation.INFINITE); + mAnimator.start(); + } + + private final Runnable mLongPressCallback = new Runnable() { + @Override + public void run() { + startAccelSpin(); + } + }; +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index a81f06e20f20..7ee47dff37e6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -37,6 +37,7 @@ import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.Switch; import android.widget.TextView; +import android.widget.Toast; import com.android.keyguard.KeyguardStatusView; import com.android.systemui.BatteryMeterView; @@ -48,6 +49,7 @@ import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener; import com.android.systemui.statusbar.policy.NextAlarmController; import com.android.systemui.statusbar.policy.UserInfoController; +import com.android.systemui.tuner.TunerService; import java.text.NumberFormat; @@ -73,7 +75,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private TextView mDateExpanded; private LinearLayout mSystemIcons; private View mSignalCluster; - private View mSettingsButton; + private SettingsButton mSettingsButton; + private View mSettingsContainer; private View mQsDetailHeader; private TextView mQsDetailHeaderTitle; private Switch mQsDetailHeaderSwitch; @@ -142,7 +145,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar); mDateCollapsed = (TextView) findViewById(R.id.date_collapsed); mDateExpanded = (TextView) findViewById(R.id.date_expanded); - mSettingsButton = findViewById(R.id.settings_button); + mSettingsButton = (SettingsButton) findViewById(R.id.settings_button); + mSettingsContainer = findViewById(R.id.settings_button_container); mSettingsButton.setOnClickListener(this); mQsDetailHeader = findViewById(R.id.qs_detail_header); mQsDetailHeader.setAlpha(0); @@ -323,13 +327,15 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mDateCollapsed.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE); mDateExpanded.setVisibility(mExpanded && mAlarmShowing ? View.INVISIBLE : View.VISIBLE); mAlarmStatus.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.INVISIBLE); - mSettingsButton.setVisibility(mExpanded ? View.VISIBLE : View.INVISIBLE); + mSettingsContainer.setVisibility(mExpanded ? View.VISIBLE : View.INVISIBLE); mQsDetailHeader.setVisibility(mExpanded && mShowingDetail? View.VISIBLE : View.INVISIBLE); if (mSignalCluster != null) { updateSignalClusterDetachment(); } mEmergencyCallsOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly ? VISIBLE : GONE); mBatteryLevel.setVisibility(mExpanded ? View.VISIBLE : View.GONE); + mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility( + TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE); } private void updateSignalClusterDetachment() { @@ -352,7 +358,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL private void updateSystemIconsLayoutParams() { RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsSuperContainer.getLayoutParams(); int rule = mExpanded - ? mSettingsButton.getId() + ? mSettingsContainer.getId() : mMultiUserSwitch.getId(); if (rule != lp.getRules()[RelativeLayout.START_OF]) { lp.addRule(RelativeLayout.START_OF, rule); @@ -495,6 +501,20 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL @Override public void onClick(View v) { if (v == mSettingsButton) { + if (mSettingsButton.isTunerClick()) { + if (TunerService.isTunerEnabled(mContext)) { + TunerService.showResetRequest(mContext, new Runnable() { + @Override + public void run() { + // Relaunch settings so that the tuner disappears. + startSettingsActivity(); + } + }); + } else { + Toast.makeText(getContext(), R.string.tuner_toast, Toast.LENGTH_LONG).show(); + TunerService.setTunerEnabled(mContext, true); + } + } startSettingsActivity(); } else if (v == mSystemIconsSuperContainer) { startBatteryActivity(); @@ -567,10 +587,10 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } target.batteryY = mSystemIconsSuperContainer.getTop() + mSystemIconsContainer.getTop(); target.batteryLevelAlpha = getAlphaForVisibility(mBatteryLevel); - target.settingsAlpha = getAlphaForVisibility(mSettingsButton); + target.settingsAlpha = getAlphaForVisibility(mSettingsContainer); target.settingsTranslation = mExpanded ? 0 - : mMultiUserSwitch.getLeft() - mSettingsButton.getLeft(); + : mMultiUserSwitch.getLeft() - mSettingsContainer.getLeft(); target.signalClusterAlpha = mSignalClusterDetached ? 0f : 1f; target.settingsRotation = !mExpanded ? 90f : 0f; } @@ -622,9 +642,11 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mSignalCluster.setTranslationX(0f); mSignalCluster.setTranslationY(0f); } - mSettingsButton.setTranslationY(mSystemIconsSuperContainer.getTranslationY()); - mSettingsButton.setTranslationX(values.settingsTranslation); - mSettingsButton.setRotation(values.settingsRotation); + if (!mSettingsButton.isAnimating()) { + mSettingsContainer.setTranslationY(mSystemIconsSuperContainer.getTranslationY()); + mSettingsContainer.setTranslationX(values.settingsTranslation); + mSettingsButton.setRotation(values.settingsRotation); + } applyAlpha(mEmergencyCallsOnly, values.emergencyCallsOnlyAlpha); if (!mShowingDetail && !mDetailTransitioning) { // Otherwise it needs to stay invisible @@ -633,7 +655,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL applyAlpha(mDateCollapsed, values.dateCollapsedAlpha); applyAlpha(mDateExpanded, values.dateExpandedAlpha); applyAlpha(mBatteryLevel, values.batteryLevelAlpha); - applyAlpha(mSettingsButton, values.settingsAlpha); + applyAlpha(mSettingsContainer, values.settingsAlpha); applyAlpha(mSignalCluster, values.signalClusterAlpha); if (!mExpanded) { mTime.setScaleX(1f); @@ -767,7 +789,9 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL mQsDetailHeader.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - detail.setToggleState(!mQsDetailHeaderSwitch.isChecked()); + boolean checked = !mQsDetailHeaderSwitch.isChecked(); + mQsDetailHeaderSwitch.setChecked(checked); + detail.setToggleState(checked); } }); } 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 a69416a60dfe..44aa780706d9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -19,15 +19,13 @@ package com.android.systemui.statusbar.phone; import android.content.ComponentCallbacks2; import android.content.Context; import android.os.Bundle; -import android.os.RemoteException; import android.os.SystemClock; -import android.util.Slog; +import android.os.Trace; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.view.WindowManagerGlobal; -import com.android.internal.policy.IKeyguardShowCallback; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.ViewMediatorCallback; @@ -62,7 +60,8 @@ public class StatusBarKeyguardViewManager { private ViewGroup mContainer; private StatusBarWindowManager mStatusBarWindowManager; - private boolean mScreenOn = false; + private boolean mDeviceInteractive = false; + private boolean mScreenTurnedOn; private KeyguardBouncer mBouncer; private boolean mShowing; private boolean mOccluded; @@ -72,8 +71,11 @@ public class StatusBarKeyguardViewManager { private boolean mLastOccluded; private boolean mLastBouncerShowing; private boolean mLastBouncerDismissible; + private boolean mLastDeferScrimFadeOut; private OnDismissAction mAfterKeyguardGoneAction; - private boolean mScreenWillWakeUp; + private boolean mDeviceWillWakeUp; + private boolean mWakeAndUnlocking; + private boolean mDeferScrimFadeOut; public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback, LockPatternUtils lockPatternUtils) { @@ -153,40 +155,39 @@ public class StatusBarKeyguardViewManager { } else { showBouncerOrKeyguard(); } + KeyguardUpdateMonitor.getInstance(mContext).sendKeyguardReset(); updateStates(); } } - public void onScreenTurnedOff() { - mScreenOn = false; + public void onFinishedGoingToSleep() { + mDeviceInteractive = false; mPhoneStatusBar.onScreenTurnedOff(); mBouncer.onScreenTurnedOff(); } - public void onScreenTurnedOn(final IKeyguardShowCallback callback) { - mScreenOn = true; - mScreenWillWakeUp = false; + public void onStartedWakingUp() { + mDeviceInteractive = true; + mDeviceWillWakeUp = false; mPhoneStatusBar.onScreenTurnedOn(); - if (callback != null) { - callbackAfterDraw(callback); + } + + public void onScreenTurnedOn() { + mScreenTurnedOn = true; + mWakeAndUnlocking = false; + if (mDeferScrimFadeOut) { + mDeferScrimFadeOut = false; + animateScrimControllerKeyguardFadingOut(0, 200); + updateStates(); } } - private void callbackAfterDraw(final IKeyguardShowCallback callback) { - mContainer.post(new Runnable() { - @Override - public void run() { - try { - callback.onShown(mContainer.getWindowToken()); - } catch (RemoteException e) { - Slog.w(TAG, "Exception calling onShown():", e); - } - } - }); + public void onScreenTurnedOff() { + mScreenTurnedOn = false; } - public void notifyScreenWakeUpRequested() { - mScreenWillWakeUp = !mScreenOn; + public void notifyDeviceWakeUpRequested() { + mDeviceWillWakeUp = !mDeviceInteractive; } public void verifyUnlock() { @@ -271,15 +272,11 @@ public class StatusBarKeyguardViewManager { boolean staying = mPhoneStatusBar.hideKeyguard(); if (!staying) { mStatusBarWindowManager.setKeyguardFadingAway(true); - mScrimController.animateKeyguardFadingOut(delay, fadeoutDuration, new Runnable() { - @Override - public void run() { - mStatusBarWindowManager.setKeyguardFadingAway(false); - mPhoneStatusBar.finishKeyguardFadingAway(); - WindowManagerGlobal.getInstance().trimMemory( - ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); - } - }); + if (mWakeAndUnlocking && !mScreenTurnedOn) { + mDeferScrimFadeOut = true; + } else { + animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration); + } } else { mScrimController.animateGoingToFullShade(delay, fadeoutDuration); mPhoneStatusBar.finishKeyguardFadingAway(); @@ -293,6 +290,23 @@ public class StatusBarKeyguardViewManager { } + private void animateScrimControllerKeyguardFadingOut(long delay, long duration) { + Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "Fading out", 0); + mScrimController.animateKeyguardFadingOut(delay, duration, new Runnable() { + @Override + public void run() { + mStatusBarWindowManager.setKeyguardFadingAway(false); + mPhoneStatusBar.finishKeyguardFadingAway(); + if (mPhoneStatusBar.getNavigationBarView() != null) { + mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(false); + } + WindowManagerGlobal.getInstance().trimMemory( + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); + Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "Fading out", 0); + } + }); + } + private void executeAfterKeyguardGoneAction() { if (mAfterKeyguardGoneAction != null) { mAfterKeyguardGoneAction.onDismiss(); @@ -304,7 +318,7 @@ public class StatusBarKeyguardViewManager { * Dismisses the keyguard by going to the next screen or making it gone. */ public void dismiss() { - if (mScreenOn || mScreenWillWakeUp) { + if (mDeviceInteractive || mDeviceWillWakeUp) { showBouncer(); } } @@ -364,6 +378,7 @@ public class StatusBarKeyguardViewManager { boolean occluded = mOccluded; boolean bouncerShowing = mBouncer.isShowing(); boolean bouncerDismissible = !mBouncer.isFullscreenBouncer(); + boolean deferScrimFadeOut = mDeferScrimFadeOut; if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing) || mFirstUpdate) { @@ -373,10 +388,15 @@ public class StatusBarKeyguardViewManager { mContainer.setSystemUiVisibility(vis | View.STATUS_BAR_DISABLE_BACK); } } - if ((!(showing && !occluded) || bouncerShowing) - != (!(mLastShowing && !mLastOccluded) || mLastBouncerShowing) || mFirstUpdate) { + + // Hide navigation bar on Keyguard but not on bouncer and also if we are deferring a scrim + // fade out, i.e. we are waiting for the screen to have turned on. + boolean navBarVisible = !deferScrimFadeOut && (!(showing && !occluded) || bouncerShowing); + boolean lastNavBarVisible = !mLastDeferScrimFadeOut && (!(mLastShowing && !mLastOccluded) + || mLastBouncerShowing); + if (navBarVisible != lastNavBarVisible || mFirstUpdate) { if (mPhoneStatusBar.getNavigationBarView() != null) { - if (!(showing && !occluded) || bouncerShowing) { + if (navBarVisible) { mContainer.postOnAnimationDelayed(mMakeNavigationBarVisibleRunnable, getNavBarShowDelay()); } else { @@ -403,6 +423,7 @@ public class StatusBarKeyguardViewManager { mFirstUpdate = false; mLastShowing = showing; mLastOccluded = occluded; + mLastDeferScrimFadeOut = deferScrimFadeOut; mLastBouncerShowing = bouncerShowing; mLastBouncerDismissible = bouncerDismissible; @@ -462,4 +483,12 @@ public class StatusBarKeyguardViewManager { public void notifyKeyguardAuthenticated() { mBouncer.notifyKeyguardAuthenticated(); } + + public void setWakeAndUnlocking() { + mWakeAndUnlocking = true; + mScrimController.setWakeAndUnlocking(); + if (mPhoneStatusBar.getNavigationBarView() != null) { + mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java index 66d71f653102..bd537f7c816d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java @@ -39,9 +39,10 @@ public class UnlockMethodCache { /** Whether the user configured a secure unlock method (PIN, password, etc.) */ private boolean mSecure; /** Whether the unlock method is currently insecure (insecure method or trusted environment) */ - private boolean mCurrentlyInsecure; + private boolean mCanSkipBouncer; private boolean mTrustManaged; private boolean mFaceUnlockRunning; + private boolean mTrusted; private UnlockMethodCache(Context ctx) { mLockPatternUtils = new LockPatternUtils(ctx); @@ -64,11 +65,15 @@ public class UnlockMethodCache { return mSecure; } + public boolean isTrusted() { + return mTrusted; + } + /** - * @return whether the lockscreen is currently insecure, i. e. the bouncer won't be shown + * @return whether the lockscreen is currently insecure, and the bouncer won't be shown */ - public boolean isCurrentlyInsecure() { - return mCurrentlyInsecure; + public boolean canSkipBouncer() { + return mCanSkipBouncer; } public void addListener(OnUnlockMethodChangedListener listener) { @@ -82,15 +87,17 @@ public class UnlockMethodCache { private void update(boolean updateAlways) { int user = KeyguardUpdateMonitor.getCurrentUser(); boolean secure = mLockPatternUtils.isSecure(user); - boolean currentlyInsecure = !secure || mKeyguardUpdateMonitor.getUserHasTrust(user); + boolean canSkipBouncer = !secure || mKeyguardUpdateMonitor.getUserCanSkipBouncer(user); boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user); + boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user); boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user) && trustManaged; - boolean changed = secure != mSecure || currentlyInsecure != mCurrentlyInsecure || + boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer || trustManaged != mTrustManaged || faceUnlockRunning != mFaceUnlockRunning; if (changed || updateAlways) { mSecure = secure; - mCurrentlyInsecure = currentlyInsecure; + mCanSkipBouncer = canSkipBouncer; + mTrusted = trusted; mTrustManaged = trustManaged; mFaceUnlockRunning = faceUnlockRunning; notifyListeners(); @@ -120,12 +127,15 @@ public class UnlockMethodCache { } @Override - public void onScreenTurnedOn() { + public void onStartedWakingUp() { update(false /* updateAlways */); } @Override - public void onFingerprintAuthenticated(int userId) { + public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { + if (!mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()) { + return; + } update(false /* updateAlways */); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index 04c626b77143..61986adc1d65 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -232,7 +232,13 @@ public class Clock extends TextView implements DemoMode { } else if (hhmm != null && hhmm.length() == 4) { int hh = Integer.parseInt(hhmm.substring(0, 2)); int mm = Integer.parseInt(hhmm.substring(2)); - mCalendar.set(Calendar.HOUR, hh); + boolean is24 = DateFormat.is24HourFormat( + getContext(), ActivityManager.getCurrentUser()); + if (is24) { + mCalendar.set(Calendar.HOUR_OF_DAY, hh); + } else { + mCalendar.set(Calendar.HOUR, hh); + } mCalendar.set(Calendar.MINUTE, mm); } setText(getSmallTime()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java index cd1914c55663..29a8f67e4cfe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java @@ -93,6 +93,10 @@ public class FlashlightController { } } + public synchronized boolean isEnabled() { + return mFlashlightEnabled; + } + public synchronized boolean isAvailable() { return mTorchAvailable; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java index 63f57116ea67..ed9b123f7431 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java @@ -51,6 +51,7 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL private static final String TAG = "HeadsUpManager"; private static final boolean DEBUG = false; private static final String SETTING_HEADS_UP_SNOOZE_LENGTH_MS = "heads_up_snooze_length_ms"; + private static final int TAG_CLICKED_NOTIFICATION = R.id.is_clicked_heads_up_tag; private final int mHeadsUpNotificationDecay; private final int mMinimumDisplayTime; @@ -452,8 +453,8 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL for (NotificationData.Entry entry : mEntriesToRemoveAfterExpand) { removeHeadsUpEntry(entry); } - mEntriesToRemoveAfterExpand.clear(); } + mEntriesToRemoveAfterExpand.clear(); } public void setTrackingHeadsUp(boolean trackingHeadsUp) { @@ -526,6 +527,15 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL }); } + public static void setIsClickedNotification(View child, boolean clicked) { + child.setTag(TAG_CLICKED_NOTIFICATION, clicked ? true : null); + } + + public static boolean isClickedHeadsUpNotification(View child) { + Boolean clicked = (Boolean) child.getTag(TAG_CLICKED_NOTIFICATION); + return clicked != null && clicked; + } + /** * This represents a notification and how long it is in a heads up mode. It also manages its * lifecycle automatically when created. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java index 1e3bc4d46eb1..41aeac9ef3f0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.policy; import android.content.BroadcastReceiver; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -27,6 +26,8 @@ import android.util.Log; import com.android.settingslib.TetherUtil; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; public class HotspotControllerImpl implements HotspotController { @@ -43,11 +44,32 @@ public class HotspotControllerImpl implements HotspotController { private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>(); private final Receiver mReceiver = new Receiver(); private final Context mContext; - private final WifiManager mWifiManager; + + private int mHotspotState; public HotspotControllerImpl(Context context) { mContext = context; - mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); + } + + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.println("HotspotController state:"); + pw.print(" mHotspotEnabled="); pw.println(stateToString(mHotspotState)); + } + + private static String stateToString(int hotspotState) { + switch (hotspotState) { + case WifiManager.WIFI_AP_STATE_DISABLED: + return "DISABLED"; + case WifiManager.WIFI_AP_STATE_DISABLING: + return "DISABLING"; + case WifiManager.WIFI_AP_STATE_ENABLED: + return "ENABLED"; + case WifiManager.WIFI_AP_STATE_ENABLING: + return "ENABLING"; + case WifiManager.WIFI_AP_STATE_FAILED: + return "FAILED"; + } + return null; } public void addCallback(Callback callback) { @@ -66,7 +88,7 @@ public class HotspotControllerImpl implements HotspotController { @Override public boolean isHotspotEnabled() { - return mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED; + return mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED; } @Override @@ -76,7 +98,6 @@ public class HotspotControllerImpl implements HotspotController { @Override public void setHotspotEnabled(boolean enabled) { - final ContentResolver cr = mContext.getContentResolver(); // Call provisioning app which is called when enabling Tethering from Settings if (enabled && TetherUtil.isProvisioningNeeded(mContext)) { mContext.startServiceAsUser(TETHER_SERVICE_INTENT, UserHandle.CURRENT); @@ -113,7 +134,8 @@ public class HotspotControllerImpl implements HotspotController { if (DEBUG) Log.d(TAG, "onReceive " + intent.getAction()); int state = intent.getIntExtra( WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED); - fireCallback(WifiManager.WIFI_AP_STATE_ENABLED == state); + mHotspotState = state; + fireCallback(mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java index d4eb55350b73..d907b0072eb1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java @@ -36,7 +36,7 @@ public final class KeyguardMonitor extends KeyguardUpdateMonitorCallback { private int mCurrentUser; private boolean mShowing; private boolean mSecure; - private boolean mTrusted; + private boolean mCanSkipBouncer; private boolean mListening; @@ -47,7 +47,7 @@ public final class KeyguardMonitor extends KeyguardUpdateMonitorCallback { @Override public void onUserSwitched(int newUserId) { mCurrentUser = newUserId; - updateTrustedState(); + updateCanSkipBouncerState(); } }; } @@ -57,7 +57,7 @@ public final class KeyguardMonitor extends KeyguardUpdateMonitorCallback { if (mCallbacks.size() != 0 && !mListening) { mListening = true; mCurrentUser = ActivityManager.getCurrentUser(); - updateTrustedState(); + updateCanSkipBouncerState(); mKeyguardUpdateMonitor.registerCallback(this); mUserTracker.startTracking(); } @@ -79,8 +79,8 @@ public final class KeyguardMonitor extends KeyguardUpdateMonitorCallback { return mSecure; } - public boolean isTrusted() { - return mTrusted; + public boolean canSkipBouncer() { + return mCanSkipBouncer; } public void notifyKeyguardState(boolean showing, boolean secure) { @@ -92,12 +92,12 @@ public final class KeyguardMonitor extends KeyguardUpdateMonitorCallback { @Override public void onTrustChanged(int userId) { - updateTrustedState(); + updateCanSkipBouncerState(); notifyKeyguardChanged(); } - private void updateTrustedState() { - mTrusted = mKeyguardUpdateMonitor.getUserHasTrust(mCurrentUser); + private void updateCanSkipBouncerState() { + mCanSkipBouncer = mKeyguardUpdateMonitor.getUserCanSkipBouncer(mCurrentUser); } private void notifyKeyguardChanged() { 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 82224d47fed7..ed1dca38780f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -25,6 +25,7 @@ import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; @@ -50,7 +51,7 @@ public class MobileSignalController extends SignalController< @VisibleForTesting final PhoneStateListener mPhoneStateListener; // Save entire info for logging, we only use the id. - private final SubscriptionInfo mSubscriptionInfo; + final SubscriptionInfo mSubscriptionInfo; // @VisibleForDemoMode final SparseArray<MobileIconGroup> mNetworkToIconLookup; @@ -389,7 +390,7 @@ public class MobileSignalController extends SignalController< } // Fill in the network name if we think we have it. if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null - && mServiceState.getOperatorAlphaShort() != null) { + && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) { mCurrentState.networkName = mServiceState.getOperatorAlphaShort(); } 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 81f2d532de35..29968081e758 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -31,6 +31,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.provider.Settings; +import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; @@ -65,6 +66,11 @@ public class NetworkControllerImpl extends BroadcastReceiver // additional diagnostics, but not logspew static final boolean CHATTY = Log.isLoggable(TAG + "Chat", Log.DEBUG); + private static final int EMERGENCY_NO_CONTROLLERS = 0; + private static final int EMERGENCY_FIRST_CONTROLLER = 100; + private static final int EMERGENCY_VOICE_CONTROLLER = 200; + private static final int EMERGENCY_NO_SUB = 300; + private final Context mContext; private final TelephonyManager mPhone; private final WifiManager mWifiManager; @@ -117,6 +123,12 @@ public class NetworkControllerImpl extends BroadcastReceiver // Handler that all callbacks are made on. private final CallbackHandler mCallbackHandler; + private int mEmergencySource; + private boolean mIsEmergency; + + @VisibleForTesting + ServiceState mLastServiceState; + /** * Construct this controller object and register for updates. */ @@ -194,10 +206,10 @@ public class NetworkControllerImpl extends BroadcastReceiver filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); filter.addAction(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED); + filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); filter.addAction(ConnectivityManager.INET_CONDITION_ACTION); - filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); mContext.registerReceiver(this, filter, null, mReceiverHandler); mListening = true; @@ -260,21 +272,31 @@ public class NetworkControllerImpl extends BroadcastReceiver } public boolean isEmergencyOnly() { + if (mMobileSignalControllers.size() == 0) { + // When there are no active subscriptions, determine emengency state from last + // broadcast. + mEmergencySource = EMERGENCY_NO_CONTROLLERS; + return mLastServiceState != null && mLastServiceState.isEmergencyOnly(); + } int voiceSubId = mSubDefaults.getDefaultVoiceSubId(); if (!SubscriptionManager.isValidSubscriptionId(voiceSubId)) { for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) { if (!mobileSignalController.getState().isEmergency) { + mEmergencySource = EMERGENCY_FIRST_CONTROLLER + + mobileSignalController.mSubscriptionInfo.getSubscriptionId(); if (DEBUG) Log.d(TAG, "Found emergency " + mobileSignalController.mTag); return false; } } } if (mMobileSignalControllers.containsKey(voiceSubId)) { + mEmergencySource = EMERGENCY_VOICE_CONTROLLER + voiceSubId; if (DEBUG) Log.d(TAG, "Getting emergency from " + voiceSubId); return mMobileSignalControllers.get(voiceSubId).getState().isEmergency; } if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId); + mEmergencySource = EMERGENCY_NO_SUB + voiceSubId; // Something is wrong, better assume we can't make calls... return true; } @@ -284,7 +306,8 @@ public class NetworkControllerImpl extends BroadcastReceiver * so we should recheck and send out the state to listeners. */ void recalculateEmergency() { - mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly()); + mIsEmergency = isEmergencyOnly(); + mCallbackHandler.setEmergencyCallsOnly(mIsEmergency); } public void addSignalCallback(SignalCallback cb) { @@ -339,8 +362,6 @@ public class NetworkControllerImpl extends BroadcastReceiver if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) || action.equals(ConnectivityManager.INET_CONDITION_ACTION)) { updateConnectivity(); - } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { - handleConfigurationChanged(); } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) { refreshLocale(); updateAirplaneMode(false); @@ -356,6 +377,13 @@ public class NetworkControllerImpl extends BroadcastReceiver } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { // Might have different subscriptions now. updateMobileControllers(); + } else if (action.equals(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED)) { + mLastServiceState = ServiceState.newFromBundle(intent.getExtras()); + if (mMobileSignalControllers.size() == 0) { + // If none of the subscriptions are active, we might need to recalculate + // emergency state. + recalculateEmergency(); + } } else { int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, SubscriptionManager.INVALID_SUBSCRIPTION_ID); @@ -373,8 +401,18 @@ public class NetworkControllerImpl extends BroadcastReceiver } } - public void handleConfigurationChanged() { + public void onConfigurationChanged() { mConfig = Config.readConfig(mContext); + mReceiverHandler.post(new Runnable() { + @Override + public void run() { + handleConfigurationChanged(); + } + }); + } + + @VisibleForTesting + void handleConfigurationChanged() { for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) { mobileSignalController.setConfiguration(mConfig); } @@ -580,6 +618,12 @@ public class NetworkControllerImpl extends BroadcastReceiver pw.println(mAirplaneMode); pw.print(" mLocale="); pw.println(mLocale); + pw.print(" mLastServiceState="); + pw.println(mLastServiceState); + pw.print(" mIsEmergency="); + pw.println(mIsEmergency); + pw.print(" mEmergencySource="); + pw.println(emergencyToString(mEmergencySource)); for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) { mobileSignalController.dump(pw); @@ -591,6 +635,19 @@ public class NetworkControllerImpl extends BroadcastReceiver mAccessPoints.dump(pw); } + private static final String emergencyToString(int emergencySource) { + if (emergencySource > EMERGENCY_NO_SUB) { + return "NO_SUB(" + (emergencySource - EMERGENCY_NO_SUB) + ")"; + } else if (emergencySource > EMERGENCY_VOICE_CONTROLLER) { + return "VOICE_CONTROLLER(" + (emergencySource - EMERGENCY_VOICE_CONTROLLER) + ")"; + } else if (emergencySource > EMERGENCY_FIRST_CONTROLLER) { + return "FIRST_CONTROLLER(" + (emergencySource - EMERGENCY_FIRST_CONTROLLER) + ")"; + } else if (emergencySource == EMERGENCY_NO_CONTROLLERS) { + return "NO_CONTROLLERS"; + } + return "UNKNOWN_SOURCE"; + } + private boolean mDemoMode; private boolean mDemoInetCondition; private WifiSignalController.WifiState mDemoWifiState; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java index 50e3977c9214..faa1a28ace8b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java @@ -101,6 +101,8 @@ public class SplitClockView extends LinearLayout { } mTimeView.setFormat12Hour(timeString); mTimeView.setFormat24Hour(timeString); + mTimeView.setContentDescriptionFormat12Hour(formatString); + mTimeView.setContentDescriptionFormat24Hour(formatString); mAmPmView.setFormat12Hour(amPmString); mAmPmView.setFormat24Hour(amPmString); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index 41fc967de14d..3e8d4e909d61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -39,6 +39,8 @@ import android.os.UserManager; import android.provider.Settings; import android.util.Log; import android.util.SparseArray; +import android.util.SparseBooleanArray; +import android.util.SparseIntArray; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; @@ -68,6 +70,11 @@ public class UserSwitcherController { private static final String SIMPLE_USER_SWITCHER_GLOBAL_SETTING = "lockscreenSimpleUserSwitcher"; private static final String ACTION_REMOVE_GUEST = "com.android.systemui.REMOVE_GUEST"; + private static final int PAUSE_REFRESH_USERS_TIMEOUT_MS = 3000; + + private static final int ID_REMOVE_GUEST = 1010; + private static final String TAG_REMOVE_GUEST = "remove_guest"; + private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF"; private final Context mContext; private final UserManager mUserManager; @@ -75,6 +82,7 @@ public class UserSwitcherController { private final GuestResumeSessionReceiver mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(); private final KeyguardMonitor mKeyguardMonitor; + private final Handler mHandler; private ArrayList<UserRecord> mUsers = new ArrayList<>(); private Dialog mExitGuestDialog; @@ -82,11 +90,15 @@ public class UserSwitcherController { private int mLastNonGuestUser = UserHandle.USER_OWNER; private boolean mSimpleUserSwitcher; private boolean mAddUsersWhenLocked; + private boolean mPauseRefreshUsers; + private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2); - public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor) { + public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor, + Handler handler) { mContext = context; mGuestResumeSessionReceiver.register(context); mKeyguardMonitor = keyguardMonitor; + mHandler = handler; mUserManager = UserManager.get(context); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_ADDED); @@ -94,10 +106,13 @@ public class UserSwitcherController { filter.addAction(Intent.ACTION_USER_INFO_CHANGED); filter.addAction(Intent.ACTION_USER_SWITCHED); filter.addAction(Intent.ACTION_USER_STOPPING); - filter.addAction(ACTION_REMOVE_GUEST); mContext.registerReceiverAsUser(mReceiver, UserHandle.OWNER, filter, null /* permission */, null /* scheduler */); + filter = new IntentFilter(); + filter.addAction(ACTION_REMOVE_GUEST); + mContext.registerReceiverAsUser(mReceiver, UserHandle.OWNER, filter, + PERMISSION_SELF, null /* scheduler */); mContext.getContentResolver().registerContentObserver( Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true, @@ -122,17 +137,26 @@ public class UserSwitcherController { */ @SuppressWarnings("unchecked") private void refreshUsers(int forcePictureLoadForId) { + if (DEBUG) Log.d(TAG, "refreshUsers(forcePictureLoadForId=" + forcePictureLoadForId+")"); + if (forcePictureLoadForId != UserHandle.USER_NULL) { + mForcePictureLoadForUserId.put(forcePictureLoadForId, true); + } + + if (mPauseRefreshUsers) { + return; + } SparseArray<Bitmap> bitmaps = new SparseArray<>(mUsers.size()); final int N = mUsers.size(); for (int i = 0; i < N; i++) { UserRecord r = mUsers.get(i); - if (r == null || r.info == null - || r.info.id == forcePictureLoadForId || r.picture == null) { + if (r == null || r.picture == null || + r.info == null || mForcePictureLoadForUserId.get(r.info.id)) { continue; } bitmaps.put(r.info.id, r.picture); } + mForcePictureLoadForUserId.clear(); final boolean addUsersWhenLocked = mAddUsersWhenLocked; new AsyncTask<SparseArray<Bitmap>, Void, ArrayList<UserRecord>>() { @@ -215,6 +239,13 @@ public class UserSwitcherController { }.execute((SparseArray) bitmaps); } + private void pauseRefreshUsers() { + if (!mPauseRefreshUsers) { + mHandler.postDelayed(mUnpauseRefreshUsers, PAUSE_REFRESH_USERS_TIMEOUT_MS); + mPauseRefreshUsers = true; + } + } + private void notifyAdapters() { for (int i = mAdapters.size() - 1; i >= 0; i--) { BaseUserAdapter adapter = mAdapters.get(i).get(); @@ -261,6 +292,7 @@ public class UserSwitcherController { private void switchToUserId(int id) { try { + pauseRefreshUsers(); ActivityManagerNative.getDefault().switchUser(id); } catch (RemoteException e) { Log.e(TAG, "Couldn't switch user.", e); @@ -302,6 +334,10 @@ public class UserSwitcherController { Log.v(TAG, "Broadcast: a=" + intent.getAction() + " user=" + intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)); } + + boolean unpauseRefreshUsers = false; + int forcePictureLoadForId = UserHandle.USER_NULL; + if (ACTION_REMOVE_GUEST.equals(intent.getAction())) { int currentUser = ActivityManager.getCurrentUser(); UserInfo userInfo = mUserManager.getUserInfo(currentUser); @@ -309,16 +345,13 @@ public class UserSwitcherController { showExitGuestDialog(currentUser); } return; - } - if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) { + } else if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) { final int currentId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); UserInfo userInfo = mUserManager.getUserInfo(currentId); if (userInfo != null && userInfo.isGuest()) { showGuestNotification(currentId); } - } - - if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { + } else if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { mExitGuestDialog.cancel(); mExitGuestDialog = null; @@ -343,13 +376,15 @@ public class UserSwitcherController { } } notifyAdapters(); - } - int forcePictureLoadForId = UserHandle.USER_NULL; - if (Intent.ACTION_USER_INFO_CHANGED.equals(intent.getAction())) { + unpauseRefreshUsers = true; + } else if (Intent.ACTION_USER_INFO_CHANGED.equals(intent.getAction())) { forcePictureLoadForId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); } refreshUsers(forcePictureLoadForId); + if (unpauseRefreshUsers) { + mUnpauseRefreshUsers.run(); + } } private void showGuestNotification(int guestUserId) { @@ -366,8 +401,17 @@ public class UserSwitcherController { mContext.getString(R.string.guest_notification_remove_action), removeGuestPI) .build(); - NotificationManager.from(mContext).notifyAsUser(null, 0, notification, - new UserHandle(guestUserId)); + NotificationManager.from(mContext).notifyAsUser(TAG_REMOVE_GUEST, ID_REMOVE_GUEST, + notification, new UserHandle(guestUserId)); + } + }; + + private final Runnable mUnpauseRefreshUsers = new Runnable() { + @Override + public void run() { + mHandler.removeCallbacks(this); + mPauseRefreshUsers = false; + refreshUsers(UserHandle.USER_NULL); } }; @@ -412,7 +456,7 @@ public class UserSwitcherController { public int getCount() { boolean secureKeyguardShowing = mController.mKeyguardMonitor.isShowing() && mController.mKeyguardMonitor.isSecure() - && !mController.mKeyguardMonitor.isTrusted(); + && !mController.mKeyguardMonitor.canSkipBouncer(); if (!secureKeyguardShowing) { return mController.mUsers.size(); } 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 0d89b214a6b7..23d9b9fe94b8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -222,6 +222,7 @@ public class NotificationStackScrollLayout extends ViewGroup private int[] mTempInt2 = new int[2]; private boolean mGenerateChildOrderChangedEvent; private HashSet<Runnable> mAnimationFinishedRunnables = new HashSet<>(); + private HashSet<View> mClearOverlayViewsWhenFinished = new HashSet<>(); private HashSet<Pair<ExpandableNotificationRow, Boolean>> mHeadsUpChangeAnimations = new HashSet<>(); private HeadsUpManager mHeadsUpManager; @@ -1656,6 +1657,11 @@ public class NotificationStackScrollLayout extends ViewGroup mAddedHeadsUpChildren.remove(child); return false; } + if (isClickedHeadsUp(child)) { + // An animation is already running, add it to the Overlay + mClearOverlayViewsWhenFinished.add(child); + return true; + } if (mIsExpanded && mAnimationsEnabled && !isChildInInvisibleGroup(child)) { if (!mChildrenToAddAnimated.contains(child)) { // Generate Animations @@ -1671,6 +1677,10 @@ public class NotificationStackScrollLayout extends ViewGroup return false; } + private boolean isClickedHeadsUp(View child) { + return HeadsUpManager.isClickedHeadsUpNotification(child); + } + /** * Remove a removed child view from the heads up animations if it was just added there * @@ -2327,6 +2337,13 @@ public class NotificationStackScrollLayout extends ViewGroup public void onChildAnimationFinished() { requestChildrenUpdate(); runAnimationFinishedRunnables(); + clearViewOverlays(); + } + + private void clearViewOverlays() { + for (View view : mClearOverlayViewsWhenFinished) { + getOverlay().remove(view); + } } private void runAnimationFinishedRunnables() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index 5d2e5b768623..82064a7c9c27 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -413,7 +413,9 @@ public class StackScrollAlgorithm { ExpandableNotificationRow topHeadsUpEntry = ambientState.getTopHeadsUpEntry(); int childCount = algorithmState.visibleChildren.size(); - int numberOfElementsCompletelyIn = (int) algorithmState.itemsInTopStack; + int numberOfElementsCompletelyIn = algorithmState.partialInTop == 1.0f + ? algorithmState.lastTopStackIndex + : (int) algorithmState.itemsInTopStack; for (int i = 0; i < childCount; i++) { ExpandableView child = algorithmState.visibleChildren.get(i); StackViewState childViewState = resultState.getViewStateForView(child); 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 5b8fe89702e1..97c7d301bd44 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java @@ -29,6 +29,7 @@ import com.android.systemui.R; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.SpeedBumpView; +import com.android.systemui.statusbar.policy.HeadsUpManager; import java.util.ArrayList; import java.util.HashSet; @@ -670,6 +671,7 @@ public class StackStateAnimator { animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { + HeadsUpManager.setIsClickedNotification(child, false); child.setTag(TAG_ANIMATOR_TRANSLATION_Y, null); child.setTag(TAG_START_TRANSLATION_Y, null); child.setTag(TAG_END_TRANSLATION_Y, null); diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java index 3f5ca58fe6ca..a2b062c8b710 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java @@ -28,13 +28,14 @@ import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; import android.preference.SwitchPreference; import android.provider.Settings; +import android.view.MenuItem; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.DemoMode; import com.android.systemui.R; public class DemoModeFragment extends PreferenceFragment implements OnPreferenceChangeListener { - private static final String DEMO_MODE_ALLOWED = "sysui_demo_allowed"; private static final String DEMO_MODE_ON = "sysui_tuner_demo_on"; private static final String[] STATUS_ICONS = { @@ -75,10 +76,33 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference updateDemoModeEnabled(); updateDemoModeOn(); ContentResolver contentResolver = getContext().getContentResolver(); - contentResolver.registerContentObserver(Settings.Global.getUriFor(DEMO_MODE_ALLOWED), false, - mDemoModeObserver); + contentResolver.registerContentObserver(Settings.Global.getUriFor( + DemoMode.DEMO_MODE_ALLOWED), false, mDemoModeObserver); contentResolver.registerContentObserver(Settings.Global.getUriFor(DEMO_MODE_ON), false, mDemoModeObserver); + setHasOptionsMenu(true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + getFragmentManager().popBackStack(); + break; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onResume() { + super.onResume(); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_DEMO_MODE, true); + } + + @Override + public void onPause() { + super.onPause(); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_DEMO_MODE, false); } @Override @@ -89,7 +113,7 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference private void updateDemoModeEnabled() { boolean enabled = Settings.Global.getInt(getContext().getContentResolver(), - DEMO_MODE_ALLOWED, 0) != 0; + DemoMode.DEMO_MODE_ALLOWED, 0) != 0; mEnabledSwitch.setChecked(enabled); mOnSwitch.setEnabled(enabled); } @@ -102,15 +126,18 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference @Override public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean enabled = newValue == Boolean.TRUE; if (preference == mEnabledSwitch) { - if (newValue != Boolean.TRUE) { + if (!enabled) { // Make sure we aren't in demo mode when disabling it. mOnSwitch.setChecked(false); stopDemoMode(); } - setGlobal(DEMO_MODE_ALLOWED, newValue == Boolean.TRUE ? 1 : 0); + MetricsLogger.action(getContext(), MetricsLogger.TUNER_DEMO_MODE_ENABLED, enabled); + setGlobal(DemoMode.DEMO_MODE_ALLOWED, enabled ? 1 : 0); } else if (preference == mOnSwitch) { - if (newValue == Boolean.TRUE) { + MetricsLogger.action(getContext(), MetricsLogger.TUNER_DEMO_MODE_ON, enabled); + if (enabled) { startDemoMode(); } else { stopDemoMode(); diff --git a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java index a5b244e21c91..37ac0986d666 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java @@ -40,6 +40,7 @@ import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ScrollView; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; import com.android.systemui.qs.QSPanel; import com.android.systemui.qs.QSTile; @@ -79,12 +80,25 @@ public class QsTuner extends Fragment implements Callback { menu.add(0, MENU_RESET, 0, com.android.internal.R.string.reset); } + public void onResume() { + super.onResume(); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_QS, true); + } + + public void onPause() { + super.onPause(); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER_QS, false); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_RESET: mTileHost.reset(); break; + case android.R.id.home: + getFragmentManager().popBackStack(); + break; } return super.onOptionsItemSelected(item); } @@ -205,6 +219,8 @@ public class QsTuner extends Fragment implements Callback { if (oldTile.equals(newTile)) { return; } + MetricsLogger.action(getContext(), MetricsLogger.TUNER_QS_REORDER, oldTile + "," + + newTile); List<String> order = new ArrayList<>(mTileSpecs); int index = order.indexOf(oldTile); if (index < 0) { @@ -217,12 +233,14 @@ public class QsTuner extends Fragment implements Callback { } public void remove(String tile) { + MetricsLogger.action(getContext(), MetricsLogger.TUNER_QS_REMOVE, tile); List<String> tiles = new ArrayList<>(mTileSpecs); tiles.remove(tile); setTiles(tiles); } public void add(String tile) { + MetricsLogger.action(getContext(), MetricsLogger.TUNER_QS_ADD, tile); List<String> tiles = new ArrayList<>(mTileSpecs); tiles.add(tile); setTiles(tiles); diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java index d4cc56deefac..e5b550e82bdb 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java @@ -23,6 +23,7 @@ import android.provider.Settings; import android.text.TextUtils; import android.util.AttributeSet; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.tuner.TunerService.Tunable; @@ -50,11 +51,14 @@ public class StatusBarSwitch extends SwitchPreference implements Tunable { if (!value) { // If not enabled add to blacklist. if (!mBlacklist.contains(getKey())) { + MetricsLogger.action(getContext(), MetricsLogger.TUNER_STATUS_BAR_DISABLE, + getKey()); mBlacklist.add(getKey()); setList(mBlacklist); } } else { if (mBlacklist.remove(getKey())) { + MetricsLogger.action(getContext(), MetricsLogger.TUNER_STATUS_BAR_ENABLE, getKey()); setList(mBlacklist); } } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java index 4a8c2e4fd9d6..71b5de56444b 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java @@ -17,7 +17,10 @@ package com.android.systemui.tuner; import static com.android.systemui.BatteryMeterView.SHOW_PERCENT_SETTING; +import android.app.AlertDialog; import android.app.FragmentTransaction; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; import android.database.ContentObserver; import android.net.Uri; import android.os.Bundle; @@ -28,19 +31,29 @@ import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceFragment; import android.preference.PreferenceGroup; import android.preference.SwitchPreference; +import android.provider.Settings; import android.provider.Settings.System; +import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; import com.android.systemui.statusbar.phone.StatusBarIconController; import com.android.systemui.tuner.TunerService.Tunable; public class TunerFragment extends PreferenceFragment { + private static final String TAG = "TunerFragment"; + private static final String KEY_QS_TUNER = "qs_tuner"; private static final String KEY_DEMO_MODE = "demo_mode"; private static final String KEY_BATTERY_PCT = "battery_pct"; + public static final String SETTING_SEEN_TUNER_WARNING = "seen_tuner_warning"; + + private static final int MENU_REMOVE = Menu.FIRST + 1; + private final SettingObserver mSettingObserver = new SettingObserver(); private SwitchPreference mBatteryPct; @@ -73,6 +86,19 @@ public class TunerFragment extends PreferenceFragment { } }); mBatteryPct = (SwitchPreference) findPreference(KEY_BATTERY_PCT); + if (Settings.Secure.getInt(getContext().getContentResolver(), SETTING_SEEN_TUNER_WARNING, + 0) == 0) { + new AlertDialog.Builder(getContext()) + .setTitle(R.string.tuner_warning_title) + .setMessage(R.string.tuner_warning) + .setPositiveButton(R.string.got_it, new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Settings.Secure.putInt(getContext().getContentResolver(), + SETTING_SEEN_TUNER_WARNING, 1); + } + }).show(); + } } @Override @@ -83,6 +109,7 @@ public class TunerFragment extends PreferenceFragment { System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver); registerPrefs(getPreferenceScreen()); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, true); } @Override @@ -91,6 +118,7 @@ public class TunerFragment extends PreferenceFragment { getContext().getContentResolver().unregisterContentObserver(mSettingObserver); unregisterPrefs(getPreferenceScreen()); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, false); } private void registerPrefs(PreferenceGroup group) { @@ -120,11 +148,24 @@ public class TunerFragment extends PreferenceFragment { } @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + menu.add(Menu.NONE, MENU_REMOVE, Menu.NONE, R.string.remove_from_settings); + } + + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: getActivity().finish(); return true; + case MENU_REMOVE: + TunerService.showResetRequest(getContext(), new Runnable() { + @Override + public void run() { + getActivity().finish(); + } + }); + return true; } return super.onOptionsItemSelected(item); } @@ -152,6 +193,7 @@ public class TunerFragment extends PreferenceFragment { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final boolean v = (Boolean) newValue; + MetricsLogger.action(getContext(), MetricsLogger.TUNER_BATTERY_PERCENTAGE, v); System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java index de5aaf617588..d3f33ab9bb19 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java @@ -16,8 +16,15 @@ package com.android.systemui.tuner; import android.app.ActivityManager; +import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.Intent; +import android.content.pm.PackageManager; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; @@ -25,9 +32,13 @@ import android.os.Looper; import android.provider.Settings; import android.util.ArrayMap; +import com.android.systemui.BatteryMeterView; +import com.android.systemui.DemoMode; +import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.SystemUIApplication; import com.android.systemui.settings.CurrentUserTracker; +import com.android.systemui.statusbar.phone.SystemUIDialog; import java.util.ArrayList; import java.util.HashMap; @@ -36,6 +47,8 @@ import java.util.List; public class TunerService extends SystemUI { + public static final String ACTION_CLEAR = "com.android.systemui.action.CLEAR_TUNER"; + private final Observer mObserver = new Observer(); // Map of Uris we listen on to their settings keys. private final ArrayMap<Uri, String> mListeningUris = new ArrayMap<>(); @@ -118,6 +131,19 @@ public class TunerService extends SystemUI { } } + public void clearAll() { + // A couple special cases. + Settings.Global.putString(mContentResolver, DemoMode.DEMO_MODE_ALLOWED, null); + Settings.System.putString(mContentResolver, BatteryMeterView.SHOW_PERCENT_SETTING, null); + Intent intent = new Intent(DemoMode.ACTION_DEMO); + intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_EXIT); + mContext.sendBroadcast(intent); + + for (String key : mTunableLookup.keySet()) { + Settings.Secure.putString(mContentResolver, key, null); + } + } + // Only used in other processes, such as the tuner. private static TunerService sInstance; @@ -141,6 +167,44 @@ public class TunerService extends SystemUI { return sInstance; } + public static final void showResetRequest(final Context context, final Runnable onDisabled) { + SystemUIDialog dialog = new SystemUIDialog(context); + dialog.setMessage(R.string.remove_from_settings_prompt); + dialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.cancel), + (OnClickListener) null); + dialog.setButton(DialogInterface.BUTTON_POSITIVE, + context.getString(R.string.guest_exit_guest_dialog_remove), new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Tell the tuner (in main SysUI process) to clear all its settings. + context.sendBroadcast(new Intent(TunerService.ACTION_CLEAR)); + // Disable access to tuner. + TunerService.setTunerEnabled(context, false); + // Make them sit through the warning dialog again. + Settings.Secure.putInt(context.getContentResolver(), + TunerFragment.SETTING_SEEN_TUNER_WARNING, 0); + if (onDisabled != null) { + onDisabled.run(); + } + } + }); + dialog.show(); + } + + public static final void setTunerEnabled(Context context, boolean enabled) { + context.getPackageManager().setComponentEnabledSetting( + new ComponentName(context, TunerActivity.class), + enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + } + + public static final boolean isTunerEnabled(Context context) { + return context.getPackageManager().getComponentEnabledSetting( + new ComponentName(context, TunerActivity.class)) + == PackageManager.COMPONENT_ENABLED_STATE_ENABLED; + } + private class Observer extends ContentObserver { public Observer() { super(new Handler(Looper.getMainLooper())); @@ -157,4 +221,13 @@ public class TunerService extends SystemUI { public interface Tunable { void onTuningChanged(String key, String newValue); } + + public static class ClearReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + if (ACTION_CLEAR.equals(intent.getAction())) { + get(context).clearAll(); + } + } + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java index 5055bfefe889..00b8de237347 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy; import android.os.HandlerThread; import android.telephony.SubscriptionInfo; import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; import com.android.systemui.R; import com.android.systemui.statusbar.policy.NetworkController.IconState; @@ -32,6 +33,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; +@SmallTest public class CallbackHandlerTest extends AndroidTestCase { private CallbackHandler mHandler; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java index 360562c8a967..0ec8802f9c60 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java @@ -2,9 +2,11 @@ package com.android.systemui.statusbar.policy; import android.os.Looper; import android.telephony.TelephonyManager; +import android.test.suitebuilder.annotation.SmallTest; import org.mockito.Mockito; +@SmallTest public class NetworkControllerDataTest extends NetworkControllerBaseTest { public void test3gDataIcon() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java index 5d63d8dd506c..b2fedfaeb8f6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java @@ -1,12 +1,14 @@ package com.android.systemui.statusbar.policy; import android.net.NetworkCapabilities; +import android.test.suitebuilder.annotation.SmallTest; import com.android.systemui.statusbar.policy.NetworkController.IconState; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +@SmallTest public class NetworkControllerEthernetTest extends NetworkControllerBaseTest { public void testEthernetIcons() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java index 52dea40ba5e6..660fd9c40721 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java @@ -21,9 +21,11 @@ import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.os.Looper; +import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; +import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.TelephonyIntents; @@ -35,6 +37,7 @@ import org.mockito.Mockito; import java.util.ArrayList; import java.util.List; +@SmallTest public class NetworkControllerSignalTest extends NetworkControllerBaseTest { public void testNoIconWithoutMobile() { @@ -70,11 +73,20 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest { public void testEmergencyOnlyNoSubscriptions() { setupDefaultSignal(); + setSubscriptions(); + mNetworkController.mLastServiceState = new ServiceState(); + mNetworkController.mLastServiceState.setEmergencyOnly(true); mNetworkController.recalculateEmergency(); - verifyEmergencyOnly(false); + verifyEmergencyOnly(true); + } + public void testNoEmengencyNoSubscriptions() { + setupDefaultSignal(); setSubscriptions(); - verifyEmergencyOnly(true); + mNetworkController.mLastServiceState = new ServiceState(); + mNetworkController.mLastServiceState.setEmergencyOnly(false); + mNetworkController.recalculateEmergency(); + verifyEmergencyOnly(false); } public void testNoSimlessIconWithoutMobile() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java index cecf2fde3cfb..d7c4e1e06514 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java @@ -5,12 +5,14 @@ import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import android.test.suitebuilder.annotation.SmallTest; import com.android.systemui.statusbar.policy.NetworkController.IconState; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +@SmallTest public class NetworkControllerWifiTest extends NetworkControllerBaseTest { // These match the constants in WifiManager and need to be kept up to date. private static final int MIN_RSSI = -100; diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlend.java b/rs/java/android/renderscript/ScriptIntrinsicBlend.java index 906e0f640a4f..6b09bb7a7741 100644 --- a/rs/java/android/renderscript/ScriptIntrinsicBlend.java +++ b/rs/java/android/renderscript/ScriptIntrinsicBlend.java @@ -360,6 +360,8 @@ public class ScriptIntrinsicBlend extends ScriptIntrinsic { /** * dst = dst.rgb * src.a + (1.0 - dst.a) * src.rgb * dst.a = src.a + * Note: Before API 23, the alpha channel was not correctly set. + * Please use with caution when targeting older APIs. * * @param ain The source buffer * @param aout The destination buffer @@ -371,6 +373,8 @@ public class ScriptIntrinsicBlend extends ScriptIntrinsic { /** * dst = dst.rgb * src.a + (1.0 - dst.a) * src.rgb * dst.a = src.a + * Note: Before API 23, the alpha channel was not correctly set. + * Please use with caution when targeting older APIs. * * @param ain The source buffer * @param aout The destination buffer diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index bf41f0f120a4..83b953ebf179 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -8091,6 +8091,7 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF keyValueAgentCleanup(); } + // TODO: clean up naming; this is now used at finish by both k/v and stream restores void keyValueAgentCleanup() { mBackupDataName.delete(); mStageName.delete(); @@ -8126,8 +8127,17 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF // usual full initialization. Note that this is only done for // full-system restores: when a single app has requested a restore, // it is explicitly not killed following that operation. - if (mTargetPackage == null && (mCurrentPackage.applicationInfo.flags - & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0) { + // + // We execute this kill when these conditions hold: + // 1. the app did not request its own restore (mTargetPackage == null), and either + // 2a. the app is a full-data target (TYPE_FULL_STREAM) or + // b. the app does not state android:killAfterRestore="false" in its manifest + final int appFlags = mCurrentPackage.applicationInfo.flags; + final boolean killAfterRestore = + (mRestoreDescription.getDataType() == RestoreDescription.TYPE_FULL_STREAM) + || ((appFlags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0); + + if (mTargetPackage == null && killAfterRestore) { if (DEBUG) Slog.d(TAG, "Restore complete, killing host process of " + mCurrentPackage.applicationInfo.processName); mActivityManager.killApplicationProcess( @@ -9535,16 +9545,8 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF public void run() { // clean up the session's bookkeeping synchronized (mSession) { - try { - if (mSession.mRestoreTransport != null) { - mSession.mRestoreTransport.finishRestore(); - } - } catch (Exception e) { - Slog.e(TAG, "Error in finishRestore", e); - } finally { - mSession.mRestoreTransport = null; - mSession.mEnded = true; - } + mSession.mRestoreTransport = null; + mSession.mEnded = true; } // clean up the BackupManagerImpl side of the bookkeeping diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index 417f18db9d76..2a3492b4f06b 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -32,6 +32,7 @@ import java.util.Map; import android.app.ActivityManager; import android.app.ActivityThread; +import android.app.AppGlobals; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -56,15 +57,18 @@ import android.util.Log; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseIntArray; import android.util.TimeUtils; import android.util.Xml; import com.android.internal.app.IAppOpsService; import com.android.internal.app.IAppOpsCallback; import com.android.internal.os.Zygote; +import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; +import libcore.util.EmptyArray; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -98,19 +102,38 @@ public class AppOpsService extends IAppOpsService.Stub { } }; - final SparseArray<HashMap<String, Ops>> mUidOps - = new SparseArray<HashMap<String, Ops>>(); + final SparseArray<UidState> mUidStates = new SparseArray<>(); private final SparseArray<boolean[]> mOpRestrictions = new SparseArray<boolean[]>(); + private static final class UidState { + public final int uid; + public ArrayMap<String, Ops> pkgOps; + public SparseIntArray opModes; + + public UidState(int uid) { + this.uid = uid; + } + + public void clear() { + pkgOps = null; + opModes = null; + } + + public boolean isDefault() { + return (pkgOps == null || pkgOps.isEmpty()) + && (opModes == null || opModes.size() <= 0); + } + } + public final static class Ops extends SparseArray<Op> { public final String packageName; - public final int uid; + public final UidState uidState; public final boolean isPrivileged; - public Ops(String _packageName, int _uid, boolean _isPrivileged) { + public Ops(String _packageName, UidState _uidState, boolean _isPrivileged) { packageName = _packageName; - uid = _uid; + uidState = _uidState; isPrivileged = _isPrivileged; } } @@ -220,27 +243,42 @@ public class AppOpsService extends IAppOpsService.Stub { public void systemReady() { synchronized (this) { boolean changed = false; - for (int i=0; i<mUidOps.size(); i++) { - HashMap<String, Ops> pkgs = mUidOps.valueAt(i); + for (int i = mUidStates.size() - 1; i >= 0; i--) { + UidState uidState = mUidStates.valueAt(i); + + String[] packageNames = getPackagesForUid(uidState.uid); + if (ArrayUtils.isEmpty(packageNames)) { + uidState.clear(); + mUidStates.removeAt(i); + changed = true; + continue; + } + + ArrayMap<String, Ops> pkgs = uidState.pkgOps; + if (pkgs == null) { + continue; + } + Iterator<Ops> it = pkgs.values().iterator(); while (it.hasNext()) { Ops ops = it.next(); int curUid; try { curUid = mContext.getPackageManager().getPackageUid(ops.packageName, - UserHandle.getUserId(ops.uid)); + UserHandle.getUserId(ops.uidState.uid)); } catch (NameNotFoundException e) { curUid = -1; } - if (curUid != ops.uid) { + if (curUid != ops.uidState.uid) { Slog.i(TAG, "Pruning old package " + ops.packageName - + "/" + ops.uid + ": new uid=" + curUid); + + "/" + ops.uidState + ": new uid=" + curUid); it.remove(); changed = true; } } - if (pkgs.size() <= 0) { - mUidOps.removeAt(i); + + if (uidState.isDefault()) { + mUidStates.removeAt(i); } } if (changed) { @@ -279,22 +317,34 @@ public class AppOpsService extends IAppOpsService.Stub { public void packageRemoved(int uid, String packageName) { synchronized (this) { - HashMap<String, Ops> pkgs = mUidOps.get(uid); - if (pkgs != null) { - if (pkgs.remove(packageName) != null) { - if (pkgs.size() <= 0) { - mUidOps.remove(uid); - } - scheduleFastWriteLocked(); - } + UidState uidState = mUidStates.get(uid); + if (uidState == null) { + return; + } + + boolean changed = false; + + // Remove any package state if such. + if (uidState.pkgOps != null && uidState.pkgOps.remove(packageName) != null) { + changed = true; + } + + // If we just nuked the last package state check if the UID is valid. + if (changed && uidState.pkgOps.isEmpty() + && getPackagesForUid(uid).length <= 0) { + mUidStates.remove(uid); + } + + if (changed) { + scheduleFastWriteLocked(); } } } public void uidRemoved(int uid) { synchronized (this) { - if (mUidOps.indexOfKey(uid) >= 0) { - mUidOps.remove(uid); + if (mUidStates.indexOfKey(uid) >= 0) { + mUidStates.remove(uid); scheduleFastWriteLocked(); } } @@ -346,16 +396,23 @@ public class AppOpsService extends IAppOpsService.Stub { Binder.getCallingPid(), Binder.getCallingUid(), null); ArrayList<AppOpsManager.PackageOps> res = null; synchronized (this) { - for (int i=0; i<mUidOps.size(); i++) { - HashMap<String, Ops> packages = mUidOps.valueAt(i); - for (Ops pkgOps : packages.values()) { + final int uidStateCount = mUidStates.size(); + for (int i = 0; i < uidStateCount; i++) { + UidState uidState = mUidStates.valueAt(i); + if (uidState.pkgOps == null || uidState.pkgOps.isEmpty()) { + continue; + } + ArrayMap<String, Ops> packages = uidState.pkgOps; + final int packageCount = packages.size(); + for (int j = 0; j < packageCount; j++) { + Ops pkgOps = packages.valueAt(j); ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); if (resOps != null) { if (res == null) { res = new ArrayList<AppOpsManager.PackageOps>(); } AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( - pkgOps.packageName, pkgOps.uid, resOps); + pkgOps.packageName, pkgOps.uidState.uid, resOps); res.add(resPackage); } } @@ -380,7 +437,7 @@ public class AppOpsService extends IAppOpsService.Stub { } ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>(); AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( - pkgOps.packageName, pkgOps.uid, resOps); + pkgOps.packageName, pkgOps.uidState.uid, resOps); res.add(resPackage); return res; } @@ -392,15 +449,126 @@ public class AppOpsService extends IAppOpsService.Stub { if (ops != null) { ops.remove(op.op); if (ops.size() <= 0) { - HashMap<String, Ops> pkgOps = mUidOps.get(uid); + UidState uidState = ops.uidState; + ArrayMap<String, Ops> pkgOps = uidState.pkgOps; if (pkgOps != null) { pkgOps.remove(ops.packageName); - if (pkgOps.size() <= 0) { - mUidOps.remove(uid); + if (pkgOps.isEmpty()) { + uidState.pkgOps = null; + } + if (uidState.isDefault()) { + mUidStates.remove(uid); + } + } + } + } + } + } + + @Override + public void setUidMode(int code, int uid, int mode) { + if (Binder.getCallingPid() != Process.myPid()) { + mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS, + Binder.getCallingPid(), Binder.getCallingUid(), null); + } + verifyIncomingOp(code); + code = AppOpsManager.opToSwitch(code); + + synchronized (this) { + final int defaultMode = AppOpsManager.opToDefaultMode(code); + + UidState uidState = getUidStateLocked(uid, false); + if (uidState == null) { + if (mode == defaultMode) { + return; + } + uidState = new UidState(uid); + uidState.opModes = new SparseIntArray(); + uidState.opModes.put(code, mode); + mUidStates.put(uid, uidState); + scheduleWriteLocked(); + } else if (uidState.opModes == null) { + if (mode != defaultMode) { + uidState.opModes = new SparseIntArray(); + uidState.opModes.put(code, mode); + scheduleWriteLocked(); + } + } else { + if (uidState.opModes.get(code) == mode) { + return; + } + if (mode == defaultMode) { + uidState.opModes.delete(code); + if (uidState.opModes.size() <= 0) { + uidState.opModes = null; + } + } else { + uidState.opModes.put(code, mode); + } + scheduleWriteLocked(); + } + } + + ArrayMap<Callback, ArraySet<String>> callbackSpecs = null; + + ArrayList<Callback> callbacks = mOpModeWatchers.get(code); + if (callbacks != null) { + final int callbackCount = callbacks.size(); + for (int i = 0; i < callbackCount; i++) { + Callback callback = callbacks.get(i); + callbackSpecs = new ArrayMap<>(); + callbackSpecs.put(callback, null); + } + } + + String[] uidPackageNames = getPackagesForUid(uid); + for (String uidPackageName : uidPackageNames) { + callbacks = mPackageModeWatchers.get(uidPackageName); + if (callbacks != null) { + if (callbackSpecs == null) { + callbackSpecs = new ArrayMap<>(); + } + final int callbackCount = callbacks.size(); + for (int i = 0; i < callbackCount; i++) { + Callback callback = callbacks.get(i); + ArraySet<String> changedPackages = callbackSpecs.get(callback); + if (changedPackages == null) { + changedPackages = new ArraySet<>(); + callbackSpecs.put(callback, changedPackages); + } + changedPackages.add(uidPackageName); + } + } + } + + if (callbackSpecs == null) { + return; + } + + // There are components watching for mode changes such as window manager + // and location manager which are in our process. The callbacks in these + // components may require permissions our remote caller does not have. + final long identity = Binder.clearCallingIdentity(); + try { + for (int i = 0; i < callbackSpecs.size(); i++) { + Callback callback = callbackSpecs.keyAt(i); + ArraySet<String> reportedPackageNames = callbackSpecs.valueAt(i); + try { + if (reportedPackageNames == null) { + callback.mCallback.opChanged(code, null); + } else { + final int reportedPackageCount = reportedPackageNames.size(); + for (int j = 0; j < reportedPackageCount; j++) { + String reportedPackageName = reportedPackageNames.valueAt(j); + callback.mCallback.opChanged(code, reportedPackageName); } } + } catch (RemoteException e) { + Log.w(TAG, "Error dispatching op op change", e); } } + } finally { + Binder.restoreCallingIdentity(identity); } } @@ -414,6 +582,7 @@ public class AppOpsService extends IAppOpsService.Stub { ArrayList<Callback> repCbs = null; code = AppOpsManager.opToSwitch(code); synchronized (this) { + UidState uidState = getUidStateLocked(uid, false); Op op = getOpLocked(code, uid, packageName, true); if (op != null) { if (op.mode != mode) { @@ -468,14 +637,26 @@ public class AppOpsService extends IAppOpsService.Stub { if (callbacks == null) { callbacks = new HashMap<Callback, ArrayList<Pair<String, Integer>>>(); } + boolean duplicate = false; for (int i=0; i<cbs.size(); i++) { Callback cb = cbs.get(i); ArrayList<Pair<String, Integer>> reports = callbacks.get(cb); if (reports == null) { reports = new ArrayList<Pair<String, Integer>>(); callbacks.put(cb, reports); + } else { + final int reportCount = reports.size(); + for (int j = 0; j < reportCount; j++) { + Pair<String, Integer> report = reports.get(j); + if (report.second == op && report.first.equals(packageName)) { + duplicate = true; + break; + } + } + } + if (!duplicate) { + reports.add(new Pair<>(packageName, op)); } - reports.add(new Pair<String, Integer>(packageName, op)); } return callbacks; } @@ -488,16 +669,54 @@ public class AppOpsService extends IAppOpsService.Stub { callingPid, callingUid, null); reqUserId = ActivityManager.handleIncomingUser(callingPid, callingUid, reqUserId, true, true, "resetAllModes", null); + + int reqUid = -1; + if (reqPackageName != null) { + try { + reqUid = AppGlobals.getPackageManager().getPackageUid( + reqPackageName, reqUserId); + } catch (RemoteException e) { + /* ignore - local call */ + } + } + HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks = null; synchronized (this) { boolean changed = false; - for (int i=mUidOps.size()-1; i>=0; i--) { - HashMap<String, Ops> packages = mUidOps.valueAt(i); + for (int i = mUidStates.size() - 1; i >= 0; i--) { + UidState uidState = mUidStates.valueAt(i); + + SparseIntArray opModes = uidState.opModes; + if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) { + final int uidOpCount = opModes.size(); + for (int j = uidOpCount - 1; j >= 0; j--) { + final int code = opModes.keyAt(j); + if (AppOpsManager.opAllowsReset(code)) { + opModes.removeAt(j); + if (opModes.size() <= 0) { + uidState.opModes = null; + } + for (String packageName : getPackagesForUid(uidState.uid)) { + callbacks = addCallbacks(callbacks, packageName, code, + mOpModeWatchers.get(code)); + callbacks = addCallbacks(callbacks, packageName, code, + mPackageModeWatchers.get(packageName)); + } + } + } + } + + if (uidState.pkgOps == null) { + continue; + } + if (reqUserId != UserHandle.USER_ALL - && reqUserId != UserHandle.getUserId(mUidOps.keyAt(i))) { + && reqUserId != UserHandle.getUserId(uidState.uid)) { // Skip any ops for a different user continue; } + + Map<String, Ops> packages = uidState.pkgOps; Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, Ops> ent = it.next(); @@ -526,10 +745,11 @@ public class AppOpsService extends IAppOpsService.Stub { it.remove(); } } - if (packages.size() == 0) { - mUidOps.removeAt(i); + if (uidState.isDefault()) { + mUidStates.remove(uidState.uid); } } + if (changed) { scheduleFastWriteLocked(); } @@ -552,7 +772,7 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) { synchronized (this) { - op = AppOpsManager.opToSwitch(op); + op = (op != AppOpsManager.OP_NONE) ? AppOpsManager.opToSwitch(op) : op; Callback cb = mModeWatchers.get(callback.asBinder()); if (cb == null) { cb = new Callback(callback); @@ -621,7 +841,15 @@ public class AppOpsService extends IAppOpsService.Stub { if (isOpRestricted(uid, code, packageName)) { return AppOpsManager.MODE_IGNORED; } - Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false); + code = AppOpsManager.opToSwitch(code); + UidState uidState = getUidStateLocked(uid, false); + if (uidState != null && uidState.opModes != null) { + final int uidMode = uidState.opModes.get(code); + if (uidMode != AppOpsManager.MODE_ALLOWED) { + return uidMode; + } + } + Op op = getOpLocked(code, uid, packageName, false); if (op == null) { return AppOpsManager.opToDefaultMode(code); } @@ -732,6 +960,17 @@ public class AppOpsService extends IAppOpsService.Stub { } op.duration = 0; final int switchCode = AppOpsManager.opToSwitch(code); + UidState uidState = ops.uidState; + if (uidState.opModes != null) { + final int uidMode = uidState.opModes.get(switchCode); + if (uidMode != AppOpsManager.MODE_ALLOWED) { + if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " + + switchCode + " (" + code + ") uid " + uid + " package " + + packageName); + op.rejectTime = System.currentTimeMillis(); + return uidMode; + } + } final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " @@ -766,6 +1005,17 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_IGNORED; } final int switchCode = AppOpsManager.opToSwitch(code); + UidState uidState = ops.uidState; + if (uidState.opModes != null) { + final int uidMode = uidState.opModes.get(switchCode); + if (uidMode != AppOpsManager.MODE_ALLOWED) { + if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " + + switchCode + " (" + code + ") uid " + uid + " package " + + packageName); + op.rejectTime = System.currentTimeMillis(); + return uidMode; + } + } final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code " @@ -847,6 +1097,18 @@ public class AppOpsService extends IAppOpsService.Stub { throw new IllegalArgumentException("Bad operation #" + op); } + private UidState getUidStateLocked(int uid, boolean edit) { + UidState uidState = mUidStates.get(uid); + if (uidState == null) { + if (!edit) { + return null; + } + uidState = new UidState(uid); + mUidStates.put(uid, uidState); + } + return uidState; + } + private Ops getOpsLocked(int uid, String packageName, boolean edit) { if (uid == 0) { packageName = "root"; @@ -857,15 +1119,19 @@ public class AppOpsService extends IAppOpsService.Stub { } private Ops getOpsRawLocked(int uid, String packageName, boolean edit) { - HashMap<String, Ops> pkgOps = mUidOps.get(uid); - if (pkgOps == null) { + UidState uidState = getUidStateLocked(uid, edit); + if (uidState == null) { + return null; + } + + if (uidState.pkgOps == null) { if (!edit) { return null; } - pkgOps = new HashMap<String, Ops>(); - mUidOps.put(uid, pkgOps); + uidState.pkgOps = new ArrayMap<>(); } - Ops ops = pkgOps.get(packageName); + + Ops ops = uidState.pkgOps.get(packageName); if (ops == null) { if (!edit) { return null; @@ -904,8 +1170,8 @@ public class AppOpsService extends IAppOpsService.Stub { Binder.restoreCallingIdentity(ident); } } - ops = new Ops(packageName, uid, isPrivileged); - pkgOps.put(packageName, ops); + ops = new Ops(packageName, uidState, isPrivileged); + uidState.pkgOps.put(packageName, ops); } return ops; } @@ -940,7 +1206,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (!edit) { return null; } - op = new Op(ops.uid, ops.packageName, code); + op = new Op(ops.uidState.uid, ops.packageName, code); ops.put(code, op); } if (edit) { @@ -1000,6 +1266,8 @@ public class AppOpsService extends IAppOpsService.Stub { String tagName = parser.getName(); if (tagName.equals("pkg")) { readPackage(parser); + } if (tagName.equals("uid")) { + readUidOps(parser); } else { Slog.w(TAG, "Unknown element under <app-ops>: " + parser.getName()); @@ -1021,7 +1289,7 @@ public class AppOpsService extends IAppOpsService.Stub { Slog.w(TAG, "Failed parsing " + e); } finally { if (!success) { - mUidOps.clear(); + mUidStates.clear(); } try { stream.close(); @@ -1032,6 +1300,34 @@ public class AppOpsService extends IAppOpsService.Stub { } } + void readUidOps(XmlPullParser parser) throws NumberFormatException, + XmlPullParserException, IOException { + final int uid = Integer.parseInt(parser.getAttributeValue(null, "n")); + 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("op")) { + final int code = Integer.parseInt(parser.getAttributeValue(null, "n")); + final int mode = Integer.parseInt(parser.getAttributeValue(null, "m")); + UidState uidState = getUidStateLocked(uid, true); + if (uidState.opModes == null) { + uidState.opModes = new SparseIntArray(); + } + uidState.opModes.put(code, mode); + } else { + Slog.w(TAG, "Unknown element under <uid-ops>: " + + parser.getName()); + XmlUtils.skipCurrentTag(parser); + } + } + } + void readPackage(XmlPullParser parser) throws NumberFormatException, XmlPullParserException, IOException { String pkgName = parser.getAttributeValue(null, "n"); @@ -1114,15 +1410,16 @@ public class AppOpsService extends IAppOpsService.Stub { if (proxyPackageName != null) { op.proxyPackageName = proxyPackageName; } - HashMap<String, Ops> pkgOps = mUidOps.get(uid); - if (pkgOps == null) { - pkgOps = new HashMap<String, Ops>(); - mUidOps.put(uid, pkgOps); + + UidState uidState = getUidStateLocked(uid, true); + if (uidState.pkgOps == null) { + uidState.pkgOps = new ArrayMap<>(); } - Ops ops = pkgOps.get(pkgName); + + Ops ops = uidState.pkgOps.get(pkgName); if (ops == null) { - ops = new Ops(pkgName, uid, isPrivileged); - pkgOps.put(pkgName, ops); + ops = new Ops(pkgName, uidState, isPrivileged); + uidState.pkgOps.put(pkgName, ops); } ops.put(op.op, op); } else { @@ -1149,7 +1446,27 @@ public class AppOpsService extends IAppOpsService.Stub { XmlSerializer out = new FastXmlSerializer(); out.setOutput(stream, StandardCharsets.UTF_8.name()); out.startDocument(null, true); - out.startTag(null, "app-ops"); + out.startTag(null, "app"); + + final int uidStateCount = mUidStates.size(); + for (int i = 0; i < uidStateCount; i++) { + UidState uidState = mUidStates.valueAt(i); + if (uidState.opModes != null && uidState.opModes.size() > 0) { + out.startTag(null, "uid"); + out.attribute(null, "n", Integer.toString(uidState.uid)); + SparseIntArray uidOpModes = uidState.opModes; + final int opCount = uidOpModes.size(); + for (int j = 0; j < opCount; j++) { + final int op = uidOpModes.keyAt(j); + final int mode = uidOpModes.valueAt(j); + out.startTag(null, "op"); + out.attribute(null, "n", Integer.toString(op)); + out.attribute(null, "m", Integer.toString(mode)); + out.endTag(null, "op"); + } + out.endTag(null, "uid"); + } + } if (allOps != null) { String lastPkg = null; @@ -1316,9 +1633,27 @@ public class AppOpsService extends IAppOpsService.Stub { if (needSep) { pw.println(); } - for (int i=0; i<mUidOps.size(); i++) { - pw.print(" Uid "); UserHandle.formatUid(pw, mUidOps.keyAt(i)); pw.println(":"); - HashMap<String, Ops> pkgOps = mUidOps.valueAt(i); + for (int i=0; i<mUidStates.size(); i++) { + UidState uidState = mUidStates.valueAt(i); + + pw.print(" Uid "); UserHandle.formatUid(pw, uidState.uid); pw.println(":"); + + SparseIntArray opModes = uidState.opModes; + if (opModes != null) { + final int opModeCount = opModes.size(); + for (int j = 0; j < opModeCount; j++) { + final int code = opModes.keyAt(j); + final int mode = opModes.valueAt(j); + pw.print(" "); pw.print(AppOpsManager.opToName(code)); + pw.print(": mode="); pw.println(mode); + } + } + + ArrayMap<String, Ops> pkgOps = uidState.pkgOps; + if (pkgOps == null) { + continue; + } + for (Ops ops : pkgOps.values()) { pw.print(" Package "); pw.print(ops.packageName); pw.println(":"); for (int j=0; j<ops.size(); j++) { @@ -1382,4 +1717,16 @@ public class AppOpsService extends IAppOpsService.Stub { } } + private static String[] getPackagesForUid(int uid) { + String[] packageNames = null; + try { + packageNames= AppGlobals.getPackageManager().getPackagesForUid(uid); + } catch (RemoteException e) { + /* ignore - local call */ + } + if (packageNames == null) { + return EmptyArray.STRING; + } + return packageNames; + } } diff --git a/services/core/java/com/android/server/AssetAtlasService.java b/services/core/java/com/android/server/AssetAtlasService.java index ebc810f3a6e1..4569daee029e 100644 --- a/services/core/java/com/android/server/AssetAtlasService.java +++ b/services/core/java/com/android/server/AssetAtlasService.java @@ -93,7 +93,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub { // Defines the number of int fields used to represent a single entry // in the atlas map. This number defines the size of the array returned // by the getMap(). See the mAtlasMap field for more information - private static final int ATLAS_MAP_ENTRY_FIELD_COUNT = 4; + private static final int ATLAS_MAP_ENTRY_FIELD_COUNT = 3; // Specifies how our GraphicBuffer will be used. To get proper swizzling // the buffer will be written to using OpenGL (from JNI) so we can leave diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index b9f62e678562..50bd544a308f 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -805,6 +805,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { IBinder mService; ComponentName mClassName; Intent mIntent; + boolean mInvokingProxyCallbacks = false; ProfileServiceConnections(Intent intent) { mService = null; @@ -871,34 +872,54 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } catch (RemoteException e) { Log.e(TAG, "Unable to linkToDeath", e); } - int n = mProxies.beginBroadcast(); - for (int i = 0; i < n; i++) { - try { - mProxies.getBroadcastItem(i).onServiceConnected(className, service); - } catch (RemoteException e) { - Log.e(TAG, "Unable to connect to proxy", e); + + if (mInvokingProxyCallbacks) { + Log.e(TAG, "Proxy callbacks already in progress."); + return; + } + mInvokingProxyCallbacks = true; + + final int n = mProxies.beginBroadcast(); + try { + for (int i = 0; i < n; i++) { + try { + mProxies.getBroadcastItem(i).onServiceConnected(className, service); + } catch (RemoteException e) { + Log.e(TAG, "Unable to connect to proxy", e); + } } + } finally { + mProxies.finishBroadcast(); + mInvokingProxyCallbacks = false; } - mProxies.finishBroadcast(); } @Override public void onServiceDisconnected(ComponentName className) { - if (mService == null) { - return; - } + if (mService == null) return; mService.unlinkToDeath(this, 0); mService = null; mClassName = null; - int n = mProxies.beginBroadcast(); - for (int i = 0; i < n; i++) { - try { - mProxies.getBroadcastItem(i).onServiceDisconnected(className); - } catch (RemoteException e) { - Log.e(TAG, "Unable to disconnect from proxy", e); + + if (mInvokingProxyCallbacks) { + Log.e(TAG, "Proxy callbacks already in progress."); + return; + } + mInvokingProxyCallbacks = true; + + final int n = mProxies.beginBroadcast(); + try { + for (int i = 0; i < n; i++) { + try { + mProxies.getBroadcastItem(i).onServiceDisconnected(className); + } catch (RemoteException e) { + Log.e(TAG, "Unable to disconnect from proxy", e); + } } + } finally { + mProxies.finishBroadcast(); + mInvokingProxyCallbacks = false; } - mProxies.finishBroadcast(); } @Override @@ -916,16 +937,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } private void sendBluetoothStateCallback(boolean isUp) { - int n = mStateChangeCallbacks.beginBroadcast(); - if (DBG) Log.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers."); - for (int i=0; i <n;i++) { - try { - mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp); - } catch (RemoteException e) { - Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e); + try { + int n = mStateChangeCallbacks.beginBroadcast(); + if (DBG) Log.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers."); + for (int i=0; i <n;i++) { + try { + mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp); + } catch (RemoteException e) { + Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e); + } } + } finally { + mStateChangeCallbacks.finishBroadcast(); } - mStateChangeCallbacks.finishBroadcast(); } /** @@ -934,16 +958,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private void sendBluetoothServiceUpCallback() { if (!mConnection.isGetNameAddressOnly()) { if (DBG) Log.d(TAG,"Calling onBluetoothServiceUp callbacks"); - int n = mCallbacks.beginBroadcast(); - Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers."); - for (int i=0; i <n;i++) { - try { - mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth); - } catch (RemoteException e) { - Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e); + try { + int n = mCallbacks.beginBroadcast(); + Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers."); + for (int i=0; i <n;i++) { + try { + mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth); + } catch (RemoteException e) { + Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e); + } } + } finally { + mCallbacks.finishBroadcast(); } - mCallbacks.finishBroadcast(); } } /** @@ -952,16 +979,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private void sendBluetoothServiceDownCallback() { if (!mConnection.isGetNameAddressOnly()) { if (DBG) Log.d(TAG,"Calling onBluetoothServiceDown callbacks"); - int n = mCallbacks.beginBroadcast(); - Log.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers."); - for (int i=0; i <n;i++) { - try { - mCallbacks.getBroadcastItem(i).onBluetoothServiceDown(); - } catch (RemoteException e) { - Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e); + try { + int n = mCallbacks.beginBroadcast(); + Log.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers."); + for (int i=0; i <n;i++) { + try { + mCallbacks.getBroadcastItem(i).onBluetoothServiceDown(); + } catch (RemoteException e) { + Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e); + } } + } finally { + mCallbacks.finishBroadcast(); } - mCallbacks.finishBroadcast(); } } @@ -1476,6 +1506,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { //Unbind mContext.unbindService(mConnection); } + mBluetoothGatt = null; } SystemClock.sleep(100); @@ -1781,6 +1812,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { //Unbind mContext.unbindService(mConnection); } + mBluetoothGatt = null; } mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 62e8532259e4..0802d301face 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1772,7 +1772,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Start gathering diagnostic information. netDiags.add(new NetworkDiagnostics( nai.network, - new LinkProperties(nai.linkProperties), + new LinkProperties(nai.linkProperties), // Must be a copy. DIAG_TIME_MS)); } @@ -2142,6 +2142,10 @@ public class ConnectivityService extends IConnectivityManager.Stub mDefaultInetConditionPublished = 0; } notifyIfacesChanged(); + // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied + // by other networks that are already connected. Perhaps that can be done by + // sending all CALLBACK_LOST messages (for requests, not listens) at the end + // of rematchAllNetworksAndRequests notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST); nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED); mNetworkAgentInfos.remove(msg.replyTo); @@ -2250,7 +2254,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // is currently satisfying the request. This is desirable when // cellular ends up validating but WiFi does not. // 2. Unvalidated WiFi will not be reaped when validated cellular - // is currently satsifying the request. This is desirable when + // is currently satisfying the request. This is desirable when // WiFi ends up validating and out scoring cellular. mNetworkForRequestId.get(nri.request.requestId).getCurrentScore() < nai.getCurrentScoreAsValidated())) { @@ -2378,14 +2382,10 @@ public class ConnectivityService extends IConnectivityManager.Stub } if (!accept) { - // Tell the NetworkAgent that the network does not have Internet access (because that's - // what we just told the user). This will hint to Wi-Fi not to autojoin this network in - // the future. We do this now because NetworkMonitor might not yet have finished - // validating and thus we might not yet have received an EVENT_NETWORK_TESTED. - nai.asyncChannel.sendMessage(NetworkAgent.CMD_REPORT_NETWORK_STATUS, - NetworkAgent.INVALID_NETWORK, 0, null); - // TODO: Tear the network down once we have determined how to tell WifiStateMachine not - // to reconnect to it immediately. http://b/20739299 + // Tell the NetworkAgent to not automatically reconnect to the network. + nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT); + // Teardown the nework. + teardownUnneededNetwork(nai); } } @@ -3048,7 +3048,10 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public LegacyVpnInfo getLegacyVpnInfo(int userId) { enforceCrossUserPermission(userId); - throwIfLockdownEnabled(); + if (mLockdownEnabled) { + return null; + } + synchronized(mVpns) { return mVpns.get(userId).getLegacyVpnInfo(); } @@ -3799,10 +3802,10 @@ public class ConnectivityService extends IConnectivityManager.Stub // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network // satisfies mDefaultRequest. - NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), + final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), new Network(reserveNetId()), new NetworkInfo(networkInfo), new LinkProperties( linkProperties), new NetworkCapabilities(networkCapabilities), currentScore, - mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest); + mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this); synchronized (this) { nai.networkMonitor.systemReady = mSystemReady; } @@ -4206,8 +4209,9 @@ public class ConnectivityService extends IConnectivityManager.Stub 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); - if (newNetwork == currentNetwork) { + final NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId); + final boolean satisfies = newNetwork.satisfies(nri.request); + if (newNetwork == currentNetwork && satisfies) { if (VDBG) { log("Network " + newNetwork.name() + " was already satisfying" + " request " + nri.request.requestId + ". No change."); @@ -4218,7 +4222,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // check if it satisfies the NetworkCapabilities if (VDBG) log(" checking if request is satisfied: " + nri.request); - if (newNetwork.satisfies(nri.request)) { + if (satisfies) { if (!nri.isRequest) { // This is not a request, it's a callback listener. // Add it to newNetwork regardless of score. @@ -4261,6 +4265,37 @@ public class ConnectivityService extends IConnectivityManager.Stub oldDefaultNetwork = currentNetwork; } } + } else if (newNetwork.networkRequests.get(nri.request.requestId) != null) { + // If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri", + // mark it as no longer satisfying "nri". Because networks are processed by + // rematchAllNetworkAndRequests() in descending score order, "currentNetwork" will + // match "newNetwork" before this loop will encounter a "currentNetwork" with higher + // score than "newNetwork" and where "currentNetwork" no longer satisfies "nri". + // This means this code doesn't have to handle the case where "currentNetwork" no + // longer satisfies "nri" when "currentNetwork" does not equal "newNetwork". + if (DBG) { + log("Network " + newNetwork.name() + " stopped satisfying" + + " request " + nri.request.requestId); + } + newNetwork.networkRequests.remove(nri.request.requestId); + if (currentNetwork == newNetwork) { + mNetworkForRequestId.remove(nri.request.requestId); + sendUpdatedScoreToFactories(nri.request, 0); + } else { + if (nri.isRequest == true) { + Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " + + newNetwork.name() + + " without updating mNetworkForRequestId or factories!"); + } + } + // TODO: technically, sending CALLBACK_LOST here is + // incorrect if nri is a request (not a listen) and there + // is a replacement network currently connected that can + // satisfy it. However, the only capability that can both + // a) be requested and b) change is NET_CAPABILITY_TRUSTED, + // so this code is only incorrect for a network that loses + // the TRUSTED capability, which is a rare case. + callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST); } } // Linger any networks that are no longer needed. @@ -4279,41 +4314,41 @@ public class ConnectivityService extends IConnectivityManager.Stub unlinger(nai); } } - if (keep) { - if (isNewDefault) { - // Notify system services that this network is up. - makeDefault(newNetwork); - synchronized (ConnectivityService.this) { - // have a new default network, release the transition wakelock in - // a second if it's held. The second pause is to allow apps - // to reconnect over the new network - if (mNetTransitionWakeLock.isHeld()) { - mHandler.sendMessageDelayed(mHandler.obtainMessage( - EVENT_CLEAR_NET_TRANSITION_WAKELOCK, - mNetTransitionWakeLockSerialNumber, 0), - 1000); - } + if (isNewDefault) { + // Notify system services that this network is up. + makeDefault(newNetwork); + synchronized (ConnectivityService.this) { + // have a new default network, release the transition wakelock in + // a second if it's held. The second pause is to allow apps + // to reconnect over the new network + if (mNetTransitionWakeLock.isHeld()) { + mHandler.sendMessageDelayed(mHandler.obtainMessage( + EVENT_CLEAR_NET_TRANSITION_WAKELOCK, + mNetTransitionWakeLockSerialNumber, 0), + 1000); } } + } - // do this after the default net is switched, but - // before LegacyTypeTracker sends legacy broadcasts - for (NetworkRequestInfo nri : addedRequests) notifyNetworkCallback(newNetwork, nri); + // do this after the default net is switched, but + // before LegacyTypeTracker sends legacy broadcasts + for (NetworkRequestInfo nri : addedRequests) notifyNetworkCallback(newNetwork, nri); - if (isNewDefault) { - // Maintain the illusion: since the legacy API only - // understands one network at a time, we must pretend - // that the current default network disconnected before - // the new one connected. - if (oldDefaultNetwork != null) { - mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), - oldDefaultNetwork, true); - } - mDefaultInetConditionPublished = newNetwork.lastValidated ? 100 : 0; - mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork); - notifyLockdownVpn(newNetwork); + if (isNewDefault) { + // Maintain the illusion: since the legacy API only + // understands one network at a time, we must pretend + // that the current default network disconnected before + // the new one connected. + if (oldDefaultNetwork != null) { + mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), + oldDefaultNetwork, true); } + mDefaultInetConditionPublished = newNetwork.lastValidated ? 100 : 0; + mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork); + notifyLockdownVpn(newNetwork); + } + if (keep) { // Notify battery stats service about this network, both the normal // interface and any stacked links. // TODO: Avoid redoing this; this must only be done once when a network comes online. @@ -4710,4 +4745,11 @@ public class ConnectivityService extends IConnectivityManager.Stub } } } + + @VisibleForTesting + public NetworkMonitor createNetworkMonitor(Context context, Handler handler, + NetworkAgentInfo nai, NetworkRequest defaultRequest) { + return new NetworkMonitor(context, handler, nai, defaultRequest); + } + } diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index c7c9d29aae65..7561c7d78b6d 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -253,6 +253,8 @@ public class DeviceIdleController extends SystemService "max_temp_app_whitelist_duration"; private static final String KEY_MMS_TEMP_APP_WHITELIST_DURATION = "mms_temp_app_whitelist_duration"; + private static final String KEY_SMS_TEMP_APP_WHITELIST_DURATION = + "sms_temp_app_whitelist_duration"; /** * This is the time, after becoming inactive, at which we start looking at the @@ -357,6 +359,13 @@ public class DeviceIdleController extends SystemService */ public long MMS_TEMP_APP_WHITELIST_DURATION; + /** + * Amount of time we would like to whitelist an app that is receiving an SMS. + * @see Settings.Global#DEVICE_IDLE_CONSTANTS + * @see #KEY_SMS_TEMP_APP_WHITELIST_DURATION + */ + public long SMS_TEMP_APP_WHITELIST_DURATION; + private final ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); @@ -410,6 +419,8 @@ public class DeviceIdleController extends SystemService KEY_MAX_TEMP_APP_WHITELIST_DURATION, 5 * 60 * 1000L); MMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong( KEY_MMS_TEMP_APP_WHITELIST_DURATION, 60 * 1000L); + SMS_TEMP_APP_WHITELIST_DURATION = mParser.getLong( + KEY_SMS_TEMP_APP_WHITELIST_DURATION, 20 * 1000L); } } @@ -465,6 +476,10 @@ public class DeviceIdleController extends SystemService pw.print(" "); pw.print(KEY_MMS_TEMP_APP_WHITELIST_DURATION); pw.print("="); TimeUtils.formatDuration(MMS_TEMP_APP_WHITELIST_DURATION, pw); pw.println(); + + pw.print(" "); pw.print(KEY_SMS_TEMP_APP_WHITELIST_DURATION); pw.print("="); + TimeUtils.formatDuration(SMS_TEMP_APP_WHITELIST_DURATION, pw); + pw.println(); } } @@ -617,6 +632,13 @@ public class DeviceIdleController extends SystemService return duration; } + @Override public long addPowerSaveTempWhitelistAppForSms(String packageName, + int userId, String reason) throws RemoteException { + long duration = mConstants.SMS_TEMP_APP_WHITELIST_DURATION; + addPowerSaveTempWhitelistApp(packageName, duration, userId, reason); + return duration; + } + @Override public void exitIdle(String reason) { getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index dbe878183e92..64ee5f1a1037 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -114,6 +114,7 @@ import android.view.inputmethod.InputBinding; import android.view.inputmethod.InputMethod; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; +import android.view.inputmethod.InputMethodManagerInternal; import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder; import android.widget.ArrayAdapter; @@ -166,6 +167,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub static final int MSG_UNBIND_METHOD = 3000; static final int MSG_BIND_METHOD = 3010; static final int MSG_SET_ACTIVE = 3020; + static final int MSG_SET_INTERACTIVE = 3030; static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 3040; static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000; @@ -394,9 +396,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub SessionState mEnabledSession; /** - * True if the screen is on. The value is true initially. + * True if the device is currently interactive with user. The value is true initially. */ - boolean mScreenOn = true; + boolean mIsInteractive = true; int mCurUserActionNotificationSequenceNumber = 0; @@ -492,30 +494,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } class ImmsBroadcastReceiver extends android.content.BroadcastReceiver { - private void updateActive() { - // Inform the current client of the change in active status - if (mCurClient != null && mCurClient.client != null) { - executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO( - MSG_SET_ACTIVE, mScreenOn ? 1 : 0, mCurClient)); - } - } - @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); - if (Intent.ACTION_SCREEN_ON.equals(action)) { - mScreenOn = true; - updateSystemUi(mCurToken, mImeWindowVis, mBackDisposition); - updateActive(); - return; - } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { - mScreenOn = false; - updateSystemUi(mCurToken, 0 /* vis */, mBackDisposition); - updateActive(); - return; - } else if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { + if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { hideInputMethodMenu(); - // No need to updateActive + // No need to update mIsInteractive return; } else if (Intent.ACTION_USER_ADDED.equals(action) || Intent.ACTION_USER_REMOVED.equals(action)) { @@ -817,8 +801,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mShowOngoingImeSwitcherForPhones = false; final IntentFilter broadcastFilter = new IntentFilter(); - broadcastFilter.addAction(Intent.ACTION_SCREEN_ON); - broadcastFilter.addAction(Intent.ACTION_SCREEN_OFF); broadcastFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); broadcastFilter.addAction(Intent.ACTION_USER_ADDED); broadcastFilter.addAction(Intent.ACTION_USER_REMOVED); @@ -938,6 +920,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } }, filter); + LocalServices.addService(InputMethodManagerInternal.class, new LocalServiceImpl(mHandler)); } private void resetDefaultImeLocked(Context context) { @@ -1379,9 +1362,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + cs.client.asBinder() + " keyguard=" + mCurClientInKeyguard); // If the screen is on, inform the new client it is active - if (mScreenOn) { + if (mIsInteractive) { executeOrSendMessage(cs.client, mCaller.obtainMessageIO( - MSG_SET_ACTIVE, mScreenOn ? 1 : 0, cs)); + MSG_SET_ACTIVE, mIsInteractive ? 1 : 0, cs)); } } @@ -2851,6 +2834,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + ((ClientState)msg.obj).uid); } return true; + case MSG_SET_INTERACTIVE: + handleSetInteractive(msg.arg1 != 0); + return true; case MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER: { final int sequenceNumber = msg.arg1; final ClientState clientState = (ClientState)msg.obj; @@ -2874,6 +2860,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return false; } + private void handleSetInteractive(final boolean interactive) { + synchronized (mMethodMap) { + mIsInteractive = interactive; + updateSystemUiLocked(mCurToken, interactive ? mImeWindowVis : 0, mBackDisposition); + + // Inform the current client of the change in active status + if (mCurClient != null && mCurClient.client != null) { + executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO( + MSG_SET_ACTIVE, mIsInteractive ? 1 : 0, mCurClient)); + } + } + } + private boolean chooseNewDefaultIMELocked() { final InputMethodInfo imi = InputMethodUtils.getMostApplicableDefaultIME( mSettings.getEnabledInputMethodListLocked()); @@ -3734,6 +3733,22 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } + private static final class LocalServiceImpl implements InputMethodManagerInternal { + @NonNull + private final Handler mHandler; + + LocalServiceImpl(@NonNull final Handler handler) { + mHandler = handler; + } + + @Override + public void setInteractive(boolean interactive) { + // Do everything in handler so as not to block the caller. + mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_INTERACTIVE, + interactive ? 1 : 0, 0)); + } + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) @@ -3784,7 +3799,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + " mInputShown=" + mInputShown); p.println(" mCurUserActionNotificationSequenceNumber=" + mCurUserActionNotificationSequenceNumber); - p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mScreenOn); + p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive); p.println(" mSettingsObserver=" + mSettingsObserver); p.println(" mSwitchingController:"); mSwitchingController.dump(p); diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 42794e721672..5e2fe5a7c431 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -335,7 +335,12 @@ public class LockSettingsService extends ILockSettings.Stub { public String getStringUnchecked(String key, String defaultValue, int userId) { if (Settings.Secure.LOCK_PATTERN_ENABLED.equals(key)) { - return mLockPatternUtils.isLockPatternEnabled(userId) ? "1" : "0"; + long ident = Binder.clearCallingIdentity(); + try { + return mLockPatternUtils.isLockPatternEnabled(userId) ? "1" : "0"; + } finally { + Binder.restoreCallingIdentity(ident); + } } return mStorage.readKeyValue(key, defaultValue, userId); diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 0e158a2e59dc..53e8d147ad3c 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -69,7 +69,6 @@ import android.os.storage.IMountServiceListener; import android.os.storage.IMountShutdownObserver; import android.os.storage.IObbActionListener; import android.os.storage.MountServiceInternal; -import android.os.storage.MountServiceInternal.ExternalStorageMountPolicy; import android.os.storage.OnObbStateChangeListener; import android.os.storage.StorageManager; import android.os.storage.StorageResultCode; @@ -146,8 +145,6 @@ import javax.crypto.spec.PBEKeySpec; class MountService extends IMountService.Stub implements INativeDaemonConnectorCallbacks, Watchdog.Monitor { - // TODO: finish enforcing UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA - // Static direct instance pointer for the tightly-coupled idle service to use static MountService sSelf = null; @@ -562,6 +559,7 @@ class MountService extends IMountService.Stub private static final int H_FSTRIM = 4; private static final int H_VOLUME_MOUNT = 5; private static final int H_VOLUME_BROADCAST = 6; + private static final int H_INTERNAL_BROADCAST = 7; class MountServiceHandler extends Handler { public MountServiceHandler(Looper looper) { @@ -631,6 +629,10 @@ class MountService extends IMountService.Stub } case H_VOLUME_MOUNT: { final VolumeInfo vol = (VolumeInfo) msg.obj; + if (isMountDisallowed(vol)) { + Slog.i(TAG, "Ignoring mount " + vol.getId() + " due to policy"); + break; + } try { mConnector.execute("volume", "mount", vol.id, vol.mountFlags, vol.mountUserId); @@ -654,6 +656,13 @@ class MountService extends IMountService.Stub } break; } + case H_INTERNAL_BROADCAST: { + // Internal broadcasts aimed at system components, not for + // third-party apps. + final Intent intent = (Intent) msg.obj; + mContext.sendBroadcastAsUser(intent, UserHandle.ALL, + android.Manifest.permission.WRITE_MEDIA_STORAGE); + } } } } @@ -740,15 +749,20 @@ class MountService extends IMountService.Stub */ @Deprecated private void killMediaProvider() { - final ProviderInfo provider = mPms.resolveContentProvider(MediaStore.AUTHORITY, 0, - UserHandle.USER_OWNER); - if (provider != null) { - final IActivityManager am = ActivityManagerNative.getDefault(); - try { - am.killApplicationWithAppId(provider.applicationInfo.packageName, - UserHandle.getAppId(provider.applicationInfo.uid), "vold reset"); - } catch (RemoteException e) { + final long token = Binder.clearCallingIdentity(); + try { + final ProviderInfo provider = mPms.resolveContentProvider(MediaStore.AUTHORITY, 0, + UserHandle.USER_OWNER); + if (provider != null) { + final IActivityManager am = ActivityManagerNative.getDefault(); + try { + am.killApplicationWithAppId(provider.applicationInfo.packageName, + UserHandle.getAppId(provider.applicationInfo.uid), "vold reset"); + } catch (RemoteException e) { + } } + } finally { + Binder.restoreCallingIdentity(token); } } @@ -802,7 +816,7 @@ class MountService extends IMountService.Stub synchronized (mVolumes) { for (int i = 0; i < mVolumes.size(); i++) { final VolumeInfo vol = mVolumes.valueAt(i); - if (vol.isVisibleToUser(userId) && vol.isMountedReadable()) { + if (vol.isVisibleForRead(userId) && vol.isMountedReadable()) { final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false); mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget(); @@ -1120,8 +1134,7 @@ class MountService extends IMountService.Stub intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.id); intent.putExtra(DiskInfo.EXTRA_VOLUME_COUNT, volumeCount); - mContext.sendBroadcastAsUser(intent, UserHandle.ALL, - android.Manifest.permission.WRITE_MEDIA_STORAGE); + mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget(); final CountDownLatch latch = mDiskScanLatches.remove(disk.id); if (latch != null) { @@ -1233,8 +1246,7 @@ class MountService extends IMountService.Stub 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); + mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget(); } final String oldStateEnv = VolumeInfo.getEnvironmentForState(oldState); @@ -1245,7 +1257,7 @@ class MountService extends IMountService.Stub // started after this point will trigger additional // user-specific broadcasts. for (int userId : mStartedUsers) { - if (vol.isVisibleToUser(userId)) { + if (vol.isVisibleForRead(userId)) { final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false); mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget(); @@ -1300,10 +1312,16 @@ class MountService extends IMountService.Stub mContext.enforceCallingOrSelfPermission(perm, perm); } - private void enforceUserRestriction(String restriction) { - UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - if (um.hasUserRestriction(restriction, Binder.getCallingUserHandle())) { - throw new SecurityException("User has restriction " + restriction); + /** + * Decide if volume is mountable per device policies. + */ + private boolean isMountDisallowed(VolumeInfo vol) { + if (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_PRIVATE) { + final UserManager userManager = mContext.getSystemService(UserManager.class); + return userManager.hasUserRestriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, + Binder.getCallingUserHandle()); + } else { + return false; } } @@ -1581,8 +1599,8 @@ class MountService extends IMountService.Stub waitForReady(); final VolumeInfo vol = findVolumeByIdOrThrow(volId); - if (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_PRIVATE) { - enforceUserRestriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA); + if (isMountDisallowed(vol)) { + throw new SecurityException("Mounting " + volId + " restricted by policy"); } try { mConnector.execute("volume", "mount", vol.id, vol.mountFlags, vol.mountUserId); @@ -2597,13 +2615,14 @@ class MountService extends IMountService.Stub } @Override - public StorageVolume[] getVolumeList(int uid, String packageName) { + public StorageVolume[] getVolumeList(int uid, String packageName, int flags) { + final boolean forWrite = (flags & StorageManager.FLAG_FOR_WRITE) != 0; + final ArrayList<StorageVolume> res = new ArrayList<>(); boolean foundPrimary = false; final int userId = UserHandle.getUserId(uid); final boolean reportUnmounted; - final long identity = Binder.clearCallingIdentity(); try { reportUnmounted = !mMountServiceInternal.hasExternalStorage( @@ -2615,7 +2634,7 @@ class MountService extends IMountService.Stub synchronized (mLock) { for (int i = 0; i < mVolumes.size(); i++) { final VolumeInfo vol = mVolumes.valueAt(i); - if (vol.isVisibleToUser(userId)) { + if (forWrite ? vol.isVisibleForWrite(userId) : vol.isVisibleForRead(userId)) { final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, reportUnmounted); if (vol.isPrimary()) { @@ -3426,6 +3445,11 @@ class MountService extends IMountService.Stub } public boolean hasExternalStorage(int uid, String packageName) { + // No need to check for system uid. This avoids a deadlock between + // PackageManagerService and AppOpsService. + if (uid == Process.SYSTEM_UID) { + return true; + } // No locking - CopyOnWriteArrayList for (ExternalStorageMountPolicy policy : mPolicies) { final boolean policyHasStorage = policy.hasExternalStorage(uid, packageName); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index a06bb3069d64..19a4851525a6 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -362,10 +362,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } try { - mContext.enforceCallingPermission( + mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, "addOnSubscriptionsChangedListener"); - // SKIP checking for run-time permission since obtained PRIVILEGED + // SKIP checking for run-time permission since caller or self has PRIVILEGED permission } catch (SecurityException e) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PHONE_STATE, @@ -481,9 +481,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) { try { - mContext.enforceCallingPermission( + mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); - // SKIP checking for run-time permission since obtained PRIVILEGED + // SKIP checking for run-time permission since caller or self has PRIVILEGED + // permission } catch (SecurityException e) { if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), callingPackage) != AppOpsManager.MODE_ALLOWED) { @@ -661,10 +662,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } private boolean canReadPhoneState(String callingPackage) { - if (mContext.checkCallingPermission( + if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { - // SKIP checking for run-time permission since obtained PRIVILEGED + // SKIP checking for run-time permission since caller or self has PRIVILEGED permission return true; } boolean canReadPhoneState = mContext.checkCallingOrSelfPermission( @@ -1589,9 +1590,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) { try { - mContext.enforceCallingPermission( + mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); - // SKIP checking for run-time permission since obtained PRIVILEGED + // SKIP checking for run-time permission since caller or self has PRIVILEGED + // permission } catch (SecurityException e) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PHONE_STATE, null); diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index a27097468405..32fd56ae4c3b 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -534,9 +534,10 @@ public class AccountManagerService account.type); throw new SecurityException(msg); } - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); return readPasswordInternal(accounts, account); } finally { restoreCallingIdentity(identityToken); @@ -572,9 +573,10 @@ public class AccountManagerService + ", pid " + Binder.getCallingPid()); } if (account == null) throw new IllegalArgumentException("account is null"); - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); return readPreviousNameInternal(accounts, account); } finally { restoreCallingIdentity(identityToken); @@ -632,9 +634,10 @@ public class AccountManagerService account.type); throw new SecurityException(msg); } - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); return readUserDataInternal(accounts, account, key); } finally { restoreCallingIdentity(identityToken); @@ -709,11 +712,12 @@ public class AccountManagerService * a limited user. */ - UserAccounts accounts = getUserAccountsForCaller(); // fails if the account already exists int uid = getCallingUid(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); return addAccountInternal(accounts, account, password, extras, false, uid); } finally { restoreCallingIdentity(identityToken); @@ -801,6 +805,13 @@ public class AccountManagerService if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) { return false; } + int user = UserHandle.getCallingUserId(); + long identityToken = clearCallingIdentity(); + try { + UserAccounts accounts = getUserAccounts(user); + } finally { + restoreCallingIdentity(identityToken); + } return updateLastAuthenticatedTime(account); } @@ -975,9 +986,10 @@ public class AccountManagerService if (account == null) throw new IllegalArgumentException("account is null"); if (features == null) throw new IllegalArgumentException("features is null"); checkReadAccountsPermitted(callingUid, account.type); - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); new TestFeaturesSession(accounts, response, account, features).bind(); } finally { restoreCallingIdentity(identityToken); @@ -1057,9 +1069,10 @@ public class AccountManagerService accountToRename.type); throw new SecurityException(msg); } - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); Account resultingAccount = renameAccountInternal(accounts, accountToRename, newName); Bundle result = new Bundle(); result.putString(AccountManager.KEY_ACCOUNT_NAME, resultingAccount.name); @@ -1206,7 +1219,6 @@ public class AccountManagerService throw new SecurityException(msg); } - UserAccounts accounts = getUserAccounts(userId); if (!canUserModifyAccounts(userId)) { try { response.onError(AccountManager.ERROR_CODE_USER_RESTRICTED, @@ -1227,6 +1239,7 @@ public class AccountManagerService UserHandle user = new UserHandle(userId); long identityToken = clearCallingIdentity(); + UserAccounts accounts = getUserAccounts(userId); cancelNotification(getSigninRequiredNotificationId(accounts, account), user); synchronized(accounts.credentialsPermissionNotificationIds) { for (Pair<Pair<Account, String>, Integer> pair: @@ -1381,9 +1394,10 @@ public class AccountManagerService } if (accountType == null) throw new IllegalArgumentException("accountType is null"); if (authToken == null) throw new IllegalArgumentException("authToken is null"); - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); synchronized (accounts.cacheLock) { final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); db.beginTransaction(); @@ -1517,9 +1531,10 @@ public class AccountManagerService account.type); throw new SecurityException(msg); } - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); return readAuthTokenInternal(accounts, account, authTokenType); } finally { restoreCallingIdentity(identityToken); @@ -1544,9 +1559,10 @@ public class AccountManagerService account.type); throw new SecurityException(msg); } - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); saveAuthTokenToDatabase(accounts, account, authTokenType, authToken); } finally { restoreCallingIdentity(identityToken); @@ -1569,9 +1585,10 @@ public class AccountManagerService account.type); throw new SecurityException(msg); } - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); setPasswordInternal(accounts, account, password, callingUid); } finally { restoreCallingIdentity(identityToken); @@ -1632,9 +1649,10 @@ public class AccountManagerService account.type); throw new SecurityException(msg); } - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); setPasswordInternal(accounts, account, null, callingUid); } finally { restoreCallingIdentity(identityToken); @@ -1659,9 +1677,10 @@ public class AccountManagerService account.type); throw new SecurityException(msg); } - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); setUserdataInternal(accounts, account, key, value); } finally { restoreCallingIdentity(identityToken); @@ -1734,9 +1753,10 @@ public class AccountManagerService if (callingUid != Process.SYSTEM_UID) { throw new SecurityException("can only call from system"); } - UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid)); + int userId = UserHandle.getUserId(callingUid); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); new Session(accounts, response, accountType, false /* expectActivityLaunch */, false /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */) { @@ -1803,11 +1823,17 @@ public class AccountManagerService Slog.w(TAG, "Failed to report error back to the client." + e); return; } - - final UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); + long ident = Binder.clearCallingIdentity(); + final UserAccounts accounts; final RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo; - authenticatorInfo = mAuthenticatorCache.getServiceInfo( - AuthenticatorDescription.newKey(account.type), accounts.userId); + try { + accounts = getUserAccounts(userId); + authenticatorInfo = mAuthenticatorCache.getServiceInfo( + AuthenticatorDescription.newKey(account.type), accounts.userId); + } finally { + Binder.restoreCallingIdentity(ident); + } final boolean customTokens = authenticatorInfo != null && authenticatorInfo.type.customTokens; @@ -1820,7 +1846,7 @@ public class AccountManagerService // Get the calling package. We will use it for the purpose of caching. final String callerPkg = loginOptions.getString(AccountManager.KEY_ANDROID_PACKAGE_NAME); List<String> callerOwnedPackageNames; - long ident = Binder.clearCallingIdentity(); + ident = Binder.clearCallingIdentity(); try { callerOwnedPackageNames = Arrays.asList(mPackageManager.getPackagesForUid(callerUid)); } finally { @@ -2108,17 +2134,18 @@ public class AccountManagerService return; } - UserAccounts accounts = getUserAccountsForCaller(); final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn; options.putInt(AccountManager.KEY_CALLER_UID, uid); options.putInt(AccountManager.KEY_CALLER_PID, pid); - logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_ADD, TABLE_ACCOUNTS); - + int usrId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(usrId); + logRecordWithUid( + accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_ADD, TABLE_ACCOUNTS, uid); new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */, true /* updateLastAuthenticationTime */) { @@ -2190,17 +2217,17 @@ public class AccountManagerService return; } - UserAccounts accounts = getUserAccounts(userId); final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn; options.putInt(AccountManager.KEY_CALLER_UID, uid); options.putInt(AccountManager.KEY_CALLER_PID, pid); - logRecord(accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_ADD, TABLE_ACCOUNTS); - long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); + logRecordWithUid( + accounts, DebugDbHelper.ACTION_CALLED_ACCOUNT_ADD, TABLE_ACCOUNTS, userId); new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */, true /* updateLastAuthenticationTime */) { @@ -2262,9 +2289,9 @@ public class AccountManagerService } if (response == null) throw new IllegalArgumentException("response is null"); if (account == null) throw new IllegalArgumentException("account is null"); - UserAccounts accounts = getUserAccounts(userId); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); new Session(accounts, response, account.type, expectActivityLaunch, true /* stripAuthTokenFromResult */, account.name, true /* authDetailsRequired */, true /* updateLastAuthenticatedTime */) { @@ -2298,9 +2325,10 @@ public class AccountManagerService if (response == null) throw new IllegalArgumentException("response is null"); if (account == null) throw new IllegalArgumentException("account is null"); if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null"); - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); new Session(accounts, response, account.type, expectActivityLaunch, true /* stripAuthTokenFromResult */, account.name, false /* authDetailsRequired */, true /* updateLastCredentialTime */) { @@ -2342,9 +2370,10 @@ public class AccountManagerService accountType); throw new SecurityException(msg); } - UserAccounts accounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */, null /* accountName */, false /* authDetailsRequired */) { @@ -2468,13 +2497,13 @@ public class AccountManagerService * @hide */ public Account[] getAccounts(int userId) { - UserAccounts accounts = getUserAccounts(userId); int callingUid = Binder.getCallingUid(); if (!isReadAccountsPermitted(callingUid, null)) { return new Account[0]; } long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); synchronized (accounts.cacheLock) { return getAccountsFromCacheLocked(accounts, null, callingUid, null); } @@ -2720,9 +2749,10 @@ public class AccountManagerService } return; } - UserAccounts userAccounts = getUserAccountsForCaller(); + int userId = UserHandle.getCallingUserId(); long identityToken = clearCallingIdentity(); try { + UserAccounts userAccounts = getUserAccounts(userId); if (features == null || features.length == 0) { Account[] accounts; synchronized (userAccounts.cacheLock) { @@ -3227,6 +3257,11 @@ public class AccountManagerService logRecord(db, action, tableName, -1, accounts); } + private void logRecordWithUid(UserAccounts accounts, String action, String tableName, int uid) { + SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); + logRecord(db, action, tableName, -1, accounts, uid); + } + /* * This function receives an opened writable database. */ @@ -3764,7 +3799,8 @@ public class AccountManagerService * access accounts of the specified account. */ boolean isPermitted = - isPermitted(callingUid, Manifest.permission.GET_ACCOUNTS); + isPermitted(callingUid, Manifest.permission.GET_ACCOUNTS, + Manifest.permission.GET_ACCOUNTS_PRIVILEGED); boolean isAccountManagedByCaller = isAccountManagedByCaller(accountType, callingUid); Log.w(TAG, String.format( "isReadAccountPermitted: isPermitted: %s, isAM: %s", diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1582037ad4b0..b8d32c3afb93 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -18,10 +18,7 @@ package com.android.server.am; 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.Manifest.permission.WRITE_MEDIA_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; @@ -68,6 +65,7 @@ import android.os.storage.IMountService; import android.os.storage.MountServiceInternal; import android.os.storage.StorageManager; import android.service.voice.IVoiceInteractionSession; +import android.service.voice.VoiceInteractionSession; import android.util.ArrayMap; import android.util.ArraySet; import android.util.DebugUtils; @@ -76,6 +74,7 @@ import android.view.Display; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; +import com.android.internal.app.AssistUtils; import com.android.internal.app.DumpHeapActivity; import com.android.internal.app.IAppOpsService; import com.android.internal.app.IVoiceInteractor; @@ -1356,6 +1355,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int DISPATCH_UIDS_CHANGED_MSG = 54; static final int REPORT_TIME_TRACKER_MSG = 55; static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56; + static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -2020,6 +2020,17 @@ public final class ActivityManagerService extends ActivityManagerNative case REPORT_USER_SWITCH_COMPLETE_MSG: { dispatchUserSwitchComplete(msg.arg1); } break; + case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: { + IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj; + try { + connection.shutdown(); + } catch (RemoteException e) { + Slog.w(TAG, "Error shutting down UiAutomationConnection"); + } + // Only a UiAutomation can set this flag and now that + // it is finished we make sure it is reset to its default. + mUserIsMonkey = false; + } break; } } }; @@ -3516,8 +3527,8 @@ public final class ActivityManagerService extends ActivityManagerNative intent.setComponent(new ComponentName( ri.activityInfo.packageName, ri.activityInfo.name)); mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, - null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, - null); + null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false, + null, null, null); } } } @@ -3641,13 +3652,13 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public boolean setProcessMemoryTrimLevel(String process, int userId, int level) { synchronized (this) { - final ProcessRecord app = getProcessRecordLocked(process, userId, true); + final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel"); if (app == null) { return false; } if (app.trimMemoryLevel < level && app.thread != null && (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN || - app.trimMemoryLevel >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)) { + app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) { try { app.thread.scheduleTrimMemory(level); app.trimMemoryLevel = level; @@ -3803,13 +3814,14 @@ public final class ActivityManagerService extends ActivityManagerNative // TODO: Switch to user app stacks here. return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, - profilerInfo, null, null, options, userId, null, null); + profilerInfo, null, null, options, false, userId, null, null); } @Override public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, - int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { + int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity, + int userId) { // This is very dangerous -- it allows you to perform a start activity (including // permission grants) as any app that may launch one of your own activities. So @@ -3843,6 +3855,16 @@ public final class ActivityManagerService extends ActivityManagerNative + sourceRecord.launchedFromUid); } } + if (ignoreTargetSecurity) { + if (intent.getComponent() == null) { + throw new SecurityException( + "Component must be specified with ignoreTargetSecurity"); + } + if (intent.getSelector() != null) { + throw new SecurityException( + "Selector not allowed with ignoreTargetSecurity"); + } + } targetUid = sourceRecord.launchedFromUid; targetPackage = sourceRecord.launchedFromPackage; } @@ -3855,7 +3877,7 @@ public final class ActivityManagerService extends ActivityManagerNative try { int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, - null, null, options, userId, null, null); + null, null, options, ignoreTargetSecurity, userId, null, null); return ret; } catch (SecurityException e) { // XXX need to figure out how to propagate to original app. @@ -3884,7 +3906,7 @@ public final class ActivityManagerService extends ActivityManagerNative // TODO: Switch to user app stacks here. mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, - options, userId, null, null); + options, false, userId, null, null); return res; } @@ -3898,7 +3920,7 @@ public final class ActivityManagerService extends ActivityManagerNative // TODO: Switch to user app stacks here. int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, - null, null, config, options, userId, null, null); + null, null, config, options, false, userId, null, null); return ret; } @@ -3956,7 +3978,7 @@ public final class ActivityManagerService extends ActivityManagerNative // TODO: Switch to user app stacks here. return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, - null, options, userId, null, null); + null, options, false, userId, null, null); } @Override @@ -4067,7 +4089,7 @@ public final class ActivityManagerService extends ActivityManagerNative int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, - -1, r.launchedFromUid, 0, options, false, null, null, null); + -1, r.launchedFromUid, 0, options, false, false, null, null, null); Binder.restoreCallingIdentity(origId); r.finishing = wasFinishing; @@ -4125,7 +4147,7 @@ public final class ActivityManagerService extends ActivityManagerNative // TODO: Switch to user app stacks here. int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, - null, null, null, options, userId, container, inTask); + null, null, null, options, false, userId, container, inTask); return ret; } @@ -5818,7 +5840,10 @@ public final class ActivityManagerService extends ActivityManagerNative // We shouldn't already have a process under this name, but just in case we // need to clean up whatever may be there now. ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid); - if (old != null) { + if (old == proc && proc.persistent) { + // We are re-adding a persistent process. Whatevs! Just leave it there. + Slog.w(TAG, "Re-adding persistent process " + proc); + } else if (old != null) { Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc); } UidRecord uidRec = mActiveUids.get(proc.uid); @@ -6527,6 +6552,17 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override + public boolean isRootVoiceInteraction(IBinder token) { + synchronized(this) { + ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null) { + return false; + } + return r.rootVoiceInteraction; + } + } + + @Override public IIntentSender getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, @@ -9129,9 +9165,10 @@ public final class ActivityManagerService extends ActivityManagerNative private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { List<ProviderInfo> providers = null; try { - providers = AppGlobals.getPackageManager(). + ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager(). queryContentProviders(app.processName, app.uid, STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); + providers = slice != null ? slice.getList() : null; } catch (RemoteException ex) { } if (DEBUG_MU) Slog.v(TAG_MU, @@ -10678,7 +10715,7 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public Bundle getAssistContextExtras(int requestType) { PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null, - UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT); + null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT); if (pae == null) { return null; } @@ -10699,7 +10736,7 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public boolean isScreenCaptureAllowedOnCurrentActivity() { + public boolean isAssistDataAllowedOnCurrentActivity() { int userId = mCurrentUserId; synchronized (this) { ActivityRecord activity = getFocusedStack().topActivity(); @@ -10714,13 +10751,41 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public void requestAssistContextExtras(int requestType, IResultReceiver receiver) { - enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(), - null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT); + public boolean showAssistFromActivity(IBinder token, Bundle args) { + long ident = Binder.clearCallingIdentity(); + try { + synchronized (this) { + ActivityRecord caller = ActivityRecord.forTokenLocked(token); + ActivityRecord top = getFocusedStack().topActivity(); + if (top != caller) { + Slog.w(TAG, "showAssistFromActivity failed: caller " + caller + + " is not current top " + top); + return false; + } + if (!top.nowVisible) { + Slog.w(TAG, "showAssistFromActivity failed: caller " + caller + + " is not visible"); + return false; + } + } + AssistUtils utils = new AssistUtils(mContext); + return utils.showSessionForActiveService(args, + VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override + public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver, + IBinder activityToken) { + return enqueueAssistContext(requestType, null, null, receiver, activityToken, + UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null; } private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, - IResultReceiver receiver, int userHandle, Bundle args, long timeout) { + IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args, + long timeout) { enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, "enqueueAssistContext()"); synchronized (this) { @@ -10733,9 +10798,13 @@ public final class ActivityManagerService extends ActivityManagerNative Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); return null; } - if (activity.app.pid == Binder.getCallingPid()) { - Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); - return null; + if (activityToken != null) { + ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken); + if (activity != caller) { + Slog.w(TAG, "enqueueAssistContext failed: caller " + caller + + " is not current top " + activity); + return null; + } } PendingAssistExtras pae; Bundle extras = new Bundle(); @@ -10846,7 +10915,7 @@ public final class ActivityManagerService extends ActivityManagerNative public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle, Bundle args) { - return enqueueAssistContext(requestType, intent, hint, null, userHandle, args, + return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null; } @@ -17060,16 +17129,11 @@ public final class ActivityManagerService extends ActivityManagerNative } catch (RemoteException e) { } } - if (app.instrumentationUiAutomationConnection != null) { - try { - app.instrumentationUiAutomationConnection.shutdown(); - } catch (RemoteException re) { - /* ignore */ - } - // Only a UiAutomation can set this flag and now that - // it is finished we make sure it is reset to its default. - mUserIsMonkey = false; - } + + // Can't call out of the system process with a lock held, so post a message. + mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG, + app.instrumentationUiAutomationConnection).sendToTarget(); + app.instrumentationWatcher = null; app.instrumentationUiAutomationConnection = null; app.instrumentationClass = null; @@ -17149,8 +17213,7 @@ public final class ActivityManagerService extends ActivityManagerNative public void updatePersistentConfiguration(Configuration values) { enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, "updateConfiguration()"); - enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, - "updateConfiguration()"); + enforceWriteSettingsPermission("updateConfiguration()"); if (values == null) { throw new NullPointerException("Configuration must not be null"); } @@ -17162,6 +17225,25 @@ public final class ActivityManagerService extends ActivityManagerNative } } + private void enforceWriteSettingsPermission(String func) { + int uid = Binder.getCallingUid(); + if (uid == Process.ROOT_UID) { + return; + } + + if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid, + Settings.getPackageNameForUid(mContext, uid), false)) { + return; + } + + String msg = "Permission Denial: " + func + " from pid=" + + Binder.getCallingPid() + + ", uid=" + uid + + " requires " + android.Manifest.permission.WRITE_SETTINGS; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } + public void updateConfiguration(Configuration values) { enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, "updateConfiguration()"); @@ -20529,7 +20611,7 @@ public final class ActivityManagerService extends ActivityManagerNative } return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, resolvedType, null, null, null, null, 0, 0, null, null, - null, options, callingUser, null, tr); + null, options, false, callingUser, null, tr); } @Override diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index d16eab6850a9..3de200954b15 100755 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -107,6 +107,7 @@ final class ActivityRecord { boolean fullscreen; // covers the full screen? final boolean noDisplay; // activity is not displayed? final boolean componentSpecified; // did caller specifiy an explicit component? + final boolean rootVoiceInteraction; // was this the root activity of a voice interaction? static final int APPLICATION_ACTIVITY_TYPE = 0; static final int HOME_ACTIVITY_TYPE = 1; @@ -207,6 +208,9 @@ final class ActivityRecord { pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded); pw.print(" componentSpecified="); pw.print(componentSpecified); pw.print(" mActivityType="); pw.println(mActivityType); + if (rootVoiceInteraction) { + pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction); + } pw.print(prefix); pw.print("compat="); pw.print(compat); pw.print(" labelRes=0x"); pw.print(Integer.toHexString(labelRes)); pw.print(" icon=0x"); pw.print(Integer.toHexString(icon)); @@ -432,7 +436,8 @@ final class ActivityRecord { int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType, ActivityInfo aInfo, Configuration _configuration, ActivityRecord _resultTo, String _resultWho, int _reqCode, - boolean _componentSpecified, ActivityStackSupervisor supervisor, + boolean _componentSpecified, boolean _rootVoiceInteraction, + ActivityStackSupervisor supervisor, ActivityContainer container, Bundle options) { service = _service; appToken = new Token(this, service); @@ -444,6 +449,7 @@ final class ActivityRecord { shortComponentName = _intent.getComponent().flattenToShortString(); resolvedType = _resolvedType; componentSpecified = _componentSpecified; + rootVoiceInteraction = _rootVoiceInteraction; configuration = _configuration; stackConfigOverride = (container != null) ? container.mStack.mOverrideConfig : Configuration.EMPTY; @@ -530,13 +536,13 @@ final class ActivityRecord { AttributeCache.Entry ent = AttributeCache.instance().get(packageName, realTheme, com.android.internal.R.styleable.Window, userId); - final boolean translucent = ent.array.getBoolean( + final boolean translucent = ent != null && (ent.array.getBoolean( com.android.internal.R.styleable.Window_windowIsTranslucent, false) || (!ent.array.hasValue( com.android.internal.R.styleable.Window_windowIsTranslucent) && ent.array.getBoolean( com.android.internal.R.styleable.Window_windowSwipeToDismiss, - false)); + false))); fullscreen = ent != null && !ent.array.getBoolean( com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent; @@ -1257,7 +1263,7 @@ final class ActivityRecord { } final ActivityRecord r = new ActivityRecord(service, /*caller*/null, launchedFromUid, launchedFromPackage, intent, resolvedType, aInfo, service.getConfiguration(), - null, null, 0, componentSpecified, stackSupervisor, null, null); + null, null, 0, componentSpecified, false, stackSupervisor, null, null); r.persistentState = persistentState; r.taskDescription = taskDescription; diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 470bbb0e29e3..a75cc4872dfa 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -617,12 +617,9 @@ final class ActivityStack { for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { ActivityRecord r = activities.get(activityNdx); if (notCurrentUserTask && (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) { - return null; + continue; } if (!r.finishing && r.intent.getComponent().equals(cls) && r.userId == userId) { - //Slog.i(TAG, "Found matching class!"); - //dump(); - //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); return r; } } @@ -3117,7 +3114,7 @@ final class ActivityStack { int res = mStackSupervisor.startActivityLocked(srec.app.thread, destIntent, null, aInfo, null, null, parent.appToken, null, 0, -1, parent.launchedFromUid, parent.launchedFromPackage, - -1, parent.launchedFromUid, 0, null, true, null, null, null); + -1, parent.launchedFromUid, 0, null, false, true, null, null, null); foundParentInTask = res == ActivityManager.START_SUCCESS; } catch (RemoteException e) { foundParentInTask = false; diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index c12aff6b626d..71fd49b71c98 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -911,7 +911,8 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 */, + 0 /* startFlags */, null /* options */, false /* ignoreTargetSecurity */, + false /* componentSpecified */, null /* outActivity */, null /* container */, null /* inTask */); if (inResumeTopActivity) { // If we are in resume section already, home activity will be initialized, but not @@ -926,7 +927,8 @@ public final class ActivityStackSupervisor implements DisplayListener { IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration config, - Bundle options, int userId, IActivityContainer iContainer, TaskRecord inTask) { + Bundle options, boolean ignoreTargetSecurity, int userId, + IActivityContainer iContainer, TaskRecord inTask) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); @@ -1043,7 +1045,7 @@ public final class ActivityStackSupervisor implements DisplayListener { int res = startActivityLocked(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, - realCallingPid, realCallingUid, startFlags, options, + realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, null, container, inTask); Binder.restoreCallingIdentity(origId); @@ -1159,7 +1161,7 @@ public final class ActivityStackSupervisor implements DisplayListener { int res = startActivityLocked(caller, intent, resolvedTypes[i], aInfo, null, null, resultTo, null, -1, callingPid, callingUid, callingPackage, callingPid, callingUid, - 0, theseOptions, componentSpecified, outActivity, null, null); + 0, theseOptions, false, componentSpecified, outActivity, null, null); if (res < 0) { return res; } @@ -1400,8 +1402,8 @@ public final class ActivityStackSupervisor implements DisplayListener { IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, Bundle options, - boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container, - TaskRecord inTask) { + boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, + ActivityContainer container, TaskRecord inTask) { int err = ActivityManager.START_SUCCESS; ProcessRecord callerApp = null; @@ -1504,6 +1506,7 @@ public final class ActivityStackSupervisor implements DisplayListener { if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) { try { + intent.addCategory(Intent.CATEGORY_VOICE); if (!AppGlobals.getPackageManager().activitySupportsIntent( intent.getComponent(), intent, resolvedType)) { err = ActivityManager.START_NOT_VOICE_COMPATIBLE; @@ -1546,7 +1549,7 @@ public final class ActivityStackSupervisor implements DisplayListener { if (startAnyPerm != PERMISSION_GRANTED) { final int componentRestriction = getComponentRestrictionForCallingPackage( - aInfo, callingPackage, callingPid, callingUid); + aInfo, callingPackage, callingPid, callingUid, ignoreTargetSecurity); final int actionRestriction = getActionRestrictionForCallingPackage( intent.getAction(), callingPackage, callingPid, callingUid); @@ -1624,7 +1627,7 @@ public final class ActivityStackSupervisor implements DisplayListener { ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, - requestCode, componentSpecified, this, container, options); + requestCode, componentSpecified, voiceSession != null, this, container, options); if (outActivity != null) { outActivity[0] = r; } @@ -1675,13 +1678,13 @@ public final class ActivityStackSupervisor implements DisplayListener { } private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, - String callingPackage, int callingPid, int callingUid) { + String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) { if (activityInfo.permission == null) { return ACTIVITY_RESTRICTION_NONE; } - if (mService.checkComponentPermission(activityInfo.permission, callingPid, callingUid, - activityInfo.applicationInfo.uid, activityInfo.exported) + if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission, + callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported) == PackageManager.PERMISSION_DENIED) { return ACTIVITY_RESTRICTION_PERMISSION; } @@ -1693,7 +1696,9 @@ public final class ActivityStackSupervisor implements DisplayListener { if (mService.mAppOpsService.noteOperation(opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) { - return ACTIVITY_RESTRICTION_APPOP; + if (!ignoreTargetSecurity) { + return ACTIVITY_RESTRICTION_APPOP; + } } return ACTIVITY_RESTRICTION_NONE; @@ -3201,10 +3206,10 @@ public final class ActivityStackSupervisor implements DisplayListener { void handleAppCrashLocked(ProcessRecord app) { for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; - final int numStacks = stacks.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - final ActivityStack stack = stacks.get(stackNdx); - stack.handleAppCrashLocked(app); + int stackNdx = stacks.size() - 1; + while (stackNdx >= 0) { + stacks.get(stackNdx).handleAppCrashLocked(app); + stackNdx--; } } } @@ -3717,19 +3722,19 @@ public final class ActivityStackSupervisor implements DisplayListener { @Override public void onDisplayAdded(int displayId) { - Slog.v(TAG, "Display added displayId=" + displayId); + if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId); mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_ADDED, displayId, 0)); } @Override public void onDisplayRemoved(int displayId) { - Slog.v(TAG, "Display removed displayId=" + displayId); + if (DEBUG_STACK) Slog.v(TAG, "Display removed displayId=" + displayId); mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_REMOVED, displayId, 0)); } @Override public void onDisplayChanged(int displayId) { - Slog.v(TAG, "Display changed displayId=" + displayId); + if (DEBUG_STACK) Slog.v(TAG, "Display changed displayId=" + displayId); mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0)); } @@ -4296,7 +4301,7 @@ public final class ActivityStackSupervisor implements DisplayListener { intent.addFlags(FORCE_NEW_TASK_FLAGS); return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null, - 0, 0, null, null, null, null, userId, this, null); + 0, 0, null, null, null, null, false, userId, this, null); } @Override diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 4b0b924e2ddb..d0f68f039aa1 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -58,6 +58,11 @@ import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.StandardCharsets; import java.util.List; /** @@ -854,26 +859,35 @@ public final class BatteryStatsService extends IBatteryStats.Stub public boolean isOnBattery() { return mStats.isOnBattery(); } - - public void setBatteryState(int status, int health, int plugType, int level, - int temp, int volt) { - enforceCallingPermission(); - synchronized (mStats) { - final boolean onBattery = plugType == BatteryStatsImpl.BATTERY_PLUGGED_NONE; - if (mStats.isOnBattery() == onBattery) { - // The battery state has not changed, so we don't need to sync external - // stats immediately. - mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt); - return; - } - } - // 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", UPDATE_ALL); - synchronized (mStats) { - mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt); - } + @Override + public void setBatteryState(final int status, final int health, final int plugType, + final int level, final int temp, final int volt) { + enforceCallingPermission(); + + // BatteryService calls us here and we may update external state. It would be wrong + // to block such a low level service like BatteryService on external stats like WiFi. + mHandler.post(new Runnable() { + @Override + public void run() { + synchronized (mStats) { + final boolean onBattery = plugType == BatteryStatsImpl.BATTERY_PLUGGED_NONE; + if (mStats.isOnBattery() == onBattery) { + // The battery state has not changed, so we don't need to sync external + // stats immediately. + mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt); + return; + } + } + + // 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", UPDATE_ALL); + synchronized (mStats) { + mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt); + } + } + }); } public long getAwakeTimeBattery() { @@ -897,7 +911,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub } final class WakeupReasonThread extends Thread { - final String[] mReason = new String[1]; + private static final int MAX_REASON_SIZE = 512; + private CharsetDecoder mDecoder; + private ByteBuffer mUtf8Buffer; + private CharBuffer mUtf16Buffer; WakeupReasonThread() { super("BatteryStats_wakeupReason"); @@ -906,25 +923,53 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void run() { Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); + mDecoder = StandardCharsets.UTF_8 + .newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE) + .replaceWith("?"); + + mUtf8Buffer = ByteBuffer.allocateDirect(MAX_REASON_SIZE); + mUtf16Buffer = CharBuffer.allocate(MAX_REASON_SIZE); + try { - int num; - while ((num = nativeWaitWakeup(mReason)) >= 0) { + String reason; + while ((reason = waitWakeup()) != null) { synchronized (mStats) { - // num will be either 0 or 1. - if (num > 0) { - mStats.noteWakeupReasonLocked(mReason[0]); - } else { - mStats.noteWakeupReasonLocked("unknown"); - } + mStats.noteWakeupReasonLocked(reason); } } } catch (RuntimeException e) { Slog.e(TAG, "Failure reading wakeup reasons", e); } } + + private String waitWakeup() { + mUtf8Buffer.clear(); + mUtf16Buffer.clear(); + mDecoder.reset(); + + int bytesWritten = nativeWaitWakeup(mUtf8Buffer); + if (bytesWritten < 0) { + return null; + } else if (bytesWritten == 0) { + return "unknown"; + } + + // Set the buffer's limit to the number of bytes written. + mUtf8Buffer.limit(bytesWritten); + + // Decode the buffer from UTF-8 to UTF-16. + // Unmappable characters will be replaced. + mDecoder.decode(mUtf8Buffer, mUtf16Buffer, true); + mUtf16Buffer.flip(); + + // Create a String from the UTF-16 buffer. + return mUtf16Buffer.toString(); + } } - private static native int nativeWaitWakeup(String[] outReason); + private static native int nativeWaitWakeup(ByteBuffer outBuffer); private void dumpHelp(PrintWriter pw) { pw.println("Battery stats (batterystats) dump options:"); @@ -1216,9 +1261,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub Slog.v(TAG, "WiFi energy data was reset, new WiFi energy data is " + result); } + // There is some accuracy error in reports so allow 30 milliseconds of error. + final long SAMPLE_ERROR_MILLIS = 30; final long totalTimeMs = result.mControllerIdleTimeMs + result.mControllerRxTimeMs + result.mControllerTxTimeMs; - if (totalTimeMs > timePeriodMs) { + if (totalTimeMs > timePeriodMs + SAMPLE_ERROR_MILLIS) { StringBuilder sb = new StringBuilder(); sb.append("Total time "); TimeUtils.formatDuration(totalTimeMs, sb); diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 91d97ef14646..a956c564f9ee 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -321,14 +321,12 @@ public final class BroadcastQueue { } public void skipCurrentReceiverLocked(ProcessRecord app) { - BroadcastRecord r = app.curReceiver; - if (r != null && r.queue == this) { - // The current broadcast is waiting for this app's receiver - // to be finished. Looks like that's not going to happen, so - // let the broadcast continue. - logBroadcastReceiverDiscardLocked(r); - finishReceiverLocked(r, r.resultCode, r.resultData, - r.resultExtras, r.resultAbort, false); + BroadcastRecord r = null; + if (mOrderedBroadcasts.size() > 0) { + BroadcastRecord br = mOrderedBroadcasts.get(0); + if (br.curApp == app) { + r = br; + } } if (r == null && mPendingBroadcast != null && mPendingBroadcast.curApp == app) { if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java index a7e6471d58a1..1fbfd9feff8e 100644 --- a/services/core/java/com/android/server/am/BroadcastRecord.java +++ b/services/core/java/com/android/server/am/BroadcastRecord.java @@ -240,8 +240,12 @@ final class BroadcastRecord extends Binder { } didSomething = true; receivers.remove(i); + if (i < nextReceiver) { + nextReceiver--; + } } } + nextReceiver = Math.min(nextReceiver, receivers.size()); return didSomething; } diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java index 9f11def4abdb..b2161149d663 100644 --- a/services/core/java/com/android/server/am/RecentTasks.java +++ b/services/core/java/com/android/server/am/RecentTasks.java @@ -435,7 +435,8 @@ class RecentTasks extends ArrayList<TaskRecord> { */ int trimForTaskLocked(TaskRecord task, boolean doTrim) { int recentsCount = size(); - final boolean document = task.intent != null && task.intent.isDocument(); + final Intent intent = task.intent; + final boolean document = intent != null && intent.isDocument(); int maxRecents = task.maxRecents - 1; for (int i = 0; i < recentsCount; i++) { final TaskRecord tr = get(i); @@ -446,13 +447,24 @@ class RecentTasks extends ArrayList<TaskRecord> { if (i > MAX_RECENT_BITMAPS) { tr.freeLastThumbnail(); } - if (task.realActivity == null || tr.realActivity == null || - !task.realActivity.equals(tr.realActivity)) { + final Intent trIntent = tr.intent; + final boolean sameAffinity = + task.affinity != null && task.affinity.equals(tr.affinity); + final boolean sameIntent = (intent != null && intent.filterEquals(trIntent)); + final boolean trIsDocument = trIntent != null && trIntent.isDocument(); + final boolean bothDocuments = document && trIsDocument; + if (!sameAffinity && !sameIntent && !bothDocuments) { continue; } - final boolean trIsDocument = tr.intent != null && tr.intent.isDocument(); - if (document && trIsDocument) { - // These are the same document activity (not necessarily the same doc). + + if (bothDocuments) { + // Do these documents belong to the same activity? + final boolean sameActivity = task.realActivity != null + && tr.realActivity != null + && task.realActivity.equals(tr.realActivity); + if (!sameActivity) { + continue; + } if (maxRecents > 0) { --maxRecents; continue; diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 78f9f181bae0..7e2ad2969843 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -1223,6 +1223,9 @@ final class TaskRecord { if (lastDescription != null) { pw.print(prefix); pw.print("lastDescription="); pw.println(lastDescription); } + if (stack != null) { + pw.print(prefix); pw.print("stackId="); pw.println(stack.mStackId); + } pw.print(prefix); pw.print("hasBeenVisible="); pw.print(hasBeenVisible); pw.print(" mResizeable="); pw.print(mResizeable); pw.print(" firstActiveTime="); pw.print(lastActiveTime); diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index eef3d6384377..a0ededfb7941 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -1260,7 +1260,11 @@ public class AudioService extends IAudioService.Stub { } for (int stream = 0; stream < mStreamStates.length; stream++) { if (streamTypeAlias == mStreamVolumeAlias[stream]) { - mStreamStates[stream].mute(state); + if (!(readCameraSoundForced() + && (mStreamStates[stream].getStreamType() + == AudioSystem.STREAM_SYSTEM_ENFORCED))) { + mStreamStates[stream].mute(state); + } } } } else if ((direction == AudioManager.ADJUST_RAISE) && @@ -4726,13 +4730,19 @@ public class AudioService extends IAudioService.Stub { Slog.i(TAG, "deviceSpec:" + deviceSpec + " is(already)Connected:" + isConnected); } if (connect && !isConnected) { - AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE, - address, deviceName); + final int res = AudioSystem.setDeviceConnectionState(device, + AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName); + if (res != AudioSystem.AUDIO_STATUS_OK) { + Slog.e(TAG, "not connecting device 0x" + Integer.toHexString(device) + + " due to command error " + res ); + return false; + } mConnectedDevices.put(deviceKey, new DeviceListSpec(device, deviceName, address)); return true; } else if (!connect && isConnected) { - AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_UNAVAILABLE, - address, deviceName); + AudioSystem.setDeviceConnectionState(device, + AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName); + // always remove even if disconnection failed mConnectedDevices.remove(deviceKey); return true; } @@ -4865,7 +4875,10 @@ public class AudioService extends IAudioService.Stub { boolean isUsb = ((device & ~AudioSystem.DEVICE_OUT_ALL_USB) == 0) || (((device & AudioSystem.DEVICE_BIT_IN) != 0) && ((device & ~AudioSystem.DEVICE_IN_ALL_USB) == 0)); - handleDeviceConnection(state == 1, device, address, deviceName); + if (!handleDeviceConnection(state == 1, device, address, deviceName)) { + // change of connection state failed, bailout + return; + } if (state != 0) { if ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) || (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) || @@ -5126,6 +5139,11 @@ public class AudioService extends IAudioService.Stub { if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) { continue; } + // Skip packages that have permission to interact across users + if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName) + == PackageManager.PERMISSION_GRANTED) { + continue; + } if (homeActivityName != null && pkg.packageName.equals(homeActivityName.getPackageName()) && pkg.applicationInfo.isSystemApp()) { diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 8a7943032b33..39333f638af6 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -30,6 +30,7 @@ import android.os.Messenger; import android.util.SparseArray; import com.android.internal.util.AsyncChannel; +import com.android.server.ConnectivityService; import com.android.server.connectivity.NetworkMonitor; import java.util.ArrayList; @@ -51,7 +52,7 @@ import java.util.Comparator; // ConnectivityService will tell netd to create the network and immediately transition to // state #3. // 3. registered, created, connected, unvalidated -// If this network can satsify the default NetworkRequest, then NetworkMonitor will +// If this network can satisfy the default NetworkRequest, then NetworkMonitor will // probe for Internet connectivity. // If this network cannot satisfy the default NetworkRequest, it will immediately be // transitioned to state #4. @@ -164,7 +165,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info, LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler, - NetworkMisc misc, NetworkRequest defaultRequest) { + NetworkMisc misc, NetworkRequest defaultRequest, ConnectivityService connService) { this.messenger = messenger; asyncChannel = ac; network = net; @@ -172,7 +173,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { linkProperties = lp; networkCapabilities = nc; currentScore = score; - networkMonitor = new NetworkMonitor(context, handler, this, defaultRequest); + networkMonitor = connService.createNetworkMonitor(context, handler, this, defaultRequest); networkMisc = misc; } diff --git a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java index 74ba404eb0ee..aca699152e02 100644 --- a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java +++ b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java @@ -20,6 +20,7 @@ import static android.system.OsConstants.*; import android.net.LinkProperties; import android.net.Network; +import android.net.NetworkUtils; import android.net.RouteInfo; import android.os.SystemClock; import android.system.ErrnoException; @@ -79,6 +80,10 @@ import libcore.io.IoUtils; public class NetworkDiagnostics { private static final String TAG = "NetworkDiagnostics"; + private static final InetAddress TEST_DNS4 = NetworkUtils.numericToInetAddress("8.8.8.8"); + private static final InetAddress TEST_DNS6 = NetworkUtils.numericToInetAddress( + "2001:4860:4860::8888"); + // For brevity elsewhere. private static final long now() { return SystemClock.elapsedRealtime(); @@ -156,6 +161,21 @@ public class NetworkDiagnostics { mStartTime = now(); mDeadlineTime = mStartTime + mTimeoutMs; + // Hardcode measurements to TEST_DNS4 and TEST_DNS6 in order to test off-link connectivity. + // We are free to modify mLinkProperties with impunity because ConnectivityService passes us + // a copy and not the original object. It's easier to do it this way because we don't need + // to check whether the LinkProperties already contains these DNS servers because + // LinkProperties#addDnsServer checks for duplicates. + if (mLinkProperties.isReachable(TEST_DNS4)) { + mLinkProperties.addDnsServer(TEST_DNS4); + } + // TODO: we could use mLinkProperties.isReachable(TEST_DNS6) here, because we won't set any + // DNS servers for which isReachable() is false, but since this is diagnostic code, be extra + // careful. + if (mLinkProperties.hasGlobalIPv6Address() || mLinkProperties.hasIPv6DefaultRoute()) { + mLinkProperties.addDnsServer(TEST_DNS6); + } + for (RouteInfo route : mLinkProperties.getRoutes()) { if (route.hasGateway()) { prepareIcmpMeasurement(route.getGateway()); diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index 26339395016b..5108564e916b 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -77,7 +77,7 @@ import java.util.Random; public class NetworkMonitor extends StateMachine { private static final boolean DBG = true; private static final String TAG = "NetworkMonitor"; - private static final String DEFAULT_SERVER = "connectivitycheck.android.com"; + private static final String DEFAULT_SERVER = "connectivitycheck.gstatic.com"; private static final int SOCKET_TIMEOUT_MS = 10000; public static final String ACTION_NETWORK_CONDITIONS_MEASURED = "android.net.conn.NETWORK_CONDITIONS_MEASURED"; @@ -349,7 +349,7 @@ public class NetworkMonitor extends StateMachine { // Being in the ValidatedState State indicates a Network is: // - Successfully validated, or // - Wanted "as is" by the user, or - // - Does not satsify the default NetworkRequest and so validation has been skipped. + // - Does not satisfy the default NetworkRequest and so validation has been skipped. private class ValidatedState extends State { @Override public void enter() { @@ -558,7 +558,7 @@ public class NetworkMonitor extends StateMachine { // Being in the LingeringState State indicates a Network's validated bit is true and it once // was the highest scoring Network satisfying a particular NetworkRequest, but since then - // another Network satsified the NetworkRequest with a higher score and hence this Network + // another Network satisfied the NetworkRequest with a higher score and hence this Network // is "lingered" for a fixed period of time before it is disconnected. This period of time // allows apps to wrap up communication and allows for seamless reactivation if the other // higher scoring Network happens to disconnect. @@ -633,7 +633,8 @@ public class NetworkMonitor extends StateMachine { * Do a URL fetch on a known server to see if we get the data we expect. * Returns HTTP response code. */ - private int isCaptivePortal() { + @VisibleForTesting + protected int isCaptivePortal() { if (!mIsCaptivePortalCheckEnabled) return 204; HttpURLConnection urlConnection = null; diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 658f6f858acc..c998c2c28aac 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -297,7 +297,6 @@ public class SyncManager { private final UserManager mUserManager; private static final long SYNC_ALARM_TIMEOUT_MIN = 30 * 1000; // 30 seconds - private static final long SYNC_ALARM_TIMEOUT_MAX = 2 * 60 * 60 * 1000; // two hours private List<UserInfo> getAllUsers() { return mUserManager.getUsers(); @@ -1478,9 +1477,9 @@ public class SyncManager { final long now = SystemClock.elapsedRealtime(); pw.print("now: "); pw.print(now); pw.println(" (" + formatTime(System.currentTimeMillis()) + ")"); - pw.print("offset: "); pw.print(DateUtils.formatElapsedTime(mSyncRandomOffsetMillis/1000)); + pw.print("offset: "); pw.print(DateUtils.formatElapsedTime(mSyncRandomOffsetMillis / 1000)); pw.println(" (HH:MM:SS)"); - pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now/1000)); + pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now / 1000)); pw.println(" (HH:MM:SS)"); pw.print("time spent syncing: "); pw.print(DateUtils.formatElapsedTime( @@ -1497,11 +1496,6 @@ public class SyncManager { pw.println("no alarm is scheduled (there had better not be any pending syncs)"); } - pw.print("notification info: "); - final StringBuilder sb = new StringBuilder(); - mSyncHandler.mSyncNotificationInfo.toString(sb); - pw.println(sb.toString()); - pw.println(); pw.println("Active Syncs: " + mActiveSyncContexts.size()); final PackageManager pm = mContext.getPackageManager(); @@ -1514,8 +1508,8 @@ public class SyncManager { pw.println(); } + final StringBuilder sb = new StringBuilder(); synchronized (mSyncQueue) { - sb.setLength(0); mSyncQueue.dump(sb); // Dump Pending Operations. getSyncStorageEngine().dumpPendingOperations(sb); @@ -2349,7 +2343,6 @@ public class SyncManager { } } finally { - manageSyncNotificationLocked(); manageSyncAlarmLocked(earliestFuturePollTime, nextPendingSyncTime); mSyncTimeTracker.update(); mSyncManagerWakeLock.release(); @@ -3169,67 +3162,6 @@ public class SyncManager { throw new IllegalStateException("we are not in an error state, " + syncResult); } - private void manageSyncNotificationLocked() { - boolean shouldCancel; - boolean shouldInstall; - - if (mActiveSyncContexts.isEmpty()) { - mSyncNotificationInfo.startTime = null; - - // we aren't syncing. if the notification is active then remember that we need - // to cancel it and then clear out the info - shouldCancel = mSyncNotificationInfo.isActive; - shouldInstall = false; - } else { - // we are syncing - final long now = SystemClock.elapsedRealtime(); - if (mSyncNotificationInfo.startTime == null) { - mSyncNotificationInfo.startTime = now; - } - - // there are three cases: - // - the notification is up: do nothing - // - the notification is not up but it isn't time yet: don't install - // - the notification is not up and it is time: need to install - - if (mSyncNotificationInfo.isActive) { - shouldInstall = shouldCancel = false; - } else { - // it isn't currently up, so there is nothing to cancel - shouldCancel = false; - - final boolean timeToShowNotification = - now > mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY; - if (timeToShowNotification) { - shouldInstall = true; - } else { - // show the notification immediately if this is a manual sync - shouldInstall = false; - for (ActiveSyncContext activeSyncContext : mActiveSyncContexts) { - final boolean manualSync = activeSyncContext.mSyncOperation.extras - .getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false); - if (manualSync) { - shouldInstall = true; - break; - } - } - } - } - } - - if (shouldCancel && !shouldInstall) { - mNeedSyncActiveNotification = false; - sendSyncStateIntent(); - mSyncNotificationInfo.isActive = false; - } - - if (shouldInstall) { - mNeedSyncActiveNotification = true; - sendSyncStateIntent(); - mSyncNotificationInfo.isActive = true; - } - } - private void manageSyncAlarmLocked(long nextPeriodicEventElapsedTime, long nextPendingEventElapsedTime) { // in each of these cases the sync loop will be kicked, which will cause this @@ -3238,13 +3170,6 @@ public class SyncManager { if (mStorageIsLow) return; if (mDeviceIsIdle) return; - // When the status bar notification should be raised - final long notificationTime = - (!mSyncHandler.mSyncNotificationInfo.isActive - && mSyncHandler.mSyncNotificationInfo.startTime != null) - ? mSyncHandler.mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY - : Long.MAX_VALUE; - // When we should consider canceling an active sync long earliestTimeoutTime = Long.MAX_VALUE; for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) { @@ -3260,24 +3185,14 @@ public class SyncManager { } if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "manageSyncAlarm: notificationTime is " + notificationTime); - } - - if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "manageSyncAlarm: earliestTimeoutTime is " + earliestTimeoutTime); - } - - if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "manageSyncAlarm: nextPeriodicEventElapsedTime is " + nextPeriodicEventElapsedTime); - } - if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "manageSyncAlarm: nextPendingEventElapsedTime is " + nextPendingEventElapsedTime); } - long alarmTime = Math.min(notificationTime, earliestTimeoutTime); - alarmTime = Math.min(alarmTime, nextPeriodicEventElapsedTime); + long alarmTime = Math.min(earliestTimeoutTime, nextPeriodicEventElapsedTime); alarmTime = Math.min(alarmTime, nextPendingEventElapsedTime); // Bound the alarm time. @@ -3288,24 +3203,16 @@ public class SyncManager { + alarmTime + ", setting to " + (now + SYNC_ALARM_TIMEOUT_MIN)); } alarmTime = now + SYNC_ALARM_TIMEOUT_MIN; - } else if (alarmTime > now + SYNC_ALARM_TIMEOUT_MAX) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "manageSyncAlarm: the alarmTime is too large, " - + alarmTime + ", setting to " + (now + SYNC_ALARM_TIMEOUT_MIN)); - } - alarmTime = now + SYNC_ALARM_TIMEOUT_MAX; } - // determine if we need to set or cancel the alarm + // Determine if we need to set or cancel the alarm boolean shouldSet = false; boolean shouldCancel = false; final boolean alarmIsActive = (mAlarmScheduleTime != null) && (now < mAlarmScheduleTime); - final boolean needAlarm = alarmTime != Long.MAX_VALUE; - if (needAlarm) { - // Need the alarm if - // - it's currently not set - // - if the alarm is set in the past. - if (!alarmIsActive || alarmTime < mAlarmScheduleTime) { + + if (alarmTime != Long.MAX_VALUE) { + // Need the alarm if it isn't set or has changed. + if (!alarmIsActive || alarmTime != mAlarmScheduleTime) { shouldSet = true; } } else { @@ -3329,14 +3236,6 @@ public class SyncManager { } } - private void sendSyncStateIntent() { - Intent syncStateIntent = new Intent(Intent.ACTION_SYNC_STATE_CHANGED); - syncStateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); - syncStateIntent.putExtra("active", mNeedSyncActiveNotification); - syncStateIntent.putExtra("failing", false); - mContext.sendBroadcastAsUser(syncStateIntent, UserHandle.OWNER); - } - private void installHandleTooManyDeletesNotification(Account account, String authority, long numDeletes, int userId) { if (mNotificationMgr == null) return; diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 8d2687ba9db9..452378ff1e45 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -106,6 +106,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private static final int BRIGHTNESS_RAMP_RATE_FAST = 200; private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40; + private static final int REPORTED_TO_POLICY_SCREEN_OFF = 0; + private static final int REPORTED_TO_POLICY_SCREEN_TURNING_ON = 1; + private static final int REPORTED_TO_POLICY_SCREEN_ON = 2; + private final Object mLock = new Object(); private final Context mContext; @@ -231,8 +235,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // 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; + // Screen state we reported to policy. Must be one of REPORTED_TO_POLICY_SCREEN_* fields. + private int mReportedScreenStateToPolicy; // Remembers whether certain kinds of brightness adjustments // were recently applied so that we can decide how to transition. @@ -699,6 +703,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call final boolean finished = ready && !mScreenBrightnessRampAnimator.isAnimating(); + // Notify policy about screen turned on. + if (ready && state != Display.STATE_OFF + && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) { + mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON; + mWindowManagerPolicy.screenTurnedOn(); + } + // Grab a wake lock if we have unfinished business. if (!finished && !mUnfinishedBusiness) { if (DEBUG) { @@ -776,12 +787,13 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // 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; + if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF + && !mScreenOffBecauseOfProximity) { + mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF; unblockScreenOn(); mWindowManagerPolicy.screenTurnedOff(); - } else if (!isOff && mReportedScreenOffToPolicy) { - mReportedScreenOffToPolicy = false; + } else if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) { + mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON; if (mPowerState.getColorFadeLevel() == 0.0f) { blockScreenOn(); } else { @@ -1095,7 +1107,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(" mAppliedLowPower=" + mAppliedLowPower); pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker); pw.println(" mPendingScreenOff=" + mPendingScreenOff); - pw.println(" mReportedScreenOffToPolicy=" + mReportedScreenOffToPolicy); + pw.println(" mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy)); pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" + mScreenBrightnessRampAnimator.isAnimating()); @@ -1132,6 +1144,19 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } } + private static String reportedToPolicyToString(int state) { + switch (state) { + case REPORTED_TO_POLICY_SCREEN_OFF: + return "REPORTED_TO_POLICY_SCREEN_OFF"; + case REPORTED_TO_POLICY_SCREEN_TURNING_ON: + return "REPORTED_TO_POLICY_SCREEN_TURNING_ON"; + case REPORTED_TO_POLICY_SCREEN_ON: + return "REPORTED_TO_POLICY_SCREEN_ON"; + default: + return Integer.toString(state); + } + } + private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) { try { final int n = brightness.length; diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index 81056757fb0a..206cc8a256d8 100644 --- a/services/core/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java @@ -65,7 +65,7 @@ final class DreamController { private final Intent mDreamingStoppedIntent = new Intent(Intent.ACTION_DREAMING_STOPPED) .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - private final Intent mCloseNotificationShadeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + private final Intent mCloseNotificationShadeIntent; private DreamRecord mCurrentDream; @@ -92,6 +92,8 @@ final class DreamController { mHandler = handler; mListener = listener; mIWindowManager = WindowManagerGlobal.getWindowManagerService(); + mCloseNotificationShadeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + mCloseNotificationShadeIntent.putExtra("reason", "dream"); } public void dump(PrintWriter pw) { diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index 8871e646d917..c705fbf93d97 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -74,7 +74,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe 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; @@ -124,20 +123,29 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe public void binderDied() { Slog.v(TAG, "fingerprintd died"); mDaemon = null; + dispatchError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); } public IFingerprintDaemon getFingerprintDaemon() { if (mDaemon == null) { mDaemon = IFingerprintDaemon.Stub.asInterface(ServiceManager.getService(FINGERPRINTD)); - if (mDaemon == null) { - Slog.w(TAG, "fingerprind service not available"); - } else { + if (mDaemon != null) { try { mDaemon.asBinder().linkToDeath(this, 0); - } catch (RemoteException e) { - Slog.w(TAG, "caught remote exception in linkToDeath: ", e); - mDaemon = null; // try again! + mDaemon.init(mDaemonCallback); + mHalDeviceId = mDaemon.openHal(); + if (mHalDeviceId != 0) { + updateActiveGroup(ActivityManager.getCurrentUser()); + } else { + Slog.w(TAG, "Failed to open Fingerprint HAL!"); + mDaemon = null; + } + } catch (RemoteException e) { + Slog.e(TAG, "Failed to open fingeprintd HAL", e); + mDaemon = null; // try again later! } + } else { + Slog.w(TAG, "fingerprint service not available"); } } return mDaemon; @@ -156,7 +164,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe protected void dispatchRemoved(long deviceId, int fingerId, int groupId) { final ClientMonitor client = mRemoveClient; if (fingerId != 0) { - ContentResolver res = mContext.getContentResolver(); removeTemplateForUser(mRemoveClient, fingerId); } if (client != null && client.sendRemoved(fingerId, groupId)) { @@ -577,12 +584,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe 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(), - "android.server.fingerprint:AUTH"); - } return result; } @@ -727,7 +728,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe mHandler.post(new Runnable() { @Override public void run() { - mIsKeyguard = KEYGUARD_PACKAGE.equals(opPackageName); startAuthentication(token, opId, groupId, receiver, flags, restricted); } }); @@ -821,15 +821,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe public void onStart() { publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper()); IFingerprintDaemon daemon = getFingerprintDaemon(); - if (daemon != null) { - try { - daemon.init(mDaemonCallback); - mHalDeviceId = daemon.openHal(); - updateActiveGroup(ActivityManager.getCurrentUser()); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to open fingeprintd HAL", e); - } - } if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId); listenForUserSwitches(); } diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 569a0fcf7204..f92f631a06d0 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -241,19 +241,10 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { flags &= ~AudioManager.FLAG_PLAY_SOUND; } if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) { - int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs); // Adjust the volume with a handler not to be blocked by other system service. - if (useSuggested) { - if (AudioSystem.isStreamActive(stream, 0)) { - postAdjustSuggestedStreamVolume(stream, direction, flags, packageName, uid); - } else { - flags |= previousFlagPlaySound; - postAdjustSuggestedStreamVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, direction, - flags, packageName, uid); - } - } else { - postAdjustStreamVolume(stream, direction, flags, packageName, uid); - } + int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs); + postAdjustLocalVolume(stream, direction, flags, packageName, uid, useSuggested, + previousFlagPlaySound); } else { if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) { // Nothing to do, the volume cannot be changed @@ -459,24 +450,25 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { return mPackageName + "/" + mTag; } - private void postAdjustSuggestedStreamVolume(final int streamType, final int direction, - final int flags, final String callingPackage, final int uid) { + private void postAdjustLocalVolume(final int stream, final int direction, final int flags, + final String packageName, final int uid, final boolean useSuggested, + final int previousFlagPlaySound) { mHandler.post(new Runnable() { @Override public void run() { - mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(streamType, direction, - flags, callingPackage, uid); - } - }); - } - - private void postAdjustStreamVolume(final int streamType, final int direction, final int flags, - final String callingPackage, final int uid) { - mHandler.post(new Runnable() { - @Override - public void run() { - mAudioManagerInternal.adjustStreamVolumeForUid(streamType, direction, flags, - callingPackage, uid); + if (useSuggested) { + if (AudioSystem.isStreamActive(stream, 0)) { + mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, direction, + flags, packageName, uid); + } else { + mAudioManagerInternal.adjustSuggestedStreamVolumeForUid( + AudioManager.USE_DEFAULT_STREAM_TYPE, direction, + flags | previousFlagPlaySound, packageName, uid); + } + } else { + mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags, + packageName, uid); + } } }); } @@ -1067,23 +1059,22 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { @Override public ParcelableVolumeInfo getVolumeAttributes() { + int volumeType; + AudioAttributes attributes; synchronized (mLock) { - int type; - int max; - int current; if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_REMOTE) { - type = mVolumeControlType; - max = mMaxVolume; - current = mOptimisticVolume != -1 ? mOptimisticVolume - : mCurrentVolume; - } else { - int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs); - type = VolumeProvider.VOLUME_CONTROL_ABSOLUTE; - max = mAudioManager.getStreamMaxVolume(stream); - current = mAudioManager.getStreamVolume(stream); + int current = mOptimisticVolume != -1 ? mOptimisticVolume : mCurrentVolume; + return new ParcelableVolumeInfo( + mVolumeType, mAudioAttrs, mVolumeControlType, mMaxVolume, current); } - return new ParcelableVolumeInfo(mVolumeType, mAudioAttrs, type, max, current); - } + volumeType = mVolumeType; + attributes = mAudioAttrs; + } + int stream = AudioAttributes.toLegacyStreamType(attributes); + int max = mAudioManager.getStreamMaxVolume(stream); + int current = mAudioManager.getStreamVolume(stream); + return new ParcelableVolumeInfo( + volumeType, attributes, VolumeProvider.VOLUME_CONTROL_ABSOLUTE, max, current); } @Override diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 80864610636e..7028fa6695f6 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -988,7 +988,7 @@ public class MediaSessionService extends SystemService implements Monitor { keyIntent.putExtra(EXTRA_WAKELOCK_ACQUIRED, WAKELOCK_RELEASE_ON_FINISHED); } - getContext().sendOrderedBroadcastAsUser(keyIntent, UserHandle.ALL, + getContext().sendOrderedBroadcastAsUser(keyIntent, UserHandle.CURRENT, null, mKeyEventDone, mHandler, Activity.RESULT_OK, null, null); } } diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java index a029b0e63971..3ea4f2c78a19 100644 --- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java +++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java @@ -127,9 +127,7 @@ public final class MediaProjectionManagerService extends SystemService IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() { @Override public void binderDied() { - synchronized (mLock) { - removeCallback(callback); - } + removeCallback(callback); } }; synchronized (mLock) { @@ -344,6 +342,7 @@ public final class MediaProjectionManagerService extends SystemService public final String packageName; public final UserHandle userHandle; + private IMediaProjectionCallback mCallback; private IBinder mToken; private IBinder.DeathRecipient mDeathEater; private int mType; @@ -406,7 +405,8 @@ public final class MediaProjectionManagerService extends SystemService throw new IllegalStateException( "Cannot start already started MediaProjection"); } - registerCallback(callback); + mCallback = callback; + registerCallback(mCallback); try { mToken = callback.asBinder(); mDeathEater = new IBinder.DeathRecipient() { @@ -435,8 +435,11 @@ public final class MediaProjectionManagerService extends SystemService + "pid=" + Binder.getCallingPid() + ")"); return; } - mToken.unlinkToDeath(mDeathEater, 0); stopProjectionLocked(this); + mToken.unlinkToDeath(mDeathEater, 0); + mToken = null; + unregisterCallback(mCallback); + mCallback = null; } } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 395aa275f412..46bda8ccfd89 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -1520,9 +1520,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } synchronized (mRulesLock) { - final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); - if (oldPolicy != policy) { - setUidPolicyUncheckedLocked(uid, policy, true); + final long token = Binder.clearCallingIdentity(); + try { + final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE); + if (oldPolicy != policy) { + setUidPolicyUncheckedLocked(uid, policy, true); + } + } finally { + Binder.restoreCallingIdentity(token); } } } @@ -1663,8 +1668,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { public NetworkPolicy[] getNetworkPolicies(String callingPackage) { mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); try { - mContext.enforceCallingPermission(READ_PRIVILEGED_PHONE_STATE, TAG); - // SKIP checking run-time OP_READ_PHONE_STATE since using PRIVILEGED + mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, TAG); + // SKIP checking run-time OP_READ_PHONE_STATE since caller or self has PRIVILEGED + // permission } catch (SecurityException e) { mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, TAG); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 7a6895f542e6..9426b76eba52 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1842,7 +1842,7 @@ public class NotificationManagerService extends SystemService { } pw.println(':'); int N; - final boolean zenOnly = filter != null && filter.zen; + final boolean zenOnly = filter.filtered && filter.zen; if (!zenOnly) { synchronized (mToastQueue) { @@ -1864,13 +1864,13 @@ public class NotificationManagerService extends SystemService { pw.println(" Notification List:"); for (int i=0; i<N; i++) { final NotificationRecord nr = mNotificationList.get(i); - if (filter != null && !filter.matches(nr.sbn)) continue; + if (filter.filtered && !filter.matches(nr.sbn)) continue; nr.dump(pw, " ", getContext(), filter.redact); } pw.println(" "); } - if (filter == null) { + if (!filter.filtered) { N = mLights.size(); if (N > 0) { pw.println(" Lights List:"); @@ -1911,7 +1911,7 @@ public class NotificationManagerService extends SystemService { mUsageStats.dump(pw, " ", filter); } - if (filter == null || zenOnly) { + if (!filter.filtered || zenOnly) { pw.println("\n Zen Mode:"); pw.print(" mInterruptionFilter="); pw.println(mInterruptionFilter); mZenModeHelper.dump(pw, " "); diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index 7fde68f55b76..3227ef857f5e 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -72,6 +72,7 @@ final class DefaultPermissionGrantPolicy { static { CONTACTS_PERMISSIONS.add(Manifest.permission.READ_CONTACTS); CONTACTS_PERMISSIONS.add(Manifest.permission.WRITE_CONTACTS); + CONTACTS_PERMISSIONS.add(Manifest.permission.GET_ACCOUNTS); } private static final Set<String> LOCATION_PERMISSIONS = new ArraySet<>(); @@ -117,11 +118,6 @@ final class DefaultPermissionGrantPolicy { 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 final PackageManagerService mService; private PackagesProvider mImePackagesProvider; @@ -129,6 +125,7 @@ final class DefaultPermissionGrantPolicy { private PackagesProvider mVoiceInteractionPackagesProvider; private PackagesProvider mSmsAppPackagesProvider; private PackagesProvider mDialerAppPackagesProvider; + private PackagesProvider mSimCallManagerPackagesProvider; private SyncAdapterPackagesProvider mSyncAdapterPackagesProvider; public DefaultPermissionGrantPolicy(PackageManagerService service) { @@ -155,6 +152,10 @@ final class DefaultPermissionGrantPolicy { mDialerAppPackagesProvider = provider; } + public void setSimCallManagerPackagesProviderLPw(PackagesProvider provider) { + mSimCallManagerPackagesProvider = provider; + } + public void setSyncAdapterPackagesProviderLPw(SyncAdapterPackagesProvider provider) { mSyncAdapterPackagesProvider = provider; } @@ -169,30 +170,23 @@ final class DefaultPermissionGrantPolicy { synchronized (mService.mPackages) { for (PackageParser.Package pkg : mService.mPackages.values()) { - if (!isSysComponentOrPersistentPlatformSignedPrivApp(pkg) - || !doesPackageSupportRuntimePermissions(pkg)) { + if (!isSysComponentOrPersistentPlatformSignedPrivAppLPr(pkg) + || !doesPackageSupportRuntimePermissions(pkg) + || pkg.requestedPermissions.isEmpty()) { continue; } + Set<String> permissions = new ArraySet<>(); 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 - | PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, userId); - if (DEBUG) { - Log.i(TAG, "Granted " + permission + " to system component " - + pkg.packageName); - } - } + permissions.add(permission); } } + if (!permissions.isEmpty()) { + grantRuntimePermissionsLPw(pkg, permissions, true, userId); + } } } } @@ -205,6 +199,7 @@ final class DefaultPermissionGrantPolicy { final PackagesProvider voiceInteractionPackagesProvider; final PackagesProvider smsAppPackagesProvider; final PackagesProvider dialerAppPackagesProvider; + final PackagesProvider simCallManagerPackagesProvider; final SyncAdapterPackagesProvider syncAdapterPackagesProvider; synchronized (mService.mPackages) { @@ -213,6 +208,7 @@ final class DefaultPermissionGrantPolicy { voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider; smsAppPackagesProvider = mSmsAppPackagesProvider; dialerAppPackagesProvider = mDialerAppPackagesProvider; + simCallManagerPackagesProvider = mSimCallManagerPackagesProvider; syncAdapterPackagesProvider = mSyncAdapterPackagesProvider; } @@ -226,6 +222,8 @@ final class DefaultPermissionGrantPolicy { ? smsAppPackagesProvider.getPackages(userId) : null; String[] dialerAppPackageNames = (dialerAppPackagesProvider != null) ? dialerAppPackagesProvider.getPackages(userId) : null; + String[] simCallManagerPackageNames = (simCallManagerPackagesProvider != null) + ? simCallManagerPackagesProvider.getPackages(userId) : null; String[] contactsSyncAdapterPackages = (syncAdapterPackagesProvider != null) ? syncAdapterPackagesProvider.getPackages(ContactsContract.AUTHORITY, userId) : null; String[] calendarSyncAdapterPackages = (syncAdapterPackagesProvider != null) ? @@ -317,6 +315,18 @@ final class DefaultPermissionGrantPolicy { } } + // Sim call manager + if (simCallManagerPackageNames != null) { + for (String simCallManagerPackageName : simCallManagerPackageNames) { + PackageParser.Package simCallManagerPackage = + getSystemPackageLPr(simCallManagerPackageName); + if (simCallManagerPackage != null) { + grantDefaultPermissionsToDefaultSimCallManagerLPr(simCallManagerPackage, + userId); + } + } + } + // SMS if (smsAppPackageNames == null) { Intent smsIntent = new Intent(Intent.ACTION_MAIN); @@ -352,7 +362,6 @@ final class DefaultPermissionGrantPolicy { && doesPackageSupportRuntimePermissions(calendarPackage)) { grantRuntimePermissionsLPw(calendarPackage, CALENDAR_PERMISSIONS, userId); grantRuntimePermissionsLPw(calendarPackage, CONTACTS_PERMISSIONS, userId); - grantRuntimePermissionsLPw(calendarPackage, ACCOUNTS_PERMISSIONS, userId); } // Calendar provider @@ -362,7 +371,6 @@ final class DefaultPermissionGrantPolicy { grantRuntimePermissionsLPw(calendarProviderPackage, CONTACTS_PERMISSIONS, userId); grantRuntimePermissionsLPw(calendarProviderPackage, CALENDAR_PERMISSIONS, true, userId); - grantRuntimePermissionsLPw(calendarProviderPackage, ACCOUNTS_PERMISSIONS, userId); grantRuntimePermissionsLPw(calendarProviderPackage, STORAGE_PERMISSIONS, userId); } @@ -386,7 +394,6 @@ final class DefaultPermissionGrantPolicy { && doesPackageSupportRuntimePermissions(contactsPackage)) { grantRuntimePermissionsLPw(contactsPackage, CONTACTS_PERMISSIONS, userId); grantRuntimePermissionsLPw(contactsPackage, PHONE_PERMISSIONS, userId); - grantRuntimePermissionsLPw(contactsPackage, ACCOUNTS_PERMISSIONS, userId); } // Contacts provider sync adapters @@ -408,7 +415,6 @@ final class DefaultPermissionGrantPolicy { true, userId); grantRuntimePermissionsLPw(contactsProviderPackage, PHONE_PERMISSIONS, true, userId); - grantRuntimePermissionsLPw(contactsProviderPackage, ACCOUNTS_PERMISSIONS, userId); grantRuntimePermissionsLPw(contactsProviderPackage, STORAGE_PERMISSIONS, userId); } @@ -419,7 +425,7 @@ final class DefaultPermissionGrantPolicy { getDefaultSystemHandlerActivityPackageLPr(deviceProvisionIntent, userId); if (deviceProvisionPackage != null && doesPackageSupportRuntimePermissions(deviceProvisionPackage)) { - grantRuntimePermissionsLPw(deviceProvisionPackage, ACCOUNTS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(deviceProvisionPackage, CONTACTS_PERMISSIONS, userId); } // Maps @@ -503,6 +509,16 @@ final class DefaultPermissionGrantPolicy { } } + // Voice recognition + Intent voiceRecoIntent = new Intent("android.speech.RecognitionService"); + voiceRecoIntent.addCategory(Intent.CATEGORY_DEFAULT); + PackageParser.Package voiceRecoPackage = getDefaultSystemHandlerServicePackageLPr( + voiceRecoIntent, userId); + if (voiceRecoPackage != null + && doesPackageSupportRuntimePermissions(voiceRecoPackage)) { + grantRuntimePermissionsLPw(voiceRecoPackage, MICROPHONE_PERMISSIONS, userId); + } + // Location if (locationPackageNames != null) { for (String packageName : locationPackageNames) { @@ -567,9 +583,9 @@ final class DefaultPermissionGrantPolicy { } 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); + grantRuntimePermissionsLPw(smsPackage, PHONE_PERMISSIONS, false, true, userId); + grantRuntimePermissionsLPw(smsPackage, CONTACTS_PERMISSIONS, false, true, userId); + grantRuntimePermissionsLPw(smsPackage, SMS_PERMISSIONS, false, true, userId); } } @@ -581,10 +597,29 @@ final class DefaultPermissionGrantPolicy { 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); + grantRuntimePermissionsLPw(dialerPackage, PHONE_PERMISSIONS, false, true, userId); + grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, false, true, userId); + grantRuntimePermissionsLPw(dialerPackage, SMS_PERMISSIONS, false, true, userId); + grantRuntimePermissionsLPw(dialerPackage, MICROPHONE_PERMISSIONS, false, true, userId); + } + } + + private void grantDefaultPermissionsToDefaultSimCallManagerLPr( + PackageParser.Package simCallManagerPackage, int userId) { + Log.i(TAG, "Granting permissions to sim call manager for user:" + userId); + if (doesPackageSupportRuntimePermissions(simCallManagerPackage)) { + grantRuntimePermissionsLPw(simCallManagerPackage, PHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(simCallManagerPackage, MICROPHONE_PERMISSIONS, userId); + } + } + + public void grantDefaultPermissionsToDefaultSimCallManagerLPr(String packageName, int userId) { + if (packageName == null) { + return; + } + PackageParser.Package simCallManagerPackage = getPackageLPr(packageName); + if (simCallManagerPackage != null) { + grantDefaultPermissionsToDefaultSimCallManagerLPr(simCallManagerPackage, userId); } } @@ -599,6 +634,7 @@ final class DefaultPermissionGrantPolicy { && doesPackageSupportRuntimePermissions(carrierPackage)) { grantRuntimePermissionsLPw(carrierPackage, PHONE_PERMISSIONS, userId); grantRuntimePermissionsLPw(carrierPackage, LOCATION_PERMISSIONS, userId); + grantRuntimePermissionsLPw(carrierPackage, SMS_PERMISSIONS, userId); } } } @@ -611,7 +647,7 @@ final class DefaultPermissionGrantPolicy { PackageParser.Package browserPackage = getSystemPackageLPr(packageName); if (browserPackage != null && doesPackageSupportRuntimePermissions(browserPackage)) { - grantRuntimePermissionsLPw(browserPackage, LOCATION_PERMISSIONS, userId); + grantRuntimePermissionsLPw(browserPackage, LOCATION_PERMISSIONS, false, false, userId); } } @@ -635,12 +671,32 @@ final class DefaultPermissionGrantPolicy { return null; } + private PackageParser.Package getDefaultSystemHandlerServicePackageLPr( + Intent intent, int userId) { + List<ResolveInfo> handlers = mService.queryIntentServices(intent, + intent.resolveType(mService.mContext.getContentResolver()), + PackageManager.GET_DISABLED_COMPONENTS, userId); + if (handlers == null) { + return null; + } + final int handlerCount = handlers.size(); + for (int i = 0; i < handlerCount; i++) { + ResolveInfo handler = handlers.get(i); + PackageParser.Package handlerPackage = getSystemPackageLPr( + handler.serviceInfo.packageName); + if (handlerPackage != null) { + return handlerPackage; + } + } + return null; + } + private List<PackageParser.Package> getHeadlessSyncAdapterPackagesLPr( String[] syncAdapterPackageNames, int userId) { List<PackageParser.Package> syncAdapterPackages = new ArrayList<>(); Intent homeIntent = new Intent(Intent.ACTION_MAIN); - homeIntent.addCategory(Intent.CATEGORY_HOME); + homeIntent.addCategory(Intent.CATEGORY_LAUNCHER); for (String syncAdapterPackageName : syncAdapterPackageNames) { homeIntent.setPackage(syncAdapterPackageName); @@ -677,37 +733,70 @@ final class DefaultPermissionGrantPolicy { private PackageParser.Package getSystemPackageLPr(String packageName) { PackageParser.Package pkg = getPackageLPr(packageName); if (pkg != null && pkg.isSystemApp()) { - return !isSysComponentOrPersistentPlatformSignedPrivApp(pkg) ? pkg : null; + return !isSysComponentOrPersistentPlatformSignedPrivAppLPr(pkg) ? pkg : null; } return null; } private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions, int userId) { - grantRuntimePermissionsLPw(pkg, permissions, false, userId); + grantRuntimePermissionsLPw(pkg, permissions, false, false, userId); } private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions, boolean systemFixed, int userId) { + grantRuntimePermissionsLPw(pkg, permissions, systemFixed, false, userId); + } + + private void grantRuntimePermissionsLPw(PackageParser.Package pkg, Set<String> permissions, + boolean systemFixed, boolean overrideUserChoice, int userId) { + if (pkg.requestedPermissions.isEmpty()) { + return; + } + List<String> requestedPermissions = pkg.requestedPermissions; + Set<String> grantablePermissions = null; if (pkg.isUpdatedSystemApp()) { PackageSetting sysPs = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName); if (sysPs != null) { - requestedPermissions = sysPs.pkg.requestedPermissions; + if (sysPs.pkg.requestedPermissions.isEmpty()) { + return; + } + if (!requestedPermissions.equals(sysPs.pkg.requestedPermissions)) { + grantablePermissions = new ArraySet<>(requestedPermissions); + requestedPermissions = sysPs.pkg.requestedPermissions; + } } } - final int permissionCount = requestedPermissions.size(); - for (int i = 0; i < permissionCount; i++) { + final int grantablePermissionCount = requestedPermissions.size(); + for (int i = 0; i < grantablePermissionCount; i++) { String permission = requestedPermissions.get(i); + + // If there is a disabled system app it may request a permission the updated + // version ot the data partition doesn't, In this case skip the permission. + if (grantablePermissions != null && !grantablePermissions.contains(permission)) { + continue; + } + 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) { + // Unless the caller wants to override user choices. The override is + // to make sure we can grant the needed permission to the default + // sms and phone apps after the user chooses this in the UI. + if (flags == 0 || overrideUserChoice) { + // Never clobber policy or system. + final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED + | PackageManager.FLAG_PERMISSION_POLICY_FIXED; + if ((flags & fixedFlags) != 0) { + continue; + } + mService.grantRuntimePermission(pkg.packageName, permission, userId); if (DEBUG) { Log.i(TAG, "Granted " + permission + " to default handler " @@ -726,12 +815,19 @@ final class DefaultPermissionGrantPolicy { } } - private boolean isSysComponentOrPersistentPlatformSignedPrivApp(PackageParser.Package pkg) { + private boolean isSysComponentOrPersistentPlatformSignedPrivAppLPr(PackageParser.Package pkg) { if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) { return true; } - if ((pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) == 0 - || (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) { + if (!pkg.isPrivilegedApp()) { + return false; + } + PackageSetting sysPkg = mService.mSettings.getDisabledSystemPkgLPr(pkg.packageName); + if (sysPkg != null) { + if ((sysPkg.pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) { + return false; + } + } else if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) { return false; } return PackageManagerService.compareSignatures(mService.mPlatformPackage.mSignatures, diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 2abd9246b01a..0366fff4eee9 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -43,7 +43,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentSender; import android.content.IntentSender.SendIntentException; -import android.content.pm.ApplicationInfo; import android.content.pm.IPackageInstaller; import android.content.pm.IPackageInstallerCallback; import android.content.pm.IPackageInstallerSession; @@ -71,7 +70,6 @@ import android.os.SELinux; import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; -import android.os.storage.VolumeInfo; import android.system.ErrnoException; import android.system.Os; import android.text.TextUtils; @@ -93,7 +91,6 @@ import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.ImageUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.server.IoThread; -import com.google.android.collect.Sets; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -108,6 +105,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Random; @@ -123,6 +121,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { /** XML constants used in {@link #mSessionsFile} */ private static final String TAG_SESSIONS = "sessions"; private static final String TAG_SESSION = "session"; + private static final String TAG_GRANTED_RUNTIME_PERMISSION = "granted-runtime-permission"; private static final String ATTR_SESSION_ID = "sessionId"; private static final String ATTR_USER_ID = "userId"; private static final String ATTR_INSTALLER_PACKAGE_NAME = "installerPackageName"; @@ -144,6 +143,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { private static final String ATTR_REFERRER_URI = "referrerUri"; private static final String ATTR_ABI_OVERRIDE = "abiOverride"; private static final String ATTR_VOLUME_UUID = "volumeUuid"; + private static final String ATTR_NAME = "name"; /** Automatically destroy sessions older than this */ private static final long MAX_AGE_MILLIS = 3 * DateUtils.DAY_IN_MILLIS; @@ -221,7 +221,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { reconcileStagesLocked(StorageManager.UUID_PRIVATE_INTERNAL); - final ArraySet<File> unclaimedIcons = Sets.newArraySet( + final ArraySet<File> unclaimedIcons = newArraySet( mSessionsDir.listFiles()); // Ignore stages and icons claimed by active sessions @@ -245,7 +245,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { private void reconcileStagesLocked(String volumeUuid) { final File stagingDir = buildStagingDir(volumeUuid); - final ArraySet<File> unclaimedStages = Sets.newArraySet( + final ArraySet<File> unclaimedStages = newArraySet( stagingDir.listFiles(sStageFilter)); // Ignore stages claimed by active sessions @@ -374,16 +374,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub { } } catch (FileNotFoundException e) { // Missing sessions are okay, probably first boot - } catch (IOException e) { - Slog.wtf(TAG, "Failed reading install sessions", e); - } catch (XmlPullParserException e) { + } catch (IOException | XmlPullParserException e) { Slog.wtf(TAG, "Failed reading install sessions", e); } finally { IoUtils.closeQuietly(fis); } } - private PackageInstallerSession readSessionLocked(XmlPullParser in) throws IOException { + private PackageInstallerSession readSessionLocked(XmlPullParser in) throws IOException, + XmlPullParserException { final int sessionId = readIntAttribute(in, ATTR_SESSION_ID); final int userId = readIntAttribute(in, ATTR_USER_ID); final String installerPackageName = readStringAttribute(in, ATTR_INSTALLER_PACKAGE_NAME); @@ -409,6 +408,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { params.referrerUri = readUriAttribute(in, ATTR_REFERRER_URI); params.abiOverride = readStringAttribute(in, ATTR_ABI_OVERRIDE); params.volumeUuid = readStringAttribute(in, ATTR_VOLUME_UUID); + params.grantedRuntimePermissions = readGrantedRuntimePermissions(in); final File appIconFile = buildAppIconFile(sessionId); if (appIconFile.exists()) { @@ -501,9 +501,51 @@ public class PackageInstallerService extends IPackageInstaller.Stub { params.appIconLastModified = appIconFile.lastModified(); } + writeGrantedRuntimePermissions(out, params.grantedRuntimePermissions); + out.endTag(null, TAG_SESSION); } + private static void writeGrantedRuntimePermissions(XmlSerializer out, + String[] grantedRuntimePermissions) throws IOException { + if (grantedRuntimePermissions != null) { + for (String permission : grantedRuntimePermissions) { + out.startTag(null, TAG_GRANTED_RUNTIME_PERMISSION); + writeStringAttribute(out, ATTR_NAME, permission); + out.endTag(null, TAG_GRANTED_RUNTIME_PERMISSION); + } + } + } + + private static String[] readGrantedRuntimePermissions(XmlPullParser in) + throws IOException, XmlPullParserException { + List<String> permissions = null; + + final int outerDepth = in.getDepth(); + int type; + while ((type = in.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG || in.getDepth() > outerDepth)) { + if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + continue; + } + if (TAG_GRANTED_RUNTIME_PERMISSION.equals(in.getName())) { + String permission = readStringAttribute(in, ATTR_NAME); + if (permissions == null) { + permissions = new ArrayList<>(); + } + permissions.add(permission); + } + } + + if (permissions == null) { + return null; + } + + String[] permissionsArray = new String[permissions.size()]; + permissions.toArray(permissionsArray); + return permissionsArray; + } + private File buildAppIconFile(int sessionId) { return new File(mSessionsDir, "app_icon." + sessionId + ".png"); } @@ -1049,6 +1091,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub { .build(); } + public static <E> ArraySet<E> newArraySet(E... elements) { + final ArraySet<E> set = new ArraySet<E>(); + if (elements != null) { + set.ensureCapacity(elements.length); + Collections.addAll(set, elements); + } + return set; + } + private static class Callbacks extends Handler { private static final int MSG_SESSION_CREATED = 1; private static final int MSG_SESSION_BADGING_CHANGED = 2; diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index b5ef3b798091..4a473fd42741 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -489,7 +489,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // User needs to accept permissions; give installer an intent they // can use to involve user. final Intent intent = new Intent(PackageInstaller.ACTION_CONFIRM_PERMISSIONS); - intent.setPackage("com.android.packageinstaller"); + intent.setPackage(mContext.getPackageManager().getPermissionControllerPackageName()); intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId); try { mRemoteObserver.onUserActionRequired(intent); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 2a08c340bb3a..11e30b52424b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -16,7 +16,6 @@ package com.android.server.pm; -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.Manifest.permission.WRITE_MEDIA_STORAGE; @@ -225,6 +224,7 @@ import com.android.server.SystemConfig; import com.android.server.Watchdog; import com.android.server.pm.PermissionsState.PermissionState; import com.android.server.pm.Settings.DatabaseVersion; +import com.android.server.pm.Settings.VersionInfo; import com.android.server.storage.DeviceStorageMonitorInternal; import org.xmlpull.v1.XmlPullParser; @@ -298,7 +298,7 @@ public class PackageManagerService extends IPackageManager.Stub { 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; + static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; private static final int RADIO_UID = Process.PHONE_UID; private static final int LOG_UID = Process.LOG_UID; @@ -323,6 +323,7 @@ public class PackageManagerService extends IPackageManager.Stub { static final int SCAN_BOOTING = 1<<8; static final int SCAN_TRUSTED_OVERLAY = 1<<9; static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; + static final int SCAN_REPLACING = 1<<11; static final int SCAN_REQUIRE_KNOWN = 1<<12; static final int SCAN_MOVE = 1<<13; static final int SCAN_INITIAL = 1<<14; @@ -1339,8 +1340,8 @@ public class PackageManagerService extends IPackageManager.Stub { // permissions if requested before broadcasting the install. if ((args.installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0) { - grantRequestedRuntimePermissions(res.pkg, - args.user.getIdentifier()); + grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(), + args.installGrantPermissions); } // Determine the set of users who are adding this @@ -1655,6 +1656,11 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public void onVolumeForgotten(String fsUuid) { + if (TextUtils.isEmpty(fsUuid)) { + Slog.w(TAG, "Forgetting internal storage is probably a mistake; ignoring"); + return; + } + // Remove any apps installed on the forgotten volume synchronized (mPackages) { final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); @@ -1664,17 +1670,23 @@ public class PackageManagerService extends IPackageManager.Stub { UserHandle.USER_OWNER, PackageManager.DELETE_ALL_USERS); } + mSettings.onVolumeForgotten(fsUuid); mSettings.writeLPr(); } } }; - private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId) { + private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId, + String[] grantedPermissions) { if (userId >= UserHandle.USER_OWNER) { - grantRequestedRuntimePermissionsForUser(pkg, userId); + grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); } else if (userId == UserHandle.USER_ALL) { - for (int someUserId : UserManagerService.getInstance().getUserIds()) { - grantRequestedRuntimePermissionsForUser(pkg, someUserId); + final int[] userIds; + synchronized (mPackages) { + userIds = UserManagerService.getInstance().getUserIds(); + } + for (int someUserId : userIds) { + grantRequestedRuntimePermissionsForUser(pkg, someUserId, grantedPermissions); } } @@ -1684,7 +1696,8 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId) { + private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, + String[] grantedPermissions) { SettingBase sb = (SettingBase) pkg.mExtras; if (sb == null) { return; @@ -1694,7 +1707,8 @@ public class PackageManagerService extends IPackageManager.Stub { for (String permission : pkg.requestedPermissions) { BasePermission bp = mSettings.mPermissions.get(permission); - if (bp != null && bp.isRuntime()) { + if (bp != null && bp.isRuntime() && (grantedPermissions == null + || ArrayUtils.contains(grantedPermissions, permission))) { permissionsState.grantRuntimePermission(bp, userId); } } @@ -2233,17 +2247,16 @@ public class PackageManagerService extends IPackageManager.Stub { // cases get permissions that the user didn't initially explicitly // allow... it would be nice to have some better way to handle // this situation. - final boolean regrantPermissions = mSettings.mInternalSdkPlatform - != mSdkVersion; - if (regrantPermissions) Slog.i(TAG, "Platform changed from " - + mSettings.mInternalSdkPlatform + " to " + mSdkVersion - + "; regranting permissions for internal storage"); - mSettings.mInternalSdkPlatform = mSdkVersion; - - updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL - | (regrantPermissions - ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) - : 0)); + final VersionInfo ver = mSettings.getInternalVersion(); + + int updateFlags = UPDATE_PERMISSIONS_ALL; + if (ver.sdkVersion != mSdkVersion) { + Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " + + mSdkVersion + "; regranting permissions for internal storage"); + updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; + } + updatePermissionsLPw(null, null, updateFlags); + ver.sdkVersion = mSdkVersion; // If this is the first boot, and it is a normal boot, then // we need to initialize the default preferred apps. @@ -2255,20 +2268,22 @@ public class PackageManagerService extends IPackageManager.Stub { // If this is first boot after an OTA, and a normal boot, then // we need to clear code cache directories. - mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint); + mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); if (mIsUpgrade && !onlyCore) { Slog.i(TAG, "Build fingerprint changed; clearing code caches"); for (int i = 0; i < mSettings.mPackages.size(); i++) { final PackageSetting ps = mSettings.mPackages.valueAt(i); - deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); + if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { + deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); + } } - mSettings.mFingerprint = Build.FINGERPRINT; + ver.fingerprint = Build.FINGERPRINT; } checkDefaultBrowser(); // All the changes are done during package scanning. - mSettings.updateInternalDatabaseVersion(); + ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; // can downgrade to reader mSettings.writeLPr(); @@ -2961,6 +2976,10 @@ public class PackageManagerService extends IPackageManager.Stub { public boolean activitySupportsIntent(ComponentName component, Intent intent, String resolvedType) { synchronized (mPackages) { + if (component.equals(mResolveComponentName)) { + // The resolver supports EVERYTHING! + return true; + } PackageParser.Activity a = mActivities.mActivities.get(component); if (a == null) { return false; @@ -3101,7 +3120,13 @@ public class PackageManagerService extends IPackageManager.Stub { final PackageParser.Package p = mPackages.get(pkgName); if (p != null && p.mExtras != null) { final PackageSetting ps = (PackageSetting) p.mExtras; - if (ps.getPermissionsState().hasPermission(permName, userId)) { + final PermissionsState permissionsState = ps.getPermissionsState(); + if (permissionsState.hasPermission(permName, userId)) { + return PackageManager.PERMISSION_GRANTED; + } + // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION + if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState + .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { return PackageManager.PERMISSION_GRANTED; } } @@ -3122,13 +3147,25 @@ public class PackageManagerService extends IPackageManager.Stub { Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); if (obj != null) { final SettingBase ps = (SettingBase) obj; - if (ps.getPermissionsState().hasPermission(permName, userId)) { + final PermissionsState permissionsState = ps.getPermissionsState(); + if (permissionsState.hasPermission(permName, userId)) { + return PackageManager.PERMISSION_GRANTED; + } + // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION + if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState + .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { return PackageManager.PERMISSION_GRANTED; } } else { ArraySet<String> perms = mSystemPermissions.get(uid); - if (perms != null && perms.contains(permName)) { - return PackageManager.PERMISSION_GRANTED; + if (perms != null) { + if (perms.contains(permName)) { + return PackageManager.PERMISSION_GRANTED; + } + if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms + .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { + return PackageManager.PERMISSION_GRANTED; + } } } } @@ -3158,6 +3195,13 @@ public class PackageManagerService extends IPackageManager.Stub { } } + @Override + public String getPermissionControllerPackageName() { + synchronized (mPackages) { + return mRequiredInstallerPackage; + } + } + /** * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. @@ -3382,7 +3426,7 @@ public class PackageManagerService extends IPackageManager.Stub { } mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, + android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, "grantRuntimePermission"); enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, @@ -3466,7 +3510,7 @@ public class PackageManagerService extends IPackageManager.Stub { } mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, + android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, "revokeRuntimePermission"); enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, @@ -3517,7 +3561,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public void resetRuntimePermissions() { mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, + android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, "revokeRuntimePermission"); int callingUid = Binder.getCallingUid(); @@ -3527,16 +3571,19 @@ public class PackageManagerService extends IPackageManager.Stub { "resetRuntimePermissions"); } - final int[] userIds; - synchronized (mPackages) { updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); - final int userCount = UserManagerService.getInstance().getUserIds().length; - userIds = Arrays.copyOf(UserManagerService.getInstance().getUserIds(), userCount); - } - - for (int userId : userIds) { - mDefaultPermissionPolicy.grantDefaultPermissions(userId); + for (int userId : UserManagerService.getInstance().getUserIds()) { + final int packageCount = mPackages.size(); + for (int i = 0; i < packageCount; i++) { + PackageParser.Package pkg = mPackages.valueAt(i); + if (!(pkg.mExtras instanceof PackageSetting)) { + continue; + } + PackageSetting ps = (PackageSetting) pkg.mExtras; + resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); + } + } } } @@ -3546,9 +3593,7 @@ public class PackageManagerService extends IPackageManager.Stub { return 0; } - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, - "getPermissionFlags"); + enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getPermissionFlags"); @@ -3581,17 +3626,17 @@ public class PackageManagerService extends IPackageManager.Stub { return; } - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, - "updatePermissionFlags"); + enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "updatePermissionFlags"); - // Only the system can change system fixed flags. + // Only the system can change these flags and nothing else. if (getCallingUid() != Process.SYSTEM_UID) { flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; + flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; + flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; } synchronized (mPackages) { @@ -3643,9 +3688,7 @@ public class PackageManagerService extends IPackageManager.Stub { return; } - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, - "updatePermissionFlagsForAllApps"); + enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "updatePermissionFlagsForAllApps"); @@ -3675,6 +3718,17 @@ public class PackageManagerService extends IPackageManager.Stub { } } + private void enforceGrantRevokeRuntimePermissionPermissions(String message) { + if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) + != PackageManager.PERMISSION_GRANTED + && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException(message + " requires " + + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " + + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); + } + } + @Override public boolean shouldShowRequestPermissionRationale(String permissionName, String packageName, int userId) { @@ -3901,10 +3955,8 @@ public class PackageManagerService extends IPackageManager.Stub { * were updated, return true. */ private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { - return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan( - DatabaseVersion.SIGNATURE_END_ENTITY)) - || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan( - DatabaseVersion.SIGNATURE_END_ENTITY)); + final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); + return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; } /** @@ -3951,13 +4003,8 @@ public class PackageManagerService extends IPackageManager.Stub { } private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { - if (isExternal(scannedPkg)) { - return mSettings.isExternalDatabaseVersionOlderThan( - DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); - } else { - return mSettings.isInternalDatabaseVersionOlderThan( - DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); - } + final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); + return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; } private int compareSignaturesRecover(PackageSignatures existingSigs, @@ -5388,7 +5435,7 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - public List<ProviderInfo> queryContentProviders(String processName, + public ParceledListSlice<ProviderInfo> queryContentProviders(String processName, int uid, int flags) { ArrayList<ProviderInfo> finalList = null; // reader @@ -5420,9 +5467,10 @@ public class PackageManagerService extends IPackageManager.Stub { if (finalList != null) { Collections.sort(finalList, mProviderInitOrderSorter); + return new ParceledListSlice<ProviderInfo>(finalList); } - return finalList; + return null; } @Override @@ -6158,12 +6206,16 @@ public class PackageManagerService extends IPackageManager.Stub { return false; } } - - synchronized (mInstallLock) { - final String[] instructionSets = new String[] { targetInstructionSet }; - int result = mPackageDexOptimizer.performDexOpt(p, instructionSets, - false /* forceDex */, false /* defer */, true /* inclDependencies */); - return result == PackageDexOptimizer.DEX_OPT_PERFORMED; + long callingId = Binder.clearCallingIdentity(); + try { + synchronized (mInstallLock) { + final String[] instructionSets = new String[] { targetInstructionSet }; + int result = mPackageDexOptimizer.performDexOpt(p, instructionSets, + false /* forceDex */, false /* defer */, true /* inclDependencies */); + return result == PackageDexOptimizer.DEX_OPT_PERFORMED; + } + } finally { + Binder.restoreCallingIdentity(callingId); } } @@ -7088,6 +7140,14 @@ public class PackageManagerService extends IPackageManager.Stub { } } + // Request the ActivityManager to kill the process(only for existing packages) + // so that we do not end up in a confused state while the user is still using the older + // version of the application while the new one gets installed. + if ((scanFlags & SCAN_REPLACING) != 0) { + killApplication(pkg.applicationInfo.packageName, + pkg.applicationInfo.uid, "replace pkg"); + } + // Also need to kill any apps that are dependent on the library. if (clientLibPkgs != null) { for (int i=0; i<clientLibPkgs.size(); i++) { @@ -7298,6 +7358,9 @@ public class PackageManagerService extends IPackageManager.Stub { for (i=0; i<N; i++) { PackageParser.Permission p = pkg.permissions.get(i); + // Assume by default that we did not install this permission into the system. + p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; + // Now that permission groups have a special meaning, we ignore permission // groups for legacy apps to prevent unexpected behavior. In particular, // permissions for one app being granted to someone just becuase they happen @@ -7327,6 +7390,7 @@ public class PackageManagerService extends IPackageManager.Stub { bp.perm = p; bp.uid = pkg.applicationInfo.uid; bp.sourcePackage = p.info.packageName; + p.info.flags |= PermissionInfo.FLAG_INSTALLED; } else if (!currentOwnerIsSystem) { String msg = "New decl " + p.owner + " of permission " + p.info.name + " is system; overriding " + bp.sourcePackage; @@ -7352,6 +7416,7 @@ public class PackageManagerService extends IPackageManager.Stub { bp.perm = p; bp.uid = pkg.applicationInfo.uid; bp.sourcePackage = p.info.packageName; + p.info.flags |= PermissionInfo.FLAG_INSTALLED; if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { if (r == null) { r = new StringBuilder(256); @@ -8542,7 +8607,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (!allowed) { if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 - && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.MNC) { + && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { // If this was a previously normal/dangerous permission that got moved // to a system permission as part of the runtime permission redesign, then // we still want to blindly grant it to old apps. @@ -9444,7 +9509,7 @@ public class PackageManagerService extends IPackageManager.Stub { final Message msg = mHandler.obtainMessage(INIT_COPY); msg.obj = new InstallParams(origin, null, observer, installFlags, installerPackageName, - null, verificationParams, user, packageAbiOverride); + null, verificationParams, user, packageAbiOverride, null); mHandler.sendMessage(msg); } @@ -9464,7 +9529,8 @@ public class PackageManagerService extends IPackageManager.Stub { final Message msg = mHandler.obtainMessage(INIT_COPY); msg.obj = new InstallParams(origin, null, observer, params.installFlags, - installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride); + installerPackageName, params.volumeUuid, verifParams, user, params.abiOverride, + params.grantedRuntimePermissions); mHandler.sendMessage(msg); } @@ -9536,6 +9602,7 @@ public class PackageManagerService extends IPackageManager.Stub { killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), "hiding pkg"); sendApplicationHiddenForUser(packageName, pkgSetting, userId); + return true; } } finally { Binder.restoreCallingIdentity(callingId); @@ -10344,10 +10411,13 @@ public class PackageManagerService extends IPackageManager.Stub { private InstallArgs mArgs; private int mRet; final String packageAbiOverride; + final String[] grantedRuntimePermissions; + InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, - VerificationParams verificationParams, UserHandle user, String packageAbiOverride) { + VerificationParams verificationParams, UserHandle user, String packageAbiOverride, + String[] grantedPermissions) { super(user); this.origin = origin; this.move = move; @@ -10357,6 +10427,7 @@ public class PackageManagerService extends IPackageManager.Stub { this.volumeUuid = volumeUuid; this.verificationParams = verificationParams; this.packageAbiOverride = packageAbiOverride; + this.grantedRuntimePermissions = grantedPermissions; } @Override @@ -10620,6 +10691,12 @@ public class PackageManagerService extends IPackageManager.Stub { final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, receivers, verificationState); + // Apps installed for "all" users use the device owner to verify the app + UserHandle verifierUser = getUser(); + if (verifierUser == UserHandle.ALL) { + verifierUser = UserHandle.OWNER; + } + /* * If any sufficient verifiers were listed in the package * manifest, attempt to ask them. @@ -10635,8 +10712,7 @@ public class PackageManagerService extends IPackageManager.Stub { final Intent sufficientIntent = new Intent(verification); sufficientIntent.setComponent(verifierComponent); - - mContext.sendBroadcastAsUser(sufficientIntent, getUser()); + mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); } } } @@ -10651,7 +10727,7 @@ public class PackageManagerService extends IPackageManager.Stub { * target BroadcastReceivers have run. */ verification.setComponent(requiredVerifierComponent); - mContext.sendOrderedBroadcastAsUser(verification, getUser(), + mContext.sendOrderedBroadcastAsUser(verification, verifierUser, android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, new BroadcastReceiver() { @Override @@ -10781,6 +10857,7 @@ public class PackageManagerService extends IPackageManager.Stub { final ManifestDigest manifestDigest; final UserHandle user; final String abiOverride; + final String[] installGrantPermissions; // The list of instruction sets supported by this app. This is currently // only used during the rmdex() phase to clean up resources. We can get rid of this @@ -10790,7 +10867,7 @@ public class PackageManagerService extends IPackageManager.Stub { InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, ManifestDigest manifestDigest, UserHandle user, String[] instructionSets, - String abiOverride) { + String abiOverride, String[] installGrantPermissions) { this.origin = origin; this.move = move; this.installFlags = installFlags; @@ -10801,6 +10878,7 @@ public class PackageManagerService extends IPackageManager.Stub { this.user = user; this.instructionSets = instructionSets; this.abiOverride = abiOverride; + this.installGrantPermissions = installGrantPermissions; } abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; @@ -10893,7 +10971,8 @@ public class PackageManagerService extends IPackageManager.Stub { FileInstallArgs(InstallParams params) { super(params.origin, params.move, params.observer, params.installFlags, params.installerPackageName, params.volumeUuid, params.getManifestDigest(), - params.getUser(), null /* instruction sets */, params.packageAbiOverride); + params.getUser(), null /* instruction sets */, params.packageAbiOverride, + params.grantedRuntimePermissions); if (isFwdLocked()) { throw new IllegalArgumentException("Forward locking only supported in ASEC"); } @@ -10902,7 +10981,7 @@ public class PackageManagerService extends IPackageManager.Stub { /** Existing install */ FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { super(OriginInfo.fromNothing(), null, null, 0, null, null, null, null, instructionSets, - null); + null, null); this.codeFile = (codePath != null) ? new File(codePath) : null; this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; } @@ -11118,7 +11197,8 @@ public class PackageManagerService extends IPackageManager.Stub { AsecInstallArgs(InstallParams params) { super(params.origin, params.move, params.observer, params.installFlags, params.installerPackageName, params.volumeUuid, params.getManifestDigest(), - params.getUser(), null /* instruction sets */, params.packageAbiOverride); + params.getUser(), null /* instruction sets */, params.packageAbiOverride, + params.grantedRuntimePermissions); } /** Existing install */ @@ -11126,7 +11206,7 @@ public class PackageManagerService extends IPackageManager.Stub { boolean isExternal, boolean isForwardLocked) { super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, - instructionSets, null); + instructionSets, null, null); // Hackily pretend we're still looking at a full code path if (!fullCodePath.endsWith(RES_FILE_NAME)) { fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); @@ -11143,7 +11223,7 @@ public class PackageManagerService extends IPackageManager.Stub { AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, null, - instructionSets, null); + instructionSets, null, null); this.cid = cid; setMountPath(PackageHelper.getSdDir(cid)); } @@ -11410,7 +11490,8 @@ public class PackageManagerService extends IPackageManager.Stub { MoveInstallArgs(InstallParams params) { super(params.origin, params.move, params.observer, params.installFlags, params.installerPackageName, params.volumeUuid, params.getManifestDigest(), - params.getUser(), null /* instruction sets */, params.packageAbiOverride); + params.getUser(), null /* instruction sets */, params.packageAbiOverride, + params.grantedRuntimePermissions); } int copyApk(IMediaContainerService imcs, boolean temp) { @@ -11705,7 +11786,6 @@ public class PackageManagerService extends IPackageManager.Stub { final String pkgName = pkg.packageName; final int[] allUsers; final boolean[] perUserInstalled; - final boolean weFroze; // First find the old package info and check signatures synchronized(mPackages) { @@ -11735,35 +11815,15 @@ public class PackageManagerService extends IPackageManager.Stub { for (int i = 0; i < allUsers.length; i++) { perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; } - - // Mark the app as frozen to prevent launching during the upgrade - // process, and then kill all running instances - if (!ps.frozen) { - ps.frozen = true; - weFroze = true; - } else { - weFroze = false; - } } - // Now that we're guarded by frozen state, kill app during upgrade - killApplication(pkgName, oldPackage.applicationInfo.uid, "replace pkg"); - - try { - boolean sysPkg = (isSystemApp(oldPackage)); - if (sysPkg) { - replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, - user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); - } else { - replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, - user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); - } - } finally { - // Regardless of success or failure of upgrade steps above, always - // unfreeze the package if we froze it - if (weFroze) { - unfreezePackage(pkgName); - } + boolean sysPkg = (isSystemApp(oldPackage)); + if (sysPkg) { + replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, + user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); + } else { + replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, + user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res); } } @@ -11893,6 +11953,8 @@ public class PackageManagerService extends IPackageManager.Stub { } } + killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg"); + res.removedInfo.uid = oldPkg.applicationInfo.uid; res.removedInfo.removedPackage = packageName; // Remove existing system package @@ -12237,6 +12299,20 @@ public class PackageManagerService extends IPackageManager.Stub { // We did an in-place move, so dex is ready to roll scanFlags |= SCAN_NO_DEX; scanFlags |= SCAN_MOVE; + + synchronized (mPackages) { + final PackageSetting ps = mSettings.mPackages.get(pkgName); + if (ps == null) { + res.setError(INSTALL_FAILED_INTERNAL_ERROR, + "Missing settings for moved package " + pkgName); + } + + // We moved the entire application as-is, so bring over the + // previously derived ABI information. + pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; + pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; + } + } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { // Enable SCAN_NO_DEX flag to skip dexopt at a later stage scanFlags |= SCAN_NO_DEX; @@ -12268,7 +12344,7 @@ public class PackageManagerService extends IPackageManager.Stub { startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); if (replace) { - replacePackageLI(pkg, parseFlags, scanFlags, args.user, + replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, installerPackageName, volumeUuid, res); } else { installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, @@ -12454,6 +12530,18 @@ public class PackageManagerService extends IPackageManager.Stub { return installFlags; } + private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { + if (isExternal(pkg)) { + if (TextUtils.isEmpty(pkg.volumeUuid)) { + return mSettings.getExternalVersion(); + } else { + return mSettings.findOrCreateVersion(pkg.volumeUuid); + } + } else { + return mSettings.getInternalVersion(); + } + } + private void deleteTempPackageFiles() { final FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir, String name) { @@ -12854,10 +12942,6 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mPackages) { PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); - // Propagate the permissions state as we do want to drop on the floor - // runtime permissions. The update permissions method below will take - // care of removing obsolete permissions and grant install permissions. - ps.getPermissionsState().copyFrom(disabledPs.getPermissionsState()); updatePermissionsLPw(newPkg.packageName, newPkg, UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); @@ -12871,6 +12955,8 @@ public class PackageManagerService extends IPackageManager.Stub { + " => " + perUserInstalled[i]); } ps.setInstalled(perUserInstalled[i], allUserHandles[i]); + + mSettings.writeRuntimePermissionsForUserLPr(allUserHandles[i], false); } // Regardless of writeSettings we need to ensure that this restriction // state propagation is persisted @@ -13021,7 +13107,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) { scheduleWritePackageRestrictionsLocked(removeUser); } - resetUserChangesToRuntimePermissionsAndFlagsLocked(ps, removeUser); + resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser); } return true; } @@ -13182,7 +13268,7 @@ public class PackageManagerService extends IPackageManager.Stub { } PackageSetting ps = (PackageSetting) pkg.mExtras; - resetUserChangesToRuntimePermissionsAndFlagsLocked(ps, userId); + resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); } // Always delete data directories for package, even if we found no other @@ -13214,12 +13300,27 @@ public class PackageManagerService extends IPackageManager.Stub { } /** + * Reverts user permission state changes (permissions and flags) in + * all packages for a given user. + * + * @param userId The device user for which to do a reset. + */ + private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { + final int packageCount = mPackages.size(); + for (int i = 0; i < packageCount; i++) { + PackageParser.Package pkg = mPackages.valueAt(i); + PackageSetting ps = (PackageSetting) pkg.mExtras; + resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); + } + } + + /** * Reverts user permission state changes (permissions and flags). * * @param ps The package for which to reset. * @param userId The device user for which to do a reset. */ - private void resetUserChangesToRuntimePermissionsAndFlagsLocked( + private void resetUserChangesToRuntimePermissionsAndFlagsLPw( final PackageSetting ps, final int userId) { if (ps.pkg == null) { return; @@ -13719,6 +13820,15 @@ public class PackageManagerService extends IPackageManager.Stub { } /** This method takes a specific user id as well as UserHandle.USER_ALL. */ + private void clearIntentFilterVerificationsLPw(int userId) { + final int packageCount = mPackages.size(); + for (int i = 0; i < packageCount; i++) { + PackageParser.Package pkg = mPackages.valueAt(i); + clearIntentFilterVerificationsLPw(pkg.packageName, userId); + } + } + + /** This method takes a specific user id as well as UserHandle.USER_ALL. */ void clearIntentFilterVerificationsLPw(String packageName, int userId) { if (userId == UserHandle.USER_ALL) { if (mSettings.removeIntentFilterVerificationLPw(packageName, @@ -13734,7 +13844,6 @@ public class PackageManagerService extends IPackageManager.Stub { } } - void clearDefaultBrowserIfNeeded(String packageName) { for (int oneUserId : sUserManager.getUserIds()) { String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); @@ -13746,17 +13855,27 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - public void resetPreferredActivities(int userId) { + public void resetApplicationPreferences(int userId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); // writer synchronized (mPackages) { - clearPackagePreferredActivitiesLPw(null, userId); - mSettings.applyDefaultPreferredAppsLPw(this, userId); - applyFactoryDefaultBrowserLPw(userId); - primeDomainVerificationsLPw(userId); - - scheduleWritePackageRestrictionsLocked(userId); + final long identity = Binder.clearCallingIdentity(); + try { + clearPackagePreferredActivitiesLPw(null, userId); + mSettings.applyDefaultPreferredAppsLPw(this, userId); + // TODO: We have to reset the default SMS and Phone. This requires + // significant refactoring to keep all default apps in the package + // manager (cleaner but more work) or have the services provide + // callbacks to the package manager to request a default app reset. + applyFactoryDefaultBrowserLPw(userId); + clearIntentFilterVerificationsLPw(userId); + primeDomainVerificationsLPw(userId); + resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); + scheduleWritePackageRestrictionsLocked(userId); + } finally { + Binder.restoreCallingIdentity(identity); + } } } @@ -14624,12 +14743,12 @@ public class PackageManagerService extends IPackageManager.Stub { pw.println(" s[hared-users]: dump shared user IDs"); pw.println(" m[essages]: print collected runtime messages"); pw.println(" v[erifiers]: print package verifier info"); + pw.println(" d[omain-preferred-apps]: print domains preferred apps"); + pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); pw.println(" version: print database version info"); pw.println(" write: write current settings now"); - pw.println(" <package.name>: info about given package"); pw.println(" installs: details about install sessions"); - pw.println(" d[omain-preferred-apps]: print domains preferred apps"); - pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); + pw.println(" <package.name>: info about given package"); return; } else if ("--checkin".equals(opt)) { checkin = true; @@ -14719,16 +14838,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (dumpState.onTitlePrinted()) pw.println(); pw.println("Database versions:"); - pw.print(" SDK Version:"); - pw.print(" internal="); - pw.print(mSettings.mInternalSdkPlatform); - pw.print(" external="); - pw.println(mSettings.mExternalSdkPlatform); - pw.print(" DB Version:"); - pw.print(" internal="); - pw.print(mSettings.mInternalDatabaseVersion); - pw.print(" external="); - pw.println(mSettings.mExternalDatabaseVersion); + mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); } } @@ -15375,20 +15485,18 @@ public class PackageManagerService extends IPackageManager.Stub { // cases get permissions that the user didn't initially explicitly // allow... it would be nice to have some better way to handle // this situation. - final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion; - if (regrantPermissions) - Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to " - + mSdkVersion + "; regranting permissions for external storage"); - mSettings.mExternalSdkPlatform = mSdkVersion; + final VersionInfo ver = mSettings.getExternalVersion(); - // Make sure group IDs have been assigned, and any permission - // changes in other apps are accounted for - updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL - | (regrantPermissions - ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) - : 0)); + int updateFlags = UPDATE_PERMISSIONS_ALL; + if (ver.sdkVersion != mSdkVersion) { + logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " + + mSdkVersion + "; regranting permissions for external"); + updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; + } + updatePermissionsLPw(null, null, updateFlags); - mSettings.updateExternalDatabaseVersion(); + // Yay, everything is now upgraded + ver.forceCurrent(); // can downgrade to reader // Persist settings @@ -15480,6 +15588,7 @@ public class PackageManagerService extends IPackageManager.Stub { final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; synchronized (mInstallLock) { synchronized (mPackages) { + final VersionInfo ver = mSettings.findOrCreateVersion(vol.fsUuid); final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); for (PackageSetting ps : packages) { final PackageParser.Package pkg; @@ -15489,9 +15598,22 @@ public class PackageManagerService extends IPackageManager.Stub { } catch (PackageManagerException e) { Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); } + + if (!Build.FINGERPRINT.equals(ver.fingerprint)) { + deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); + } } - // TODO: regrant any permissions that changed based since original install + int updateFlags = UPDATE_PERMISSIONS_ALL; + if (ver.sdkVersion != mSdkVersion) { + logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " + + mSdkVersion + "; regranting permissions for " + vol.fsUuid); + updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; + } + updatePermissionsLPw(null, null, updateFlags); + + // Yay, everything is now upgraded + ver.forceCurrent(); mSettings.writeLPr(); } @@ -15533,12 +15655,8 @@ public class PackageManagerService extends IPackageManager.Stub { * recycled. */ private void reconcileUsers(String volumeUuid) { - final File[] files = Environment.getDataUserDirectory(volumeUuid).listFiles(); - if (ArrayUtils.isEmpty(files)) { - Slog.d(TAG, "No users found on " + volumeUuid); - return; - } - + final File[] files = FileUtils + .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid)); for (File file : files) { if (!file.isDirectory()) continue; @@ -15594,12 +15712,8 @@ public class PackageManagerService extends IPackageManager.Stub { * another volume. */ private void reconcileApps(String volumeUuid) { - final File[] files = Environment.getDataAppDirectory(volumeUuid).listFiles(); - if (ArrayUtils.isEmpty(files)) { - Slog.d(TAG, "No apps found on " + volumeUuid); - return; - } - + final File[] files = FileUtils + .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); for (File file : files) { final boolean isPackage = (isApkFile(file) || file.isDirectory()) && !PackageInstallerService.isStageName(file.getName()); @@ -15700,16 +15814,27 @@ public class PackageManagerService extends IPackageManager.Stub { "Cannot move system application"); } - if (Objects.equals(ps.volumeUuid, volumeUuid)) { - throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, - "Package already moved to " + volumeUuid); + if (pkg.applicationInfo.isExternalAsec()) { + currentAsec = true; + currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; + } else if (pkg.applicationInfo.isForwardLocked()) { + currentAsec = true; + currentVolumeUuid = "forward_locked"; + } else { + currentAsec = false; + currentVolumeUuid = ps.volumeUuid; + + final File probe = new File(pkg.codePath); + final File probeOat = new File(probe, "oat"); + if (!probe.isDirectory() || !probeOat.isDirectory()) { + throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, + "Move only supported for modern cluster style installs"); + } } - final File probe = new File(pkg.codePath); - final File probeOat = new File(probe, "oat"); - if (!probe.isDirectory() || !probeOat.isDirectory()) { + if (Objects.equals(currentVolumeUuid, volumeUuid)) { throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, - "Move only supported for modern cluster style installs"); + "Package already moved to " + volumeUuid); } if (ps.frozen) { @@ -15718,9 +15843,6 @@ public class PackageManagerService extends IPackageManager.Stub { } ps.frozen = true; - currentAsec = pkg.applicationInfo.isForwardLocked() - || pkg.applicationInfo.isExternalAsec(); - currentVolumeUuid = ps.volumeUuid; codeFile = new File(pkg.codePath); installerPackageName = ps.installerPackageName; packageAbiOverride = ps.cpuAbiOverrideString; @@ -15730,7 +15852,12 @@ public class PackageManagerService extends IPackageManager.Stub { } // Now that we're guarded by frozen state, kill app during move - killApplication(packageName, appId, "move pkg"); + final long token = Binder.clearCallingIdentity(); + try { + killApplication(packageName, appId, "move pkg"); + } finally { + Binder.restoreCallingIdentity(token); + } final Bundle extras = new Bundle(); extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); @@ -15864,7 +15991,7 @@ public class PackageManagerService extends IPackageManager.Stub { final Message msg = mHandler.obtainMessage(INIT_COPY); final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); msg.obj = new InstallParams(origin, move, installObserver, installFlags, - installerPackageName, volumeUuid, null, user, packageAbiOverride); + installerPackageName, volumeUuid, null, user, packageAbiOverride, null); mHandler.sendMessage(msg); } @@ -16031,7 +16158,9 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public void setPermissionEnforced(String permission, boolean enforced) { - mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null); + // TODO: Now that we no longer change GID for storage, this should to away. + mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, + "setPermissionEnforced"); if (READ_EXTERNAL_STORAGE.equals(permission)) { synchronized (mPackages) { if (mSettings.mReadExternalStorageEnforced == null @@ -16405,6 +16534,13 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override + public void setSimCallManagerPackagesProvider(PackagesProvider provider) { + synchronized (mPackages) { + mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); + } + } + + @Override public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { synchronized (mPackages) { mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); @@ -16426,6 +16562,13 @@ public class PackageManagerService extends IPackageManager.Stub { packageName, userId); } } + @Override + public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { + synchronized (mPackages) { + mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( + packageName, userId); + } + } } @Override diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 312b7b37d732..82ffa474867c 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -45,6 +45,7 @@ import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; +import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; import android.util.AtomicFile; import android.text.TextUtils; @@ -56,6 +57,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BackgroundThread; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; +import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.JournaledFile; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; @@ -125,7 +127,7 @@ final class Settings { * Note that care should be taken to make sure all database upgrades are * idempotent. */ - private static final int CURRENT_DATABASE_VERSION = DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; + public static final int CURRENT_DATABASE_VERSION = DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; /** * This class contains constants that can be referred to from upgrade code. @@ -173,11 +175,12 @@ final class Settings { "persistent-preferred-activities"; static final String TAG_CROSS_PROFILE_INTENT_FILTERS = "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 = + private static final String TAG_DOMAIN_VERIFICATION = "domain-verification"; + private static final String TAG_DEFAULT_APPS = "default-apps"; + private 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 TAG_DEFAULT_BROWSER = "default-browser"; + private static final String TAG_VERSION = "version"; private static final String ATTR_NAME = "name"; private static final String ATTR_USER = "user"; @@ -195,9 +198,12 @@ final class Settings { private static final String ATTR_INSTALLED = "inst"; 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_PACKAGE_NAME = "packageName"; private static final String ATTR_FINGERPRINT = "fingerprint"; private static final String ATTR_APP_LINK_GENERATION = "app-link-generation"; + private static final String ATTR_VOLUME_UUID = "volumeUuid"; + private static final String ATTR_SDK_VERSION = "sdkVersion"; + private static final String ATTR_DATABASE_VERSION = "databaseVersion"; private final Object mLock; @@ -222,27 +228,43 @@ final class Settings { private static int mFirstAvailableUid = 0; - // TODO: store SDK versions and fingerprint for each volume UUID - - // These are the last platform API version we were using for - // the apps installed on internal and external storage. It is - // used to grant newer permissions one time during a system upgrade. - int mInternalSdkPlatform; - int mExternalSdkPlatform; + /** Map from volume UUID to {@link VersionInfo} */ + private ArrayMap<String, VersionInfo> mVersion = new ArrayMap<>(); /** - * The current database version for apps on internal storage. This is - * used to upgrade the format of the packages.xml database not necessarily - * tied to an SDK version. + * Version details for a storage volume that may hold apps. */ - int mInternalDatabaseVersion; - int mExternalDatabaseVersion; + public static class VersionInfo { + /** + * These are the last platform API version we were using for the apps + * installed on internal and external storage. It is used to grant newer + * permissions one time during a system upgrade. + */ + int sdkVersion; - /** - * Last known value of {@link Build#FINGERPRINT}. Used to determine when an - * system update has occurred, meaning we need to clear code caches. - */ - String mFingerprint; + /** + * The current database version for apps on internal storage. This is + * used to upgrade the format of the packages.xml database not + * necessarily tied to an SDK version. + */ + int databaseVersion; + + /** + * Last known value of {@link Build#FINGERPRINT}. Used to determine when + * an system update has occurred, meaning we need to clear code caches. + */ + String fingerprint; + + /** + * Force all version information to match current system values, + * typically after resolving any required upgrade steps. + */ + public void forceCurrent() { + sdkVersion = Build.VERSION.SDK_INT; + databaseVersion = CURRENT_DATABASE_VERSION; + fingerprint = Build.FINGERPRINT; + } + } Boolean mReadExternalStorageEnforced; @@ -591,6 +613,7 @@ final class Settings { p.sharedUser = origPackage.sharedUser; p.appId = origPackage.appId; p.origPackage = origPackage; + p.getPermissionsState().copyFrom(origPackage.getPermissionsState()); mRenamedPackages.put(name, origPackage.name); name = origPackage.name; // Update new package state. @@ -790,6 +813,20 @@ final class Settings { p.sharedUser = sharedUser; p.appId = sharedUser.userId; } + + // If the we know about this user id, we have to update it as it + // has to point to the same PackageSetting instance as the package. + Object userIdPs = getUserIdLPr(p.appId); + if (sharedUser == null) { + if (userIdPs != null && userIdPs != p) { + replaceUserIdLPw(p.appId, p); + } + } else { + if (userIdPs != null && userIdPs != sharedUser) { + replaceUserIdLPw(p.appId, sharedUser); + } + } + IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.get(name); if (ivi != null) { if (DEBUG_DOMAIN_VERIFICATION) { @@ -1056,13 +1093,7 @@ final class Settings { } return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; } - int status = (int)(ps.getDomainVerificationStatusForUser(userId) >> 32); - if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { - if (ps.getIntentFilterVerificationInfo() != null) { - status = ps.getIntentFilterVerificationInfo().getStatus(); - } - } - return status; + return (int)(ps.getDomainVerificationStatusForUser(userId) >> 32); } boolean updateIntentFilterVerificationStatusLPw(String packageName, final int status, int userId) { @@ -1184,38 +1215,26 @@ final class Settings { .onDefaultRuntimePermissionsGrantedLPr(userId); } - /** - * Returns whether the current database has is older than {@code version} - * for apps on internal storage. - */ - public boolean isInternalDatabaseVersionOlderThan(int version) { - return mInternalDatabaseVersion < version; + public VersionInfo findOrCreateVersion(String volumeUuid) { + VersionInfo ver = mVersion.get(volumeUuid); + if (ver == null) { + ver = new VersionInfo(); + ver.forceCurrent(); + mVersion.put(volumeUuid, ver); + } + return ver; } - /** - * Returns whether the current database has is older than {@code version} - * for apps on external storage. - */ - public boolean isExternalDatabaseVersionOlderThan(int version) { - return mExternalDatabaseVersion < version; + public VersionInfo getInternalVersion() { + return mVersion.get(StorageManager.UUID_PRIVATE_INTERNAL); } - /** - * Updates the database version for apps on internal storage. Called after - * call the updates to the database format are done for apps on internal - * storage after the initial start-up scan. - */ - public void updateInternalDatabaseVersion() { - mInternalDatabaseVersion = CURRENT_DATABASE_VERSION; + public VersionInfo getExternalVersion() { + return mVersion.get(StorageManager.UUID_PRIMARY_PHYSICAL); } - /** - * Updates the database version for apps on internal storage. Called after - * call the updates to the database format are done for apps on internal - * storage after the initial start-up scan. - */ - public void updateExternalDatabaseVersion() { - mExternalDatabaseVersion = CURRENT_DATABASE_VERSION; + public void onVolumeForgotten(String fsUuid) { + mVersion.remove(fsUuid); } /** @@ -2056,16 +2075,17 @@ final class Settings { serializer.startTag(null, "packages"); - serializer.startTag(null, "last-platform-version"); - serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform)); - serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform)); - serializer.attribute(null, "fingerprint", mFingerprint); - serializer.endTag(null, "last-platform-version"); + for (int i = 0; i < mVersion.size(); i++) { + final String volumeUuid = mVersion.keyAt(i); + final VersionInfo ver = mVersion.valueAt(i); - serializer.startTag(null, "database-version"); - serializer.attribute(null, "internal", Integer.toString(mInternalDatabaseVersion)); - serializer.attribute(null, "external", Integer.toString(mExternalDatabaseVersion)); - serializer.endTag(null, "database-version"); + serializer.startTag(null, TAG_VERSION); + XmlUtils.writeStringAttribute(serializer, ATTR_VOLUME_UUID, volumeUuid); + XmlUtils.writeIntAttribute(serializer, ATTR_SDK_VERSION, ver.sdkVersion); + XmlUtils.writeIntAttribute(serializer, ATTR_DATABASE_VERSION, ver.databaseVersion); + XmlUtils.writeStringAttribute(serializer, ATTR_FINGERPRINT, ver.fingerprint); + serializer.endTag(null, TAG_VERSION); + } if (mVerifierDeviceIdentity != null) { serializer.startTag(null, "verifier"); @@ -2495,8 +2515,10 @@ final class Settings { mReadMessages.append("No settings file found\n"); PackageManagerService.reportSettingsProblem(Log.INFO, "No settings file; creating initial state"); - mInternalSdkPlatform = mExternalSdkPlatform = sdkVersion; - mFingerprint = Build.FINGERPRINT; + // It's enough to just touch version details to create them + // with default values + findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL); + findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL); return false; } str = new FileInputStream(mSettingsFilename); @@ -2580,48 +2602,27 @@ final class Settings { } else if (tagName.equals("restored-ivi")) { readRestoredIntentFilterVerifications(parser); } else if (tagName.equals("last-platform-version")) { - mInternalSdkPlatform = mExternalSdkPlatform = 0; - try { - String internal = parser.getAttributeValue(null, "internal"); - if (internal != null) { - mInternalSdkPlatform = Integer.parseInt(internal); - } - String external = parser.getAttributeValue(null, "external"); - if (external != null) { - mExternalSdkPlatform = Integer.parseInt(external); - } - } 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); - } - } - } - } + // Upgrade from older XML schema + final VersionInfo internal = findOrCreateVersion( + StorageManager.UUID_PRIVATE_INTERNAL); + final VersionInfo external = findOrCreateVersion( + StorageManager.UUID_PRIMARY_PHYSICAL); + + internal.sdkVersion = XmlUtils.readIntAttribute(parser, "internal", 0); + external.sdkVersion = XmlUtils.readIntAttribute(parser, "external", 0); + internal.fingerprint = external.fingerprint = + XmlUtils.readStringAttribute(parser, "fingerprint"); + } else if (tagName.equals("database-version")) { - mInternalDatabaseVersion = mExternalDatabaseVersion = 0; - try { - String internalDbVersionString = parser.getAttributeValue(null, "internal"); - if (internalDbVersionString != null) { - mInternalDatabaseVersion = Integer.parseInt(internalDbVersionString); - } - String externalDbVersionString = parser.getAttributeValue(null, "external"); - if (externalDbVersionString != null) { - mExternalDatabaseVersion = Integer.parseInt(externalDbVersionString); - } - } catch (NumberFormatException ignored) { - } + // Upgrade from older XML schema + final VersionInfo internal = findOrCreateVersion( + StorageManager.UUID_PRIVATE_INTERNAL); + final VersionInfo external = findOrCreateVersion( + StorageManager.UUID_PRIMARY_PHYSICAL); + + internal.databaseVersion = XmlUtils.readIntAttribute(parser, "internal", 0); + external.databaseVersion = XmlUtils.readIntAttribute(parser, "external", 0); + } else if (tagName.equals("verifier")) { final String deviceIdentity = parser.getAttributeValue(null, "device"); try { @@ -2635,6 +2636,14 @@ final class Settings { mReadExternalStorageEnforced = "1".equals(enforcement); } else if (tagName.equals("keyset-settings")) { mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs); + } else if (TAG_VERSION.equals(tagName)) { + final String volumeUuid = XmlUtils.readStringAttribute(parser, + ATTR_VOLUME_UUID); + final VersionInfo ver = findOrCreateVersion(volumeUuid); + ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION); + ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION); + ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT); + } else { Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: " + parser.getName()); @@ -2655,6 +2664,23 @@ final class Settings { Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); } + // If the build is setup to drop runtime permissions + // on update drop the files before loading them. + if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) { + final VersionInfo internal = getInternalVersion(); + if (!Build.FINGERPRINT.equals(internal.fingerprint)) { + if (users == null) { + mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile( + UserHandle.USER_OWNER); + } else { + for (UserInfo user : users) { + mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile( + user.id); + } + } + } + } + final int N = mPendingPackages.size(); for (int i = 0; i < N; i++) { @@ -3898,6 +3924,29 @@ final class Settings { ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE", }; + void dumpVersionLPr(IndentingPrintWriter pw) { + pw.increaseIndent(); + for (int i= 0; i < mVersion.size(); i++) { + final String volumeUuid = mVersion.keyAt(i); + final VersionInfo ver = mVersion.valueAt(i); + if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { + pw.println("Internal:"); + } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { + pw.println("External:"); + } else { + pw.println("UUID " + volumeUuid + ":"); + } + pw.increaseIndent(); + pw.printPair("sdkVersion", ver.sdkVersion); + pw.printPair("databaseVersion", ver.databaseVersion); + pw.println(); + pw.printPair("fingerprint", ver.fingerprint); + pw.println(); + pw.decreaseIndent(); + } + pw.decreaseIndent(); + } + void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf, Date date, List<UserInfo> users) { @@ -4086,6 +4135,28 @@ final class Settings { pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC); pw.println(); + if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) { + final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions; + pw.print(prefix); pw.println(" declared permissions:"); + for (int i=0; i<perms.size(); i++) { + PackageParser.Permission perm = perms.get(i); + if (permissionNames != null + && !permissionNames.contains(perm.info.name)) { + continue; + } + pw.print(prefix); pw.print(" "); pw.print(perm.info.name); + pw.print(": prot="); + pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel)); + if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) { + pw.print(", COSTS_MONEY"); + } + if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) { + pw.print(", INSTALLED"); + } + pw.println(); + } + } + if (ps.sharedUser == null || permissionNames != null) { PermissionsState permissionsState = ps.getPermissionsState(); dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState); @@ -4121,14 +4192,14 @@ final class Settings { if (cmp != null && cmp.size() > 0) { pw.print(prefix); pw.println(" disabledComponents:"); for (String s : cmp) { - pw.print(prefix); pw.print(" "); pw.println(s); + 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); + pw.print(prefix); pw.print(" "); pw.println(s); } } } @@ -4233,11 +4304,14 @@ final class Settings { pw.print(" type="); pw.print(p.type); pw.print(" prot="); pw.println(PermissionInfo.protectionToString(p.protectionLevel)); - if (p.packageSetting != null) { - pw.print(" packageSetting="); pw.println(p.packageSetting); - } if (p.perm != null) { pw.print(" perm="); pw.println(p.perm); + if (p.perm.info.flags != PermissionInfo.FLAG_INSTALLED) { + pw.print(" flags=0x"); pw.println(Integer.toHexString(p.perm.info.flags)); + } + } + if (p.packageSetting != null) { + pw.print(" packageSetting="); pw.println(p.packageSetting); } if (READ_EXTERNAL_STORAGE.equals(p.name)) { pw.print(" enforced="); @@ -4338,24 +4412,32 @@ final class Settings { continue; } pw.print(prefix); pw.print(" "); pw.print(permissionState.getName()); - pw.print(", granted="); pw.print(permissionState.isGranted()); - pw.print(", flags="); pw.println(permissionFlagsToString( - permissionState.getFlags())); + pw.print(": granted="); pw.print(permissionState.isGranted()); + pw.println(permissionFlagsToString(", flags=", + permissionState.getFlags())); } } } - private static String permissionFlagsToString(int flags) { - StringBuilder flagsString = new StringBuilder(); - flagsString.append("[ "); + private static String permissionFlagsToString(String prefix, int flags) { + StringBuilder flagsString = null; while (flags != 0) { + if (flagsString == null) { + flagsString = new StringBuilder(); + flagsString.append(prefix); + flagsString.append("[ "); + } final int flag = 1 << Integer.numberOfTrailingZeros(flags); flags &= ~flag; flagsString.append(PackageManager.permissionFlagToString(flag)); flagsString.append(' '); } - flagsString.append(']'); - return flagsString.toString(); + if (flagsString != null) { + flagsString.append(']'); + return flagsString.toString(); + } else { + return ""; + } } void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, @@ -4369,8 +4451,8 @@ final class Settings { continue; } pw.print(prefix); pw.print(" "); pw.print(permissionState.getName()); - pw.print(", granted="); pw.print(permissionState.isGranted()); - pw.print(", flags="); pw.println(permissionFlagsToString( + pw.print(": granted="); pw.print(permissionState.isGranted()); + pw.println(permissionFlagsToString(", flags=", permissionState.getFlags())); } } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 23cb76771b58..670756216dae 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -529,6 +529,7 @@ public class UserManagerService extends IUserManager.Stub { @Override public void setUserRestriction(String key, boolean value, int userId) { + checkManageUsersPermission("setUserRestriction"); synchronized (mPackagesLock) { if (!SYSTEM_CONTROLLED_RESTRICTIONS.contains(key)) { Bundle restrictions = getUserRestrictions(userId); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 13e075cc5c8e..da8fb702a56e 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -104,7 +104,6 @@ import com.android.internal.policy.PhoneWindow; import android.view.Surface; import android.view.View; import android.view.ViewConfiguration; -import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.WindowManagerInternal; @@ -120,7 +119,7 @@ import com.android.internal.util.ScreenShapeHelper; import com.android.internal.widget.PointerLocationView; import com.android.server.LocalServices; import com.android.server.policy.keyguard.KeyguardServiceDelegate; -import com.android.server.policy.keyguard.KeyguardServiceDelegate.ShowListener; +import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener; import java.io.File; import java.io.FileReader; @@ -252,7 +251,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** Amount of time (in milliseconds) to wait for windows drawn before powering on. */ - static final int WAITING_FOR_DRAWN_TIMEOUT = 500; + static final int WAITING_FOR_DRAWN_TIMEOUT = 1000; /** * Lock protecting internal state. Must not call out into window @@ -324,10 +323,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE); } }; - final ShowListener mKeyguardDelegateCallback = new ShowListener() { + final DrawnListener mKeyguardDrawnCallback = new DrawnListener() { @Override - public void onShown(IBinder windowToken) { - if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onShown."); + public void onDrawn() { + if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onDrawn."); mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE); } }; @@ -359,6 +358,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mSystemReady; boolean mSystemBooted; + private boolean mDeferBindKeyguard; boolean mHdmiPlugged; HdmiControl mHdmiControl; IUiModeManager mUiModeManager; @@ -2469,6 +2469,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { return isKeyguard ? -1 : R.anim.dock_top_enter; } } else if (win == mNavigationBar) { + if (win.getAttrs().windowAnimations != 0) { + return 0; + } // This can be on either the bottom or the right. if (mNavigationBarOnBottom) { if (transit == TRANSIT_EXIT @@ -3111,6 +3114,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { private void launchAssistAction(String hint, int deviceId) { sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); + if (!isUserSetupComplete()) { + // Disable opening assist window during setup + return; + } Bundle args = null; if (deviceId > Integer.MIN_VALUE) { args = new Bundle(); @@ -5462,7 +5469,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { // the wake lock and let the system suspend once this function returns. synchronized (mLock) { mAwake = false; - mKeyguardDrawComplete = false; updateWakeGestureListenerLp(); updateOrientationListenerLp(); updateLockScreenTimeout(); @@ -5484,7 +5490,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { // may happen in a future call to goToSleep. synchronized (mLock) { mAwake = true; - mKeyguardDrawComplete = false; if (mKeyguardDelegate != null) { mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000); @@ -5496,11 +5501,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if (mKeyguardDelegate != null) { - mKeyguardDelegate.onStartedWakingUp(mKeyguardDelegateCallback); - // ... eventually calls finishKeyguardDrawn - } else { - if (DEBUG_WAKEUP) Slog.d(TAG, "null mKeyguardDelegate: setting mKeyguardDrawComplete."); - finishKeyguardDrawn(); + mKeyguardDelegate.onStartedWakingUp(); } } @@ -5531,7 +5532,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private void finishKeyguardDrawn() { synchronized (mLock) { - if (!mAwake || mKeyguardDrawComplete) { + if (!mScreenOnEarly || mKeyguardDrawComplete) { return; // We are not awake yet or we have already informed of this event. } @@ -5539,9 +5540,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mKeyguardDelegate != null) { mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT); } + mWindowManagerDrawComplete = false; } - finishScreenTurningOn(); + // ... eventually calls finishWindowsDrawn which will finalize our screen turn on + // as well as enabling the orientation change logic/sensor. + mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback, + WAITING_FOR_DRAWN_TIMEOUT); } // Called on the DisplayManager's DisplayPowerController thread. @@ -5553,9 +5558,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { synchronized (mLock) { mScreenOnEarly = false; mScreenOnFully = false; + mKeyguardDrawComplete = false; mWindowManagerDrawComplete = false; mScreenOnListener = null; updateOrientationListenerLp(); + + if (mKeyguardDelegate != null) { + mKeyguardDelegate.onScreenTurnedOff(); + } } } @@ -5568,14 +5578,28 @@ public class PhoneWindowManager implements WindowManagerPolicy { synchronized (mLock) { mScreenOnEarly = true; mScreenOnFully = false; + mKeyguardDrawComplete = false; mWindowManagerDrawComplete = false; mScreenOnListener = screenOnListener; + + if (mKeyguardDelegate != null) { + mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback); + } else { + if (DEBUG_WAKEUP) Slog.d(TAG, + "null mKeyguardDelegate: setting mKeyguardDrawComplete."); + finishKeyguardDrawn(); + } } + } - mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback, - WAITING_FOR_DRAWN_TIMEOUT); - // ... eventually calls finishWindowsDrawn which will finalize our screen turn on - // as well as enabling the orientation change logic/sensor. + // Called on the DisplayManager's DisplayPowerController thread. + @Override + public void screenTurnedOn() { + synchronized (mLock) { + if (mKeyguardDelegate != null) { + mKeyguardDelegate.onScreenTurnedOn(); + } + } } private void finishWindowsDrawn() { @@ -6012,6 +6036,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { readCameraLensCoverState(); updateUiMode(); + boolean bindKeyguardNow; synchronized (mLock) { updateOrientationListenerLp(); mSystemReady = true; @@ -6021,13 +6046,36 @@ public class PhoneWindowManager implements WindowManagerPolicy { updateSettings(); } }); + + bindKeyguardNow = mDeferBindKeyguard; + if (bindKeyguardNow) { + // systemBooted ran but wasn't able to bind to the Keyguard, we'll do it now. + mDeferBindKeyguard = false; + } + } + + if (bindKeyguardNow) { + mKeyguardDelegate.bindService(mContext); + mKeyguardDelegate.onBootCompleted(); } } /** {@inheritDoc} */ @Override public void systemBooted() { - if (mKeyguardDelegate != null) { + boolean bindKeyguardNow = false; + synchronized (mLock) { + // Time to bind Keyguard; take care to only bind it once, either here if ready or + // in systemReady if not. + if (mKeyguardDelegate != null) { + bindKeyguardNow = true; + } else { + // Because mKeyguardDelegate is null, we know that the synchronized block in + // systemReady didn't run yet and setting this will actually have an effect. + mDeferBindKeyguard = true; + } + } + if (bindKeyguardNow) { mKeyguardDelegate.bindService(mContext); mKeyguardDelegate.onBootCompleted(); } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java index b9f132bbc380..5d5230756e42 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java @@ -8,6 +8,7 @@ import android.content.pm.ActivityInfo; import android.content.res.Resources; import android.graphics.PixelFormat; import android.os.Bundle; +import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; @@ -18,9 +19,9 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.view.WindowManagerPolicy.OnKeyguardExitResult; +import com.android.internal.policy.IKeyguardDrawnCallback; import com.android.internal.policy.IKeyguardExitCallback; import com.android.internal.policy.IKeyguardService; -import com.android.internal.policy.IKeyguardShowCallback; /** * A local class that keeps a cache of keyguard state that can be restored in the event @@ -34,10 +35,11 @@ public class KeyguardServiceDelegate { protected KeyguardServiceWrapper mKeyguardService; private final Context mContext; private final View mScrim; // shown if keyguard crashes + private final Handler mScrimHandler; private final KeyguardState mKeyguardState = new KeyguardState(); - private ShowListener mShowListenerWhenConnect; + private DrawnListener mDrawnListenerWhenConnect; - /* package */ static final class KeyguardState { + private static final class KeyguardState { KeyguardState() { // Assume keyguard is showing and secure until we know for sure. This is here in // the event something checks before the service is actually started. @@ -61,23 +63,23 @@ public class KeyguardServiceDelegate { public boolean bootCompleted; }; - public interface ShowListener { - public void onShown(IBinder windowToken); + public interface DrawnListener { + void onDrawn(); } // A delegate class to map a particular invocation with a ShowListener object. - private final class KeyguardShowDelegate extends IKeyguardShowCallback.Stub { - private ShowListener mShowListener; + private final class KeyguardShowDelegate extends IKeyguardDrawnCallback.Stub { + private DrawnListener mDrawnListener; - KeyguardShowDelegate(ShowListener showListener) { - mShowListener = showListener; + KeyguardShowDelegate(DrawnListener drawnListener) { + mDrawnListener = drawnListener; } @Override - public void onShown(IBinder windowToken) throws RemoteException { + public void onDrawn() throws RemoteException { if (DEBUG) Log.v(TAG, "**** SHOWN CALLED ****"); - if (mShowListener != null) { - mShowListener.onShown(windowToken); + if (mDrawnListener != null) { + mDrawnListener.onDrawn(); } hideScrim(); } @@ -103,6 +105,7 @@ public class KeyguardServiceDelegate { public KeyguardServiceDelegate(Context context) { mContext = context; mScrim = createScrim(context); + mScrimHandler = new Handler(); } public void bindService(Context context) { @@ -119,8 +122,13 @@ public class KeyguardServiceDelegate { mKeyguardState.showing = false; mKeyguardState.showingAndNotOccluded = false; mKeyguardState.secure = false; - mKeyguardState.deviceHasKeyguard = false; - hideScrim(); + synchronized (mKeyguardState) { + // TODO: Fix synchronisation model in this class. The other state in this class + // is at least self-healing but a race condition here can lead to the scrim being + // stuck on keyguard-less devices. + mKeyguardState.deviceHasKeyguard = false; + hideScrim(); + } } else { if (DEBUG) Log.v(TAG, "*** Keyguard started"); } @@ -136,9 +144,11 @@ public class KeyguardServiceDelegate { // If the system is ready, it means keyguard crashed and restarted. mKeyguardService.onSystemReady(); // This is used to hide the scrim once keyguard displays. - mKeyguardService.onStartedWakingUp(new KeyguardShowDelegate( - mShowListenerWhenConnect)); - mShowListenerWhenConnect = null; + mKeyguardService.onStartedWakingUp(); + mKeyguardService.onScreenTurningOn( + new KeyguardShowDelegate(mDrawnListenerWhenConnect)); + mKeyguardService.onScreenTurnedOn(); + mDrawnListenerWhenConnect = null; } if (mKeyguardState.bootCompleted) { mKeyguardService.onBootCompleted(); @@ -216,20 +226,41 @@ public class KeyguardServiceDelegate { mKeyguardState.dreaming = false; } - public void onStartedWakingUp(final ShowListener showListener) { + public void onStartedWakingUp() { + if (mKeyguardService != null) { + if (DEBUG) Log.v(TAG, "onStartedWakingUp()"); + mKeyguardService.onStartedWakingUp(); + } + } + + public void onScreenTurnedOff() { + if (mKeyguardService != null) { + if (DEBUG) Log.v(TAG, "onScreenTurnedOff()"); + mKeyguardService.onScreenTurnedOff(); + } + } + + public void onScreenTurningOn(final DrawnListener drawnListener) { if (mKeyguardService != null) { - if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + showListener + ")"); - mKeyguardService.onStartedWakingUp(new KeyguardShowDelegate(showListener)); + if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + drawnListener + ")"); + mKeyguardService.onScreenTurningOn(new KeyguardShowDelegate(drawnListener)); } else { // try again when we establish a connection - Slog.w(TAG, "onScreenTurnedOn(): no keyguard service!"); + Slog.w(TAG, "onScreenTurningOn(): no keyguard service!"); // This shouldn't happen, but if it does, show the scrim immediately and // invoke the listener's callback after the service actually connects. - mShowListenerWhenConnect = showListener; + mDrawnListenerWhenConnect = drawnListener; showScrim(); } } + public void onScreenTurnedOn() { + if (mKeyguardService != null) { + if (DEBUG) Log.v(TAG, "onScreenTurnedOn()"); + mKeyguardService.onScreenTurnedOn(); + } + } + public void onStartedGoingToSleep(int why) { if (mKeyguardService != null) { mKeyguardService.onStartedGoingToSleep(why); @@ -307,17 +338,19 @@ public class KeyguardServiceDelegate { } public void showScrim() { - if (!mKeyguardState.deviceHasKeyguard) return; - mScrim.post(new Runnable() { - @Override - public void run() { - mScrim.setVisibility(View.VISIBLE); - } - }); + synchronized (mKeyguardState) { + if (!mKeyguardState.deviceHasKeyguard) return; + mScrimHandler.post(new Runnable() { + @Override + public void run() { + mScrim.setVisibility(View.VISIBLE); + } + }); + } } public void hideScrim() { - mScrim.post(new Runnable() { + mScrimHandler.post(new Runnable() { @Override public void run() { mScrim.setVisibility(View.GONE); diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java index 51d59fa4cb30..cd88b664e2f8 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java @@ -22,9 +22,9 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; +import com.android.internal.policy.IKeyguardDrawnCallback; import com.android.internal.policy.IKeyguardExitCallback; import com.android.internal.policy.IKeyguardService; -import com.android.internal.policy.IKeyguardShowCallback; import com.android.internal.policy.IKeyguardStateCallback; /** @@ -124,9 +124,36 @@ public class KeyguardServiceWrapper implements IKeyguardService { } @Override - public void onStartedWakingUp(IKeyguardShowCallback callback) { + public void onStartedWakingUp() { try { - mService.onStartedWakingUp(callback); + mService.onStartedWakingUp(); + } catch (RemoteException e) { + Slog.w(TAG , "Remote Exception", e); + } + } + + @Override + public void onScreenTurningOn(IKeyguardDrawnCallback callback) { + try { + mService.onScreenTurningOn(callback); + } catch (RemoteException e) { + Slog.w(TAG , "Remote Exception", e); + } + } + + @Override + public void onScreenTurnedOn() { + try { + mService.onScreenTurnedOn(); + } catch (RemoteException e) { + Slog.w(TAG , "Remote Exception", e); + } + } + + @Override + public void onScreenTurnedOff() { + try { + mService.onScreenTurnedOff(); } catch (RemoteException e) { Slog.w(TAG , "Remote Exception", e); } diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index c5ad7fed047d..7108f4afb192 100644 --- a/services/core/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java @@ -48,6 +48,7 @@ import android.provider.Settings; import android.util.EventLog; import android.util.Slog; import android.view.WindowManagerPolicy; +import android.view.inputmethod.InputMethodManagerInternal; /** * Sends broadcasts about important power state changes. @@ -89,6 +90,7 @@ final class Notifier { private final WindowManagerPolicy mPolicy; private final ActivityManagerInternal mActivityManagerInternal; private final InputManagerInternal mInputManagerInternal; + private final InputMethodManagerInternal mInputMethodManagerInternal; private final NotifierHandler mHandler; private final Intent mScreenOnIntent; @@ -133,6 +135,7 @@ final class Notifier { mPolicy = policy; mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); + mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class); mHandler = new NotifierHandler(looper); mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); @@ -314,6 +317,7 @@ final class Notifier { // Start input as soon as we start waking up or going to sleep. mInputManagerInternal.setInteractive(interactive); + mInputMethodManagerInternal.setInteractive(interactive); // Notify battery stats. try { diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 88476cee65c1..b920f97ac839 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -30,6 +30,7 @@ import com.android.server.lights.LightsManager; import com.android.server.Watchdog; import android.Manifest; +import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -3319,8 +3320,14 @@ public final class PowerManagerService extends SystemService */ @Override // Binder call public void setStayOnSetting(int val) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.WRITE_SETTINGS, null); + int uid = Binder.getCallingUid(); + // if uid is of root's, we permit this operation straight away + if (uid != Process.ROOT_UID) { + if (!Settings.checkAndNoteWriteSettingsOperation(mContext, uid, + Settings.getPackageNameForUid(mContext, uid), true)) { + return; + } + } final long ident = 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 c2ce572262da..f4bd61fa39cd 100644 --- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java +++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java @@ -16,9 +16,11 @@ package com.android.server.telecom; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.PackageManagerInternal; import android.database.ContentObserver; @@ -31,6 +33,9 @@ import android.os.ServiceManager; import android.os.UserHandle; import android.provider.Settings; import android.telecom.DefaultDialerManager; +import android.telecom.PhoneAccountHandle; +import android.telecom.TelecomManager; +import android.telephony.CarrierConfigManager; import android.util.IntArray; import android.util.Slog; @@ -39,6 +44,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.telephony.SmsApplication; import com.android.server.LocalServices; import com.android.server.SystemService; +import com.android.server.pm.UserManagerService; /** * Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup @@ -64,7 +70,8 @@ public class TelecomLoaderService extends SystemService { ServiceManager.addService(Context.TELECOM_SERVICE, service); synchronized (mLock) { - if (mDefaultSmsAppRequests != null || mDefaultDialerAppRequests != null) { + if (mDefaultSmsAppRequests != null || mDefaultDialerAppRequests != null + || mDefaultSimCallManagerRequests != null) { final PackageManagerInternal packageManagerInternal = LocalServices .getService(PackageManagerInternal.class); @@ -95,6 +102,23 @@ public class TelecomLoaderService extends SystemService { } } } + if (mDefaultSimCallManagerRequests != null) { + TelecomManager telecomManager = + (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); + PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(); + if (phoneAccount != null) { + final int requestCount = mDefaultSimCallManagerRequests.size(); + final String packageName = + phoneAccount.getComponentName().getPackageName(); + for (int i = requestCount - 1; i >= 0; i--) { + final int userId = mDefaultSimCallManagerRequests.get(i); + mDefaultSimCallManagerRequests.remove(i); + packageManagerInternal + .grantDefaultPermissionsToDefaultSimCallManager( + packageName, userId); + } + } + } } } } catch (RemoteException e) { @@ -122,6 +146,9 @@ public class TelecomLoaderService extends SystemService { @GuardedBy("mLock") private IntArray mDefaultDialerAppRequests; + @GuardedBy("mLock") + private IntArray mDefaultSimCallManagerRequests; + private final Context mContext; @GuardedBy("mLock") @@ -141,6 +168,7 @@ public class TelecomLoaderService extends SystemService { public void onBootPhase(int phase) { if (phase == PHASE_ACTIVITY_MANAGER_READY) { registerDefaultAppNotifier(); + registerCarrierConfigChangedReceiver(); connectToTelecom(); } } @@ -215,6 +243,30 @@ public class TelecomLoaderService extends SystemService { return null; } }); + + // Set a callback for the package manager to query the default sim call manager. + packageManagerInternal.setSimCallManagerPackagesProvider( + new PackageManagerInternal.PackagesProvider() { + @Override + public String[] getPackages(int userId) { + synchronized (mLock) { + if (mServiceConnection == null) { + if (mDefaultSimCallManagerRequests == null) { + mDefaultSimCallManagerRequests = new IntArray(); + } + mDefaultSimCallManagerRequests.add(userId); + return null; + } + } + TelecomManager telecomManager = + (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); + PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId); + if (phoneAccount != null) { + return new String[]{phoneAccount.getComponentName().getPackageName()}; + } + return null; + } + }); } private void registerDefaultAppNotifier() { @@ -245,6 +297,7 @@ public class TelecomLoaderService extends SystemService { packageManagerInternal.grantDefaultPermissionsToDefaultDialerApp( packageName, userId); } + updateSimCallManagerPermissions(packageManagerInternal, userId); } } }; @@ -254,4 +307,36 @@ public class TelecomLoaderService extends SystemService { mContext.getContentResolver().registerContentObserver(defaultDialerAppUri, false, contentObserver, UserHandle.USER_ALL); } + + + private void registerCarrierConfigChangedReceiver() { + final PackageManagerInternal packageManagerInternal = LocalServices.getService( + PackageManagerInternal.class); + BroadcastReceiver receiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) { + for (int userId : UserManagerService.getInstance().getUserIds()) { + updateSimCallManagerPermissions(packageManagerInternal, userId); + } + } + } + }; + + mContext.registerReceiverAsUser(receiver, UserHandle.ALL, + new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED), null, null); + } + + private void updateSimCallManagerPermissions(PackageManagerInternal packageManagerInternal, + int userId) { + TelecomManager telecomManager = + (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); + PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId); + if (phoneAccount != null) { + Slog.i(TAG, "updating sim call manager permissions for userId:" + userId); + String packageName = phoneAccount.getComponentName().getPackageName(); + packageManagerInternal.grantDefaultPermissionsToDefaultSimCallManager( + packageName, userId); + } + } } diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 51df31fde504..a5344b421172 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -133,7 +133,7 @@ public final class TvInputManagerService extends SystemService { mTvInputHardwareManager = new TvInputHardwareManager(context, new HardwareListener()); synchronized (mLock) { - mUserStates.put(mCurrentUserId, new UserState(mContext, mCurrentUserId)); + getOrCreateUserStateLocked(mCurrentUserId); } } @@ -222,7 +222,7 @@ public final class TvInputManagerService extends SystemService { @Override public void onPackageRemoved(String packageName, int uid) { synchronized (mLock) { - UserState userState = getUserStateLocked(getChangingUserId()); + UserState userState = getOrCreateUserStateLocked(getChangingUserId()); if (!userState.packageSet.contains(packageName)) { // Not a TV input package. return; @@ -281,7 +281,7 @@ public final class TvInputManagerService extends SystemService { } private void buildTvInputListLocked(int userId, String[] updatedPackages) { - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); userState.packageSet.clear(); if (DEBUG) Slog.d(TAG, "buildTvInputList"); @@ -368,7 +368,7 @@ public final class TvInputManagerService extends SystemService { } private void buildTvContentRatingSystemListLocked(int userId) { - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); userState.contentRatingSystemList.clear(); final PackageManager pm = mContext.getPackageManager(); @@ -402,11 +402,7 @@ public final class TvInputManagerService extends SystemService { clearSessionAndServiceStatesLocked(mUserStates.get(mCurrentUserId)); mCurrentUserId = userId; - UserState userState = mUserStates.get(userId); - if (userState == null) { - userState = new UserState(mContext, userId); - mUserStates.put(userId, userState); - } + getOrCreateUserStateLocked(userId); buildTvInputListLocked(userId, null); buildTvContentRatingSystemListLocked(userId); mWatchLogHandler.obtainMessage(WatchLogHandler.MSG_SWITCH_CONTENT_RESOLVER, @@ -473,16 +469,17 @@ public final class TvInputManagerService extends SystemService { return context.getContentResolver(); } - private UserState getUserStateLocked(int userId) { + private UserState getOrCreateUserStateLocked(int userId) { UserState userState = mUserStates.get(userId); if (userState == null) { - throw new IllegalStateException("User state not found for user ID " + userId); + userState = new UserState(mContext, userId); + mUserStates.put(userId, userState); } return userState; } private ServiceState getServiceStateLocked(ComponentName component, int userId) { - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); ServiceState serviceState = userState.serviceStateMap.get(component); if (serviceState == null) { throw new IllegalStateException("Service state not found for " + component + " (userId=" @@ -492,7 +489,7 @@ public final class TvInputManagerService extends SystemService { } private SessionState getSessionStateLocked(IBinder sessionToken, int callingUid, int userId) { - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); SessionState sessionState = userState.sessionStateMap.get(sessionToken); if (sessionState == null) { throw new SessionNotFoundException("Session state not found for token " + sessionToken); @@ -530,7 +527,7 @@ public final class TvInputManagerService extends SystemService { } private void updateServiceConnectionLocked(ComponentName component, int userId) { - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); ServiceState serviceState = userState.serviceStateMap.get(component); if (serviceState == null) { return; @@ -574,7 +571,7 @@ public final class TvInputManagerService extends SystemService { private void abortPendingCreateSessionRequestsLocked(ServiceState serviceState, String inputId, int userId) { // Let clients know the create session requests are failed. - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); List<SessionState> sessionsToAbort = new ArrayList<>(); for (IBinder sessionToken : serviceState.sessionTokens) { SessionState sessionState = userState.sessionStateMap.get(sessionToken); @@ -593,7 +590,7 @@ public final class TvInputManagerService extends SystemService { private void createSessionInternalLocked(ITvInputService service, IBinder sessionToken, int userId) { - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); SessionState sessionState = userState.sessionStateMap.get(sessionToken); if (DEBUG) { Slog.d(TAG, "createSessionInternalLocked(inputId=" + sessionState.info.getId() + ")"); @@ -629,7 +626,7 @@ public final class TvInputManagerService extends SystemService { try { sessionState = getSessionStateLocked(sessionToken, callingUid, userId); if (sessionState.session != null) { - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); if (sessionToken == userState.mainSessionToken) { setMainLocked(sessionToken, false, callingUid, userId); } @@ -646,7 +643,7 @@ public final class TvInputManagerService extends SystemService { } private void removeSessionStateLocked(IBinder sessionToken, int userId) { - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); if (sessionToken == userState.mainSessionToken) { if (DEBUG) { Slog.d(TAG, "mainSessionToken=null"); @@ -768,7 +765,7 @@ public final class TvInputManagerService extends SystemService { } private void setStateLocked(String inputId, int state, int userId) { - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); TvInputState inputState = userState.inputMap.get(inputId); ServiceState serviceState = userState.serviceStateMap.get(inputState.info.getComponent()); int oldState = inputState.state; @@ -791,7 +788,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); List<TvInputInfo> inputList = new ArrayList<>(); for (TvInputState state : userState.inputMap.values()) { inputList.add(state.info); @@ -810,7 +807,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); TvInputState state = userState.inputMap.get(inputId); return state == null ? null : state.info; } @@ -826,7 +823,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); TvInputState state = userState.inputMap.get(inputId); return state == null ? INPUT_STATE_CONNECTED : state.state; } @@ -842,7 +839,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); return userState.contentRatingSystemList; } } finally { @@ -857,7 +854,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - final UserState userState = getUserStateLocked(resolvedUserId); + final UserState userState = getOrCreateUserStateLocked(resolvedUserId); userState.callbackSet.add(callback); try { callback.asBinder().linkToDeath(new IBinder.DeathRecipient() { @@ -886,7 +883,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); userState.callbackSet.remove(callback); } } finally { @@ -901,7 +898,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); return userState.persistentDataStore.isParentalControlsEnabled(); } } finally { @@ -917,7 +914,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); userState.persistentDataStore.setParentalControlsEnabled(enabled); } } finally { @@ -932,7 +929,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); return userState.persistentDataStore.isRatingBlocked( TvContentRating.unflattenFromString(rating)); } @@ -948,7 +945,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); List<String> ratings = new ArrayList<>(); for (TvContentRating rating : userState.persistentDataStore.getBlockedRatings()) { @@ -969,7 +966,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); userState.persistentDataStore.addBlockedRating( TvContentRating.unflattenFromString(rating)); } @@ -986,7 +983,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); userState.persistentDataStore.removeBlockedRating( TvContentRating.unflattenFromString(rating)); } @@ -1013,7 +1010,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); TvInputState inputState = userState.inputMap.get(inputId); if (inputState == null) { Slog.w(TAG, "Failed to find input state for inputId=" + inputId); @@ -1084,7 +1081,7 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); if (userState.mainSessionToken == sessionToken) { return; } @@ -1211,7 +1208,7 @@ public final class TvInputManagerService extends SystemService { return; } - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); SessionState sessionState = userState.sessionStateMap.get(sessionToken); // Log the start of watch. @@ -1639,7 +1636,7 @@ public final class TvInputManagerService extends SystemService { try { String hardwareInputId = null; synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); if (userState.inputMap.get(inputId) == null) { Slog.e(TAG, "input not found for " + inputId); return false; @@ -1669,7 +1666,7 @@ public final class TvInputManagerService extends SystemService { userId, "isSingleSessionActive"); try { synchronized (mLock) { - UserState userState = getUserStateLocked(resolvedUserId); + UserState userState = getOrCreateUserStateLocked(resolvedUserId); if (userState.sessionStateMap.size() == 1) { return true; } else if (userState.sessionStateMap.size() == 2) { @@ -1710,7 +1707,7 @@ public final class TvInputManagerService extends SystemService { for (int i = 0; i < mUserStates.size(); i++) { int userId = mUserStates.keyAt(i); - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); pw.println("UserState (" + userId + "):"); pw.increaseIndent(); @@ -1864,7 +1861,7 @@ public final class TvInputManagerService extends SystemService { @Override public void binderDied() { synchronized (mLock) { - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); // DO NOT remove the client state of clientStateMap in this method. It will be // removed in releaseSessionLocked(). ClientState clientState = userState.clientStateMap.get(clientToken); @@ -1945,7 +1942,7 @@ public final class TvInputManagerService extends SystemService { } } // If there are any other sessions based on this session, they should be released. - UserState userState = getUserStateLocked(userId); + UserState userState = getOrCreateUserStateLocked(userId); for (SessionState sessionState : userState.sessionStateMap.values()) { if (sessionToken == sessionState.hardwareSessionToken) { releaseSessionLocked(sessionState.sessionToken, Process.SYSTEM_UID, @@ -1977,7 +1974,7 @@ public final class TvInputManagerService extends SystemService { Slog.d(TAG, "onServiceConnected(component=" + component + ")"); } synchronized (mLock) { - UserState userState = getUserStateLocked(mUserId); + UserState userState = getOrCreateUserStateLocked(mUserId); ServiceState serviceState = userState.serviceStateMap.get(mComponent); serviceState.service = ITvInputService.Stub.asInterface(service); @@ -2038,7 +2035,7 @@ public final class TvInputManagerService extends SystemService { + mComponent + " (expected), " + component + " (actual)."); } synchronized (mLock) { - UserState userState = getUserStateLocked(mUserId); + UserState userState = getOrCreateUserStateLocked(mUserId); ServiceState serviceState = userState.serviceStateMap.get(mComponent); if (serviceState != null) { serviceState.reconnecting = true; @@ -2163,7 +2160,7 @@ public final class TvInputManagerService extends SystemService { } IBinder clientToken = mSessionState.client.asBinder(); - UserState userState = getUserStateLocked(mSessionState.userId); + UserState userState = getOrCreateUserStateLocked(mSessionState.userId); ClientState clientState = userState.clientStateMap.get(clientToken); if (clientState == null) { clientState = new ClientState(clientToken, mSessionState.userId); @@ -2509,7 +2506,7 @@ public final class TvInputManagerService extends SystemService { @Override public void onHardwareDeviceAdded(TvInputHardwareInfo info) { synchronized (mLock) { - UserState userState = getUserStateLocked(mCurrentUserId); + UserState userState = getOrCreateUserStateLocked(mCurrentUserId); // Broadcast the event to all hardware inputs. for (ServiceState serviceState : userState.serviceStateMap.values()) { if (!serviceState.isHardware || serviceState.service == null) continue; @@ -2525,7 +2522,7 @@ public final class TvInputManagerService extends SystemService { @Override public void onHardwareDeviceRemoved(TvInputHardwareInfo info) { synchronized (mLock) { - UserState userState = getUserStateLocked(mCurrentUserId); + UserState userState = getOrCreateUserStateLocked(mCurrentUserId); // Broadcast the event to all hardware inputs. for (ServiceState serviceState : userState.serviceStateMap.values()) { if (!serviceState.isHardware || serviceState.service == null) continue; @@ -2541,7 +2538,7 @@ public final class TvInputManagerService extends SystemService { @Override public void onHdmiDeviceAdded(HdmiDeviceInfo deviceInfo) { synchronized (mLock) { - UserState userState = getUserStateLocked(mCurrentUserId); + UserState userState = getOrCreateUserStateLocked(mCurrentUserId); // Broadcast the event to all hardware inputs. for (ServiceState serviceState : userState.serviceStateMap.values()) { if (!serviceState.isHardware || serviceState.service == null) continue; @@ -2557,7 +2554,7 @@ public final class TvInputManagerService extends SystemService { @Override public void onHdmiDeviceRemoved(HdmiDeviceInfo deviceInfo) { synchronized (mLock) { - UserState userState = getUserStateLocked(mCurrentUserId); + UserState userState = getOrCreateUserStateLocked(mCurrentUserId); // Broadcast the event to all hardware inputs. for (ServiceState serviceState : userState.serviceStateMap.values()) { if (!serviceState.isHardware || serviceState.service == null) continue; diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index a57463c21f48..7bd0635a814a 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -559,6 +559,7 @@ public class AppTransition implements Dump { set.addAnimation(clipAnimTB); set.addAnimation(translateY); set.addAnimation(alpha); + set.setZAdjustment(Animation.ZORDER_TOP); set.initialize(appWidth, appHeight, appWidth, appHeight); anim = set; } else { diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 76301781f4d6..85a962471656 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -500,7 +500,13 @@ public class WindowAnimator { mPostKeyguardExitAnimation.getStartOffset(), mPostKeyguardExitAnimation.getDuration()); mKeyguardGoingAway = false; - } else if (mPostKeyguardExitAnimation.hasEnded()) { + } + // mPostKeyguardExitAnimation might either be ended normally, cancelled, or "orphaned", + // meaning that the window it was running on was removed. We check for hasEnded() for + // ended normally and cancelled case, and check the time for the "orphaned" case. + else if (mPostKeyguardExitAnimation.hasEnded() + || mCurrentTime - mPostKeyguardExitAnimation.getStartTime() + > mPostKeyguardExitAnimation.getDuration()) { // Done with the animation, reset. if (DEBUG_KEYGUARD) Slog.v(TAG, "Done with Keyguard exit animations."); mPostKeyguardExitAnimation = null; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index bc63c69c4184..26e75bd30df1 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2658,6 +2658,16 @@ public class WindowManagerService extends IWindowManager.Stub return disabled; } + boolean isSecureLocked(WindowState w) { + if ((w.mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) { + return true; + } + if (isScreenCaptureDisabledLocked(UserHandle.getUserId(w.mOwnerUid))) { + return true; + } + return false; + } + /** * Set mScreenCaptureDisabled for specific user */ @@ -2730,10 +2740,10 @@ public class WindowManagerService extends IWindowManager.Stub wasVisible = win.isWinVisibleLw(); if (wasVisible) { - int transit = WindowManagerPolicy.TRANSIT_EXIT; - if (win.mAttrs.type == TYPE_APPLICATION_STARTING) { - transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE; - } + final int transit = (!startingWindow) + ? WindowManagerPolicy.TRANSIT_EXIT + : WindowManagerPolicy.TRANSIT_PREVIEW_DONE; + // Try starting an animation. if (win.mWinAnimator.applyAnimationLocked(transit, false)) { win.mExiting = true; @@ -2745,12 +2755,13 @@ public class WindowManagerService extends IWindowManager.Stub } } final AppWindowToken appToken = win.mAppToken; + final boolean isAnimating = win.mWinAnimator.isAnimating(); // The starting window is the last window in this app token and it isn't animating. // Allow it to be removed now as there is no additional window or animation that will // trigger its removal. final boolean lastWinStartingNotAnimating = startingWindow && appToken!= null - && appToken.allAppWindows.size() == 1 && !win.mWinAnimator.isAnimating(); - if (!lastWinStartingNotAnimating && (win.mExiting || win.mWinAnimator.isAnimating())) { + && appToken.allAppWindows.size() == 1 && !isAnimating; + if (!lastWinStartingNotAnimating && (win.mExiting || isAnimating)) { // The exit animation is running... wait for it! win.mExiting = true; win.mRemoveOnExit = true; @@ -3168,6 +3179,9 @@ public class WindowManagerService extends IWindowManager.Stub boolean wallpaperMayMove = win.mViewVisibility != viewVisibility && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0; wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0; + if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceControl != null) { + winAnimator.mSurfaceControl.setSecure(isSecureLocked(win)); + } win.mRelayoutCalled = true; final int oldVisibility = win.mViewVisibility; @@ -4527,7 +4541,10 @@ public class WindowManagerService extends IWindowManager.Stub } wtoken.willBeHidden = false; - if (wtoken.hidden == visible) { + // Allow for state changes and animation to be applied if token is transitioning + // visibility state or the token was marked as hidden and is exiting before we had a chance + // to play the transition animation. + if (wtoken.hidden == visible || (wtoken.hidden && wtoken.mIsExiting)) { boolean changed = false; if (DEBUG_APP_TRANSITIONS) Slog.v( TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden @@ -10011,7 +10028,7 @@ public class WindowManagerService extends IWindowManager.Stub w.mContentChanged = false; // Moved from updateWindowsAndWallpaperLocked(). - if (w.mHasSurface && !w.isHiddenFromUserLocked()) { + if (w.mHasSurface) { // Take care of the window being ready to display. final boolean committed = winAnimator.commitFinishDrawingLocked(); @@ -10025,20 +10042,20 @@ public class WindowManagerService extends IWindowManager.Stub WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; if (DEBUG_LAYOUT_REPEATS) { debugLayoutRepeats( - "dream and commitFinishDrawingLocked true", - displayContent.pendingLayoutChanges); + "dream and commitFinishDrawingLocked true", + displayContent.pendingLayoutChanges); } } if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) { if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, - "First draw done in potential wallpaper target " + w); + "First draw done in potential wallpaper target " + w); mInnerFields.mWallpaperMayChange = true; displayContent.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; if (DEBUG_LAYOUT_REPEATS) { debugLayoutRepeats( - "wallpaper and commitFinishDrawingLocked true", - displayContent.pendingLayoutChanges); + "wallpaper and commitFinishDrawingLocked true", + displayContent.pendingLayoutChanges); } } } @@ -10046,52 +10063,49 @@ public class WindowManagerService extends IWindowManager.Stub winAnimator.setSurfaceBoundariesLocked(recoveringMemory); } - // Check the draw state of the window, but only if it is visible to the user. - if (!w.isHiddenFromUserLocked()) { - final AppWindowToken atoken = w.mAppToken; - if (DEBUG_STARTING_WINDOW && atoken != null - && w == atoken.startingWindow) { - Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" - + w.isOnScreen() + " allDrawn=" + atoken.allDrawn - + " freezingScreen=" + atoken.mAppAnimator.freezingScreen); + final AppWindowToken atoken = w.mAppToken; + if (DEBUG_STARTING_WINDOW && atoken != null + && w == atoken.startingWindow) { + Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + + w.isOnScreen() + " allDrawn=" + atoken.allDrawn + + " freezingScreen=" + atoken.mAppAnimator.freezingScreen); + } + if (atoken != null + && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) { + if (atoken.lastTransactionSequence != mTransactionSequence) { + atoken.lastTransactionSequence = mTransactionSequence; + atoken.numInterestingWindows = atoken.numDrawnWindows = 0; + atoken.startingDisplayed = false; } - if (atoken != null - && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) { - if (atoken.lastTransactionSequence != mTransactionSequence) { - atoken.lastTransactionSequence = mTransactionSequence; - atoken.numInterestingWindows = atoken.numDrawnWindows = 0; - atoken.startingDisplayed = false; - } - if ((w.isOnScreenIgnoringKeyguard() - || winAnimator.mAttrType == TYPE_BASE_APPLICATION) - && !w.mExiting && !w.mDestroying) { - if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { - Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() - + ", isAnimating=" + winAnimator.isAnimating()); - if (!w.isDrawnLw()) { - Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl - + " pv=" + w.mPolicyVisibility - + " mDrawState=" + winAnimator.drawStateToString() - + " ah=" + w.mAttachedHidden - + " th=" + atoken.hiddenRequested - + " a=" + winAnimator.mAnimating); - } + if ((w.isOnScreenIgnoringKeyguard() + || winAnimator.mAttrType == TYPE_BASE_APPLICATION) + && !w.mExiting && !w.mDestroying) { + if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { + Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() + + ", isAnimating=" + winAnimator.isAnimating()); + if (!w.isDrawnLw()) { + Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl + + " pv=" + w.mPolicyVisibility + + " mDrawState=" + winAnimator.drawStateToString() + + " ah=" + w.mAttachedHidden + + " th=" + atoken.hiddenRequested + + " a=" + winAnimator.mAnimating); } - if (w != atoken.startingWindow) { - if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) { - atoken.numInterestingWindows++; - if (w.isDrawnLw()) { - atoken.numDrawnWindows++; - if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, - "tokenMayBeDrawn: " + atoken - + " freezingScreen=" + atoken.mAppAnimator.freezingScreen - + " mAppFreezing=" + w.mAppFreezing); - updateAllDrawn = true; - } + } + if (w != atoken.startingWindow) { + if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) { + atoken.numInterestingWindows++; + if (w.isDrawnLw()) { + atoken.numDrawnWindows++; + if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, + "tokenMayBeDrawn: " + atoken + + " freezingScreen=" + atoken.mAppAnimator.freezingScreen + + " mAppFreezing=" + w.mAppFreezing); + updateAllDrawn = true; } - } else if (w.isDrawnLw()) { - atoken.startingDisplayed = true; } + } else if (w.isDrawnLw()) { + atoken.startingDisplayed = true; } } } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 96cd14bbac89..3ac6bba8df3c 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -788,11 +788,7 @@ class WindowStateAnimator { int flags = SurfaceControl.HIDDEN; final WindowManager.LayoutParams attrs = w.mAttrs; - if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) { - flags |= SurfaceControl.SECURE; - } - - if (mService.isScreenCaptureDisabledLocked(UserHandle.getUserId(mWin.mOwnerUid))) { + if (mService.isSecureLocked(w)) { flags |= SurfaceControl.SECURE; } @@ -1277,6 +1273,7 @@ class WindowStateAnimator { if (displayContent == null) { return; } + final DisplayInfo displayInfo = displayContent.getDisplayInfo(); // Need to recompute a new system decor rect each time. if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) { @@ -1286,7 +1283,6 @@ class WindowStateAnimator { } else if (!w.isDefaultDisplay()) { // On a different display there is no system decor. Crop the window // by the screen boundaries. - final DisplayInfo displayInfo = displayContent.getDisplayInfo(); w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height()); w.mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top, displayInfo.logicalWidth - w.mCompatFrame.left, @@ -1308,9 +1304,11 @@ class WindowStateAnimator { applyDecorRect(w.mDecorFrame); } - // By default, the clip rect is the system decor if the transformation doesn't specify one. + final boolean fullscreen = w.isFullscreen(displayInfo.appWidth, displayInfo.appHeight); final Rect clipRect = mTmpClipRect; - clipRect.set((mHasClipRect) ? mClipRect : w.mSystemDecorRect); + // We use the clip rect as provided by the tranformation for non-fullscreen windows to + // avoid premature clipping with the system decor rect. + clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : w.mSystemDecorRect); // Expand the clip rect for surface insets. final WindowManager.LayoutParams attrs = w.mAttrs; @@ -1319,6 +1317,13 @@ class WindowStateAnimator { clipRect.right += attrs.surfaceInsets.right; clipRect.bottom += attrs.surfaceInsets.bottom; + if (mHasClipRect && fullscreen) { + // We intersect the clip rect specified by the transformation with the expanded system + // decor rect to prevent artifacts from drawing during animation if the transformation + // clip rect extends outside the system decor rect. + clipRect.intersect(mClipRect); + } + // The clip rect was generated assuming (0,0) as the window origin, // so we need to translate to match the actual surface coordinates. clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top); @@ -1667,6 +1672,8 @@ class WindowStateAnimator { // This must be called while inside a transaction. boolean performShowLocked() { if (mWin.isHiddenFromUserLocked()) { + if (DEBUG_VISIBILITY) Slog.w(TAG, "hiding " + mWin + ", belonging to " + mWin.mOwnerUid); + mWin.hideLw(false); return false; } if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW && diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp index e257e89b3300..dfc5ef6ec366 100644 --- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp +++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp @@ -59,9 +59,9 @@ static void wakeup_callback(bool success) } } -static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobjectArray outReasons) +static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobject outBuf) { - if (outReasons == NULL) { + if (outBuf == NULL) { jniThrowException(env, "java/lang/NullPointerException", "null argument"); return -1; } @@ -99,11 +99,11 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobjectArray outReasons return -1; } - ALOGV("Reading wakeup reasons"); + char* mergedreason = (char*)env->GetDirectBufferAddress(outBuf); + int remainreasonlen = (int)env->GetDirectBufferCapacity(outBuf); - char mergedreason[MAX_REASON_SIZE]; + ALOGV("Reading wakeup reasons"); char* mergedreasonpos = mergedreason; - int remainreasonlen = MAX_REASON_SIZE; char reasonline[128]; int i = 0; while (fgets(reasonline, sizeof(reasonline), fp) != NULL) { @@ -161,21 +161,17 @@ static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jobjectArray outReasons ALOGV("Got %d reasons", i); if (i > 0) { *mergedreasonpos = 0; - ScopedLocalRef<jstring> reasonString(env, env->NewStringUTF(mergedreason)); - env->SetObjectArrayElement(outReasons, 0, reasonString.get()); - i = 1; } if (fclose(fp) != 0) { ALOGE("Failed to close %s", LAST_RESUME_REASON); return -1; } - - return i; + return mergedreasonpos - mergedreason; } static JNINativeMethod method_table[] = { - { "nativeWaitWakeup", "([Ljava/lang/String;)I", (void*)nativeWaitWakeup }, + { "nativeWaitWakeup", "(Ljava/nio/ByteBuffer;)I", (void*)nativeWaitWakeup }, }; int register_android_server_BatteryStatsService(JNIEnv *env) diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index f3edbd1db281..e29d0a94610c 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -27,6 +27,8 @@ #include "JNIHelp.h" #include "jni.h" +#include <atomic> +#include <cinttypes> #include <limits.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/Log.h> @@ -56,6 +58,8 @@ #include "com_android_server_input_InputApplicationHandle.h" #include "com_android_server_input_InputWindowHandle.h" +#define INDENT " " + namespace android { // The exponent used to calculate the pointer speed scaling factor. @@ -126,6 +130,10 @@ inline static T max(const T& a, const T& b) { return a > b ? a : b; } +static inline const char* toString(bool value) { + return value ? "true" : "false"; +} + static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env, const sp<InputApplicationHandle>& inputApplicationHandle) { if (inputApplicationHandle == NULL) { @@ -262,7 +270,7 @@ private: wp<PointerController> pointerController; } mLocked; - volatile bool mInteractive; + std::atomic<bool> mInteractive; void updateInactivityTimeoutLocked(const sp<PointerController>& controller); void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags); @@ -292,6 +300,7 @@ NativeInputManager::NativeInputManager(jobject contextObj, mLocked.pointerGesturesEnabled = true; mLocked.showTouches = false; } + mInteractive = true; sp<EventHub> eventHub = new EventHub(); mInputManager = new InputManager(eventHub, this, this); @@ -305,6 +314,21 @@ NativeInputManager::~NativeInputManager() { } void NativeInputManager::dump(String8& dump) { + dump.append("Input Manager State:\n"); + { + dump.appendFormat(INDENT "Interactive: %s\n", toString(mInteractive.load())); + } + { + AutoMutex _l(mLock); + dump.appendFormat(INDENT "System UI Visibility: 0x%0" PRIx32 "\n", + mLocked.systemUiVisibility); + dump.appendFormat(INDENT "Pointer Speed: %" PRId32 "\n", mLocked.pointerSpeed); + dump.appendFormat(INDENT "Pointer Gestures Enabled: %s\n", + toString(mLocked.pointerGesturesEnabled)); + dump.appendFormat(INDENT "Show Touches: %s\n", toString(mLocked.showTouches)); + } + dump.append("\n"); + mInputManager->getReader()->dump(dump); dump.append("\n"); @@ -830,7 +854,8 @@ void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent, // - Ignore untrusted events and pass them along. // - Ask the window manager what to do with normal events and trusted injected events. // - For normal events wake and brighten the screen if currently off or dim. - if (mInteractive) { + bool interactive = mInteractive.load(); + if (interactive) { policyFlags |= POLICY_FLAG_INTERACTIVE; } if ((policyFlags & POLICY_FLAG_TRUSTED)) { @@ -854,7 +879,7 @@ void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent, handleInterceptActions(wmActions, when, /*byref*/ policyFlags); } else { - if (mInteractive) { + if (interactive) { policyFlags |= POLICY_FLAG_PASS_TO_USER; } } @@ -866,7 +891,8 @@ void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& p // - No special filtering for injected events required at this time. // - Filter normal events based on screen state. // - For normal events brighten (but do not wake) the screen if currently dim. - if (mInteractive) { + bool interactive = mInteractive.load(); + if (interactive) { policyFlags |= POLICY_FLAG_INTERACTIVE; } if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) { @@ -885,7 +911,7 @@ void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& p handleInterceptActions(wmActions, when, /*byref*/ policyFlags); } } else { - if (mInteractive) { + if (interactive) { policyFlags |= POLICY_FLAG_PASS_TO_USER; } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 5d05f3296fe0..cd2885b9fdd4 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1277,11 +1277,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { && !hasUserSetupCompleted(userId); if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { - if (ownsDevice || (userId == UserHandle.USER_OWNER && ownsInitialization)) { + if ((userId == UserHandle.USER_OWNER && (ownsDevice || ownsInitialization)) + || (ownsDevice && ownsProfile)) { return true; } } else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { - if (ownsDevice || ownsProfile || ownsInitialization) { + if ((userId == UserHandle.USER_OWNER && ownsDevice) || ownsProfile + || ownsInitialization) { return true; } } else { @@ -4140,6 +4142,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } mDeviceOwner.writeOwnerFile(); updateDeviceOwnerLocked(); + Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED); + + ident = Binder.clearCallingIdentity(); + try { + mContext.sendBroadcastAsUser(intent, UserHandle.OWNER); + } finally { + Binder.restoreCallingIdentity(ident); + } return true; } } @@ -4236,6 +4246,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { throw new IllegalArgumentException("Invalid component name " + initializer + " for device initializer"); } + boolean isInitializerSystemApp; + try { + isInitializerSystemApp = isSystemApp(AppGlobals.getPackageManager(), + initializer.getPackageName(), Binder.getCallingUserHandle().getIdentifier()); + } catch (RemoteException | IllegalArgumentException e) { + isInitializerSystemApp = false; + Slog.e(LOG_TAG, "Fail to check if device initialzer is system app.", e); + } + if (!isInitializerSystemApp) { + throw new IllegalArgumentException("Only system app can be set as device initializer."); + } synchronized (this) { enforceCanSetDeviceInitializer(who); @@ -6415,7 +6436,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 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) { + if (targetSdkVersion < android.os.Build.VERSION_CODES.M) { return false; } final PackageManager packageManager = mContext.getPackageManager(); diff --git a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java index ba1231f7530c..da1df1accdb0 100644 --- a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java +++ b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java @@ -21,12 +21,13 @@ import android.net.DhcpResults; import android.net.LinkAddress; import android.system.OsConstants; import android.test.suitebuilder.annotation.SmallTest; -import junit.framework.TestCase; +import com.android.internal.util.HexDump; import java.net.Inet4Address; import java.nio.ByteBuffer; import java.util.ArrayList; +import junit.framework.TestCase; import libcore.util.HexEncoding; import static android.net.dhcp.DhcpPacket.*; @@ -370,4 +371,69 @@ public class DhcpPacketTest extends TestCase { assertDhcpResults("172.17.152.118/16", "172.17.1.1", "172.17.1.1", null, "1.1.1.1", null, 43200, false, dhcpResults); } + + @SmallTest + public void testBug2111() throws Exception { + final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode(( + // IP header. + "4500014c00000000ff119beac3eaf3880a3f5d04" + + // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation). + "0043004401387464" + + // BOOTP header. + "0201060002554812000a0000000000000a3f5d040000000000000000" + + // MAC address. + "00904c00000000000000000000000000" + + // Server name. + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + // File. + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + // Options. + "638253633501023604c00002fe33040000bfc60104fffff00003040a3f50010608c0000201c0000202" + + "0f0f646f6d61696e3132332e636f2e756b0000000000ff00000000" + ).toCharArray(), false)); + + DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3); + assertTrue(offerPacket instanceof DhcpOfferPacket); + DhcpResults dhcpResults = offerPacket.toDhcpResults(); + assertDhcpResults("10.63.93.4/20", "10.63.80.1", "192.0.2.1,192.0.2.2", + "domain123.co.uk", "192.0.2.254", null, 49094, false, dhcpResults); + } + + @SmallTest + public void testBug2136() throws Exception { + final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode(( + // Ethernet header. + "bcf5ac000000d0c7890000000800" + + // IP header. + "4500014c00000000ff119beac3eaf3880a3f5d04" + + // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation). + "0043004401387574" + + // BOOTP header. + "0201060163339a3000050000000000000a209ecd0000000000000000" + + // MAC address. + "bcf5ac00000000000000000000000000" + + // Server name. + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + // File. + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + // Options. + "6382536335010236040a20ff80330400001c200104fffff00003040a20900106089458413494584135" + + "0f0b6c616e63732e61632e756b000000000000000000ff00000000" + ).toCharArray(), false)); + + DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2); + assertTrue(offerPacket instanceof DhcpOfferPacket); + assertEquals("BCF5AC000000", HexDump.toHexString(offerPacket.getClientMac())); + DhcpResults dhcpResults = offerPacket.toDhcpResults(); + assertDhcpResults("10.32.158.205/20", "10.32.144.1", "148.88.65.52,148.88.65.53", + "lancs.ac.uk", "10.32.255.128", null, 7200, false, dhcpResults); + } } diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java index 999496448706..696f106bceca 100644 --- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java @@ -81,6 +81,7 @@ import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import android.util.LogPrinter; +import com.android.server.connectivity.NetworkAgentInfo; import com.android.server.connectivity.NetworkMonitor; import org.mockito.ArgumentCaptor; @@ -118,7 +119,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { private INetworkPolicyManager mPolicyService; private BroadcastInterceptingContext mServiceContext; - private ConnectivityService mService; + private WrappedConnectivityService mService; private ConnectivityManager mCm; private MockNetworkAgent mWiFiNetworkAgent; private MockNetworkAgent mCellNetworkAgent; @@ -148,6 +149,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { } private class MockNetworkAgent { + private final WrappedNetworkMonitor mWrappedNetworkMonitor; private final NetworkInfo mNetworkInfo; private final NetworkCapabilities mNetworkCapabilities; private final Thread mThread; @@ -172,6 +174,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { throw new UnsupportedOperationException("unimplemented network type"); } final ConditionVariable initComplete = new ConditionVariable(); + final ConditionVariable networkMonitorAvailable = mService.getNetworkMonitorCreatedCV(); mThread = new Thread() { public void run() { Looper.prepare(); @@ -186,6 +189,8 @@ public class ConnectivityServiceTest extends AndroidTestCase { }; mThread.start(); waitFor(initComplete); + waitFor(networkMonitorAvailable); + mWrappedNetworkMonitor = mService.getLastCreatedWrappedNetworkMonitor(); } public void adjustScore(int change) { @@ -211,44 +216,46 @@ public class ConnectivityServiceTest extends AndroidTestCase { assertEquals(mNetworkInfo.getDetailedState(), DetailedState.IDLE); assertFalse(mNetworkCapabilities.hasCapability(NET_CAPABILITY_INTERNET)); - // To pretend network is validated, we transition it to the CONNECTED state without - // NET_CAPABILITY_INTERNET so NetworkMonitor doesn't bother trying to validate and - // just rubber stamps it as validated. Afterwards we add NET_CAPABILITY_INTERNET so - // the network can satisfy the default request. NetworkCallback callback = null; final ConditionVariable validatedCv = new ConditionVariable(); if (validated) { - // If we connect a network without INTERNET capability, it'll get reaped. - // Prevent the reaping by adding a NetworkRequest. + mWrappedNetworkMonitor.gen204ProbeResult = 204; NetworkRequest request = new NetworkRequest.Builder() .addTransportType(mNetworkCapabilities.getTransportTypes()[0]) .build(); callback = new NetworkCallback() { public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { - if (networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { + if (network.equals(getNetwork()) && + networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { validatedCv.open(); } } }; - mCm.requestNetwork(request, callback); - } else { - mNetworkCapabilities.addCapability(NET_CAPABILITY_INTERNET); - mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); + mCm.registerNetworkCallback(request, callback); } + addCapability(NET_CAPABILITY_INTERNET); connectWithoutInternet(); if (validated) { // Wait for network to validate. waitFor(validatedCv); - mNetworkCapabilities.addCapability(NET_CAPABILITY_INTERNET); - mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); + mWrappedNetworkMonitor.gen204ProbeResult = 500; } if (callback != null) mCm.unregisterNetworkCallback(callback); } + public void connectWithCaptivePortal() { + mWrappedNetworkMonitor.gen204ProbeResult = 200; + connect(false); + waitFor(new Criteria() { public boolean get() { + NetworkCapabilities caps = mCm.getNetworkCapabilities(getNetwork()); + return caps != null && caps.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL);} }); + mWrappedNetworkMonitor.gen204ProbeResult = 500; + } + public void disconnect() { mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null); mNetworkAgent.sendNetworkInfo(mNetworkInfo); @@ -261,14 +268,18 @@ public class ConnectivityServiceTest extends AndroidTestCase { public ConditionVariable getDisconnectedCV() { return mDisconnected; } + + public WrappedNetworkMonitor getWrappedNetworkMonitor() { + return mWrappedNetworkMonitor; + } } private static class MockNetworkFactory extends NetworkFactory { - final ConditionVariable mNetworkStartedCV = new ConditionVariable(); - final ConditionVariable mNetworkStoppedCV = new ConditionVariable(); - final ConditionVariable mNetworkRequestedCV = new ConditionVariable(); - final ConditionVariable mNetworkReleasedCV = new ConditionVariable(); - final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); + private final ConditionVariable mNetworkStartedCV = new ConditionVariable(); + private final ConditionVariable mNetworkStoppedCV = new ConditionVariable(); + private final ConditionVariable mNetworkRequestedCV = new ConditionVariable(); + private final ConditionVariable mNetworkReleasedCV = new ConditionVariable(); + private final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); public MockNetworkFactory(Looper looper, Context context, String logTag, NetworkCapabilities filter) { @@ -328,7 +339,26 @@ public class ConnectivityServiceTest extends AndroidTestCase { } } + // NetworkMonitor implementation allowing overriding of Internet connectivity probe result. + private class WrappedNetworkMonitor extends NetworkMonitor { + // HTTP response code fed back to NetworkMonitor for Internet connectivity probe. + public int gen204ProbeResult = 500; + + public WrappedNetworkMonitor(Context context, Handler handler, + NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest) { + super(context, handler, networkAgentInfo, defaultRequest); + } + + @Override + protected int isCaptivePortal() { + return gen204ProbeResult; + } + } + private class WrappedConnectivityService extends ConnectivityService { + private final ConditionVariable mNetworkMonitorCreated = new ConditionVariable(); + private WrappedNetworkMonitor mLastCreatedNetworkMonitor; + public WrappedConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager) { super(context, netManager, statsService, policyManager); @@ -360,6 +390,25 @@ public class ConnectivityServiceTest extends AndroidTestCase { return netId; } } + + @Override + public NetworkMonitor createNetworkMonitor(Context context, Handler handler, + NetworkAgentInfo nai, NetworkRequest defaultRequest) { + final WrappedNetworkMonitor monitor = new WrappedNetworkMonitor(context, handler, nai, + defaultRequest); + mLastCreatedNetworkMonitor = monitor; + mNetworkMonitorCreated.open(); + return monitor; + } + + public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() { + return mLastCreatedNetworkMonitor; + } + + public ConditionVariable getNetworkMonitorCreatedCV() { + mNetworkMonitorCreated.close(); + return mNetworkMonitorCreated; + } } private interface Criteria { @@ -414,7 +463,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { mService = new WrappedConnectivityService( mServiceContext, mNetManager, mStatsService, mPolicyService); mService.systemReady(); - mCm = new ConnectivityManager(mService); + mCm = new ConnectivityManager(getContext(), mService); } private int transportToLegacyType(int transport) { @@ -586,29 +635,29 @@ public class ConnectivityServiceTest extends AndroidTestCase { @LargeTest public void testUnlingeringDoesNotValidate() throws Exception { - // Test bringing up unvalidated cellular. - mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); + // Test bringing up unvalidated WiFi. + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); ConditionVariable cv = waitForConnectivityBroadcasts(1); - mCellNetworkAgent.connect(false); + mWiFiNetworkAgent.connect(false); waitFor(cv); - verifyActiveNetwork(TRANSPORT_CELLULAR); - assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( + verifyActiveNetwork(TRANSPORT_WIFI); + assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( NET_CAPABILITY_VALIDATED)); - // Test bringing up validated WiFi. - mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + // Test bringing up validated cellular. + mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); cv = waitForConnectivityBroadcasts(2); - mWiFiNetworkAgent.connect(true); + mCellNetworkAgent.connect(true); waitFor(cv); - verifyActiveNetwork(TRANSPORT_WIFI); - assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( + verifyActiveNetwork(TRANSPORT_CELLULAR); + assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( NET_CAPABILITY_VALIDATED)); - // Test WiFi disconnect. + // Test cellular disconnect. cv = waitForConnectivityBroadcasts(2); - mWiFiNetworkAgent.disconnect(); + mCellNetworkAgent.disconnect(); waitFor(cv); - verifyActiveNetwork(TRANSPORT_CELLULAR); + verifyActiveNetwork(TRANSPORT_WIFI); // Unlingering a network should not cause it to be marked as validated. - assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( + assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( NET_CAPABILITY_VALIDATED)); } @@ -846,12 +895,8 @@ public class ConnectivityServiceTest extends AndroidTestCase { 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()); @@ -868,12 +913,8 @@ public class ConnectivityServiceTest extends AndroidTestCase { 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); @@ -1088,6 +1129,63 @@ public class ConnectivityServiceTest extends AndroidTestCase { verifyActiveNetwork(TRANSPORT_CELLULAR); } + @LargeTest + public void testCaptivePortal() { + final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); + final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() + .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build(); + mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback); + + final TestNetworkCallback validatedCallback = new TestNetworkCallback(); + final NetworkRequest validatedRequest = new NetworkRequest.Builder() + .addCapability(NET_CAPABILITY_VALIDATED).build(); + mCm.registerNetworkCallback(validatedRequest, validatedCallback); + ConditionVariable validatedCv = validatedCallback.getConditionVariable(); + + // Bring up a network with a captive portal. + // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. + ConditionVariable cv = captivePortalCallback.getConditionVariable(); + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + mWiFiNetworkAgent.connectWithCaptivePortal(); + waitFor(cv); + assertEquals(CallbackState.AVAILABLE, captivePortalCallback.getLastCallback()); + + // Take down network. + // Expect onLost callback. + cv = captivePortalCallback.getConditionVariable(); + mWiFiNetworkAgent.disconnect(); + waitFor(cv); + assertEquals(CallbackState.LOST, captivePortalCallback.getLastCallback()); + + // Bring up a network with a captive portal. + // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. + cv = captivePortalCallback.getConditionVariable(); + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + mWiFiNetworkAgent.connectWithCaptivePortal(); + waitFor(cv); + assertEquals(CallbackState.AVAILABLE, captivePortalCallback.getLastCallback()); + + // Make captive portal disappear then revalidate. + // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. + cv = captivePortalCallback.getConditionVariable(); + mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204; + mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true); + waitFor(cv); + assertEquals(CallbackState.LOST, captivePortalCallback.getLastCallback()); + + // Expect NET_CAPABILITY_VALIDATED onAvailable callback. + waitFor(validatedCv); + assertEquals(CallbackState.AVAILABLE, validatedCallback.getLastCallback()); + + // Break network connectivity. + // Expect NET_CAPABILITY_VALIDATED onLost callback. + validatedCv = validatedCallback.getConditionVariable(); + mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 500; + mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false); + waitFor(validatedCv); + assertEquals(CallbackState.LOST, validatedCallback.getLastCallback()); + } + // @Override // public void tearDown() throws Exception { // super.tearDown(); diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java index 4498b84aae09..f8ae03f1107c 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java +++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java @@ -21,6 +21,7 @@ import android.app.usage.UsageStatsManager; import android.os.Build; import android.util.AtomicFile; import android.util.Slog; +import android.util.TimeUtils; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -191,7 +192,11 @@ class UsageStatsDatabase { for (File f : files) { final AtomicFile af = new AtomicFile(f); - mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af); + try { + mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af); + } catch (IOException e) { + Slog.e(TAG, "failed to index file: " + f, e); + } } } } @@ -273,14 +278,21 @@ class UsageStatsDatabase { public void onTimeChanged(long timeDiffMillis) { synchronized (mLock) { + StringBuilder logBuilder = new StringBuilder(); + logBuilder.append("Time changed by "); + TimeUtils.formatDuration(timeDiffMillis, logBuilder); + logBuilder.append("."); + + int filesDeleted = 0; + int filesMoved = 0; + for (TimeSparseArray<AtomicFile> files : mSortedStatFiles) { final int fileCount = files.size(); for (int i = 0; i < fileCount; i++) { final AtomicFile file = files.valueAt(i); final long newTime = files.keyAt(i) + timeDiffMillis; if (newTime < 0) { - Slog.i(TAG, "Deleting file " + file.getBaseFile().getAbsolutePath() - + " for it is in the future now."); + filesDeleted++; file.delete(); } else { try { @@ -295,14 +307,17 @@ class UsageStatsDatabase { } final File newFile = new File(file.getBaseFile().getParentFile(), newName); - Slog.i(TAG, "Moving file " + file.getBaseFile().getAbsolutePath() + " to " - + newFile.getAbsolutePath()); + filesMoved++; file.getBaseFile().renameTo(newFile); } } files.clear(); } + logBuilder.append(" files deleted: ").append(filesDeleted); + logBuilder.append(" files moved: ").append(filesMoved); + Slog.i(TAG, logBuilder.toString()); + // Now re-index the new files. indexFilesLocked(); } @@ -506,7 +521,14 @@ class UsageStatsDatabase { if (path.endsWith(BAK_SUFFIX)) { f = new File(path.substring(0, path.length() - BAK_SUFFIX.length())); } - long beginTime = UsageStatsXml.parseBeginTime(f); + + long beginTime; + try { + beginTime = UsageStatsXml.parseBeginTime(f); + } catch (IOException e) { + beginTime = 0; + } + if (beginTime < expiryTime) { new AtomicFile(f).delete(); } diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index b0a14c8ea591..a433ec45191c 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -42,6 +42,7 @@ import android.content.pm.UserInfo; import android.content.res.Configuration; import android.database.ContentObserver; import android.hardware.display.DisplayManager; +import android.net.NetworkScoreManager; import android.os.BatteryManager; import android.os.BatteryStats; import android.os.Binder; @@ -812,6 +813,10 @@ public class UsageStatsService extends SystemService implements return false; } + if (isActiveNetworkScorer(packageName)) { + return false; + } + if (mAppWidgetManager != null && mAppWidgetManager.isBoundWidgetPackage(packageName, userId)) { return false; @@ -847,6 +852,12 @@ public class UsageStatsService extends SystemService implements == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; } + private boolean isActiveNetworkScorer(String packageName) { + NetworkScoreManager nsm = (NetworkScoreManager) getContext().getSystemService( + Context.NETWORK_SCORE_SERVICE); + return packageName != null && packageName.equals(nsm.getActiveScorerPackage()); + } + void informListeners(String packageName, int userId, boolean isIdle) { for (AppIdleStateChangeListener listener : mPackageAccessListeners) { listener.onAppIdleStateChanged(packageName, userId, isIdle); diff --git a/services/usage/java/com/android/server/usage/UsageStatsXml.java b/services/usage/java/com/android/server/usage/UsageStatsXml.java index 186813ef703c..543f361f79e5 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsXml.java +++ b/services/usage/java/com/android/server/usage/UsageStatsXml.java @@ -33,11 +33,11 @@ public class UsageStatsXml { private static final String VERSION_ATTR = "version"; static final String CHECKED_IN_SUFFIX = "-c"; - public static long parseBeginTime(AtomicFile file) { + public static long parseBeginTime(AtomicFile file) throws IOException { return parseBeginTime(file.getBaseFile()); } - public static long parseBeginTime(File file) { + public static long parseBeginTime(File file) throws IOException { String name = file.getName(); // Eat as many occurrences of -c as possible. This is due to a bug where -c @@ -47,7 +47,12 @@ public class UsageStatsXml { while (name.endsWith(CHECKED_IN_SUFFIX)) { name = name.substring(0, name.length() - CHECKED_IN_SUFFIX.length()); } - return Long.parseLong(name); + + try { + return Long.parseLong(name); + } catch (NumberFormatException e) { + throw new IOException(e); + } } public static void read(AtomicFile file, IntervalStats statsOut) throws IOException { diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 653cbd860982..09e15a885bea 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -49,10 +49,8 @@ import com.android.internal.util.IndentingPrintWriter; import com.android.server.FgThread; import java.io.File; -import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.PrintWriter; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -122,6 +120,8 @@ public class UsbDeviceManager { // Request is cancelled if host does not configure device within 10 seconds. private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000; + private static final String BOOT_MODE_PROPERTY = "ro.bootmode"; + private UsbHandler mHandler; private boolean mBootCompleted; @@ -314,6 +314,9 @@ public class UsbDeviceManager { // Restore default functions. mCurrentFunctions = SystemProperties.get(USB_CONFIG_PROPERTY, UsbManager.USB_FUNCTION_NONE); + if (UsbManager.USB_FUNCTION_NONE.equals(mCurrentFunctions)) { + mCurrentFunctions = UsbManager.USB_FUNCTION_MTP; + } mCurrentFunctionsApplied = mCurrentFunctions.equals( SystemProperties.get(USB_STATE_PROPERTY)); mAdbEnabled = UsbManager.containsFunction(getDefaultFunctions(), @@ -398,6 +401,14 @@ public class UsbDeviceManager { return waitForState(config); } + private void setUsbDataUnlocked(boolean enable) { + if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked: " + enable); + mUsbDataUnlocked = enable; + updateUsbNotification(); + updateUsbStateBroadcast(); + setEnabledFunctions(mCurrentFunctions, true); + } + private void setAdbEnabled(boolean enable) { if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable); if (enable != mAdbEnabled) { @@ -468,7 +479,7 @@ public class UsbDeviceManager { functions = getDefaultFunctions(); } functions = applyAdbFunction(functions); - functions = applyUserRestrictions(functions); + functions = applyOemOverrideFunction(functions); if (!mCurrentFunctions.equals(functions) || !mCurrentFunctionsApplied || forceRestart) { @@ -499,13 +510,9 @@ public class UsbDeviceManager { return functions; } - private String applyUserRestrictions(String functions) { + private boolean isUsbTransferAllowed() { UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) { - functions = UsbManager.removeFunction(functions, UsbManager.USB_FUNCTION_MTP); - functions = UsbManager.removeFunction(functions, UsbManager.USB_FUNCTION_PTP); - } - return functions; + return !userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER); } private void updateCurrentAccessory() { @@ -552,7 +559,7 @@ public class UsbDeviceManager { | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(UsbManager.USB_CONNECTED, mConnected); intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); - intent.putExtra(UsbManager.USB_DATA_UNLOCKED, mUsbDataUnlocked); + intent.putExtra(UsbManager.USB_DATA_UNLOCKED, isUsbTransferAllowed() && mUsbDataUnlocked); if (mCurrentFunctions != null) { String[] functions = mCurrentFunctions.split(","); @@ -656,10 +663,7 @@ public class UsbDeviceManager { setEnabledFunctions(mCurrentFunctions, false); break; case MSG_SET_USB_DATA_UNLOCKED: - mUsbDataUnlocked = (msg.arg1 == 1); - updateUsbNotification(); - updateUsbStateBroadcast(); - setEnabledFunctions(mCurrentFunctions, true); + setUsbDataUnlocked(msg.arg1 == 1); break; case MSG_SYSTEM_READY: updateUsbNotification(); @@ -804,8 +808,12 @@ public class UsbDeviceManager { } private String getDefaultFunctions() { - return SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, - UsbManager.USB_FUNCTION_ADB); + String func = SystemProperties.get(USB_PERSISTENT_CONFIG_PROPERTY, + UsbManager.USB_FUNCTION_NONE); + if (UsbManager.USB_FUNCTION_NONE.equals(func)) { + func = UsbManager.USB_FUNCTION_MTP; + } + return func; } public void dump(IndentingPrintWriter pw) { @@ -814,6 +822,7 @@ public class UsbDeviceManager { pw.println(" mCurrentFunctionsApplied: " + mCurrentFunctionsApplied); pw.println(" mConnected: " + mConnected); pw.println(" mConfigured: " + mConfigured); + pw.println(" mUsbDataUnlocked: " + mUsbDataUnlocked); pw.println(" mCurrentAccessory: " + mCurrentAccessory); try { pw.println(" Kernel state: " @@ -861,11 +870,6 @@ public class UsbDeviceManager { mHandler.sendMessage(MSG_SET_USB_DATA_UNLOCKED, unlocked); } - public boolean isUsbDataUnlocked() { - if (DEBUG) Slog.d(TAG, "isUsbDataUnlocked() -> " + mHandler.mUsbDataUnlocked); - return mHandler.mUsbDataUnlocked; - } - private void readOemUsbOverrideConfig() { String[] configList = mContext.getResources().getStringArray( com.android.internal.R.array.config_oemUsbModeOverride); @@ -888,6 +892,24 @@ public class UsbDeviceManager { } } + private String applyOemOverrideFunction(String usbFunctions) { + if ((usbFunctions == null) || (mOemModeMap == null)) return usbFunctions; + + String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown"); + + List<Pair<String, String>> overrides = mOemModeMap.get(bootMode); + if (overrides != null) { + for (Pair<String, String> pair: overrides) { + if (pair.first.equals(usbFunctions)) { + Slog.d(TAG, "OEM USB override: " + pair.first + " ==> " + pair.second); + return pair.second; + } + } + } + // return passed in functions as is. + return usbFunctions; + } + public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { if (mDebuggingManager != null) { mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey); diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java index 6300a9a186cd..965341e418ba 100644 --- a/services/usb/java/com/android/server/usb/UsbHostManager.java +++ b/services/usb/java/com/android/server/usb/UsbHostManager.java @@ -231,6 +231,8 @@ public class UsbHostManager { mNewConfigurations = null; mNewInterfaces = null; mNewEndpoints = null; + mNewConfiguration = null; + mNewInterface = null; } } diff --git a/services/usb/java/com/android/server/usb/UsbMidiDevice.java b/services/usb/java/com/android/server/usb/UsbMidiDevice.java index 97bf5059bf9b..38ede87d2b85 100644 --- a/services/usb/java/com/android/server/usb/UsbMidiDevice.java +++ b/services/usb/java/com/android/server/usb/UsbMidiDevice.java @@ -128,7 +128,7 @@ public final class UsbMidiDevice implements Closeable { mReceiver = receiver; } } - + public static UsbMidiDevice create(Context context, Bundle properties, int card, int device) { // FIXME - support devices with different number of input and output ports int subDeviceCount = nativeGetSubdeviceCount(card, device); @@ -203,6 +203,8 @@ public final class UsbMidiDevice implements Closeable { byte[] buffer = new byte[BUFFER_SIZE]; try { while (true) { + // Record time of event immediately after waking. + long timestamp = System.nanoTime(); synchronized (mLock) { if (!mIsOpen) break; @@ -215,14 +217,14 @@ public final class UsbMidiDevice implements Closeable { } else if ((pfd.revents & OsConstants.POLLIN) != 0) { // clear readable flag pfd.revents = 0; - + if (index == mInputStreams.length - 1) { // last file descriptor is used only for unblocking Os.poll() break; } int count = mInputStreams[index].read(buffer); - outputReceivers[index].send(buffer, 0, count); + outputReceivers[index].send(buffer, 0, count, timestamp); } } } diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index f93a2ef1adce..edd9201fe822 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -322,23 +322,10 @@ public class UsbService extends IUsbManager.Stub { @Override public void setUsbDataUnlocked(boolean unlocked) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); - // If attempt to change USB function while file transfer is restricted, ensure that - // usb data is always locked, and return. - UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) { - if (mDeviceManager != null) mDeviceManager.setUsbDataUnlocked(false); - return; - } mDeviceManager.setUsbDataUnlocked(unlocked); } @Override - public boolean isUsbDataUnlocked() { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); - return mDeviceManager.isUsbDataUnlocked(); - } - - @Override public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey); diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 42f879c8a992..a8874d0e11ac 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -448,7 +448,7 @@ public class VoiceInteractionManagerService extends SystemService { } final long caller = Binder.clearCallingIdentity(); try { - mImpl.showSessionLocked(args, flags, null /* showCallback */); + mImpl.showSessionLocked(args, flags, null, null); } finally { Binder.restoreCallingIdentity(caller); } @@ -463,12 +463,9 @@ public class VoiceInteractionManagerService extends SystemService { throw new SecurityException( "deliverNewSession without running voice interaction service"); } - final int callingPid = Binder.getCallingPid(); - final int callingUid = Binder.getCallingUid(); final long caller = Binder.clearCallingIdentity(); try { - return mImpl.deliverNewSessionLocked(callingPid, callingUid, token, session, - interactor); + return mImpl.deliverNewSessionLocked(token, session, interactor); } finally { Binder.restoreCallingIdentity(caller); } @@ -484,7 +481,7 @@ public class VoiceInteractionManagerService extends SystemService { } final long caller = Binder.clearCallingIdentity(); try { - return mImpl.showSessionLocked(sessionArgs, flags, null /* showCallback */); + return mImpl.showSessionLocked(sessionArgs, flags, null, null); } finally { Binder.restoreCallingIdentity(caller); } @@ -533,11 +530,9 @@ public class VoiceInteractionManagerService extends SystemService { Slog.w(TAG, "setKeepAwake without running voice interaction service"); return; } - final int callingPid = Binder.getCallingPid(); - final int callingUid = Binder.getCallingUid(); final long caller = Binder.clearCallingIdentity(); try { - mImpl.setKeepAwakeLocked(callingPid, callingUid, token, keepAwake); + mImpl.setKeepAwakeLocked(token, keepAwake); } finally { Binder.restoreCallingIdentity(caller); } @@ -551,11 +546,9 @@ public class VoiceInteractionManagerService extends SystemService { Slog.w(TAG, "closeSystemDialogs without running voice interaction service"); return; } - final int callingPid = Binder.getCallingPid(); - final int callingUid = Binder.getCallingUid(); final long caller = Binder.clearCallingIdentity(); try { - mImpl.closeSystemDialogsLocked(callingPid, callingUid, token); + mImpl.closeSystemDialogsLocked(token); } finally { Binder.restoreCallingIdentity(caller); } @@ -585,16 +578,14 @@ public class VoiceInteractionManagerService extends SystemService { Slog.w(TAG, "setDisabledShowContext without running voice interaction service"); return; } - final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long caller = Binder.clearCallingIdentity(); try { - mImpl.setDisabledShowContextLocked(callingPid, callingUid, flags); + mImpl.setDisabledShowContextLocked(callingUid, flags); } finally { Binder.restoreCallingIdentity(caller); } } - } @Override @@ -604,16 +595,32 @@ public class VoiceInteractionManagerService extends SystemService { Slog.w(TAG, "getDisabledShowContext without running voice interaction service"); return 0; } - final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long caller = Binder.clearCallingIdentity(); try { - return mImpl.getDisabledShowContextLocked(callingPid, callingUid); + return mImpl.getDisabledShowContextLocked(callingUid); } finally { Binder.restoreCallingIdentity(caller); } } + } + @Override + public int getUserDisabledShowContext() { + synchronized (this) { + if (mImpl == null) { + Slog.w(TAG, + "getUserDisabledShowContext without running voice interaction service"); + return 0; + } + final int callingUid = Binder.getCallingUid(); + final long caller = Binder.clearCallingIdentity(); + try { + return mImpl.getUserDisabledShowContextLocked(callingUid); + } finally { + Binder.restoreCallingIdentity(caller); + } + } } //----------------- Model management APIs --------------------------------// @@ -799,22 +806,22 @@ public class VoiceInteractionManagerService extends SystemService { } @Override - public void showSessionForActiveService(Bundle args, - IVoiceInteractionSessionShowCallback showCallback) { + public boolean showSessionForActiveService(Bundle args, int sourceFlags, + IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) { enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE); synchronized (this) { if (mImpl == null) { Slog.w(TAG, "showSessionForActiveService without running voice interaction" + "service"); - return; + return false; } final long caller = Binder.clearCallingIdentity(); try { - mImpl.showSessionLocked(args, - VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE + return mImpl.showSessionLocked(args, + sourceFlags | VoiceInteractionSession.SHOW_WITH_ASSIST | VoiceInteractionSession.SHOW_WITH_SCREENSHOT, - showCallback); + showCallback, activityToken); } finally { Binder.restoreCallingIdentity(caller); } @@ -887,6 +894,28 @@ public class VoiceInteractionManagerService extends SystemService { } @Override + public void onLockscreenShown() { + enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE); + synchronized (this) { + if (mImpl == null) { + return; + } + final long caller = Binder.clearCallingIdentity(); + try { + if (mImpl.mActiveSession != null && mImpl.mActiveSession.mSession != null) { + try { + mImpl.mActiveSession.mSession.onLockscreenShown(); + } catch (RemoteException e) { + Log.w(TAG, "Failed to call onLockscreenShown", e); + } + } + } finally { + Binder.restoreCallingIdentity(caller); + } + } + } + + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { @@ -908,7 +937,8 @@ public class VoiceInteractionManagerService extends SystemService { } private void enforceCallingPermission(String permission) { - if (mContext.checkCallingPermission(permission) != PackageManager.PERMISSION_GRANTED) { + if (mContext.checkCallingOrSelfPermission(permission) + != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Caller does not hold the permission " + permission); } } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java index 7409f99ded51..28520be8b7dc 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java @@ -72,7 +72,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne public void onReceive(Context context, Intent intent) { if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) { String reason = intent.getStringExtra("reason"); - if (!CLOSE_REASON_VOICE_INTERACTION.equals(reason)) { + if (!CLOSE_REASON_VOICE_INTERACTION.equals(reason) && !"dream".equals(reason)) { synchronized (mLock) { if (mActiveSession != null && mActiveSession.mSession != null) { try { @@ -142,12 +142,13 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne } public boolean showSessionLocked(Bundle args, int flags, - IVoiceInteractionSessionShowCallback showCallback) { + IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) { if (mActiveSession == null) { mActiveSession = new VoiceInteractionSessionConnection(mLock, mSessionComponentName, mUser, mContext, this, mInfo.getServiceInfo().applicationInfo.uid, mHandler); } - return mActiveSession.showLocked(args, flags, mDisabledShowContext, showCallback); + return mActiveSession.showLocked(args, flags, mDisabledShowContext, showCallback, + activityToken); } public boolean hideSessionLocked() { @@ -157,7 +158,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne return false; } - public boolean deliverNewSessionLocked(int callingPid, int callingUid, IBinder token, + public boolean deliverNewSessionLocked(IBinder token, IVoiceInteractionSession session, IVoiceInteractor interactor) { if (mActiveSession == null || token != mActiveSession.mToken) { Slog.w(TAG, "deliverNewSession does not match active session"); @@ -189,8 +190,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne } } - public void setKeepAwakeLocked(int callingPid, int callingUid, IBinder token, - boolean keepAwake) { + public void setKeepAwakeLocked(IBinder token, boolean keepAwake) { try { if (mActiveSession == null || token != mActiveSession.mToken) { Slog.w(TAG, "setKeepAwake does not match active session"); @@ -202,7 +202,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne } } - public void closeSystemDialogsLocked(int callingPid, int callingUid, IBinder token) { + public void closeSystemDialogsLocked(IBinder token) { try { if (mActiveSession == null || token != mActiveSession.mToken) { Slog.w(TAG, "closeSystemDialogs does not match active session"); @@ -223,7 +223,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne mActiveSession = null; } - public void setDisabledShowContextLocked(int callingPid, int callingUid, int flags) { + public void setDisabledShowContextLocked(int callingUid, int flags) { int activeUid = mInfo.getServiceInfo().applicationInfo.uid; if (callingUid != activeUid) { throw new SecurityException("Calling uid " + callingUid @@ -232,7 +232,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne mDisabledShowContext = flags; } - public int getDisabledShowContextLocked(int callingPid, int callingUid) { + public int getDisabledShowContextLocked(int callingUid) { int activeUid = mInfo.getServiceInfo().applicationInfo.uid; if (callingUid != activeUid) { throw new SecurityException("Calling uid " + callingUid @@ -241,6 +241,15 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne return mDisabledShowContext; } + public int getUserDisabledShowContextLocked(int callingUid) { + int activeUid = mInfo.getServiceInfo().applicationInfo.uid; + if (callingUid != activeUid) { + throw new SecurityException("Calling uid " + callingUid + + " does not match active uid " + activeUid); + } + return mActiveSession != null ? mActiveSession.getUserDisabledShowContextLocked() : 0; + } + public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) { if (!mValid) { pw.print(" NOT VALID: "); diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java index dfdd639b83bf..04d6d98fe2b2 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java @@ -183,8 +183,21 @@ final class VoiceInteractionSessionConnection implements ServiceConnection { } } + public int getUserDisabledShowContextLocked() { + int flags = 0; + if (Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) == 0) { + flags |= VoiceInteractionSession.SHOW_WITH_ASSIST; + } + if (Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1, mUser) == 0) { + flags |= VoiceInteractionSession.SHOW_WITH_SCREENSHOT; + } + return flags; + } + public boolean showLocked(Bundle args, int flags, int disabledContext, - IVoiceInteractionSessionShowCallback showCallback) { + IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) { if (mBound) { if (!mFullyBound) { mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection, @@ -193,18 +206,15 @@ final class VoiceInteractionSessionConnection implements ServiceConnection { new UserHandle(mUser)); } mShown = true; - boolean isScreenCaptureAllowed = true; + boolean isAssistDataAllowed = true; try { - isScreenCaptureAllowed = mAm.isScreenCaptureAllowedOnCurrentActivity(); + isAssistDataAllowed = mAm.isAssistDataAllowedOnCurrentActivity(); } catch (RemoteException e) { } - boolean structureEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0 - && isScreenCaptureAllowed + disabledContext |= getUserDisabledShowContextLocked(); + boolean structureEnabled = isAssistDataAllowed && (disabledContext&VoiceInteractionSession.SHOW_WITH_ASSIST) == 0; - boolean screenshotEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1, mUser) != 0 - && isScreenCaptureAllowed + boolean screenshotEnabled = isAssistDataAllowed && structureEnabled && (disabledContext&VoiceInteractionSession.SHOW_WITH_SCREENSHOT) == 0; mShowArgs = args; mShowFlags = flags; @@ -215,9 +225,15 @@ final class VoiceInteractionSessionConnection implements ServiceConnection { mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED && structureEnabled) { try { - needDisclosure = true; - mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL, - mAssistReceiver); + if (mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL, + mAssistReceiver, activityToken)) { + needDisclosure = true; + } else { + // Wasn't allowed... given that, let's not do the screenshot either. + mHaveAssistData = true; + mAssistData = null; + screenshotEnabled = false; + } } catch (RemoteException e) { } } else { diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 58fb088c0470..d66395263afd 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -252,6 +252,29 @@ public abstract class Connection extends Conferenceable { // Next CAPABILITY value: 0x00400000 //********************************************************************************************** + /** + * Connection extra key used to store the last forwarded number associated with the current + * connection. Used to communicate to the user interface that the connection was forwarded via + * the specified number. + */ + public static final String EXTRA_LAST_FORWARDED_NUMBER = + "android.telecom.extra.LAST_FORWARDED_NUMBER"; + + /** + * Connection extra key used to store a child number associated with the current connection. + * Used to communicate to the user interface that the connection was received via + * a child address (i.e. phone number) associated with the {@link PhoneAccount}'s primary + * address. + */ + public static final String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS"; + + /** + * Connection extra key used to store the subject for an incoming call. The user interface can + * query this extra and display its contents for incoming calls. Will only be used if the + * {@link PhoneAccount} supports the capability {@link PhoneAccount#CAPABILITY_CALL_SUBJECT}. + */ + public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT"; + // Flag controlling whether PII is emitted into the logs private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG); @@ -1050,6 +1073,7 @@ public abstract class Connection extends Conferenceable { private int mConnectionCapabilities; private VideoProvider mVideoProvider; private boolean mAudioModeIsVoip; + private long mConnectTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED; private StatusHints mStatusHints; private int mVideoState; private DisconnectCause mDisconnectCause; @@ -1162,6 +1186,19 @@ public abstract class Connection extends Conferenceable { } /** + * Retrieves the connection start time of the {@code Connnection}, if specified. A value of + * {@link Conference#CONNECT_TIME_NOT_SPECIFIED} indicates that Telecom should determine the + * start time of the conference. + * + * @return The time at which the {@code Connnection} was connected. + * + * @hide + */ + public final long getConnectTimeMillis() { + return mConnectTimeMillis; + } + + /** * @return The status hints for this connection. */ public final StatusHints getStatusHints() { @@ -1476,6 +1513,18 @@ public abstract class Connection extends Conferenceable { } /** + * Sets the time at which a call became active on this Connection. This is set only + * when a conference call becomes active on this connection. + * + * @param connectionTimeMillis The connection time, in milliseconds. + * + * @hide + */ + public final void setConnectTimeMillis(long connectTimeMillis) { + mConnectTimeMillis = connectTimeMillis; + } + + /** * Sets the label and icon status to display in the in-call UI. * * @param statusHints The status label and icon to set. diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index d2e7a74977e0..96f44b9e421a 100644 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -651,6 +651,7 @@ public abstract class ConnectionService extends Service { connection.getVideoState(), connection.isRingbackRequested(), connection.getAudioModeIsVoip(), + connection.getConnectTimeMillis(), connection.getStatusHints(), connection.getDisconnectCause(), createIdList(connection.getConferenceables()), @@ -979,6 +980,7 @@ public abstract class ConnectionService extends Service { connection.getVideoState(), connection.isRingbackRequested(), connection.getAudioModeIsVoip(), + connection.getConnectTimeMillis(), connection.getStatusHints(), connection.getDisconnectCause(), emptyList, diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java index 683ab6a638b7..fe0a4d8eef3d 100644 --- a/telecomm/java/android/telecom/ParcelableConnection.java +++ b/telecomm/java/android/telecom/ParcelableConnection.java @@ -44,6 +44,7 @@ public final class ParcelableConnection implements Parcelable { private final int mVideoState; private final boolean mRingbackRequested; private final boolean mIsVoipAudioMode; + private final long mConnectTimeMillis; private final StatusHints mStatusHints; private final DisconnectCause mDisconnectCause; private final List<String> mConferenceableConnectionIds; @@ -62,6 +63,7 @@ public final class ParcelableConnection implements Parcelable { int videoState, boolean ringbackRequested, boolean isVoipAudioMode, + long connectTimeMillis, StatusHints statusHints, DisconnectCause disconnectCause, List<String> conferenceableConnectionIds, @@ -77,6 +79,7 @@ public final class ParcelableConnection implements Parcelable { mVideoState = videoState; mRingbackRequested = ringbackRequested; mIsVoipAudioMode = isVoipAudioMode; + mConnectTimeMillis = connectTimeMillis; mStatusHints = statusHints; mDisconnectCause = disconnectCause; mConferenceableConnectionIds = conferenceableConnectionIds; @@ -128,6 +131,10 @@ public final class ParcelableConnection implements Parcelable { return mIsVoipAudioMode; } + public long getConnectTimeMillis() { + return mConnectTimeMillis; + } + public final StatusHints getStatusHints() { return mStatusHints; } @@ -176,6 +183,7 @@ public final class ParcelableConnection implements Parcelable { int videoState = source.readInt(); boolean ringbackRequested = source.readByte() == 1; boolean audioModeIsVoip = source.readByte() == 1; + long connectTimeMillis = source.readLong(); StatusHints statusHints = source.readParcelable(classLoader); DisconnectCause disconnectCause = source.readParcelable(classLoader); List<String> conferenceableConnectionIds = new ArrayList<>(); @@ -194,6 +202,7 @@ public final class ParcelableConnection implements Parcelable { videoState, ringbackRequested, audioModeIsVoip, + connectTimeMillis, statusHints, disconnectCause, conferenceableConnectionIds, @@ -227,6 +236,7 @@ public final class ParcelableConnection implements Parcelable { destination.writeInt(mVideoState); destination.writeByte((byte) (mRingbackRequested ? 1 : 0)); destination.writeByte((byte) (mIsVoipAudioMode ? 1 : 0)); + destination.writeLong(mConnectTimeMillis); destination.writeParcelable(mStatusHints, 0); destination.writeParcelable(mDisconnectCause, 0); destination.writeStringList(mConferenceableConnectionIds); diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java index df6fa2e1b391..cdb0bf257baa 100644 --- a/telecomm/java/android/telecom/PhoneAccount.java +++ b/telecomm/java/android/telecom/PhoneAccount.java @@ -112,6 +112,15 @@ public final class PhoneAccount implements Parcelable { public static final int CAPABILITY_MULTI_USER = 0x20; /** + * Flag indicating that this {@code PhoneAccount} supports a subject for Calls. This means a + * caller is able to specify a short subject line for an outgoing call. A capable receiving + * device displays the call subject on the incoming call screen. + * <p> + * See {@link #getCapabilities} + */ + public static final int CAPABILITY_CALL_SUBJECT = 0x40; + + /** * URI scheme for telephone number URIs. */ public static final String SCHEME_TEL = "tel"; diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index a30e1c0dada7..067e7342cc28 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -177,6 +177,13 @@ public class TelecomManager { "android.telecom.extra.PHONE_ACCOUNT_HANDLE"; /** + * Optional extra for {@link android.content.Intent#ACTION_CALL} containing a string call + * subject which will be associated with an outgoing call. Should only be specified if the + * {@link PhoneAccount} supports the capability {@link PhoneAccount#CAPABILITY_CALL_SUBJECT}. + */ + public static final String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT"; + + /** * The extra used by a {@link ConnectionService} to provide the handle of the caller that * has initiated a new incoming call. */ @@ -493,6 +500,26 @@ public class TelecomManager { } /** + * Returns the current SIM call manager for the specified user. Apps must be prepared for this + * method to return {@code null}, indicating that there currently exists no user-chosen default + * {@code PhoneAccount}. + * + * @return The phone account handle of the current sim call manager. + * + * @hide + */ + public PhoneAccountHandle getSimCallManager(int userId) { + try { + if (isServiceConnected()) { + return getTelecomService().getSimCallManagerForUser(userId); + } + } catch (RemoteException e) { + Log.e(TAG, "Error calling ITelecomService#getSimCallManagerForUser"); + } + return null; + } + + /** * 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}. diff --git a/telecomm/java/android/telecom/Voicemail.java b/telecomm/java/android/telecom/Voicemail.java index 151917ea30d1..ca235bf3baa5 100644 --- a/telecomm/java/android/telecom/Voicemail.java +++ b/telecomm/java/android/telecom/Voicemail.java @@ -36,10 +36,11 @@ public class Voicemail implements Parcelable { private final Uri mUri; private final Boolean mIsRead; private final Boolean mHasContent; + private final String mTranscription; private Voicemail(Long timestamp, String number, PhoneAccountHandle phoneAccountHandle, Long id, Long duration, String source, String providerData, Uri uri, Boolean isRead, - Boolean hasContent) { + Boolean hasContent, String transcription) { mTimestamp = timestamp; mNumber = number; mPhoneAccount = phoneAccountHandle; @@ -50,6 +51,7 @@ public class Voicemail implements Parcelable { mUri = uri; mIsRead = isRead; mHasContent = hasContent; + mTranscription = transcription; } /** @@ -88,6 +90,7 @@ public class Voicemail implements Parcelable { private Uri mBuilderUri; private Boolean mBuilderIsRead; private boolean mBuilderHasContent; + private String mBuilderTranscription; /** You should use the correct factory method to construct a builder. */ private Builder() { @@ -143,6 +146,11 @@ public class Voicemail implements Parcelable { return this; } + public Builder setTranscription(String transcription) { + mBuilderTranscription = transcription; + return this; + } + public Voicemail build() { mBuilderId = mBuilderId == null ? -1 : mBuilderId; mBuilderTimestamp = mBuilderTimestamp == null ? 0 : mBuilderTimestamp; @@ -150,7 +158,7 @@ public class Voicemail implements Parcelable { mBuilderIsRead = mBuilderIsRead == null ? false : mBuilderIsRead; return new Voicemail(mBuilderTimestamp, mBuilderNumber, mBuilderPhoneAccount, mBuilderId, mBuilderDuration, mBuilderSourcePackage, mBuilderSourceData, - mBuilderUri, mBuilderIsRead, mBuilderHasContent); + mBuilderUri, mBuilderIsRead, mBuilderHasContent, mBuilderTranscription); } } @@ -230,6 +238,13 @@ public class Voicemail implements Parcelable { return mHasContent; } + /** + * Returns the text transcription of this voicemail, or null if this field is not set. + */ + public String getTranscription() { + return mTranscription; + } + @Override public int describeContents() { return 0; @@ -265,6 +280,7 @@ public class Voicemail implements Parcelable { } else { dest.writeInt(0); } + dest.writeCharSequence(mTranscription); } public static final Creator<Voicemail> CREATOR @@ -299,5 +315,6 @@ public class Voicemail implements Parcelable { } mIsRead = in.readInt() > 0 ? true : false; mHasContent = in.readInt() > 0 ? true : false; + mTranscription = (String) in.readCharSequence(); } } diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index fb0f6dafee71..2e07759f09f1 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -93,6 +93,11 @@ interface ITelecomService { PhoneAccountHandle getSimCallManager(); /** + * @see TelecomServiceImpl#getSimCallManagerForUser + */ + PhoneAccountHandle getSimCallManagerForUser(int userId); + + /** * @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 e8616682436c..e9c41a1682da 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -273,6 +273,14 @@ public class CarrierConfigManager { */ public static final String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string"; + /** + * The default flag specifying whether ETWS/CMAS test setting is forcibly disabled in + * Settings->More->Emergency broadcasts menu even though developer options is turned on. + * @hide + */ + public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = + "carrier_force_disable_etws_cmas_test_bool"; + /* The following 3 fields are related to carrier visual voicemail. */ /** @@ -381,6 +389,7 @@ public class CarrierConfigManager { 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_FORCE_DISABLE_ETWS_CMAS_TEST_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); diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl index 21c94c2608ad..70a8653135c8 100644 --- a/telephony/java/com/android/internal/telephony/ISms.aidl +++ b/telephony/java/com/android/internal/telephony/ISms.aidl @@ -149,10 +149,14 @@ interface ISms { * broadcast when the message is delivered to the recipient. The * raw pdu of the status report is in the extended data ("pdu"). * @param subId the subId on which the SMS has to be sent. + * @param persistMessageForNonDefaultSmsApp whether the sent message should + * be automatically persisted in the SMS db. It only affects messages sent + * by a non-default SMS app. Currently only the carrier app can set this + * parameter to false to skip auto message persistence. */ void sendTextForSubscriber(in int subId, String callingPkg, in String destAddr, in String scAddr, in String text, in PendingIntent sentIntent, - in PendingIntent deliveryIntent); + in PendingIntent deliveryIntent, in boolean persistMessageForNonDefaultSmsApp); /** * Send an SMS. Internal use only. @@ -219,11 +223,15 @@ interface ISms { * to the recipient. The raw pdu of the status report is in the * extended data ("pdu"). * @param subId the subId on which the SMS has to be sent. + * @param persistMessageForNonDefaultSmsApp whether the sent message should + * be automatically persisted in the SMS db. It only affects messages sent + * by a non-default SMS app. Currently only the carrier app can set this + * parameter to false to skip auto message persistence. */ void sendMultipartTextForSubscriber(in int subId, String callingPkg, in String destinationAddress, in String scAddress, in List<String> parts, in List<PendingIntent> sentIntents, - in List<PendingIntent> deliveryIntents); + in List<PendingIntent> deliveryIntents, in boolean persistMessageForNonDefaultSmsApp); /** * Enable reception of cell broadcast (SMS-CB) messages with the given diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index 3df7bbc91e9b..1ff621a6cac9 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -181,6 +181,12 @@ public class MockPackageManager extends PackageManager { throw new UnsupportedOperationException(); } + /** @hide */ + @Override + public String getPermissionControllerPackageName() { + throw new UnsupportedOperationException(); + } + @Override public boolean addPermission(PermissionInfo info) { throw new UnsupportedOperationException(); diff --git a/tests/AccessibilityEventsLogger/Android.mk b/tests/AccessibilityEventsLogger/Android.mk new file mode 100644 index 000000000000..52bc57900e3f --- /dev/null +++ b/tests/AccessibilityEventsLogger/Android.mk @@ -0,0 +1,13 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := AccessibilityEventsLogger +LOCAL_CERTIFICATE := platform + +LOCAL_PROGUARD_ENABLED := disabled + +include $(BUILD_PACKAGE) diff --git a/tests/AccessibilityEventsLogger/AndroidManifest.xml b/tests/AccessibilityEventsLogger/AndroidManifest.xml new file mode 100644 index 000000000000..d86769f570c5 --- /dev/null +++ b/tests/AccessibilityEventsLogger/AndroidManifest.xml @@ -0,0 +1,51 @@ +<?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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="com.android.tests.accessibilityeventlogger" + android:versionCode="1" + android:versionName="0.0" > + + <uses-sdk + android:minSdkVersion="18" + android:targetSdkVersion="18" /> + + <application + android:allowBackup="true" + android:enabled="true" + android:label="@string/app_name" > + + <service + android:name=".AELogger" + android:enabled="true" + android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" + android:configChanges="locale" > + <intent-filter> + <action android:name="android.accessibilityservice.AccessibilityService"/> + + <category android:name="android.accessibilityservice.category.FEEDBACK_GENERIC"/> + <category android:name="android.accessibilityservice.category.FEEDBACK_VISUAL"/> + <category android:name="android.accessibilityservice.category.FEEDBACK_AUDIBLE"/> + </intent-filter> + + <meta-data + android:name="android.accessibilityservice" + android:resource="@xml/accessibilityservice" /> + </service> + </application> +</manifest> diff --git a/tests/AccessibilityEventsLogger/res/values/strings.xml b/tests/AccessibilityEventsLogger/res/values/strings.xml new file mode 100644 index 000000000000..353f912c2767 --- /dev/null +++ b/tests/AccessibilityEventsLogger/res/values/strings.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- CHAR LIMIT=none --> + <string name="app_name"> + Accessibility Event Logger + </string> + + <!-- CHAR LIMIT=none --> + <string name="service_description"> + Debugging service + </string> +</resources> diff --git a/tests/AccessibilityEventsLogger/res/xml/accessibilityservice.xml b/tests/AccessibilityEventsLogger/res/xml/accessibilityservice.xml new file mode 100644 index 000000000000..69ecd61287fe --- /dev/null +++ b/tests/AccessibilityEventsLogger/res/xml/accessibilityservice.xml @@ -0,0 +1,24 @@ +<?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. +--> + +<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" + android:accessibilityEventTypes="typeAllMask" + android:accessibilityFeedbackType="feedbackGeneric|feedbackVisual|feedbackAudible" + android:canRetrieveWindowContent="true" + android:accessibilityFlags="flagDefault" + android:description="@string/service_description" + android:notificationTimeout="0" /> diff --git a/tests/AccessibilityEventsLogger/src/com/android/tests/accessibilityeventslogger/AELogger.java b/tests/AccessibilityEventsLogger/src/com/android/tests/accessibilityeventslogger/AELogger.java new file mode 100644 index 000000000000..27d8eb9063ee --- /dev/null +++ b/tests/AccessibilityEventsLogger/src/com/android/tests/accessibilityeventslogger/AELogger.java @@ -0,0 +1,65 @@ +/* + * 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.tests.accessibilityeventslogger; + +import android.accessibilityservice.AccessibilityService; +import android.accessibilityservice.AccessibilityServiceInfo; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; +import android.widget.Toast; + +import java.util.Locale; + +public class AELogger extends AccessibilityService { + private static final String TAG = AELogger.class.getCanonicalName(); + + private static final int TOAST_EVENT_TYPES = + AccessibilityEvent.TYPE_VIEW_CLICKED | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED; + + @Override + public void onServiceConnected() { + super.onServiceConnected(); + Log.v(TAG, "Service connected."); + } + + + @Override + public void onInterrupt() { + // Do nothing + } + + @Override + public void onAccessibilityEvent(AccessibilityEvent event) { + final String eventClass = event.getClassName().toString(); + final String eventText = String.valueOf(event.getText()).toLowerCase(Locale.getDefault()); + final String eventType = AccessibilityEvent.eventTypeToString(event.getEventType()); + + Log.d(TAG, String.format( + "typ=%s cls=%s pkg=%s txt=%s dsc=%s", + eventType, + eventClass, + event.getPackageName(), + eventText, + event.getContentDescription() + )); + + // Show selected event types + if (0 != (TOAST_EVENT_TYPES & event.getEventType())) { + final Toast toast = Toast.makeText(this, + eventType + ": " + eventClass, Toast.LENGTH_SHORT); + toast.show(); + } + } +} diff --git a/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java index 43f1e32c9409..851bda92a5a5 100644 --- a/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java +++ b/tests/Assist/src/com/android/test/assist/AssistInteractionSession.java @@ -24,6 +24,7 @@ import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.service.voice.VoiceInteractionSession; +import android.util.Log; import android.view.View; import android.view.ViewAnimationUtils; import android.view.ViewTreeObserver; @@ -69,6 +70,7 @@ public class AssistInteractionSession extends VoiceInteractionSession { @Override public void onCreate() { + super.onCreate(); // Simulate slowness of Assist app try { Thread.sleep(1000); @@ -105,6 +107,12 @@ public class AssistInteractionSession extends VoiceInteractionSession { } } + @Override + public void onLockscreenShown() { + super.onLockscreenShown(); + Log.i("Assistant", "Lockscreen was shown"); + } + private void playAssistAnimation() { Interpolator linearOutSlowIn = AnimationUtils.loadInterpolator(mBackground.getContext(), android.R.interpolator.linear_out_slow_in); diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/ScaleDrawableTests.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/ScaleDrawableTests.java index 3787843c2ee1..c5be6c417f69 100644 --- a/tests/VectorDrawableTest/src/com/android/test/dynamic/ScaleDrawableTests.java +++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/ScaleDrawableTests.java @@ -37,8 +37,8 @@ public class ScaleDrawableTests extends Activity { }; protected int icon = R.drawable.bitmap_drawable01; - protected int vector_icon = R.drawable.vector_drawable16; + protected int animated_vector_icon = R.drawable.ic_hourglass_animation; @Override protected void onCreate(Bundle savedInstanceState) { @@ -46,12 +46,12 @@ public class ScaleDrawableTests extends Activity { ScrollView scrollView = new ScrollView(this); GridLayout container = new GridLayout(this); scrollView.addView(container); - container.setColumnCount(3); + container.setColumnCount(4); container.setBackgroundColor(0xFF888888); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - params.width = 400; - params.height = 300; + params.width = 300; + params.height = 200; for (int i = 0; i < scaleTypes.length; i++) { TextView t = new TextView(this); @@ -71,6 +71,13 @@ public class ScaleDrawableTests extends Activity { view.setScaleType(scaleType); view.setImageResource(vector_icon); container.addView(view); + + ImageView avd_view = new ImageView(this); + avd_view.setLayoutParams(params); + avd_view.setScaleType(scaleType); + avd_view.setImageResource(animated_vector_icon); + container.addView(avd_view); + } setContentView(scrollView); diff --git a/tests/VoiceInteraction/res/layout/main.xml b/tests/VoiceInteraction/res/layout/main.xml index 0f968eb65996..a83d02c2c729 100644 --- a/tests/VoiceInteraction/res/layout/main.xml +++ b/tests/VoiceInteraction/res/layout/main.xml @@ -26,6 +26,12 @@ android:text="@string/start" /> + <CheckBox android:id="@+id/secure" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/secure" + /> + <com.android.test.voiceinteraction.AsyncStructure android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/tests/VoiceInteraction/res/layout/test_interaction.xml b/tests/VoiceInteraction/res/layout/test_interaction.xml index d1a7ad532abd..277117e3e157 100644 --- a/tests/VoiceInteraction/res/layout/test_interaction.xml +++ b/tests/VoiceInteraction/res/layout/test_interaction.xml @@ -39,6 +39,19 @@ android:layout_marginTop="16dp" android:orientation="horizontal"> + <Button android:id="@+id/airplane" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/launchAirplane" + /> + + </LinearLayout> + + <LinearLayout android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:orientation="horizontal"> + <Button android:id="@+id/complete" android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml index dc4e31bc0035..b1064370d344 100644 --- a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml +++ b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml @@ -80,6 +80,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Disallow screenshot" /> + <TextView android:id="@+id/options_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:layout_marginBottom="16dp" + android:textAppearance="?android:attr/textAppearanceMedium" /> </LinearLayout> </LinearLayout> diff --git a/tests/VoiceInteraction/res/values/strings.xml b/tests/VoiceInteraction/res/values/strings.xml index ab39f99478b2..c665c23faa63 100644 --- a/tests/VoiceInteraction/res/values/strings.xml +++ b/tests/VoiceInteraction/res/values/strings.xml @@ -17,9 +17,11 @@ <resources> <string name="start">Start</string> + <string name="secure">Secure</string> <string name="tree">Tree</string> <string name="text">Text</string> <string name="asyncStructure">(Async structure goes here)</string> + <string name="launchAirplane">Launch airplane mode</string> <string name="confirm">Confirm</string> <string name="abort">Abort</string> <string name="complete">Complete</string> diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java index 8381aa16e005..f1dd1de0e517 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java @@ -74,21 +74,6 @@ public class MainInteractionService extends VoiceInteractionService { "Hello There", Locale.forLanguageTag("en-US"), mHotwordCallback); } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (isActiveService(this, new ComponentName(this, getClass()))) { - Bundle args = new Bundle(); - args.putParcelable("intent", new Intent(this, TestInteractionActivity.class)); - args.putBundle("assist", intent.getExtras()); - showSession(args, VoiceInteractionSession.SHOW_WITH_ASSIST - | VoiceInteractionSession.SHOW_WITH_SCREENSHOT); - } else { - Log.w(TAG, "Not starting -- not current voice interaction service"); - } - stopSelf(startId); - return START_NOT_STICKY; - } - private void hotwordAvailabilityChangeHelper(int availability) { Log.i(TAG, "Hotword availability = " + availability); switch (availability) { diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java index 8796c9f75037..6e3694b345e9 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java @@ -50,6 +50,7 @@ public class MainInteractionSession extends VoiceInteractionSession View mOptionsContainer; CheckBox mDisallowAssist; CheckBox mDisallowScreenshot; + TextView mOptionsText; ImageView mScreenshot; ImageView mFullScreenshot; Button mConfirmButton; @@ -71,6 +72,7 @@ public class MainInteractionSession extends VoiceInteractionSession VoiceInteractor.PickOptionRequest.Option[] mPendingOptions; CharSequence mPendingPrompt; Request mPendingRequest; + int mCurrentTask = -1; MainInteractionSession(Context context) { super(context); @@ -86,8 +88,9 @@ public class MainInteractionSession extends VoiceInteractionSession @Override public void onShow(Bundle args, int showFlags) { super.onShow(args, showFlags); + Log.i(TAG, "onShow: flags=0x" + Integer.toHexString(showFlags) + " args=" + args); mState = STATE_IDLE; - mStartIntent = args.getParcelable("intent"); + mStartIntent = args != null ? (Intent)args.getParcelable("intent") : null; if (mStartIntent == null) { mStartIntent = new Intent(getContext(), TestInteractionActivity.class); } @@ -96,6 +99,7 @@ public class MainInteractionSession extends VoiceInteractionSession } onHandleScreenshot(null); updateState(); + refreshOptions(); } @Override @@ -134,6 +138,7 @@ public class MainInteractionSession extends VoiceInteractionSession mDisallowAssist.setOnClickListener(this); mDisallowScreenshot = (CheckBox)mContentView.findViewById(R.id.disallow_screenshot); mDisallowScreenshot.setOnClickListener(this); + mOptionsText = (TextView)mContentView.findViewById(R.id.options_text); mConfirmButton = (Button)mContentView.findViewById(R.id.confirm); mConfirmButton.setOnClickListener(this); mCompleteButton = (Button)mContentView.findViewById(R.id.complete); @@ -145,13 +150,17 @@ public class MainInteractionSession extends VoiceInteractionSession } void refreshOptions() { - if (mOptionsCheck.isChecked()) { - mOptionsContainer.setVisibility(View.VISIBLE); - int flags = getDisabledShowContext(); - mDisallowAssist.setChecked((flags & SHOW_WITH_ASSIST) != 0); - mDisallowScreenshot.setChecked((flags & SHOW_WITH_SCREENSHOT) != 0); - } else { - mOptionsContainer.setVisibility(View.GONE); + if (mOptionsContainer != null) { + if (mOptionsCheck.isChecked()) { + mOptionsContainer.setVisibility(View.VISIBLE); + int flags = getDisabledShowContext(); + mDisallowAssist.setChecked((flags & SHOW_WITH_ASSIST) != 0); + mDisallowScreenshot.setChecked((flags & SHOW_WITH_SCREENSHOT) != 0); + int disabled = getUserDisabledShowContext(); + mOptionsText.setText("Disabled: 0x" + Integer.toHexString(disabled)); + } else { + mOptionsContainer.setVisibility(View.GONE); + } } } @@ -306,6 +315,27 @@ public class MainInteractionSession extends VoiceInteractionSession } @Override + public void onTaskStarted(Intent intent, int taskId) { + super.onTaskStarted(intent, taskId); + mCurrentTask = taskId; + } + + @Override + public void onTaskFinished(Intent intent, int taskId) { + super.onTaskFinished(intent, taskId); + if (mCurrentTask == taskId) { + mCurrentTask = -1; + } + } + + @Override + public void onLockscreenShown() { + if (mCurrentTask < 0) { + hide(); + } + } + + @Override public boolean[] onGetSupportedCommands(String[] commands) { boolean[] res = new boolean[commands.length]; for (int i=0; i<commands.length; i++) { diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java index b0d6b399eaaa..ada0e21e059a 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java @@ -16,12 +16,12 @@ package com.android.test.voiceinteraction; -import android.annotation.Nullable; import android.app.Activity; import android.app.VoiceInteractor; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; +import android.provider.Settings; import android.service.voice.VoiceInteractionService; import android.util.Log; import android.view.View; @@ -40,6 +40,7 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis VoiceInteractor mInteractor; VoiceInteractor.Request mCurrentRequest = null; TextView mLog; + Button mAirplaneButton; Button mAbortButton; Button mCompleteButton; Button mCommandButton; @@ -66,6 +67,8 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis setContentView(R.layout.test_interaction); mLog = (TextView)findViewById(R.id.log); + mAirplaneButton = (Button)findViewById(R.id.airplane); + mAirplaneButton.setOnClickListener(this); mAbortButton = (Button)findViewById(R.id.abort); mAbortButton.setOnClickListener(this); mCompleteButton = (Button)findViewById(R.id.complete); @@ -123,7 +126,12 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis @Override public void onClick(View v) { - if (v == mAbortButton) { + if (v == mAirplaneButton) { + Intent intent = new Intent(Settings.ACTION_VOICE_CONTROL_AIRPLANE_MODE); + intent.addCategory(Intent.CATEGORY_VOICE); + intent.putExtra(Settings.EXTRA_AIRPLANE_MODE_ENABLED, true); + startActivity(intent); + } else if (v == mAbortButton) { VoiceInteractor.AbortVoiceRequest req = new TestAbortVoice(); mInteractor.submitRequest(req, REQUEST_ABORT); } else if (v == mCompleteButton) { diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java index a7636c32511a..87fa91a86a6b 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/VoiceInteractionMain.java @@ -21,6 +21,8 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; +import android.view.WindowManager; +import android.widget.CheckBox; public class VoiceInteractionMain extends Activity { @@ -30,6 +32,7 @@ public class VoiceInteractionMain extends Activity { setContentView(R.layout.main); findViewById(R.id.start).setOnClickListener(mStartListener); + findViewById(R.id.secure).setOnClickListener(mSecureListener); } @Override @@ -49,7 +52,17 @@ public class VoiceInteractionMain extends Activity { View.OnClickListener mStartListener = new View.OnClickListener() { public void onClick(View v) { - startService(new Intent(VoiceInteractionMain.this, MainInteractionService.class)); + showAssist(null); + } + }; + + View.OnClickListener mSecureListener = new View.OnClickListener() { + public void onClick(View v) { + if (((CheckBox)v).isChecked()) { + getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); + } else { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE); + } } }; } diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index e64fdf7f54b9..81642fa4392c 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -4466,6 +4466,37 @@ static int getMinSdkVersion(const Bundle* bundle) { return 0; } +static bool shouldGenerateVersionedResource(const sp<ResourceTable::ConfigList>& configList, + const ConfigDescription& sourceConfig, + const int sdkVersionToGenerate) { + assert(sdkVersionToGenerate > sourceConfig.sdkVersion); + const DefaultKeyedVector<ConfigDescription, sp<ResourceTable::Entry>>& entries + = configList->getEntries(); + ssize_t idx = entries.indexOfKey(sourceConfig); + + // The source config came from this list, so it should be here. + assert(idx >= 0); + + idx += 1; + if (static_cast<size_t>(idx) >= entries.size()) { + // This is the last configuration, so we should generate a versioned resource. + return true; + } + + const ConfigDescription& nextConfig = entries.keyAt(idx); + + // Build a configuration that is the same as the source config, + // but with the SDK level of the next config. If they are the same, + // then they only differ in SDK level. If the next configs SDK level is + // higher than the one we want to generate, we must generate it. + ConfigDescription tempConfig(sourceConfig); + tempConfig.sdkVersion = nextConfig.sdkVersion; + if (nextConfig == tempConfig) { + return sdkVersionToGenerate < nextConfig.sdkVersion; + } + return false; +} + /** * Modifies the entries in the resource table to account for compatibility * issues with older versions of Android. @@ -4574,6 +4605,11 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) { for (size_t i = 0; i < sdkCount; i++) { const int sdkLevel = attributesToRemove.keyAt(i); + if (!shouldGenerateVersionedResource(c, config, sdkLevel)) { + // There is a style that will override this generated one. + continue; + } + // Duplicate the entry under the same configuration // but with sdkVersion == sdkLevel. ConfigDescription newConfig(config); @@ -4610,13 +4646,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle) { const size_t entriesToAddCount = entriesToAdd.size(); for (size_t i = 0; i < entriesToAddCount; i++) { - if (entries.indexOfKey(entriesToAdd[i].key) >= 0) { - // An entry already exists for this config. - // That means that any attributes that were - // defined in L in the original bag will be overriden - // anyways on L devices, so we do nothing. - continue; - } + assert(entries.indexOfKey(entriesToAdd[i].key) < 0); if (bundle->getVerbose()) { entriesToAdd[i].value->getPos() @@ -4662,8 +4692,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, } sp<XMLNode> newRoot = NULL; - ConfigDescription newConfig(target->getGroupEntry().toParams()); - newConfig.sdkVersion = SDK_LOLLIPOP_MR1; + int sdkVersionToGenerate = SDK_LOLLIPOP_MR1; Vector<sp<XMLNode> > nodesToVisit; nodesToVisit.push(root); @@ -4689,9 +4718,7 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, // Find the smallest sdk version that we need to synthesize for // and do that one. Subsequent versions will be processed on // the next pass. - if (sdkLevel < newConfig.sdkVersion) { - newConfig.sdkVersion = sdkLevel; - } + sdkVersionToGenerate = std::min(sdkLevel, sdkVersionToGenerate); if (bundle->getVerbose()) { SourcePos(node->getFilename(), node->getStartLineNumber()).printf( @@ -4721,8 +4748,10 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, // Look to see if we already have an overriding v21 configuration. sp<ConfigList> cl = getConfigList(String16(mAssets->getPackage()), String16(target->getResourceType()), resourceName); - if (cl->getEntries().indexOfKey(newConfig) < 0) { + if (shouldGenerateVersionedResource(cl, config, sdkVersionToGenerate)) { // We don't have an overriding entry for v21, so we must duplicate this one. + ConfigDescription newConfig(config); + newConfig.sdkVersion = sdkVersionToGenerate; sp<AaptFile> newFile = new AaptFile(target->getSourceFile(), AaptGroupEntry(newConfig), target->getResourceType()); String8 resPath = String8::format("res/%s/%s", @@ -4760,7 +4789,8 @@ status_t ResourceTable::modifyForCompat(const Bundle* bundle, return NO_ERROR; } -void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) { +void ResourceTable::getDensityVaryingResources( + KeyedVector<Symbol, Vector<SymbolDefinition> >& resources) { const ConfigDescription nullConfig; const size_t packageCount = mOrderedPackages.size(); @@ -4771,19 +4801,23 @@ void ResourceTable::getDensityVaryingResources(KeyedVector<Symbol, Vector<Symbol const Vector<sp<ConfigList> >& configs = types[t]->getOrderedConfigs(); const size_t configCount = configs.size(); for (size_t c = 0; c < configCount; c++) { - const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries = configs[c]->getEntries(); + const DefaultKeyedVector<ConfigDescription, sp<Entry> >& configEntries + = configs[c]->getEntries(); const size_t configEntryCount = configEntries.size(); for (size_t ce = 0; ce < configEntryCount; ce++) { const ConfigDescription& config = configEntries.keyAt(ce); if (AaptConfig::isDensityOnly(config)) { // This configuration only varies with regards to density. - const Symbol symbol(mOrderedPackages[p]->getName(), + const Symbol symbol( + mOrderedPackages[p]->getName(), types[t]->getName(), configs[c]->getName(), - getResId(mOrderedPackages[p], types[t], configs[c]->getEntryIndex())); + getResId(mOrderedPackages[p], types[t], + configs[c]->getEntryIndex())); const sp<Entry>& entry = configEntries.valueAt(ce); - AaptUtil::appendValue(resources, symbol, SymbolDefinition(symbol, config, entry->getPos())); + AaptUtil::appendValue(resources, symbol, + SymbolDefinition(symbol, config, entry->getPos())); } } } diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java index 1105c7b0fb19..a503e50407ed 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java @@ -673,7 +673,7 @@ public final class Matrix_Delegate { return; } - System.arraycopy(d.mValues, 0, d.mValues, 0, MATRIX_SIZE); + System.arraycopy(d.mValues, 0, values, 0, MATRIX_SIZE); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java index 776398fbb094..3c9a062719e2 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java @@ -21,6 +21,7 @@ import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; +import android.annotation.NonNull; import android.graphics.Path.Direction; import android.graphics.Path.FillType; @@ -30,6 +31,7 @@ import java.awt.geom.Arc2D; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; +import java.awt.geom.Path2D; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; @@ -56,7 +58,7 @@ public final class Path_Delegate { // ---- delegate data ---- private FillType mFillType = FillType.WINDING; - private GeneralPath mPath = new GeneralPath(); + private Path2D mPath = new Path2D.Double(); private float mLastX = 0; private float mLastY = 0; @@ -486,8 +488,54 @@ public final class Path_Delegate { @LayoutlibDelegate /*package*/ static float[] native_approximate(long nPath, float error) { - Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not supported", null); - return new float[0]; + Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not fully supported", + null); + Path_Delegate pathDelegate = sManager.getDelegate(nPath); + if (pathDelegate == null) { + return null; + } + PathIterator pathIterator = pathDelegate.mPath.getPathIterator(null); + float[] tmp = new float[6]; + float[] coords = new float[6]; + boolean isFirstPoint = true; + while (!pathIterator.isDone()) { + int type = pathIterator.currentSegment(tmp); + switch (type) { + case PathIterator.SEG_MOVETO: + case PathIterator.SEG_LINETO: + store(tmp, coords, 1, isFirstPoint); + break; + case PathIterator.SEG_QUADTO: + store(tmp, coords, 2, isFirstPoint); + break; + case PathIterator.SEG_CUBICTO: + store(tmp, coords, 3, isFirstPoint); + break; + case PathIterator.SEG_CLOSE: + // No points returned. + } + isFirstPoint = false; + pathIterator.next(); + } + if (isFirstPoint) { + // No points found + return new float[0]; + } else { + return coords; + } + } + + private static void store(float[] src, float[] dst, int count, boolean isFirst) { + if (isFirst) { + dst[0] = 0; // fraction + dst[1] = src[0]; // abscissa + dst[2] = src[1]; // ordinate + } + if (count > 1 || !isFirst) { + dst[3] = 1; + dst[4] = src[2 * count - 2]; + dst[5] = src[2 * count - 1]; + } } // ---- Private helper methods ---- @@ -522,6 +570,7 @@ public final class Path_Delegate { throw new IllegalArgumentException(); } + @NonNull private static Direction getDirection(int direction) { for (Direction d : Direction.values()) { if (direction == d.nativeInt) { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java index 3ae10f2f9a36..48ca7d8d5fb6 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -50,6 +50,7 @@ import java.lang.ref.SoftReference; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Arrays; +import java.util.Comparator; import java.util.EnumMap; import java.util.EnumSet; import java.util.HashMap; @@ -93,7 +94,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { /** * Same as sRMap except for int[] instead of int resources. This is for android.R only. */ - private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>(); + private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>(384); /** * Reverse map compared to sRMap, resource type -> (resource name -> id). * This is for com.android.internal.R. @@ -182,7 +183,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { */ private static LayoutLog sCurrentLog = sDefaultLog; - private static final int LAST_SUPPORTED_FEATURE = Features.RENDER_ALL_DRAWABLE_STATES; + private static final int LAST_SUPPORTED_FEATURE = Features.RECYCLER_VIEW_ADAPTER; @Override public int getApiLevel() { @@ -249,37 +250,56 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { // the internal version), and put the content in the maps. try { Class<?> r = com.android.internal.R.class; + // Parse the styleable class first, since it may contribute to attr values. + parseStyleable(); for (Class<?> inner : r.getDeclaredClasses()) { + if (inner == com.android.internal.R.styleable.class) { + // Already handled the styleable case. Not skipping attr, as there may be attrs + // that are not referenced from styleables. + continue; + } String resTypeName = inner.getSimpleName(); ResourceType resType = ResourceType.getEnum(resTypeName); if (resType != null) { - Map<String, Integer> fullMap = new HashMap<String, Integer>(); - sRevRMap.put(resType, fullMap); + Map<String, Integer> fullMap = null; + switch (resType) { + case ATTR: + fullMap = sRevRMap.get(ResourceType.ATTR); + break; + case STRING: + case STYLE: + // Slightly less than thousand entries in each. + fullMap = new HashMap<String, Integer>(1280); + // no break. + default: + if (fullMap == null) { + fullMap = new HashMap<String, Integer>(); + } + sRevRMap.put(resType, fullMap); + } for (Field f : inner.getDeclaredFields()) { // only process static final fields. Since the final attribute may have // been altered by layoutlib_create, we only check static - int modifiers = f.getModifiers(); - if (Modifier.isStatic(modifiers)) { - Class<?> type = f.getType(); - if (type.isArray() && type.getComponentType() == int.class) { - // if the object is an int[] we put it in sRArrayMap using an IntArray - // wrapper that properly implements equals and hashcode for the array - // objects, as required by the map contract. - sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName()); - } else if (type == int.class) { - Integer value = (Integer) f.get(null); - sRMap.put(value, Pair.of(resType, f.getName())); - fullMap.put(f.getName(), value); - } else { - assert false; - } + if (!isValidRField(f)) { + continue; + } + Class<?> type = f.getType(); + if (type.isArray()) { + // if the object is an int[] we put it in sRArrayMap using an IntArray + // wrapper that properly implements equals and hashcode for the array + // objects, as required by the map contract. + sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName()); + } else { + Integer value = (Integer) f.get(null); + sRMap.put(value, Pair.of(resType, f.getName())); + fullMap.put(f.getName(), value); } } } } - } catch (Throwable throwable) { + } catch (Exception throwable) { if (log != null) { log.error(LayoutLog.TAG_BROKEN, "Failed to load com.android.internal.R from the layout library jar", @@ -291,6 +311,90 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { return true; } + /** + * Tests if the field is pubic, static and one of int or int[]. + */ + private static boolean isValidRField(Field field) { + int modifiers = field.getModifiers(); + boolean isAcceptable = Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers); + Class<?> type = field.getType(); + return isAcceptable && type == int.class || + (type.isArray() && type.getComponentType() == int.class); + + } + + private static void parseStyleable() throws Exception { + // R.attr doesn't contain all the needed values. There are too many resources in the + // framework for all to be in the R class. Only the ones specified manually in + // res/values/symbols.xml are put in R class. Since, we need to create a map of all attr + // values, we try and find them from the styleables. + + // There were 1500 elements in this map at M timeframe. + Map<String, Integer> revRAttrMap = new HashMap<String, Integer>(2048); + sRevRMap.put(ResourceType.ATTR, revRAttrMap); + // There were 2000 elements in this map at M timeframe. + Map<String, Integer> revRStyleableMap = new HashMap<String, Integer>(3072); + sRevRMap.put(ResourceType.STYLEABLE, revRStyleableMap); + Class<?> c = com.android.internal.R.styleable.class; + Field[] fields = c.getDeclaredFields(); + // Sort the fields to bring all arrays to the beginning, so that indices into the array are + // able to refer back to the arrays (i.e. no forward references). + Arrays.sort(fields, new Comparator<Field>() { + @Override + public int compare(Field o1, Field o2) { + if (o1 == o2) { + return 0; + } + Class<?> t1 = o1.getType(); + Class<?> t2 = o2.getType(); + if (t1.isArray() && !t2.isArray()) { + return -1; + } else if (t2.isArray() && !t1.isArray()) { + return 1; + } + return o1.getName().compareTo(o2.getName()); + } + }); + Map<String, int[]> styleables = new HashMap<String, int[]>(); + for (Field field : fields) { + if (!isValidRField(field)) { + // Only consider public static fields that are int or int[]. + // Don't check the final flag as it may have been modified by layoutlib_create. + continue; + } + String name = field.getName(); + if (field.getType().isArray()) { + int[] styleableValue = (int[]) field.get(null); + sRArrayMap.put(new IntArray(styleableValue), name); + styleables.put(name, styleableValue); + continue; + } + // Not an array. + String arrayName = name; + int[] arrayValue = null; + int index; + while ((index = arrayName.lastIndexOf('_')) >= 0) { + // Find the name of the corresponding styleable. + // Search in reverse order so that attrs like LinearLayout_Layout_layout_gravity + // are mapped to LinearLayout_Layout and not to LinearLayout. + arrayName = arrayName.substring(0, index); + arrayValue = styleables.get(arrayName); + if (arrayValue != null) { + break; + } + } + index = (Integer) field.get(null); + if (arrayValue != null) { + String attrName = name.substring(arrayName.length() + 1); + int attrValue = arrayValue[index]; + sRMap.put(attrValue, Pair.of(ResourceType.ATTR, attrName)); + revRAttrMap.put(attrName, attrValue); + } + sRMap.put(index, Pair.of(ResourceType.STYLEABLE, name)); + revRStyleableMap.put(name, index); + } + } + @Override public boolean dispose() { BridgeAssetManager.clearSystem(); @@ -490,9 +594,13 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { /** * Returns the integer id of a framework resource, from a given resource type and resource name. + * <p/> + * If no resource is found, it creates a dynamic id for the resource. + * * @param type the type of the resource * @param name the name of the resource. - * @return an {@link Integer} containing the resource id, or null if no resource were found. + * + * @return an {@link Integer} containing the resource id. */ @NonNull public static Integer getResourceId(ResourceType type, String name) { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java index 4a9f7187b29c..44a9aad55daa 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java @@ -30,6 +30,10 @@ import android.widget.TextView; */ public class MockView extends TextView { + public MockView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + public MockView(Context context, AttributeSet attrs, int defStyle) { this(context, attrs, defStyle, 0); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java index 90ef28cd0fc3..f04654eded0f 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java @@ -172,6 +172,11 @@ public class BridgePackageManager extends PackageManager { } @Override + public String getPermissionControllerPackageName() { + return null; + } + + @Override public boolean addPermission(PermissionInfo info) { return false; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java index 0426907b3a4c..aa873a6476ae 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java @@ -18,14 +18,12 @@ package com.android.layoutlib.bridge.android.support; import com.android.ide.common.rendering.api.LayoutLog; import com.android.layoutlib.bridge.Bridge; +import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException; import android.annotation.NonNull; import android.annotation.Nullable; import android.view.View; -import java.lang.reflect.Method; - -import static com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException; import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod; import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke; @@ -53,10 +51,7 @@ public class DesignLibUtil { return; } try { - Method setTitle = getMethod(view.getClass(), "setTitle", CharSequence.class); - if (setTitle != null) { - invoke(setTitle, view, title); - } + invoke(getMethod(view.getClass(), "setTitle", CharSequence.class), view, title); } catch (ReflectionException e) { Bridge.getLog().warning(LayoutLog.TAG_INFO, "Error occurred while trying to set title.", e); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java index d14c80b90890..d432120ccb6f 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java @@ -21,16 +21,13 @@ import com.android.ide.common.rendering.api.LayoutlibCallback; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.RenderParamsFlags; -import com.android.layoutlib.bridge.util.ReflectionUtils; +import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.view.View; -import java.lang.reflect.Method; - -import static com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException; import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause; import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod; import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke; @@ -98,8 +95,7 @@ public class RecyclerViewUtil { @Nullable private static Object getLayoutManager(View recyclerView) throws ReflectionException { - Method getLayoutManager = getMethod(recyclerView.getClass(), "getLayoutManager"); - return getLayoutManager != null ? invoke(getLayoutManager, recyclerView) : null; + return invoke(getMethod(recyclerView.getClass(), "getLayoutManager"), recyclerView); } @Nullable @@ -127,10 +123,7 @@ public class RecyclerViewUtil { private static void setProperty(@NonNull Object object, @NonNull Class<?> propertyClass, @Nullable Object propertyValue, @NonNull String propertySetter) throws ReflectionException { - Method setter = getMethod(object.getClass(), propertySetter, propertyClass); - if (setter != null) { - invoke(setter, object, propertyValue); - } + invoke(getMethod(object.getClass(), propertySetter, propertyClass), object, propertyValue); } /** diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java index 958b7aa02ea2..868c6d328e8e 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java @@ -31,7 +31,6 @@ import android.graphics.drawable.Drawable; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.widget.FrameLayout; import java.lang.reflect.InvocationTargetException; @@ -51,9 +50,8 @@ public class AppCompatActionBar extends BridgeActionBar { /** * Inflate the action bar and attach it to {@code parentView} */ - public AppCompatActionBar(@NonNull BridgeContext context, @NonNull SessionParams params, - @NonNull ViewGroup parentView) { - super(context, params, parentView); + public AppCompatActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) { + super(context, params); int contentRootId = context.getProjectResourceValue(ResourceType.ID, "action_bar_activity_content", 0); View contentView = getDecorContent().findViewById(contentRootId); @@ -64,7 +62,9 @@ public class AppCompatActionBar extends BridgeActionBar { // Something went wrong. Create a new FrameLayout in the enclosing layout. FrameLayout contentRoot = new FrameLayout(context); setMatchParent(contentRoot); - mEnclosingLayout.addView(contentRoot); + if (mEnclosingLayout != null) { + mEnclosingLayout.addView(contentRoot); + } setContentRoot(contentRoot); } try { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java index a19b689f116c..f900b451fa6e 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java @@ -24,6 +24,7 @@ import com.android.ide.common.rendering.api.SessionParams; import com.android.layoutlib.bridge.android.BridgeContext; import android.annotation.NonNull; +import android.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -39,7 +40,7 @@ public abstract class BridgeActionBar { @NonNull protected final BridgeContext mBridgeContext; @NonNull protected final SessionParams mParams; // A Layout that contains the inflated action bar. The menu popup is added to this layout. - @NonNull protected final ViewGroup mEnclosingLayout; + @Nullable protected final ViewGroup mEnclosingLayout; private final View mDecorContent; private final ActionBarCallback mCallback; @@ -47,8 +48,7 @@ public abstract class BridgeActionBar { @SuppressWarnings("NullableProblems") // Should be initialized by subclasses. @NonNull private FrameLayout mContentRoot; - public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params, - @NonNull ViewGroup parentView) { + public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) { mBridgeContext = context; mParams = params; mCallback = params.getLayoutlibCallback().getActionBarCallback(); @@ -75,14 +75,13 @@ public abstract class BridgeActionBar { // added. mEnclosingLayout = new RelativeLayout(mBridgeContext); setMatchParent(mEnclosingLayout); - parentView.addView(mEnclosingLayout); } else { - mEnclosingLayout = parentView; + mEnclosingLayout = null; } // Inflate action bar layout. - mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout, true); - + mDecorContent = + getInflater(context).inflate(layoutId, mEnclosingLayout, mEnclosingLayout != null); } /** @@ -153,6 +152,13 @@ public abstract class BridgeActionBar { public abstract void createMenuPopup(); + /** + * The root view that represents the action bar and possibly the content included in it. + */ + public View getRootView() { + return mEnclosingLayout == null ? mDecorContent : mEnclosingLayout; + } + public ActionBarCallback getCallBack() { return mCallback; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java index dc89d0c6546a..09937bc5ac38 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java @@ -74,8 +74,8 @@ public class Config { } public static String getTime(int platformVersion) { - if (isGreaterOrEqual(platformVersion, LOLLIPOP_MR1)) { - return "5:10"; + if (isGreaterOrEqual(platformVersion, M)) { + return "6:00"; } if (platformVersion < GINGERBREAD) { return "2:20"; @@ -95,6 +95,9 @@ public class Config { if (platformVersion < LOLLIPOP_MR1) { return "5:00"; } + if (platformVersion < M) { + return "5:10"; + } // Should never happen. return "4:04"; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java index 90a1c7556b61..b76ec1707fcc 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java @@ -16,6 +16,7 @@ package com.android.layoutlib.bridge.bars; +import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceValue; import com.android.ide.common.rendering.api.StyleResourceValue; @@ -32,7 +33,6 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.annotation.NonNull; -import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Bitmap_Delegate; @@ -68,7 +68,7 @@ abstract class CustomBar extends LinearLayout { protected abstract TextView getStyleableTextView(); protected CustomBar(BridgeContext context, int orientation, String layoutPath, - String name, int simulatedPlatformVersion) throws XmlPullParserException { + String name, int simulatedPlatformVersion) { super(context); mSimulatedPlatformVersion = simulatedPlatformVersion; setOrientation(orientation); @@ -78,14 +78,18 @@ abstract class CustomBar extends LinearLayout { setGravity(Gravity.CENTER_HORIZONTAL); } - LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( - Context.LAYOUT_INFLATER_SERVICE); + LayoutInflater inflater = LayoutInflater.from(mContext); - XmlPullParser parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath), - name); + XmlPullParser parser; + try { + parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath), name); + } catch (XmlPullParserException e) { + // Should not happen as the resource is bundled with the jar, and ParserFactory should + // have been initialized. + throw new AssertionError(e); + } - BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser( - parser, (BridgeContext) context, false /*platformFile*/); + BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(parser, context, false); try { inflater.inflate(bridgeParser, this, true); @@ -154,7 +158,7 @@ abstract class CustomBar extends LinearLayout { protected void setStyle(String themeEntryName) { - BridgeContext bridgeContext = (BridgeContext) mContext; + BridgeContext bridgeContext = getContext(); RenderResources res = bridgeContext.getRenderResources(); ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/); @@ -214,36 +218,68 @@ abstract class CustomBar extends LinearLayout { } } + @Override + public BridgeContext getContext() { + return (BridgeContext) mContext; + } + /** - * Given a theme attribute name, get the color referenced by it. The theme attribute may be - * used in a layout like "?attr/foo". + * Find the background color for this bar from the theme attributes. Only relevant to StatusBar + * and NavigationBar. * <p/> * Returns 0 if not found. * + * @param colorAttrName the attribute name for the background color + * @param translucentAttrName the attribute name for the translucency property of the bar. + * * @throws NumberFormatException if color resolved to an invalid string. */ - protected int getThemeAttrColor(@NonNull String attrName, boolean isFramework) { + protected int getBarColor(@NonNull String colorAttrName, @NonNull String translucentAttrName) { if (!Config.isGreaterOrEqual(mSimulatedPlatformVersion, LOLLIPOP)) { return 0; } - assert mContext instanceof BridgeContext; - BridgeContext context = ((BridgeContext) mContext); - RenderResources renderResources = context.getRenderResources(); + RenderResources renderResources = getContext().getRenderResources(); + // First check if the bar is translucent. + boolean translucent = ResourceHelper.getBooleanThemeValue(renderResources, + translucentAttrName, true, false); + if (translucent) { + // Keep in sync with R.color.system_bar_background_semi_transparent from system ui. + return 0x66000000; // 40% black. + } + boolean transparent = ResourceHelper.getBooleanThemeValue(renderResources, + "windowDrawsSystemBarBackgrounds", true, false); + if (transparent) { + return getColor(renderResources, colorAttrName); + } + return 0; + } + + private static int getColor(RenderResources renderResources, String attr) { // From ?attr/foo to @color/bar. This is most likely an ItemResourceValue. - ResourceValue resource = renderResources.findItemInTheme(attrName, isFramework); + ResourceValue resource = renderResources.findItemInTheme(attr, true); + // Form @color/bar to the #AARRGGBB + resource = renderResources.resolveResValue(resource); if (resource != null) { - // Form @color/bar to the #AARRGGBB - resource = renderResources.resolveResValue(resource); - } - if (resource != null && ResourceType.COLOR.equals(resource.getResourceType())) { - return ResourceHelper.getColor(resource.getValue()); + ResourceType type = resource.getResourceType(); + if (type == null || type == ResourceType.COLOR) { + // if no type is specified, the value may have been specified directly in the style + // file, rather than referencing a color resource value. + try { + return ResourceHelper.getColor(resource.getValue()); + } catch (NumberFormatException e) { + // Conversion failed. + Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, + "Theme attribute @android:" + attr + + " does not reference a color, instead is '" + + resource.getValue() + "'.", resource); + } + } } return 0; } private ResourceValue getResourceValue(String reference) { - BridgeContext bridgeContext = (BridgeContext) mContext; - RenderResources res = bridgeContext.getRenderResources(); + RenderResources res = getContext().getRenderResources(); // find the resource ResourceValue value = res.findResValue(reference, false); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java index bb3d13f50b0e..d2a5117cf866 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBar.java @@ -60,23 +60,24 @@ public class FrameworkActionBar extends BridgeActionBar { /** * Inflate the action bar and attach it to {@code parentView} */ - public FrameworkActionBar(@NonNull BridgeContext context, @NonNull SessionParams params, - @NonNull ViewGroup parentView) { - super(context, params, parentView); + public FrameworkActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) { + super(context, params); View decorContent = getDecorContent(); mActionBar = FrameworkActionBarWrapper.getActionBarWrapper(context, getCallBack(), decorContent); - FrameLayout contentRoot = (FrameLayout) mEnclosingLayout.findViewById(android.R.id.content); + FrameLayout contentRoot = (FrameLayout) decorContent.findViewById(android.R.id.content); // If something went wrong and we were not able to initialize the content root, // just add a frame layout inside this and return. if (contentRoot == null) { contentRoot = new FrameLayout(context); setMatchParent(contentRoot); - mEnclosingLayout.addView(contentRoot); + if (mEnclosingLayout != null) { + mEnclosingLayout.addView(contentRoot); + } setContentRoot(contentRoot); } else { setContentRoot(contentRoot); @@ -162,6 +163,7 @@ public class FrameworkActionBar extends BridgeActionBar { listView.setDivider(a.getDrawable(R.attr.actionBarDivider)); a.recycle(); listView.setElevation(mActionBar.getMenuPopupElevation()); + assert mEnclosingLayout != null : "Unable to find view to attach ActionMenuPopup."; mEnclosingLayout.addView(listView); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java index daad6024a8b1..af6ba2445309 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FrameworkActionBarWrapper.java @@ -79,7 +79,7 @@ public abstract class FrameworkActionBarWrapper { } } - FrameworkActionBarWrapper(@NonNull BridgeContext context, ActionBarCallback callback, + FrameworkActionBarWrapper(@NonNull BridgeContext context, @NonNull ActionBarCallback callback, @NonNull ActionBar actionBar) { mActionBar = actionBar; mCallback = callback; diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java index dcf82a3c7490..9c89bfe2a28f 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java @@ -19,8 +19,6 @@ package com.android.layoutlib.bridge.bars; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.resources.Density; -import org.xmlpull.v1.XmlPullParserException; - import android.content.Context; import android.content.pm.ApplicationInfo; import android.util.AttributeSet; @@ -33,6 +31,8 @@ public class NavigationBar extends CustomBar { /** Navigation bar background color attribute name. */ private static final String ATTR_COLOR = "navigationBarColor"; + /** Attribute for translucency property. */ + public static final String ATTR_TRANSLUCENT = "windowTranslucentNavigation"; // These correspond to @dimen/navigation_side_padding in the system ui code. private static final int PADDING_WIDTH_DEFAULT = 36; private static final int PADDING_WIDTH_SW360 = 40; @@ -49,8 +49,8 @@ public class NavigationBar extends CustomBar { * Constructor to be used when creating the {@link NavigationBar} as a regular control. * This is currently used by the theme editor. */ - public NavigationBar(Context context, AttributeSet attrs) - throws XmlPullParserException { + @SuppressWarnings("unused") + public NavigationBar(Context context, AttributeSet attrs) { this((BridgeContext) context, Density.getEnum(((BridgeContext) context).getMetrics().densityDpi), LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically @@ -61,11 +61,11 @@ public class NavigationBar extends CustomBar { } public NavigationBar(BridgeContext context, Density density, int orientation, boolean isRtl, - boolean rtlEnabled, int simulatedPlatformVersion) throws XmlPullParserException { + boolean rtlEnabled, int simulatedPlatformVersion) { super(context, orientation, getShortestWidth(context)>= 600 ? LAYOUT_600DP_XML : LAYOUT_XML, "navigation_bar.xml", simulatedPlatformVersion); - int color = getThemeAttrColor(ATTR_COLOR, true); + int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT); setBackgroundColor(color == 0 ? 0xFF000000 : color); // Cannot access the inside items through id because no R.id values have been diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java index a0ed0e86d27f..2dc7c65e2085 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java @@ -26,6 +26,7 @@ import com.android.resources.Density; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; +import android.content.pm.ApplicationInfo; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.Gravity; @@ -42,22 +43,26 @@ public class StatusBar extends CustomBar { private final int mSimulatedPlatformVersion; /** Status bar background color attribute name. */ private static final String ATTR_COLOR = "statusBarColor"; + /** Attribute for translucency property. */ + public static final String ATTR_TRANSLUCENT = "windowTranslucentStatus"; /** * Constructor to be used when creating the {@link StatusBar} as a regular control. This * is currently used by the theme editor. */ - public StatusBar(Context context, AttributeSet attrs) throws XmlPullParserException { + @SuppressWarnings("UnusedParameters") + public StatusBar(Context context, AttributeSet attrs) { this((BridgeContext) context, Density.getEnum(((BridgeContext) context).getMetrics().densityDpi), - LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically ((BridgeContext) context).getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL, + (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0, context.getApplicationInfo().targetSdkVersion); } - public StatusBar(BridgeContext context, Density density, int direction, boolean RtlEnabled, - int simulatedPlatformVersion) throws XmlPullParserException { + @SuppressWarnings("UnusedParameters") + public StatusBar(BridgeContext context, Density density, boolean isRtl, boolean rtlEnabled, + int simulatedPlatformVersion) { // FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar. super(context, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml", simulatedPlatformVersion); @@ -66,7 +71,7 @@ public class StatusBar extends CustomBar { // FIXME: use FILL_H? setGravity(Gravity.START | Gravity.TOP | Gravity.RIGHT); - int color = getThemeAttrColor(ATTR_COLOR, true); + int color = getBarColor(ATTR_COLOR, ATTR_TRANSLUCENT); setBackgroundColor(color == 0 ? Config.getStatusBarColor(simulatedPlatformVersion) : color); // Cannot access the inside items through id because no R.id values have been diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java index c610601ef019..4fe1001d9229 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java @@ -27,8 +27,7 @@ public class TitleBar extends CustomBar { private TextView mTextView; - public TitleBar(BridgeContext context, String label, int simulatedPlatformVersion) - throws XmlPullParserException { + public TitleBar(BridgeContext context, String label, int simulatedPlatformVersion) { super(context, LinearLayout.HORIZONTAL, "/bars/title_bar.xml", "title_bar.xml", simulatedPlatformVersion); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java new file mode 100644 index 000000000000..c72c97930b26 --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/Layout.java @@ -0,0 +1,470 @@ +/* + * 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.layoutlib.bridge.impl; + +import com.android.ide.common.rendering.api.HardwareConfig; +import com.android.ide.common.rendering.api.RenderResources; +import com.android.ide.common.rendering.api.ResourceValue; +import com.android.ide.common.rendering.api.SessionParams; +import com.android.ide.common.rendering.api.StyleResourceValue; +import com.android.layoutlib.bridge.Bridge; +import com.android.layoutlib.bridge.android.BridgeContext; +import com.android.layoutlib.bridge.bars.AppCompatActionBar; +import com.android.layoutlib.bridge.bars.BridgeActionBar; +import com.android.layoutlib.bridge.bars.Config; +import com.android.layoutlib.bridge.bars.FrameworkActionBar; +import com.android.layoutlib.bridge.bars.NavigationBar; +import com.android.layoutlib.bridge.bars.StatusBar; +import com.android.layoutlib.bridge.bars.TitleBar; +import com.android.resources.Density; +import com.android.resources.ResourceType; +import com.android.resources.ScreenOrientation; + +import android.annotation.NonNull; +import android.graphics.drawable.Drawable; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; + +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.widget.LinearLayout.VERTICAL; +import static com.android.layoutlib.bridge.impl.ResourceHelper.getBooleanThemeValue; + +/** + * The Layout used to create the system decor. + * + * The layout inflated will contain a content frame where the user's layout can be inflated. + * <pre> + * +-------------------------------------------------+---+ + * | Status bar | N | + * +-------------------------------------------------+ a | + * | Title/Action bar (optional) | v | + * +-------------------------------------------------+ | + * | Content, vertical extending | b | + * | | a | + * | | r | + * +-------------------------------------------------+---+ + * </pre> + * or + * <pre> + * +-------------------------------------+ + * | Status bar | + * +-------------------------------------+ + * | Title/Action bar (optional) | + * +-------------------------------------+ + * | Content, vertical extending | + * | | + * | | + * +-------------------------------------+ + * | Nav bar | + * +-------------------------------------+ + * </pre> + * + */ +class Layout extends RelativeLayout { + + // Theme attributes used for configuring appearance of the system decor. + private static final String ATTR_WINDOW_FLOATING = "windowIsFloating"; + private static final String ATTR_WINDOW_BACKGROUND = "windowBackground"; + private static final String ATTR_WINDOW_FULL_SCREEN = "windowFullscreen"; + private static final String ATTR_NAV_BAR_HEIGHT = "navigation_bar_height"; + private static final String ATTR_NAV_BAR_WIDTH = "navigation_bar_width"; + private static final String ATTR_STATUS_BAR_HEIGHT = "status_bar_height"; + private static final String ATTR_WINDOW_ACTION_BAR = "windowActionBar"; + private static final String ATTR_ACTION_BAR_SIZE = "actionBarSize"; + private static final String ATTR_WINDOW_NO_TITLE = "windowNoTitle"; + private static final String ATTR_WINDOW_TITLE_SIZE = "windowTitleSize"; + private static final String ATTR_WINDOW_TRANSLUCENT_STATUS = StatusBar.ATTR_TRANSLUCENT; + private static final String ATTR_WINDOW_TRANSLUCENT_NAV = NavigationBar.ATTR_TRANSLUCENT; + private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat"; + + // Default sizes + private static final int DEFAULT_STATUS_BAR_HEIGHT = 25; + private static final int DEFAULT_TITLE_BAR_HEIGHT = 25; + private static final int DEFAULT_NAV_BAR_SIZE = 48; + + // Ids assigned to components created. This is so that we can refer to other components in + // layout params. + private static final String ID_NAV_BAR = "navBar"; + private static final String ID_STATUS_BAR = "statusBar"; + private static final String ID_TITLE_BAR = "titleBar"; + // Prefix used with the above ids in order to make them unique in framework namespace. + private static final String ID_PREFIX = "android_layoutlib_"; + + /** + * Temporarily store the builder so that it doesn't have to be passed to all methods used + * during inflation. + */ + private Builder mBuilder; + + /** + * This holds user's layout. + */ + private FrameLayout mContentRoot; + + public Layout(@NonNull Builder builder) { + super(builder.mContext); + mBuilder = builder; + if (builder.mWindowBackground != null) { + Drawable d = ResourceHelper.getDrawable(builder.mWindowBackground, builder.mContext); + setBackground(d); + } + + int simulatedPlatformVersion = getParams().getSimulatedPlatformVersion(); + HardwareConfig hwConfig = getParams().getHardwareConfig(); + Density density = hwConfig.getDensity(); + boolean isRtl = Bridge.isLocaleRtl(getParams().getLocale()); + + NavigationBar navBar = null; + if (mBuilder.hasNavBar()) { + navBar = createNavBar(getContext(), density, isRtl, getParams().isRtlSupported(), + simulatedPlatformVersion); + } + + StatusBar statusBar = null; + if (builder.mStatusBarSize > 0) { + statusBar = createStatusBar(getContext(), density, isRtl, getParams().isRtlSupported(), + simulatedPlatformVersion); + } + + View actionBar = null; + TitleBar titleBar = null; + if (builder.mActionBarSize > 0) { + BridgeActionBar bar = createActionBar(getContext(), getParams()); + mContentRoot = bar.getContentRoot(); + actionBar = bar.getRootView(); + } else if (mBuilder.mTitleBarSize > 0) { + titleBar = createTitleBar(getContext(), getParams().getAppLabel(), + simulatedPlatformVersion); + } + + addViews(titleBar, mContentRoot == null ? (mContentRoot = createContentFrame()) : actionBar, + statusBar, navBar); + // Done with the builder. Don't hold a reference to it. + mBuilder = null; + } + + @NonNull + private FrameLayout createContentFrame() { + FrameLayout contentRoot = new FrameLayout(getContext()); + LayoutParams params = createLayoutParams(MATCH_PARENT, MATCH_PARENT); + int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE; + if (mBuilder.hasNavBar() && mBuilder.solidBars()) { + params.addRule(rule, getId(ID_NAV_BAR)); + } + int below = -1; + if (mBuilder.mActionBarSize <= 0 && mBuilder.mTitleBarSize > 0) { + below = getId(ID_TITLE_BAR); + } else if (mBuilder.hasStatusBar() && mBuilder.solidBars()) { + below = getId(ID_STATUS_BAR); + } + if (below != -1) { + params.addRule(BELOW, below); + } + contentRoot.setLayoutParams(params); + return contentRoot; + } + + @NonNull + private LayoutParams createLayoutParams(int width, int height) { + DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); + if (width > 0) { + width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, width, metrics); + } + if (height > 0) { + height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, height, metrics); + } + return new LayoutParams(width, height); + } + + @NonNull + public FrameLayout getContentRoot() { + return mContentRoot; + } + + @NonNull + private SessionParams getParams() { + return mBuilder.mParams; + } + + @NonNull + @Override + public BridgeContext getContext(){ + return (BridgeContext) super.getContext(); + } + + /** + * @param isRtl whether the current locale is an RTL locale. + * @param isRtlSupported whether the applications supports RTL (i.e. has supportsRtl=true + * in the manifest and targetSdkVersion >= 17. + */ + @NonNull + private StatusBar createStatusBar(BridgeContext context, Density density, boolean isRtl, + boolean isRtlSupported, int simulatedPlatformVersion) { + StatusBar statusBar = + new StatusBar(context, density, isRtl, isRtlSupported, simulatedPlatformVersion); + LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mStatusBarSize); + if (mBuilder.isNavBarVertical()) { + params.addRule(START_OF, getId(ID_NAV_BAR)); + } + statusBar.setLayoutParams(params); + statusBar.setId(getId(ID_STATUS_BAR)); + return statusBar; + } + + private BridgeActionBar createActionBar(@NonNull BridgeContext context, + @NonNull SessionParams params) { + BridgeActionBar actionBar; + if (mBuilder.isThemeAppCompat()) { + actionBar = new AppCompatActionBar(context, params); + } else { + actionBar = new FrameworkActionBar(context, params); + } + LayoutParams layoutParams = createLayoutParams(MATCH_PARENT, MATCH_PARENT); + int rule = mBuilder.isNavBarVertical() ? START_OF : ABOVE; + if (mBuilder.hasNavBar() && mBuilder.solidBars()) { + layoutParams.addRule(rule, getId(ID_NAV_BAR)); + } + if (mBuilder.hasStatusBar() && mBuilder.solidBars()) { + layoutParams.addRule(BELOW, getId(ID_STATUS_BAR)); + } + actionBar.getRootView().setLayoutParams(layoutParams); + actionBar.createMenuPopup(); + return actionBar; + } + + @NonNull + private TitleBar createTitleBar(BridgeContext context, String title, + int simulatedPlatformVersion) { + TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion); + LayoutParams params = createLayoutParams(MATCH_PARENT, mBuilder.mTitleBarSize); + if (mBuilder.hasStatusBar() && mBuilder.solidBars()) { + params.addRule(BELOW, getId(ID_STATUS_BAR)); + } + if (mBuilder.isNavBarVertical() && mBuilder.solidBars()) { + params.addRule(START_OF, getId(ID_NAV_BAR)); + } + titleBar.setLayoutParams(params); + titleBar.setId(getId(ID_TITLE_BAR)); + return titleBar; + } + + /** + * @param isRtl whether the current locale is an RTL locale. + * @param isRtlSupported whether the applications supports RTL (i.e. has supportsRtl=true + * in the manifest and targetSdkVersion >= 17. + */ + @NonNull + private NavigationBar createNavBar(BridgeContext context, Density density, boolean isRtl, + boolean isRtlSupported, int simulatedPlatformVersion) { + int orientation = mBuilder.mNavBarOrientation; + int size = mBuilder.mNavBarSize; + NavigationBar navBar = new NavigationBar(context, density, orientation, isRtl, + isRtlSupported, simulatedPlatformVersion); + boolean isVertical = mBuilder.isNavBarVertical(); + int w = isVertical ? size : MATCH_PARENT; + int h = isVertical ? MATCH_PARENT : size; + LayoutParams params = createLayoutParams(w, h); + params.addRule(isVertical ? ALIGN_PARENT_END : ALIGN_PARENT_BOTTOM); + navBar.setLayoutParams(params); + navBar.setId(getId(ID_NAV_BAR)); + return navBar; + } + + private void addViews(@NonNull View... views) { + for (View view : views) { + if (view != null) { + addView(view); + } + } + } + + private int getId(String name) { + return Bridge.getResourceId(ResourceType.ID, ID_PREFIX + name); + } + + /** + * A helper class to help initialize the Layout. + */ + static class Builder { + @NonNull + private final SessionParams mParams; + @NonNull + private final BridgeContext mContext; + private final RenderResources mResources; + + private final boolean mWindowIsFloating; + private ResourceValue mWindowBackground; + private int mStatusBarSize; + private int mNavBarSize; + private int mNavBarOrientation; + private int mActionBarSize; + private int mTitleBarSize; + private boolean mTranslucentStatus; + private boolean mTranslucentNav; + + private Boolean mIsThemeAppCompat; + + public Builder(@NonNull SessionParams params, @NonNull BridgeContext context) { + mParams = params; + mContext = context; + mResources = mParams.getResources(); + mWindowIsFloating = getBooleanThemeValue(mResources, ATTR_WINDOW_FLOATING, true, true); + + findBackground(); + + if (!mParams.isForceNoDecor()) { + findStatusBar(); + findActionBar(); + findNavBar(); + } + } + + private void findBackground() { + if (!mParams.isBgColorOverridden()) { + mWindowBackground = mResources.findItemInTheme(ATTR_WINDOW_BACKGROUND, true); + mWindowBackground = mResources.resolveResValue(mWindowBackground); + } + } + + private void findStatusBar() { + boolean windowFullScreen = + getBooleanThemeValue(mResources, ATTR_WINDOW_FULL_SCREEN, true, false); + if (!windowFullScreen && !mWindowIsFloating) { + mStatusBarSize = + getDimension(ATTR_STATUS_BAR_HEIGHT, true, DEFAULT_STATUS_BAR_HEIGHT); + mTranslucentStatus = getBooleanThemeValue(mResources, + ATTR_WINDOW_TRANSLUCENT_STATUS, true, false); + } + } + + private void findActionBar() { + if (mWindowIsFloating) { + return; + } + // Check if an actionbar is needed + boolean windowActionBar = getBooleanThemeValue(mResources, ATTR_WINDOW_ACTION_BAR, + !isThemeAppCompat(), true); + if (windowActionBar) { + mActionBarSize = getDimension(ATTR_ACTION_BAR_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT); + } else { + // Maybe the gingerbread era title bar is needed + boolean windowNoTitle = + getBooleanThemeValue(mResources, ATTR_WINDOW_NO_TITLE, true, false); + if (!windowNoTitle) { + mTitleBarSize = + getDimension(ATTR_WINDOW_TITLE_SIZE, true, DEFAULT_TITLE_BAR_HEIGHT); + } + } + } + + private void findNavBar() { + if (hasSoftwareButtons() && !mWindowIsFloating) { + + // get orientation + HardwareConfig hwConfig = mParams.getHardwareConfig(); + boolean barOnBottom = true; + + if (hwConfig.getOrientation() == ScreenOrientation.LANDSCAPE) { + int shortSize = hwConfig.getScreenHeight(); + int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / + hwConfig.getDensity().getDpiValue(); + + // 0-599dp: "phone" UI with bar on the side + // 600+dp: "tablet" UI with bar on the bottom + barOnBottom = shortSizeDp >= 600; + } + + mNavBarOrientation = barOnBottom ? LinearLayout.HORIZONTAL : VERTICAL; + mNavBarSize = getDimension(barOnBottom ? ATTR_NAV_BAR_HEIGHT : ATTR_NAV_BAR_WIDTH, + true, DEFAULT_NAV_BAR_SIZE); + mTranslucentNav = getBooleanThemeValue(mResources, + ATTR_WINDOW_TRANSLUCENT_NAV, true, false); + } + } + + private int getDimension(String attr, boolean isFramework, int defaultValue) { + ResourceValue value = mResources.findItemInTheme(attr, isFramework); + value = mResources.resolveResValue(value); + if (value != null) { + TypedValue typedValue = ResourceHelper.getValue(attr, value.getValue(), true); + if (typedValue != null) { + return (int) typedValue.getDimension(mContext.getMetrics()); + } + } + return defaultValue; + } + + private boolean hasSoftwareButtons() { + return mParams.getHardwareConfig().hasSoftwareButtons(); + } + + private boolean isThemeAppCompat() { + // If a cached value exists, return it. + if (mIsThemeAppCompat != null) { + return mIsThemeAppCompat; + } + // Ideally, we should check if the corresponding activity extends + // android.support.v7.app.ActionBarActivity, and not care about the theme name at all. + StyleResourceValue defaultTheme = mResources.getDefaultTheme(); + // We can't simply check for parent using resources.themeIsParentOf() since the + // inheritance structure isn't really what one would expect. The first common parent + // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21). + boolean isThemeAppCompat = false; + for (int i = 0; i < 50; i++) { + if (defaultTheme == null) { + break; + } + // for loop ensures that we don't run into cyclic theme inheritance. + if (defaultTheme.getName().startsWith(PREFIX_THEME_APPCOMPAT)) { + isThemeAppCompat = true; + break; + } + defaultTheme = mResources.getParent(defaultTheme); + } + mIsThemeAppCompat = isThemeAppCompat; + return isThemeAppCompat; + } + + /** + * Return true if the status bar or nav bar are present, they are not translucent (i.e + * content doesn't overlap with them). + */ + private boolean solidBars() { + return !(hasNavBar() && mTranslucentNav) && !(hasStatusBar() && mTranslucentStatus); + } + + private boolean hasNavBar() { + return Config.showOnScreenNavBar(mParams.getSimulatedPlatformVersion()) && + hasSoftwareButtons() && mNavBarSize > 0; + } + + private boolean hasStatusBar() { + return mStatusBarSize > 0; + } + + /** + * Return true if the nav bar is present and is vertical. + */ + private boolean isNavBarVertical() { + return hasNavBar() && mNavBarOrientation == VERTICAL; + } + } +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java index 23df3f1c4267..ac7c4097e271 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java @@ -29,10 +29,8 @@ import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.Result.Status; import com.android.ide.common.rendering.api.SessionParams; import com.android.ide.common.rendering.api.SessionParams.RenderingMode; -import com.android.ide.common.rendering.api.StyleResourceValue; import com.android.ide.common.rendering.api.ViewInfo; import com.android.ide.common.rendering.api.ViewType; -import com.android.internal.util.XmlUtils; import com.android.internal.view.menu.ActionMenuItemView; import com.android.internal.view.menu.BridgeMenuItemImpl; import com.android.internal.view.menu.IconMenuItemView; @@ -45,22 +43,11 @@ import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; import com.android.layoutlib.bridge.android.RenderParamsFlags; import com.android.layoutlib.bridge.android.support.DesignLibUtil; -import com.android.layoutlib.bridge.bars.AppCompatActionBar; -import com.android.layoutlib.bridge.bars.BridgeActionBar; -import com.android.layoutlib.bridge.bars.Config; -import com.android.layoutlib.bridge.bars.FrameworkActionBar; -import com.android.layoutlib.bridge.bars.NavigationBar; -import com.android.layoutlib.bridge.bars.StatusBar; -import com.android.layoutlib.bridge.bars.TitleBar; import com.android.layoutlib.bridge.impl.binding.FakeAdapter; import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter; -import com.android.resources.Density; import com.android.resources.ResourceType; -import com.android.resources.ScreenOrientation; import com.android.util.Pair; -import org.xmlpull.v1.XmlPullParserException; - import android.animation.AnimationThread; import android.animation.Animator; import android.animation.AnimatorInflater; @@ -72,10 +59,7 @@ import android.app.Fragment_Delegate; import android.graphics.Bitmap; import android.graphics.Bitmap_Delegate; import android.graphics.Canvas; -import android.graphics.drawable.Drawable; import android.preference.Preference_Delegate; -import android.util.DisplayMetrics; -import android.util.TypedValue; import android.view.AttachInfo_Accessor; import android.view.BridgeInflater; import android.view.IWindowManager; @@ -126,33 +110,22 @@ import static com.android.layoutlib.bridge.util.ReflectionUtils.isInstanceOf; */ public class RenderSessionImpl extends RenderAction<SessionParams> { - private static final int DEFAULT_TITLE_BAR_HEIGHT = 25; - private static final int DEFAULT_STATUS_BAR_HEIGHT = 25; - // scene state private RenderSession mScene; private BridgeXmlBlockParser mBlockParser; private BridgeInflater mInflater; - private ResourceValue mWindowBackground; private ViewGroup mViewRoot; private FrameLayout mContentRoot; private Canvas mCanvas; private int mMeasuredScreenWidth = -1; private int mMeasuredScreenHeight = -1; private boolean mIsAlphaChannelImage; - private boolean mWindowIsFloating; - private Boolean mIsThemeAppCompat; - - private int mStatusBarSize; - private int mNavigationBarSize; - private int mNavigationBarOrientation = LinearLayout.HORIZONTAL; - private int mTitleBarSize; - private int mActionBarSize; // information being returned through the API private BufferedImage mImage; private List<ViewInfo> mViewInfoList; private List<ViewInfo> mSystemViewInfoList; + private Layout.Builder mLayoutBuilder; private static final class PostInflateException extends Exception { private static final long serialVersionUID = 1L; @@ -196,34 +169,24 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { SessionParams params = getParams(); BridgeContext context = getContext(); - - RenderResources resources = getParams().getResources(); - DisplayMetrics metrics = getContext().getMetrics(); - // use default of true in case it's not found to use alpha by default - mIsAlphaChannelImage = getBooleanThemeValue(resources, "windowIsFloating", true, true); - // FIXME: Find out why both variables are taking the same value. - mWindowIsFloating = getBooleanThemeValue(resources, "windowIsFloating", true, true); + mIsAlphaChannelImage = ResourceHelper.getBooleanThemeValue(params.getResources(), + "windowIsFloating", true, true); - findBackground(resources); - findStatusBar(resources, metrics); - findActionBar(resources, metrics); - findNavigationBar(resources, metrics); + mLayoutBuilder = new Layout.Builder(params, context); // FIXME: find those out, and possibly add them to the render params boolean hasNavigationBar = true; //noinspection ConstantConditions IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(), - metrics, Surface.ROTATION_0, - hasNavigationBar); + context.getMetrics(), Surface.ROTATION_0, hasNavigationBar); WindowManagerGlobal_Delegate.setWindowManagerService(iwm); // build the inflater and parser. mInflater = new BridgeInflater(context, params.getLayoutlibCallback()); context.setBridgeInflater(mInflater); - mBlockParser = new BridgeXmlBlockParser( - params.getLayoutDescription(), context, false /* platformResourceFlag */); + mBlockParser = new BridgeXmlBlockParser(params.getLayoutDescription(), context, false); return SUCCESS.createResult(); } @@ -240,164 +203,11 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { checkLock(); try { - + mViewRoot = new Layout(mLayoutBuilder); + mLayoutBuilder = null; // Done with the builder. + mContentRoot = ((Layout) mViewRoot).getContentRoot(); SessionParams params = getParams(); - HardwareConfig hardwareConfig = params.getHardwareConfig(); BridgeContext context = getContext(); - boolean isRtl = Bridge.isLocaleRtl(params.getLocale()); - int layoutDirection = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; - - // the view group that receives the window background. - ViewGroup backgroundView; - - if (mWindowIsFloating || params.isForceNoDecor()) { - backgroundView = mViewRoot = mContentRoot = new FrameLayout(context); - mViewRoot.setLayoutDirection(layoutDirection); - } else { - int simulatedPlatformVersion = params.getSimulatedPlatformVersion(); - if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) { - /* - * This is a special case where the navigation bar is on the right. - +-------------------------------------------------+---+ - | Status bar (always) | | - +-------------------------------------------------+ | - | (Layout with background drawable) | | - | +---------------------------------------------+ | | - | | Title/Action bar (optional) | | | - | +---------------------------------------------+ | | - | | Content, vertical extending | | | - | | | | | - | +---------------------------------------------+ | | - +-------------------------------------------------+---+ - - So we create a horizontal layout, with the nav bar on the right, - and the left part is the normal layout below without the nav bar at - the bottom - */ - LinearLayout topLayout = new LinearLayout(context); - topLayout.setLayoutDirection(layoutDirection); - mViewRoot = topLayout; - topLayout.setOrientation(LinearLayout.HORIZONTAL); - - if (Config.showOnScreenNavBar(simulatedPlatformVersion)) { - try { - NavigationBar navigationBar = createNavigationBar(context, - hardwareConfig.getDensity(), isRtl, params.isRtlSupported(), - simulatedPlatformVersion); - topLayout.addView(navigationBar); - } catch (XmlPullParserException ignored) { - } - } - } - - /* - * we're creating the following layout - * - +-------------------------------------------------+ - | Status bar (always) | - +-------------------------------------------------+ - | (Layout with background drawable) | - | +---------------------------------------------+ | - | | Title/Action bar (optional) | | - | +---------------------------------------------+ | - | | Content, vertical extending | | - | | | | - | +---------------------------------------------+ | - +-------------------------------------------------+ - | Navigation bar for soft buttons, maybe see above| - +-------------------------------------------------+ - - */ - - LinearLayout topLayout = new LinearLayout(context); - topLayout.setOrientation(LinearLayout.VERTICAL); - topLayout.setLayoutDirection(layoutDirection); - // if we don't already have a view root this is it - if (mViewRoot == null) { - mViewRoot = topLayout; - } else { - int topLayoutWidth = - params.getHardwareConfig().getScreenWidth() - mNavigationBarSize; - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( - topLayoutWidth, LayoutParams.MATCH_PARENT); - topLayout.setLayoutParams(layoutParams); - - // this is the case of soft buttons + vertical bar. - // this top layout is the first layout in the horizontal layout. see above) - if (isRtl && params.isRtlSupported()) { - // If RTL is enabled, layoutlib will mirror the layouts. So, add the - // topLayout to the right of Navigation Bar and layoutlib will draw it - // to the left. - mViewRoot.addView(topLayout); - } else { - // Add the top layout to the left of the Navigation Bar. - mViewRoot.addView(topLayout, 0); - } - } - - if (mStatusBarSize > 0) { - // system bar - try { - StatusBar statusBar = createStatusBar(context, hardwareConfig.getDensity(), - layoutDirection, params.isRtlSupported(), - simulatedPlatformVersion); - topLayout.addView(statusBar); - } catch (XmlPullParserException ignored) { - - } - } - - LinearLayout backgroundLayout = new LinearLayout(context); - backgroundView = backgroundLayout; - backgroundLayout.setOrientation(LinearLayout.VERTICAL); - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, 0); - layoutParams.weight = 1; - backgroundLayout.setLayoutParams(layoutParams); - topLayout.addView(backgroundLayout); - - - // if the theme says no title/action bar, then the size will be 0 - if (mActionBarSize > 0) { - BridgeActionBar actionBar = createActionBar(context, params, backgroundLayout); - actionBar.createMenuPopup(); - mContentRoot = actionBar.getContentRoot(); - } else if (mTitleBarSize > 0) { - try { - TitleBar titleBar = createTitleBar(context, - params.getAppLabel(), - simulatedPlatformVersion); - backgroundLayout.addView(titleBar); - } catch (XmlPullParserException ignored) { - - } - } - - // content frame - if (mContentRoot == null) { - mContentRoot = new FrameLayout(context); - layoutParams = new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, 0); - layoutParams.weight = 1; - mContentRoot.setLayoutParams(layoutParams); - backgroundLayout.addView(mContentRoot); - } - - if (Config.showOnScreenNavBar(simulatedPlatformVersion) && - mNavigationBarOrientation == LinearLayout.HORIZONTAL && - mNavigationBarSize > 0) { - // system bar - try { - NavigationBar navigationBar = createNavigationBar(context, - hardwareConfig.getDensity(), isRtl, params.isRtlSupported(), - simulatedPlatformVersion); - topLayout.addView(navigationBar); - } catch (XmlPullParserException ignored) { - - } - } - } - // Sets the project callback (custom view loader) to the fragment delegate so that // it can instantiate the custom Fragment. @@ -408,7 +218,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { View view; if (isPreference) { view = Preference_Delegate.inflatePreference(getContext(), mBlockParser, - mContentRoot); + mContentRoot); } else { view = mInflater.inflate(mBlockParser, mContentRoot); } @@ -427,12 +237,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { setActiveToolbar(view, context, params); - // get the background drawable - if (mWindowBackground != null) { - Drawable d = ResourceHelper.getDrawable(mWindowBackground, context); - backgroundView.setBackground(d); - } - return SUCCESS.createResult(); } catch (PostInflateException e) { return ERROR_INFLATION.createResult(e.getMessage(), e); @@ -526,6 +330,11 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { if (neededWidth > measuredWidth) { mMeasuredScreenWidth += neededWidth - measuredWidth; } + if (mMeasuredScreenWidth < measuredWidth) { + // If the screen width is less than the exact measured width, + // expand to match. + mMeasuredScreenWidth = measuredWidth; + } } if (renderingMode.isVertExpand()) { @@ -534,6 +343,11 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { if (neededHeight > measuredHeight) { mMeasuredScreenHeight += neededHeight - measuredHeight; } + if (mMeasuredScreenHeight < measuredHeight) { + // If the screen height is less than the exact measured height, + // expand to match. + mMeasuredScreenHeight = measuredHeight; + } } } } @@ -1063,198 +877,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } } - - private void findBackground(RenderResources resources) { - if (!getParams().isBgColorOverridden()) { - mWindowBackground = resources.findItemInTheme("windowBackground", - true /*isFrameworkAttr*/); - if (mWindowBackground != null) { - mWindowBackground = resources.resolveResValue(mWindowBackground); - } - } - } - - private boolean hasSoftwareButtons() { - return getParams().getHardwareConfig().hasSoftwareButtons(); - } - - private void findStatusBar(RenderResources resources, DisplayMetrics metrics) { - boolean windowFullscreen = getBooleanThemeValue(resources, - "windowFullscreen", false, true); - - if (!windowFullscreen && !mWindowIsFloating) { - // default value - mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT; - - // get the real value - ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, - "status_bar_height"); - - if (value != null) { - TypedValue typedValue = ResourceHelper.getValue("status_bar_height", - value.getValue(), true /*requireUnit*/); - if (typedValue != null) { - // compute the pixel value based on the display metrics - mStatusBarSize = (int)typedValue.getDimension(metrics); - } - } - } - } - - private void findActionBar(RenderResources resources, DisplayMetrics metrics) { - if (mWindowIsFloating) { - return; - } - - boolean windowActionBar = getBooleanThemeValue(resources, - "windowActionBar", true, !isThemeAppCompat(resources)); - - // if there's a value and it's false (default is true) - if (windowActionBar) { - - // default size of the window title bar - mActionBarSize = DEFAULT_TITLE_BAR_HEIGHT; - - // get value from the theme. - ResourceValue value = resources.findItemInTheme("actionBarSize", - true /*isFrameworkAttr*/); - - // resolve it - value = resources.resolveResValue(value); - - if (value != null) { - // get the numerical value, if available - TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(), - true /*requireUnit*/); - if (typedValue != null) { - // compute the pixel value based on the display metrics - mActionBarSize = (int)typedValue.getDimension(metrics); - } - } - } else { - // action bar overrides title bar so only look for this one if action bar is hidden - boolean windowNoTitle = getBooleanThemeValue(resources, "windowNoTitle", false, true); - - if (!windowNoTitle) { - - // default size of the window title bar - mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT; - - // get value from the theme. - ResourceValue value = resources.findItemInTheme("windowTitleSize", - true /*isFrameworkAttr*/); - - // resolve it - value = resources.resolveResValue(value); - - if (value != null) { - // get the numerical value, if available - TypedValue typedValue = ResourceHelper.getValue("windowTitleSize", - value.getValue(), true /*requireUnit*/); - if (typedValue != null) { - // compute the pixel value based on the display metrics - mTitleBarSize = (int)typedValue.getDimension(metrics); - } - } - } - - } - } - - private void findNavigationBar(RenderResources resources, DisplayMetrics metrics) { - if (hasSoftwareButtons() && !mWindowIsFloating) { - - // default value - mNavigationBarSize = 48; // ?? - - HardwareConfig hardwareConfig = getParams().getHardwareConfig(); - - boolean barOnBottom = true; - - if (hardwareConfig.getOrientation() == ScreenOrientation.LANDSCAPE) { - // compute the dp of the screen. - int shortSize = hardwareConfig.getScreenHeight(); - - // compute in dp - int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / - hardwareConfig.getDensity().getDpiValue(); - - // 0-599dp: "phone" UI with bar on the side - // 600+dp: "tablet" UI with bar on the bottom - barOnBottom = shortSizeDp >= 600; - } - - if (barOnBottom) { - mNavigationBarOrientation = LinearLayout.HORIZONTAL; - } else { - mNavigationBarOrientation = LinearLayout.VERTICAL; - } - - // get the real value - ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN, - barOnBottom ? "navigation_bar_height" : "navigation_bar_width"); - - if (value != null) { - TypedValue typedValue = ResourceHelper.getValue("navigation_bar_height", - value.getValue(), true /*requireUnit*/); - if (typedValue != null) { - // compute the pixel value based on the display metrics - mNavigationBarSize = (int)typedValue.getDimension(metrics); - } - } - } - } - - private boolean isThemeAppCompat(RenderResources resources) { - // Ideally, we should check if the corresponding activity extends - // android.support.v7.app.ActionBarActivity, and not care about the theme name at all. - if (mIsThemeAppCompat == null) { - StyleResourceValue defaultTheme = resources.getDefaultTheme(); - // We can't simply check for parent using resources.themeIsParentOf() since the - // inheritance structure isn't really what one would expect. The first common parent - // between Theme.AppCompat.Light and Theme.AppCompat is Theme.Material (for v21). - boolean isThemeAppCompat = false; - for (int i = 0; i < 50; i++) { - if (defaultTheme == null) { - break; - } - // for loop ensures that we don't run into cyclic theme inheritance. - if (defaultTheme.getName().startsWith("Theme.AppCompat")) { - isThemeAppCompat = true; - break; - } - defaultTheme = resources.getParent(defaultTheme); - } - mIsThemeAppCompat = isThemeAppCompat; - } - return mIsThemeAppCompat; - } - - /** - * Looks for an attribute in the current theme. - * - * @param resources the render resources - * @param name the name of the attribute - * @param defaultValue the default value. - * @param isFrameworkAttr if the attribute is in android namespace - * @return the value of the attribute or the default one if not found. - */ - private boolean getBooleanThemeValue(RenderResources resources, - String name, boolean defaultValue, boolean isFrameworkAttr) { - - ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr); - - // because it may reference something else, we resolve it. - value = resources.resolveResValue(value); - - // if there's no value, return the default. - if (value == null || value.getValue() == null) { - return defaultValue; - } - - return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue); - } - /** * Post process on a view hierarchy that was just inflated. * <p/> @@ -1727,63 +1349,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { mMeasuredScreenWidth = mMeasuredScreenHeight = -1; } - /** - * Creates the status bar with wifi and battery icons. - */ - private StatusBar createStatusBar(BridgeContext context, Density density, int direction, - boolean isRtlSupported, int platformVersion) throws XmlPullParserException { - StatusBar statusBar = new StatusBar(context, density, - direction, isRtlSupported, platformVersion); - statusBar.setLayoutParams( - new LinearLayout.LayoutParams( - LayoutParams.MATCH_PARENT, mStatusBarSize)); - return statusBar; - } - - /** - * Creates the navigation bar with back, home and recent buttons. - * - * @param isRtl true if the current locale is right-to-left - * @param isRtlSupported true is the project manifest declares that the application - * is RTL aware. - */ - private NavigationBar createNavigationBar(BridgeContext context, Density density, - boolean isRtl, boolean isRtlSupported, int simulatedPlatformVersion) - throws XmlPullParserException { - NavigationBar navigationBar = new NavigationBar(context, - density, mNavigationBarOrientation, isRtl, - isRtlSupported, simulatedPlatformVersion); - if (mNavigationBarOrientation == LinearLayout.VERTICAL) { - navigationBar.setLayoutParams(new LinearLayout.LayoutParams(mNavigationBarSize, - LayoutParams.MATCH_PARENT)); - } else { - navigationBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, - mNavigationBarSize)); - } - return navigationBar; - } - - private TitleBar createTitleBar(BridgeContext context, String title, - int simulatedPlatformVersion) - throws XmlPullParserException { - TitleBar titleBar = new TitleBar(context, title, simulatedPlatformVersion); - titleBar.setLayoutParams( - new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mTitleBarSize)); - return titleBar; - } - - /** - * Creates the action bar. Also queries the project callback for missing information. - */ - private BridgeActionBar createActionBar(BridgeContext context, SessionParams params, - ViewGroup parentView) { - if (mIsThemeAppCompat == Boolean.TRUE) { - return new AppCompatActionBar(context, params, parentView); - } else { - return new FrameworkActionBar(context, params, parentView); - } - } - public BufferedImage getImage() { return mImage; } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java index ca77193b121b..c72eeb11c62d 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java @@ -21,6 +21,7 @@ import com.android.ide.common.rendering.api.DensityBasedResourceValue; import com.android.ide.common.rendering.api.LayoutLog; import com.android.ide.common.rendering.api.RenderResources; import com.android.ide.common.rendering.api.ResourceValue; +import com.android.internal.util.XmlUtils; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; @@ -327,6 +328,25 @@ public final class ResourceHelper { return null; } + /** + * Looks for an attribute in the current theme. + * + * @param resources the render resources + * @param name the name of the attribute + * @param defaultValue the default value. + * @param isFrameworkAttr if the attribute is in android namespace + * @return the value of the attribute or the default one if not found. + */ + public static boolean getBooleanThemeValue(@NonNull RenderResources resources, String name, + boolean isFrameworkAttr, boolean defaultValue) { + ResourceValue value = resources.findItemInTheme(name, isFrameworkAttr); + value = resources.resolveResValue(value); + if (value == null) { + return defaultValue; + } + return XmlUtils.convertValueToBoolean(value.getValue(), defaultValue); + } + // ------- TypedValue stuff // This is taken from //device/libs/utils/ResourceTypes.cpp diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class Binary files differindex e172b2d9d571..6c351da69d69 100644 --- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R$layout.class diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class Binary files differindex d5b81c48b404..6d7c71995eaf 100644 --- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/build/intermediates/classes/debug/com/android/layoutlib/test/myapplication/R.class diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png Binary files differindex 9a135684f33e..336f9d8b4798 100644 --- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/array_check.png diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png Binary files differnew file mode 100644 index 000000000000..0c1621544870 --- /dev/null +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png Binary files differnew file mode 100644 index 000000000000..81755cec9b15 --- /dev/null +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml new file mode 100644 index 000000000000..2c66b7fa3596 --- /dev/null +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_horz_layout.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:padding="16dp" + android:orientation="horizontal" + android:background="#AAAAAA" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <include layout="@layout/expand_layout" + android:layout_height="wrap_content" + android:layout_width="wrap_content" /> + +</LinearLayout> + diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml new file mode 100644 index 000000000000..a255da7bcbcf --- /dev/null +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_layout.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> + +<merge xmlns:android="http://schemas.android.com/apk/res/android"> + <TextView + android:background="#FF0000" + android:textSize="200sp" + android:layout_width="200dp" + android:layout_height="200dp" /> + <TextView + android:background="#00FF00" + android:textSize="200sp" + android:layout_width="200dp" + android:layout_height="200dp" /> + <TextView + android:background="#0000FF" + android:textSize="200sp" + android:layout_width="200dp" + android:layout_height="200dp" /> + <TextView + android:background="#FF00FF" + android:textSize="200sp" + android:layout_width="200dp" + android:layout_height="200dp" /> + <TextView + android:background="#00FFFF" + android:textSize="200sp" + android:layout_width="200dp" + android:layout_height="200dp" /> +</merge> diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml new file mode 100644 index 000000000000..5319654ed659 --- /dev/null +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/expand_vert_layout.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:padding="16dp" + android:orientation="vertical" + android:background="#AAAAAA" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <include layout="@layout/expand_layout" + android:layout_height="wrap_content" + android:layout_width="wrap_content" /> + +</LinearLayout> + diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java index 272a2b86c5a1..9ebeebd49c82 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java @@ -31,6 +31,8 @@ import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator; import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback; import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser; +import com.android.resources.Density; +import com.android.resources.Navigation; import com.android.utils.ILogger; import org.junit.AfterClass; @@ -283,7 +285,7 @@ public class Main { ConfigGenerator.getEnumMap(attrs), getLayoutLog()); } - /** Text activity.xml */ + /** Test activity.xml */ @Test public void testActivity() throws ClassNotFoundException { renderAndVerify("activity.xml", "activity.png"); @@ -310,21 +312,52 @@ public class Main { sBridge = null; } + /** Test expand_layout.xml */ + @Test + public void testExpand() throws ClassNotFoundException { + // Create the layout pull parser. + LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/" + + "expand_vert_layout.xml"); + // Create LayoutLibCallback. + LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger()); + layoutLibCallback.initResources(); + + ConfigGenerator customConfigGenerator = new ConfigGenerator() + .setScreenWidth(300) + .setScreenHeight(20) + .setDensity(Density.XHIGH) + .setNavigation(Navigation.NONAV); + + SessionParams params = getSessionParams(parser, customConfigGenerator, + layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false, + RenderingMode.V_SCROLL, 22); + + renderAndVerify(params, "expand_vert_layout.png"); + + customConfigGenerator = new ConfigGenerator() + .setScreenWidth(20) + .setScreenHeight(300) + .setDensity(Density.XHIGH) + .setNavigation(Navigation.NONAV); + parser = new LayoutPullParser(APP_TEST_RES + "/layout/" + + "expand_horz_layout.xml"); + params = getSessionParams(parser, customConfigGenerator, + layoutLibCallback, "Theme.Material.NoActionBar.Fullscreen", false, + RenderingMode.H_SCROLL, 22); + + renderAndVerify(params, "expand_horz_layout.png"); + } + /** * Create a new rendering session and test that rendering given layout on nexus 5 * doesn't throw any exceptions and matches the provided image. */ - private void renderAndVerify(String layoutFileName, String goldenFileName) + private void renderAndVerify(SessionParams params, String goldenFileName) throws ClassNotFoundException { - // Create the layout pull parser. - LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/" + layoutFileName); - // Create LayoutLibCallback. - LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger()); - layoutLibCallback.initResources(); // TODO: Set up action bar handler properly to test menu rendering. // Create session params. - SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5, layoutLibCallback); RenderSession session = sBridge.createSession(params); + if (!session.getResult().isSuccess()) { getLogger().error(session.getResult().getException(), session.getResult().getErrorMessage()); @@ -344,25 +377,44 @@ public class Main { } /** + * Create a new rendering session and test that rendering given layout on nexus 5 + * doesn't throw any exceptions and matches the provided image. + */ + private void renderAndVerify(String layoutFileName, String goldenFileName) + throws ClassNotFoundException { + // Create the layout pull parser. + LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/" + layoutFileName); + // Create LayoutLibCallback. + LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger()); + layoutLibCallback.initResources(); + // TODO: Set up action bar handler properly to test menu rendering. + // Create session params. + SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5, + layoutLibCallback, "AppTheme", true, RenderingMode.NORMAL, 22); + renderAndVerify(params, goldenFileName); + } + + /** * Uses Theme.Material and Target sdk version as 22. */ private SessionParams getSessionParams(LayoutPullParser layoutParser, - ConfigGenerator configGenerator, LayoutLibTestCallback layoutLibCallback) { + ConfigGenerator configGenerator, LayoutLibTestCallback layoutLibCallback, + String themeName, boolean isProjectTheme, RenderingMode renderingMode, int targetSdk) { FolderConfiguration config = configGenerator.getFolderConfig(); ResourceResolver resourceResolver = ResourceResolver.create(sProjectResources.getConfiguredResources(config), sFrameworkRepo.getConfiguredResources(config), - "AppTheme", true); + themeName, isProjectTheme); return new SessionParams( layoutParser, - RenderingMode.NORMAL, + renderingMode, null /*used for caching*/, configGenerator.getHardwareConfig(), resourceResolver, layoutLibCallback, 0, - 22, // TODO: Make it more configurable to run tests for various versions. + targetSdk, getLayoutLog()); } diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java index 2951edb0e5ac..383168face86 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java @@ -119,6 +119,7 @@ public class Main { "android.icu.**", // needed by LayoutLib "android.annotation.NonNull", // annotations "android.annotation.Nullable", // annotations + "com.android.internal.transition.EpicenterTranslateClipReveal", }, excludeClasses, new String[] { diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index b2af044fb24d..0d95b38feb46 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -158,15 +158,12 @@ interface IWifiManager void setAllowScansWithTraffic(int enabled); int getAllowScansWithTraffic(); - void setAllowScansWhileAssociated(int enabled); - int getAllowScansWhileAssociated(); - - void setAllowNetworkSwitchingWhileAssociated(int enabled); - int getAllowNetworkSwitchingWhileAssociated(); - void setHalBasedAutojoinOffload(int enabled); int getHalBasedAutojoinOffload(); + boolean enableAutoJoinWhenAssociated(boolean enabled); + boolean getEnableAutoJoinWhenAssociated(); + WifiConnectionStatistics getConnectionStatistics(); void disableEphemeralNetwork(String SSID); diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index cc1e97666e17..8a2001267eb0 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -363,11 +363,10 @@ public class ScanResult implements Parcelable { } /** {@hide} */ - public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency, + public ScanResult(String Ssid, String BSSID, String caps, int level, int frequency, long tsf, int distCm, int distSdCm, int channelWidth, int centerFreq0, int centerFreq1, boolean is80211McRTTResponder) { - this.wifiSsid = wifiSsid; - this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE; + this.SSID = Ssid; this.BSSID = BSSID; this.capabilities = caps; this.level = level; @@ -385,6 +384,15 @@ public class ScanResult implements Parcelable { } } + /** {@hide} */ + public ScanResult(WifiSsid wifiSsid, String Ssid, String BSSID, String caps, int level, + int frequency, long tsf, int distCm, int distSdCm, int channelWidth, + int centerFreq0, int centerFreq1, boolean is80211McRTTResponder) { + this(Ssid, BSSID, caps,level, frequency, tsf, distCm, distSdCm, channelWidth, centerFreq0, + centerFreq1, is80211McRTTResponder); + this.wifiSsid = wifiSsid; + } + /** copy constructor {@hide} */ public ScanResult(ScanResult source) { if (source != null) { @@ -469,6 +477,7 @@ public class ScanResult implements Parcelable { } else { dest.writeInt(0); } + dest.writeString(SSID); dest.writeString(BSSID); dest.writeString(capabilities); dest.writeInt(level); @@ -512,6 +521,7 @@ public class ScanResult implements Parcelable { } ScanResult sr = new ScanResult( wifiSsid, + in.readString(), /* SSID */ in.readString(), /* BSSID */ in.readString(), /* capabilities */ in.readInt(), /* level */ diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index f91e0e21dbd2..cf88df42f8d3 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -669,6 +669,7 @@ public class WifiManager { try { return mService.getConfiguredNetworks(); } catch (RemoteException e) { + Log.w(TAG, "Caught RemoteException trying to get configured networks: " + e); return null; } } @@ -1302,7 +1303,7 @@ public class WifiManager { * Return the results of the latest access point scan. * @return the list of access points found in the most recent scan. An app must hold * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or - * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION} permission + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission * in order to get valid results. */ public List<ScanResult> getScanResults() { @@ -1589,6 +1590,7 @@ public class WifiManager { try { return mService.buildWifiConfig(uriString, mimeType, data); } catch (RemoteException e) { + Log.w(TAG, "Caught RemoteException trying to build wifi config: " + e); return null; } } @@ -2807,30 +2809,6 @@ public class WifiManager { } /** - * Set setting for allowing Scans when infrastructure is associated - * @hide - */ - public void setAllowScansWhileAssociated(int enabled) { - try { - mService.setAllowScansWhileAssociated(enabled); - } catch (RemoteException e) { - - } - } - - /** - * Get setting for allowing Scans when infrastructure is associated - * @hide - */ - public int getAllowScansWhileAssociated() { - try { - return mService.getAllowScansWhileAssociated(); - } catch (RemoteException e) { - } - return 0; - } - - /** * Resets all wifi manager settings back to factory defaults. * * @hide @@ -2856,48 +2834,49 @@ public class WifiManager { } /** - * Set setting for enabling autojoin Offload thru Wifi HAL layer + * Framework layer autojoin enable/disable when device is associated + * this will enable/disable autojoin scan and switch network when connected + * @return true -- if set successful false -- if set failed * @hide */ - public void setHalBasedAutojoinOffload(int enabled) { + public boolean enableAutoJoinWhenAssociated(boolean enabled) { try { - mService.setHalBasedAutojoinOffload(enabled); + return mService.enableAutoJoinWhenAssociated(enabled); } catch (RemoteException e) { - + return false; } } /** - * Get setting for enabling autojoin Offload thru Wifi HAL layer + * Get setting for Framework layer autojoin enable status * @hide */ - public int getHalBasedAutojoinOffload() { + public boolean getEnableAutoJoinWhenAssociated() { try { - return mService.getHalBasedAutojoinOffload(); + return mService.getEnableAutoJoinWhenAssociated(); } catch (RemoteException e) { + return false; } - return 0; } - /** - * Set setting for enabling network switching while wifi is associated + * Set setting for enabling autojoin Offload thru Wifi HAL layer * @hide */ - public void setAllowNetworkSwitchingWhileAssociated(int enabled) { + public void setHalBasedAutojoinOffload(int enabled) { try { - mService.setAllowNetworkSwitchingWhileAssociated(enabled); + mService.setHalBasedAutojoinOffload(enabled); } catch (RemoteException e) { } } /** - * Get setting for enabling network switching while wifi is associated + * Get setting for enabling autojoin Offload thru Wifi HAL layer * @hide */ - public int getAllowNetworkSwitchingWhileAssociated() { + public int getHalBasedAutojoinOffload() { try { - return mService.getAllowNetworkSwitchingWhileAssociated(); + return mService.getHalBasedAutojoinOffload(); } catch (RemoteException e) { } return 0; diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index a3dc07716629..a65f2508249e 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -255,9 +255,7 @@ public class WifiScanner { mResults = new ScanResult[s.mResults.length]; for (int i = 0; i < s.mResults.length; i++) { ScanResult result = s.mResults[i]; - WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(result.SSID); ScanResult newResult = new ScanResult(result); - newResult.wifiSsid = wifiSsid; mResults[i] = newResult; } } |