diff options
124 files changed, 2006 insertions, 875 deletions
diff --git a/api/current.txt b/api/current.txt index 3fd4fcb..90e44e7 100644 --- a/api/current.txt +++ b/api/current.txt @@ -215,6 +215,8 @@ package android { public static final class R.attr { ctor public R.attr(); + field public static final int __removeBeforeMRelease_leftIndents = 16844016; // 0x10104f0 + field public static final int __removeBeforeMRelease_rightIndents = 16844017; // 0x10104f1 field public static final int __reserved0 = 16844020; // 0x10104f4 field public static final int __reserved1 = 16844019; // 0x10104f3 field public static final int __reserved2 = 16843999; // 0x10104df @@ -801,7 +803,6 @@ package android { field public static final int layout_x = 16843135; // 0x101017f field public static final int layout_y = 16843136; // 0x1010180 field public static final int left = 16843181; // 0x10101ad - field public static final int leftIndents = 16844016; // 0x10104f0 field public static final int letterSpacing = 16843958; // 0x10104b6 field public static final int lineSpacingExtra = 16843287; // 0x1010217 field public static final int lineSpacingMultiplier = 16843288; // 0x1010218 @@ -826,6 +827,7 @@ package android { field public static final int listViewWhiteStyle = 16842869; // 0x1010075 field public static final int lockTaskMode = 16844015; // 0x10104ef field public static final int logo = 16843454; // 0x10102be + field public static final int logoDescription = 16844026; // 0x10104fa field public static final int longClickable = 16842982; // 0x10100e6 field public static final int loopViews = 16843527; // 0x1010307 field public static final int manageSpaceActivity = 16842756; // 0x1010004 @@ -1026,7 +1028,6 @@ package android { field public static final int reversible = 16843851; // 0x101044b field public static final int revisionCode = 16843989; // 0x10104d5 field public static final int right = 16843183; // 0x10101af - field public static final int rightIndents = 16844017; // 0x10104f1 field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093 field public static final int ringtoneType = 16843257; // 0x10101f9 field public static final int rotation = 16843558; // 0x1010326 @@ -1178,6 +1179,7 @@ package android { field public static final int submitBackground = 16843912; // 0x1010488 field public static final int subtitle = 16843473; // 0x10102d1 field public static final int subtitleTextAppearance = 16843823; // 0x101042f + field public static final int subtitleTextColor = 16844028; // 0x10104fc field public static final int subtitleTextStyle = 16843513; // 0x10102f9 field public static final int subtypeExtraValue = 16843674; // 0x101039a field public static final int subtypeId = 16843713; // 0x10103c1 @@ -1308,6 +1310,7 @@ package android { field public static final int title = 16843233; // 0x10101e1 field public static final int titleCondensed = 16843234; // 0x10101e2 field public static final int titleTextAppearance = 16843822; // 0x101042e + field public static final int titleTextColor = 16844027; // 0x10104fb field public static final int titleTextStyle = 16843512; // 0x10102f8 field public static final int toAlpha = 16843211; // 0x10101cb field public static final int toDegrees = 16843188; // 0x10101b4 @@ -3758,7 +3761,7 @@ package android.app { method public void requestUsageTimeReport(android.app.PendingIntent); method public android.os.Bundle toBundle(); method public void update(android.app.ActivityOptions); - field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.usage_time"; + field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time"; field public static final java.lang.String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages"; } @@ -4809,6 +4812,7 @@ package android.app { method public android.graphics.drawable.Icon getLargeIcon(); method public android.graphics.drawable.Icon getSmallIcon(); method public java.lang.String getSortKey(); + method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); method public void writeToParcel(android.os.Parcel, int); field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT; field public static final java.lang.String CATEGORY_ALARM = "alarm"; @@ -5193,6 +5197,7 @@ package android.app { method public void send(int, android.app.PendingIntent.OnFinished, android.os.Handler) throws android.app.PendingIntent.CanceledException; method public void send(android.content.Context, int, android.content.Intent, android.app.PendingIntent.OnFinished, android.os.Handler) throws android.app.PendingIntent.CanceledException; method public void send(android.content.Context, int, android.content.Intent, android.app.PendingIntent.OnFinished, android.os.Handler, java.lang.String) throws android.app.PendingIntent.CanceledException; + method public void send(android.content.Context, int, android.content.Intent, android.app.PendingIntent.OnFinished, android.os.Handler, java.lang.String, android.os.Bundle) throws android.app.PendingIntent.CanceledException; method public static void writePendingIntentOrNullToParcel(android.app.PendingIntent, android.os.Parcel); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.PendingIntent> CREATOR; @@ -5847,7 +5852,6 @@ package android.app.admin { field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED"; field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE"; field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME"; - field public static final java.lang.String EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS = "android.app.extra.PROVISIONING_RESET_PROTECTION_PARAMETERS"; field public static final java.lang.String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION"; field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE"; field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN"; @@ -12301,7 +12305,6 @@ package android.graphics.drawable { method public android.graphics.drawable.Drawable.ConstantState getConstantState(); method public android.graphics.drawable.Drawable getCurrent(); method public android.graphics.Rect getDirtyBounds(); - method public boolean getDither(); method public void getHotspotBounds(android.graphics.Rect); method public int getIntrinsicHeight(); method public int getIntrinsicWidth(); @@ -12318,6 +12321,7 @@ package android.graphics.drawable { method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public void invalidateSelf(); method public boolean isAutoMirrored(); + method public boolean isDither(); method public boolean isFilterBitmap(); method public boolean isStateful(); method public final boolean isVisible(); @@ -26056,6 +26060,7 @@ package android.provider { field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF"; field public static final java.lang.String EXTRA_INFO = "info"; field public static final java.lang.String EXTRA_LOADING = "loading"; + field public static final java.lang.String EXTRA_PROMPT = "android.provider.extra.PROMPT"; field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER"; } @@ -30620,10 +30625,14 @@ package android.telephony { field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool"; field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool"; field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool"; + field public static final java.lang.String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array"; + field public static final java.lang.String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array"; field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string"; field public static final java.lang.String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool"; field public static final java.lang.String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool"; field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_vibration_bool"; + field public static final java.lang.String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array"; + field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array"; field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool"; field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool"; field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool"; @@ -36808,6 +36817,8 @@ package android.view { method public boolean onRequestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent); method public boolean onStartNestedScroll(android.view.View, android.view.View, int); method public void onStopNestedScroll(android.view.View); + method public void onViewAdded(android.view.View); + method public void onViewRemoved(android.view.View); method public void recomputeViewAttributes(android.view.View); method public void removeAllViews(); method public void removeAllViewsInLayout(); @@ -41560,7 +41571,6 @@ package android.widget { method public int getInputType(); method public final android.text.method.KeyListener getKeyListener(); method public final android.text.Layout getLayout(); - method public int[] getLeftIndents(); method public float getLetterSpacing(); method public int getLineBounds(int, android.graphics.Rect); method public int getLineCount(); @@ -41583,7 +41593,6 @@ package android.widget { method public android.text.TextPaint getPaint(); method public int getPaintFlags(); method public java.lang.String getPrivateImeOptions(); - method public int[] getRightIndents(); method public int getSelectionEnd(); method public int getSelectionStart(); method public int getShadowColor(); @@ -41663,7 +41672,6 @@ package android.widget { method public void setImeActionLabel(java.lang.CharSequence, int); method public void setImeOptions(int); method public void setIncludeFontPadding(boolean); - method public void setIndents(int[], int[]); method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public void setInputType(int); method public void setKeyListener(android.text.method.KeyListener); diff --git a/api/removed.txt b/api/removed.txt index 8eb2d8e..2e6c685 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -1,11 +1,3 @@ -package android.app { - - public class Notification implements android.os.Parcelable { - method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); - } - -} - package android.content.pm { public class PackageInfo implements android.os.Parcelable { diff --git a/api/system-current.txt b/api/system-current.txt index 25ef6be..8a99eaf 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -290,6 +290,8 @@ package android { public static final class R.attr { ctor public R.attr(); + field public static final int __removeBeforeMRelease_leftIndents = 16844016; // 0x10104f0 + field public static final int __removeBeforeMRelease_rightIndents = 16844017; // 0x10104f1 field public static final int __reserved0 = 16844020; // 0x10104f4 field public static final int __reserved1 = 16844019; // 0x10104f3 field public static final int __reserved2 = 16843999; // 0x10104df @@ -876,7 +878,6 @@ package android { field public static final int layout_x = 16843135; // 0x101017f field public static final int layout_y = 16843136; // 0x1010180 field public static final int left = 16843181; // 0x10101ad - field public static final int leftIndents = 16844016; // 0x10104f0 field public static final int letterSpacing = 16843958; // 0x10104b6 field public static final int lineSpacingExtra = 16843287; // 0x1010217 field public static final int lineSpacingMultiplier = 16843288; // 0x1010218 @@ -901,6 +902,7 @@ package android { field public static final int listViewWhiteStyle = 16842869; // 0x1010075 field public static final int lockTaskMode = 16844015; // 0x10104ef field public static final int logo = 16843454; // 0x10102be + field public static final int logoDescription = 16844026; // 0x10104fa field public static final int longClickable = 16842982; // 0x10100e6 field public static final int loopViews = 16843527; // 0x1010307 field public static final int manageSpaceActivity = 16842756; // 0x1010004 @@ -1101,7 +1103,6 @@ package android { field public static final int reversible = 16843851; // 0x101044b field public static final int revisionCode = 16843989; // 0x10104d5 field public static final int right = 16843183; // 0x10101af - field public static final int rightIndents = 16844017; // 0x10104f1 field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093 field public static final int ringtoneType = 16843257; // 0x10101f9 field public static final int rotation = 16843558; // 0x1010326 @@ -1257,6 +1258,7 @@ package android { field public static final int submitBackground = 16843912; // 0x1010488 field public static final int subtitle = 16843473; // 0x10102d1 field public static final int subtitleTextAppearance = 16843823; // 0x101042f + field public static final int subtitleTextColor = 16844028; // 0x10104fc field public static final int subtitleTextStyle = 16843513; // 0x10102f9 field public static final int subtypeExtraValue = 16843674; // 0x101039a field public static final int subtypeId = 16843713; // 0x10103c1 @@ -1387,6 +1389,7 @@ package android { field public static final int title = 16843233; // 0x10101e1 field public static final int titleCondensed = 16843234; // 0x10101e2 field public static final int titleTextAppearance = 16843822; // 0x101042e + field public static final int titleTextColor = 16844027; // 0x10104fb field public static final int titleTextStyle = 16843512; // 0x10102f8 field public static final int toAlpha = 16843211; // 0x10101cb field public static final int toDegrees = 16843188; // 0x10101b4 @@ -3851,7 +3854,7 @@ package android.app { method public void requestUsageTimeReport(android.app.PendingIntent); method public android.os.Bundle toBundle(); method public void update(android.app.ActivityOptions); - field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.usage_time"; + field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time"; field public static final java.lang.String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages"; } @@ -4183,6 +4186,12 @@ package android.app { method public int getWidth(); } + public class BroadcastOptions { + method public static android.app.BroadcastOptions makeBasic(); + method public void setTemporaryAppWhitelistDuration(long); + method public android.os.Bundle toBundle(); + } + public class DatePickerDialog extends android.app.AlertDialog implements android.widget.DatePicker.OnDateChangedListener android.content.DialogInterface.OnClickListener { ctor public DatePickerDialog(android.content.Context, android.app.DatePickerDialog.OnDateSetListener, int, int, int); ctor public DatePickerDialog(android.content.Context, int, android.app.DatePickerDialog.OnDateSetListener, int, int, int); @@ -4904,6 +4913,7 @@ package android.app { method public android.graphics.drawable.Icon getLargeIcon(); method public android.graphics.drawable.Icon getSmallIcon(); method public java.lang.String getSortKey(); + method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); method public void writeToParcel(android.os.Parcel, int); field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT; field public static final java.lang.String CATEGORY_ALARM = "alarm"; @@ -5288,6 +5298,7 @@ package android.app { method public void send(int, android.app.PendingIntent.OnFinished, android.os.Handler) throws android.app.PendingIntent.CanceledException; method public void send(android.content.Context, int, android.content.Intent, android.app.PendingIntent.OnFinished, android.os.Handler) throws android.app.PendingIntent.CanceledException; method public void send(android.content.Context, int, android.content.Intent, android.app.PendingIntent.OnFinished, android.os.Handler, java.lang.String) throws android.app.PendingIntent.CanceledException; + method public void send(android.content.Context, int, android.content.Intent, android.app.PendingIntent.OnFinished, android.os.Handler, java.lang.String, android.os.Bundle) throws android.app.PendingIntent.CanceledException; method public static void writePendingIntentOrNullToParcel(android.app.PendingIntent, android.os.Parcel); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.PendingIntent> CREATOR; @@ -5958,7 +5969,6 @@ package android.app.admin { field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED"; field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE"; field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME"; - field public static final java.lang.String EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS = "android.app.extra.PROVISIONING_RESET_PROTECTION_PARAMETERS"; field public static final java.lang.String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION"; field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE"; field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN"; @@ -7962,10 +7972,12 @@ package android.content { method public abstract void revokeUriPermission(android.net.Uri, int); method public abstract void sendBroadcast(android.content.Intent); method public abstract void sendBroadcast(android.content.Intent, java.lang.String); + method public abstract void sendBroadcast(android.content.Intent, java.lang.String, android.os.Bundle); method public abstract void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle); method public abstract void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String); method public abstract void sendOrderedBroadcast(android.content.Intent, java.lang.String); method public abstract void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle); + method public abstract void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.os.Bundle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle); method public abstract void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle); method public abstract deprecated void sendStickyBroadcast(android.content.Intent); method public abstract deprecated void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle); @@ -8139,10 +8151,12 @@ package android.content { method public void revokeUriPermission(android.net.Uri, int); method public void sendBroadcast(android.content.Intent); method public void sendBroadcast(android.content.Intent, java.lang.String); + method public void sendBroadcast(android.content.Intent, java.lang.String, android.os.Bundle); method public void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle); method public void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String); method public void sendOrderedBroadcast(android.content.Intent, java.lang.String); method public void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle); + method public void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.os.Bundle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle); method public void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle); method public deprecated void sendStickyBroadcast(android.content.Intent); method public deprecated void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle); @@ -12616,7 +12630,6 @@ package android.graphics.drawable { method public android.graphics.drawable.Drawable.ConstantState getConstantState(); method public android.graphics.drawable.Drawable getCurrent(); method public android.graphics.Rect getDirtyBounds(); - method public boolean getDither(); method public void getHotspotBounds(android.graphics.Rect); method public int getIntrinsicHeight(); method public int getIntrinsicWidth(); @@ -12633,6 +12646,7 @@ package android.graphics.drawable { method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public void invalidateSelf(); method public boolean isAutoMirrored(); + method public boolean isDither(); method public boolean isFilterBitmap(); method public boolean isStateful(); method public final boolean isVisible(); @@ -27990,6 +28004,7 @@ package android.provider { field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF"; field public static final java.lang.String EXTRA_INFO = "info"; field public static final java.lang.String EXTRA_LOADING = "loading"; + field public static final java.lang.String EXTRA_PROMPT = "android.provider.extra.PROMPT"; field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER"; } @@ -30902,7 +30917,6 @@ package android.service.persistentdata { method public abstract byte[] read() throws android.os.RemoteException; method public abstract void setOemUnlockEnabled(boolean) throws android.os.RemoteException; method public abstract void wipe() throws android.os.RemoteException; - method public abstract void wipeIfAllowed(android.os.Bundle, android.app.PendingIntent) throws android.os.RemoteException; method public abstract int write(byte[]) throws android.os.RemoteException; } @@ -30914,14 +30928,7 @@ package android.service.persistentdata { method public byte[] read(); method public void setOemUnlockEnabled(boolean); method public void wipe(); - method public void wipeIfAllowed(android.os.Bundle, android.app.PendingIntent); method public int write(byte[]); - field public static final java.lang.String ACTION_WIPE_IF_ALLOWED = "android.service.persistentdata.action.WIPE_IF_ALLOWED"; - field public static final java.lang.String EXTRA_WIPE_IF_ALLOWED_CALLBACK = "android.service.persistentdata.extra.WIPE_IF_ALLOWED_CALLBACK"; - field public static final int STATUS_ERROR_NETWORK_ERROR = 2; // 0x2 - field public static final int STATUS_ERROR_NOT_COMPLIANT = 3; // 0x3 - field public static final int STATUS_ERROR_REMOTE_EXCEPTION = 1; // 0x1 - field public static final int STATUS_SUCCESS = 0; // 0x0 } } @@ -32840,10 +32847,14 @@ package android.telephony { field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool"; field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool"; field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool"; + field public static final java.lang.String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array"; + field public static final java.lang.String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array"; field public static final java.lang.String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string"; field public static final java.lang.String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool"; field public static final java.lang.String KEY_DTMF_TYPE_ENABLED_BOOL = "dtmf_type_enabled_bool"; field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_vibration_bool"; + field public static final java.lang.String KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array"; + field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array"; field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool"; field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool"; field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool"; @@ -34018,10 +34029,12 @@ package android.test.mock { method public void revokeUriPermission(android.net.Uri, int); method public void sendBroadcast(android.content.Intent); method public void sendBroadcast(android.content.Intent, java.lang.String); + method public void sendBroadcast(android.content.Intent, java.lang.String, android.os.Bundle); method public void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle); method public void sendBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String); method public void sendOrderedBroadcast(android.content.Intent, java.lang.String); method public void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle); + method public void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.os.Bundle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle); method public void sendOrderedBroadcastAsUser(android.content.Intent, android.os.UserHandle, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle); method public void sendStickyBroadcast(android.content.Intent); method public void sendStickyBroadcastAsUser(android.content.Intent, android.os.UserHandle); @@ -39084,6 +39097,8 @@ package android.view { method public boolean onRequestSendAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent); method public boolean onStartNestedScroll(android.view.View, android.view.View, int); method public void onStopNestedScroll(android.view.View); + method public void onViewAdded(android.view.View); + method public void onViewRemoved(android.view.View); method public void recomputeViewAttributes(android.view.View); method public void removeAllViews(); method public void removeAllViewsInLayout(); @@ -44150,7 +44165,6 @@ package android.widget { method public int getInputType(); method public final android.text.method.KeyListener getKeyListener(); method public final android.text.Layout getLayout(); - method public int[] getLeftIndents(); method public float getLetterSpacing(); method public int getLineBounds(int, android.graphics.Rect); method public int getLineCount(); @@ -44173,7 +44187,6 @@ package android.widget { method public android.text.TextPaint getPaint(); method public int getPaintFlags(); method public java.lang.String getPrivateImeOptions(); - method public int[] getRightIndents(); method public int getSelectionEnd(); method public int getSelectionStart(); method public int getShadowColor(); @@ -44253,7 +44266,6 @@ package android.widget { method public void setImeActionLabel(java.lang.CharSequence, int); method public void setImeOptions(int); method public void setIncludeFontPadding(boolean); - method public void setIndents(int[], int[]); method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public void setInputType(int); method public void setKeyListener(android.text.method.KeyListener); diff --git a/api/system-removed.txt b/api/system-removed.txt index 8eb2d8e..2e6c685 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -1,11 +1,3 @@ -package android.app { - - public class Notification implements android.os.Parcelable { - method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); - } - -} - package android.content.pm { public class PackageInfo implements android.os.Parcelable { diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index bf3b455..69ba27c 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -1002,7 +1002,7 @@ public class Am extends BaseCommand { IntentReceiver receiver = new IntentReceiver(); System.out.println("Broadcasting: " + intent); mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, mReceiverPermission, - android.app.AppOpsManager.OP_NONE, true, false, mUserId); + android.app.AppOpsManager.OP_NONE, null, true, false, mUserId); receiver.waitForFinish(); } @@ -1658,7 +1658,7 @@ public class Am extends BaseCommand { Intent intent = new Intent( "com.android.server.task.controllers.IdleController.ACTION_TRIGGER_IDLE"); mAm.broadcastIntent(null, intent, null, null, 0, null, null, null, - android.app.AppOpsManager.OP_NONE, true, false, UserHandle.USER_ALL); + android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL); } private void runScreenCompat() throws Exception { diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index 1faf41b..2be44bc 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -1812,7 +1812,7 @@ public final class Pm { private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { @Override public int send(int code, Intent intent, String resolvedType, - IIntentReceiver finishedReceiver, String requiredPermission) { + IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { try { mResult.offer(intent, 5, TimeUnit.SECONDS); } catch (InterruptedException e) { diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 6ae21eb..680feae 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -108,7 +108,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM try { getDefault().broadcastIntent( null, intent, null, null, Activity.RESULT_OK, null, null, - null /*permission*/, appOp, false, true, userId); + null /*permission*/, appOp, null, false, true, userId); } catch (RemoteException ex) { } } @@ -458,12 +458,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM Bundle resultExtras = data.readBundle(); String perm = data.readString(); int appOp = data.readInt(); + Bundle options = data.readBundle(); boolean serialized = data.readInt() != 0; boolean sticky = data.readInt() != 0; int userId = data.readInt(); int res = broadcastIntent(app, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, perm, appOp, - serialized, sticky, userId); + options, serialized, sticky, userId); reply.writeNoException(); reply.writeInt(res); return true; @@ -2991,9 +2992,9 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } public int broadcastIntent(IApplicationThread caller, - Intent intent, String resolvedType, IIntentReceiver resultTo, + Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, - String requiredPermission, int appOp, boolean serialized, + String requiredPermission, int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException { Parcel data = Parcel.obtain(); @@ -3008,6 +3009,7 @@ class ActivityManagerProxy implements IActivityManager data.writeBundle(map); data.writeString(requiredPermission); data.writeInt(appOp); + data.writeBundle(options); data.writeInt(serialized ? 1 : 0); data.writeInt(sticky ? 1 : 0); data.writeInt(userId); diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 6fb997e..2406985 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -43,7 +43,7 @@ public class ActivityOptions { * A long in the extras delivered by {@link #requestUsageTimeReport} that contains * the total time (in ms) the user spent in the app flow. */ - public static final String EXTRA_USAGE_TIME_REPORT = "android.usage_time"; + public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time"; /** * A Bundle in the extras delivered by {@link #requestUsageTimeReport} that contains @@ -56,67 +56,67 @@ public class ActivityOptions { * The package name that created the options. * @hide */ - public static final String KEY_PACKAGE_NAME = "android:packageName"; + public static final String KEY_PACKAGE_NAME = "android:activity.packageName"; /** * Type of animation that arguments specify. * @hide */ - public static final String KEY_ANIM_TYPE = "android:animType"; + public static final String KEY_ANIM_TYPE = "android:activity.animType"; /** * Custom enter animation resource ID. * @hide */ - public static final String KEY_ANIM_ENTER_RES_ID = "android:animEnterRes"; + public static final String KEY_ANIM_ENTER_RES_ID = "android:activity.animEnterRes"; /** * Custom exit animation resource ID. * @hide */ - public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes"; + public static final String KEY_ANIM_EXIT_RES_ID = "android:activity.animExitRes"; /** * Custom in-place animation resource ID. * @hide */ - public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:animInPlaceRes"; + public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:activity.animInPlaceRes"; /** * Bitmap for thumbnail animation. * @hide */ - public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail"; + public static final String KEY_ANIM_THUMBNAIL = "android:activity.animThumbnail"; /** * Start X position of thumbnail animation. * @hide */ - public static final String KEY_ANIM_START_X = "android:animStartX"; + public static final String KEY_ANIM_START_X = "android:activity.animStartX"; /** * Start Y position of thumbnail animation. * @hide */ - public static final String KEY_ANIM_START_Y = "android:animStartY"; + public static final String KEY_ANIM_START_Y = "android:activity.animStartY"; /** * Initial width of the animation. * @hide */ - public static final String KEY_ANIM_WIDTH = "android:animWidth"; + public static final String KEY_ANIM_WIDTH = "android:activity.animWidth"; /** * Initial height of the animation. * @hide */ - public static final String KEY_ANIM_HEIGHT = "android:animHeight"; + public static final String KEY_ANIM_HEIGHT = "android:activity.animHeight"; /** * Callback for when animation is started. * @hide */ - public static final String KEY_ANIM_START_LISTENER = "android:animStartListener"; + public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener"; /** * For Activity transitions, the calling Activity's TransitionListener used to @@ -124,15 +124,18 @@ public class ActivityOptions { * complete. */ private static final String KEY_TRANSITION_COMPLETE_LISTENER - = "android:transitionCompleteListener"; - - private static final String KEY_TRANSITION_IS_RETURNING = "android:transitionIsReturning"; - private static final String KEY_TRANSITION_SHARED_ELEMENTS = "android:sharedElementNames"; - private static final String KEY_RESULT_DATA = "android:resultData"; - private static final String KEY_RESULT_CODE = "android:resultCode"; - private static final String KEY_EXIT_COORDINATOR_INDEX = "android:exitCoordinatorIndex"; - - private static final String KEY_USAGE_TIME_REPORT = "android:usageTimeReport"; + = "android:activity.transitionCompleteListener"; + + private static final String KEY_TRANSITION_IS_RETURNING + = "android:activity.transitionIsReturning"; + private static final String KEY_TRANSITION_SHARED_ELEMENTS + = "android:activity.sharedElementNames"; + private static final String KEY_RESULT_DATA = "android:activity.resultData"; + private static final String KEY_RESULT_CODE = "android:activity.resultCode"; + private static final String KEY_EXIT_COORDINATOR_INDEX + = "android:activity.exitCoordinatorIndex"; + + private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport"; /** @hide */ public static final int ANIM_NONE = 0; diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java new file mode 100644 index 0000000..1f378da --- /dev/null +++ b/core/java/android/app/BroadcastOptions.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.annotation.SystemApi; +import android.os.Bundle; + +/** + * Helper class for building an options Bundle that can be used with + * {@link android.content.Context#sendBroadcast(android.content.Intent) + * Context.sendBroadcast(Intent)} and related methods. + * {@hide} + */ +@SystemApi +public class BroadcastOptions { + private long mTemporaryAppWhitelistDuration; + + /** + * How long to temporarily put an app on the power whitelist when executing this broadcast + * to it. + * @hide + */ + public static final String KEY_TEMPORARY_APP_WHITELIST_DURATION + = "android:broadcast.temporaryAppWhitelistDuration"; + + public static BroadcastOptions makeBasic() { + BroadcastOptions opts = new BroadcastOptions(); + return opts; + } + + private BroadcastOptions() { + } + + /** @hide */ + public BroadcastOptions(Bundle opts) { + mTemporaryAppWhitelistDuration = opts.getLong(KEY_TEMPORARY_APP_WHITELIST_DURATION); + } + + /** + * Set a duration for which the system should temporary place an application on the + * power whitelist when this broadcast is being delivered to it. + * @param duration The duration in milliseconds; 0 means to not place on whitelist. + */ + public void setTemporaryAppWhitelistDuration(long duration) { + mTemporaryAppWhitelistDuration = duration; + } + + /** + * Return {@link #setTemporaryAppWhitelistDuration}. + * @hide + */ + public long getTemporaryAppWhitelistDuration() { + return mTemporaryAppWhitelistDuration; + } + + /** + * Returns the created options as a Bundle, which can be passed to + * {@link android.content.Context#sendBroadcast(android.content.Intent) + * Context.sendBroadcast(Intent)} and related methods. + * Note that the returned Bundle is still owned by the ActivityOptions + * object; you must not modify it, but can supply it to the sendBroadcast + * methods that take an options Bundle. + */ + public Bundle toBundle() { + Bundle b = new Bundle(); + if (mTemporaryAppWhitelistDuration > 0) { + b.putLong(KEY_TEMPORARY_APP_WHITELIST_DURATION, mTemporaryAppWhitelistDuration); + } + return b.isEmpty() ? null : b; + } +} diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index be36af7..0420fb6 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -46,7 +46,6 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; -import android.hardware.display.DisplayManager; import android.net.Uri; import android.os.Binder; import android.os.Build; @@ -676,8 +675,8 @@ class ContextImpl extends Context { + " Is this really what you want?"); } mMainThread.getInstrumentation().execStartActivity( - getOuterContext(), mMainThread.getApplicationThread(), null, - (Activity)null, intent, -1, options); + getOuterContext(), mMainThread.getApplicationThread(), null, + (Activity) null, intent, -1, options); } /** @hide */ @@ -710,8 +709,8 @@ class ContextImpl extends Context { + " Is this really what you want?"); } mMainThread.getInstrumentation().execStartActivitiesAsUser( - getOuterContext(), mMainThread.getApplicationThread(), null, - (Activity)null, intents, options, userHandle.getIdentifier()); + getOuterContext(), mMainThread.getApplicationThread(), null, + (Activity) null, intents, options, userHandle.getIdentifier()); } @Override @@ -724,8 +723,8 @@ class ContextImpl extends Context { + " Is this really what you want?"); } mMainThread.getInstrumentation().execStartActivities( - getOuterContext(), mMainThread.getApplicationThread(), null, - (Activity)null, intents, options); + getOuterContext(), mMainThread.getApplicationThread(), null, + (Activity) null, intents, options); } @Override @@ -766,9 +765,9 @@ class ContextImpl extends Context { try { intent.prepareToLeaveProcess(); ActivityManagerNative.getDefault().broadcastIntent( - mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false, - getUserId()); + mMainThread.getApplicationThread(), intent, resolvedType, null, + Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false, + getUserId()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } @@ -781,9 +780,24 @@ class ContextImpl extends Context { try { intent.prepareToLeaveProcess(); ActivityManagerNative.getDefault().broadcastIntent( - mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, - false, false, getUserId()); + mMainThread.getApplicationThread(), intent, resolvedType, null, + Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, + null, false, false, getUserId()); + } catch (RemoteException e) { + throw new RuntimeException("Failure from system", e); + } + } + + @Override + public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) { + warnIfCallingFromSystemProcess(); + String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); + try { + intent.prepareToLeaveProcess(); + ActivityManagerNative.getDefault().broadcastIntent( + mMainThread.getApplicationThread(), intent, resolvedType, null, + Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, + options, false, false, getUserId()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } @@ -796,25 +810,24 @@ class ContextImpl extends Context { try { intent.prepareToLeaveProcess(); ActivityManagerNative.getDefault().broadcastIntent( - mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false, - getUserId()); + mMainThread.getApplicationThread(), intent, resolvedType, null, + Activity.RESULT_OK, null, null, receiverPermission, appOp, null, false, false, + getUserId()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } } @Override - public void sendOrderedBroadcast(Intent intent, - String receiverPermission) { + public void sendOrderedBroadcast(Intent intent, String receiverPermission) { warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); try { intent.prepareToLeaveProcess(); ActivityManagerNative.getDefault().broadcastIntent( - mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, true, false, - getUserId()); + mMainThread.getApplicationThread(), intent, resolvedType, null, + Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, + null, true, false, getUserId()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } @@ -826,7 +839,16 @@ class ContextImpl extends Context { Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE, - resultReceiver, scheduler, initialCode, initialData, initialExtras); + resultReceiver, scheduler, initialCode, initialData, initialExtras, null); + } + + @Override + public void sendOrderedBroadcast(Intent intent, + String receiverPermission, Bundle options, BroadcastReceiver resultReceiver, + Handler scheduler, int initialCode, String initialData, + Bundle initialExtras) { + sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE, + resultReceiver, scheduler, initialCode, initialData, initialExtras, options); } @Override @@ -834,6 +856,14 @@ class ContextImpl extends Context { String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { + sendOrderedBroadcast(intent, receiverPermission, appOp, + resultReceiver, scheduler, initialCode, initialData, initialExtras, null); + } + + void sendOrderedBroadcast(Intent intent, + String receiverPermission, int appOp, BroadcastReceiver resultReceiver, + Handler scheduler, int initialCode, String initialData, + Bundle initialExtras, Bundle options) { warnIfCallingFromSystemProcess(); IIntentReceiver rd = null; if (resultReceiver != null) { @@ -858,7 +888,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, receiverPermission, appOp, - true, false, getUserId()); + options, true, false, getUserId()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } @@ -871,7 +901,7 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(); ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, - AppOpsManager.OP_NONE, false, false, user.getIdentifier()); + AppOpsManager.OP_NONE, null, false, false, user.getIdentifier()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } @@ -891,7 +921,7 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false, + Activity.RESULT_OK, null, null, receiverPermission, appOp, null, false, false, user.getIdentifier()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); @@ -934,7 +964,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, receiverPermission, - appOp, true, false, user.getIdentifier()); + appOp, null, true, false, user.getIdentifier()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } @@ -949,7 +979,7 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, + Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true, getUserId()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); @@ -986,7 +1016,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, null, - AppOpsManager.OP_NONE, true, true, getUserId()); + AppOpsManager.OP_NONE, null, true, true, getUserId()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } @@ -1017,7 +1047,7 @@ class ContextImpl extends Context { intent.prepareToLeaveProcess(); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, - Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, user.getIdentifier()); + Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, true, user.getIdentifier()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } @@ -1052,7 +1082,7 @@ class ContextImpl extends Context { ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, rd, initialCode, initialData, initialExtras, null, - AppOpsManager.OP_NONE, true, true, user.getIdentifier()); + AppOpsManager.OP_NONE, null, true, true, user.getIdentifier()); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 9311e5e..e7f7e13 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -107,7 +107,7 @@ public interface IActivityManager extends IInterface { public int broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, - int appOp, boolean serialized, boolean sticky, int userId) throws RemoteException; + int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException; public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException; public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map, boolean abortBroadcast, int flags) throws RemoteException; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 9d3bdf0..5a0d246 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -1371,6 +1371,9 @@ public class Notification implements Parcelable when = parcel.readLong(); if (parcel.readInt() != 0) { mSmallIcon = Icon.CREATOR.createFromParcel(parcel); + if (mSmallIcon.getType() == Icon.TYPE_RESOURCE) { + icon = mSmallIcon.getResId(); + } } number = parcel.readInt(); if (parcel.readInt() != 0) { @@ -1588,13 +1591,17 @@ public class Notification implements Parcelable } /** - * Flatten this notification from a parcel. + * Flatten this notification into a parcel. */ public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(1); parcel.writeLong(when); + if (mSmallIcon == null && icon != 0) { + // you snuck an icon in here without using the builder; let's try to keep it + mSmallIcon = Icon.createWithResource("", icon); + } if (mSmallIcon != null) { parcel.writeInt(1); mSmallIcon.writeToParcel(parcel, 0); @@ -1742,7 +1749,6 @@ public class Notification implements Parcelable * Stack</a> document. * * @deprecated Use {@link Builder} instead. - * @removed */ @Deprecated public void setLatestEventInfo(Context context, @@ -2792,7 +2798,10 @@ public class Notification implements Parcelable return this; } - private void setFlag(int mask, boolean value) { + /** + * @hide + */ + public void setFlag(int mask, boolean value) { if (value) { mFlags |= mask; } else { diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 0904e21..605c006 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -25,6 +25,7 @@ import android.content.Context; import android.content.pm.ParceledListSlice; import android.graphics.drawable.Icon; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -216,6 +217,12 @@ public class NotificationManager } } fixLegacySmallIcon(notification, pkg); + if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { + if (notification.getSmallIcon() == null) { + throw new IllegalArgumentException("Invalid notification (no valid small icon): " + + notification); + } + } if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); Notification stripped = notification.clone(); Builder.stripForDelivery(stripped); diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 031854a..c42ba65 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -613,7 +613,7 @@ public final class PendingIntent implements Parcelable { * is no longer allowing more intents to be sent through it. */ public void send() throws CanceledException { - send(null, 0, null, null, null, null); + send(null, 0, null, null, null, null, null); } /** @@ -627,7 +627,7 @@ public final class PendingIntent implements Parcelable { * is no longer allowing more intents to be sent through it. */ public void send(int code) throws CanceledException { - send(null, code, null, null, null, null); + send(null, code, null, null, null, null, null); } /** @@ -646,9 +646,9 @@ public final class PendingIntent implements Parcelable { * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. */ - public void send(Context context, int code, Intent intent) + public void send(Context context, int code, @Nullable Intent intent) throws CanceledException { - send(context, code, intent, null, null, null); + send(context, code, intent, null, null, null, null); } /** @@ -667,9 +667,9 @@ public final class PendingIntent implements Parcelable { * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. */ - public void send(int code, OnFinished onFinished, Handler handler) + public void send(int code, @Nullable OnFinished onFinished, @Nullable Handler handler) throws CanceledException { - send(null, code, null, onFinished, handler, null); + send(null, code, null, onFinished, handler, null, null); } /** @@ -705,9 +705,9 @@ public final class PendingIntent implements Parcelable { * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. */ - public void send(Context context, int code, Intent intent, - OnFinished onFinished, Handler handler) throws CanceledException { - send(context, code, intent, onFinished, handler, null); + public void send(Context context, int code, @Nullable Intent intent, + @Nullable OnFinished onFinished, @Nullable Handler handler) throws CanceledException { + send(context, code, intent, onFinished, handler, null, null); } /** @@ -748,8 +748,56 @@ public final class PendingIntent implements Parcelable { * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. */ - public void send(Context context, int code, Intent intent, - OnFinished onFinished, Handler handler, String requiredPermission) + public void send(Context context, int code, @Nullable Intent intent, + @Nullable OnFinished onFinished, @Nullable Handler handler, + @Nullable String requiredPermission) + throws CanceledException { + send(context, code, intent, onFinished, handler, requiredPermission, null); + } + + /** + * Perform the operation associated with this PendingIntent, allowing the + * caller to specify information about the Intent to use and be notified + * when the send has completed. + * + * <p>For the intent parameter, a PendingIntent + * often has restrictions on which fields can be supplied here, based on + * how the PendingIntent was retrieved in {@link #getActivity}, + * {@link #getBroadcast}, or {@link #getService}. + * + * @param context The Context of the caller. This may be null if + * <var>intent</var> is also null. + * @param code Result code to supply back to the PendingIntent's target. + * @param intent Additional Intent data. See {@link Intent#fillIn + * Intent.fillIn()} for information on how this is applied to the + * original Intent. Use null to not modify the original Intent. + * If flag {@link #FLAG_IMMUTABLE} was set when this pending intent was + * created, this argument will be ignored. + * @param onFinished The object to call back on when the send has + * completed, or null for no callback. + * @param handler Handler identifying the thread on which the callback + * should happen. If null, the callback will happen from the thread + * pool of the process. + * @param requiredPermission Name of permission that a recipient of the PendingIntent + * is required to hold. This is only valid for broadcast intents, and + * corresponds to the permission argument in + * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}. + * If null, no permission is required. + * @param options Additional options the caller would like to provide to modify the sending + * behavior. May be built from an {@link ActivityOptions} to apply to an activity start. + * + * @see #send() + * @see #send(int) + * @see #send(Context, int, Intent) + * @see #send(int, android.app.PendingIntent.OnFinished, Handler) + * @see #send(Context, int, Intent, OnFinished, Handler) + * + * @throws CanceledException Throws CanceledException if the PendingIntent + * is no longer allowing more intents to be sent through it. + */ + public void send(Context context, int code, @Nullable Intent intent, + @Nullable OnFinished onFinished, @Nullable Handler handler, + @Nullable String requiredPermission, @Nullable Bundle options) throws CanceledException { try { String resolvedType = intent != null ? @@ -759,7 +807,7 @@ public final class PendingIntent implements Parcelable { onFinished != null ? new FinishedDispatcher(this, onFinished, handler) : null, - requiredPermission); + requiredPermission, options); if (res < 0) { throw new CanceledException(); } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index ed20086..b9862ca 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -552,19 +552,6 @@ public class DevicePolicyManager { = "android.app.extra.PROVISIONING_DEVICE_INITIALIZER_SIGNATURE_CHECKSUM"; /** - * A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that - * holds data needed by the system to wipe factory reset protection. The data needed to wipe - * the device depend on the installed factory reset protection implementation. For example, - * if an account is needed to unlock a device, this extra may contain data used to - * authenticate that account. - * - * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC_V2} that starts device owner - * provisioning via an NFC bump. - */ - public static final String EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS - = "android.app.extra.PROVISIONING_RESET_PROTECTION_PARAMETERS"; - - /** * This MIME type is used for starting the Device Owner provisioning that does not require * provisioning features introduced in Android API level * {@link android.os.Build.VERSION_CODES#MNC} or later levels. diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java index 1205708..278c9d6 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -20,6 +20,7 @@ import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.ParceledListSlice; import android.os.Bundle; import android.os.IBinder; import android.os.Process; @@ -753,16 +754,16 @@ public class AppWidgetManager { } try { - List<AppWidgetProviderInfo> providers = mService.getInstalledProvidersForProfile( + ParceledListSlice<AppWidgetProviderInfo> providers = mService.getInstalledProvidersForProfile( categoryFilter, profile.getIdentifier()); if (providers == null) { return Collections.emptyList(); } - for (AppWidgetProviderInfo info : providers) { + for (AppWidgetProviderInfo info : providers.getList()) { // Converting complex to dp. convertSizesToPixels(info); } - return providers; + return providers.getList(); } catch (RemoteException e) { throw new RuntimeException("system server dead?", e); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 83ce087..675515b 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1517,6 +1517,38 @@ public abstract class Context { @Nullable String receiverPermission); /** + * Broadcast the given intent to all interested BroadcastReceivers, allowing + * an optional required permission to be enforced. This + * call is asynchronous; it returns immediately, and you will continue + * executing while the receivers are run. No results are propagated from + * receivers and receivers can not abort the broadcast. If you want + * to allow receivers to propagate results or abort the broadcast, you must + * send an ordered broadcast using + * {@link #sendOrderedBroadcast(Intent, String)}. + * + * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts. + * + * @param intent The Intent to broadcast; all receivers matching this + * Intent will receive the broadcast. + * @param receiverPermission (optional) String naming a permission that + * a receiver must hold in order to receive your broadcast. + * If null, no permission is required. + * @param options (optional) Additional sending options, generated from a + * {@link android.app.BroadcastOptions}. + * + * @see android.content.BroadcastReceiver + * @see #registerReceiver + * @see #sendBroadcast(Intent) + * @see #sendOrderedBroadcast(Intent, String) + * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) + * @hide + */ + @SystemApi + public abstract void sendBroadcast(Intent intent, + @Nullable String receiverPermission, + @Nullable Bundle options); + + /** * Like {@link #sendBroadcast(Intent, String)}, but also allows specification * of an associated app op as per {@link android.app.AppOpsManager}. * @hide @@ -1588,11 +1620,60 @@ public abstract class Context { * @see android.app.Activity#RESULT_OK */ public abstract void sendOrderedBroadcast(@NonNull Intent intent, - @Nullable String receiverPermission, BroadcastReceiver resultReceiver, + @Nullable String receiverPermission, @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler, int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras); /** + * Version of {@link #sendBroadcast(Intent)} that allows you to + * receive data back from the broadcast. This is accomplished by + * supplying your own BroadcastReceiver when calling, which will be + * treated as a final receiver at the end of the broadcast -- its + * {@link BroadcastReceiver#onReceive} method will be called with + * the result values collected from the other receivers. The broadcast will + * be serialized in the same way as calling + * {@link #sendOrderedBroadcast(Intent, String)}. + * + * <p>Like {@link #sendBroadcast(Intent)}, this method is + * asynchronous; it will return before + * resultReceiver.onReceive() is called. + * + * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts. + * + * + * @param intent The Intent to broadcast; all receivers matching this + * Intent will receive the broadcast. + * @param receiverPermission String naming a permissions that + * a receiver must hold in order to receive your broadcast. + * If null, no permission is required. + * @param options (optional) Additional sending options, generated from a + * {@link android.app.BroadcastOptions}. + * @param resultReceiver Your own BroadcastReceiver to treat as the final + * receiver of the broadcast. + * @param scheduler A custom Handler with which to schedule the + * resultReceiver callback; if null it will be + * scheduled in the Context's main thread. + * @param initialCode An initial value for the result code. Often + * Activity.RESULT_OK. + * @param initialData An initial value for the result data. Often + * null. + * @param initialExtras An initial value for the result extras. Often + * null. + * @see #sendBroadcast(Intent) + * @see #sendBroadcast(Intent, String) + * @see #sendOrderedBroadcast(Intent, String) + * @see android.content.BroadcastReceiver + * @see #registerReceiver + * @see android.app.Activity#RESULT_OK + * @hide + */ + @SystemApi + public abstract void sendOrderedBroadcast(@NonNull Intent intent, + @Nullable String receiverPermission, @Nullable Bundle options, + @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler, + int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras); + + /** * Like {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, * int, String, android.os.Bundle)}, but also allows specification * of an associated app op as per {@link android.app.AppOpsManager}. diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index fb9e194..4e7c832 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -16,6 +16,7 @@ package android.content; +import android.annotation.SystemApi; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; @@ -401,6 +402,13 @@ public class ContextWrapper extends Context { } /** @hide */ + @SystemApi + @Override + public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) { + mBase.sendBroadcast(intent, receiverPermission, options); + } + + /** @hide */ @Override public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { mBase.sendBroadcast(intent, receiverPermission, appOp); @@ -423,6 +431,18 @@ public class ContextWrapper extends Context { } /** @hide */ + @SystemApi + @Override + public void sendOrderedBroadcast( + Intent intent, String receiverPermission, Bundle options, BroadcastReceiver resultReceiver, + Handler scheduler, int initialCode, String initialData, + Bundle initialExtras) { + mBase.sendOrderedBroadcast(intent, receiverPermission, + options, resultReceiver, scheduler, initialCode, + initialData, initialExtras); + } + + /** @hide */ @Override public void sendOrderedBroadcast( Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, diff --git a/core/java/android/content/IIntentSender.aidl b/core/java/android/content/IIntentSender.aidl index 7dbd6f2..f3affa7 100644 --- a/core/java/android/content/IIntentSender.aidl +++ b/core/java/android/content/IIntentSender.aidl @@ -18,9 +18,10 @@ package android.content; import android.content.IIntentReceiver; import android.content.Intent; +import android.os.Bundle; /** @hide */ interface IIntentSender { int send(int code, in Intent intent, String resolvedType, - IIntentReceiver finishedReceiver, String requiredPermission); + IIntentReceiver finishedReceiver, String requiredPermission, in Bundle options); } diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java index 166495b..13a767e 100644 --- a/core/java/android/content/IntentSender.java +++ b/core/java/android/content/IntentSender.java @@ -195,7 +195,7 @@ public class IntentSender implements Parcelable { onFinished != null ? new FinishedDispatcher(this, onFinished, handler) : null, - requiredPermission); + requiredPermission, null); if (res < 0) { throw new SendIntentException(); } diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index ecc3fb4..3f40484 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -61,6 +61,17 @@ public class NetworkPolicyManager { public static final int FIREWALL_RULE_ALLOW = 1; public static final int FIREWALL_RULE_DENY = 2; + public static final int FIREWALL_TYPE_WHITELIST = 0; + public static final int FIREWALL_TYPE_BLACKLIST = 1; + + public static final int FIREWALL_CHAIN_NONE = 0; + public static final int FIREWALL_CHAIN_DOZABLE = 1; + public static final int FIREWALL_CHAIN_STANDBY = 2; + + public static final String FIREWALL_CHAIN_NAME_NONE = "none"; + public static final String FIREWALL_CHAIN_NAME_DOZABLE = "dozable"; + public static final String FIREWALL_CHAIN_NAME_STANDBY = "standby"; + private static final boolean ALLOW_PLATFORM_APP_POLICY = true; /** diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index b29e8d0..8114155 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -342,7 +342,9 @@ interface INetworkManagementService void setFirewallInterfaceRule(String iface, boolean allow); void setFirewallEgressSourceRule(String addr, boolean allow); void setFirewallEgressDestRule(String addr, int port, boolean allow); - void setFirewallUidRule(int uid, int rule); + void setFirewallUidRule(int chain, int uid, int rule); + void setFirewallUidRules(int chain, in int[] uids, in int[] rules); + void setFirewallChainEnabled(int chain, boolean enable); /** * Set all packets from users in ranges to go through VPN specified by netId. diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 30535ff..c7ba607 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -107,6 +107,11 @@ public final class DocumentsContract { */ public static final String EXTRA_ORIENTATION = "android.content.extra.ORIENTATION"; + /** + * Overrides the default prompt text in DocumentsUI when set in an intent. + */ + public static final String EXTRA_PROMPT = "android.provider.extra.PROMPT"; + /** {@hide} */ public static final String ACTION_MANAGE_ROOT = "android.provider.action.MANAGE_ROOT"; /** {@hide} */ diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 3e9c9de..56cd1a7 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7133,6 +7133,29 @@ public final class Settings { public static final String APP_IDLE_CONSTANTS = "app_idle_constants"; /** + * Alarm manager specific settings. + * This is encoded as a key=value list, separated by commas. Ex: + * + * "min_futurity=5000,allow_while_idle_short_time=4500" + * + * The following keys are supported: + * + * <pre> + * min_futurity (long) + * min_interval (long) + * allow_while_idle_short_time (long) + * allow_while_idle_long_time (long) + * allow_while_idle_whitelist_duration (long) + * </pre> + * + * <p> + * Type: string + * @hide + * @see com.android.server.AlarmManagerService.Constants + */ + public static final String ALARM_MANAGER_CONSTANTS = "alarm_manager_constants"; + + /** * Get the key that retrieves a bluetooth headset's priority. * @hide */ diff --git a/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl b/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl index 0071a33..52db223 100644 --- a/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl +++ b/core/java/android/service/persistentdata/IPersistentDataBlockService.aidl @@ -16,8 +16,6 @@ package android.service.persistentdata; -import android.app.PendingIntent; -import android.os.Bundle; import android.os.ParcelFileDescriptor; /** @@ -32,7 +30,6 @@ interface IPersistentDataBlockService { int write(in byte[] data); byte[] read(); void wipe(); - void wipeIfAllowed(in Bundle bundle, in PendingIntent pi); int getDataBlockSize(); long getMaximumDataBlockSize(); diff --git a/core/java/android/service/persistentdata/PersistentDataBlockManager.java b/core/java/android/service/persistentdata/PersistentDataBlockManager.java index 31570c6..0ffdf68 100644 --- a/core/java/android/service/persistentdata/PersistentDataBlockManager.java +++ b/core/java/android/service/persistentdata/PersistentDataBlockManager.java @@ -17,8 +17,6 @@ package android.service.persistentdata; import android.annotation.SystemApi; -import android.app.PendingIntent; -import android.os.Bundle; import android.os.RemoteException; import android.util.Slog; @@ -43,56 +41,6 @@ import android.util.Slog; @SystemApi public class PersistentDataBlockManager { private static final String TAG = PersistentDataBlockManager.class.getSimpleName(); - - /** - * Broadcast action that will be called when the {@link #wipeIfAllowed(Bundle,PendingIntent)} - * method is called. A broadcast with this action will be sent to the package allowed to write - * to the persistent data block. Packages receiving this broadcasts should respond by using the - * {@link android.app.PendingIntent} sent in the {@link #EXTRA_WIPE_IF_ALLOWED_CALLBACK} extra. - */ - public static final String ACTION_WIPE_IF_ALLOWED - = "android.service.persistentdata.action.WIPE_IF_ALLOWED"; - - /** - * A {@link android.os.Parcelable} extra of type {@link android.app.PendingIntent} used to - * response to {@link #wipeIfAllowed(Bundle,PendingIntent)}. This extra will set in broadcasts - * with an action of {@link #ACTION_WIPE_IF_ALLOWED}. - */ - public static final String EXTRA_WIPE_IF_ALLOWED_CALLBACK - = "android.service.persistentdata.extra.WIPE_IF_ALLOWED_CALLBACK"; - - /** - * Result code indicating that the data block was wiped. - * - * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to - * {@link #wipeIfAllowed(Bundle,PendingIntent)} - */ - public static final int STATUS_SUCCESS = 0; - - /** - * Result code indicating that a remote exception was received while processing the request. - * - * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to - * {@link #wipeIfAllowed(Bundle,PendingIntent)} - */ - public static final int STATUS_ERROR_REMOTE_EXCEPTION = 1; - - /** - * Result code indicating that a network error occurred while processing the request. - * - * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to - * {@link #wipeIfAllowed(Bundle,PendingIntent)} - */ - public static final int STATUS_ERROR_NETWORK_ERROR = 2; - - /** - * Result code indicating that the data block could not be cleared with the provided data. - * - * <p>This value is set as result code of the {@link android.app.PendingIntent} argument to - * {@link #wipeIfAllowed(Bundle,PendingIntent)} - */ - public static final int STATUS_ERROR_NOT_COMPLIANT = 3; - private IPersistentDataBlockService sService; public PersistentDataBlockManager(IPersistentDataBlockService service) { @@ -170,28 +118,6 @@ public class PersistentDataBlockManager { } /** - * Attempt to wipe the data block by sending a broadcast to the package allowed to modify the - * datablock. The allowed package can refuse to wipe the data block based on the contents of - * the specified bundle. This bundle may contain data used by the allowed package to wipe the - * partition such as account credentials or an authorization token. - * @param bundle data used to wipe the data block. The contents of this bundle depend on the - * allowed package receiving the data. - * @param pi intent called when attempt finished. The result code of this intent will be set - * to one of {@link #STATUS_SUCCESS}, {@link #STATUS_ERROR_REMOTE_EXCEPTION}, - * {@link #STATUS_ERROR_NETWORK_ERROR}, or {@link #STATUS_ERROR_NOT_COMPLIANT}. - */ - public void wipeIfAllowed(Bundle bundle, PendingIntent pi) { - if (pi == null) { - throw new NullPointerException(); - } - try { - sService.wipeIfAllowed(bundle, pi); - } catch (RemoteException e) { - onError("wiping persistent partition"); - } - } - - /** * Writes a byte enabling or disabling the ability to "OEM unlock" the device. */ public void setOemUnlockEnabled(boolean enabled) { diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index 0367cfc..39dd29b 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -1097,7 +1097,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.BOTTOM, true); mWindow.getWindow().addFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED | - WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | + WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); initViews(); mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT); mWindow.setToken(mToken); @@ -1142,7 +1143,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall mContentFrame.addView(view, new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - + mContentFrame.requestApplyInsets(); } /** @hide */ diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 73cfd8c..2e2ba88 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -4148,24 +4148,38 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager mOnHierarchyChangeListener = listener; } - /** - * @hide - */ - protected void onViewAdded(View child) { + void dispatchViewAdded(View child) { + onViewAdded(child); if (mOnHierarchyChangeListener != null) { mOnHierarchyChangeListener.onChildViewAdded(this, child); } } /** - * @hide + * Called when a new child is added to this ViewGroup. Overrides should always + * call super.onViewAdded. + * + * @param child the added child view */ - protected void onViewRemoved(View child) { + public void onViewAdded(View child) { + } + + void dispatchViewRemoved(View child) { + onViewRemoved(child); if (mOnHierarchyChangeListener != null) { mOnHierarchyChangeListener.onChildViewRemoved(this, child); } } + /** + * Called when a child view is removed from this ViewGroup. Overrides should always + * call super.onViewRemoved. + * + * @param child the removed child view + */ + public void onViewRemoved(View child) { + } + private void clearCachedLayoutMode() { if (!hasBooleanFlag(FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET)) { mLayoutMode = LAYOUT_MODE_UNDEFINED; @@ -4292,7 +4306,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager child.resetRtlProperties(); } - onViewAdded(child); + dispatchViewAdded(child); if ((child.mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE) { mGroupFlags |= FLAG_NOTIFY_CHILDREN_ON_DRAWABLE_STATE_CHANGE; @@ -4554,7 +4568,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } - onViewRemoved(view); + dispatchViewRemoved(view); if (view.getVisibility() != View.GONE) { notifySubtreeAccessibilityStateChangedIfNeeded(); @@ -4646,7 +4660,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager needGlobalAttributesUpdate(false); - onViewRemoved(view); + dispatchViewRemoved(view); } removeFromArray(start, count); @@ -4729,7 +4743,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager childHasTransientStateChanged(view, false); } - onViewRemoved(view); + dispatchViewRemoved(view); view.mParent = null; children[i] = null; @@ -4788,7 +4802,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager childHasTransientStateChanged(child, false); } - onViewRemoved(child); + dispatchViewRemoved(child); } /** diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index db78ec5..b49cbc6 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -186,7 +186,9 @@ public final class AccessibilityInteractionClient if (DEBUG) { Log.i(LOG_TAG, "Window cache miss"); } + final long identityToken = Binder.clearCallingIdentity(); window = connection.getWindow(accessibilityWindowId); + Binder.restoreCallingIdentity(identityToken); if (window != null) { sAccessibilityCache.addWindow(window); return window; @@ -222,7 +224,9 @@ public final class AccessibilityInteractionClient if (DEBUG) { Log.i(LOG_TAG, "Windows cache miss"); } + final long identityToken = Binder.clearCallingIdentity(); windows = connection.getWindows(); + Binder.restoreCallingIdentity(identityToken); if (windows != null) { final int windowCount = windows.size(); for (int i = 0; i < windowCount; i++) { @@ -282,9 +286,11 @@ public final class AccessibilityInteractionClient } } final int interactionId = mInteractionIdCounter.getAndIncrement(); + final long identityToken = Binder.clearCallingIdentity(); final boolean success = connection.findAccessibilityNodeInfoByAccessibilityId( accessibilityWindowId, accessibilityNodeId, interactionId, this, prefetchFlags, Thread.currentThread().getId()); + Binder.restoreCallingIdentity(identityToken); // If the scale is zero the call has failed. if (success) { List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear( @@ -328,9 +334,11 @@ public final class AccessibilityInteractionClient IAccessibilityServiceConnection connection = getConnection(connectionId); if (connection != null) { final int interactionId = mInteractionIdCounter.getAndIncrement(); + final long identityToken = Binder.clearCallingIdentity(); final boolean success = connection.findAccessibilityNodeInfosByViewId( accessibilityWindowId, accessibilityNodeId, viewId, interactionId, this, Thread.currentThread().getId()); + Binder.restoreCallingIdentity(identityToken); if (success) { List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear( interactionId); @@ -374,9 +382,11 @@ public final class AccessibilityInteractionClient IAccessibilityServiceConnection connection = getConnection(connectionId); if (connection != null) { final int interactionId = mInteractionIdCounter.getAndIncrement(); + final long identityToken = Binder.clearCallingIdentity(); final boolean success = connection.findAccessibilityNodeInfosByText( accessibilityWindowId, accessibilityNodeId, text, interactionId, this, Thread.currentThread().getId()); + Binder.restoreCallingIdentity(identityToken); if (success) { List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear( interactionId); @@ -419,9 +429,11 @@ public final class AccessibilityInteractionClient IAccessibilityServiceConnection connection = getConnection(connectionId); if (connection != null) { final int interactionId = mInteractionIdCounter.getAndIncrement(); + final long identityToken = Binder.clearCallingIdentity(); final boolean success = connection.findFocus(accessibilityWindowId, accessibilityNodeId, focusType, interactionId, this, Thread.currentThread().getId()); + Binder.restoreCallingIdentity(identityToken); if (success) { AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear( interactionId); @@ -461,9 +473,11 @@ public final class AccessibilityInteractionClient IAccessibilityServiceConnection connection = getConnection(connectionId); if (connection != null) { final int interactionId = mInteractionIdCounter.getAndIncrement(); + final long identityToken = Binder.clearCallingIdentity(); final boolean success = connection.focusSearch(accessibilityWindowId, accessibilityNodeId, direction, interactionId, this, Thread.currentThread().getId()); + Binder.restoreCallingIdentity(identityToken); if (success) { AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear( interactionId); @@ -502,9 +516,11 @@ public final class AccessibilityInteractionClient IAccessibilityServiceConnection connection = getConnection(connectionId); if (connection != null) { final int interactionId = mInteractionIdCounter.getAndIncrement(); + final long identityToken = Binder.clearCallingIdentity(); final boolean success = connection.performAccessibilityAction( accessibilityWindowId, accessibilityNodeId, action, arguments, interactionId, this, Thread.currentThread().getId()); + Binder.restoreCallingIdentity(identityToken); if (success) { return getPerformAccessibilityActionResultAndClear(interactionId); } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 6454b57..a96bf71 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -3113,9 +3113,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } private boolean performStylusButtonPressAction(MotionEvent ev) { - if (ev.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS - && ev.isButtonPressed(MotionEvent.BUTTON_SECONDARY) - && mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mChoiceActionMode == null) { + if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mChoiceActionMode == null) { final View child = getChildAt(mMotionPosition - mFirstPosition); if (child != null) { final int longPressPosition = mMotionPosition; @@ -3785,7 +3783,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } if (mTouchMode == TOUCH_MODE_DOWN && mMotionPosition != INVALID_POSITION - && (performButtonActionOnTouchDown(ev) || performStylusButtonPressAction(ev))) { + && performButtonActionOnTouchDown(ev)) { removeCallbacks(mPendingCheckForTap); } } @@ -3828,11 +3826,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTouchMode = TOUCH_MODE_DONE_WAITING; updateSelectorState(); } else if (motionView != null) { - if (performStylusButtonPressAction(ev)) { - removeCallbacks(mPendingCheckForTap); - removeCallbacks(mPendingCheckForLongPress); - } - // Still within bounds, update the hotspot. final float[] point = mTmpPoint; point[0] = x; @@ -4072,7 +4065,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public boolean onGenericMotionEvent(MotionEvent event) { if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { switch (event.getAction()) { - case MotionEvent.ACTION_SCROLL: { + case MotionEvent.ACTION_SCROLL: if (mTouchMode == TOUCH_MODE_REST) { final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL); if (vscroll != 0) { @@ -4082,9 +4075,22 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } } - } + break; + + case MotionEvent.ACTION_BUTTON_PRESS: + int actionButton = event.getActionButton(); + if ((actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY + || actionButton == MotionEvent.BUTTON_SECONDARY) + && (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP)) { + if (performStylusButtonPressAction(event)) { + removeCallbacks(mPendingCheckForLongPress); + removeCallbacks(mPendingCheckForTap); + } + } + break; } } + return super.onGenericMotionEvent(event); } diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index bde8dcf..9ca59f1 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -3568,13 +3568,24 @@ public class Editor { } protected void updateDrawable() { + if (mIsDragging) { + // Don't update drawable during dragging. + return; + } final int offset = getCurrentCursorOffset(); final boolean isRtlCharAtOffset = mTextView.getLayout().isRtlCharAt(offset); final Drawable oldDrawable = mDrawable; mDrawable = isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr; mHotspotX = getHotspotX(mDrawable, isRtlCharAtOffset); mHorizontalGravity = getHorizontalGravity(isRtlCharAtOffset); - if (oldDrawable != mDrawable) { + final Layout layout = mTextView.getLayout(); + if (layout != null && oldDrawable != mDrawable && isShowing()) { + // Update popup window position. + mPositionX = (int) (layout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX - + getHorizontalOffset() + getCursorOffset()); + mPositionX += mTextView.viewportToContentHorizontalOffset(); + mPositionHasChanged = true; + updatePosition(mLastParentX, mLastParentY, false, false); postInvalidate(); } } @@ -3848,10 +3859,12 @@ public class Editor { case MotionEvent.ACTION_UP: filterOnTouchUp(); mIsDragging = false; + updateDrawable(); break; case MotionEvent.ACTION_CANCEL: mIsDragging = false; + updateDrawable(); break; } return true; @@ -4144,6 +4157,11 @@ public class Editor { offset = adjustedOffset; } positionCursor = true; + } else if (adjustedOffset < mPreviousOffset) { + // Handle has jumped to the start of the word, and the user is moving + // their finger towards the handle, the delta should be updated. + mTouchWordDelta = mTextView.convertToLocalHorizontalCoordinate(x) + - layout.getPrimaryHorizontal(mPreviousOffset); } } @@ -4278,6 +4296,11 @@ public class Editor { offset = adjustedOffset; } positionCursor = true; + } else if (adjustedOffset > mPreviousOffset) { + // Handle has jumped to the end of the word, and the user is moving + // their finger towards the handle, the delta should be updated. + mTouchWordDelta = layout.getPrimaryHorizontal(mPreviousOffset) + - mTextView.convertToLocalHorizontalCoordinate(x); } } diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index 6cc4bda..258424a 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -935,22 +935,14 @@ public class GridLayout extends ViewGroup { super.onDebugDraw(canvas); } - // Add/remove - - /** - * @hide - */ @Override - protected void onViewAdded(View child) { + public void onViewAdded(View child) { super.onViewAdded(child); invalidateStructure(); } - /** - * @hide - */ @Override - protected void onViewRemoved(View child) { + public void onViewRemoved(View child) { super.onViewRemoved(child); invalidateStructure(); } diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index 6b28f89..e0b2395 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -216,7 +216,7 @@ public class ImageView extends View { protected boolean verifyDrawable(Drawable dr) { return mDrawable == dr || super.verifyDrawable(dr); } - + @Override public void jumpDrawablesToCurrentState() { super.jumpDrawablesToCurrentState(); @@ -226,6 +226,15 @@ public class ImageView extends View { @Override public void invalidateDrawable(Drawable dr) { if (dr == mDrawable) { + if (dr != null) { + // update cached drawable dimensions if they've changed + final int w = dr.getIntrinsicWidth(); + final int h = dr.getIntrinsicHeight(); + if (w != mDrawableWidth || h != mDrawableHeight) { + mDrawableWidth = w; + mDrawableHeight = h; + } + } /* we invalidate the whole view in this case because it's very * hard to know where the drawable actually is. This is made * complicated because of the offsets and transformations that diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index affc5da..339038e 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -522,7 +522,7 @@ public class RelativeLayout extends ViewGroup { View baselineView = null; LayoutParams baselineParams = null; for (int i = 0; i < count; i++) { - final View child = getChildAt(i); + final View child = views[i]; if (child.getVisibility() != GONE) { final LayoutParams childParams = (LayoutParams) child.getLayoutParams(); if (baselineView == null || baselineParams == null @@ -548,9 +548,9 @@ public class RelativeLayout extends ViewGroup { if (offsetHorizontalAxis) { for (int i = 0; i < count; i++) { - View child = getChildAt(i); + final View child = views[i]; if (child.getVisibility() != GONE) { - LayoutParams params = (LayoutParams) child.getLayoutParams(); + final LayoutParams params = (LayoutParams) child.getLayoutParams(); final int[] rules = params.getRules(layoutDirection); if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_HORIZONTAL] != 0) { centerHorizontal(child, params, width); @@ -578,9 +578,9 @@ public class RelativeLayout extends ViewGroup { if (offsetVerticalAxis) { for (int i = 0; i < count; i++) { - View child = getChildAt(i); + final View child = views[i]; if (child.getVisibility() != GONE) { - LayoutParams params = (LayoutParams) child.getLayoutParams(); + final LayoutParams params = (LayoutParams) child.getLayoutParams(); final int[] rules = params.getRules(layoutDirection); if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_VERTICAL] != 0) { centerVertical(child, params, height); @@ -607,9 +607,9 @@ public class RelativeLayout extends ViewGroup { final int verticalOffset = contentBounds.top - top; if (horizontalOffset != 0 || verticalOffset != 0) { for (int i = 0; i < count; i++) { - View child = getChildAt(i); + final View child = views[i]; if (child.getVisibility() != GONE && child != ignore) { - LayoutParams params = (LayoutParams) child.getLayoutParams(); + final LayoutParams params = (LayoutParams) child.getLayoutParams(); if (horizontalGravity) { params.mLeft += horizontalOffset; params.mRight += horizontalOffset; @@ -626,9 +626,9 @@ public class RelativeLayout extends ViewGroup { if (isLayoutRtl()) { final int offsetWidth = myWidth - width; for (int i = 0; i < count; i++) { - View child = getChildAt(i); + final View child = views[i]; if (child.getVisibility() != GONE) { - LayoutParams params = (LayoutParams) child.getLayoutParams(); + final LayoutParams params = (LayoutParams) child.getLayoutParams(); params.mLeft -= offsetWidth; params.mRight -= offsetWidth; } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 78b5d5d..c538dc2 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -241,8 +241,6 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; * @attr ref android.R.styleable#TextView_fontFeatureSettings * @attr ref android.R.styleable#TextView_breakStrategy * @attr ref android.R.styleable#TextView_hyphenationFrequency - * @attr ref android.R.styleable#TextView_leftIndents - * @attr ref android.R.styleable#TextView_rightIndents */ @RemoteView public class TextView extends View implements ViewTreeObserver.OnPreDrawListener { @@ -559,8 +557,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private int mBreakStrategy; private int mHyphenationFrequency; - private int[] mLeftIndents; - private int[] mRightIndents; private int mMaximum = Integer.MAX_VALUE; private int mMaxMode = LINES; @@ -1165,16 +1161,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener case com.android.internal.R.styleable.TextView_hyphenationFrequency: mHyphenationFrequency = a.getInt(attr, Layout.HYPHENATION_FREQUENCY_NONE); break; - - case com.android.internal.R.styleable.TextView_leftIndents: - TypedArray margins = res.obtainTypedArray(a.getResourceId(attr, View.NO_ID)); - mLeftIndents = parseDimensionArray(margins); - break; - - case com.android.internal.R.styleable.TextView_rightIndents: - margins = res.obtainTypedArray(a.getResourceId(attr, View.NO_ID)); - mRightIndents = parseDimensionArray(margins); - break; } } a.recycle(); @@ -3095,51 +3081,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** - * Set indents. Arguments are arrays holding an indent amount, one per line, measured in - * pixels. For lines past the last element in the array, the last element repeats. - * - * @param leftIndents array of indent values for left margin, in pixels - * @param rightIndents array of indent values for right margin, in pixels - * - * @see #getLeftIndents() - * @see #getRightIndents() - * - * @attr ref android.R.styleable#TextView_leftIndents - * @attr ref android.R.styleable#TextView_rightIndents - */ - public void setIndents(@Nullable int[] leftIndents, @Nullable int[] rightIndents) { - mLeftIndents = leftIndents; - mRightIndents = rightIndents; - if (mLayout != null) { - nullLayouts(); - requestLayout(); - invalidate(); - } - } - - /** - * Get left indents. See {#link setMargins} for more details. - * - * @return left indents - * @see #setIndents(int[], int[]) - * @attr ref android.R.styleable#TextView_leftIndents - */ - public int[] getLeftIndents() { - return mLeftIndents; - } - - /** - * Get right indents. See {#link setMargins} for more details. - * - * @return right indents - * @see #setIndents(int[], int[]) - * @attr ref android.R.styleable#TextView_rightIndents - */ - public int[] getRightIndents() { - return mRightIndents; - } - - /** * Sets font feature settings. The format is the same as the CSS * font-feature-settings attribute: * http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings @@ -6685,9 +6626,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy) .setHyphenationFrequency(mHyphenationFrequency); - if (mLeftIndents != null || mRightIndents != null) { - builder.setIndents(mLeftIndents, mRightIndents); - } if (shouldEllipsize) { builder.setEllipsize(mEllipsize) .setEllipsizedWidth(ellipsisWidth) @@ -6776,9 +6714,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy) .setHyphenationFrequency(mHyphenationFrequency); - if (mLeftIndents != null || mRightIndents != null) { - builder.setIndents(mLeftIndents, mRightIndents); - } if (shouldEllipsize) { builder.setEllipsize(effectiveEllipsize) .setEllipsizedWidth(ellipsisWidth) diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java index 2ea2667..471ea9b 100644 --- a/core/java/android/widget/Toolbar.java +++ b/core/java/android/widget/Toolbar.java @@ -273,6 +273,24 @@ public class Toolbar extends ViewGroup { if (!TextUtils.isEmpty(navDesc)) { setNavigationContentDescription(navDesc); } + + final Drawable logo = a.getDrawable(R.styleable.Toolbar_logo); + if (logo != null) { + setLogo(logo); + } + + final CharSequence logoDesc = a.getText(R.styleable.Toolbar_logoDescription); + if (!TextUtils.isEmpty(logoDesc)) { + setLogoDescription(logoDesc); + } + + if (a.hasValue(R.styleable.Toolbar_titleTextColor)) { + setTitleTextColor(a.getColor(R.styleable.Toolbar_titleTextColor, 0xffffffff)); + } + + if (a.hasValue(R.styleable.Toolbar_subtitleTextColor)) { + setSubtitleTextColor(a.getColor(R.styleable.Toolbar_subtitleTextColor, 0xffffffff)); + } a.recycle(); } diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl index 7d3db02..5a195cb 100644 --- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl +++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl @@ -20,6 +20,7 @@ import android.content.ComponentName; import android.content.Intent; import android.content.IntentSender; import android.content.pm.ApplicationInfo; +import android.content.pm.ParceledListSlice; import android.appwidget.AppWidgetProviderInfo; import com.android.internal.appwidget.IAppWidgetHost; import android.os.Bundle; @@ -54,7 +55,7 @@ interface IAppWidgetService { in RemoteViews views); void updateAppWidgetProvider(in ComponentName provider, in RemoteViews views); void notifyAppWidgetViewDataChanged(String packageName, in int[] appWidgetIds, int viewId); - List<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter, + ParceledListSlice getInstalledProvidersForProfile(int categoryFilter, int profileId); AppWidgetProviderInfo getAppWidgetInfo(String callingPackage, int appWidgetId); boolean hasBindAppWidgetPermission(in String packageName, int userId); diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index 230d96d..03f2e3a 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -26,6 +26,13 @@ import android.view.View; * @hide */ public class MetricsLogger implements MetricsConstants { + public static final int VOLUME_DIALOG = 207; + public static final int VOLUME_DIALOG_DETAILS = 208; + public static final int ACTION_VOLUME_SLIDER = 209; + public static final int ACTION_VOLUME_STREAM = 210; + public static final int ACTION_VOLUME_KEY = 211; + public static final int ACTION_VOLUME_ICON = 212; + public static final int ACTION_RINGER_MODE = 213; // Temporary constants go here, to await migration to MetricsConstants. public static void visible(Context context, int category) throws IllegalArgumentException { diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 294e4ba..66f6079 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -390,6 +390,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } else { mLayoutInflater.inflate(layoutResID, mContentParent); } + mContentParent.requestApplyInsets(); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); @@ -419,6 +420,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } else { mContentParent.addView(view, params); } + mContentParent.requestApplyInsets(); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); @@ -435,6 +437,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { Log.v(TAG, "addContentView does not support content transitions"); } mContentParent.addView(view, params); + mContentParent.requestApplyInsets(); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java index 4693d4b..1d62623 100644 --- a/core/java/com/android/internal/statusbar/StatusBarIcon.java +++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java @@ -20,17 +20,27 @@ import android.graphics.drawable.Icon; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; +import android.text.TextUtils; public class StatusBarIcon implements Parcelable { public UserHandle user; + public String pkg; public Icon icon; public int iconLevel; public boolean visible = true; public int number; public CharSequence contentDescription; - public StatusBarIcon(UserHandle user, Icon icon, int iconLevel, int number, + public StatusBarIcon(UserHandle user, String resPackage, Icon icon, int iconLevel, int number, CharSequence contentDescription) { + if (icon.getType() == Icon.TYPE_RESOURCE + && TextUtils.isEmpty(icon.getResPackage())) { + // This is an odd situation where someone's managed to hand us an icon without a + // package inside, probably by mashing an int res into a Notification object. + // Now that we have the correct package name handy, let's fix it. + icon = Icon.createWithResource(resPackage, icon.getResId()); + } + this.pkg = resPackage; this.user = user; this.icon = icon; this.iconLevel = iconLevel; @@ -41,21 +51,23 @@ public class StatusBarIcon implements Parcelable { public StatusBarIcon(String iconPackage, UserHandle user, int iconId, int iconLevel, int number, CharSequence contentDescription) { - this(user, Icon.createWithResource(iconPackage, iconId), + this(user, iconPackage, Icon.createWithResource(iconPackage, iconId), iconLevel, number, contentDescription); } @Override public String toString() { - return "StatusBarIcon(icon=" + this.icon + return "StatusBarIcon(icon=" + icon + + ((iconLevel != 0)?(" level=" + iconLevel):"") + + (visible?" visible":"") + " user=" + user.getIdentifier() - + " level=" + this.iconLevel + " visible=" + visible - + " num=" + this.number + " )"; + + ((number != 0)?(" num=" + number):"") + + " )"; } @Override public StatusBarIcon clone() { - StatusBarIcon that = new StatusBarIcon(this.user, this.icon, + StatusBarIcon that = new StatusBarIcon(this.user, this.pkg, this.icon, this.iconLevel, this.number, this.contentDescription); that.visible = this.visible; return that; @@ -70,6 +82,7 @@ public class StatusBarIcon implements Parcelable { public void readFromParcel(Parcel in) { this.icon = (Icon) in.readParcelable(null); + this.pkg = in.readString(); this.user = (UserHandle) in.readParcelable(null); this.iconLevel = in.readInt(); this.visible = in.readInt() != 0; @@ -79,6 +92,7 @@ public class StatusBarIcon implements Parcelable { public void writeToParcel(Parcel out, int flags) { out.writeParcelable(this.icon, 0); + out.writeString(this.pkg); out.writeParcelable(this.user, 0); out.writeInt(this.iconLevel); out.writeInt(this.visible ? 1 : 0); diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java index 99c1277..784b256 100644 --- a/core/java/com/android/internal/view/FloatingActionMode.java +++ b/core/java/com/android/internal/view/FloatingActionMode.java @@ -25,6 +25,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewConfiguration; +import com.android.internal.R; import com.android.internal.util.Preconditions; import com.android.internal.view.menu.MenuBuilder; import com.android.internal.widget.FloatingToolbar; @@ -44,6 +45,7 @@ public class FloatingActionMode extends ActionMode { private final Rect mViewRect; private final Rect mScreenRect; private final View mOriginatingView; + private final int mBottomAllowance; private final Runnable mMovingOff = new Runnable() { public void run() { @@ -77,6 +79,10 @@ public class FloatingActionMode extends ActionMode { mScreenRect = new Rect(); mOriginatingView = Preconditions.checkNotNull(originatingView); mOriginatingView.getLocationInWindow(mViewPosition); + // Allow the content rect to overshoot a little bit beyond the + // bottom view bound if necessary. + mBottomAllowance = context.getResources() + .getDimensionPixelSize(R.dimen.content_rect_bottom_clip_allowance); } public void setFloatingToolbar(FloatingToolbar floatingToolbar) { @@ -141,7 +147,7 @@ public class FloatingActionMode extends ActionMode { Math.max(mContentRectOnWindow.left, mViewRect.left), Math.max(mContentRectOnWindow.top, mViewRect.top), Math.min(mContentRectOnWindow.right, mViewRect.right), - Math.min(mContentRectOnWindow.bottom, mViewRect.bottom)); + Math.min(mContentRectOnWindow.bottom, mViewRect.bottom + mBottomAllowance)); if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) { // Content rect is moving. diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index 53ebc23..65f2f53f 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -20,7 +20,9 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; +import android.content.ComponentCallbacks; import android.content.Context; +import android.content.res.Configuration; import android.graphics.Color; import android.graphics.Point; import android.graphics.Rect; @@ -89,6 +91,19 @@ public final class FloatingToolbar { private int mSuggestedWidth; private boolean mWidthChanged = true; + private final ComponentCallbacks mOrientationChangeHandler = new ComponentCallbacks() { + @Override + public void onConfigurationChanged(Configuration newConfig) { + if (mPopup.isShowing() && mPopup.viewPortHasChanged()) { + mWidthChanged = true; + updateLayout(); + } + } + + @Override + public void onLowMemory() {} + }; + /** * Initializes a floating toolbar. */ @@ -151,6 +166,8 @@ public final class FloatingToolbar { * Shows this floating toolbar. */ public FloatingToolbar show() { + mContext.unregisterComponentCallbacks(mOrientationChangeHandler); + mContext.registerComponentCallbacks(mOrientationChangeHandler); List<MenuItem> menuItems = getVisibleAndEnabledMenuItems(mMenu); if (!isCurrentlyShowing(menuItems) || mWidthChanged) { mPopup.dismiss(); @@ -181,6 +198,7 @@ public final class FloatingToolbar { * Dismisses this floating toolbar. */ public void dismiss() { + mContext.unregisterComponentCallbacks(mOrientationChangeHandler); mPopup.dismiss(); } @@ -329,6 +347,7 @@ public final class FloatingToolbar { private final Rect mViewPort = new Rect(); private final Point mCoords = new Point(); + private final Rect mTmpRect = new Rect(); private final Region mTouchableRegion = new Region(); private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer = @@ -873,6 +892,11 @@ public final class FloatingToolbar { mParent.getWindowVisibleDisplayFrame(mViewPort); } + private boolean viewPortHasChanged() { + mParent.getWindowVisibleDisplayFrame(mTmpRect); + return !mTmpRect.equals(mViewPort); + } + private int getToolbarWidth(int suggestedWidth) { int width = suggestedWidth; refreshViewPort(); diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp index 3bab2df..e99bdfc 100644 --- a/core/jni/android/graphics/Region.cpp +++ b/core/jni/android/graphics/Region.cpp @@ -231,15 +231,24 @@ static jlong Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel) static jboolean Region_writeToParcel(JNIEnv* env, jobject clazz, jlong regionHandle, jobject parcel) { const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle); - if (parcel == NULL) { + if (parcel == nullptr) { return JNI_FALSE; } android::Parcel* p = android::parcelForJavaObject(env, parcel); - size_t size = region->writeToMemory(NULL); + const size_t size = region->writeToMemory(nullptr); p->writeInt32(size); - region->writeToMemory(p->writeInplace(size)); + void* dst = p->writeInplace(size); + if (dst == nullptr) { + ALOGE("Region.writeToParcel could not write %zi bytes", size); + return JNI_FALSE; + } + const size_t sizeWritten = region->writeToMemory(dst); + if (sizeWritten != size) { + ALOGE("SkRegion::writeToMemory should have written %zi bytes but wrote %zi", + size, sizeWritten); + } return JNI_TRUE; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 65c064b..f197597 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -316,8 +316,6 @@ <protected-broadcast android:name="android.intent.action.ACTION_SET_RADIO_CAPABILITY_FAILED" /> <protected-broadcast android:name="android.internal.policy.action.BURN_IN_PROTECTION" /> - <protected-broadcast android:name="android.service.persistentdata.action.WIPE_IF_ALLOWED" /> - <protected-broadcast android:name="android.app.action.SYSTEM_UPDATE_POLICY_CHANGED" /> <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> diff --git a/core/res/res/drawable/seekbar_track_material.xml b/core/res/res/drawable/seekbar_track_material.xml index 6e40c48..01eb243 100644 --- a/core/res/res/drawable/seekbar_track_material.xml +++ b/core/res/res/drawable/seekbar_track_material.xml @@ -20,7 +20,7 @@ <shape android:shape="rectangle" android:tint="?attr/colorControlNormal"> <size android:height="@dimen/seekbar_track_background_height_material" /> - <solid android:color="#ff000000" /> + <solid android:color="@color/white_disabled_material" /> </shape> </item> <item android:id="@id/secondaryProgress" diff --git a/core/res/res/drawable/spinner_background_material.xml b/core/res/res/drawable/spinner_background_material.xml index 892dbc5..d37f5b7 100644 --- a/core/res/res/drawable/spinner_background_material.xml +++ b/core/res/res/drawable/spinner_background_material.xml @@ -17,22 +17,18 @@ <layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:paddingMode="stack" android:paddingStart="0dp" - android:paddingEnd="48dp" + android:paddingEnd="24dp" android:paddingLeft="0dp" android:paddingRight="0dp"> <item android:gravity="end|center_vertical" - android:width="48dp" - android:height="48dp"> - <ripple - android:color="?attr/colorControlHighlight" - android:radius="24dp" /> - </item> + android:width="24dp" + android:height="24dp" + android:drawable="@drawable/control_background_40dp_material" /> <item android:drawable="@drawable/ic_spinner_caret" android:gravity="end|center_vertical" android:width="24dp" - android:height="24dp" - android:end="12dp" /> + android:height="24dp" /> </layer-list> diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml index 9147cbf..09a63aa 100644 --- a/core/res/res/values-mcc302-mnc220/config.xml +++ b/core/res/res/values-mcc302-mnc220/config.xml @@ -38,7 +38,8 @@ note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" --> <string-array translatable="false" name="config_tether_apndata"> <item>[ApnSettingV3]TELUS ISP,isp.telus.com,,,,,,,,,302,220,,DUN,,,true,0,,,,,,,gid,54</item> - <item>[ApnSettingV3]Tethered PC Mobile,isp.mb.com,,,,,,,,,302,220,,DUN,,,true,0,,,,,,,gid,50</item> + <item>[ApnSettingV3]Tethered Mobile Internet,isp.mb.com,,,,,,,,,302,220,,DUN,,,true,0,,,,,,,gid,50</item> + <item>[ApnSettingV3]Tethered Public Mobile,isp.mb.com,,,,,,,,,302,220,,DUN,,,true,0,,,,,,,gid,4D4F</item> </string-array> </resources> diff --git a/core/res/res/values-mcc302-mnc720/config.xml b/core/res/res/values-mcc302-mnc720/config.xml index a83107a..dcfa5c5 100644 --- a/core/res/res/values-mcc302-mnc720/config.xml +++ b/core/res/res/values-mcc302-mnc720/config.xml @@ -29,6 +29,8 @@ <string-array translatable="false" name="config_tether_apndata"> <item>Rogers LTE Tethering,ltedata.apn,,,,,,,,,302,720,,DUN</item> <item>[ApnSettingV3]chatr Tethering,chatrisp.apn,,,,,,,,,302,720,,DUN,,,true,0,,,,,,,imsi,302720x94</item> + <item>[ApnSettingV3]Tbaytel Tethering,ltedata.apn,,,,,,,,,302,720,,DUN,IPV4V6,IP,true,0,,,,,,,gid,BA</item> + <item>[ApnSettingV3]Cityfone Tethering,ltedata.apn,,,,,,,,,302,720,,DUN,IPV4V6,IP,true,0,,,,,,,spn,CITYFONE</item> </string-array> <!-- Configure mobile network MTU. Carrier specific value is set here. diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index c08d511..33c9c60 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -4384,7 +4384,7 @@ i <enum name="simple" value="0" /> <!-- Line breaking uses high-quality strategy, including hyphenation. --> <enum name="high_quality" value="1" /> - <!-- Line breaking stratgegy balances line lengths. --> + <!-- Line breaking strategy balances line lengths. --> <enum name="balanced" value="2" /> </attr> <!-- Frequency of automatic hyphenation. --> @@ -4398,10 +4398,10 @@ i screens with limited space for text. --> <enum name="full" value="2" /> </attr> - <!-- Array of indents, one dimension value per line, left side. --> - <attr name="leftIndents" format="reference" /> - <!-- Array of indents, one dimension value per line, right side. --> - <attr name="rightIndents" format="reference" /> + <!-- Placeholder for a deleted attribute. This should be removed before M release. --> + <attr name="__removeBeforeMRelease_leftIndents" format="reference" /> + <!-- Placeholder for a deleted attribute. This should be removed before M release. --> + <attr name="__removeBeforeMRelease_rightIndents" format="reference" /> </declare-styleable> <declare-styleable name="TextViewAppearance"> <!-- Base text color, typeface, size, and style. --> @@ -7775,6 +7775,16 @@ i <!-- Text to set as the content description for the navigation button located at the start of the toolbar. --> <attr name="navigationContentDescription" format="string" /> + <!-- Drawable to set as the logo that appears at the starting side of + the Toolbar, just after the navigation button. --> + <attr name="logo" /> + <!-- A content description string to describe the appearance of the + associated logo image. --> + <attr name="logoDescription" format="string" /> + <!-- A color to apply to the title string. --> + <attr name="titleTextColor" format="color" /> + <!-- A color to apply to the subtitle string. --> + <attr name="subtitleTextColor" format="color" /> </declare-styleable> <declare-styleable name="Toolbar_LayoutParams"> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index e60a48d..7e74680 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -399,6 +399,7 @@ <dimen name="floating_toolbar_maximum_overflow_height">192dp</dimen> <dimen name="floating_toolbar_horizontal_margin">16dp</dimen> <dimen name="floating_toolbar_vertical_margin">8dp</dimen> + <dimen name="content_rect_bottom_clip_allowance">20dp</dimen> <dimen name="chooser_grid_padding">0dp</dimen> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index bbe27a4..65fa36b 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2683,8 +2683,9 @@ <public type="attr" name="lockTaskMode" /> - <public type="attr" name="leftIndents" /> - <public type="attr" name="rightIndents" /> + <!-- Placeholder for a removed attribute. Remove this before M release. --> + <public type="attr" name="__removeBeforeMRelease_leftIndents" /> + <public type="attr" name="__removeBeforeMRelease_rightIndents" /> <public type="attr" name="showForAllUsers" /> @@ -2699,4 +2700,7 @@ <public type="attr" name="scrollIndicators" /> <public type="attr" name="hyphenationFrequency" /> <public type="attr" name="fingerprintAuthDrawable" /> + <public type="attr" name="logoDescription" /> + <public type="attr" name="titleTextColor" /> + <public type="attr" name="subtitleTextColor" /> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 510f6a5..ea0d349 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -537,10 +537,10 @@ <!-- Label for the Android system components when they are shown to the user. --> <string name="android_system_label">Android System</string> - <!-- Label for the user owner in the intent forwarding app. --> - <string name="user_owner_label">Personal apps</string> + <!-- Label for the user owner in the intent forwarding app. [CHAR LIMIT=15] --> + <string name="user_owner_label">Personal</string> - <!-- Label for a corporate profile in the intent forwarding app. --> + <!-- Label for a corporate profile in the intent forwarding app. [CHAR LIMIT=15] --> <string name="managed_profile_label">Work</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 5ba57c4..4160e0e 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2274,6 +2274,7 @@ <java-symbol type="dimen" name="floating_toolbar_maximum_overflow_height" /> <java-symbol type="dimen" name="floating_toolbar_horizontal_margin" /> <java-symbol type="dimen" name="floating_toolbar_vertical_margin" /> + <java-symbol type="dimen" name="content_rect_bottom_clip_allowance" /> <java-symbol type="string" name="date_picker_prev_month_button" /> <java-symbol type="string" name="date_picker_next_month_button" /> diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index a0c407f..f059727 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -363,7 +363,7 @@ public class BitmapDrawable extends Drawable { } @Override - public boolean getDither() { + public boolean isDither() { return mBitmapState.mPaint.isDither(); } diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 415af0d..6090cf0 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -279,7 +279,7 @@ public abstract class Drawable { * @return whether this drawable dithers its colors * @see #setDither(boolean) */ - public boolean getDither() { + public boolean isDither() { return false; } diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 8b801c3..1759f53 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -167,7 +167,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } @Override - public boolean getDither() { + public boolean isDither() { return mDrawableContainerState.mDither; } diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index ed47eed..626991d 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -826,7 +826,7 @@ public class GradientDrawable extends Drawable { } @Override - public boolean getDither() { + public boolean isDither() { return mGradientState.mDither; } diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java index 7b4329a..85db6a1 100644 --- a/graphics/java/android/graphics/drawable/Icon.java +++ b/graphics/java/android/graphics/drawable/Icon.java @@ -29,6 +29,7 @@ import android.os.Handler; import android.os.Message; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; import android.util.Log; import java.io.DataInputStream; @@ -258,16 +259,21 @@ public final class Icon implements Parcelable { return new BitmapDrawable(context.getResources(), getBitmap()); case TYPE_RESOURCE: if (getResources() == null) { - if (getResPackage() == null || "android".equals(getResPackage())) { + // figure out where to load resources from + String resPackage = getResPackage(); + if (TextUtils.isEmpty(resPackage)) { + // if none is specified, try the given context + resPackage = context.getPackageName(); + } + if ("android".equals(resPackage)) { mObj1 = Resources.getSystem(); } else { final PackageManager pm = context.getPackageManager(); try { - mObj1 = pm.getResourcesForApplication(getResPackage()); + mObj1 = pm.getResourcesForApplication(resPackage); } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, String.format("Unable to find pkg=%s", - getResPackage()), - e); + Log.e(TAG, String.format("Unable to find pkg=%s for icon %s", + resPackage, this), e); break; } } @@ -320,12 +326,15 @@ public final class Icon implements Parcelable { */ public Drawable loadDrawableAsUser(Context context, int userId) { if (mType == TYPE_RESOURCE) { - if (getResources() == null - && getResPackage() != null - && !(getResPackage().equals("android"))) { + String resPackage = getResPackage(); + if (TextUtils.isEmpty(resPackage)) { + resPackage = context.getPackageName(); + } + if (getResources() == null && !(getResPackage().equals("android"))) { final PackageManager pm = context.getPackageManager(); try { - mObj1 = pm.getResourcesForApplicationAsUser(getResPackage(), userId); + // assign getResources() as the correct user + mObj1 = pm.getResourcesForApplicationAsUser(resPackage, userId); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, String.format("Unable to find pkg=%s user=%d", getResPackage(), @@ -410,6 +419,9 @@ public final class Icon implements Parcelable { * @param resId ID of the drawable resource */ public static Icon createWithResource(Context context, @DrawableRes int resId) { + if (context == null) { + throw new IllegalArgumentException("Context must not be null."); + } final Icon rep = new Icon(TYPE_RESOURCE); rep.mInt1 = resId; rep.mString1 = context.getPackageName(); diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 5c00a23..90891f6 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -1248,12 +1248,12 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { } @Override - public boolean getDither() { + public boolean isDither() { final Drawable dr = getFirstNonNullDrawable(); if (dr != null) { - return dr.getDither(); + return dr.isDither(); } else { - return super.getDither(); + return super.isDither(); } } @@ -1537,8 +1537,23 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { continue; } + // Take the resolved layout direction into account. If start / end + // padding are defined, they will be resolved (hence overriding) to + // left / right or right / left depending on the resolved layout + // direction. If start / end padding are not defined, use the + // left / right ones. + final int insetL, insetR; + final int layoutDirection = getLayoutDirection(); + if (layoutDirection == LayoutDirection.RTL) { + insetL = r.mInsetE == UNDEFINED_INSET ? r.mInsetL : r.mInsetE; + insetR = r.mInsetS == UNDEFINED_INSET ? r.mInsetR : r.mInsetS; + } else { + insetL = r.mInsetS == UNDEFINED_INSET ? r.mInsetL : r.mInsetS; + insetR = r.mInsetE == UNDEFINED_INSET ? r.mInsetR : r.mInsetE; + } + final int minWidth = r.mWidth < 0 ? r.mDrawable.getIntrinsicWidth() : r.mWidth; - final int w = minWidth + r.mInsetL + r.mInsetR + padL + padR; + final int w = minWidth + insetL + insetR + padL + padR; if (w > width) { width = w; } diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 0b7869b..adf53e3 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -374,7 +374,7 @@ public class NinePatchDrawable extends Drawable { } @Override - public boolean getDither() { + public boolean isDither() { return mPaint == null ? DEFAULT_DITHER : mPaint.isDither(); } diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index 334b3bd..a669d3c 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -328,7 +328,7 @@ public class ShapeDrawable extends Drawable { } @Override - public boolean getDither() { + public boolean isDither() { return mShapeState.mPaint.isDither(); } diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java index 06b76fa..156f45f 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java @@ -132,52 +132,52 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { putSignatureImpl("MD5withRSA", PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$MD5WithPKCS1Padding"); - put("Alg.Alias.Signature.MD5WithRSAEncryption", "MD5WithRSA"); - put("Alg.Alias.Signature.MD5/RSA", "MD5WithRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5WithRSA"); - put("Alg.Alias.Signature.1.2.840.113549.2.5with1.2.840.113549.1.1.1", "MD5WithRSA"); + put("Alg.Alias.Signature.MD5WithRSAEncryption", "MD5withRSA"); + put("Alg.Alias.Signature.MD5/RSA", "MD5withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.2.5with1.2.840.113549.1.1.1", "MD5withRSA"); putSignatureImpl("SHA1withRSA", PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA1WithPKCS1Padding"); - put("Alg.Alias.Signature.SHA1WithRSAEncryption", "SHA1WithRSA"); - put("Alg.Alias.Signature.SHA1/RSA", "SHA1WithRSA"); - put("Alg.Alias.Signature.SHA-1/RSA", "SHA1WithRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1WithRSA"); - put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.1", "SHA1WithRSA"); - put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.5", "SHA1WithRSA"); - put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1WithRSA"); + put("Alg.Alias.Signature.SHA1WithRSAEncryption", "SHA1withRSA"); + put("Alg.Alias.Signature.SHA1/RSA", "SHA1withRSA"); + put("Alg.Alias.Signature.SHA-1/RSA", "SHA1withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA"); + put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.1", "SHA1withRSA"); + put("Alg.Alias.Signature.1.3.14.3.2.26with1.2.840.113549.1.1.5", "SHA1withRSA"); + put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA"); putSignatureImpl("SHA224withRSA", PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA224WithPKCS1Padding"); - put("Alg.Alias.Signature.SHA224WithRSAEncryption", "SHA224WithRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA224WithRSA"); + put("Alg.Alias.Signature.SHA224WithRSAEncryption", "SHA224withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA224withRSA"); put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.4with1.2.840.113549.1.1.1", - "SHA224WithRSA"); + "SHA224withRSA"); put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.4with1.2.840.113549.1.1.11", - "SHA224WithRSA"); + "SHA224withRSA"); putSignatureImpl("SHA256withRSA", PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA256WithPKCS1Padding"); - put("Alg.Alias.Signature.SHA256WithRSAEncryption", "SHA256WithRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256WithRSA"); + put("Alg.Alias.Signature.SHA256WithRSAEncryption", "SHA256withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA"); put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.1", - "SHA256WithRSA"); + "SHA256withRSA"); put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.1with1.2.840.113549.1.1.11", - "SHA256WithRSA"); + "SHA256withRSA"); putSignatureImpl("SHA384withRSA", PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA384WithPKCS1Padding"); - put("Alg.Alias.Signature.SHA384WithRSAEncryption", "SHA384WithRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384WithRSA"); + put("Alg.Alias.Signature.SHA384WithRSAEncryption", "SHA384withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA"); put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.2with1.2.840.113549.1.1.1", - "SHA384WithRSA"); + "SHA384withRSA"); putSignatureImpl("SHA512withRSA", PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA512WithPKCS1Padding"); - put("Alg.Alias.Signature.SHA512WithRSAEncryption", "SHA512WithRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512WithRSA"); + put("Alg.Alias.Signature.SHA512WithRSAEncryption", "SHA512withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA"); put("Alg.Alias.Signature.2.16.840.1.101.3.4.2.3with1.2.840.113549.1.1.1", - "SHA512WithRSA"); + "SHA512withRSA"); putSignatureImpl("SHA1withRSA/PSS", PACKAGE_NAME + ".AndroidKeyStoreRSASignatureSpi$SHA1WithPSSPadding"); diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java index af05578..2055cdb 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -226,9 +226,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato | KeyProperties.PURPOSE_VERIFY); // Authorized to be used with any digest (including no digest). specBuilder.setDigests(KeyProperties.DIGEST_NONE); - specBuilder.setSignaturePaddings( - KeyProperties.SIGNATURE_PADDING_RSA_PKCS1); - // Authorized to be used with any padding (including no padding). + // Authorized to be used with any encryption and signature padding + // scheme (including no padding). specBuilder.setEncryptionPaddings( KeyProperties.ENCRYPTION_PADDING_NONE); // Disable randomized encryption requirement to support encryption diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java index 3bd9d1d..5fb589e 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java @@ -258,9 +258,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { | KeyProperties.PURPOSE_VERIFY); // Authorized to be used with any digest (including no digest). specBuilder.setDigests(KeyProperties.DIGEST_NONE); - specBuilder.setSignaturePaddings( - KeyProperties.SIGNATURE_PADDING_RSA_PKCS1); - // Authorized to be used with any padding (including no padding). + // Authorized to be used with any encryption and signature padding scheme (including no + // padding). specBuilder.setEncryptionPaddings( KeyProperties.ENCRYPTION_PADDING_NONE); // Disable randomized encryption requirement to support encryption padding NONE diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index a3ea896..f3d755c 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -75,6 +75,7 @@ interface ILocationManager String getBestProvider(in Criteria criteria, boolean enabledOnly); boolean providerMeetsCriteria(String provider, in Criteria criteria); ProviderProperties getProviderProperties(String provider); + String getNetworkProviderPackage(); boolean isProviderEnabled(String provider); void addTestProvider(String name, in ProviderProperties properties, String opPackageName); diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 8e96218..c75c7e5 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -40,7 +40,7 @@ import android.view.KeyEvent; */ interface IAudioService { - void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, + oneway void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller); void adjustStreamVolume(int streamType, int direction, int flags, String callingPackage); diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp index 634ba64..ba7634c 100644 --- a/media/jni/android_media_ImageWriter.cpp +++ b/media/jni/android_media_ImageWriter.cpp @@ -361,8 +361,7 @@ static void ImageWriter_close(JNIEnv* env, jobject thiz, jlong nativeCtx) { ALOGV("%s:", __FUNCTION__); JNIImageWriterContext* const ctx = reinterpret_cast<JNIImageWriterContext *>(nativeCtx); if (ctx == NULL || thiz == NULL) { - jniThrowException(env, "java/lang/IllegalStateException", - "ImageWriterContext is not initialized"); + // ImageWriter is already closed. return; } diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index 90ccf91..fe148da 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -393,25 +393,23 @@ public class DocumentsActivity extends BaseActivity { @Override public void updateActionBar() { if (mRootsToolbar != null) { - if (mState.action == ACTION_OPEN || - mState.action == ACTION_GET_CONTENT || - mState.action == ACTION_OPEN_TREE) { - mRootsToolbar.setTitle(R.string.title_open); - } else if (mState.action == ACTION_CREATE || - mState.action == ACTION_OPEN_COPY_DESTINATION) { - mRootsToolbar.setTitle(R.string.title_save); + final String prompt = getIntent().getStringExtra(DocumentsContract.EXTRA_PROMPT); + if (prompt != null) { + mRootsToolbar.setTitle(prompt); + } else { + if (mState.action == ACTION_OPEN || + mState.action == ACTION_GET_CONTENT || + mState.action == ACTION_OPEN_TREE) { + mRootsToolbar.setTitle(R.string.title_open); + } else if (mState.action == ACTION_CREATE || + mState.action == ACTION_OPEN_COPY_DESTINATION) { + mRootsToolbar.setTitle(R.string.title_save); + } } } - final RootInfo root = getCurrentRoot(); - final boolean showRootIcon = mShowAsDialog - || (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE); - if (showRootIcon) { - mToolbar.setNavigationIcon( - root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null); - mToolbar.setNavigationContentDescription(R.string.drawer_open); - mToolbar.setNavigationOnClickListener(null); - } else { + if (!mShowAsDialog && mDrawerLayout.getDrawerLockMode(mRootsDrawer) == + DrawerLayout.LOCK_MODE_UNLOCKED) { mToolbar.setNavigationIcon(R.drawable.ic_hamburger); mToolbar.setNavigationContentDescription(R.string.drawer_open); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @@ -420,6 +418,10 @@ public class DocumentsActivity extends BaseActivity { setRootsDrawerOpen(true); } }); + } else { + mToolbar.setNavigationIcon(null); + mToolbar.setNavigationContentDescription(R.string.drawer_open); + mToolbar.setNavigationOnClickListener(null); } if (mSearchManager.isExpanded()) { @@ -428,7 +430,7 @@ public class DocumentsActivity extends BaseActivity { mToolbarStack.setAdapter(null); } else { if (mState.stack.size() <= 1) { - mToolbar.setTitle(root.title); + mToolbar.setTitle(getCurrentRoot().title); mToolbarStack.setVisibility(View.GONE); mToolbarStack.setAdapter(null); } else { diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index 442af90..89c456c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -316,14 +316,12 @@ public class Recents extends SystemUI void hideRecentsInternal(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) { if (mBootCompleted) { - ActivityManager.RunningTaskInfo topTask = mSystemServicesProxy.getTopMostTask(); - if (topTask != null && mSystemServicesProxy.isRecentsTopMost(topTask, null)) { - // Notify recents to hide itself - Intent intent = createLocalBroadcastIntent(mContext, ACTION_HIDE_RECENTS_ACTIVITY); - intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab); - intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey); - mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); - } + // Defer to the activity to handle hiding recents, if it handles it, then it must still + // be visible + Intent intent = createLocalBroadcastIntent(mContext, ACTION_HIDE_RECENTS_ACTIVITY); + intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab); + intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey); + mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 3885799..3cd769e 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -134,9 +134,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView dismissRecentsToFocusedTaskOrHome(false); } else if (intent.getBooleanExtra(Recents.EXTRA_TRIGGERED_FROM_HOME_KEY, false)) { // Otherwise, dismiss Recents to Home - dismissRecentsToHome(true); + dismissRecentsToHomeRaw(true); } else { - // Do nothing, another activity is being launched on top of Recents + // Do nothing } } else if (action.equals(Recents.ACTION_TOGGLE_RECENTS_ACTIVITY)) { // If we are toggling Recents, then first unfilter any filtered stacks first diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java index 02a7b94..d4e50f8 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsAppWidgetHost.java @@ -70,6 +70,7 @@ public class RecentsAppWidgetHost extends AppWidgetHost { @Override protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidgetInfo) { if (mCb == null) return; + if (mContext == null) return; SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); if (appWidgetId > -1 && appWidgetId == mConfig.searchBarAppWidgetId) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 5711cd6..ebfc796 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -22,10 +22,12 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import com.android.systemui.R; import com.android.systemui.recents.Constants; @@ -133,6 +135,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } } }); + setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); } /** Sets the callbacks */ @@ -350,6 +353,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mTmpTaskViewMap.clear(); List<TaskView> taskViews = getTaskViews(); int taskViewCount = taskViews.size(); + boolean reaquireAccessibilityFocus = false; for (int i = taskViewCount - 1; i >= 0; i--) { TaskView tv = taskViews.get(i); Task task = tv.getTask(); @@ -358,6 +362,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mTmpTaskViewMap.put(task, tv); } else { mViewPool.returnViewToPool(tv); + reaquireAccessibilityFocus |= (i == mPrevAccessibilityFocusedIndex); // Hide the dismiss button if the front most task is invisible if (task == mStack.getFrontMostTask()) { @@ -402,14 +407,17 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Request accessibility focus on the next view if we removed the task // that previously held accessibility focus - taskViews = getTaskViews(); - taskViewCount = taskViews.size(); - if (taskViewCount > 0 && ssp.isTouchExplorationEnabled()) { - TaskView atv = taskViews.get(taskViewCount - 1); - int indexOfTask = mStack.indexOfTask(atv.getTask()); - if (mPrevAccessibilityFocusedIndex != indexOfTask) { - tv.requestAccessibilityFocus(); - mPrevAccessibilityFocusedIndex = indexOfTask; + if (reaquireAccessibilityFocus) { + taskViews = getTaskViews(); + taskViewCount = taskViews.size(); + if (taskViewCount > 0 && ssp.isTouchExplorationEnabled() && + mPrevAccessibilityFocusedIndex != -1) { + TaskView atv = taskViews.get(taskViewCount - 1); + int indexOfTask = mStack.indexOfTask(atv.getTask()); + if (mPrevAccessibilityFocusedIndex != indexOfTask) { + tv.requestAccessibilityFocus(); + mPrevAccessibilityFocusedIndex = indexOfTask; + } } } } @@ -496,25 +504,20 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal if (0 <= taskIndex && taskIndex < mStack.getTaskCount()) { mFocusedTaskIndex = taskIndex; + mPrevAccessibilityFocusedIndex = taskIndex; // Focus the view if possible, otherwise, focus the view after we scroll into position - Task t = mStack.getTasks().get(taskIndex); - TaskView tv = getChildViewForTask(t); - Runnable postScrollRunnable = null; - if (tv != null) { - tv.setFocusedTask(animateFocusedState); - } else { - postScrollRunnable = new Runnable() { - @Override - public void run() { - Task t = mStack.getTasks().get(mFocusedTaskIndex); - TaskView tv = getChildViewForTask(t); - if (tv != null) { - tv.setFocusedTask(animateFocusedState); - } + final Task t = mStack.getTasks().get(mFocusedTaskIndex); + Runnable postScrollRunnable = new Runnable() { + @Override + public void run() { + TaskView tv = getChildViewForTask(t); + if (tv != null) { + tv.setFocusedTask(animateFocusedState); + tv.requestAccessibilityFocus(); } - }; - } + } + }; // Scroll the view into position (just center it in the curve) if (scrollToNewPosition) { @@ -534,25 +537,30 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal * Ensures that there is a task focused, if nothing is focused, then we will use the task * at the center of the visible stack. */ - public boolean ensureFocusedTask() { + public boolean ensureFocusedTask(boolean findClosestToCenter) { if (mFocusedTaskIndex < 0) { - // If there is no task focused, then find the task that is closes to the center - // of the screen and use that as the currently focused task - int x = mLayoutAlgorithm.mStackVisibleRect.centerX(); - int y = mLayoutAlgorithm.mStackVisibleRect.centerY(); List<TaskView> taskViews = getTaskViews(); int taskViewCount = taskViews.size(); - for (int i = taskViewCount - 1; i >= 0; i--) { - TaskView tv = taskViews.get(i); - tv.getHitRect(mTmpRect); - if (mTmpRect.contains(x, y)) { - mFocusedTaskIndex = mStack.indexOfTask(tv.getTask()); - break; + if (findClosestToCenter) { + // If there is no task focused, then find the task that is closes to the center + // of the screen and use that as the currently focused task + int x = mLayoutAlgorithm.mStackVisibleRect.centerX(); + int y = mLayoutAlgorithm.mStackVisibleRect.centerY(); + for (int i = taskViewCount - 1; i >= 0; i--) { + TaskView tv = taskViews.get(i); + tv.getHitRect(mTmpRect); + if (mTmpRect.contains(x, y)) { + mFocusedTaskIndex = mStack.indexOfTask(tv.getTask()); + mPrevAccessibilityFocusedIndex = mFocusedTaskIndex; + break; + } } } // If we can't find the center task, then use the front most index if (mFocusedTaskIndex < 0 && taskViewCount > 0) { - mFocusedTaskIndex = taskViewCount - 1; + TaskView tv = taskViews.get(taskViewCount - 1); + mFocusedTaskIndex = mStack.indexOfTask(tv.getTask()); + mPrevAccessibilityFocusedIndex = mFocusedTaskIndex; } } return mFocusedTaskIndex >= 0; @@ -600,6 +608,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } } mFocusedTaskIndex = -1; + mPrevAccessibilityFocusedIndex = -1; } @Override @@ -620,6 +629,53 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } @Override + public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + List<TaskView> taskViews = getTaskViews(); + int taskViewCount = taskViews.size(); + if (taskViewCount > 1 && mPrevAccessibilityFocusedIndex != -1) { + info.setScrollable(true); + if (mPrevAccessibilityFocusedIndex > 0) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); + } + if (mPrevAccessibilityFocusedIndex < mStack.getTaskCount() - 1) { + info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); + } + } + } + + @Override + public CharSequence getAccessibilityClassName() { + return TaskStackView.class.getName(); + } + + @Override + public boolean performAccessibilityAction(int action, Bundle arguments) { + if (super.performAccessibilityAction(action, arguments)) { + return true; + } + if (ensureFocusedTask(false)) { + switch (action) { + case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { + if (mPrevAccessibilityFocusedIndex > 0) { + focusNextTask(true, false); + return true; + } + } + break; + case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { + if (mPrevAccessibilityFocusedIndex < mStack.getTaskCount() - 1) { + focusNextTask(false, false); + return true; + } + } + break; + } + } + return false; + } + + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return mTouchHandler.onInterceptTouchEvent(ev); } @@ -724,8 +780,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal if (mDismissAllButton != null) { int taskRectWidth = mLayoutAlgorithm.mTaskRect.width(); mDismissAllButton.measure( - MeasureSpec.makeMeasureSpec(taskRectWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(mConfig.dismissAllButtonSizePx, MeasureSpec.EXACTLY)); + MeasureSpec.makeMeasureSpec(taskRectWidth, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(mConfig.dismissAllButtonSizePx, MeasureSpec.EXACTLY)); } setMeasuredDimension(width, height); 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 509560eb..13bdbd2 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java @@ -396,11 +396,11 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { // Find the front most task and scroll the next task to the front float vScroll = ev.getAxisValue(MotionEvent.AXIS_VSCROLL); if (vScroll > 0) { - if (mSv.ensureFocusedTask()) { + if (mSv.ensureFocusedTask(true)) { mSv.focusNextTask(true, false); } } else { - if (mSv.ensureFocusedTask()) { + if (mSv.ensureFocusedTask(true)) { mSv.focusNextTask(false, false); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 79761ec..a496548 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -41,6 +41,7 @@ import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.os.AsyncTask; import android.os.Build; import android.os.Handler; @@ -1396,6 +1397,7 @@ public abstract class BaseStatusBar extends SystemUI implements final StatusBarIcon ic = new StatusBarIcon( entry.notification.getUser(), + entry.notification.getPackageName(), entry.notification.getNotification().getSmallIcon(), entry.notification.getNotification().iconLevel, entry.notification.getNotification().number, @@ -1682,10 +1684,11 @@ public abstract class BaseStatusBar extends SystemUI implements final StatusBarIcon ic = new StatusBarIcon( sbn.getUser(), - n.getSmallIcon(), - n.iconLevel, - n.number, - n.tickerText); + sbn.getPackageName(), + n.getSmallIcon(), + n.iconLevel, + n.number, + n.tickerText); if (!iconView.set(ic)) { handleNotificationError(sbn, "Couldn't create icon: " + ic); return null; @@ -1825,6 +1828,7 @@ public abstract class BaseStatusBar extends SystemUI implements // Update the icon final StatusBarIcon ic = new StatusBarIcon( notification.getUser(), + notification.getPackageName(), n.getSmallIcon(), n.iconLevel, n.number, @@ -1847,6 +1851,7 @@ public abstract class BaseStatusBar extends SystemUI implements if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key); final StatusBarIcon ic = new StatusBarIcon( notification.getUser(), + notification.getPackageName(), n.getSmallIcon(), n.iconLevel, n.number, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java index dbabe3f..aedae52 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java @@ -125,16 +125,22 @@ public class NotificationData { @Override public int compare(Entry a, Entry b) { - String mediaNotification = mEnvironment.getCurrentMediaNotificationKey(); - boolean aMedia = a.key.equals(mediaNotification); - boolean bMedia = b.key.equals(mediaNotification); - final StatusBarNotification na = a.notification; final StatusBarNotification nb = b.notification; + final int aPriority = na.getNotification().priority; + final int bPriority = nb.getNotification().priority; + + String mediaNotification = mEnvironment.getCurrentMediaNotificationKey(); + + // PRIORITY_MIN media streams are allowed to drift to the bottom + final boolean aMedia = a.key.equals(mediaNotification) + && aPriority > Notification.PRIORITY_MIN; + final boolean bMedia = b.key.equals(mediaNotification) + && bPriority > Notification.PRIORITY_MIN; - boolean aSystemMax = na.getNotification().priority >= Notification.PRIORITY_MAX && + boolean aSystemMax = aPriority >= Notification.PRIORITY_MAX && isSystemNotification(na); - boolean bSystemMax = nb.getNotification().priority >= Notification.PRIORITY_MAX && + boolean bSystemMax = bPriority >= Notification.PRIORITY_MAX && isSystemNotification(nb); int d = nb.getScore() - na.getScore(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 26d1c86..fcdd4b7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -124,6 +124,9 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode { private void updateSlot(String slot, String iconPkg, int iconId) { if (!mDemoMode) return; + if (iconPkg == null) { + iconPkg = mContext.getPackageName(); + } int removeIndex = -1; for (int i = 0; i < getChildCount(); i++) { StatusBarIconView v = (StatusBarIconView) getChildAt(i); @@ -143,10 +146,10 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode { if (iconId == 0) { if (removeIndex != -1) { removeViewAt(removeIndex); - return; } + return; } - StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.CURRENT, iconId, 0, 0, "Demo"); + StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.OWNER, iconId, 0, 0, "Demo"); StatusBarIconView v = new StatusBarIconView(getContext(), null, null); v.setTag(slot); v.set(icon); 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 495f0fd..c30cb34 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -491,7 +491,7 @@ public class NotificationPanelView extends PanelView implements } public void closeQs() { - cancelAnimation(); + cancelQsAnimation(); setQsExpansion(mQsMinExpansionHeight); } @@ -508,7 +508,7 @@ public class NotificationPanelView extends PanelView implements } public void openQs() { - cancelAnimation(); + cancelQsAnimation(); if (mQsExpansionEnabled) { setQsExpansion(mQsMaxExpansionHeight); } @@ -921,7 +921,7 @@ public class NotificationPanelView extends PanelView implements @Override public void onOverscrollTopChanged(float amount, boolean isRubberbanded) { - cancelAnimation(); + cancelQsAnimation(); if (!mQsExpansionEnabled) { amount = 0f; } @@ -953,7 +953,8 @@ public class NotificationPanelView extends PanelView implements } private void onQsExpansionStarted(int overscrollAmount) { - cancelAnimation(); + cancelQsAnimation(); + cancelHeightAnimator(); // Reset scroll position and apply that position to the expanded height. float height = mQsExpansionHeight - mScrollView.getScrollY() - overscrollAmount; @@ -1391,7 +1392,7 @@ public class NotificationPanelView extends PanelView implements return mVelocityTracker.getYVelocity(); } - private void cancelAnimation() { + private void cancelQsAnimation() { if (mQsExpansionAnimator != null) { mQsExpansionAnimator.cancel(); } 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 9d4997c..094d5f0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -535,7 +535,7 @@ public abstract class PanelView extends FrameLayout { */ protected abstract boolean isInContentBounds(float x, float y); - private void cancelHeightAnimator() { + protected void cancelHeightAnimator() { if (mHeightAnimator != null) { mHeightAnimator.cancel(); } 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 69198ed..cd90d27 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -3460,6 +3460,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mKeyguardIndicationController.setVisible(true); mNotificationPanel.resetViews(); mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked); + mStatusBarView.removePendingHideExpandedRunnables(); } else { mKeyguardIndicationController.setVisible(false); mKeyguardUserSwitcher.setKeyguard(false, 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 dfd280a..6a46924 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -42,6 +42,12 @@ public class PhoneStatusBarView extends PanelBar { private ScrimController mScrimController; private float mMinFraction; private float mPanelFraction; + private Runnable mHideExpandedRunnable = new Runnable() { + @Override + public void run() { + mBar.makeExpandedInvisible(); + } + }; public PhoneStatusBarView(Context context, AttributeSet attrs) { super(context, attrs); @@ -118,15 +124,14 @@ public class PhoneStatusBarView extends PanelBar { + Log.getStackTraceString(new Throwable())); } // Close the status bar in the next frame so we can show the end of the animation. - postOnAnimation(new Runnable() { - @Override - public void run() { - mBar.makeExpandedInvisible(); - } - }); + postOnAnimation(mHideExpandedRunnable); mLastFullyOpenedPanel = null; } + public void removePendingHideExpandedRunnables() { + removeCallbacks(mHideExpandedRunnable); + } + @Override public void onPanelFullyOpened(PanelView openPanel) { super.onPanelFullyOpened(openPanel); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java index 0eb7197..d1e4963 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessPointControllerImpl.java @@ -116,7 +116,7 @@ public class AccessPointControllerImpl // Unknown network, need to add it. if (ap.getSecurity() != AccessPoint.SECURITY_NONE) { Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS); - intent.putExtra(EXTRA_START_CONNECT_SSID, ap.getSsid()); + intent.putExtra(EXTRA_START_CONNECT_SSID, ap.getSsidStr()); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); fireSettingsIntentCallback(intent); return true; 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 18b5820..1ba87da 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -408,7 +408,7 @@ public class NetworkControllerImpl extends BroadcastReceiver boolean hasNoSims = mHasMobileDataFeature && mMobileSignalControllers.size() == 0; if (hasNoSims != mHasNoSims) { mHasNoSims = hasNoSims; - notifyListeners(); + mCallbackHandler.setNoSims(mHasNoSims); } } @@ -660,8 +660,8 @@ public class NetworkControllerImpl extends BroadcastReceiver } String nosim = args.getString("nosim"); if (nosim != null) { - boolean show = nosim.equals("show"); - mCallbackHandler.setNoSims(show); + mHasNoSims = nosim.equals("show"); + mCallbackHandler.setNoSims(mHasNoSims); } String mobile = args.getString("mobile"); if (mobile != null) { 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 1bf4547..5700732 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -228,6 +228,7 @@ public class NotificationStackScrollLayout extends ViewGroup private ScrimController mScrimController; private boolean mForceNoOverlappingRendering; private NotificationOverflowContainer mOverflowContainer; + private final ArrayList<Pair<ExpandableNotificationRow, Boolean>> mTmpList = new ArrayList<>(); public NotificationStackScrollLayout(Context context) { this(context, null); @@ -1608,7 +1609,7 @@ public class NotificationStackScrollLayout extends ViewGroup } @Override - protected void onViewRemoved(View child) { + public void onViewRemoved(View child) { super.onViewRemoved(child); // we only call our internal methods if this is actually a removal and not just a // notification which becomes a child notification @@ -1651,8 +1652,7 @@ public class NotificationStackScrollLayout extends ViewGroup * @return Whether an animation was generated. */ private boolean generateRemoveAnimation(View child) { - if (mAddedHeadsUpChildren.contains(child)) { - removeChildFromHeadsUpChangeAnimations(child); + if (removeRemovedChildFromHeadsUpChangeAnimations(child)) { mAddedHeadsUpChildren.remove(child); return false; } @@ -1671,15 +1671,27 @@ public class NotificationStackScrollLayout extends ViewGroup return false; } - private void removeChildFromHeadsUpChangeAnimations(View child) { - ArrayList<Pair<ExpandableNotificationRow, Boolean> > toRemove = new ArrayList<>(); + /** + * Remove a removed child view from the heads up animations if it was just added there + * + * @return whether any child was removed from the list to animate + */ + private boolean removeRemovedChildFromHeadsUpChangeAnimations(View child) { + boolean hasAddEvent = false; for (Pair<ExpandableNotificationRow, Boolean> eventPair : mHeadsUpChangeAnimations) { ExpandableNotificationRow row = eventPair.first; + boolean isHeadsUp = eventPair.second; if (child == row) { - toRemove.add(eventPair); + mTmpList.add(eventPair); + hasAddEvent |= isHeadsUp; } } - mHeadsUpChangeAnimations.removeAll(toRemove); + if (hasAddEvent) { + // This child was just added lets remove all events. + mHeadsUpChangeAnimations.removeAll(mTmpList); + } + mTmpList.clear(); + return hasAddEvent; } /** @@ -1745,7 +1757,7 @@ public class NotificationStackScrollLayout extends ViewGroup } @Override - protected void onViewAdded(View child) { + public void onViewAdded(View child) { super.onViewAdded(child); onViewAddedInternal(child); } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java index d9f0598..ca6aaeb 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java @@ -131,11 +131,14 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference intent.putExtra("mobile", "show"); intent.putExtra("sims", "1"); intent.putExtra("nosim", "false"); - intent.putExtra("fully", "true"); intent.putExtra("level", "4"); intent.putExtra("datatypel", ""); getContext().sendBroadcast(intent); + // Need to send this after so that the sim controller already exists. + intent.putExtra("fully", "true"); + getContext().sendBroadcast(intent); + intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_BATTERY); intent.putExtra("level", "100"); intent.putExtra("plugged", "false"); diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java index 12dca94..893c939 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/Events.java +++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java @@ -16,11 +16,13 @@ package com.android.systemui.volume; +import android.content.Context; import android.media.AudioManager; import android.media.AudioSystem; import android.provider.Settings.Global; import android.util.Log; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.volume.VolumeDialogController.State; import java.util.Arrays; @@ -47,6 +49,7 @@ public class Events { public static final int EVENT_ZEN_MODE_CHANGED = 13; // (mode|int) public static final int EVENT_SUPPRESSOR_CHANGED = 14; // (component|string) (name|string) public static final int EVENT_MUTE_CHANGED = 15; // (stream|int) (muted|bool) + public static final int EVENT_TOUCH_LEVEL_DONE = 16; // (stream|int) (level|bool) private static final String[] EVENT_TAGS = { "show_dialog", @@ -65,6 +68,7 @@ public class Events { "zen_mode_changed", "suppressor_changed", "mute_changed", + "touch_level_done", }; public static final int DISMISS_REASON_UNKNOWN = 0; @@ -100,36 +104,59 @@ public class Events { public static Callback sCallback; - public static void writeEvent(int tag, Object... list) { + public static void writeEvent(Context context, int tag, Object... list) { final long time = System.currentTimeMillis(); final StringBuilder sb = new StringBuilder("writeEvent ").append(EVENT_TAGS[tag]); if (list != null && list.length > 0) { sb.append(" "); switch (tag) { case EVENT_SHOW_DIALOG: + MetricsLogger.visible(context, MetricsLogger.VOLUME_DIALOG); + MetricsLogger.histogram(context, "volume_from_keyguard", + (Boolean) list[1] ? 1 : 0); sb.append(SHOW_REASONS[(Integer) list[0]]).append(" keyguard=").append(list[1]); break; case EVENT_EXPAND: + MetricsLogger.visibility(context, MetricsLogger.VOLUME_DIALOG_DETAILS, + (Boolean) list[0]); sb.append(list[0]); break; case EVENT_DISMISS_DIALOG: + MetricsLogger.hidden(context, MetricsLogger.VOLUME_DIALOG); sb.append(DISMISS_REASONS[(Integer) list[0]]); break; case EVENT_ACTIVE_STREAM_CHANGED: + MetricsLogger.action(context, MetricsLogger.ACTION_VOLUME_STREAM, + (Integer) list[0]); sb.append(AudioSystem.streamToString((Integer) list[0])); break; case EVENT_ICON_CLICK: + MetricsLogger.action(context, MetricsLogger.ACTION_VOLUME_ICON, + (Integer) list[1]); sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ') .append(iconStateToString((Integer) list[1])); break; + case EVENT_TOUCH_LEVEL_DONE: + MetricsLogger.action(context, MetricsLogger.ACTION_VOLUME_SLIDER, + (Integer) list[1]); + // fall through case EVENT_TOUCH_LEVEL_CHANGED: case EVENT_LEVEL_CHANGED: case EVENT_MUTE_CHANGED: sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ') .append(list[1]); break; - case EVENT_INTERNAL_RINGER_MODE_CHANGED: + case EVENT_KEY: + MetricsLogger.action(context, MetricsLogger.ACTION_VOLUME_KEY, + (Integer) list[1]); + sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ') + .append(list[1]); + break; case EVENT_EXTERNAL_RINGER_MODE_CHANGED: + MetricsLogger.action(context, MetricsLogger.ACTION_RINGER_MODE, + (Integer) list[0]); + // fall through + case EVENT_INTERNAL_RINGER_MODE_CHANGED: sb.append(ringerModeToString((Integer) list[0])); break; case EVENT_ZEN_MODE_CHANGED: diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java index aa891b6..5b2eb84 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java @@ -369,7 +369,7 @@ public class VolumeDialog { row.icon.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - Events.writeEvent(Events.EVENT_ICON_CLICK, row.stream, row.iconState); + Events.writeEvent(mContext, Events.EVENT_ICON_CLICK, row.stream, row.iconState); mController.setActiveStream(row.stream); if (row.stream == AudioManager.STREAM_RING) { final boolean hasVibrator = mController.hasVibrator(); @@ -417,7 +417,7 @@ public class VolumeDialog { if (mShowing) return; mShowing = true; mDialog.show(); - Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked()); + Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked()); mController.notifyVisible(true); } @@ -444,7 +444,7 @@ public class VolumeDialog { if (!mShowing) return; mShowing = false; mDialog.dismiss(); - Events.writeEvent(Events.EVENT_DISMISS_DIALOG, reason); + Events.writeEvent(mContext, Events.EVENT_DISMISS_DIALOG, reason); setExpandedH(false); mController.notifyVisible(false); synchronized (mSafetyWarningLock) { @@ -834,7 +834,7 @@ public class VolumeDialog { public void onClick(View v) { if (mExpanding) return; final boolean newExpand = !mExpanded; - Events.writeEvent(Events.EVENT_EXPAND, v); + Events.writeEvent(mContext, Events.EVENT_EXPAND, newExpand); setExpandedH(newExpand); } }; @@ -845,7 +845,7 @@ public class VolumeDialog { mSettingsButton.postDelayed(new Runnable() { @Override public void run() { - Events.writeEvent(Events.EVENT_SETTINGS_CLICK); + Events.writeEvent(mContext, Events.EVENT_SETTINGS_CLICK); if (mCallback != null) { mCallback.onSettingsClicked(); } @@ -933,7 +933,8 @@ public class VolumeDialog { if (mRow.requestedLevel != userLevel) { mController.setStreamVolume(mRow.stream, userLevel); mRow.requestedLevel = userLevel; - Events.writeEvent(Events.EVENT_TOUCH_LEVEL_CHANGED, mRow.stream, userLevel); + Events.writeEvent(mContext, Events.EVENT_TOUCH_LEVEL_CHANGED, mRow.stream, + userLevel); } } } @@ -951,6 +952,7 @@ public class VolumeDialog { mRow.tracking = false; mRow.userAttempt = SystemClock.uptimeMillis(); int userLevel = getImpliedLevel(seekBar, seekBar.getProgress()); + Events.writeEvent(mContext, Events.EVENT_TOUCH_LEVEL_DONE, mRow.stream, userLevel); if (mRow.ss.level != userLevel) { mHandler.sendMessageDelayed(mHandler.obtainMessage(H.RECHECK, mRow), USER_ATTEMPT_GRACE_PERIOD); diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java index c6d9e46..9a59a2a 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java @@ -104,7 +104,7 @@ public class VolumeDialogController { public VolumeDialogController(Context context, ComponentName component) { mContext = context.getApplicationContext(); - Events.writeEvent(Events.EVENT_COLLECTION_STARTED); + Events.writeEvent(mContext, Events.EVENT_COLLECTION_STARTED); mComponent = component; mWorkerThread = new HandlerThread(VolumeDialogController.class.getSimpleName()); mWorkerThread.start(); @@ -168,7 +168,7 @@ public class VolumeDialogController { if (D.BUG) Log.d(TAG, "destroy"); if (mDestroyed) return; mDestroyed = true; - Events.writeEvent(Events.EVENT_COLLECTION_STOPPED); + Events.writeEvent(mContext, Events.EVENT_COLLECTION_STOPPED); mMediaSessions.destroy(); mObserver.destroy(); mReceiver.destroy(); @@ -293,7 +293,8 @@ public class VolumeDialogController { if (showUI) { changed |= updateActiveStreamW(stream); } - changed |= updateStreamLevelW(stream, mAudio.getLastAudibleStreamVolume(stream)); + int lastAudibleStreamVolume = mAudio.getLastAudibleStreamVolume(stream); + changed |= updateStreamLevelW(stream, lastAudibleStreamVolume); changed |= checkRoutedToBluetoothW(showUI ? AudioManager.STREAM_MUSIC : stream); if (changed) { mCallbacks.onStateChanged(mState); @@ -308,14 +309,14 @@ public class VolumeDialogController { mCallbacks.onShowSilentHint(); } if (changed && fromKey) { - Events.writeEvent(Events.EVENT_KEY); + Events.writeEvent(mContext, Events.EVENT_KEY, stream, lastAudibleStreamVolume); } } private boolean updateActiveStreamW(int activeStream) { if (activeStream == mState.activeStream) return false; mState.activeStream = activeStream; - Events.writeEvent(Events.EVENT_ACTIVE_STREAM_CHANGED, activeStream); + Events.writeEvent(mContext, Events.EVENT_ACTIVE_STREAM_CHANGED, activeStream); if (D.BUG) Log.d(TAG, "updateActiveStreamW " + activeStream); final int s = activeStream < DYNAMIC_STREAM_START_INDEX ? activeStream : -1; if (D.BUG) Log.d(TAG, "forceVolumeControlStream " + s); @@ -364,7 +365,7 @@ public class VolumeDialogController { if (ss.level == level) return false; ss.level = level; if (isLogWorthy(stream)) { - Events.writeEvent(Events.EVENT_LEVEL_CHANGED, stream, level); + Events.writeEvent(mContext, Events.EVENT_LEVEL_CHANGED, stream, level); } return true; } @@ -387,7 +388,7 @@ public class VolumeDialogController { if (ss.muted == muted) return false; ss.muted = muted; if (isLogWorthy(stream)) { - Events.writeEvent(Events.EVENT_MUTE_CHANGED, stream, muted); + Events.writeEvent(mContext, Events.EVENT_MUTE_CHANGED, stream, muted); } if (muted && isRinger(stream)) { updateRingerModeInternalW(mAudio.getRingerModeInternal()); @@ -410,7 +411,7 @@ public class VolumeDialogController { if (Objects.equals(mState.effectsSuppressor, effectsSuppressor)) return false; mState.effectsSuppressor = effectsSuppressor; mState.effectsSuppressorName = getApplicationName(mContext, mState.effectsSuppressor); - Events.writeEvent(Events.EVENT_SUPPRESSOR_CHANGED, mState.effectsSuppressor, + Events.writeEvent(mContext, Events.EVENT_SUPPRESSOR_CHANGED, mState.effectsSuppressor, mState.effectsSuppressorName); return true; } @@ -434,21 +435,21 @@ public class VolumeDialogController { Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF); if (mState.zenMode == zen) return false; mState.zenMode = zen; - Events.writeEvent(Events.EVENT_ZEN_MODE_CHANGED, zen); + Events.writeEvent(mContext, Events.EVENT_ZEN_MODE_CHANGED, zen); return true; } private boolean updateRingerModeExternalW(int rm) { if (rm == mState.ringerModeExternal) return false; mState.ringerModeExternal = rm; - Events.writeEvent(Events.EVENT_EXTERNAL_RINGER_MODE_CHANGED, rm); + Events.writeEvent(mContext, Events.EVENT_EXTERNAL_RINGER_MODE_CHANGED, rm); return true; } private boolean updateRingerModeInternalW(int rm) { if (rm == mState.ringerModeInternal) return false; mState.ringerModeInternal = rm; - Events.writeEvent(Events.EVENT_INTERNAL_RINGER_MODE_CHANGED, rm); + Events.writeEvent(mContext, Events.EVENT_INTERNAL_RINGER_MODE_CHANGED, rm); return true; } diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 17d7078..30680ed 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -37,6 +37,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; @@ -1281,7 +1282,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } @Override - public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter, + public ParceledListSlice<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter, int profileId) { final int userId = UserHandle.getCallingUserId(); @@ -1297,7 +1298,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku synchronized (mLock) { ensureGroupStateLoadedLocked(userId); - ArrayList<AppWidgetProviderInfo> result = null; + ArrayList<AppWidgetProviderInfo> result = new ArrayList<AppWidgetProviderInfo>(); final int providerCount = mProviders.size(); for (int i = 0; i < providerCount; i++) { @@ -1314,14 +1315,11 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku if (providerProfileId == profileId && mSecurityPolicy.isProviderInCallerOrInProfileAndWhitelListed( provider.id.componentName.getPackageName(), providerProfileId)) { - if (result == null) { - result = new ArrayList<>(); - } result.add(cloneIfLocalBinder(info)); } } - return result; + return new ParceledListSlice<AppWidgetProviderInfo>(result); } } diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 26ece72..839b87a 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -20,13 +20,16 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.AlarmManager; +import android.app.BroadcastOptions; import android.app.IAlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; import android.os.Bundle; @@ -43,6 +46,7 @@ import android.provider.Settings; import android.text.TextUtils; import android.text.format.DateFormat; import android.util.ArrayMap; +import android.util.KeyValueListParser; import android.util.Log; import android.util.Slog; import android.util.SparseArray; @@ -75,22 +79,6 @@ import static android.app.AlarmManager.ELAPSED_REALTIME; import com.android.internal.util.LocalLog; class AlarmManagerService extends SystemService { - // The threshold for how long an alarm can be late before we print a - // warning message. The time duration is in milliseconds. - private static final long LATE_ALARM_THRESHOLD = 10 * 1000; - - // Minimum futurity of a new alarm - private static final long MIN_FUTURITY = 5 * 1000; // 5 seconds, in millis - - // Minimum alarm recurrence interval - private static final long MIN_INTERVAL = 60 * 1000; // one minute, in millis - - // Minimum time between ALLOW_WHILE_IDLE alarms when system is not idle. - private static final long ALLOW_WHILE_IDLE_SHORT_TIME = 60*1000; - - // Minimum time between ALLOW_WHILE_IDLE alarms when system is idling. - private static final long ALLOW_WHILE_IDLE_LONG_TIME = 15*60*1000; - private static final int RTC_WAKEUP_MASK = 1 << RTC_WAKEUP; private static final int RTC_MASK = 1 << RTC; private static final int ELAPSED_REALTIME_WAKEUP_MASK = 1 << ELAPSED_REALTIME_WAKEUP; @@ -102,7 +90,6 @@ class AlarmManagerService extends SystemService { static final int TYPE_NONWAKEUP_MASK = 0x1; // low bit => non-wakeup static final String TAG = "AlarmManager"; - static final String ClockReceiver_TAG = "ClockReceiver"; static final boolean localLOGV = false; static final boolean DEBUG_BATCH = localLOGV || false; static final boolean DEBUG_VALIDATE = localLOGV || false; @@ -148,7 +135,7 @@ class AlarmManagerService extends SystemService { long mNextNonWakeupDeliveryTime; long mLastTimeChangeClockTime; long mLastTimeChangeRealtime; - long mAllowWhileIdleMinTime = ALLOW_WHILE_IDLE_SHORT_TIME; + long mAllowWhileIdleMinTime; int mNumTimeChanged; /** @@ -157,6 +144,11 @@ class AlarmManagerService extends SystemService { */ final SparseLongArray mLastAllowWhileIdleDispatch = new SparseLongArray(); + /** + * Broadcast options to use for FLAG_ALLOW_WHILE_IDLE. + */ + Bundle mIdleOptions; + private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser = new SparseArray<>(); private final SparseArray<AlarmManager.AlarmClockInfo> mTmpSparseAlarmClockArray = @@ -169,12 +161,137 @@ class AlarmManagerService extends SystemService { private final SparseArray<AlarmManager.AlarmClockInfo> mHandlerSparseAlarmClockArray = new SparseArray<>(); + /** + * All times are in milliseconds. These constants are kept synchronized with the system + * global Settings. Any access to this class or its fields should be done while + * holding the AlarmManagerService.mLock lock. + */ + private final class Constants extends ContentObserver { + // Key names stored in the settings value. + private static final String KEY_MIN_FUTURITY = "min_futurity"; + private static final String KEY_MIN_INTERVAL = "min_interval"; + private static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time"; + private static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time"; + private static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION + = "allow_while_idle_whitelist_duration"; + + private static final long DEFAULT_MIN_FUTURITY = 5 * 1000; + private static final long DEFAULT_MIN_INTERVAL = 60 * 1000; + private static final long DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME = 60*1000; + private static final long DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME = 15*60*1000; + private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10*1000; + + // Minimum futurity of a new alarm + public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY; + + // Minimum alarm recurrence interval + public long MIN_INTERVAL = DEFAULT_MIN_INTERVAL; + + // Minimum time between ALLOW_WHILE_IDLE alarms when system is not idle. + public long ALLOW_WHILE_IDLE_SHORT_TIME = DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME; + + // Minimum time between ALLOW_WHILE_IDLE alarms when system is idling. + public long ALLOW_WHILE_IDLE_LONG_TIME = DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME; + + // BroadcastOptions.setTemporaryAppWhitelistDuration() to use for FLAG_ALLOW_WHILE_IDLE. + public long ALLOW_WHILE_IDLE_WHITELIST_DURATION + = DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION; + + private ContentResolver mResolver; + private final KeyValueListParser mParser = new KeyValueListParser(','); + private long mLastAllowWhileIdleWhitelistDuration = -1; + + public Constants(Handler handler) { + super(handler); + updateAllowWhileIdleMinTimeLocked(); + updateAllowWhileIdleWhitelistDurationLocked(); + } + + public void start(ContentResolver resolver) { + mResolver = resolver; + mResolver.registerContentObserver(Settings.Global.getUriFor( + Settings.Global.ALARM_MANAGER_CONSTANTS), false, this); + updateConstants(); + } + + public void updateAllowWhileIdleMinTimeLocked() { + mAllowWhileIdleMinTime = mPendingIdleUntil != null + ? ALLOW_WHILE_IDLE_LONG_TIME : ALLOW_WHILE_IDLE_SHORT_TIME; + } + + public void updateAllowWhileIdleWhitelistDurationLocked() { + if (mLastAllowWhileIdleWhitelistDuration != ALLOW_WHILE_IDLE_WHITELIST_DURATION) { + mLastAllowWhileIdleWhitelistDuration = ALLOW_WHILE_IDLE_WHITELIST_DURATION; + BroadcastOptions opts = BroadcastOptions.makeBasic(); + opts.setTemporaryAppWhitelistDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION); + mIdleOptions = opts.toBundle(); + } + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + updateConstants(); + } + + private void updateConstants() { + synchronized (mLock) { + try { + mParser.setString(Settings.Global.getString(mResolver, + Settings.Global.ALARM_MANAGER_CONSTANTS)); + } catch (IllegalArgumentException e) { + // Failed to parse the settings string, log this and move on + // with defaults. + Slog.e(TAG, "Bad device idle settings", e); + } + + MIN_FUTURITY = mParser.getLong(KEY_MIN_FUTURITY, DEFAULT_MIN_FUTURITY); + MIN_INTERVAL = mParser.getLong(KEY_MIN_INTERVAL, DEFAULT_MIN_INTERVAL); + ALLOW_WHILE_IDLE_SHORT_TIME = mParser.getLong(KEY_ALLOW_WHILE_IDLE_SHORT_TIME, + DEFAULT_ALLOW_WHILE_IDLE_SHORT_TIME); + ALLOW_WHILE_IDLE_LONG_TIME = mParser.getLong(KEY_ALLOW_WHILE_IDLE_LONG_TIME, + DEFAULT_ALLOW_WHILE_IDLE_LONG_TIME); + ALLOW_WHILE_IDLE_WHITELIST_DURATION = mParser.getLong( + KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION, + DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION); + + updateAllowWhileIdleMinTimeLocked(); + updateAllowWhileIdleWhitelistDurationLocked(); + } + } + + void dump(PrintWriter pw) { + pw.println(" Settings:"); + + pw.print(" "); pw.print(KEY_MIN_FUTURITY); pw.print("="); + TimeUtils.formatDuration(MIN_FUTURITY, pw); + pw.println(); + + pw.print(" "); pw.print(KEY_MIN_INTERVAL); pw.print("="); + TimeUtils.formatDuration(MIN_INTERVAL, pw); + pw.println(); + + pw.print(" "); pw.print(KEY_ALLOW_WHILE_IDLE_SHORT_TIME); pw.print("="); + TimeUtils.formatDuration(ALLOW_WHILE_IDLE_SHORT_TIME, pw); + pw.println(); + + pw.print(" "); pw.print(KEY_ALLOW_WHILE_IDLE_LONG_TIME); pw.print("="); + TimeUtils.formatDuration(ALLOW_WHILE_IDLE_LONG_TIME, pw); + pw.println(); + + pw.print(" "); pw.print(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION); pw.print("="); + TimeUtils.formatDuration(ALLOW_WHILE_IDLE_WHITELIST_DURATION, pw); + pw.println(); + } + } + + final Constants mConstants; + // Alarm delivery ordering bookkeeping static final int PRIO_TICK = 0; static final int PRIO_WAKEUP = 1; static final int PRIO_NORMAL = 2; - class PriorityClass { + final class PriorityClass { int seq; int priority; @@ -184,11 +301,10 @@ class AlarmManagerService extends SystemService { } } - final HashMap<String, PriorityClass> mPriorities = - new HashMap<String, PriorityClass>(); + final HashMap<String, PriorityClass> mPriorities = new HashMap<>(); int mCurrentSeq = 0; - class WakeupEvent { + static final class WakeupEvent { public long when; public int uid; public String action; @@ -482,6 +598,7 @@ class AlarmManagerService extends SystemService { public AlarmManagerService(Context context) { super(context); + mConstants = new Constants(mHandler); } static long convertToElapsed(long when, int type) { @@ -595,7 +712,7 @@ class AlarmManagerService extends SystemService { } // Make sure we are using the correct ALLOW_WHILE_IDLE min time. - mAllowWhileIdleMinTime = ALLOW_WHILE_IDLE_SHORT_TIME; + mConstants.updateAllowWhileIdleMinTimeLocked(); // Reschedule everything. rescheduleKernelAlarmsLocked(); @@ -714,6 +831,13 @@ class AlarmManagerService extends SystemService { } @Override + public void onBootPhase(int phase) { + if (phase == PHASE_SYSTEM_SERVICES_READY) { + mConstants.start(getContext().getContentResolver()); + } + } + + @Override protected void finalize() throws Throwable { try { close(mNativeData); @@ -784,11 +908,12 @@ class AlarmManagerService extends SystemService { // Sanity check the recurrence interval. This will catch people who supply // seconds when the API expects milliseconds. - if (interval > 0 && interval < MIN_INTERVAL) { + final long minInterval = mConstants.MIN_INTERVAL; + if (interval > 0 && interval < minInterval) { Slog.w(TAG, "Suspiciously short interval " + interval - + " millis; expanding to " + (int)(MIN_INTERVAL/1000) + + " millis; expanding to " + (minInterval/1000) + " seconds"); - interval = MIN_INTERVAL; + interval = minInterval; } if (type < RTC_WAKEUP || type > ELAPSED_REALTIME) { @@ -805,7 +930,7 @@ class AlarmManagerService extends SystemService { final long nowElapsed = SystemClock.elapsedRealtime(); final long nominalTrigger = convertToElapsed(triggerAtTime, type); // Try to prevent spamming by making sure we aren't firing alarms in the immediate future - final long minTrigger = nowElapsed + MIN_FUTURITY; + final long minTrigger = nowElapsed + mConstants.MIN_FUTURITY; final long triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger; final long maxElapsed; @@ -904,7 +1029,7 @@ class AlarmManagerService extends SystemService { if ((a.flags&AlarmManager.FLAG_IDLE_UNTIL) != 0) { mPendingIdleUntil = a; - mAllowWhileIdleMinTime = ALLOW_WHILE_IDLE_LONG_TIME; + mConstants.updateAllowWhileIdleMinTimeLocked(); needRebatch = true; } else if ((a.flags&AlarmManager.FLAG_WAKE_FROM_IDLE) != 0) { if (mNextWakeFromIdle == null || mNextWakeFromIdle.whenElapsed > a.whenElapsed) { @@ -1054,45 +1179,48 @@ class AlarmManagerService extends SystemService { void dumpImpl(PrintWriter pw) { synchronized (mLock) { pw.println("Current Alarm Manager state:"); + mConstants.dump(pw); + pw.println(); + final long nowRTC = System.currentTimeMillis(); final long nowELAPSED = SystemClock.elapsedRealtime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - pw.print("nowRTC="); pw.print(nowRTC); + pw.print(" nowRTC="); pw.print(nowRTC); pw.print("="); pw.print(sdf.format(new Date(nowRTC))); pw.print(" nowELAPSED="); TimeUtils.formatDuration(nowELAPSED, pw); pw.println(); - pw.print("mLastTimeChangeClockTime="); pw.print(mLastTimeChangeClockTime); + pw.print(" mLastTimeChangeClockTime="); pw.print(mLastTimeChangeClockTime); pw.print("="); pw.println(sdf.format(new Date(mLastTimeChangeClockTime))); - pw.print("mLastTimeChangeRealtime="); + pw.print(" mLastTimeChangeRealtime="); TimeUtils.formatDuration(mLastTimeChangeRealtime, pw); pw.println(); if (!mInteractive) { - pw.print("Time since non-interactive: "); + pw.print(" Time since non-interactive: "); TimeUtils.formatDuration(nowELAPSED - mNonInteractiveStartTime, pw); pw.println(); - pw.print("Max wakeup delay: "); + pw.print(" Max wakeup delay: "); TimeUtils.formatDuration(currentNonWakeupFuzzLocked(nowELAPSED), pw); pw.println(); - pw.print("Time since last dispatch: "); + pw.print(" Time since last dispatch: "); TimeUtils.formatDuration(nowELAPSED - mLastAlarmDeliveryTime, pw); pw.println(); - pw.print("Next non-wakeup delivery time: "); + pw.print(" Next non-wakeup delivery time: "); TimeUtils.formatDuration(nowELAPSED - mNextNonWakeupDeliveryTime, pw); pw.println(); } long nextWakeupRTC = mNextWakeup + (nowRTC - nowELAPSED); long nextNonWakeupRTC = mNextNonWakeup + (nowRTC - nowELAPSED); - pw.print("Next non-wakeup alarm: "); + pw.print(" Next non-wakeup alarm: "); TimeUtils.formatDuration(mNextNonWakeup, nowELAPSED, pw); pw.print(" = "); pw.println(sdf.format(new Date(nextNonWakeupRTC))); - pw.print("Next wakeup: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw); + pw.print(" Next wakeup: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw); pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC))); - pw.print("Num time change events: "); pw.println(mNumTimeChanged); + pw.print(" Num time change events: "); pw.println(mNumTimeChanged); pw.println(); - pw.println("Next alarm clock information: "); + pw.println(" Next alarm clock information: "); final TreeSet<Integer> users = new TreeSet<>(); for (int i = 0; i < mNextAlarmClockForUser.size(); i++) { users.add(mNextAlarmClockForUser.keyAt(i)); @@ -1104,7 +1232,7 @@ class AlarmManagerService extends SystemService { final AlarmManager.AlarmClockInfo next = mNextAlarmClockForUser.get(user); final long time = next != null ? next.getTriggerTime() : 0; final boolean pendingSend = mPendingSendNextAlarmClockChangedForUser.get(user); - pw.print(" user:"); pw.print(user); + pw.print(" user:"); pw.print(user); pw.print(" pendingSend:"); pw.print(pendingSend); pw.print(" time:"); pw.print(time); if (time > 0) { @@ -1115,25 +1243,25 @@ class AlarmManagerService extends SystemService { } if (mAlarmBatches.size() > 0) { pw.println(); - pw.print("Pending alarm batches: "); + pw.print(" Pending alarm batches: "); pw.println(mAlarmBatches.size()); for (Batch b : mAlarmBatches) { pw.print(b); pw.println(':'); - dumpAlarmList(pw, b.alarms, " ", nowELAPSED, nowRTC, sdf); + dumpAlarmList(pw, b.alarms, " ", nowELAPSED, nowRTC, sdf); } } if (mPendingIdleUntil != null || mPendingWhileIdleAlarms.size() > 0) { pw.println(); - pw.println("Idle mode state:"); - pw.print(" Idling until: "); + pw.println(" Idle mode state:"); + pw.print(" Idling until: "); if (mPendingIdleUntil != null) { pw.println(mPendingIdleUntil); mPendingIdleUntil.dump(pw, " ", nowRTC, nowELAPSED, sdf); } else { pw.println("null"); } - pw.println(" Pending alarms:"); - dumpAlarmList(pw, mPendingWhileIdleAlarms, " ", nowELAPSED, nowRTC, sdf); + pw.println(" Pending alarms:"); + dumpAlarmList(pw, mPendingWhileIdleAlarms, " ", nowELAPSED, nowRTC, sdf); } if (mNextWakeFromIdle != null) { pw.println(); @@ -1142,17 +1270,17 @@ class AlarmManagerService extends SystemService { } pw.println(); - pw.print("Past-due non-wakeup alarms: "); + pw.print(" Past-due non-wakeup alarms: "); if (mPendingNonWakeupAlarms.size() > 0) { pw.println(mPendingNonWakeupAlarms.size()); - dumpAlarmList(pw, mPendingNonWakeupAlarms, " ", nowELAPSED, nowRTC, sdf); + dumpAlarmList(pw, mPendingNonWakeupAlarms, " ", nowELAPSED, nowRTC, sdf); } else { pw.println("(none)"); } - pw.print(" Number of delayed alarms: "); pw.print(mNumDelayedAlarms); + pw.print(" Number of delayed alarms: "); pw.print(mNumDelayedAlarms); pw.print(", total delay time: "); TimeUtils.formatDuration(mTotalDelayTime, pw); pw.println(); - pw.print(" Max delay time: "); TimeUtils.formatDuration(mMaxDelayTime, pw); + pw.print(" Max delay time: "); TimeUtils.formatDuration(mMaxDelayTime, pw); pw.print(", max non-interactive time: "); TimeUtils.formatDuration(mNonInteractiveTime, pw); pw.println(); @@ -1161,11 +1289,11 @@ class AlarmManagerService extends SystemService { pw.print(" Broadcast ref count: "); pw.println(mBroadcastRefCount); pw.println(); - pw.print("mAllowWhileIdleMinTime="); + pw.print(" mAllowWhileIdleMinTime="); TimeUtils.formatDuration(mAllowWhileIdleMinTime, pw); pw.println(); if (mLastAllowWhileIdleDispatch.size() > 0) { - pw.println("Last allow while idle dispatch times:"); + pw.println(" Last allow while idle dispatch times:"); for (int i=0; i<mLastAllowWhileIdleDispatch.size(); i++) { pw.print(" UID "); UserHandle.formatUid(pw, mLastAllowWhileIdleDispatch.keyAt(i)); @@ -1969,6 +2097,7 @@ class AlarmManagerService extends SystemService { mLastAlarmDeliveryTime = nowELAPSED; for (int i=0; i<triggerList.size(); i++) { Alarm alarm = triggerList.get(i); + final boolean allowWhileIdle = (alarm.flags&AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0; try { if (localLOGV) { Slog.v(TAG, "sending alarm " + alarm); @@ -1987,7 +2116,7 @@ class AlarmManagerService extends SystemService { alarm.operation.send(getContext(), 0, mBackgroundIntent.putExtra( Intent.EXTRA_ALARM_COUNT, alarm.count), - mResultReceiver, mHandler); + mResultReceiver, mHandler, null, allowWhileIdle ? mIdleOptions : null); // we have an active broadcast so stay awake. if (mBroadcastRefCount == 0) { @@ -2000,7 +2129,7 @@ class AlarmManagerService extends SystemService { mInFlight.add(inflight); mBroadcastRefCount++; - if ((alarm.flags&AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) { + if (allowWhileIdle) { // Record the last time this uid handled an ALLOW_WHILE_IDLE alarm. mLastAllowWhileIdleDispatch.put(alarm.uid, nowELAPSED); } diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index fbb6dc9..f9f6714 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -237,6 +237,12 @@ class BluetoothManagerService extends IBluetoothManager.Stub { sendEnableMsg(mQuietEnableExternal); } } + + if (!isNameAndAddressSet()) { + // Sync the Bluetooth name and address from the Bluetooth Adapter + if (DBG) Log.d(TAG,"Retrieving Bluetooth Adapter name and address..."); + getNameAndAddress(); + } } } }; diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 82399da..98f0b45 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -136,11 +136,13 @@ import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -3920,10 +3922,52 @@ public class ConnectivityService extends IConnectivityManager.Stub } return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty(); } + + // TODO: investigate moving this into LinkProperties, if only to make more accurate + // the isProvisioned() checks. + private static Collection<InetAddress> getLikelyReachableDnsServers(LinkProperties lp) { + final ArrayList<InetAddress> dnsServers = new ArrayList<InetAddress>(); + final List<RouteInfo> allRoutes = lp.getAllRoutes(); + for (InetAddress nameserver : lp.getDnsServers()) { + // If the LinkProperties doesn't include a route to the nameserver, ignore it. + final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, nameserver); + if (bestRoute == null) { + continue; + } + + // TODO: better source address evaluation for destination addresses. + if (nameserver instanceof Inet4Address) { + if (!lp.hasIPv4Address()) { + continue; + } + } else if (nameserver instanceof Inet6Address) { + if (nameserver.isLinkLocalAddress()) { + if (((Inet6Address)nameserver).getScopeId() == 0) { + // For now, just make sure link-local DNS servers have + // scopedIds set, since DNS lookups will fail otherwise. + // TODO: verify the scopeId matches that of lp's interface. + continue; + } + } else { + if (bestRoute.isIPv6Default() && !lp.hasGlobalIPv6Address()) { + // TODO: reconsider all corner cases (disconnected ULA networks, ...). + continue; + } + } + } + + dnsServers.add(nameserver); + } + return Collections.unmodifiableList(dnsServers); + } + private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId, boolean flush, boolean useDefaultDns) { + // TODO: consider comparing the getLikelyReachableDnsServers() lists, in case the + // route to a DNS server has been removed (only really applicable in special cases + // where there is no default route). if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) { - Collection<InetAddress> dnses = newLp.getDnsServers(); + Collection<InetAddress> dnses = getLikelyReachableDnsServers(newLp); if (dnses.size() == 0 && mDefaultDns != null && useDefaultDns) { dnses = new ArrayList(); dnses.add(mDefaultDns); diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index 6eba3f6..8dd087a 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -19,7 +19,6 @@ package com.android.server; import android.Manifest; import android.app.ActivityManagerNative; import android.app.AlarmManager; -import android.app.AppGlobals; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -27,7 +26,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.database.ContentObserver; @@ -101,10 +99,6 @@ public class DeviceIdleController extends SystemService private static final String ACTION_ENTER_INACTIVE_STATE = "com.android.server.device_idle.ENTER_INACTIVE_STATE"; - // TODO: These need to be moved to system settings. - - - private AlarmManager mAlarmManager; private IBatteryStats mBatteryStats; private PowerManagerInternal mLocalPowerManager; @@ -180,7 +174,7 @@ public class DeviceIdleController extends SystemService * List of end times for UIDs that are temporarily marked as being allowed to access * the network and acquire wakelocks. Times are in milliseconds. */ - private SparseLongArray mTempWhitelistAppIdEndTimes = new SparseLongArray(); + private final SparseLongArray mTempWhitelistAppIdEndTimes = new SparseLongArray(); /** * Current app IDs of temporarily whitelist apps for high-priority messages. @@ -234,7 +228,7 @@ public class DeviceIdleController extends SystemService * global Settings. Any access to this class or its fields should be done while * holding the DeviceIdleController lock. */ - private class Constants extends ContentObserver { + private final class Constants extends ContentObserver { // Key names stored in the settings value. private static final String KEY_INACTIVE_TIMEOUT = "inactive_to"; private static final String KEY_SENSING_TIMEOUT = "sensing_to"; @@ -403,49 +397,49 @@ public class DeviceIdleController extends SystemService void dump(PrintWriter pw) { pw.println(" Settings:"); - pw.print(" DOZE_INACTIVE_TIMEOUT="); + pw.print(" "); pw.print(KEY_INACTIVE_TIMEOUT); pw.print("="); TimeUtils.formatDuration(INACTIVE_TIMEOUT, pw); pw.println(); - pw.print(" DOZE_SENSING_TIMEOUT="); + pw.print(" "); pw.print(KEY_SENSING_TIMEOUT); pw.print("="); TimeUtils.formatDuration(SENSING_TIMEOUT, pw); pw.println(); - pw.print(" DOZE_MOTION_INACTIVE_TIMEOUT="); + pw.print(" "); pw.print(KEY_MOTION_INACTIVE_TIMEOUT); pw.print("="); TimeUtils.formatDuration(MOTION_INACTIVE_TIMEOUT, pw); pw.println(); - pw.print(" DOZE_IDLE_AFTER_INACTIVE_TIMEOUT="); + pw.print(" "); pw.print(KEY_IDLE_AFTER_INACTIVE_TIMEOUT); pw.print("="); TimeUtils.formatDuration(IDLE_AFTER_INACTIVE_TIMEOUT, pw); pw.println(); - pw.print(" DOZE_IDLE_PENDING_TIMEOUT="); + pw.print(" "); pw.print(KEY_IDLE_PENDING_TIMEOUT); pw.print("="); TimeUtils.formatDuration(IDLE_PENDING_TIMEOUT, pw); pw.println(); - pw.print(" DOZE_MAX_IDLE_PENDING_TIMEOUT="); + pw.print(" "); pw.print(KEY_MAX_IDLE_PENDING_TIMEOUT); pw.print("="); TimeUtils.formatDuration(MAX_IDLE_PENDING_TIMEOUT, pw); pw.println(); - pw.print(" DOZE_IDLE_PENDING_FACTOR="); + pw.print(" "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("="); pw.println(IDLE_PENDING_FACTOR); - pw.print(" DOZE_IDLE_TIMEOUT="); + pw.print(" "); pw.print(KEY_IDLE_TIMEOUT); pw.print("="); TimeUtils.formatDuration(IDLE_TIMEOUT, pw); pw.println(); - pw.print(" DOZE_MAX_IDLE_TIMEOUT="); + pw.print(" "); pw.print(KEY_MAX_IDLE_TIMEOUT); pw.print("="); TimeUtils.formatDuration(MAX_IDLE_TIMEOUT, pw); pw.println(); - pw.print(" DOZE_IDLE_FACTOR="); + pw.print(" "); pw.print(KEY_IDLE_FACTOR); pw.print("="); pw.println(IDLE_FACTOR); - pw.print(" DOZE_MIN_TIME_TO_ALARM="); + pw.print(" "); pw.print(KEY_MIN_TIME_TO_ALARM); pw.print("="); TimeUtils.formatDuration(MIN_TIME_TO_ALARM, pw); pw.println(); - pw.print(" DOZE_MAX_TEMP_APP_WHITELIST_DURATION="); + pw.print(" "); pw.print(KEY_MAX_TEMP_APP_WHITELIST_DURATION); pw.print("="); TimeUtils.formatDuration(MAX_TEMP_APP_WHITELIST_DURATION, pw); pw.println(); } @@ -465,6 +459,7 @@ public class DeviceIdleController extends SystemService } else if (result == AnyMotionDetector.RESULT_MOVED) { if (DEBUG) Slog.d(TAG, "RESULT_MOVED received."); synchronized (this) { + EventLogTags.writeDeviceIdle(mState, "sense_moved"); enterInactiveStateLocked(); } } @@ -573,15 +568,11 @@ public class DeviceIdleController extends SystemService userId, /*allowAll=*/ false, /*requireFull=*/ false, - "addAppBrieflyToWhitelist", null); + "addPowerSaveTempWhitelistApp", null); final long token = Binder.clearCallingIdentity(); try { - PackageInfo pi = AppGlobals.getPackageManager() - .getPackageInfo(packageName, 0, userId); - if (pi == null) return; DeviceIdleController.this.addPowerSaveTempWhitelistAppInternal(packageName, duration, userId); - } catch (RemoteException re) { } finally { Binder.restoreCallingIdentity(token); } @@ -592,6 +583,12 @@ public class DeviceIdleController extends SystemService } } + public final class LocalService { + public void addPowerSaveTempWhitelistAppDirect(int appId, long duration) { + DeviceIdleController.this.addPowerSaveTempWhitelistAppDirectInternal(appId, duration); + } + } + public DeviceIdleController(Context context) { super(context); mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml")); @@ -635,6 +632,7 @@ public class DeviceIdleController extends SystemService } publishBinderService(Context.DEVICE_IDLE_CONTROLLER, new BinderService()); + publishLocalService(LocalService.class, new LocalService()); } @Override @@ -765,33 +763,41 @@ public class DeviceIdleController extends SystemService try { int uid = getContext().getPackageManager().getPackageUid(packageName, userId); int appId = UserHandle.getAppId(uid); - final long timeNow = System.currentTimeMillis(); - synchronized (this) { - duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION); - long currentEndTime = mTempWhitelistAppIdEndTimes.get(appId); - // Set the new end time - mTempWhitelistAppIdEndTimes.put(appId, timeNow + duration); - if (DEBUG) { - Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist"); - } - if (currentEndTime == 0) { - // No pending timeout for the app id, post a delayed message - postTempActiveTimeoutMessage(appId, duration); - updateTempWhitelistAppIdsLocked(); - reportTempWhitelistChangedLocked(); - } - } + addPowerSaveTempWhitelistAppDirectInternal(appId, duration); } catch (NameNotFoundException e) { } } + /** + * Adds an app to the temporary whitelist and resets the endTime for granting the + * app an exemption to access network and acquire wakelocks. + */ + public void addPowerSaveTempWhitelistAppDirectInternal(int appId, long duration) { + final long timeNow = SystemClock.elapsedRealtime(); + synchronized (this) { + duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION); + long currentEndTime = mTempWhitelistAppIdEndTimes.get(appId); + // Set the new end time + mTempWhitelistAppIdEndTimes.put(appId, timeNow + duration); + if (DEBUG) { + Slog.d(TAG, "Adding AppId " + appId + " to temp whitelist"); + } + if (currentEndTime == 0) { + // No pending timeout for the app id, post a delayed message + postTempActiveTimeoutMessage(appId, duration); + updateTempWhitelistAppIdsLocked(); + reportTempWhitelistChangedLocked(); + } + } + } + private void postTempActiveTimeoutMessage(int uid, long delay) { mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TEMP_APP_WHITELIST_TIMEOUT, uid, 0), delay); } void checkTempAppWhitelistTimeout(int uid) { - final long timeNow = System.currentTimeMillis(); + final long timeNow = SystemClock.elapsedRealtime(); synchronized (this) { long endTime = mTempWhitelistAppIdEndTimes.get(uid); if (endTime == 0) { @@ -1295,6 +1301,8 @@ public class DeviceIdleController extends SystemService } synchronized (this) { + mConstants.dump(pw); + int size = mPowerSaveWhitelistApps.size(); if (size > 0) { pw.println(" Whitelist system apps:"); @@ -1313,17 +1321,34 @@ public class DeviceIdleController extends SystemService } size = mPowerSaveWhitelistAppIds.size(); if (size > 0) { - pw.println(" Whitelist app uids:"); + pw.println(" Whitelist app ids:"); for (int i = 0; i < size; i++) { - pw.print(" UID="); + pw.print(" "); pw.print(mPowerSaveWhitelistAppIds.keyAt(i)); + pw.println(); + } + } + size = mTempWhitelistAppIdEndTimes.size(); + if (size > 0) { + pw.println(" Temp whitelist schedule:"); + final long timeNow = SystemClock.elapsedRealtime(); + for (int i = 0; i < size; i++) { + pw.print(" UID="); + pw.print(mTempWhitelistAppIdEndTimes.keyAt(i)); pw.print(": "); - pw.print(mPowerSaveWhitelistAppIds.valueAt(i)); + TimeUtils.formatDuration(mTempWhitelistAppIdEndTimes.valueAt(i), timeNow, pw); + pw.println(); + } + } + size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0; + if (size > 0) { + pw.println(" Temp whitelist app ids:"); + for (int i = 0; i < size; i++) { + pw.print(" "); + pw.print(mTempWhitelistAppIdArray[i]); pw.println(); } } - - mConstants.dump(pw); pw.print(" mSigMotionSensor="); pw.println(mSigMotionSensor); pw.print(" mCurDisplay="); pw.println(mCurDisplay); diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index a5d536e..2f153a0 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -2112,8 +2112,23 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (DEBUG) Slog.v(TAG, "Not hiding: forced show not cancelled by not-always hide"); return false; } + + // There is a chance that IMM#hideSoftInput() is called in a transient state where + // IMMS#InputShown is already updated to be true whereas IMMS#mImeWindowVis is still waiting + // to be updated with the new value sent from IME process. Even in such a transient state + // historically we have accepted an incoming call of IMM#hideSoftInput() from the + // application process as a valid request, and have even promised such a behavior with CTS + // since Android Eclair. That's why we need to accept IMM#hideSoftInput() even when only + // IMMS#InputShown indicates that the software keyboard is shown. + // TODO: Clean up, IMMS#mInputShown, IMMS#mImeWindowVis and mShowRequested. + final boolean shouldHideSoftInput = (mCurMethod != null) && (mInputShown || + (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0); boolean res; - if ((mImeWindowVis & InputMethodService.IME_ACTIVE) != 0 && mCurMethod != null) { + if (shouldHideSoftInput) { + // The IME will report its visible state again after the following message finally + // delivered to the IME process as an IPC. Hence the inconsistency between + // IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in + // the final state. executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( MSG_HIDE_SOFT_INPUT, mCurMethod, resultReceiver)); res = true; diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index c76fc1c..743aafb 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -1958,6 +1958,27 @@ public class LocationManagerService extends ILocationManager.Stub { return p.getProperties(); } + /** + * @return null if the provider does not exist + * @throws SecurityException if the provider is not allowed to be + * accessed by the caller + */ + @Override + public String getNetworkProviderPackage() { + LocationProviderInterface p; + synchronized (mLock) { + if (mProvidersByName.get(LocationManager.NETWORK_PROVIDER) == null) { + return null; + } + p = mProvidersByName.get(LocationManager.NETWORK_PROVIDER); + } + + if (p instanceof LocationProviderProxy) { + return ((LocationProviderProxy) p).getConnectedPackageName(); + } + return null; + } + @Override public boolean isProviderEnabled(String provider) { // Fused provider is accessed indirectly via criteria rather than the provider-based APIs, diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index a1e2a54..baa55e7 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -19,6 +19,15 @@ package com.android.server; import static android.Manifest.permission.CONNECTIVITY_INTERNAL; import static android.Manifest.permission.DUMP; import static android.Manifest.permission.SHUTDOWN; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_NONE; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; +import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; +import static android.net.NetworkPolicyManager.FIREWALL_TYPE_BLACKLIST; +import static android.net.NetworkPolicyManager.FIREWALL_TYPE_WHITELIST; import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.TAG_ALL; import static android.net.NetworkStats.TAG_NONE; @@ -35,6 +44,7 @@ import static com.android.server.NetworkManagementService.NetdResponseCode.Tethe import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult; import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED; +import android.annotation.NonNull; import android.app.ActivityManagerNative; import android.content.Context; import android.net.ConnectivityManager; @@ -192,6 +202,21 @@ public class NetworkManagementService extends INetworkManagementService.Stub /** Set of UIDs that are to be blocked/allowed by firewall controller. */ @GuardedBy("mQuotaLock") private SparseIntArray mUidFirewallRules = new SparseIntArray(); + /** + * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches + * to application idles. + */ + @GuardedBy("mQuotaLock") + private SparseIntArray mUidFirewallStandbyRules = new SparseIntArray(); + /** + * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches + * to device idles. + */ + @GuardedBy("mQuotaLock") + private SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); + + private boolean mStandbyChainEnabled = false; + private boolean mDozableChainEnabled = false; private Object mIdleTimerLock = new Object(); /** Set of interfaces with active idle timers. */ @@ -282,6 +307,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub } public void systemReady() { + // init firewall states + mDozableChainEnabled = false; + mStandbyChainEnabled = true; prepareNativeDaemon(); if (DBG) Slog.d(TAG, "Prepared"); } @@ -568,9 +596,38 @@ public class NetworkManagementService extends INetworkManagementService.Stub final SparseIntArray uidFirewallRules = mUidFirewallRules; mUidFirewallRules = new SparseIntArray(); for (int i = 0; i < uidFirewallRules.size(); i++) { - setFirewallUidRule(uidFirewallRules.keyAt(i), uidFirewallRules.valueAt(i)); + setFirewallUidRuleInternal(FIREWALL_CHAIN_NONE, uidFirewallRules.keyAt(i), + uidFirewallRules.valueAt(i)); + } + } + + size = mUidFirewallStandbyRules.size(); + if (size > 0) { + Slog.d(TAG, "Pushing " + size + " active firewall standby UID rules"); + final SparseIntArray uidFirewallRules = mUidFirewallStandbyRules; + mUidFirewallStandbyRules = new SparseIntArray(); + for (int i = 0; i < uidFirewallRules.size(); i++) { + setFirewallUidRuleInternal(FIREWALL_CHAIN_STANDBY, uidFirewallRules.keyAt(i), + uidFirewallRules.valueAt(i)); + } + } + if (mStandbyChainEnabled) { + setFirewallChainEnabled(FIREWALL_CHAIN_STANDBY, true); + } + + size = mUidFirewallDozableRules.size(); + if (size > 0) { + Slog.d(TAG, "Pushing " + size + " active firewall dozable UID rules"); + final SparseIntArray uidFirewallRules = mUidFirewallDozableRules; + mUidFirewallDozableRules = new SparseIntArray(); + for (int i = 0; i < uidFirewallRules.size(); i++) { + setFirewallUidRuleInternal(FIREWALL_CHAIN_DOZABLE, uidFirewallRules.keyAt(i), + uidFirewallRules.valueAt(i)); } } + if (mDozableChainEnabled) { + setFirewallChainEnabled(FIREWALL_CHAIN_DOZABLE, true); + } } } @@ -1954,13 +2011,78 @@ public class NetworkManagementService extends INetworkManagementService.Stub } @Override - public void setFirewallUidRule(int uid, int rule) { + public void setFirewallChainEnabled(int chain, boolean enable) { enforceSystemUid(); - if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) { - Preconditions.checkState(mFirewallEnabled); + final String operation = enable ? "enable_chain" : "disable_chain"; + try { + String chainName; + switch(chain) { + case FIREWALL_CHAIN_STANDBY: + chainName = FIREWALL_CHAIN_NAME_STANDBY; + mStandbyChainEnabled = enable; + break; + case FIREWALL_CHAIN_DOZABLE: + chainName = FIREWALL_CHAIN_NAME_DOZABLE; + mDozableChainEnabled = enable; + break; + default: + throw new IllegalArgumentException("Bad child chain: " + chain); + } + mConnector.execute("firewall", operation, chainName); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); } + } + + private int getFirewallType(int chain) { + switch (chain) { + case FIREWALL_CHAIN_STANDBY: + return FIREWALL_TYPE_BLACKLIST; + case FIREWALL_CHAIN_DOZABLE: + return FIREWALL_TYPE_WHITELIST; + default: + return isFirewallEnabled() ? FIREWALL_TYPE_WHITELIST : FIREWALL_TYPE_BLACKLIST; + } + } + + @Override + public void setFirewallUidRules(int chain, int[] uids, int[] rules) { + enforceSystemUid(); + SparseIntArray uidFirewallRules = getUidFirewallRules(chain); + SparseIntArray newRules = new SparseIntArray(); + // apply new set of rules + for (int index = uids.length - 1; index >= 0; --index) { + int uid = uids[index]; + int rule = rules[index]; + setFirewallUidRule(chain, uid, rule); + newRules.put(uid, rule); + } + // collect the rules to remove. + SparseIntArray rulesToRemove = new SparseIntArray(); + for (int index = uidFirewallRules.size() - 1; index >= 0; --index) { + int uid = uidFirewallRules.keyAt(index); + if (newRules.indexOfKey(uid) < 0) { + rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT); + } + } + // remove dead rules + for (int index = rulesToRemove.size() - 1; index >= 0; --index) { + int uid = rulesToRemove.keyAt(index); + setFirewallUidRuleInternal(chain, uid, FIREWALL_RULE_DEFAULT); + } + } + + @Override + public void setFirewallUidRule(int chain, int uid, int rule) { + enforceSystemUid(); + setFirewallUidRuleInternal(chain, uid, rule); + } + + private void setFirewallUidRuleInternal(int chain, int uid, int rule) { synchronized (mQuotaLock) { - final int oldUidFirewallRule = mUidFirewallRules.get(uid); + SparseIntArray uidFirewallRules = getUidFirewallRules(chain); + + final int oldUidFirewallRule = uidFirewallRules.get(uid, FIREWALL_RULE_DEFAULT); if (DBG) { Slog.d(TAG, "oldRule = " + oldUidFirewallRule + ", newRule=" + rule + " for uid=" + uid); @@ -1973,7 +2095,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub try { String ruleName; - if (isFirewallEnabled()) { // Whitelist mode + if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) { if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) { ruleName = "allow"; } else { @@ -1988,17 +2110,44 @@ public class NetworkManagementService extends INetworkManagementService.Stub } if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { - mUidFirewallRules.delete(uid); + uidFirewallRules.delete(uid); } else { - mUidFirewallRules.put(uid, rule); + uidFirewallRules.put(uid, rule); } - mConnector.execute("firewall", "set_uid_rule", uid, ruleName); + mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid, + ruleName); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } } + private @NonNull SparseIntArray getUidFirewallRules(int chain) { + switch (chain) { + case FIREWALL_CHAIN_STANDBY: + return mUidFirewallStandbyRules; + case FIREWALL_CHAIN_DOZABLE: + return mUidFirewallDozableRules; + case FIREWALL_CHAIN_NONE: + return mUidFirewallRules; + default: + throw new IllegalArgumentException("Unknown chain:" + chain); + } + } + + public @NonNull String getFirewallChainName(int chain) { + switch (chain) { + case FIREWALL_CHAIN_STANDBY: + return FIREWALL_CHAIN_NAME_STANDBY; + case FIREWALL_CHAIN_DOZABLE: + return FIREWALL_CHAIN_NAME_DOZABLE; + case FIREWALL_CHAIN_NONE: + return FIREWALL_CHAIN_NAME_NONE; + default: + throw new IllegalArgumentException("Unknown chain:" + chain); + } + } + private static void enforceSystemUid() { final int uid = Binder.getCallingUid(); if (uid != Process.SYSTEM_UID) { @@ -2123,6 +2272,32 @@ public class NetworkManagementService extends INetworkManagementService.Stub pw.println("]"); } + pw.println("UID firewall standby chain enabled: " + mStandbyChainEnabled); + synchronized (mUidFirewallStandbyRules) { + pw.print("UID firewall standby rule: ["); + final int size = mUidFirewallStandbyRules.size(); + for (int i = 0; i < size; i++) { + pw.print(mUidFirewallStandbyRules.keyAt(i)); + pw.print(":"); + pw.print(mUidFirewallStandbyRules.valueAt(i)); + if (i < size - 1) pw.print(","); + } + pw.println("]"); + } + + pw.println("UID firewall dozable chain enabled: " + mDozableChainEnabled); + synchronized (mUidFirewallDozableRules) { + pw.print("UID firewall dozable rule: ["); + final int size = mUidFirewallDozableRules.size(); + for (int i = 0; i < size; i++) { + pw.print(mUidFirewallDozableRules.keyAt(i)); + pw.print(":"); + pw.print(mUidFirewallDozableRules.valueAt(i)); + if (i < size - 1) pw.print(","); + } + pw.println("]"); + } + synchronized (mIdleTimerLock) { pw.println("Idle timers:"); for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) { diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java index 56f9942..94316fe 100644 --- a/services/core/java/com/android/server/PersistentDataBlockService.java +++ b/services/core/java/com/android/server/PersistentDataBlockService.java @@ -18,18 +18,14 @@ package com.android.server; import android.Manifest; import android.app.ActivityManager; -import android.app.PendingIntent; import android.content.Context; -import android.content.Intent; import android.content.pm.PackageManager; import android.os.Binder; -import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.service.persistentdata.IPersistentDataBlockService; -import android.service.persistentdata.PersistentDataBlockManager; import android.util.Slog; import com.android.internal.R; @@ -432,29 +428,6 @@ public class PersistentDataBlockService extends SystemService { } @Override - public void wipeIfAllowed(Bundle bundle, PendingIntent pi) { - // Should only be called by owner - if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { - throw new SecurityException("Only the Owner is allowed to wipe"); - } - // Caller must be able to query the the state of the PersistentDataBlock - enforcePersistentDataBlockAccess(); - String allowedPackage = mContext.getResources() - .getString(R.string.config_persistentDataPackageName); - Intent intent = new Intent(); - intent.setPackage(allowedPackage); - intent.setAction(PersistentDataBlockManager.ACTION_WIPE_IF_ALLOWED); - intent.putExtras(bundle); - intent.putExtra(PersistentDataBlockManager.EXTRA_WIPE_IF_ALLOWED_CALLBACK, pi); - long id = Binder.clearCallingIdentity(); - try { - mContext.sendBroadcastAsUser(intent, UserHandle.OWNER); - } finally { - restoreCallingIdentity(id); - } - } - - @Override public void setOemUnlockEnabled(boolean enabled) { // do not allow monkey to flip the flag if (ActivityManager.isUserAMonkey()) { diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java index 6e67970..e0a9ab4 100644 --- a/services/core/java/com/android/server/SystemService.java +++ b/services/core/java/com/android/server/SystemService.java @@ -34,7 +34,7 @@ import android.os.ServiceManager; * local interfaces that other services within the system server may use to access * privileged internal functions. * <li>Then {@link #onBootPhase(int)} is called as many times as there are boot phases - * until {@link #PHASE_BOOT_COMPLETE} is sent, which is the last boot phase. Each phase + * until {@link #PHASE_BOOT_COMPLETED} is sent, which is the last boot phase. Each phase * is an opportunity to do special work, like acquiring optional service dependencies, * waiting to see if SafeMode is enabled, or registering with a service that gets * started after this one. diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 667abb6..c4f460e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -39,6 +39,7 @@ import static org.xmlpull.v1.XmlPullParser.START_TAG; import android.Manifest; import android.app.AppOpsManager; import android.app.ApplicationThreadNative; +import android.app.BroadcastOptions; import android.app.IActivityContainer; import android.app.IActivityContainerCallback; import android.app.IAppTask; @@ -89,6 +90,7 @@ import com.android.internal.util.MemInfoReader; import com.android.internal.util.Preconditions; import com.android.server.AppOpsService; import com.android.server.AttributeCache; +import com.android.server.DeviceIdleController; import com.android.server.IntentResolver; import com.android.server.LocalServices; import com.android.server.ServiceThread; @@ -941,6 +943,11 @@ public final class ActivityManagerService extends ActivityManagerNative UsageStatsManagerInternal mUsageStatsService; /** + * Access to DeviceIdleController service. + */ + DeviceIdleController.LocalService mLocalDeviceIdleController; + + /** * Information about and control over application operations */ final AppOpsService mAppOpsService; @@ -1438,7 +1445,7 @@ public final class ActivityManagerService extends ActivityManagerNative } broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); + null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); if (mShowDialogs) { Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, @@ -2559,9 +2566,9 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void batterySendBroadcast(Intent intent) { - broadcastIntentLocked(null, null, intent, null, - null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, - Process.SYSTEM_UID, UserHandle.USER_ALL); + broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, + AppOpsManager.OP_NONE, null, false, false, + -1, Process.SYSTEM_UID, UserHandle.USER_ALL); } /** @@ -5089,7 +5096,7 @@ public final class ActivityManagerService extends ActivityManagerNative Uri.fromParts("package", packageName, null)); intent.putExtra(Intent.EXTRA_UID, pkgUid); broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, - null, null, 0, null, null, null, false, false, userId); + null, null, 0, null, null, null, null, false, false, userId); } catch (RemoteException e) { } } finally { @@ -5322,9 +5329,9 @@ public final class ActivityManagerService extends ActivityManagerNative mStackSupervisor.closeSystemDialogsLocked(); - broadcastIntentLocked(null, null, intent, null, - null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, - Process.SYSTEM_UID, UserHandle.USER_ALL); + broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, + AppOpsManager.OP_NONE, null, false, false, + -1, Process.SYSTEM_UID, UserHandle.USER_ALL); } @Override @@ -5423,8 +5430,7 @@ public final class ActivityManagerService extends ActivityManagerNative intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - false, false, - MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); + null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); } private void forceStopUserLocked(int userId, String reason) { @@ -5435,8 +5441,7 @@ public final class ActivityManagerService extends ActivityManagerNative intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - false, false, - MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); + null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } private final boolean killPackageProcessesLocked(String packageName, int appId, @@ -6329,8 +6334,8 @@ public final class ActivityManagerService extends ActivityManagerNative }, 0, null, null, android.Manifest.permission.RECEIVE_BOOT_COMPLETED, - AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, - userId); + AppOpsManager.OP_NONE, null, true, false, + MY_PID, Process.SYSTEM_UID, userId); } } scheduleStartProfilesLocked(); @@ -11442,8 +11447,7 @@ public final class ActivityManagerService extends ActivityManagerNative EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName()); broadcastIntentLocked(null, null, intent, null, this, 0, null, null, null, AppOpsManager.OP_NONE, - true, false, MY_PID, Process.SYSTEM_UID, - users[curUser]); + null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]); } public void performReceive(Intent intent, int resultCode, @@ -11535,6 +11539,9 @@ public final class ActivityManagerService extends ActivityManagerNative return; } + mLocalDeviceIdleController + = LocalServices.getService(DeviceIdleController.LocalService.class); + // Make sure we have the current profile info, since it is needed for // security checks. updateCurrentProfileIdsLocked(); @@ -11704,7 +11711,7 @@ public final class ActivityManagerService extends ActivityManagerNative intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); + null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); intent = new Intent(Intent.ACTION_USER_STARTING); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); @@ -11717,7 +11724,7 @@ public final class ActivityManagerService extends ActivityManagerNative } }, 0, null, null, INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, - true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); + null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } catch (Throwable t) { Slog.wtf(TAG, "Failed sending first user broadcasts", t); } finally { @@ -16101,8 +16108,8 @@ public final class ActivityManagerService extends ActivityManagerNative Intent intent = allSticky.get(i); BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, null, - null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, - null, null, false, true, true, -1); + null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers, + null, 0, null, null, false, true, true, -1); queue.enqueueParallelBroadcastLocked(r); queue.scheduleBroadcastsLocked(); } @@ -16255,9 +16262,8 @@ public final class ActivityManagerService extends ActivityManagerNative private final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, - Bundle map, String requiredPermission, int appOp, - boolean ordered, boolean sticky, int callingPid, int callingUid, - int userId) { + Bundle resultExtras, String requiredPermission, int appOp, Bundle options, + boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) { intent = new Intent(intent); // By default broadcasts do not go to stopped apps. @@ -16292,6 +16298,28 @@ public final class ActivityManagerService extends ActivityManagerNative } } + BroadcastOptions brOptions = null; + if (options != null) { + brOptions = new BroadcastOptions(options); + if (brOptions.getTemporaryAppWhitelistDuration() > 0) { + // See if the caller is allowed to do this. Note we are checking against + // the actual real caller (not whoever provided the operation as say a + // PendingIntent), because that who is actually supplied the arguments. + if (checkComponentPermission( + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, + Binder.getCallingPid(), Binder.getCallingUid(), -1, true) + != PackageManager.PERMISSION_GRANTED) { + String msg = "Permission Denial: " + intent.getAction() + + " broadcast from " + callerPackage + " (pid=" + callingPid + + ", uid=" + callingUid + ")" + + " requires " + + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; + Slog.w(TAG, msg); + throw new SecurityException(msg); + } + } + } + /* * Prevent non-system code (defined here to be non-persistent * processes) from sending protected broadcasts. @@ -16598,8 +16626,8 @@ public final class ActivityManagerService extends ActivityManagerNative final BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, resolvedType, requiredPermission, - appOp, registeredReceivers, resultTo, resultCode, resultData, map, - ordered, sticky, false, userId); + appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData, + resultExtras, ordered, sticky, false, userId); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r); final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); if (!replaced) { @@ -16687,8 +16715,8 @@ public final class ActivityManagerService extends ActivityManagerNative BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, resolvedType, - requiredPermission, appOp, receivers, resultTo, resultCode, - resultData, map, ordered, sticky, false, userId); + requiredPermission, appOp, brOptions, receivers, resultTo, resultCode, + resultData, resultExtras, ordered, sticky, false, userId); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r + ": prev had " + queue.mOrderedBroadcasts.size()); @@ -16735,8 +16763,9 @@ public final class ActivityManagerService extends ActivityManagerNative public final int broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, - int resultCode, String resultData, Bundle map, - String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { + int resultCode, String resultData, Bundle resultExtras, + String requiredPermission, int appOp, Bundle options, + boolean serialized, boolean sticky, int userId) { enforceNotIsolatedCaller("broadcastIntent"); synchronized(this) { intent = verifyBroadcastLocked(intent); @@ -16747,8 +16776,8 @@ public final class ActivityManagerService extends ActivityManagerNative final long origId = Binder.clearCallingIdentity(); int res = broadcastIntentLocked(callerApp, callerApp != null ? callerApp.info.packageName : null, - intent, resolvedType, resultTo, - resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, + intent, resolvedType, resultTo, resultCode, resultData, resultExtras, + requiredPermission, appOp, null, serialized, sticky, callingPid, callingUid, userId); Binder.restoreCallingIdentity(origId); return res; @@ -16757,15 +16786,16 @@ public final class ActivityManagerService extends ActivityManagerNative int broadcastIntentInPackage(String packageName, int uid, Intent intent, String resolvedType, IIntentReceiver resultTo, - int resultCode, String resultData, Bundle map, - String requiredPermission, boolean serialized, boolean sticky, int userId) { + int resultCode, String resultData, Bundle resultExtras, + String requiredPermission, Bundle options, boolean serialized, boolean sticky, + int userId) { synchronized(this) { intent = verifyBroadcastLocked(intent); final long origId = Binder.clearCallingIdentity(); int res = broadcastIntentLocked(null, packageName, intent, resolvedType, - resultTo, resultCode, resultData, map, requiredPermission, - AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); + resultTo, resultCode, resultData, resultExtras, requiredPermission, + AppOpsManager.OP_NONE, options, serialized, sticky, -1, uid, userId); Binder.restoreCallingIdentity(origId); return res; } @@ -17162,8 +17192,8 @@ public final class ActivityManagerService extends ActivityManagerNative | Intent.FLAG_RECEIVER_REPLACE_PENDING | Intent.FLAG_RECEIVER_FOREGROUND); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, - null, AppOpsManager.OP_NONE, false, false, MY_PID, - Process.SYSTEM_UID, UserHandle.USER_ALL); + null, AppOpsManager.OP_NONE, null, false, false, + MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { intent = new Intent(Intent.ACTION_LOCALE_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); @@ -17172,7 +17202,7 @@ public final class ActivityManagerService extends ActivityManagerNative } broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); + null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } } } @@ -19642,7 +19672,7 @@ public final class ActivityManagerService extends ActivityManagerNative intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - false, false, MY_PID, Process.SYSTEM_UID, userId); + null, false, false, MY_PID, Process.SYSTEM_UID, userId); } if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { @@ -19657,8 +19687,7 @@ public final class ActivityManagerService extends ActivityManagerNative onUserInitialized(uss, foreground, oldUserId, userId); } }, 0, null, null, null, AppOpsManager.OP_NONE, - true, false, MY_PID, Process.SYSTEM_UID, - userId); + null, true, false, MY_PID, Process.SYSTEM_UID, userId); uss.initializing = true; } else { getUserManagerLocked().makeInitialized(userInfo.id); @@ -19680,13 +19709,13 @@ public final class ActivityManagerService extends ActivityManagerNative broadcastIntentLocked(null, null, intent, null, new IIntentReceiver.Stub() { @Override - public void performReceive(Intent intent, int resultCode, String data, - Bundle extras, boolean ordered, boolean sticky, int sendingUser) - throws RemoteException { + public void performReceive(Intent intent, int resultCode, + String data, Bundle extras, boolean ordered, boolean sticky, + int sendingUser) throws RemoteException { } }, 0, null, null, INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, - true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); + null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } } } finally { @@ -19724,7 +19753,7 @@ public final class ActivityManagerService extends ActivityManagerNative intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - false, false, MY_PID, Process.SYSTEM_UID, profileUserId); + null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId); } } if (newUserId >= 0) { @@ -19739,7 +19768,7 @@ public final class ActivityManagerService extends ActivityManagerNative intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, - false, false, MY_PID, Process.SYSTEM_UID, profileUserId); + null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId); } intent = new Intent(Intent.ACTION_USER_SWITCHED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY @@ -19748,7 +19777,7 @@ public final class ActivityManagerService extends ActivityManagerNative broadcastIntentLocked(null, null, intent, null, null, 0, null, null, android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, - false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); + null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } } finally { Binder.restoreCallingIdentity(ident); @@ -19925,7 +19954,7 @@ public final class ActivityManagerService extends ActivityManagerNative broadcastIntentLocked(null, null, intent, null, null, 0, null, null, android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, - true, false, MY_PID, Process.SYSTEM_UID, userId); + null, true, false, MY_PID, Process.SYSTEM_UID, userId); } } } @@ -20057,14 +20086,14 @@ public final class ActivityManagerService extends ActivityManagerNative mSystemServiceManager.stopUser(userId); broadcastIntentLocked(null, null, shutdownIntent, null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, - true, false, MY_PID, Process.SYSTEM_UID, userId); + null, true, false, MY_PID, Process.SYSTEM_UID, userId); } }; // Kick things off. broadcastIntentLocked(null, null, stoppingIntent, null, stoppingReceiver, 0, null, null, INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, - true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); + null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index eb5af9e..0714d36 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1326,7 +1326,12 @@ final class ActivityStack { if (r != starting) { mStackSupervisor.startSpecificActivityLocked( r, noStackActivityResumed, false); - noStackActivityResumed = false; + if (activityNdx >= activities.size()) { + // Record may be removed if its process needs to restart. + activityNdx = activities.size() - 1; + } else { + noStackActivityResumed = false; + } } } else if (r.visible) { diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 80b8a93..2335071 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -26,6 +26,7 @@ import java.util.Set; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.AppOpsManager; +import android.app.BroadcastOptions; import android.content.ComponentName; import android.content.IIntentReceiver; import android.content.Intent; @@ -43,6 +44,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.util.EventLog; import android.util.Slog; +import com.android.server.DeviceIdleController; import static com.android.server.am.ActivityManagerDebugConfig.*; @@ -146,6 +148,8 @@ public final class BroadcastQueue { static final int BROADCAST_INTENT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG; static final int BROADCAST_TIMEOUT_MSG = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 1; + static final int SCHEDULE_TEMP_WHITELIST_MSG + = ActivityManagerService.FIRST_BROADCAST_QUEUE_MSG + 2; final BroadcastHandler mHandler; @@ -167,6 +171,13 @@ public final class BroadcastQueue { broadcastTimeoutLocked(true); } } break; + case SCHEDULE_TEMP_WHITELIST_MSG: { + DeviceIdleController.LocalService dic = mService.mLocalDeviceIdleController; + if (dic != null) { + dic.addPowerSaveTempWhitelistAppDirect(UserHandle.getAppId(msg.arg1), + msg.arg2); + } + } break; } } }; @@ -547,6 +558,19 @@ public final class BroadcastQueue { } } + final void scheduleTempWhitelistLocked(int uid, long duration) { + if (duration > Integer.MAX_VALUE) { + duration = Integer.MAX_VALUE; + } + // XXX ideally we should pause the broadcast until everything behind this is done, + // or else we will likely start dispatching the broadcast before we have opened + // access to the app (there is a lot of asynchronicity behind this). It is probably + // not that big a deal, however, because the main purpose here is to allow apps + // to hold wake locks, and they will be able to acquire their wake lock immediately + // it just won't be enabled until we get through this work. + mHandler.obtainMessage(SCHEDULE_TEMP_WHITELIST_MSG, uid, (int)duration).sendToTarget(); + } + final void processNextBroadcast(boolean fromMsg) { synchronized(mService) { BroadcastRecord r; @@ -721,7 +745,9 @@ public final class BroadcastQueue { setBroadcastTimeoutLocked(timeoutTime); } - Object nextReceiver = r.receivers.get(recIdx); + final BroadcastOptions brOptions = r.options; + final Object nextReceiver = r.receivers.get(recIdx); + if (nextReceiver instanceof BroadcastFilter) { // Simple case: this is a registered receiver who gets // a direct call. @@ -739,6 +765,11 @@ public final class BroadcastQueue { + r.ordered + " receiver=" + r.receiver); r.state = BroadcastRecord.IDLE; scheduleBroadcastsLocked(); + } else { + if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) { + scheduleTempWhitelistLocked(filter.owningUid, + brOptions.getTemporaryAppWhitelistDuration()); + } } return; } @@ -882,6 +913,11 @@ public final class BroadcastQueue { + info.activityInfo.applicationInfo.uid); } + if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) { + scheduleTempWhitelistLocked(receiverUid, + brOptions.getTemporaryAppWhitelistDuration()); + } + // Broadcast is being executed, its package can't be stopped. try { AppGlobals.getPackageManager().setPackageStoppedState( diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java index c050d03..b943222 100644 --- a/services/core/java/com/android/server/am/BroadcastRecord.java +++ b/services/core/java/com/android/server/am/BroadcastRecord.java @@ -17,6 +17,7 @@ package com.android.server.am; import android.app.AppOpsManager; +import android.app.BroadcastOptions; import android.content.IIntentReceiver; import android.content.ComponentName; import android.content.Intent; @@ -52,6 +53,7 @@ final class BroadcastRecord extends Binder { final String resolvedType; // the resolved data type final String requiredPermission; // a permission the caller has required final int appOp; // an app op that is associated with this broadcast + final BroadcastOptions options; // BroadcastOptions supplied by caller final List receivers; // contains BroadcastFilter and ResolveInfo IIntentReceiver resultTo; // who receives final result if non-null long enqueueClockTime; // the clock time the broadcast was enqueued @@ -105,6 +107,9 @@ final class BroadcastRecord extends Binder { pw.print(prefix); pw.print("requiredPermission="); pw.print(requiredPermission); pw.print(" appOp="); pw.println(appOp); } + if (options != null) { + pw.print(prefix); pw.print("options="); pw.println(options.toBundle()); + } pw.print(prefix); pw.print("enqueueClockTime="); pw.print(new Date(enqueueClockTime)); pw.print(" dispatchClockTime="); @@ -180,8 +185,8 @@ final class BroadcastRecord extends Binder { BroadcastRecord(BroadcastQueue _queue, Intent _intent, ProcessRecord _callerApp, String _callerPackage, int _callingPid, int _callingUid, String _resolvedType, String _requiredPermission, - int _appOp, List _receivers, IIntentReceiver _resultTo, int _resultCode, - String _resultData, Bundle _resultExtras, boolean _serialized, + int _appOp, BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo, + int _resultCode, String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky, boolean _initialSticky, int _userId) { queue = _queue; @@ -194,6 +199,7 @@ final class BroadcastRecord extends Binder { resolvedType = _resolvedType; requiredPermission = _requiredPermission; appOp = _appOp; + options = _options; receivers = _receivers; resultTo = _resultTo; resultCode = _resultCode; diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 531de46..ece3ffb 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -199,9 +199,9 @@ final class PendingIntentRecord extends IIntentSender.Stub { } public int send(int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, - String requiredPermission) throws TransactionTooLargeException { + String requiredPermission, Bundle options) throws TransactionTooLargeException { return sendInner(code, intent, resolvedType, finishedReceiver, - requiredPermission, null, null, 0, 0, 0, null, null); + requiredPermission, null, null, 0, 0, 0, options, null); } int sendInner(int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, @@ -293,9 +293,9 @@ final class PendingIntentRecord extends IIntentSender.Stub { // If a completion callback has been requested, require // that the broadcast be delivered synchronously int sent = owner.broadcastIntentInPackage(key.packageName, uid, - finalIntent, resolvedType, - finishedReceiver, code, null, null, - requiredPermission, (finishedReceiver != null), false, userId); + finalIntent, resolvedType, finishedReceiver, code, null, null, + requiredPermission, options, (finishedReceiver != null), + false, userId); if (sent == ActivityManager.BROADCAST_SUCCESS) { sendFinish = false; } diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 236af37..87cb40e 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -445,6 +445,11 @@ final class ServiceRecord extends Binder { // icon, but this used to be able to slip through, so for // those dirty apps we will create a notification clearly // blaming the app. + Slog.v(TAG, "Attempted to start a foreground service (" + + name + + ") with a broken notification (no icon: " + + localForegroundNoti + + ")"); CharSequence appName = appInfo.loadLabel( ams.mContext.getPackageManager()); @@ -461,6 +466,12 @@ final class ServiceRecord extends Binder { // it's ugly, but it clearly identifies the app notiBuilder.setSmallIcon(appInfo.icon); + // mark as foreground + notiBuilder.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true); + + // we are doing the app a kindness here + notiBuilder.setPriority(Notification.PRIORITY_MIN); + Intent runningIntent = new Intent( Settings.ACTION_APPLICATION_DETAILS_SETTINGS); runningIntent.setData(Uri.fromParts("package", @@ -498,6 +509,8 @@ final class ServiceRecord extends Binder { nm.enqueueNotification(localPackageName, localPackageName, appUid, appPid, null, localForegroundId, localForegroundNoti, outId, userId); + + foregroundNoti = localForegroundNoti; // save it for amending next time } catch (RuntimeException e) { Slog.w(TAG, "Error showing notification for service", e); // If it gave us a garbage notification, it doesn't diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index dca762c..569a0fc 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -242,19 +242,17 @@ public class MediaSessionRecord implements IBinder.DeathRecipient { } 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)) { - mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream, direction, - flags, packageName, uid); + postAdjustSuggestedStreamVolume(stream, direction, flags, packageName, uid); } else { flags |= previousFlagPlaySound; - mAudioManagerInternal.adjustSuggestedStreamVolumeForUid( - AudioManager.USE_DEFAULT_STREAM_TYPE, direction, flags, packageName, - uid); + postAdjustSuggestedStreamVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, direction, + flags, packageName, uid); } } else { - mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags, - packageName, uid); + postAdjustStreamVolume(stream, direction, flags, packageName, uid); } } else { if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) { @@ -461,6 +459,28 @@ 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) { + 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); + } + }); + } + private String getShortMetadataString() { int fields = mMetadata == null ? 0 : mMetadata.size(); MediaDescription description = mMetadata == null ? null : mMetadata diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java index 0f88883..9db6a06 100644 --- a/services/core/java/com/android/server/net/LockdownVpnTracker.java +++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java @@ -17,6 +17,7 @@ package com.android.server.net; import static android.Manifest.permission.CONNECTIVITY_INTERNAL; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE; import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; @@ -201,8 +202,8 @@ public class LockdownVpnTracker { setFirewallEgressSourceRule(addr, true); } - mNetService.setFirewallUidRule(ROOT_UID, FIREWALL_RULE_ALLOW); - mNetService.setFirewallUidRule(Os.getuid(), FIREWALL_RULE_ALLOW); + mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, ROOT_UID, FIREWALL_RULE_ALLOW); + mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, Os.getuid(), FIREWALL_RULE_ALLOW); mErrorCount = 0; mAcceptedIface = iface; @@ -291,8 +292,8 @@ public class LockdownVpnTracker { setFirewallEgressSourceRule(addr, false); } - mNetService.setFirewallUidRule(ROOT_UID, FIREWALL_RULE_DEFAULT); - mNetService.setFirewallUidRule(Os.getuid(), FIREWALL_RULE_DEFAULT); + mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE, ROOT_UID, FIREWALL_RULE_DEFAULT); + mNetService.setFirewallUidRule(FIREWALL_CHAIN_NONE,Os.getuid(), FIREWALL_RULE_DEFAULT); mAcceptedSourceAddr = null; } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index e009455..b0550d6 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -36,8 +36,10 @@ import static android.net.NetworkPolicy.LIMIT_DISABLED; import static android.net.NetworkPolicy.SNOOZE_NEVER; import static android.net.NetworkPolicy.WARNING_DISABLED; import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY; +import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW; import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY; -import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE; import static android.net.NetworkPolicyManager.POLICY_NONE; import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND; @@ -80,7 +82,6 @@ import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.INotificationManager; -import android.app.IProcessObserver; import android.app.IUidObserver; import android.app.Notification; import android.app.PendingIntent; @@ -141,7 +142,6 @@ import android.util.Log; import android.util.NtpTrustedTime; import android.util.Pair; import android.util.Slog; -import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.util.TrustedTime; @@ -279,6 +279,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub final SparseIntArray mUidPolicy = new SparseIntArray(); /** Currently derived rules for each UID. */ final SparseIntArray mUidRules = new SparseIntArray(); + final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); /** * UIDs that have been white-listed to always be able to have network access @@ -412,8 +413,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); - final PackageManager pm = mContext.getPackageManager(); - synchronized (mRulesLock) { updatePowerSaveWhitelistLocked(); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); @@ -1103,7 +1102,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub // will not have a bandwidth limit. Also only do this if restrict // background data use is *not* enabled, since that takes precendence // use over those networks can have a cost associated with it). - final boolean powerSave = (mRestrictPower || mDeviceIdleMode) && !mRestrictBackground; + final boolean powerSave = mRestrictPower && !mRestrictBackground; // First, generate identities of all connected networks so we can // quickly compare them against all defined policies below. @@ -2024,6 +2023,29 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub } } + void updateRulesForDeviceIdleLocked() { + if (mDeviceIdleMode) { + // sync the whitelists before enable dozable chain. We don't care about the rules if + // we are disabling the chain. + SparseIntArray uidRules = new SparseIntArray(); + final List<UserInfo> users = mUserManager.getUsers(); + for (UserInfo user : users) { + for (int i = mPowerSaveTempWhitelistAppIds.size() - 1; i >= 0; i--) { + int appId = mPowerSaveTempWhitelistAppIds.keyAt(i); + int uid = UserHandle.getUid(user.id, appId); + uidRules.put(uid, FIREWALL_RULE_ALLOW); + } + for (int i = mPowerSaveWhitelistAppIds.size() - 1; i >= 0; i--) { + int appId = mPowerSaveWhitelistAppIds.keyAt(i); + int uid = UserHandle.getUid(user.id, appId); + uidRules.put(uid, FIREWALL_RULE_ALLOW); + } + } + setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules); + } + enableFirewallChain(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode); + } + /** * Update rules that might be changed by {@link #mRestrictBackground}, * {@link #mRestrictPower}, or {@link #mDeviceIdleMode} value. @@ -2034,10 +2056,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub // If we are in restrict power mode, we allow all important apps // to have data access. Otherwise, we restrict data access to only // the top apps. - mCurForegroundState = (!mRestrictBackground && (mRestrictPower || mDeviceIdleMode)) + mCurForegroundState = (!mRestrictBackground && mRestrictPower) ? ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE : ActivityManager.PROCESS_STATE_TOP; + updateRulesForDeviceIdleLocked(); + // update rules for all installed applications final List<UserInfo> users = mUserManager.getUsers(); final List<ApplicationInfo> apps = pm.getInstalledApplications( @@ -2131,7 +2155,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub // uid in background, and global background disabled uidRules = RULE_REJECT_METERED; } - } else if (mRestrictPower || mDeviceIdleMode) { + } else if (mRestrictPower) { final boolean whitelisted = mPowerSaveWhitelistAppIds.get(appId) || mPowerSaveTempWhitelistAppIds.get(appId); if (!whitelisted && !uidForeground @@ -2162,7 +2186,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub final boolean oldFirewallReject = (oldRules & RULE_REJECT_ALL) != 0; final boolean firewallReject = (uidRules & RULE_REJECT_ALL) != 0; if (oldFirewallReject != firewallReject) { - setUidFirewallRules(uid, firewallReject); + setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, firewallReject); + if (mDeviceIdleMode && !firewallReject) { + // if we are in device idle mode, and we decide to allow this uid. we need to punch + // a hole in the device idle chain. + setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, false); + } } // dispatch changed rule to existing listeners @@ -2314,14 +2343,34 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub } /** + * Set uid rules on a particular firewall chain. This is going to synchronize the rules given + * here to netd. It will clean up dead rules and make sure the target chain only contains rules + * specified here. + */ + private void setUidFirewallRules(int chain, SparseIntArray uidRules) { + try { + int size = uidRules.size(); + int[] uids = new int[size]; + int[] rules = new int[size]; + for(int index = size - 1; index >= 0; --index) { + uids[index] = uidRules.keyAt(index); + rules[index] = uidRules.valueAt(index); + } + mNetworkManager.setFirewallUidRules(chain, uids, rules); + } catch (IllegalStateException e) { + Log.wtf(TAG, "problem setting firewall uid rules", e); + } catch (RemoteException e) { + // ignored; service lives in system_server + } + } + + /** * Add or remove a uid to the firewall blacklist for all network ifaces. - * @param uid - * @param rejectOnAll */ - private void setUidFirewallRules(int uid, boolean rejectOnAll) { + private void setUidFirewallRule(int chain, int uid, boolean rejectOnAll) { try { - mNetworkManager.setFirewallUidRule(uid, - rejectOnAll ? FIREWALL_RULE_DENY : FIREWALL_RULE_DEFAULT); + mNetworkManager.setFirewallUidRule(chain, uid, + rejectOnAll ? FIREWALL_RULE_DENY : FIREWALL_RULE_ALLOW); } catch (IllegalStateException e) { Log.wtf(TAG, "problem setting firewall uid rules", e); } catch (RemoteException e) { @@ -2329,6 +2378,24 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub } } + /** + * Add or remove a uid to the firewall blacklist for all network ifaces. + */ + private void enableFirewallChain(int chain, boolean enable) { + if (mFirewallChainStates.indexOfKey(chain) >= 0 && + mFirewallChainStates.get(chain) == enable) { + // All is the same, nothing to do. + return; + } + try { + mNetworkManager.setFirewallChainEnabled(chain, enable); + } catch (IllegalStateException e) { + Log.wtf(TAG, "problem enable firewall chain", e); + } catch (RemoteException e) { + // ignored; service lives in system_server + } + } + private long getTotalBytes(NetworkTemplate template, long start, long end) { try { return mNetworkStats.getNetworkTotalBytes(template, start, end); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5b7dd70..06e27fc 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -8808,7 +8808,7 @@ public class PackageManagerService extends IPackageManager.Stub { } am.broadcastIntent(null, intent, null, finishedReceiver, 0, null, null, null, android.app.AppOpsManager.OP_NONE, - finishedReceiver != null, false, id); + null, finishedReceiver != null, false, id); } } catch (RemoteException ex) { } @@ -8982,7 +8982,7 @@ public class PackageManagerService extends IPackageManager.Stub { .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) .setPackage(packageName); am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, - android.app.AppOpsManager.OP_NONE, false, false, userId); + android.app.AppOpsManager.OP_NONE, null, false, false, userId); } } catch (RemoteException e) { // shouldn't happen diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index dbcfa19..6fb9a5c 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -3739,13 +3739,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { attrs.gravity = Gravity.BOTTOM; mDockLayer = win.getSurfaceLayer(); } else if (attrs.type == TYPE_VOICE_INTERACTION) { - pf.left = df.left = of.left = cf.left = vf.left = mUnrestrictedScreenLeft; + pf.left = df.left = of.left = mUnrestrictedScreenLeft; pf.top = df.top = of.top = mUnrestrictedScreenTop; - pf.right = df.right = of.right = cf.right = vf.right = mUnrestrictedScreenLeft - + mUnrestrictedScreenWidth; - pf.bottom = df.bottom = of.bottom = cf.bottom = mUnrestrictedScreenTop - + mUnrestrictedScreenHeight; + pf.right = df.right = of.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; + pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; cf.bottom = vf.bottom = mStableBottom; + // Note: In Phone landscape mode, the button bar should also be excluded. + cf.right = vf.right = mStableRight; + cf.left = vf.left = mStableLeft; cf.top = vf.top = mStableTop; } else if (win == mStatusBar) { pf.left = df.left = of.left = mUnrestrictedScreenLeft; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 1b63ca0..ace5997 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7139,20 +7139,14 @@ public class WindowManagerService extends IWindowManager.Stub public Configuration computeNewConfiguration() { synchronized (mWindowMap) { - if (!mDisplayReady) { - return null; - } - Configuration config = computeNewConfigurationLocked(); - if (mWaitingForConfig) { - mWaitingForConfig = false; - mLastFinishedFreezeSource = "new-config"; - performLayoutAndPlaceSurfacesLocked(); - } - return config; + return computeNewConfigurationLocked(); } } - Configuration computeNewConfigurationLocked() { + private Configuration computeNewConfigurationLocked() { + if (!mDisplayReady) { + return null; + } Configuration config = new Configuration(); config.fontScale = 0; computeScreenConfigurationLocked(config); @@ -9678,7 +9672,7 @@ public class WindowManagerService extends IWindowManager.Stub /** * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method. - * @param w WindowState this method is applied to. + * @param w WindowState this method is applied to. * @param innerDw Width of app window. * @param innerDh Height of app window. */ diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index f1f61f3..3b62b61 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -211,6 +211,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_SMS); DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_FUN); DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_SAFE_BOOT); + DEVICE_OWNER_USER_RESTRICTIONS.add(UserManager.DISALLOW_CREATE_WINDOWS); } // The following user restrictions cannot be changed by any active admin, including device diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 75b8278..3767fce 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -981,7 +981,7 @@ public class UsageStatsService extends SystemService implements } } - private class BinderService extends IUsageStatsManager.Stub { + private final class BinderService extends IUsageStatsManager.Stub { private boolean hasPermission(String callingPackage) { final int callingUid = Binder.getCallingUid(); @@ -1121,7 +1121,7 @@ public class UsageStatsService extends SystemService implements * ActivityManagerService will call these methods holding the 'am' lock, which means we * shouldn't be doing any IO work or other long running tasks in these methods. */ - private class LocalService extends UsageStatsManagerInternal { + private final class LocalService extends UsageStatsManagerInternal { @Override public void reportEvent(ComponentName component, int userId, int eventType) { diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 3f78497..0eb94b8 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -182,6 +182,34 @@ public class CarrierConfigManager { public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool"; + /** + * Override the platform's notion of a network operator being considered roaming. + * Value is string array of MCCMNCs to be considered roaming for 3GPP RATs. + */ + public static final String + KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array"; + + /** + * Override the platform's notion of a network operator being considered not roaming. + * Value is string array of MCCMNCs to be considered not roaming for 3GPP RATs. + */ + public static final String + KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY = "gsm_nonroaming_networks_string_array"; + + /** + * Override the platform's notion of a network operator being considered roaming. + * Value is string array of SIDs to be considered roaming for 3GPP2 RATs. + */ + public static final String + KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array"; + + /** + * Override the platform's notion of a network operator being considered non roaming. + * Value is string array of SIDs to be considered not roaming for 3GPP2 RATs. + */ + public static final String + KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array"; + /** * Flag specifying whether VoLTE should be available for carrier, independent of carrier * provisioning. If false: hard disabled. If true: then depends on carrier provisioning, @@ -358,6 +386,11 @@ public class CarrierConfigManager { sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING, ""); sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING, ""); + sDefaults.putStringArray(KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, null); + sDefaults.putStringArray(KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY, null); + sDefaults.putStringArray(KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY, null); + sDefaults.putStringArray(KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY, null); + // MMS defaults sDefaults.putBoolean(KEY_MMS_ALIAS_ENABLED_BOOL, false); sDefaults.putBoolean(KEY_MMS_ALLOW_ATTACH_AUDIO_BOOL, true); diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java index 674777e..8443490 100644 --- a/telephony/java/android/telephony/DisconnectCause.java +++ b/telephony/java/android/telephony/DisconnectCause.java @@ -153,17 +153,17 @@ public class DisconnectCause { /** * The outgoing call failed with an unknown cause. */ - public static final int OUTGOING_FAILURE = 43; + public static final int OUTGOING_FAILURE = 43; /** * The outgoing call was canceled by the {@link android.telecom.ConnectionService}. */ - public static final int OUTGOING_CANCELED = 44; + public static final int OUTGOING_CANCELED = 44; /** * The call, which was an IMS call, disconnected because it merged with another call. */ - public static final int IMS_MERGED_SUCCESSFULLY = 45; + public static final int IMS_MERGED_SUCCESSFULLY = 45; /** * Stk Call Control modified DIAL request to USSD request. @@ -181,6 +181,12 @@ public class DisconnectCause { */ public static final int DIAL_MODIFIED_TO_DIAL = 48; + /** + * The call was terminated because CDMA phone service and roaming have already been activated. + * {@hide} + */ + public static final int CDMA_ALREADY_ACTIVATED = 49; + //********************************************************************************************* // When adding a disconnect type: // 1) Please assign the new type the next id value below. @@ -189,14 +195,14 @@ public class DisconnectCause { // 4) Update toString() with the newly added disconnect type. // 5) Update android.telecom.DisconnectCauseUtil with any mappings to a telecom.DisconnectCause. // - // NextId: 49 + // NextId: 50 //********************************************************************************************* /** Smallest valid value for call disconnect codes. */ public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED; /** Largest valid value for call disconnect codes. */ - public static final int MAXIMUM_VALID_VALUE = DIAL_MODIFIED_TO_DIAL; + public static final int MAXIMUM_VALID_VALUE = CDMA_ALREADY_ACTIVATED; /** Private constructor to avoid class instantiation. */ private DisconnectCause() { @@ -302,6 +308,8 @@ public class DisconnectCause { return "OUTGOING_CANCELED"; case IMS_MERGED_SUCCESSFULLY: return "IMS_MERGED_SUCCESSFULLY"; + case CDMA_ALREADY_ACTIVATED: + return "CDMA_ALREADY_ACTIVATED"; default: return "INVALID: " + cause; } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index e085d89..fa1ed54 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -1124,13 +1124,14 @@ public class SubscriptionManager { * {@hide} */ public static int getSimStateForSlotIdx(int slotIdx) { - int simState; + int simState = TelephonyManager.SIM_STATE_UNKNOWN; try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); - simState = iSub.getSimStateForSlotIdx(slotIdx); + if (iSub != null) { + simState = iSub.getSimStateForSlotIdx(slotIdx); + } } catch (RemoteException ex) { - simState = TelephonyManager.SIM_STATE_UNKNOWN; } logd("getSimStateForSubscriber: simState=" + simState + " slotIdx=" + slotIdx); return simState; @@ -1144,7 +1145,9 @@ public class SubscriptionManager { public boolean isActiveSubId(int subId) { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); - return iSub.isActiveSubId(subId); + if (iSub != null) { + return iSub.isActiveSubId(subId); + } } catch (RemoteException ex) { } return false; diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java index 04ded9d..e5e3e44 100644 --- a/test-runner/src/android/test/mock/MockContext.java +++ b/test-runner/src/android/test/mock/MockContext.java @@ -16,6 +16,7 @@ package android.test.mock; +import android.annotation.SystemApi; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -317,6 +318,13 @@ public class MockContext extends Context { } /** @hide */ + @SystemApi + @Override + public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) { + throw new UnsupportedOperationException(); + } + + /** @hide */ @Override public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { throw new UnsupportedOperationException(); @@ -336,6 +344,15 @@ public class MockContext extends Context { } /** @hide */ + @SystemApi + @Override + public void sendOrderedBroadcast(Intent intent, String receiverPermission, + Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, + Bundle initialExtras) { + throw new UnsupportedOperationException(); + } + + /** @hide */ @Override public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml index d282fc9..0f3fb95 100644 --- a/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml +++ b/tests/VectorDrawableTest/res/drawable/vector_drawable04.xml @@ -13,37 +13,41 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="64dp" - android:height="64dp" - android:viewportWidth="7.30625" - android:viewportHeight="12.25" - android:autoMirrored="true"> + android:autoMirrored="true" + android:height="64dp" + android:viewportHeight="12.25" + android:viewportWidth="7.30625" + android:width="64dp" > <group> <clip-path - android:name="clip1" - android:pathData=" + android:name="clip1" + android:pathData=" M 3.65, 6.125 m-.001, 0 a .001,.001 0 1,0 .002,0 - a .001,.001 0 1,0-.002,0z"/> + a .001,.001 0 1,0-.002,0z" /> + <path - android:name="one" - android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125 + android:name="one" + android:fillColor="#ff88ff" + android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875-2.109375,0.421875 0.0-1.078125 l 2.09375-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0 - l-5.046875,0.0 0.0-1.0Z" - android:fillColor="#ff88ff"/> - + l-5.046875,0.0 0.0-1.0Z" /> + </group> + <group> <clip-path - android:name="clip2" - android:pathData=" + android:name="clip2" + android:pathData=" M 3.65, 6.125 m-6, 0 a 6,6 0 1,0 12,0 - a 6,6 0 1,0-12,0z"/> + a 6,6 0 1,0-12,0z" /> + <path - android:name="two" - android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375 + android:name="two" + android:fillColor="#ff88ff" + android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375 q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625 q 0.234375-0.453125 0.234375-0.875 0.0-0.703125-0.5-1.140625 q-0.484375-0.4375-1.2656252-0.4375-0.5625,0.0-1.1875,0.1875 @@ -51,7 +55,7 @@ q 0.625-0.15625 1.140625-0.15625 1.3593752,0.0 2.1718752,0.6875 q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125-0.203125,1.015625 q-0.203125,0.484375-0.734375,1.140625-0.15625,0.171875-0.9375,0.984375 - q-0.78125024,0.8125-2.2187502,2.265625Z" - android:fillColor="#ff88ff"/> + q-0.78125024,0.8125-2.2187502,2.265625Z" /> </group> -</vector> + +</vector>
\ No newline at end of file diff --git a/tools/aapt2/BinaryResourceParser.cpp b/tools/aapt2/BinaryResourceParser.cpp index 3559f43..4f1947a 100644 --- a/tools/aapt2/BinaryResourceParser.cpp +++ b/tools/aapt2/BinaryResourceParser.cpp @@ -116,9 +116,11 @@ private: BinaryResourceParser::BinaryResourceParser(const std::shared_ptr<ResourceTable>& table, const std::shared_ptr<IResolver>& resolver, const Source& source, + const std::u16string& defaultPackage, const void* data, size_t len) : - mTable(table), mResolver(resolver), mSource(source), mData(data), mDataLen(len) { + mTable(table), mResolver(resolver), mSource(source), mDefaultPackage(defaultPackage), + mData(data), mDataLen(len) { } bool BinaryResourceParser::parse() { @@ -177,6 +179,9 @@ bool BinaryResourceParser::getSymbol(const void* data, ResourceNameRef* outSymbo if (!type) { return false; } + if (outSymbol->package.empty()) { + outSymbol->package = mTable->getPackage(); + } outSymbol->type = *type; // Since we scan the symbol table in order, we can start looking for the @@ -350,7 +355,22 @@ bool BinaryResourceParser::parsePackage(const ResChunk_header* chunk) { size_t len = strnlen16(reinterpret_cast<const char16_t*>(packageHeader->name), sizeof(packageHeader->name) / sizeof(packageHeader->name[0])); - mTable->setPackage(StringPiece16(reinterpret_cast<const char16_t*>(packageHeader->name), len)); + if (mTable->getPackage().empty() && len == 0) { + mTable->setPackage(mDefaultPackage); + } else if (len > 0) { + StringPiece16 thisPackage(reinterpret_cast<const char16_t*>(packageHeader->name), len); + if (mTable->getPackage().empty()) { + mTable->setPackage(thisPackage); + } else if (thisPackage != mTable->getPackage()) { + Logger::error(mSource) + << "incompatible packages: " + << mTable->getPackage() + << " vs. " + << thisPackage + << std::endl; + return false; + } + } ResChunkPullParser parser(getChunkData(packageHeader->header), getChunkDataLen(packageHeader->header)); diff --git a/tools/aapt2/BinaryResourceParser.h b/tools/aapt2/BinaryResourceParser.h index 32876cd..3aab301 100644 --- a/tools/aapt2/BinaryResourceParser.h +++ b/tools/aapt2/BinaryResourceParser.h @@ -45,6 +45,7 @@ public: BinaryResourceParser(const std::shared_ptr<ResourceTable>& table, const std::shared_ptr<IResolver>& resolver, const Source& source, + const std::u16string& defaultPackage, const void* data, size_t len); BinaryResourceParser(const BinaryResourceParser&) = delete; // No copy. @@ -97,12 +98,12 @@ private: const Source mSource; + // The package name of the resource table. + std::u16string mDefaultPackage; + const void* mData; const size_t mDataLen; - // The package name of the resource table. - std::u16string mPackage; - // The array of symbol entries. Each element points to an offset // in the table and an index into the symbol table string pool. const SymbolTable_entry* mSymbolEntries = nullptr; diff --git a/tools/aapt2/Linker.cpp b/tools/aapt2/Linker.cpp index f3f04a5..c37cc93 100644 --- a/tools/aapt2/Linker.cpp +++ b/tools/aapt2/Linker.cpp @@ -160,7 +160,7 @@ const Attribute* Linker::doResolveAttribute(Reference& attribute, const SourceLi void Linker::visit(Reference& reference, ValueVisitorArgs& a) { Args& args = static_cast<Args&>(a); - if (!reference.name.isValid()) { + if (reference.name.entry.empty()) { // We can't have a completely bad reference. if (!reference.id.isValid()) { Logger::error() << "srsly? " << args.referrer << std::endl; diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 41c229d..54a7329 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -756,8 +756,8 @@ bool link(const AaptOptions& options, const std::shared_ptr<ResourceTable>& outT zipFile->uncompress(entry)); assert(uncompressedData); - BinaryResourceParser parser(table, resolver, source, uncompressedData.get(), - entry->getUncompressedLen()); + BinaryResourceParser parser(table, resolver, source, options.appInfo.package, + uncompressedData.get(), entry->getUncompressedLen()); if (!parser.parse()) { return false; } @@ -1085,50 +1085,47 @@ static AaptOptions prepareArgs(int argc, char** argv) { } bool isStaticLib = false; + if (options.phase == AaptOptions::Phase::Link) { + flag::requiredFlag("--manifest", "AndroidManifest.xml of your app", + [&options](const StringPiece& arg) { + options.manifest = Source{ arg.toString() }; + }); + + flag::optionalFlag("-I", "add an Android APK to link against", + [&options](const StringPiece& arg) { + options.libraries.push_back(Source{ arg.toString() }); + }); + + flag::optionalFlag("--java", "directory in which to generate R.java", + [&options](const StringPiece& arg) { + options.generateJavaClass = Source{ arg.toString() }; + }); + + flag::optionalFlag("--proguard", "file in which to output proguard rules", + [&options](const StringPiece& arg) { + options.generateProguardRules = Source{ arg.toString() }; + }); + + flag::optionalSwitch("--static-lib", "generate a static Android library", true, + &isStaticLib); + + flag::optionalFlag("--binding", "Output directory for binding XML files", + [&options](const StringPiece& arg) { + options.bindingOutput = Source{ arg.toString() }; + }); + flag::optionalSwitch("--no-version", "Disables automatic style and layout versioning", + false, &options.versionStylesAndLayouts); + } + if (options.phase == AaptOptions::Phase::Compile || options.phase == AaptOptions::Phase::Link) { - if (options.phase == AaptOptions::Phase::Compile) { - flag::requiredFlag("--package", "Android package name", - [&options](const StringPiece& arg) { - options.appInfo.package = util::utf8ToUtf16(arg); - }); - } else if (options.phase == AaptOptions::Phase::Link) { - flag::requiredFlag("--manifest", "AndroidManifest.xml of your app", - [&options](const StringPiece& arg) { - options.manifest = Source{ arg.toString() }; - }); - - flag::optionalFlag("-I", "add an Android APK to link against", - [&options](const StringPiece& arg) { - options.libraries.push_back(Source{ arg.toString() }); - }); - - flag::optionalFlag("--java", "directory in which to generate R.java", - [&options](const StringPiece& arg) { - options.generateJavaClass = Source{ arg.toString() }; - }); - - flag::optionalFlag("--proguard", "file in which to output proguard rules", - [&options](const StringPiece& arg) { - options.generateProguardRules = Source{ arg.toString() }; - }); - - flag::optionalSwitch("--static-lib", "generate a static Android library", true, - &isStaticLib); - - flag::optionalFlag("--binding", "Output directory for binding XML files", - [&options](const StringPiece& arg) { - options.bindingOutput = Source{ arg.toString() }; - }); - flag::optionalSwitch("--no-version", "Disables automatic style and layout versioning", - false, &options.versionStylesAndLayouts); - } - // Common flags for all steps. flag::requiredFlag("-o", "Output path", [&options](const StringPiece& arg) { options.output = Source{ arg.toString() }; }); - } else if (options.phase == AaptOptions::Phase::DumpStyleGraph) { + } + + if (options.phase == AaptOptions::Phase::DumpStyleGraph) { flag::requiredFlag("--style", "Name of the style to dump", [&options](const StringPiece& arg, std::string* outError) -> bool { Reference styleReference; @@ -1191,7 +1188,7 @@ static bool doDump(const AaptOptions& options) { zipFile->uncompress(entry)); assert(uncompressedData); - BinaryResourceParser parser(table, resolver, source, uncompressedData.get(), + BinaryResourceParser parser(table, resolver, source, {}, uncompressedData.get(), entry->getUncompressedLen()); if (!parser.parse()) { return false; @@ -1223,16 +1220,17 @@ int main(int argc, char** argv) { if (!loadAppInfo(options.manifest, &options.appInfo)) { return false; } - } - // Verify we have some common options set. - if (options.appInfo.package.empty()) { - Logger::error() << "no package name specified." << std::endl; - return false; + if (options.appInfo.package.empty()) { + Logger::error() << "no package name specified." << std::endl; + return false; + } } // Every phase needs a resource table. std::shared_ptr<ResourceTable> table = std::make_shared<ResourceTable>(); + + // The package name is empty when in the compile phase. table->setPackage(options.appInfo.package); if (options.appInfo.package == u"android") { table->setPackageId(0x01); diff --git a/tools/aapt2/TableFlattener.cpp b/tools/aapt2/TableFlattener.cpp index 539c48f..b7c04f0 100644 --- a/tools/aapt2/TableFlattener.cpp +++ b/tools/aapt2/TableFlattener.cpp @@ -79,7 +79,7 @@ public: // Write the key. if (!Res_INTERNALID(key.id.id) && !key.id.isValid()) { - assert(key.name.isValid()); + assert(!key.name.entry.empty()); mSymbols->push_back(std::make_pair(ResourceNameRef(key.name), mOut->size() - sizeof(*outMapEntry))); } @@ -284,13 +284,6 @@ bool TableFlattener::flattenValue(BigBuffer* out, const FlatEntry& flatEntry, bool TableFlattener::flatten(BigBuffer* out, const ResourceTable& table) { const size_t beginning = out->size(); - if (table.getPackage().size() == 0) { - Logger::error() - << "ResourceTable has no package name." - << std::endl; - return false; - } - if (table.getPackageId() == ResourceTable::kUnsetPackageId) { Logger::error() << "ResourceTable has no package ID set." diff --git a/tools/aapt2/data/Makefile b/tools/aapt2/data/Makefile index 3387135..91ff5fe 100644 --- a/tools/aapt2/data/Makefile +++ b/tools/aapt2/data/Makefile @@ -50,7 +50,7 @@ $(info PRIVATE_INTERMEDIATE_TABLES = $(PRIVATE_INTERMEDIATE_TABLES)) # returns: out/values-v4.apk: res/values-v4/styles.xml res/values-v4/colors.xml define make-collect-rule $(LOCAL_OUT)/$1.apk: $(filter $(LOCAL_RESOURCE_DIR)/$1/%,$(PRIVATE_RESOURCES)) - $(AAPT) compile --package $(LOCAL_PACKAGE) -o $$@ $$^ + $(AAPT) compile -o $$@ $$^ endef # Collect: out/values-v4.apk <- res/values-v4/styles.xml res/values-v4/colors.xml diff --git a/tools/aapt2/data/lib/Makefile b/tools/aapt2/data/lib/Makefile index 372c225..741be9a 100644 --- a/tools/aapt2/data/lib/Makefile +++ b/tools/aapt2/data/lib/Makefile @@ -48,7 +48,7 @@ $(info PRIVATE_INTERMEDIATE_TABLES = $(PRIVATE_INTERMEDIATE_TABLES)) # returns: out/values-v4.apk: res/values-v4/styles.xml res/values-v4/colors.xml define make-collect-rule $(LOCAL_OUT)/$1.apk: $(filter $(LOCAL_RESOURCE_DIR)/$1/%,$(PRIVATE_RESOURCES)) - $(AAPT) compile --package $(LOCAL_PACKAGE) -o $$@ $$^ + $(AAPT) compile -o $$@ $$^ endef # Collect: out/values-v4.apk <- res/values-v4/styles.xml res/values-v4/colors.xml diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index 6be5a95..422b2aa 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -1506,6 +1506,12 @@ public final class BridgeContext extends Context { } @Override + public void sendBroadcast(Intent arg0, String arg1, Bundle arg2) { + // pass + + } + + @Override public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { // pass } @@ -1525,6 +1531,14 @@ public final class BridgeContext extends Context { } @Override + public void sendOrderedBroadcast(Intent arg0, String arg1, + Bundle arg7, BroadcastReceiver arg2, Handler arg3, int arg4, String arg5, + Bundle arg6) { + // pass + + } + + @Override public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { |
