diff options
46 files changed, 568 insertions, 226 deletions
diff --git a/api/current.txt b/api/current.txt index 4c069cd1afa1..936ca882ce14 100644 --- a/api/current.txt +++ b/api/current.txt @@ -10101,27 +10101,22 @@ package android.content.res { method public final long skip(long) throws java.io.IOException; } - public class ColorStateList extends android.content.res.ComplexColor implements android.os.Parcelable { + public class ColorStateList implements android.os.Parcelable { ctor public ColorStateList(int[][], int[]); method public static deprecated android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public int describeContents(); + method public int getChangingConfigurations(); method public int getColorForState(int[], int); method public int getDefaultColor(); method public boolean isOpaque(); + method public boolean isStateful(); method public static android.content.res.ColorStateList valueOf(int); method public android.content.res.ColorStateList withAlpha(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.content.res.ColorStateList> CREATOR; } - public abstract class ComplexColor { - ctor public ComplexColor(); - method public int getChangingConfigurations(); - method public abstract int getDefaultColor(); - method public boolean isStateful(); - } - public final class Configuration implements java.lang.Comparable android.os.Parcelable { ctor public Configuration(); ctor public Configuration(android.content.res.Configuration); @@ -10225,11 +10220,6 @@ package android.content.res { field public int uiMode; } - public class GradientColor extends android.content.res.ComplexColor { - method public static android.content.res.GradientColor createFromXml(android.content.res.Resources, android.content.res.XmlResourceParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; - method public int getDefaultColor(); - } - public class ObbInfo implements android.os.Parcelable { method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); @@ -10289,7 +10279,6 @@ package android.content.res { method public void getValue(java.lang.String, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException; method public void getValueForDensity(int, int, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException; method public android.content.res.XmlResourceParser getXml(int) throws android.content.res.Resources.NotFoundException; - method public android.content.res.ComplexColor loadComplexColor(android.util.TypedValue, int, android.content.res.Resources.Theme); method public final android.content.res.Resources.Theme newTheme(); method public android.content.res.TypedArray obtainAttributes(android.util.AttributeSet, int[]); method public android.content.res.TypedArray obtainTypedArray(int) throws android.content.res.Resources.NotFoundException; @@ -10325,7 +10314,6 @@ package android.content.res { method public int getChangingConfigurations(); method public int getColor(int, int); method public android.content.res.ColorStateList getColorStateList(int); - method public android.content.res.ComplexColor getComplexColor(int); method public float getDimension(int, float); method public int getDimensionPixelOffset(int, int); method public int getDimensionPixelSize(int, int); @@ -36719,11 +36707,10 @@ package android.telephony { method public void notifyConfigChanged(int); method public deprecated void notifyConfigChangedForSubId(int); field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED"; - field public static final java.lang.String BOOL_ALLOW_EMERGENCY_VIDEO_CALLS = "bool_allow_emergency_video_calls"; - field public static final java.lang.String BOOL_ALLOW_VIDEO_PAUSE = "bool_allow_video_pause"; field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool"; field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool"; field public static final java.lang.String KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool"; + field public static final java.lang.String KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL = "allow_emergency_video_calls_bool"; field public static final java.lang.String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool"; field public static final java.lang.String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool"; field public static final java.lang.String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool"; @@ -39766,8 +39753,10 @@ package android.text.util { method public static final boolean addLinks(android.widget.TextView, int); method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String); method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); + method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String); method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); + method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); field public static final int ALL = 15; // 0xf field public static final int EMAIL_ADDRESSES = 2; // 0x2 field public static final int MAP_ADDRESSES = 8; // 0x8 diff --git a/api/system-current.txt b/api/system-current.txt index 1ed7ac2ec6be..f8863e53d8ba 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -10499,27 +10499,22 @@ package android.content.res { method public final long skip(long) throws java.io.IOException; } - public class ColorStateList extends android.content.res.ComplexColor implements android.os.Parcelable { + public class ColorStateList implements android.os.Parcelable { ctor public ColorStateList(int[][], int[]); method public static deprecated android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public int describeContents(); + method public int getChangingConfigurations(); method public int getColorForState(int[], int); method public int getDefaultColor(); method public boolean isOpaque(); + method public boolean isStateful(); method public static android.content.res.ColorStateList valueOf(int); method public android.content.res.ColorStateList withAlpha(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.content.res.ColorStateList> CREATOR; } - public abstract class ComplexColor { - ctor public ComplexColor(); - method public int getChangingConfigurations(); - method public abstract int getDefaultColor(); - method public boolean isStateful(); - } - public final class Configuration implements java.lang.Comparable android.os.Parcelable { ctor public Configuration(); ctor public Configuration(android.content.res.Configuration); @@ -10623,11 +10618,6 @@ package android.content.res { field public int uiMode; } - public class GradientColor extends android.content.res.ComplexColor { - method public static android.content.res.GradientColor createFromXml(android.content.res.Resources, android.content.res.XmlResourceParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; - method public int getDefaultColor(); - } - public class ObbInfo implements android.os.Parcelable { method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); @@ -10687,7 +10677,6 @@ package android.content.res { method public void getValue(java.lang.String, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException; method public void getValueForDensity(int, int, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException; method public android.content.res.XmlResourceParser getXml(int) throws android.content.res.Resources.NotFoundException; - method public android.content.res.ComplexColor loadComplexColor(android.util.TypedValue, int, android.content.res.Resources.Theme); method public final android.content.res.Resources.Theme newTheme(); method public android.content.res.TypedArray obtainAttributes(android.util.AttributeSet, int[]); method public android.content.res.TypedArray obtainTypedArray(int) throws android.content.res.Resources.NotFoundException; @@ -10723,7 +10712,6 @@ package android.content.res { method public int getChangingConfigurations(); method public int getColor(int, int); method public android.content.res.ColorStateList getColorStateList(int); - method public android.content.res.ComplexColor getComplexColor(int); method public float getDimension(int, float); method public int getDimensionPixelOffset(int, int); method public int getDimensionPixelSize(int, int); @@ -39380,11 +39368,10 @@ package android.telephony { method public deprecated void notifyConfigChangedForSubId(int); method public void updateConfigForPhoneId(int, java.lang.String); field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED"; - field public static final java.lang.String BOOL_ALLOW_EMERGENCY_VIDEO_CALLS = "bool_allow_emergency_video_calls"; - field public static final java.lang.String BOOL_ALLOW_VIDEO_PAUSE = "bool_allow_video_pause"; field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool"; field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool"; field public static final java.lang.String KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool"; + field public static final java.lang.String KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL = "allow_emergency_video_calls_bool"; field public static final java.lang.String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool"; field public static final java.lang.String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool"; field public static final java.lang.String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool"; @@ -42491,8 +42478,10 @@ package android.text.util { method public static final boolean addLinks(android.widget.TextView, int); method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String); method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); + method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String); method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); + method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); field public static final int ALL = 15; // 0xf field public static final int EMAIL_ADDRESSES = 2; // 0x2 field public static final int MAP_ADDRESSES = 8; // 0x8 diff --git a/api/test-current.txt b/api/test-current.txt index c0f551a83039..6327dc2200d1 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -10111,27 +10111,22 @@ package android.content.res { method public final long skip(long) throws java.io.IOException; } - public class ColorStateList extends android.content.res.ComplexColor implements android.os.Parcelable { + public class ColorStateList implements android.os.Parcelable { ctor public ColorStateList(int[][], int[]); method public static deprecated android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public int describeContents(); + method public int getChangingConfigurations(); method public int getColorForState(int[], int); method public int getDefaultColor(); method public boolean isOpaque(); + method public boolean isStateful(); method public static android.content.res.ColorStateList valueOf(int); method public android.content.res.ColorStateList withAlpha(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.content.res.ColorStateList> CREATOR; } - public abstract class ComplexColor { - ctor public ComplexColor(); - method public int getChangingConfigurations(); - method public abstract int getDefaultColor(); - method public boolean isStateful(); - } - public final class Configuration implements java.lang.Comparable android.os.Parcelable { ctor public Configuration(); ctor public Configuration(android.content.res.Configuration); @@ -10235,11 +10230,6 @@ package android.content.res { field public int uiMode; } - public class GradientColor extends android.content.res.ComplexColor { - method public static android.content.res.GradientColor createFromXml(android.content.res.Resources, android.content.res.XmlResourceParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; - method public int getDefaultColor(); - } - public class ObbInfo implements android.os.Parcelable { method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); @@ -10299,7 +10289,6 @@ package android.content.res { method public void getValue(java.lang.String, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException; method public void getValueForDensity(int, int, android.util.TypedValue, boolean) throws android.content.res.Resources.NotFoundException; method public android.content.res.XmlResourceParser getXml(int) throws android.content.res.Resources.NotFoundException; - method public android.content.res.ComplexColor loadComplexColor(android.util.TypedValue, int, android.content.res.Resources.Theme); method public final android.content.res.Resources.Theme newTheme(); method public android.content.res.TypedArray obtainAttributes(android.util.AttributeSet, int[]); method public android.content.res.TypedArray obtainTypedArray(int) throws android.content.res.Resources.NotFoundException; @@ -10335,7 +10324,6 @@ package android.content.res { method public int getChangingConfigurations(); method public int getColor(int, int); method public android.content.res.ColorStateList getColorStateList(int); - method public android.content.res.ComplexColor getComplexColor(int); method public float getDimension(int, float); method public int getDimensionPixelOffset(int, int); method public int getDimensionPixelSize(int, int); @@ -36790,11 +36778,10 @@ package android.telephony { method public void notifyConfigChanged(int); method public deprecated void notifyConfigChangedForSubId(int); field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED"; - field public static final java.lang.String BOOL_ALLOW_EMERGENCY_VIDEO_CALLS = "bool_allow_emergency_video_calls"; - field public static final java.lang.String BOOL_ALLOW_VIDEO_PAUSE = "bool_allow_video_pause"; field public static final java.lang.String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool"; field public static final java.lang.String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool"; field public static final java.lang.String KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool"; + field public static final java.lang.String KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL = "allow_emergency_video_calls_bool"; field public static final java.lang.String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool"; field public static final java.lang.String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool"; field public static final java.lang.String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = "always_show_emergency_alert_onoff_bool"; @@ -39839,8 +39826,10 @@ package android.text.util { method public static final boolean addLinks(android.widget.TextView, int); method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String); method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); + method public static final void addLinks(android.widget.TextView, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String); method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); + method public static final boolean addLinks(android.text.Spannable, java.util.regex.Pattern, java.lang.String, java.lang.String[], android.text.util.Linkify.MatchFilter, android.text.util.Linkify.TransformFilter); field public static final int ALL = 15; // 0xf field public static final int EMAIL_ADDRESSES = 2; // 0x2 field public static final int MAP_ADDRESSES = 8; // 0x8 diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index e6c576825e67..86734b1c222c 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -1814,7 +1814,7 @@ public class Am extends BaseCommand { private void resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate) { try { - mAm.resizeStack(stackId, bounds, false, false, animate); + mAm.resizeStack(stackId, bounds, false, false, animate, -1); Thread.sleep(delayMs); } catch (RemoteException e) { showError("Error: resizing stack " + e); diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index ddc5b0c7eb08..bf823f8d960f 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -406,7 +406,9 @@ public abstract class AccessibilityService extends Service { /** * Callback for {@link android.view.accessibility.AccessibilityEvent}s. * - * @param event An event. + * @param event The new event. This event is owned by the caller and cannot be used after + * this method returns. Services wishing to use the event after this method returns should + * make a copy. */ public abstract void onAccessibilityEvent(AccessibilityEvent event); @@ -493,7 +495,9 @@ public abstract class AccessibilityService extends Service { * functionality. * <p> * - * @param event The event to be processed. + * @param event The event to be processed. This event is owned by the caller and cannot be used + * after this method returns. Services wishing to use the event after this method returns should + * make a copy. * @return If true then the event will be consumed and not delivered to * applications, otherwise it will be delivered as usual. */ diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 5f317b0849c7..f5d7e7e068cf 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -820,7 +820,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM final boolean allowResizeInDockedMode = data.readInt() == 1; final boolean preserveWindows = data.readInt() == 1; final boolean animate = data.readInt() == 1; - resizeStack(stackId, r, allowResizeInDockedMode, preserveWindows, animate); + final int animationDuration = data.readInt(); + resizeStack(stackId, + r, allowResizeInDockedMode, preserveWindows, animate, animationDuration); reply.writeNoException(); return true; } @@ -3889,7 +3891,8 @@ class ActivityManagerProxy implements IActivityManager } @Override public void resizeStack(int stackId, Rect r, boolean allowResizeInDockedMode, - boolean preserveWindows, boolean animate) throws RemoteException { + boolean preserveWindows, boolean animate, int animationDuration) + throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); @@ -3903,6 +3906,7 @@ class ActivityManagerProxy implements IActivityManager data.writeInt(allowResizeInDockedMode ? 1 : 0); data.writeInt(preserveWindows ? 1 : 0); data.writeInt(animate ? 1 : 0); + data.writeInt(animationDuration); mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index d0c21f5ad011..639c207ec6d9 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -148,8 +148,23 @@ public interface IActivityManager extends IInterface { public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate, Rect initialBounds) throws RemoteException; public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) throws RemoteException; + + /** + * Resizes the input stack id to the given bounds. + * + * @param stackId Id of the stack to resize. + * @param bounds Bounds to resize the stack to or {@code null} for fullscreen. + * @param allowResizeInDockedMode True if the resize should be allowed when the docked stack is + * active. + * @param preserveWindows True if the windows of activities contained in the stack should be + * preserved. + * @param animate True if the stack resize should be animated. + * @param animationDuration The duration of the resize animation in milliseconds or -1 if the + * default animation duration should be used. + * @throws RemoteException + */ public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode, - boolean preserveWindows, boolean animate) throws RemoteException; + boolean preserveWindows, boolean animate, int animationDuration) throws RemoteException; /** * Moves all tasks from the docked stack in the fullscreen stack and puts the top task of the diff --git a/core/java/android/content/res/ComplexColor.java b/core/java/android/content/res/ComplexColor.java index b297764629cf..58c6fc5174d3 100644 --- a/core/java/android/content/res/ComplexColor.java +++ b/core/java/android/content/res/ComplexColor.java @@ -23,6 +23,7 @@ import android.graphics.Color; /** * Defines an abstract class for the complex color information, like * {@link android.content.res.ColorStateList} or {@link android.content.res.GradientColor} + * @hide */ public abstract class ComplexColor { private int mChangingConfigurations; diff --git a/core/java/android/content/res/GradientColor.java b/core/java/android/content/res/GradientColor.java index f29656abe6c3..c49c4b28a413 100644 --- a/core/java/android/content/res/GradientColor.java +++ b/core/java/android/content/res/GradientColor.java @@ -68,6 +68,7 @@ import java.lang.annotation.RetentionPolicy; * * Also note if any color "item" element is defined, then startColor, centerColor and endColor will * be ignored. + * @hide */ public class GradientColor extends ComplexColor { private static final String TAG = "GradientColor"; diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index fb706fcb3c94..387fda717e48 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -999,6 +999,9 @@ public class Resources { return mResourcesImpl.loadColorStateList(this, value, id, theme); } + /** + * @hide + */ @Nullable public ComplexColor loadComplexColor(@NonNull TypedValue value, int id, @Nullable Theme theme) { return mResourcesImpl.loadComplexColor(this, value, id, theme); diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index f6ac0bac125a..92134ee01de8 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -475,6 +475,7 @@ public class TypedArray { * been recycled. * @throws UnsupportedOperationException if the attribute is defined but is * not an integer color, color state list or GradientColor. + * @hide */ @Nullable public ComplexColor getComplexColor(@StyleableRes int index) { diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java index bd376ead2334..ca037a229b0a 100644 --- a/core/java/android/text/util/Linkify.java +++ b/core/java/android/text/util/Linkify.java @@ -16,6 +16,9 @@ package android.text.util; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.telephony.PhoneNumberUtils; import android.text.method.LinkMovementMethod; import android.text.method.MovementMethod; @@ -29,6 +32,8 @@ import android.widget.TextView; import java.io.UnsupportedEncodingException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collections; @@ -41,19 +46,21 @@ import com.android.i18n.phonenumbers.PhoneNumberMatch; import com.android.i18n.phonenumbers.PhoneNumberUtil; import com.android.i18n.phonenumbers.PhoneNumberUtil.Leniency; +import libcore.util.EmptyArray; + /** * Linkify take a piece of text and a regular expression and turns all of the * regex matches in the text into clickable links. This is particularly - * useful for matching things like email addresses, web urls, etc. and making + * useful for matching things like email addresses, web URLs, etc. and making * them actionable. * - * Alone with the pattern that is to be matched, a url scheme prefix is also + * Alone with the pattern that is to be matched, a URL scheme prefix is also * required. Any pattern match that does not begin with the supplied scheme - * will have the scheme prepended to the matched text when the clickable url - * is created. For instance, if you are matching web urls you would supply - * the scheme <code>http://</code>. If the pattern matches example.com, which - * does not have a url scheme prefix, the supplied scheme will be prepended to - * create <code>http://example.com</code> when the clickable url link is + * will have the scheme prepended to the matched text when the clickable URL + * is created. For instance, if you are matching web URLs you would supply + * the scheme <code>http://</code>. If the pattern matches example.com, which + * does not have a URL scheme prefix, the supplied scheme will be prepended to + * create <code>http://example.com</code> when the clickable URL link is * created. */ @@ -97,6 +104,11 @@ public class Linkify { */ private static final int PHONE_NUMBER_MINIMUM_DIGITS = 5; + /** @hide */ + @IntDef(flag = true, value = { WEB_URLS, EMAIL_ADDRESSES, PHONE_NUMBERS, MAP_ADDRESSES, ALL }) + @Retention(RetentionPolicy.SOURCE) + public @interface LinkifyMask {} + /** * Filters out web URL matches that occur after an at-sign (@). This is * to prevent turning the domain name in an email address into a web link. @@ -152,10 +164,10 @@ public class Linkify { * MatchFilter enables client code to have more control over * what is allowed to match and become a link, and what is not. * - * For example: when matching web urls you would like things like + * For example: when matching web URLs you would like things like * http://www.example.com to match, as well as just example.com itelf. * However, you would not want to match against the domain in - * support@example.com. So, when matching against a web url pattern you + * support@example.com. So, when matching against a web URL pattern you * might also include a MatchFilter that disallows the match if it is * immediately preceded by an at-sign (@). */ @@ -203,8 +215,13 @@ public class Linkify { * If the mask is nonzero, it also removes any existing URLSpans * attached to the Spannable, to avoid problems if you call it * repeatedly on the same text. + * + * @param text Spannable whose text is to be marked-up with links + * @param mask Mask to define which kinds of links will be searched. + * + * @return True if at least one link is found and applied. */ - public static final boolean addLinks(Spannable text, int mask) { + public static final boolean addLinks(@NonNull Spannable text, @LinkifyMask int mask) { if (mask == 0) { return false; } @@ -255,8 +272,13 @@ public class Linkify { * the link types indicated in the mask into clickable links. If matches * are found the movement method for the TextView is set to * LinkMovementMethod. + * + * @param text TextView whose text is to be marked-up with links + * @param mask Mask to define which kinds of links will be searched. + * + * @return True if at least one link is found and applied. */ - public static final boolean addLinks(TextView text, int mask) { + public static final boolean addLinks(@NonNull TextView text, @LinkifyMask int mask) { if (mask == 0) { return false; } @@ -284,7 +306,7 @@ public class Linkify { } } - private static final void addLinkMovementMethod(TextView t) { + private static final void addLinkMovementMethod(@NonNull TextView t) { MovementMethod m = t.getMovementMethod(); if ((m == null) || !(m instanceof LinkMovementMethod)) { @@ -302,12 +324,12 @@ public class Linkify { * * @param text TextView whose text is to be marked-up with links * @param pattern Regex pattern to be used for finding links - * @param scheme Url scheme string (eg <code>http://</code> to be - * prepended to the url of links that do not have - * a scheme specified in the link text + * @param scheme URL scheme string (eg <code>http://</code>) to be + * prepended to the links that do not start with this scheme. */ - public static final void addLinks(TextView text, Pattern pattern, String scheme) { - addLinks(text, pattern, scheme, null, null); + public static final void addLinks(@NonNull TextView text, @NonNull Pattern pattern, + @Nullable String scheme) { + addLinks(text, pattern, scheme, null, null, null); } /** @@ -317,20 +339,45 @@ public class Linkify { * to LinkMovementMethod. * * @param text TextView whose text is to be marked-up with links - * @param p Regex pattern to be used for finding links - * @param scheme Url scheme string (eg <code>http://</code> to be - * prepended to the url of links that do not have - * a scheme specified in the link text + * @param pattern Regex pattern to be used for finding links + * @param scheme URL scheme string (eg <code>http://</code>) to be + * prepended to the links that do not start with this scheme. * @param matchFilter The filter that is used to allow the client code * additional control over which pattern matches are * to be converted into links. */ - public static final void addLinks(TextView text, Pattern p, String scheme, - MatchFilter matchFilter, TransformFilter transformFilter) { - SpannableString s = SpannableString.valueOf(text.getText()); + public static final void addLinks(@NonNull TextView text, @NonNull Pattern pattern, + @Nullable String scheme, @Nullable MatchFilter matchFilter, + @Nullable TransformFilter transformFilter) { + addLinks(text, pattern, scheme, null, matchFilter, transformFilter); + } - if (addLinks(s, p, scheme, matchFilter, transformFilter)) { - text.setText(s); + /** + * Applies a regex to the text of a TextView turning the matches into + * links. If links are found then UrlSpans are applied to the link + * text match areas, and the movement method for the text is changed + * to LinkMovementMethod. + * + * @param text TextView whose text is to be marked-up with links. + * @param pattern Regex pattern to be used for finding links. + * @param defaultScheme The default scheme to be prepended to links if the link does not + * start with one of the <code>schemes</code> given. + * @param schemes Array of schemes (eg <code>http://</code>) to check if the link found + * contains a scheme. Passing a null or empty value means prepend defaultScheme + * to all links. + * @param matchFilter The filter that is used to allow the client code additional control + * over which pattern matches are to be converted into links. + * @param transformFilter Filter to allow the client code to update the link found. + */ + public static final void addLinks(@NonNull TextView text, @NonNull Pattern pattern, + @Nullable String defaultScheme, @Nullable String[] schemes, + @Nullable MatchFilter matchFilter, @Nullable TransformFilter transformFilter) { + SpannableString spannable = SpannableString.valueOf(text.getText()); + + boolean linksAdded = addLinks(spannable, pattern, defaultScheme, schemes, matchFilter, + transformFilter); + if (linksAdded) { + text.setText(spannable); addLinkMovementMethod(text); } } @@ -339,37 +386,72 @@ public class Linkify { * Applies a regex to a Spannable turning the matches into * links. * - * @param text Spannable whose text is to be marked-up with - * links + * @param text Spannable whose text is to be marked-up with links * @param pattern Regex pattern to be used for finding links - * @param scheme Url scheme string (eg <code>http://</code> to be - * prepended to the url of links that do not have - * a scheme specified in the link text + * @param scheme URL scheme string (eg <code>http://</code>) to be + * prepended to the links that do not start with this scheme. */ - public static final boolean addLinks(Spannable text, Pattern pattern, String scheme) { - return addLinks(text, pattern, scheme, null, null); + public static final boolean addLinks(@NonNull Spannable text, @NonNull Pattern pattern, + @Nullable String scheme) { + return addLinks(text, pattern, scheme, null, null, null); } /** - * Applies a regex to a Spannable turning the matches into - * links. + * Applies a regex to a Spannable turning the matches into + * links. * - * @param s Spannable whose text is to be marked-up with - * links - * @param p Regex pattern to be used for finding links - * @param scheme Url scheme string (eg <code>http://</code> to be - * prepended to the url of links that do not have - * a scheme specified in the link text - * @param matchFilter The filter that is used to allow the client code - * additional control over which pattern matches are - * to be converted into links. + * @param spannable Spannable whose text is to be marked-up with links + * @param pattern Regex pattern to be used for finding links + * @param scheme URL scheme string (eg <code>http://</code>) to be + * prepended to the links that do not start with this scheme. + * @param matchFilter The filter that is used to allow the client code + * additional control over which pattern matches are + * to be converted into links. + * @param transformFilter Filter to allow the client code to update the link found. + * + * @return True if at least one link is found and applied. + */ + public static final boolean addLinks(@NonNull Spannable spannable, @NonNull Pattern pattern, + @Nullable String scheme, @Nullable MatchFilter matchFilter, + @Nullable TransformFilter transformFilter) { + return addLinks(spannable, pattern, scheme, null, matchFilter, + transformFilter); + } + + /** + * Applies a regex to a Spannable turning the matches into links. + * + * @param spannable Spannable whose text is to be marked-up with links. + * @param pattern Regex pattern to be used for finding links. + * @param defaultScheme The default scheme to be prepended to links if the link does not + * start with one of the <code>schemes</code> given. + * @param schemes Array of schemes (eg <code>http://</code>) to check if the link found + * contains a scheme. Passing a null or empty value means prepend defaultScheme + * to all links. + * @param matchFilter The filter that is used to allow the client code additional control + * over which pattern matches are to be converted into links. + * @param transformFilter Filter to allow the client code to update the link found. + * + * @return True if at least one link is found and applied. */ - public static final boolean addLinks(Spannable s, Pattern p, - String scheme, MatchFilter matchFilter, - TransformFilter transformFilter) { + public static final boolean addLinks(@NonNull Spannable spannable, @NonNull Pattern pattern, + @Nullable String defaultScheme, @Nullable String[] schemes, + @Nullable MatchFilter matchFilter, @Nullable TransformFilter transformFilter) { + final String[] schemesCopy; + if (defaultScheme == null) defaultScheme = ""; + if (schemes == null || schemes.length < 1) { + schemes = EmptyArray.STRING; + } + + schemesCopy = new String[schemes.length + 1]; + schemesCopy[0] = defaultScheme.toLowerCase(Locale.ROOT); + for (int index = 0; index < schemes.length; index++) { + String scheme = schemes[index]; + schemesCopy[index + 1] = (scheme == null) ? "" : scheme.toLowerCase(Locale.ROOT); + } + boolean hasMatches = false; - String prefix = (scheme == null) ? "" : scheme.toLowerCase(Locale.ROOT); - Matcher m = p.matcher(s); + Matcher m = pattern.matcher(spannable); while (m.find()) { int start = m.start(); @@ -377,14 +459,13 @@ public class Linkify { boolean allowed = true; if (matchFilter != null) { - allowed = matchFilter.acceptMatch(s, start, end); + allowed = matchFilter.acceptMatch(spannable, start, end); } if (allowed) { - String url = makeUrl(m.group(0), new String[] { prefix }, - m, transformFilter); + String url = makeUrl(m.group(0), schemesCopy, m, transformFilter); - applyLink(url, start, end, s); + applyLink(url, start, end, spannable); hasMatches = true; } } @@ -398,22 +479,20 @@ public class Linkify { text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } - private static final String makeUrl(String url, String[] prefixes, - Matcher m, TransformFilter filter) { + private static final String makeUrl(@NonNull String url, @NonNull String[] prefixes, + Matcher matcher, @Nullable TransformFilter filter) { if (filter != null) { - url = filter.transformUrl(m, url); + url = filter.transformUrl(matcher, url); } boolean hasPrefix = false; - + for (int i = 0; i < prefixes.length; i++) { - if (url.regionMatches(true, 0, prefixes[i], 0, - prefixes[i].length())) { + if (url.regionMatches(true, 0, prefixes[i], 0, prefixes[i].length())) { hasPrefix = true; // Fix capitalization if necessary - if (!url.regionMatches(false, 0, prefixes[i], 0, - prefixes[i].length())) { + if (!url.regionMatches(false, 0, prefixes[i], 0, prefixes[i].length())) { url = prefixes[i] + url.substring(prefixes[i].length()); } @@ -421,7 +500,7 @@ public class Linkify { } } - if (!hasPrefix) { + if (!hasPrefix && prefixes.length > 0) { url = prefixes[0] + url; } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index e5ab9715af0d..358648432863 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5020,8 +5020,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (scrollabilityCache.scrollBar == null) { scrollabilityCache.scrollBar = new ScrollBarDrawable(); - scrollabilityCache.scrollBar.setCallback(this); scrollabilityCache.scrollBar.setState(getDrawableState()); + scrollabilityCache.scrollBar.setCallback(this); } final boolean fadeScrollbars = a.getBoolean(R.styleable.View_fadeScrollbars, true); @@ -13295,8 +13295,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (scrollCache.scrollBar == null) { scrollCache.scrollBar = new ScrollBarDrawable(); - scrollCache.scrollBar.setCallback(this); scrollCache.scrollBar.setState(getDrawableState()); + scrollCache.scrollBar.setCallback(this); } if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) { @@ -18049,7 +18049,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // which requires the view set as the callback (us) to recognize the drawable as // belonging to it as per verifyDrawable. mBackground = background; - background.setCallback(this); if (background.isStateful()) { background.setState(getDrawableState()); } @@ -18059,6 +18058,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, applyBackgroundTint(); + // Set callback last, since the view may still be initializing. + background.setCallback(this); + if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) { mPrivateFlags &= ~PFLAG_SKIP_DRAW; requestLayout = true; @@ -18248,7 +18250,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) { mPrivateFlags &= ~PFLAG_SKIP_DRAW; } - foreground.setCallback(this); foreground.setLayoutDirection(getLayoutDirection()); if (foreground.isStateful()) { foreground.setState(getDrawableState()); @@ -18257,6 +18258,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (isAttachedToWindow()) { foreground.setVisible(getWindowVisibility() == VISIBLE && isShown(), false); } + // Set callback last, since the view may still be initializing. + foreground.setCallback(this); } else if ((mViewFlags & WILL_NOT_DRAW) != 0 && mBackground == null) { mPrivateFlags |= PFLAG_SKIP_DRAW; } diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 36e0c77613aa..6a10743c1c56 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -1183,28 +1183,28 @@ public class ListPopupWindow implements ShowableListMenu { } // getMaxAvailableHeight() subtracts the padding, so we put it back - // to get the available height for the whole window - int padding = 0; - Drawable background = mPopup.getBackground(); + // to get the available height for the whole window. + final int padding; + final Drawable background = mPopup.getBackground(); if (background != null) { background.getPadding(mTempRect); padding = mTempRect.top + mTempRect.bottom; - // If we don't have an explicit vertical offset, determine one from the window - // background so that content will line up. + // If we don't have an explicit vertical offset, determine one from + // the window background so that content will line up. if (!mDropDownVerticalOffsetSet) { mDropDownVerticalOffset = -mTempRect.top; } } else { mTempRect.setEmpty(); + padding = 0; } // Max height available on the screen for a popup. - boolean ignoreBottomDecorations = + final boolean ignoreBottomDecorations = mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; final int maxHeight = mPopup.getMaxAvailableHeight( getAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations); - if (mDropDownAlwaysVisible || mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { return maxHeight + padding; } @@ -1213,25 +1213,30 @@ public class ListPopupWindow implements ShowableListMenu { switch (mDropDownWidth) { case ViewGroup.LayoutParams.WRAP_CONTENT: childWidthSpec = MeasureSpec.makeMeasureSpec( - mContext.getResources().getDisplayMetrics().widthPixels - - (mTempRect.left + mTempRect.right), + mContext.getResources().getDisplayMetrics().widthPixels + - (mTempRect.left + mTempRect.right), MeasureSpec.AT_MOST); break; case ViewGroup.LayoutParams.MATCH_PARENT: childWidthSpec = MeasureSpec.makeMeasureSpec( - mContext.getResources().getDisplayMetrics().widthPixels - - (mTempRect.left + mTempRect.right), + mContext.getResources().getDisplayMetrics().widthPixels + - (mTempRect.left + mTempRect.right), MeasureSpec.EXACTLY); break; default: childWidthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.EXACTLY); break; } + + // Add padding only if the list has items in it, that way we don't show + // the popup if it is not needed. final int listContent = mDropDownList.measureHeightOfChildren(childWidthSpec, - 0, ListView.NO_POSITION, maxHeight - otherHeights, -1); - // add padding only if the list has items in it, that way we don't show - // the popup if it is not needed - if (listContent > 0) otherHeights += padding; + 0, DropDownListView.NO_POSITION, maxHeight - otherHeights, -1); + if (listContent > 0) { + final int listPadding = mDropDownList.getPaddingTop() + + mDropDownList.getPaddingBottom(); + otherHeights += padding + listPadding; + } return listContent + otherHeights; } diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 063288e2adfc..8bd63dfc2075 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -60,6 +60,7 @@ import android.widget.AdapterView.OnItemClickListener; import libcore.util.Objects; import com.android.internal.R; +import com.android.internal.util.Preconditions; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -1096,6 +1097,13 @@ public class RemoteViews implements Parcelable, Filter { memoryCounter.addBitmapMemory(mBitmaps.get(i)); } } + + @Override + protected BitmapCache clone() { + BitmapCache bitmapCache = new BitmapCache(); + bitmapCache.mBitmaps.addAll(mBitmaps); + return bitmapCache; + } } private class BitmapReflectionAction extends Action { @@ -2227,10 +2235,21 @@ public class RemoteViews implements Parcelable, Filter { public RemoteViews clone() { + Preconditions.checkState(mIsRoot, "RemoteView has been attached to another RemoteView. " + + "May only clone the root of a RemoteView hierarchy."); + Parcel p = Parcel.obtain(); + + // Do not parcel the Bitmap cache - doing so creates an expensive copy of all bitmaps. + // Instead pretend we're not owning the cache while parceling. + mIsRoot = false; writeToParcel(p, 0); p.setDataPosition(0); - RemoteViews rv = new RemoteViews(p); + mIsRoot = true; + + RemoteViews rv = new RemoteViews(p, mBitmapCache.clone()); + rv.mIsRoot = true; + p.recycle(); return rv; } @@ -2240,7 +2259,7 @@ public class RemoteViews implements Parcelable, Filter { } /** - * Reutrns the layout id of the root layout associated with this RemoteViews. In the case + * Returns the layout id of the root layout associated with this RemoteViews. In the case * that the RemoteViews has both a landscape and portrait root, this will return the layout * id associated with the portrait layout. * diff --git a/core/tests/coretests/res/layout/remote_views_test.xml b/core/tests/coretests/res/layout/remote_views_test.xml new file mode 100644 index 000000000000..c5f7a47c1e96 --- /dev/null +++ b/core/tests/coretests/res/layout/remote_views_test.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2016 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/layout" + android:orientation="vertical"> + + <TextView android:id="@+id/text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <ImageView android:id="@+id/image" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + +</LinearLayout> diff --git a/core/tests/coretests/src/android/view/RemoteViewsTest.java b/core/tests/coretests/src/android/view/RemoteViewsTest.java new file mode 100644 index 000000000000..9c4fd7047334 --- /dev/null +++ b/core/tests/coretests/src/android/view/RemoteViewsTest.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.view; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RemoteViews; +import android.widget.TextView; + +import com.android.frameworks.coretests.R; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +/** + * Tests for RemoteViews. + */ +@RunWith(AndroidJUnit4.class) +@SmallTest +public class RemoteViewsTest { + + @Rule + public final ExpectedException exception = ExpectedException.none(); + + private Context mContext; + private String mPackage; + private LinearLayout mContainer; + + @Before + public void setup() { + mContext = InstrumentationRegistry.getContext(); + mPackage = mPackage; + mContainer = new LinearLayout(mContext); + } + + @Test + public void clone_doesNotCopyBitmap() { + RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); + Bitmap bitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888); + + original.setImageViewBitmap(R.id.image, bitmap); + RemoteViews clone = original.clone(); + View inflated = clone.apply(mContext, mContainer); + + Drawable drawable = ((ImageView) inflated.findViewById(R.id.image)).getDrawable(); + assertSame(bitmap, ((BitmapDrawable)drawable).getBitmap()); + } + + @Test + public void clone_originalCanStillBeApplied() { + RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); + + RemoteViews clone = original.clone(); + + clone.apply(mContext, mContainer); + } + + @Test + public void clone_clones() { + RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); + + RemoteViews clone = original.clone(); + original.setTextViewText(R.id.text, "test"); + View inflated = clone.apply(mContext, mContainer); + + TextView textView = (TextView) inflated.findViewById(R.id.text); + assertEquals("", textView.getText()); + } + + @Test + public void clone_child_fails() { + RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); + RemoteViews child = new RemoteViews(mPackage, R.layout.remote_views_test); + + original.addView(R.id.layout, child); + + exception.expect(IllegalStateException.class); + RemoteViews clone = child.clone(); + } + + @Test + public void clone_repeatedly() { + RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); + + original.clone(); + original.clone(); + + original.apply(mContext, mContainer); + } + + @Test + public void clone_chained() { + RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test); + + RemoteViews clone = original.clone().clone(); + + clone.apply(mContext, mContainer); + } + +} diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index bd069ffeddad..e75fb9870e0b 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -53,8 +53,15 @@ import java.util.HashMap; import java.util.Stack; /** - * This lets you create a drawable based on an XML vector graphic. It can be - * defined in an XML file with the <code><vector></code> element. + * This lets you create a drawable based on an XML vector graphic. + * <p/> + * <strong>Note:</strong> To optimize for the re-drawing performance, one bitmap cache is created + * for each VectorDrawable. Therefore, referring to the same VectorDrawable means sharing the same + * bitmap cache. If these references don't agree upon on the same size, the bitmap will be recreated + * and redrawn every time size is changed. In other words, if a VectorDrawable is used for + * different sizes, it is more efficient to create multiple VectorDrawables, one for each size. + * <p/> + * VectorDrawable can be defined in an XML file with the <code><vector></code> element. * <p/> * The vector drawable has the following elements: * <p/> diff --git a/libs/hwui/BakedOpState.cpp b/libs/hwui/BakedOpState.cpp index 26653f77daeb..859036543b4a 100644 --- a/libs/hwui/BakedOpState.cpp +++ b/libs/hwui/BakedOpState.cpp @@ -82,6 +82,16 @@ ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& s } } +ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot, + const Matrix4& localTransform, const ClipBase* localClip) { + transform.loadMultiply(*snapshot.transform, localTransform); + clipState = snapshot.mutateClipArea().serializeIntersectedClip(allocator, + localClip, *(snapshot.transform)); + clippedBounds = clipState->rect; + clipSideFlags = OpClipSideFlags::Full; + localProjectionPathMask = nullptr; +} + ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot) : transform(*snapshot.transform) , clipState(snapshot.mutateClipArea().serializeClip(allocator)) diff --git a/libs/hwui/BakedOpState.h b/libs/hwui/BakedOpState.h index ffe2901782a9..4e3cb8a15e24 100644 --- a/libs/hwui/BakedOpState.h +++ b/libs/hwui/BakedOpState.h @@ -55,6 +55,10 @@ public: ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp, bool expandForStroke); + // Constructor for unbounded ops *with* transform/clip + ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot, + const Matrix4& localTransform, const ClipBase* localClip); + // Constructor for unbounded ops without transform/clip (namely shadows) ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot); @@ -111,8 +115,14 @@ public: return bakedState; } + static BakedOpState* tryConstructUnbounded(LinearAllocator& allocator, + Snapshot& snapshot, const RecordedOp& recordedOp) { + if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr; + return allocator.create_trivial<BakedOpState>(allocator, snapshot, recordedOp); + } + enum class StrokeBehavior { - // stroking is forced, regardless of style on paint + // stroking is forced, regardless of style on paint (such as for lines) Forced, // stroking is defined by style on paint StyleDefined, @@ -167,6 +177,13 @@ private: , roundRectClipState(snapshot.roundRectClipState) , op(&recordedOp) {} + // TODO: fix this brittleness + BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp) + : computedState(allocator, snapshot, recordedOp.localMatrix, recordedOp.localClip) + , alpha(snapshot.alpha) + , roundRectClipState(snapshot.roundRectClipState) + , op(&recordedOp) {} + BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const ShadowOp* shadowOpPtr) : computedState(allocator, snapshot) , alpha(snapshot.alpha) diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp index 50b21a40d7c3..fc396825029f 100644 --- a/libs/hwui/FrameBuilder.cpp +++ b/libs/hwui/FrameBuilder.cpp @@ -574,7 +574,7 @@ void FrameBuilder::deferCirclePropsOp(const CirclePropsOp& op) { } void FrameBuilder::deferFunctorOp(const FunctorOp& op) { - BakedOpState* bakedState = tryBakeOpState(op); + BakedOpState* bakedState = tryBakeUnboundedOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Functor); } @@ -663,7 +663,7 @@ void FrameBuilder::deferTextOp(const TextOp& op) { } void FrameBuilder::deferTextOnPathOp(const TextOnPathOp& op) { - BakedOpState* bakedState = tryBakeOpState(op); + BakedOpState* bakedState = tryBakeUnboundedOpState(op); if (!bakedState) return; // quick rejected currentLayer().deferUnmergeableOp(mAllocator, bakedState, textBatchId(*(op.paint))); } diff --git a/libs/hwui/FrameBuilder.h b/libs/hwui/FrameBuilder.h index f44306a931bf..8a00d336dc08 100644 --- a/libs/hwui/FrameBuilder.h +++ b/libs/hwui/FrameBuilder.h @@ -173,6 +173,10 @@ private: BakedOpState* tryBakeOpState(const RecordedOp& recordedOp) { return BakedOpState::tryConstruct(mAllocator, *mCanvasState.writableSnapshot(), recordedOp); } + BakedOpState* tryBakeUnboundedOpState(const RecordedOp& recordedOp) { + return BakedOpState::tryConstructUnbounded(mAllocator, *mCanvasState.writableSnapshot(), recordedOp); + } + // should always be surrounded by a save/restore pair, and not called if DisplayList is null void deferNodePropsAndOps(RenderNode& node); diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h index c37458d31029..96a57b6a8efe 100644 --- a/libs/hwui/RecordedOp.h +++ b/libs/hwui/RecordedOp.h @@ -257,8 +257,10 @@ struct CirclePropsOp : RecordedOp { }; struct FunctorOp : RecordedOp { - FunctorOp(BASE_PARAMS_PAINTLESS, Functor* functor) - : SUPER_PAINTLESS(FunctorOp) + // Note: undefined record-time bounds, since this op fills the clip + // TODO: explicitly define bounds + FunctorOp(const Matrix4& localMatrix, const ClipBase* localClip, Functor* functor) + : RecordedOp(RecordedOpId::FunctorOp, Rect(), localMatrix, localClip, nullptr) , functor(functor) {} Functor* functor; }; @@ -385,9 +387,10 @@ struct TextOp : RecordedOp { }; struct TextOnPathOp : RecordedOp { - TextOnPathOp(BASE_PARAMS, const glyph_t* glyphs, int glyphCount, - const SkPath* path, float hOffset, float vOffset) - : SUPER(TextOnPathOp) + // TODO: explicitly define bounds + TextOnPathOp(const Matrix4& localMatrix, const ClipBase* localClip, const SkPaint* paint, + const glyph_t* glyphs, int glyphCount, const SkPath* path, float hOffset, float vOffset) + : RecordedOp(RecordedOpId::TextOnPathOp, Rect(), localMatrix, localClip, paint) , glyphs(glyphs) , glyphCount(glyphCount) , path(path) diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index 11eb825a56b0..1546baf88691 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -24,14 +24,6 @@ namespace android { namespace uirenderer { -#define MIL_PIX 1000000 -static Rect sUnreasonablyLargeBounds(-MIL_PIX, -MIL_PIX, MIL_PIX, MIL_PIX); - -static const Rect& getConservativeOpBounds(const ClipBase* clip) { - // if op is clipped, that rect can be used, but otherwise just use a conservatively large rect - return clip ? clip->rect : sUnreasonablyLargeBounds; -} - RecordingCanvas::RecordingCanvas(size_t width, size_t height) : mState(*this) , mResourceCache(ResourceCache::getInstance()) { @@ -249,12 +241,10 @@ void RecordingCanvas::drawColor(int color, SkXfermode::Mode mode) { } void RecordingCanvas::drawPaint(const SkPaint& paint) { - const ClipBase* clip = getRecordedClip(); - addOp(alloc().create_trivial<RectOp>( - getConservativeOpBounds(clip), - Matrix4::identity(), - clip, - refPaint(&paint))); + SkRect bounds; + if (getClipBounds(&bounds)) { + drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint); + } } static Rect calcBoundsOfPoints(const float* points, int floatCount) { @@ -544,11 +534,9 @@ void RecordingCanvas::drawTextOnPath(const uint16_t* glyphs, int glyphCount, con float hOffset, float vOffset, const SkPaint& paint) { if (!glyphs || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return; glyphs = refBuffer<glyph_t>(glyphs, glyphCount); - auto clip = getRecordedClip(); addOp(alloc().create_trivial<TextOnPathOp>( - getConservativeOpBounds(clip), // TODO: explicitly define bounds *(mState.currentSnapshot()->transform), - clip, + getRecordedClip(), refPaint(&paint), glyphs, glyphCount, refPath(&path), hOffset, vOffset)); } @@ -599,11 +587,9 @@ void RecordingCanvas::drawLayer(DeferredLayerUpdater* layerHandle) { void RecordingCanvas::callDrawGLFunction(Functor* functor) { mDisplayList->functors.push_back(functor); - auto clip = getRecordedClip(); addOp(alloc().create_trivial<FunctorOp>( - getConservativeOpBounds(clip), *(mState.currentSnapshot()->transform), - clip, + getRecordedClip(), functor)); } diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp index 5e613fd50c3e..e6d84c6681f1 100644 --- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp +++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp @@ -223,8 +223,7 @@ TEST(RecordingCanvas, drawColor) { auto op = *(dl->getOps()[0]); EXPECT_EQ(RecordedOpId::RectOp, op.opId); EXPECT_EQ(nullptr, op.localClip); - EXPECT_TRUE(op.unmappedBounds.contains(Rect(-1000, -1000, 1000, 1000))) - << "no clip, unmappedBounds should resolve to be much larger than DL bounds"; + EXPECT_TRUE(op.unmappedBounds.contains(Rect(200, 200))) << "Expect recording/clip bounds"; } TEST(RecordingCanvas, backgroundAndImage) { diff --git a/media/java/android/media/AudioDeviceCallback.java b/media/java/android/media/AudioDeviceCallback.java index d9f0037ce206..a5b1d2402183 100644 --- a/media/java/android/media/AudioDeviceCallback.java +++ b/media/java/android/media/AudioDeviceCallback.java @@ -19,7 +19,7 @@ package android.media; /** * AudioDeviceCallback defines the mechanism by which applications can receive notifications * of audio device connection and disconnection events. - * @see AudioManager#registerAudioDeviceCallback. + * @see AudioManager#registerAudioDeviceCallback(AudioDeviceCallback, android.os.Handler handler). */ public abstract class AudioDeviceCallback { /** diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java index abb6f4e9964c..a4484e757ac5 100644 --- a/media/java/android/media/AudioFormat.java +++ b/media/java/android/media/AudioFormat.java @@ -256,6 +256,11 @@ public final class AudioFormat implements Parcelable { public static final int ENCODING_AAC_HE_V2 = 12; /** Audio data format: compressed audio wrapped in PCM for HDMI * or S/PDIF passthrough. + * IEC61937 uses a stereo stream of 16-bit samples as the wrapper. + * So the channel mask for the track must be {@link #CHANNEL_OUT_STEREO}. + * Data should be written to the stream in a short[] array. + * If the data is written in a byte[] array then there may be endian problems + * on some platforms when converting to short internally. */ public static final int ENCODING_IEC61937 = 13; diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index e1dab092a3f7..d9caf030a8fb 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -806,6 +806,15 @@ public class AudioTrack implements AudioRouting } mSampleRate = sampleRateInHz; + // IEC61937 is based on stereo. We could coerce it to stereo. + // But the application needs to know the stream is stereo so that + // it is encoded and played correctly. So better to just reject it. + if (audioFormat == AudioFormat.ENCODING_IEC61937 + && channelConfig != AudioFormat.CHANNEL_OUT_STEREO) { + throw new IllegalArgumentException( + "ENCODING_IEC61937 must be configured as CHANNEL_OUT_STEREO"); + } + //-------------- // channel config mChannelConfiguration = channelConfig; diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml index 746457fa4e7b..61966b2ee1a4 100644 --- a/packages/Keyguard/res/values/strings.xml +++ b/packages/Keyguard/res/values/strings.xml @@ -302,7 +302,7 @@ <string name="keyguard_carrier_default">No service.</string> <!-- Content description of the switch input method button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> - <string name="accessibility_ime_switch_button" msgid="5032926134740456424">Switch input method button.</string> + <string name="accessibility_ime_switch_button" msgid="5032926134740456424">Switch input method</string> <!-- Description of airplane mode --> <string name="airplane_mode">Airplane mode</string> diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java index e312fa2028a5..ef32f7e8777e 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java @@ -100,8 +100,8 @@ public class WindowManagerProxy { @Override public void run() { try { - ActivityManagerNative.getDefault().resizeStack(DOCKED_STACK_ID, null, true, true, - false); + ActivityManagerNative.getDefault().resizeStack( + DOCKED_STACK_ID, null, true, true, false, -1); } catch (RemoteException e) { Log.w(TAG, "Failed to resize stack: " + e); } diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java index ff7ea276aa91..8db75344e483 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java @@ -385,7 +385,7 @@ public class PipManager { break; } try { - mActivityManager.resizeStack(PINNED_STACK_ID, mCurrentPipBounds, true, true, true); + mActivityManager.resizeStack(PINNED_STACK_ID, mCurrentPipBounds, true, true, true, -1); } catch (RemoteException e) { Log.e(TAG, "showPipMenu failed", e); } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 9ce81ed2f10c..c810e6c89c9f 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -4086,7 +4086,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } public boolean isHandlingAccessibilityEvents() { - return !mBoundServices.isEmpty() || !mBoundServices.isEmpty(); + return !mBoundServices.isEmpty() || !mBindingServices.isEmpty(); } public void onSwitchToAnotherUser() { diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index cd4d107d5a98..b737ae2c3ee4 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -2918,9 +2918,15 @@ public class BackupManagerService { mBackupRunning = false; if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) { // Make sure we back up everything and perform the one-time init - clearMetadata(); if (MORE_DEBUG) Slog.d(TAG, "Server requires init; rerunning"); addBackupTrace("init required; rerunning"); + try { + mPendingInits.add(mTransport.transportDirName()); + } catch (Exception e) { + Slog.w(TAG, "Failed to query transport name heading for init", e); + // swallow it and proceed; we don't rely on this + } + clearMetadata(); backupNow(); } } @@ -4451,13 +4457,21 @@ public class BackupManagerService { } } - // We still could fail in backup runner thread, getting result from there. - int backupRunnerResult = backupRunner.getBackupResultBlocking(); - if (backupPackageStatus != BackupTransport.TRANSPORT_ERROR - && backupRunnerResult != BackupTransport.TRANSPORT_OK) { - // If there was an error in runner thread and - // not TRANSPORT_ERROR here, overwrite it. - backupPackageStatus = backupRunnerResult; + // TRANSPORT_ERROR here means that we've hit an error that the runner + // doesn't know about, so it's still moving data but we're pulling the + // rug out from under it. Don't ask for its result: we already know better + // and we'll hang if we block waiting for it, since it relies on us to + // read back the data it's writing into the engine. Just proceed with + // a graceful failure. The runner/engine mechanism will tear itself + // down cleanly when we close the pipes from this end. + if (backupPackageStatus != BackupTransport.TRANSPORT_ERROR) { + // We still could fail in backup runner thread, getting result from there. + int backupRunnerResult = backupRunner.getBackupResultBlocking(); + if (backupRunnerResult != BackupTransport.TRANSPORT_OK) { + // If there was an error in runner thread and + // not TRANSPORT_ERROR here, overwrite it. + backupPackageStatus = backupRunnerResult; + } } if (MORE_DEBUG) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a22e0efb70d4..c1ec71c92a2d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -9674,14 +9674,14 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode, - boolean preserveWindows, boolean animate) { + boolean preserveWindows, boolean animate, int animationDuration) { enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); long ident = Binder.clearCallingIdentity(); try { synchronized (this) { if (animate) { if (stackId == PINNED_STACK_ID) { - mWindowManager.animateResizePinnedStack(bounds); + mWindowManager.animateResizePinnedStack(bounds, animationDuration); } else { throw new IllegalArgumentException("Stack: " + stackId + " doesn't support animated resize."); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index d364d8569db0..7def1bd57aaf 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2408,7 +2408,7 @@ public final class ActivityStackSupervisor implements DisplayListener { ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); resumeFocusedStackTopActivityLocked(); - mWindowManager.animateResizePinnedStack(bounds); + mWindowManager.animateResizePinnedStack(bounds, -1); mService.notifyActivityPinnedLocked(); } diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index efa74209afaa..af69c93b8a64 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -1483,7 +1483,8 @@ class ActivityStarter { if (mLaunchBounds != null) { final int stackId = mTargetStack.mStackId; if (StackId.resizeStackWithLaunchBounds(stackId)) { - mService.resizeStack(stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE); + mService.resizeStack( + stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1); } else { mStartActivity.task.updateOverrideConfiguration(mLaunchBounds); } @@ -1571,7 +1572,7 @@ class ActivityStarter { stackId = stack.mStackId; } if (StackId.resizeStackWithLaunchBounds(stackId)) { - mService.resizeStack(stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE); + mService.resizeStack(stackId, mLaunchBounds, true, !PRESERVE_WINDOWS, ANIMATE, -1); } } mTargetStack = mInTask.stack; diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 5fd196b4eb5b..a3622b58cb4d 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -387,6 +387,15 @@ public class UserManagerService extends IUserManager.Stub { synchronized (mRestrictionsLock) { applyUserRestrictionsLR(UserHandle.USER_SYSTEM); } + + UserInfo currentGuestUser = findCurrentGuestUser(); + if (currentGuestUser != null && !hasUserRestriction( + UserManager.DISALLOW_CONFIG_WIFI, currentGuestUser.id)) { + // If a guest user currently exists, apply the DISALLOW_CONFIG_WIFI option + // to it, in case this guest was created in a previous version where this + // user restriction was not a default guest restriction. + setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, currentGuestUser.id); + } } @Override @@ -828,6 +837,7 @@ public class UserManagerService extends IUserManager.Stub { private void initDefaultGuestRestrictions() { synchronized (mGuestRestrictions) { if (mGuestRestrictions.isEmpty()) { + mGuestRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_WIFI, true); mGuestRestrictions.putBoolean(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true); mGuestRestrictions.putBoolean(UserManager.DISALLOW_OUTGOING_CALLS, true); mGuestRestrictions.putBoolean(UserManager.DISALLOW_SMS, true); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index cbd77d4bcfe2..ff5a0f967b54 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -71,6 +71,8 @@ import com.android.server.Watchdog; import com.android.server.am.BatteryStatsService; import com.android.server.lights.Light; import com.android.server.lights.LightsManager; +import com.android.server.vr.VrManagerInternal; +import com.android.server.vr.VrStateListener; import libcore.util.Objects; import java.io.FileDescriptor; @@ -158,6 +160,7 @@ public final class PowerManagerService extends SystemService // Power hints defined in hardware/libhardware/include/hardware/power.h. private static final int POWER_HINT_LOW_POWER = 5; private static final int POWER_HINT_SUSTAINED_PERFORMANCE = 6; + private static final int POWER_HINT_VR_MODE = 7; // Power features defined in hardware/libhardware/include/hardware/power.h. private static final int POWER_FEATURE_DOUBLE_TAP_TO_WAKE = 1; @@ -654,6 +657,7 @@ public final class PowerManagerService extends SystemService resolver.registerContentObserver(Settings.Secure.getUriFor( Secure.BRIGHTNESS_USE_TWILIGHT), false, mSettingsObserver, UserHandle.USER_ALL); + getLocalService(VrManagerInternal.class).registerListener(mVrStateListener); // Go. readConfigurationLocked(); updateSettingsLocked(); @@ -3002,6 +3006,13 @@ public final class PowerManagerService extends SystemService } } + private final VrStateListener mVrStateListener = new VrStateListener() { + @Override + public void onVrStateChanged(boolean enabled) { + powerHintInternal(POWER_HINT_VR_MODE, enabled ? 1 : 0); + } + }; + /** * Handler for asynchronous operations performed by the power manager. */ diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index 0aa30526ed2e..6bf949cf8655 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -158,7 +158,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC @Override public void onBootPhase(int phase) { - if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { + if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { synchronized (mLock) { Looper looper = Looper.getMainLooper(); Handler handler = new Handler(looper); diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java index 79d3d84cfae2..b7d6062a3dc0 100644 --- a/services/core/java/com/android/server/wm/BoundsAnimationController.java +++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java @@ -214,7 +214,7 @@ public class BoundsAnimationController { void getFullScreenBounds(Rect bounds); } - void animateBounds(final AnimateBoundsUser target, Rect from, Rect to) { + void animateBounds(final AnimateBoundsUser target, Rect from, Rect to, int animationDuration) { boolean moveToFullscreen = false; if (to == null) { to = new Rect(); @@ -242,7 +242,8 @@ public class BoundsAnimationController { new BoundsAnimator(target, from, to, moveToFullscreen, replacing); mRunningAnimations.put(target, animator); animator.setFloatValues(0f, 1f); - animator.setDuration(DEFAULT_APP_TRANSITION_DURATION * DEBUG_ANIMATION_SLOW_DOWN_FACTOR); + animator.setDuration((animationDuration != -1 ? animationDuration + : DEFAULT_APP_TRANSITION_DURATION) * DEBUG_ANIMATION_SLOW_DOWN_FACTOR); animator.setInterpolator(new LinearInterpolator()); animator.start(); } diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 60b2e4a68f6d..c6677670190e 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -1089,7 +1089,7 @@ public class TaskStack implements DimLayer.DimLayerUser, } } try { - mService.mActivityManager.resizeStack(mStackId, bounds, false, true, false); + mService.mActivityManager.resizeStack(mStackId, bounds, false, true, false, -1); } catch (RemoteException e) { } return true; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 607a3e96ecba..b84ed7be9ad4 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -8241,8 +8241,8 @@ public class WindowManagerService extends IWindowManager.Stub break; case RESIZE_STACK: { try { - mActivityManager.resizeStack(msg.arg1, (Rect) msg.obj, msg.arg2 == 1, false, - false); + mActivityManager.resizeStack( + msg.arg1, (Rect) msg.obj, msg.arg2 == 1, false, false, -1); } catch (RemoteException e) { // This will not happen since we are in the same process. } @@ -10460,7 +10460,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void animateResizePinnedStack(final Rect bounds) { + public void animateResizePinnedStack(final Rect bounds, final int animationDuration) { synchronized (mWindowMap) { final TaskStack stack = mStackIdToStack.get(PINNED_STACK_ID); if (stack == null) { @@ -10472,7 +10472,8 @@ public class WindowManagerService extends IWindowManager.Stub UiThread.getHandler().post(new Runnable() { @Override public void run() { - mBoundsAnimationController.animateBounds(stack, originalBounds, bounds); + mBoundsAnimationController.animateBounds( + stack, originalBounds, bounds, animationDuration); } }); } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 86518b57c430..c69a360aeb5e 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -590,21 +590,8 @@ public class CarrierConfigManager { * When {@code true}, video calls to emergency numbers will be allowed. When {@code false}, * video calls to emergency numbers will be initiated as audio-only calls instead. */ - @SystemApi - public static final String BOOL_ALLOW_EMERGENCY_VIDEO_CALLS = - "bool_allow_emergency_video_calls"; - - /** - * Flag indicating whether the carrier supports video pause signaling. When {@code true}, the - * carrier supports use of the {@link android.telecom.VideoProfile#STATE_PAUSED} video state - * to pause transmission of video when the In-Call app is sent to the background. - * When {@code false}, video pause signaling is not supported. {@code True} by default unless - * a carrier configuration overrides the default. - */ - @SystemApi - public static final String BOOL_ALLOW_VIDEO_PAUSE = - "bool_allow_video_pause"; - + public static final String KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL = + "allow_emergency_video_calls_bool"; /** * Flag indicating whether the carrier supports RCS presence indication for video calls. When @@ -617,7 +604,6 @@ public class CarrierConfigManager { * and can choose to hide or show the video calling icon based on whether a contact supports * video. */ - @SystemApi public static final String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool"; /** @@ -715,8 +701,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true); sDefaults.putBoolean(KEY_HIDE_IMS_APN_BOOL, false); sDefaults.putBoolean(KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, false); - sDefaults.putBoolean(BOOL_ALLOW_EMERGENCY_VIDEO_CALLS, false); - sDefaults.putBoolean(BOOL_ALLOW_VIDEO_PAUSE, true); + sDefaults.putBoolean(KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL, false); sDefaults.putBoolean(KEY_EDITABLE_WFC_MODE_BOOL, true); // MMS defaults diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index 4f0e036e04ca..8aa0e3406ee3 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -81,8 +81,7 @@ public interface RILConstants { int INTERNAL_ERR = 38; /* Hit unexpected vendor internal error scenario */ int SYSTEM_ERR = 39; /* Hit platform or system error */ int MODEM_ERR = 40; /* Hit unexpected modem error */ - int INVALID_STATE = 41; /* Can not process the request as vendor RIL is in - invalid state. */ + int INVALID_STATE = 41; /* Unexpected request for the current state */ int NO_RESOURCES = 42; /* Not sufficient resource to process the request */ int SIM_ERR = 43; /* Received error from SIM card */ int INVALID_ARGUMENTS = 44; /* Received invalid arguments in request */ @@ -103,6 +102,11 @@ public interface RILConstants { int NO_SUCH_ENTRY = 59; /* No such entry present to perform the request */ int NETWORK_NOT_READY = 60; /* Network is not ready to perform the request */ int NOT_PROVISIONED = 61; /* Device doesnot have this value provisioned */ + int NO_SUBSCRIPTION = 62; /* Device doesnot have subscription */ + int NO_NETWORK_FOUND = 63; /* Network cannot be found */ + int DEVICE_IN_USE = 64; /* Operation cannot be performed because the device + is currently in use */ + int ABORTED = 65; /* Operation aborted */ // Below is list of OEM specific error codes which can by used by OEMs in case they don't want to // reveal particular replacement for Generic failure int OEM_ERROR_1 = 501; diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index c4495509614e..ca06ac440731 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -249,7 +249,7 @@ public: * above. SDK levels that have a non-numeric identifier are assumed * to be newer than any SDK level that has a number designated. */ - bool isMinSdkAtLeast(int desired) { + bool isMinSdkAtLeast(int desired) const { /* If the application specifies a minSdkVersion in the manifest * then use that. Otherwise, check what the user specified on * the command line. If neither, it's not available since diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp index 40466bd25451..9939c188cdd9 100644 --- a/tools/aapt/Images.cpp +++ b/tools/aapt/Images.cpp @@ -1134,10 +1134,9 @@ static void analyze_image(const char *imageName, image_info &imageInfo, int gray } } - static void write_png(const char* imageName, png_structp write_ptr, png_infop write_info, - image_info& imageInfo, int grayscaleTolerance) + image_info& imageInfo, const Bundle* bundle) { png_uint_32 width, height; int color_type; @@ -1174,9 +1173,26 @@ static void write_png(const char* imageName, bool hasTransparency; int paletteEntries, alphaPaletteEntries; + int grayscaleTolerance = bundle->getGrayscaleTolerance(); analyze_image(imageName, imageInfo, grayscaleTolerance, rgbPalette, alphaPalette, &paletteEntries, &alphaPaletteEntries, &hasTransparency, &color_type, outRows); + // Legacy versions of aapt would always encode 9patch PNGs as RGBA. This had the unintended + // benefit of working around a bug decoding paletted images in Android 4.1. + // https://code.google.com/p/android/issues/detail?id=34619 + // + // If SDK_JELLY_BEAN is supported, we need to avoid a paletted encoding in order to not expose + // this bug. + if (!bundle->isMinSdkAtLeast(SDK_JELLY_BEAN_MR1)) { + if (imageInfo.is9Patch && PNG_COLOR_TYPE_PALETTE == color_type) { + if (hasTransparency) { + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + } else { + color_type = PNG_COLOR_TYPE_RGB; + } + } + } + if (kIsDebug) { switch (color_type) { case PNG_COLOR_TYPE_PALETTE: @@ -1332,8 +1348,7 @@ static bool write_png_protected(png_structp write_ptr, String8& printableName, p return false; } - write_png(printableName.string(), write_ptr, write_info, *imageInfo, - bundle->getGrayscaleTolerance()); + write_png(printableName.string(), write_ptr, write_info, *imageInfo, bundle); return true; } @@ -1543,8 +1558,7 @@ status_t preProcessImageToCache(const Bundle* bundle, const String8& source, con } // Actually write out to the new png - write_png(dest.string(), write_ptr, write_info, imageInfo, - bundle->getGrayscaleTolerance()); + write_png(dest.string(), write_ptr, write_info, imageInfo, bundle); if (bundle->getVerbose()) { // Find the size of our new file |