diff options
18 files changed, 327 insertions, 138 deletions
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index b75c39c0d350..bab39802da3f 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -782,6 +782,16 @@ public class ActivityInfo extends ComponentInfo * constant starts at the high bits. */ public static final int CONFIG_FONT_SCALE = 0x40000000; + /** + * Bit in {@link #configChanges} that indicates that the activity + * can itself handle changes to the rotation. Set from the + * {@link android.R.attr#configChanges} attribute. This is + * not a core resource configuration, but a higher-level value, so its + * constant starts at the high bits. + * @hide We do not want apps to handle this. It will eventually be moved out of + * {@link Configuration}. + */ + public static final int CONFIG_ROTATION = 0x20000000; /** @hide * Unfortunately the constants for config changes in native code are diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index eb6e0d8bd4de..426c4f26945c 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -202,6 +202,8 @@ public class PackageParser { // Temporary workaround; allow meta-data to expose components to instant apps private static final String META_DATA_INSTANT_APPS = "instantapps.clients.allowed"; + private static final String METADATA_MAX_ASPECT_RATIO = "android.max_aspect"; + /** * Bit mask of all the valid bits that can be set in recreateOnConfigChanges. * @hide @@ -3662,6 +3664,7 @@ public class PackageParser { // getting added to the wrong package. final CachedComponentArgs cachedArgs = new CachedComponentArgs(); int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { @@ -3839,6 +3842,10 @@ public class PackageParser { } } + // Must be ran after the entire {@link ApplicationInfo} has been fully processed and after + // every activity info has had a chance to set it from its attributes. + setMaxAspectRatio(owner); + modifySharedLibrariesForBackwardCompatibility(owner); if (hasDomainURLs(owner)) { @@ -4286,7 +4293,12 @@ public class PackageParser { a.info.flags |= FLAG_ALWAYS_FOCUSABLE; } - setActivityMaxAspectRatio(a.info, sa, owner); + if (sa.hasValue(R.styleable.AndroidManifestActivity_maxAspectRatio) + && sa.getType(R.styleable.AndroidManifestActivity_maxAspectRatio) + == TypedValue.TYPE_FLOAT) { + a.setMaxAspectRatio(sa.getFloat(R.styleable.AndroidManifestActivity_maxAspectRatio, + 0 /*default*/)); + } a.info.lockTaskLaunchMode = sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0); @@ -4533,28 +4545,40 @@ public class PackageParser { } } - private void setActivityMaxAspectRatio(ActivityInfo aInfo, TypedArray sa, Package owner) { - if (aInfo.resizeMode == RESIZE_MODE_RESIZEABLE - || aInfo.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) { - // Resizeable activities can be put in any aspect ratio. - aInfo.maxAspectRatio = 0; - return; - } - + /** + * Sets every the max aspect ratio of every child activity that doesn't already have an aspect + * ratio set. + */ + private void setMaxAspectRatio(Package owner) { // Default to (1.86) 16.7:9 aspect ratio for pre-O apps and unset for O and greater. // NOTE: 16.7:9 was the max aspect ratio Android devices can support pre-O per the CDD. - float defaultMaxAspectRatio = owner.applicationInfo.targetSdkVersion < O + float maxAspectRatio = owner.applicationInfo.targetSdkVersion < O ? DEFAULT_PRE_O_MAX_ASPECT_RATIO : 0; - if (owner.applicationInfo.maxAspectRatio != 0 ) { + + if (owner.applicationInfo.maxAspectRatio != 0) { // Use the application max aspect ration as default if set. - defaultMaxAspectRatio = owner.applicationInfo.maxAspectRatio; + maxAspectRatio = owner.applicationInfo.maxAspectRatio; + } else if (owner.mAppMetaData != null + && owner.mAppMetaData.containsKey(METADATA_MAX_ASPECT_RATIO)) { + maxAspectRatio = owner.mAppMetaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio); } - aInfo.maxAspectRatio = sa.getFloat( - R.styleable.AndroidManifestActivity_maxAspectRatio, defaultMaxAspectRatio); - if (aInfo.maxAspectRatio < 1.0f && aInfo.maxAspectRatio != 0) { - // Ignore any value lesser than 1.0. - aInfo.maxAspectRatio = 0; + for (Activity activity : owner.activities) { + // If the max aspect ratio for the activity has already been set, skip. + if (activity.hasMaxAspectRatio()) { + continue; + } + + // By default we prefer to use a values defined on the activity directly than values + // defined on the application. We do not check the styled attributes on the activity + // as it would have already been set when we processed the activity. We wait to process + // the meta data here since this method is called at the end of processing the + // application and all meta data is guaranteed. + final float activityAspectRatio = activity.metaData != null + ? activity.metaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio) + : maxAspectRatio; + + activity.setMaxAspectRatio(activityAspectRatio); } } @@ -4696,6 +4720,7 @@ public class PackageParser { info.windowLayout = target.info.windowLayout; info.resizeMode = target.info.resizeMode; info.maxAspectRatio = target.info.maxAspectRatio; + info.encryptionAware = info.directBootAware = target.info.directBootAware; Activity a = new Activity(cachedArgs.mActivityAliasArgs, info); @@ -6980,6 +7005,11 @@ public class PackageParser { public final static class Activity extends Component<ActivityIntentInfo> implements Parcelable { public final ActivityInfo info; + private boolean mHasMaxAspectRatio; + + private boolean hasMaxAspectRatio() { + return mHasMaxAspectRatio; + } public Activity(final ParseComponentArgs args, final ActivityInfo _info) { super(args, _info); @@ -6992,6 +7022,23 @@ public class PackageParser { info.packageName = packageName; } + + private void setMaxAspectRatio(float maxAspectRatio) { + if (info.resizeMode == RESIZE_MODE_RESIZEABLE + || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) { + // Resizeable activities can be put in any aspect ratio. + return; + } + + if (maxAspectRatio < 1.0f && maxAspectRatio != 0) { + // Ignore any value lesser than 1.0. + return; + } + + info.maxAspectRatio = maxAspectRatio; + mHasMaxAspectRatio = true; + } + public String toString() { StringBuilder sb = new StringBuilder(128); sb.append("Activity{"); @@ -7011,11 +7058,13 @@ public class PackageParser { public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeParcelable(info, flags | Parcelable.PARCELABLE_ELIDE_DUPLICATES); + dest.writeBoolean(mHasMaxAspectRatio); } private Activity(Parcel in) { super(in); info = in.readParcelable(Object.class.getClassLoader()); + mHasMaxAspectRatio = in.readBoolean(); for (ActivityIntentInfo aii : intents) { aii.activity = this; diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index ef279b86662a..68d4cd8c5f7d 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -1395,7 +1395,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration } if ((compareUndefined || delta.mRotation != ROTATION_UNDEFINED) && mRotation != delta.mRotation) { - changed |= ActivityInfo.CONFIG_ORIENTATION; + changed |= ActivityInfo.CONFIG_ROTATION; } if ((compareUndefined || getScreenLayoutNoDirection(delta.screenLayout) != (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED)) diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java index 2608698f5b63..04819a5999eb 100644 --- a/core/java/com/android/internal/colorextraction/ColorExtractor.java +++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java @@ -43,10 +43,6 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener private static final String TAG = "ColorExtractor"; - public static final int FALLBACK_COLOR = 0xff83888d; - - private int mMainFallbackColor = FALLBACK_COLOR; - private int mSecondaryFallbackColor = FALLBACK_COLOR; private final SparseArray<GradientColors[]> mGradientColors; private final ArrayList<OnColorsChangedListener> mOnColorsChangedListeners; private final Context mContext; @@ -73,6 +69,9 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener } mOnColorsChangedListeners = new ArrayList<>(); + GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM); + GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK); + WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class); if (wallpaperManager == null) { Log.w(TAG, "Can't listen to color changes!"); @@ -83,23 +82,18 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener Trace.beginSection("ColorExtractor#getWallpaperColors"); mSystemColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM); mLockColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_LOCK); - - GradientColors[] systemColors = mGradientColors.get( - WallpaperManager.FLAG_SYSTEM); - extractInto(mSystemColors, - systemColors[TYPE_NORMAL], - systemColors[TYPE_DARK], - systemColors[TYPE_EXTRA_DARK]); - - GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK); - extractInto(mLockColors, - lockColors[TYPE_NORMAL], - lockColors[TYPE_DARK], - lockColors[TYPE_EXTRA_DARK]); - triggerColorsChanged(WallpaperManager.FLAG_SYSTEM - | WallpaperManager.FLAG_LOCK); Trace.endSection(); } + + // Initialize all gradients with the current colors + extractInto(mSystemColors, + systemColors[TYPE_NORMAL], + systemColors[TYPE_DARK], + systemColors[TYPE_EXTRA_DARK]); + extractInto(mLockColors, + lockColors[TYPE_NORMAL], + lockColors[TYPE_DARK], + lockColors[TYPE_EXTRA_DARK]); } /** @@ -181,25 +175,8 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener private void extractInto(WallpaperColors inWallpaperColors, GradientColors outGradientColorsNormal, GradientColors outGradientColorsDark, GradientColors outGradientColorsExtraDark) { - if (inWallpaperColors == null) { - applyFallback(outGradientColorsNormal); - applyFallback(outGradientColorsDark); - applyFallback(outGradientColorsExtraDark); - return; - } - boolean success = mExtractionType.extractInto(inWallpaperColors, outGradientColorsNormal, + mExtractionType.extractInto(inWallpaperColors, outGradientColorsNormal, outGradientColorsDark, outGradientColorsExtraDark); - if (!success) { - applyFallback(outGradientColorsNormal); - applyFallback(outGradientColorsDark); - applyFallback(outGradientColorsExtraDark); - } - } - - private void applyFallback(GradientColors outGradientColors) { - outGradientColors.setMainColor(mMainFallbackColor); - outGradientColors.setSecondaryColor(mSecondaryFallbackColor); - outGradientColors.setSupportsDarkText(false); } public void destroy() { @@ -218,8 +195,8 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener } public static class GradientColors { - private int mMainColor = FALLBACK_COLOR; - private int mSecondaryColor = FALLBACK_COLOR; + private int mMainColor; + private int mSecondaryColor; private boolean mSupportsDarkText; public void setMainColor(int mainColor) { diff --git a/core/java/com/android/internal/colorextraction/types/ExtractionType.java b/core/java/com/android/internal/colorextraction/types/ExtractionType.java index 762b54fb1e6b..7000e798f87b 100644 --- a/core/java/com/android/internal/colorextraction/types/ExtractionType.java +++ b/core/java/com/android/internal/colorextraction/types/ExtractionType.java @@ -38,9 +38,8 @@ public interface ExtractionType { * @param outGradientColorsNormal object that should receive normal colors * @param outGradientColorsDark object that should receive dark colors * @param outGradientColorsExtraDark object that should receive extra dark colors - * @return true if successful. */ - boolean extractInto(WallpaperColors inWallpaperColors, + void extractInto(WallpaperColors inWallpaperColors, ColorExtractor.GradientColors outGradientColorsNormal, ColorExtractor.GradientColors outGradientColorsDark, ColorExtractor.GradientColors outGradientColorsExtraDark); diff --git a/core/java/com/android/internal/colorextraction/types/Tonal.java b/core/java/com/android/internal/colorextraction/types/Tonal.java index b8ebe3000d8e..e78ca3844bed 100644 --- a/core/java/com/android/internal/colorextraction/types/Tonal.java +++ b/core/java/com/android/internal/colorextraction/types/Tonal.java @@ -44,24 +44,54 @@ public class Tonal implements ExtractionType { private static final boolean DEBUG = true; + public static final int MAIN_COLOR_LIGHT = 0xffe0e0e0; + public static final int SECONDARY_COLOR_LIGHT = 0xff9e9e9e; + public static final int MAIN_COLOR_DARK = 0xff212121; + public static final int SECONDARY_COLOR_DARK = 0xff000000; + // Temporary variable to avoid allocations private float[] mTmpHSL = new float[3]; /** - * Grab colors from WallpaperColors as set them into GradientColors + * Grab colors from WallpaperColors and set them into GradientColors. + * Also applies the default gradient in case extraction fails. + * + * @param inWallpaperColors Input. + * @param outColorsNormal Colors for normal theme. + * @param outColorsDark Colors for dar theme. + * @param outColorsExtraDark Colors for extra dark theme. + */ + public void extractInto(@Nullable WallpaperColors inWallpaperColors, + @NonNull GradientColors outColorsNormal, @NonNull GradientColors outColorsDark, + @NonNull GradientColors outColorsExtraDark) { + boolean success = runTonalExtraction(inWallpaperColors, outColorsNormal, outColorsDark, + outColorsExtraDark); + if (!success) { + applyFallback(inWallpaperColors, outColorsNormal, outColorsDark, outColorsExtraDark); + } + } + + /** + * Grab colors from WallpaperColors and set them into GradientColors. * - * @param inWallpaperColors input - * @param outColorsNormal colors for normal theme - * @param outColorsDark colors for dar theme - * @param outColorsExtraDark colors for extra dark theme - * @return true if successful + * @param inWallpaperColors Input. + * @param outColorsNormal Colors for normal theme. + * @param outColorsDark Colors for dar theme. + * @param outColorsExtraDark Colors for extra dark theme. + * @return True if succeeded or false if failed. */ - public boolean extractInto(@NonNull WallpaperColors inWallpaperColors, + private boolean runTonalExtraction(@Nullable WallpaperColors inWallpaperColors, @NonNull GradientColors outColorsNormal, @NonNull GradientColors outColorsDark, @NonNull GradientColors outColorsExtraDark) { + if (inWallpaperColors == null) { + return false; + } + final List<Color> mainColors = inWallpaperColors.getMainColors(); final int mainColorsSize = mainColors.size(); + final boolean supportsDarkText = (inWallpaperColors.getColorHints() & + WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0; if (mainColorsSize == 0) { return false; @@ -120,7 +150,6 @@ public class Tonal implements ExtractionType { float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f); float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f); - final int textInversionIndex = h.length - 3; if (DEBUG) { StringBuilder builder = new StringBuilder("Tonal Palette - index: " + fitIndex + ". Main color: " + Integer.toHexString(getColorInt(fitIndex, h, s, l)) + @@ -135,21 +164,38 @@ public class Tonal implements ExtractionType { Log.d(TAG, builder.toString()); } + int primaryIndex = fitIndex; + int mainColor = getColorInt(primaryIndex, h, s, l); + + // We might want use the fallback in case the extracted color is brighter than our + // light fallback or darker than our dark fallback. + ColorUtils.colorToHSL(mainColor, mTmpHSL); + final float mainLuminosity = mTmpHSL[2]; + ColorUtils.colorToHSL(MAIN_COLOR_LIGHT, mTmpHSL); + final float lightLuminosity = mTmpHSL[2]; + if (mainLuminosity > lightLuminosity) { + return false; + } + ColorUtils.colorToHSL(MAIN_COLOR_DARK, mTmpHSL); + final float darkLuminosity = mTmpHSL[2]; + if (mainLuminosity < darkLuminosity) { + return false; + } + // Normal colors: // best fit + a 2 colors offset - int primaryIndex = fitIndex; + outColorsNormal.setMainColor(mainColor); int secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2); - outColorsNormal.setMainColor(getColorInt(primaryIndex, h, s, l)); outColorsNormal.setSecondaryColor(getColorInt(secondaryIndex, h, s, l)); // Dark colors: // Stops at 4th color, only lighter if dark text is supported - if (fitIndex < 2) { + if (supportsDarkText) { + primaryIndex = h.length - 1; + } else if (fitIndex < 2) { primaryIndex = 0; - } else if (fitIndex < textInversionIndex) { - primaryIndex = Math.min(fitIndex, 3); } else { - primaryIndex = h.length - 1; + primaryIndex = Math.min(fitIndex, 3); } secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2); outColorsDark.setMainColor(getColorInt(primaryIndex, h, s, l)); @@ -157,18 +203,17 @@ public class Tonal implements ExtractionType { // Extra Dark: // Stay close to dark colors until dark text is supported - if (fitIndex < 2) { + if (supportsDarkText) { + primaryIndex = h.length - 1; + } else if (fitIndex < 2) { primaryIndex = 0; - } else if (fitIndex < textInversionIndex) { - primaryIndex = 2; } else { - primaryIndex = h.length - 1; + primaryIndex = 2; } secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2); outColorsExtraDark.setMainColor(getColorInt(primaryIndex, h, s, l)); outColorsExtraDark.setSecondaryColor(getColorInt(secondaryIndex, h, s, l)); - final boolean supportsDarkText = fitIndex >= textInversionIndex; outColorsNormal.setSupportsDarkText(supportsDarkText); outColorsDark.setSupportsDarkText(supportsDarkText); outColorsExtraDark.setSupportsDarkText(supportsDarkText); @@ -181,6 +226,33 @@ public class Tonal implements ExtractionType { return true; } + private void applyFallback(@Nullable WallpaperColors inWallpaperColors, + GradientColors outColorsNormal, GradientColors outColorsDark, + GradientColors outColorsExtraDark) { + applyFallback(inWallpaperColors, outColorsNormal); + applyFallback(inWallpaperColors, outColorsDark); + applyFallback(inWallpaperColors, outColorsExtraDark); + } + + /** + * Sets the gradient to the light or dark fallbacks based on the current wallpaper colors. + * + * @param inWallpaperColors Colors to read. + * @param outGradientColors Destination. + */ + public static void applyFallback(@Nullable WallpaperColors inWallpaperColors, + @NonNull GradientColors outGradientColors) { + boolean light = inWallpaperColors != null + && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) + != 0; + int innerColor = light ? MAIN_COLOR_LIGHT : MAIN_COLOR_DARK; + int outerColor = light ? SECONDARY_COLOR_LIGHT : SECONDARY_COLOR_DARK; + + outGradientColors.setMainColor(innerColor); + outGradientColors.setSecondaryColor(outerColor); + outGradientColors.setSupportsDarkText(light); + } + private int getColorInt(int fitIndex, float[] h, float[] s, float[] l) { mTmpHSL[0] = fract(h[fitIndex]) * 360.0f; mTmpHSL[1] = s[fitIndex]; diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java index ccb81172c75c..3c895abd5e88 100644 --- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java +++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java @@ -16,6 +16,7 @@ package com.android.systemui.colorextraction; +import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; import android.os.Handler; @@ -47,10 +48,10 @@ public class SysuiColorExtractor extends ColorExtractor { @VisibleForTesting public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) { super(context, type); - mWpHiddenColors = new GradientColors(); - mWpHiddenColors.setMainColor(FALLBACK_COLOR); - mWpHiddenColors.setSecondaryColor(FALLBACK_COLOR); + + WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM); + updateDefaultGradients(systemColors); if (registerVisibility) { try { @@ -71,6 +72,24 @@ public class SysuiColorExtractor extends ColorExtractor { } } + private void updateDefaultGradients(WallpaperColors colors) { + Tonal.applyFallback(colors, mWpHiddenColors); + } + + @Override + public void onColorsChanged(WallpaperColors colors, int which) { + super.onColorsChanged(colors, which); + + if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { + updateDefaultGradients(colors); + } + } + + @VisibleForTesting + GradientColors getFallbackColors() { + return mWpHiddenColors; + } + /** * Get TYPE_NORMAL colors when wallpaper is visible, or fallback otherwise. * diff --git a/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java b/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java index a10aa5413ca9..b8535a3f5a40 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java @@ -61,6 +61,7 @@ public class SlashDrawable extends Drawable { private boolean mSlashed; private Mode mTintMode; private ColorStateList mTintList; + private boolean mAnimationEnabled = true; public SlashDrawable(Drawable d) { mDrawable = d; @@ -97,6 +98,10 @@ public class SlashDrawable extends Drawable { invalidateSelf(); } + public void setAnimationEnabled(boolean enabled) { + mAnimationEnabled = enabled; + } + // Animate this value on change private float mCurrentSlashLength; private final FloatProperty mSlashLengthProp = new FloatProperty<SlashDrawable>("slashLength") { @@ -119,12 +124,15 @@ public class SlashDrawable extends Drawable { final float end = mSlashed ? SLASH_HEIGHT / SCALE : 0f; final float start = mSlashed ? 0f : SLASH_HEIGHT / SCALE; - ObjectAnimator anim = ObjectAnimator.ofFloat(this, mSlashLengthProp, start, end); - anim.addUpdateListener((ValueAnimator valueAnimator) -> { + if (mAnimationEnabled) { + ObjectAnimator anim = ObjectAnimator.ofFloat(this, mSlashLengthProp, start, end); + anim.addUpdateListener((ValueAnimator valueAnimator) -> invalidateSelf()); + anim.setDuration(QS_ANIM_LENGTH); + anim.start(); + } else { + mCurrentSlashLength = end; invalidateSelf(); - }); - anim.setDuration(QS_ANIM_LENGTH); - anim.start(); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java index 5ab3927ff098..8074cb9b0443 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java @@ -98,10 +98,14 @@ public class QSIconViewImpl extends QSIconView { d.setAutoMirrored(false); d.setLayoutDirection(getLayoutDirection()); } - iv.setImageDrawable(d); - if (state.slash != null && iv instanceof SlashImageView) { - ((SlashImageView) iv).setState(state.slash); + + if (iv instanceof SlashImageView) { + ((SlashImageView) iv).setAnimationEnabled(shouldAnimate); + ((SlashImageView) iv).setState(state.slash, d); + } else { + iv.setImageDrawable(d); } + iv.setTag(R.id.qs_icon_tag, state.icon); iv.setTag(R.id.qs_slash_tag, state.slash); iv.setPadding(0, padding, 0, padding); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java index 315a815af100..13912fe0c16d 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/SlashImageView.java @@ -14,8 +14,10 @@ package com.android.systemui.qs.tileimpl; +import android.annotation.Nullable; import android.content.Context; import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; import android.widget.ImageView; import com.android.internal.annotations.VisibleForTesting; @@ -26,6 +28,7 @@ public class SlashImageView extends ImageView { @VisibleForTesting protected SlashDrawable mSlash; + private boolean mAnimationEnabled = true; public SlashImageView(Context context) { super(context); @@ -34,6 +37,7 @@ public class SlashImageView extends ImageView { private void ensureSlashDrawable() { if (mSlash == null) { mSlash = new SlashDrawable(getDrawable()); + mSlash.setAnimationEnabled(mAnimationEnabled); super.setImageDrawable(mSlash); } } @@ -46,13 +50,28 @@ public class SlashImageView extends ImageView { } else if (mSlash == null) { super.setImageDrawable(drawable); } else { + mSlash.setAnimationEnabled(mAnimationEnabled); mSlash.setDrawable(drawable); } } - public void setState(SlashState slashState) { + public void setAnimationEnabled(boolean enabled) { + mAnimationEnabled = enabled; + } + + private void setSlashState(@NonNull SlashState slashState) { ensureSlashDrawable(); mSlash.setRotation(slashState.rotation); mSlash.setSlashed(slashState.isSlashed); } + + public void setState(@Nullable SlashState state, @Nullable Drawable drawable) { + if (state != null) { + setImageDrawable(drawable); + setSlashState(state); + } else { + mSlash = null; + setImageDrawable(drawable); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java index e5aad0336061..ba92c451f764 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java @@ -32,7 +32,7 @@ public class AnimatedImageView extends ImageView { private final boolean mHasOverlappingRendering; AnimationDrawable mAnim; boolean mAttached; - private boolean mAllowAnimation; + private boolean mAllowAnimation = true; // Tracks the last image that was set, so that we don't refresh the image if it is exactly // the same as the previous one. If this is a resid, we track that. If it's a drawable, we diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java index a81188af85ef..690186e91f55 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java +++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java @@ -48,14 +48,12 @@ public class SysuiColorExtractorTests extends SysuiTestCase { @Test public void getColors_usesGreyIfWallpaperNotVisible() { - ColorExtractor.GradientColors fallbackColors = new ColorExtractor.GradientColors(); - fallbackColors.setMainColor(ColorExtractor.FALLBACK_COLOR); - fallbackColors.setSecondaryColor(ColorExtractor.FALLBACK_COLOR); - SysuiColorExtractor extractor = new SysuiColorExtractor(getContext(), new Tonal(), false); simulateEvent(extractor); extractor.setWallpaperVisible(false); + ColorExtractor.GradientColors fallbackColors = extractor.getFallbackColors(); + for (int which : sWhich) { for (int type : sTypes) { assertEquals("Not using fallback!", extractor.getColors(which, type), @@ -76,7 +74,6 @@ public class SysuiColorExtractorTests extends SysuiTestCase { outGradientColorsNormal.set(colors); outGradientColorsDark.set(colors); outGradientColorsExtraDark.set(colors); - return true; }, false); simulateEvent(extractor); extractor.setWallpaperVisible(true); @@ -91,7 +88,7 @@ public class SysuiColorExtractorTests extends SysuiTestCase { private void simulateEvent(SysuiColorExtractor extractor) { // Let's fake a color event - extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.BLACK), null, null, 0), + extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.GREEN), null, null, 0), WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK); } }
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java index aef584f8d986..9fe3e10b752e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/SlashImageViewTest.java @@ -38,16 +38,29 @@ public class SlashImageViewTest extends SysuiTestCase { private TestableSlashImageView mSlashView; @Test - public void testSetSlashStateCreatesSlashDrawable() { + public void testSetNonNullSlashStateCreatesSlashDrawable() { SlashState mockState = mock(SlashState.class); Drawable mockDrawable = mock(Drawable.class); mSlashView = new TestableSlashImageView(mContext); assertTrue(mSlashView.getSlashDrawable() == null); - mSlashView.setImageDrawable(mockDrawable); - mSlashView.setState(mockState); + mSlashView.setState(mockState, mockDrawable); + + assertTrue(mSlashView.getSlashDrawable() != null); + } + + @Test + public void testSetNullSlashStateRemovesSlashDrawable() { + SlashState mockState = mock(SlashState.class); + Drawable mockDrawable = mock(Drawable.class); + mSlashView = new TestableSlashImageView(mContext); + mSlashView.setState(mockState, mockDrawable); assertTrue(mSlashView.getSlashDrawable() != null); + + mSlashView.setState(null, mockDrawable); + + assertTrue(mSlashView.getSlashDrawable() == null); } @Test @@ -57,7 +70,7 @@ public class SlashImageViewTest extends SysuiTestCase { mSlashView = new TestableSlashImageView(mContext); mSlashView.setImageDrawable(mockDrawable); - mSlashView.setState(mockState); + mSlashView.setState(mockState, mockDrawable); mSlashView.setImageDrawable(null); assertTrue(mSlashView.getSlashDrawable() == null); diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 4b17625f7d36..6f68c7a1df5f 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -42,6 +42,7 @@ import static android.content.Intent.CATEGORY_LAUNCHER; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; +import static android.content.pm.ActivityInfo.CONFIG_ROTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE; @@ -2580,6 +2581,10 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo changes &= ~CONFIG_SMALLEST_SCREEN_SIZE; } } + // We don't want rotation to cause relaunches. + if ((changes & CONFIG_ROTATION) != 0) { + changes &= ~CONFIG_ROTATION; + } return changes; } diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java index 7c074dadadf9..303a577767ad 100644 --- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java +++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java @@ -118,27 +118,28 @@ public class UsbDescriptorParser { /** * @hide */ - public boolean parseDescriptors(byte[] descriptors) { - try { - mDescriptors.clear(); - - ByteStream stream = new ByteStream(descriptors); - while (stream.available() > 0) { - UsbDescriptor descriptor = allocDescriptor(stream); - if (descriptor != null) { - // Parse + public void parseDescriptors(byte[] descriptors) { + mDescriptors.clear(); + + ByteStream stream = new ByteStream(descriptors); + while (stream.available() > 0) { + UsbDescriptor descriptor = allocDescriptor(stream); + if (descriptor != null) { + // Parse + try { descriptor.parseRawDescriptors(stream); - mDescriptors.add(descriptor); - - // Clean up - descriptor.postParse(stream); + } catch (Exception ex) { + Log.e(TAG, "Exception parsing USB descriptors.", ex); } + + // Its OK to add the invalid descriptor as the postParse() + // routine will mark it as invalid. + mDescriptors.add(descriptor); + + // Clean up + descriptor.postParse(stream); } - return true; - } catch (Exception ex) { - Log.e(TAG, "Exception parsing USB descriptors.", ex); } - return false; } /** @@ -146,7 +147,11 @@ public class UsbDescriptorParser { */ public boolean parseDevice(String deviceAddr) { byte[] rawDescriptors = getRawDescriptors(deviceAddr); - return rawDescriptors != null && parseDescriptors(rawDescriptors); + if (rawDescriptors != null) { + parseDescriptors(rawDescriptors); + return true; + } + return false; } private native byte[] getRawDescriptors(String deviceAddr); diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java index 71821472f55e..0060901578cd 100644 --- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java +++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java @@ -62,21 +62,6 @@ public class ColorExtractorTest { } @Test - public void getColors_usesFallbackIfFails() { - ExtractionType alwaysFail = - (inWallpaperColors, outGradientColorsNormal, outGradientColorsDark, - outGradientColorsExtraDark) -> false; - ColorExtractor extractor = new ColorExtractor(mContext, alwaysFail); - GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM); - - assertEquals("Should be using the fallback color.", - colors.getMainColor(), ColorExtractor.FALLBACK_COLOR); - assertEquals("Should be using the fallback color.", - colors.getSecondaryColor(), ColorExtractor.FALLBACK_COLOR); - assertFalse("Dark text support should be false.", colors.supportsDarkText()); - } - - @Test public void getColors_usesExtractedColors() { GradientColors colorsExpectedNormal = new GradientColors(); colorsExpectedNormal.setMainColor(Color.RED); @@ -96,8 +81,6 @@ public class ColorExtractorTest { outGradientColorsNormal.set(colorsExpectedNormal); outGradientColorsDark.set(colorsExpectedDark); outGradientColorsExtraDark.set(colorsExpectedExtraDark); - // Successful extraction - return true; }; ColorExtractor extractor = new ColorExtractor(mContext, type); diff --git a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java index 1e3e8e91d9ef..d408b84109bc 100644 --- a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java +++ b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java @@ -40,6 +40,31 @@ import java.util.Arrays; public class TonalTest { @Test + public void extractInto_usesFallback() { + GradientColors normal = new GradientColors(); + Tonal tonal = new Tonal(); + tonal.extractInto(null, normal, new GradientColors(), + new GradientColors()); + assertFalse("Should use fallback color if WallpaperColors is null.", + normal.getMainColor() == Tonal.MAIN_COLOR_LIGHT); + } + + @Test + public void extractInto_usesFallbackWhenTooLightOrDark() { + GradientColors normal = new GradientColors(); + Tonal tonal = new Tonal(); + tonal.extractInto(new WallpaperColors(Color.valueOf(0xff000000), null, null, 0), + normal, new GradientColors(), new GradientColors()); + assertTrue("Should use fallback color if WallpaperColors is too dark.", + normal.getMainColor() == Tonal.MAIN_COLOR_DARK); + + tonal.extractInto(new WallpaperColors(Color.valueOf(0xffffffff), null, null, 0), + normal, new GradientColors(), new GradientColors()); + assertTrue("Should use fallback color if WallpaperColors is too light.", + normal.getMainColor() == Tonal.MAIN_COLOR_LIGHT); + } + + @Test public void colorRange_containsColor() { Tonal.ColorRange colorRange = new Tonal.ColorRange(new Range<>(0f, 50f), new Range<>(0f, 1f), new Range<>(0f, 1f)); @@ -72,8 +97,10 @@ public class TonalTest { // Make sure that palette generation will fail Tonal tonal = new Tonal(); - boolean success = tonal.extractInto(colors, new GradientColors(), new GradientColors(), + GradientColors normal = new GradientColors(); + tonal.extractInto(colors, normal, new GradientColors(), new GradientColors()); - assertFalse("Cannot generate a tonal palette from blacklisted colors ", success); + assertFalse("Cannot generate a tonal palette from blacklisted colors.", + normal.getMainColor() == Tonal.MAIN_COLOR_LIGHT); } } diff --git a/tests/radio/src/android/hardware/radio/tests/RadioTest.java b/tests/radio/src/android/hardware/radio/tests/RadioTest.java index b7a5ac4eb19b..b69d781a941b 100644 --- a/tests/radio/src/android/hardware/radio/tests/RadioTest.java +++ b/tests/radio/src/android/hardware/radio/tests/RadioTest.java @@ -22,6 +22,7 @@ import android.hardware.radio.RadioManager; import android.hardware.radio.RadioTuner; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.MediumTest; import android.util.Log; import java.lang.reflect.Constructor; @@ -54,6 +55,7 @@ import static org.testng.Assert.assertThrows; * A test for broadcast radio API. */ @RunWith(AndroidJUnit4.class) +@MediumTest public class RadioTest { private static final String TAG = "RadioTest"; |