Merge "Add API windowSplashScreenIconBackground(12/N)" into sc-dev

This commit is contained in:
Wei Sheng Shih
2021-03-19 11:44:37 +00:00
committed by Android (Google) Code Review
9 changed files with 329 additions and 67 deletions

View File

@@ -330,7 +330,7 @@ package android {
field public static final int apiKey = 16843281; // 0x1010211
field public static final int appCategory = 16844101; // 0x1010545
field public static final int appComponentFactory = 16844154; // 0x101057a
field public static final int attributionTags = 16844353; // 0x1010641
field public static final int attributionTags = 16844354; // 0x1010642
field public static final int author = 16843444; // 0x10102b4
field public static final int authorities = 16842776; // 0x1010018
field public static final int autoAdvanceViewId = 16843535; // 0x101030f
@@ -508,7 +508,7 @@ package android {
field public static final int dashGap = 16843175; // 0x10101a7
field public static final int dashWidth = 16843174; // 0x10101a6
field public static final int data = 16842798; // 0x101002e
field public static final int dataExtractionRules = 16844349; // 0x101063d
field public static final int dataExtractionRules = 16844350; // 0x101063e
field public static final int datePickerDialogTheme = 16843948; // 0x10104ac
field public static final int datePickerMode = 16843955; // 0x10104b3
field public static final int datePickerStyle = 16843612; // 0x101035c
@@ -530,8 +530,8 @@ package android {
field public static final int detailSocialSummary = 16843428; // 0x10102a4
field public static final int detailsElementBackground = 16843598; // 0x101034e
field public static final int dial = 16843010; // 0x1010102
field public static final int dialTint = 16844341; // 0x1010635
field public static final int dialTintMode = 16844342; // 0x1010636
field public static final int dialTint = 16844342; // 0x1010636
field public static final int dialTintMode = 16844343; // 0x1010637
field public static final int dialogCornerRadius = 16844145; // 0x1010571
field public static final int dialogIcon = 16843252; // 0x10101f4
field public static final int dialogLayout = 16843255; // 0x10101f7
@@ -729,14 +729,14 @@ package android {
field public static final int groupIndicator = 16843019; // 0x101010b
field public static final int gwpAsanMode = 16844310; // 0x1010616
field public static final int hand_hour = 16843011; // 0x1010103
field public static final int hand_hourTint = 16844343; // 0x1010637
field public static final int hand_hourTintMode = 16844344; // 0x1010638
field public static final int hand_hourTint = 16844344; // 0x1010638
field public static final int hand_hourTintMode = 16844345; // 0x1010639
field public static final int hand_minute = 16843012; // 0x1010104
field public static final int hand_minuteTint = 16844345; // 0x1010639
field public static final int hand_minuteTintMode = 16844346; // 0x101063a
field public static final int hand_minuteTint = 16844346; // 0x101063a
field public static final int hand_minuteTintMode = 16844347; // 0x101063b
field public static final int hand_second = 16844323; // 0x1010623
field public static final int hand_secondTint = 16844347; // 0x101063b
field public static final int hand_secondTintMode = 16844348; // 0x101063c
field public static final int hand_secondTint = 16844348; // 0x101063c
field public static final int hand_secondTintMode = 16844349; // 0x101063d
field public static final int handle = 16843354; // 0x101025a
field public static final int handleProfiling = 16842786; // 0x1010022
field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
@@ -820,7 +820,7 @@ package android {
field public static final int installLocation = 16843447; // 0x10102b7
field public static final int interactiveUiTimeout = 16844181; // 0x1010595
field public static final int interpolator = 16843073; // 0x1010141
field public static final int isAccessibilityTool = 16844352; // 0x1010640
field public static final int isAccessibilityTool = 16844353; // 0x1010641
field public static final int isAlwaysSyncable = 16843571; // 0x1010333
field public static final int isAsciiCapable = 16843753; // 0x10103e9
field public static final int isAuxiliary = 16843647; // 0x101037f
@@ -972,8 +972,8 @@ package android {
field public static final int maxLines = 16843091; // 0x1010153
field public static final int maxLongVersionCode = 16844163; // 0x1010583
field public static final int maxRecents = 16843846; // 0x1010446
field public static final int maxResizeHeight = 16844338; // 0x1010632
field public static final int maxResizeWidth = 16844337; // 0x1010631
field public static final int maxResizeHeight = 16844339; // 0x1010633
field public static final int maxResizeWidth = 16844338; // 0x1010632
field public static final int maxRows = 16843059; // 0x1010133
field public static final int maxSdkVersion = 16843377; // 0x1010271
field public static final int maxWidth = 16843039; // 0x101011f
@@ -1076,7 +1076,7 @@ package android {
field public static final int panelTextAppearance = 16842850; // 0x1010062
field public static final int parentActivityName = 16843687; // 0x10103a7
field @Deprecated public static final int password = 16843100; // 0x101015c
field public static final int passwordsActivity = 16844350; // 0x101063e
field public static final int passwordsActivity = 16844351; // 0x101063f
field public static final int path = 16842794; // 0x101002a
field public static final int pathAdvancedPattern = 16844320; // 0x1010620
field public static final int pathData = 16843781; // 0x1010405
@@ -1262,7 +1262,7 @@ package android {
field public static final int segmentedButtonStyle = 16843568; // 0x1010330
field public static final int selectAllOnFocus = 16843102; // 0x101015e
field public static final int selectable = 16843238; // 0x10101e6
field public static final int selectableAsDefault = 16844351; // 0x101063f
field public static final int selectableAsDefault = 16844352; // 0x1010640
field public static final int selectableItemBackground = 16843534; // 0x101030e
field public static final int selectableItemBackgroundBorderless = 16843868; // 0x101045c
field @Deprecated public static final int selectedDateVerticalBar = 16843591; // 0x1010347
@@ -1312,7 +1312,7 @@ package android {
field public static final int spinnerMode = 16843505; // 0x10102f1
field public static final int spinnerStyle = 16842881; // 0x1010081
field public static final int spinnersShown = 16843595; // 0x101034b
field public static final int splashScreenTheme = 16844336; // 0x1010630
field public static final int splashScreenTheme = 16844337; // 0x1010631
field public static final int splitMotionEvents = 16843503; // 0x10102ef
field public static final int splitName = 16844105; // 0x1010549
field public static final int splitTrack = 16843852; // 0x101044c
@@ -1395,7 +1395,7 @@ package android {
field public static final int supportsRtl = 16843695; // 0x10103af
field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
field public static final int supportsUploading = 16843419; // 0x101029b
field public static final int suppressesSpellChecker = 16844354; // 0x1010642
field public static final int suppressesSpellChecker = 16844355; // 0x1010643
field public static final int switchMinWidth = 16843632; // 0x1010370
field public static final int switchPadding = 16843633; // 0x1010371
field public static final int switchPreferenceStyle = 16843629; // 0x101036d
@@ -1410,8 +1410,8 @@ package android {
field public static final int tabWidgetStyle = 16842883; // 0x1010083
field public static final int tag = 16842961; // 0x10100d1
field public static final int targetActivity = 16843266; // 0x1010202
field public static final int targetCellHeight = 16844340; // 0x1010634
field public static final int targetCellWidth = 16844339; // 0x1010633
field public static final int targetCellHeight = 16844341; // 0x1010635
field public static final int targetCellWidth = 16844340; // 0x1010634
field public static final int targetClass = 16842799; // 0x101002f
field @Deprecated public static final int targetDescriptions = 16843680; // 0x10103a0
field public static final int targetId = 16843740; // 0x10103dc
@@ -1680,6 +1680,7 @@ package android {
field public static final int windowSplashScreenAnimationDuration = 16844334; // 0x101062e
field public static final int windowSplashScreenBackground = 16844332; // 0x101062c
field public static final int windowSplashScreenBrandingImage = 16844335; // 0x101062f
field public static final int windowSplashScreenIconBackgroundColor = 16844336; // 0x1010630
field @Deprecated public static final int windowSplashscreenContent = 16844132; // 0x1010564
field @Deprecated public static final int windowSwipeToDismiss = 16843763; // 0x10103f3
field public static final int windowTitleBackgroundStyle = 16842844; // 0x101005c

View File

@@ -2929,6 +2929,7 @@ package android.window {
public final class SplashScreenView extends android.widget.FrameLayout {
method @Nullable public android.view.View getBrandingView();
method @ColorInt public int getIconBackgroundColor();
}
public final class StartingWindowInfo implements android.os.Parcelable {

View File

@@ -17,8 +17,6 @@ package android.window;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -29,7 +27,6 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
@@ -47,6 +44,8 @@ import android.widget.FrameLayout;
import com.android.internal.R;
import com.android.internal.policy.DecorView;
import java.util.function.Consumer;
/**
* <p>The view which allows an activity to customize its splash screen exit animation.</p>
*
@@ -69,6 +68,7 @@ public final class SplashScreenView extends FrameLayout {
private boolean mNotCopyable;
private int mInitBackgroundColor;
private int mInitIconBackgroundColor;
private View mIconView;
private Bitmap mParceledIconBitmap;
private View mBrandingImageView;
@@ -76,8 +76,6 @@ public final class SplashScreenView extends FrameLayout {
private long mIconAnimationDuration;
private long mIconAnimationStart;
private Animatable mAnimatableIcon;
private ValueAnimator mAnimator;
// The host activity when transfer view to it.
private Activity mHostActivity;
// cache original window and status
@@ -94,6 +92,7 @@ public final class SplashScreenView extends FrameLayout {
private final Context mContext;
private int mIconSize;
private @ColorInt int mBackgroundColor;
private @ColorInt int mIconBackground;
private Bitmap mParceledIconBitmap;
private Drawable mIconDrawable;
private int mBrandingImageWidth;
@@ -114,6 +113,7 @@ public final class SplashScreenView extends FrameLayout {
public Builder createFromParcel(SplashScreenViewParcelable parcelable) {
mIconSize = parcelable.getIconSize();
mBackgroundColor = parcelable.getBackgroundColor();
mIconBackground = parcelable.getIconBackground();
if (parcelable.mIconBitmap != null) {
mIconDrawable = new BitmapDrawable(mContext.getResources(), parcelable.mIconBitmap);
mParceledIconBitmap = parcelable.mIconBitmap;
@@ -153,6 +153,14 @@ public final class SplashScreenView extends FrameLayout {
return this;
}
/**
* Set the background color for the icon.
*/
public Builder setIconBackground(int color) {
mIconBackground = color;
return this;
}
/**
* Set the animation duration if icon is animatable.
*/
@@ -179,6 +187,7 @@ public final class SplashScreenView extends FrameLayout {
final SplashScreenView view = (SplashScreenView)
layoutInflater.inflate(R.layout.splash_screen_view, null, false);
view.mInitBackgroundColor = mBackgroundColor;
view.mInitIconBackgroundColor = mIconBackground;
view.setBackgroundColor(mBackgroundColor);
view.mIconView = view.findViewById(R.id.splashscreen_icon_view);
view.mBrandingImageView = view.findViewById(R.id.splashscreen_branding_view);
@@ -266,43 +275,15 @@ public final class SplashScreenView extends FrameLayout {
}
void initIconAnimation(Drawable iconDrawable, long duration) {
if (iconDrawable instanceof Animatable) {
mAnimatableIcon = (Animatable) iconDrawable;
mAnimator = ValueAnimator.ofInt(0, 1);
mAnimator.setDuration(duration);
mAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
mIconAnimationStart = SystemClock.uptimeMillis();
mAnimatableIcon.start();
}
@Override
public void onAnimationEnd(Animator animation) {
mAnimatableIcon.stop();
}
@Override
public void onAnimationCancel(Animator animation) {
mAnimatableIcon.stop();
}
@Override
public void onAnimationRepeat(Animator animation) {
// do not repeat
mAnimatableIcon.stop();
}
});
if (!(iconDrawable instanceof SplashscreenIconDrawable)) {
return;
}
SplashscreenIconDrawable aniDrawable = (SplashscreenIconDrawable) iconDrawable;
aniDrawable.prepareAnimate(duration, this::animationStartCallback);
}
/**
* @hide
*/
public void startIntroAnimation() {
if (mAnimatableIcon != null) {
mAnimator.start();
}
private void animationStartCallback(long startAt) {
mIconAnimationStart = startAt;
}
/**
@@ -400,6 +381,15 @@ public final class SplashScreenView extends FrameLayout {
return mBrandingImageView;
}
/**
* Get the icon background color
* @hide
*/
@TestApi
public @ColorInt int getIconBackgroundColor() {
return mInitIconBackgroundColor;
}
/**
* Get the initial background color of this view.
* @hide
@@ -408,6 +398,23 @@ public final class SplashScreenView extends FrameLayout {
return mInitBackgroundColor;
}
/**
* A lightweight Drawable object to make the view drawing faster and keep this
* drawable masked by config_icon_mask.
* @hide
*/
public abstract static class SplashscreenIconDrawable extends Drawable {
/**
* Prepare the animation if this drawable also be animatable.
* @param duration The animation duration.
* @param startListener The callback listener used to receive the start of the animation.
* @return true if this drawable object can also be animated and it can be played now.
*/
protected boolean prepareAnimate(long duration, Consumer<Long> startListener) {
return false;
}
}
/**
* Use to create {@link SplashScreenView} object across process.
* @hide
@@ -415,6 +422,7 @@ public final class SplashScreenView extends FrameLayout {
public static class SplashScreenViewParcelable implements Parcelable {
private int mIconSize;
private int mBackgroundColor;
private int mIconBackground;
private Bitmap mIconBitmap;
private int mBrandingWidth;
@@ -428,7 +436,7 @@ public final class SplashScreenView extends FrameLayout {
ViewGroup.LayoutParams params = view.getIconView().getLayoutParams();
mIconSize = params.height;
mBackgroundColor = view.getInitBackgroundColor();
mIconBackground = view.getIconBackgroundColor();
mIconBitmap = copyDrawable(view.getIconView().getBackground());
mBrandingBitmap = copyDrawable(view.getBrandingView().getBackground());
params = view.getBrandingView().getLayoutParams();
@@ -469,6 +477,7 @@ public final class SplashScreenView extends FrameLayout {
mBrandingBitmap = source.readTypedObject(Bitmap.CREATOR);
mIconAnimationStart = source.readLong();
mIconAnimationDuration = source.readLong();
mIconBackground = source.readInt();
}
@Override
@@ -486,6 +495,7 @@ public final class SplashScreenView extends FrameLayout {
dest.writeTypedObject(mBrandingBitmap, flags);
dest.writeLong(mIconAnimationStart);
dest.writeLong(mIconAnimationDuration);
dest.writeInt(mIconBackground);
}
public static final @NonNull Parcelable.Creator<SplashScreenViewParcelable> CREATOR =
@@ -519,5 +529,9 @@ public final class SplashScreenView extends FrameLayout {
int getBackgroundColor() {
return mBackgroundColor;
}
int getIconBackground() {
return mIconBackground;
}
}
}

View File

@@ -2280,6 +2280,10 @@
<!-- Place an drawable image in the bottom of the starting window, it can be used to
represent the branding of the application. -->
<attr name="windowSplashScreenBrandingImage" format="reference"/>
<!-- Set a background behind the splash screen icon. This is useful if there is not enough
contrast between the window background and the icon. Note the shape would also be
masking like an icon. -->
<attr name="windowSplashScreenIconBackgroundColor" format="color"/>
</declare-styleable>
<!-- The set of attributes that describe a AlertDialog's theme. -->

View File

@@ -3071,6 +3071,7 @@
<public name="windowSplashScreenAnimatedIcon"/>
<public name="windowSplashScreenAnimationDuration"/>
<public name="windowSplashScreenBrandingImage"/>
<public name="windowSplashScreenIconBackgroundColor"/>
<public name="splashScreenTheme" />
<public name="maxResizeWidth" />
<public name="maxResizeHeight" />

View File

@@ -170,6 +170,7 @@ please see themes_device_defaults.xml.
<item name="windowSplashScreenBackground">@color/transparent</item>
<item name="windowSplashScreenAnimatedIcon">@null</item>
<item name="windowSplashScreenBrandingImage">@null</item>
<item name="windowSplashScreenIconBackgroundColor">@color/transparent</item>
<item name="windowClipToOutline">false</item>
<item name="windowFrame">@null</item>
<item name="windowNoTitle">false</item>

View File

@@ -16,6 +16,7 @@
package com.android.wm.shell.startingsurface;
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.app.ActivityThread;
import android.content.Context;
@@ -149,14 +150,16 @@ public class SplashscreenContentDrawer {
.setThemeDrawable(themeBGDrawable)
.setIconDrawable(iconDrawable)
.setIconAnimationDuration(animationDuration)
.setBrandingDrawable(attrs.mBrandingImage).build();
.setBrandingDrawable(attrs.mBrandingImage)
.setIconBackground(attrs.mIconBgColor).build();
}
private static class SplashScreenWindowAttrs {
static class SplashScreenWindowAttrs {
private int mWindowBgResId = 0;
private int mWindowBgColor = Color.TRANSPARENT;
private Drawable mReplaceIcon = null;
private Drawable mBrandingImage = null;
private int mIconBgColor = Color.TRANSPARENT;
private int mAnimationDuration = 0;
static SplashScreenWindowAttrs createWindowAttrs(Context context) {
@@ -172,6 +175,8 @@ public class SplashscreenContentDrawer {
R.styleable.Window_windowSplashScreenAnimationDuration, 0);
attrs.mBrandingImage = typedArray.getDrawable(
R.styleable.Window_windowSplashScreenBrandingImage);
attrs.mIconBgColor = typedArray.getColor(
R.styleable.Window_windowSplashScreenIconBackgroundColor, Color.TRANSPARENT);
typedArray.recycle();
if (DEBUG) {
Slog.d(TAG, "window attributes color: "
@@ -189,6 +194,7 @@ public class SplashscreenContentDrawer {
private int mIconAnimationDuration;
private Context mContext;
private Drawable mBrandingDrawable;
private @ColorInt int mIconBackground;
// result
private boolean mBuildComplete = false;
@@ -221,6 +227,12 @@ public class SplashscreenContentDrawer {
return this;
}
StartingWindowViewBuilder setIconBackground(int color) {
mIconBackground = color;
mBuildComplete = false;
return this;
}
StartingWindowViewBuilder setContext(Context context) {
mContext = context;
mBuildComplete = false;
@@ -244,7 +256,9 @@ public class SplashscreenContentDrawer {
if (DEBUG) {
Slog.d(TAG, "The icon is not an AdaptiveIconDrawable");
}
mFinalIconDrawable = mIconDrawable;
mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable(
mIconBackground != Color.TRANSPARENT
? mIconBackground : mThemeColor, mIconDrawable);
}
final int iconSize = mFinalIconDrawable != null ? (int) (mIconSize * mScale) : 0;
mCachedResult = fillViewWithIcon(mContext, iconSize, mFinalIconDrawable);
@@ -252,6 +266,12 @@ public class SplashscreenContentDrawer {
return mCachedResult;
}
private void createIconDrawable(Drawable iconDrawable) {
mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable(
mIconBackground != Color.TRANSPARENT
? mIconBackground : mThemeColor, iconDrawable);
}
private void processThemeColor() {
final DrawableColorTester themeBGTester =
new DrawableColorTester(mThemeBGDrawable, true /* filterTransparent */);
@@ -307,8 +327,7 @@ public class SplashscreenContentDrawer {
}
// Using AdaptiveIconDrawable here can help keep the shape consistent with the
// current settings.
mFinalIconDrawable = new AdaptiveIconDrawable(
new ColorDrawable(mThemeColor), iconForeground);
createIconDrawable(iconForeground);
// Reference AdaptiveIcon description, outer is 108 and inner is 72, so we
// should enlarge the size 108/72 if we only draw adaptiveIcon's foreground.
if (foreIconTester.nonTransparentRatio() < ENLARGE_FOREGROUND_ICON_THRESHOLD) {
@@ -318,7 +337,11 @@ public class SplashscreenContentDrawer {
if (DEBUG) {
Slog.d(TAG, "makeSplashScreenContentView: draw whole icon");
}
mFinalIconDrawable = adaptiveIconDrawable;
if (mIconBackground != Color.TRANSPARENT) {
createIconDrawable(adaptiveIconDrawable);
} else {
mFinalIconDrawable = adaptiveIconDrawable;
}
}
return true;
}
@@ -326,7 +349,8 @@ public class SplashscreenContentDrawer {
private SplashScreenView fillViewWithIcon(Context context,
int iconSize, Drawable iconDrawable) {
final SplashScreenView.Builder builder = new SplashScreenView.Builder(context);
builder.setIconSize(iconSize).setBackgroundColor(mThemeColor);
builder.setIconSize(iconSize).setBackgroundColor(mThemeColor)
.setIconBackground(mIconBackground);
if (iconDrawable != null) {
builder.setCenterViewDrawable(iconDrawable);
}

View File

@@ -0,0 +1,217 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell.startingsurface;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
import android.util.PathParser;
import android.window.SplashScreenView;
import com.android.internal.R;
import java.util.function.Consumer;
/**
* Creating a lightweight Drawable object used for splash screen.
* @hide
*/
public class SplashscreenIconDrawableFactory {
static Drawable makeIconDrawable(@ColorInt int backgroundColor,
@NonNull Drawable foregroundDrawable) {
if (foregroundDrawable instanceof Animatable) {
return new AnimatableIconDrawable(backgroundColor, foregroundDrawable);
} else {
// TODO make a light weight drawable instead of AdaptiveIconDrawable
return new AdaptiveIconDrawable(new ColorDrawable(backgroundColor), foregroundDrawable);
}
}
/**
* A lightweight AdaptiveIconDrawable which support foreground to be Animatable, and keep this
* drawable masked by config_icon_mask.
* @hide
*/
private static class AnimatableIconDrawable extends SplashScreenView.SplashscreenIconDrawable {
private static final float MASK_SIZE = AdaptiveIconDrawable.MASK_SIZE;
private static final float EXTRA_INSET_PERCENTAGE = 1 / 4f;
private static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE);
private final Rect mTmpOutRect = new Rect();
/**
* Clip path defined in R.string.config_icon_mask.
*/
private static Path sMask;
/**
* Scaled mask based on the view bounds.
*/
private final Path mMask;
private final Path mMaskScaleOnly;
private final Matrix mMaskMatrix;
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Drawable mForegroundDrawable;
private Animatable mAnimatableIcon;
private Animator mIconAnimator;
private boolean mAnimationTriggered;
private long mIconAnimationStart;
AnimatableIconDrawable(@ColorInt int backgroundColor, Drawable foregroundDrawable) {
mForegroundDrawable = foregroundDrawable;
final Resources r = Resources.getSystem();
sMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
mMask = new Path(sMask);
mMaskScaleOnly = new Path(mMask);
mMaskMatrix = new Matrix();
mPaint.setColor(backgroundColor);
mPaint.setStyle(Paint.Style.FILL);
if (mForegroundDrawable != null) {
mForegroundDrawable.setCallback(mCallback);
}
}
@Override
protected boolean prepareAnimate(long duration, Consumer<Long> startListener) {
mAnimatableIcon = (Animatable) mForegroundDrawable;
mIconAnimator = ValueAnimator.ofInt(0, 1);
mIconAnimator.setDuration(duration);
mIconAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
mIconAnimationStart = SystemClock.uptimeMillis();
if (startListener != null) {
startListener.accept(mIconAnimationStart);
}
mAnimatableIcon.start();
}
@Override
public void onAnimationEnd(Animator animation) {
mAnimatableIcon.stop();
}
@Override
public void onAnimationCancel(Animator animation) {
mAnimatableIcon.stop();
}
@Override
public void onAnimationRepeat(Animator animation) {
// do not repeat
mAnimatableIcon.stop();
}
});
return true;
}
@Override
protected void onBoundsChange(Rect bounds) {
if (bounds.isEmpty()) {
return;
}
updateLayerBounds(bounds);
}
private final Callback mCallback = new Callback() {
@Override
public void invalidateDrawable(@NonNull Drawable who) {
invalidateSelf();
}
@Override
public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
scheduleSelf(what, when);
}
@Override
public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
unscheduleSelf(what);
}
};
private void updateLayerBounds(Rect bounds) {
int cX = bounds.width() / 2;
int cY = bounds.height() / 2;
int insetWidth = (int) (bounds.width() / (DEFAULT_VIEW_PORT_SCALE * 2));
int insetHeight = (int) (bounds.height() / (DEFAULT_VIEW_PORT_SCALE * 2));
final Rect outRect = mTmpOutRect;
outRect.set(cX - insetWidth, cY - insetHeight, cX + insetWidth, cY + insetHeight);
if (mForegroundDrawable != null) {
mForegroundDrawable.setBounds(outRect);
}
// reset everything that depends on the view bounds
mMaskMatrix.setScale(bounds.width() / MASK_SIZE, bounds.height() / MASK_SIZE);
sMask.transform(mMaskMatrix, mMaskScaleOnly);
invalidateSelf();
}
private void ensureAnimationStarted() {
if (mAnimationTriggered) {
return;
}
if (mIconAnimator != null && !mIconAnimator.isRunning()) {
mIconAnimator.start();
}
mAnimationTriggered = true;
}
@Override
public void draw(Canvas canvas) {
if (mMaskScaleOnly != null) {
canvas.drawPath(mMaskScaleOnly, mPaint);
}
if (mForegroundDrawable != null) {
ensureAnimationStarted();
mForegroundDrawable.draw(canvas);
}
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
if (mForegroundDrawable != null) {
mForegroundDrawable.setColorFilter(colorFilter);
}
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
}

View File

@@ -362,7 +362,6 @@ public class StartingSurfaceDrawer {
final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
if (record != null) {
record.setSplashScreenView(splashScreenView);
splashScreenView.startIntroAnimation();
}
}