Merge "Do not draw icon background if it shouldn't be seen" into sc-dev
This commit is contained in:
@@ -3176,7 +3176,6 @@ package android.window {
|
|||||||
|
|
||||||
public final class SplashScreenView extends android.widget.FrameLayout {
|
public final class SplashScreenView extends android.widget.FrameLayout {
|
||||||
method @Nullable public android.view.View getBrandingView();
|
method @Nullable public android.view.View getBrandingView();
|
||||||
method @ColorInt public int getIconBackgroundColor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class StartingWindowInfo implements android.os.Parcelable {
|
public final class StartingWindowInfo implements android.os.Parcelable {
|
||||||
|
|||||||
@@ -89,11 +89,11 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
private boolean mNotCopyable;
|
private boolean mNotCopyable;
|
||||||
private boolean mIsCopied;
|
private boolean mIsCopied;
|
||||||
private int mInitBackgroundColor;
|
private int mInitBackgroundColor;
|
||||||
private int mInitIconBackgroundColor;
|
|
||||||
private View mIconView;
|
private View mIconView;
|
||||||
private Bitmap mParceledIconBitmap;
|
private Bitmap mParceledIconBitmap;
|
||||||
private View mBrandingImageView;
|
private View mBrandingImageView;
|
||||||
private Bitmap mParceledBrandingBitmap;
|
private Bitmap mParceledBrandingBitmap;
|
||||||
|
private Bitmap mParceledIconBackgroundBitmap;
|
||||||
private Duration mIconAnimationDuration;
|
private Duration mIconAnimationDuration;
|
||||||
private Instant mIconAnimationStart;
|
private Instant mIconAnimationStart;
|
||||||
|
|
||||||
@@ -130,11 +130,12 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private int mIconSize;
|
private int mIconSize;
|
||||||
private @ColorInt int mBackgroundColor;
|
private @ColorInt int mBackgroundColor;
|
||||||
private @ColorInt int mIconBackground;
|
|
||||||
private Bitmap mParceledIconBitmap;
|
private Bitmap mParceledIconBitmap;
|
||||||
|
private Bitmap mParceledIconBackgroundBitmap;
|
||||||
private Drawable mIconDrawable;
|
private Drawable mIconDrawable;
|
||||||
// It is only set for legacy splash screen which won't be sent across processes.
|
// It is only set for legacy splash screen which won't be sent across processes.
|
||||||
private Drawable mOverlayDrawable;
|
private Drawable mOverlayDrawable;
|
||||||
|
private Drawable mIconBackground;
|
||||||
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
|
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
|
||||||
private RemoteCallback mClientCallback;
|
private RemoteCallback mClientCallback;
|
||||||
private int mBrandingImageWidth;
|
private int mBrandingImageWidth;
|
||||||
@@ -155,7 +156,6 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
public Builder createFromParcel(SplashScreenViewParcelable parcelable) {
|
public Builder createFromParcel(SplashScreenViewParcelable parcelable) {
|
||||||
mIconSize = parcelable.getIconSize();
|
mIconSize = parcelable.getIconSize();
|
||||||
mBackgroundColor = parcelable.getBackgroundColor();
|
mBackgroundColor = parcelable.getBackgroundColor();
|
||||||
mIconBackground = parcelable.getIconBackground();
|
|
||||||
mSurfacePackage = parcelable.mSurfacePackage;
|
mSurfacePackage = parcelable.mSurfacePackage;
|
||||||
if (mSurfacePackage == null && parcelable.mIconBitmap != null) {
|
if (mSurfacePackage == null && parcelable.mIconBitmap != null) {
|
||||||
// We only create a Bitmap copies of immobile icons since animated icon are using
|
// We only create a Bitmap copies of immobile icons since animated icon are using
|
||||||
@@ -163,6 +163,11 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
mIconDrawable = new BitmapDrawable(mContext.getResources(), parcelable.mIconBitmap);
|
mIconDrawable = new BitmapDrawable(mContext.getResources(), parcelable.mIconBitmap);
|
||||||
mParceledIconBitmap = parcelable.mIconBitmap;
|
mParceledIconBitmap = parcelable.mIconBitmap;
|
||||||
}
|
}
|
||||||
|
if (parcelable.mIconBackground != null) {
|
||||||
|
mIconBackground = new BitmapDrawable(mContext.getResources(),
|
||||||
|
parcelable.mIconBackground);
|
||||||
|
mParceledIconBackgroundBitmap = parcelable.mIconBackground;
|
||||||
|
}
|
||||||
if (parcelable.mBrandingBitmap != null) {
|
if (parcelable.mBrandingBitmap != null) {
|
||||||
setBrandingDrawable(new BitmapDrawable(mContext.getResources(),
|
setBrandingDrawable(new BitmapDrawable(mContext.getResources(),
|
||||||
parcelable.mBrandingBitmap), parcelable.mBrandingWidth,
|
parcelable.mBrandingBitmap), parcelable.mBrandingWidth,
|
||||||
@@ -213,8 +218,8 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
/**
|
/**
|
||||||
* Set the background color for the icon.
|
* Set the background color for the icon.
|
||||||
*/
|
*/
|
||||||
public Builder setIconBackground(int color) {
|
public Builder setIconBackground(Drawable iconBackground) {
|
||||||
mIconBackground = color;
|
mIconBackground = iconBackground;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +250,6 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
final SplashScreenView view = (SplashScreenView)
|
final SplashScreenView view = (SplashScreenView)
|
||||||
layoutInflater.inflate(R.layout.splash_screen_view, null, false);
|
layoutInflater.inflate(R.layout.splash_screen_view, null, false);
|
||||||
view.mInitBackgroundColor = mBackgroundColor;
|
view.mInitBackgroundColor = mBackgroundColor;
|
||||||
view.mInitIconBackgroundColor = mIconBackground;
|
|
||||||
if (mOverlayDrawable != null) {
|
if (mOverlayDrawable != null) {
|
||||||
view.setBackground(mOverlayDrawable);
|
view.setBackground(mOverlayDrawable);
|
||||||
} else {
|
} else {
|
||||||
@@ -263,25 +267,29 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
mIconAnimationDuration != null ? mIconAnimationDuration.toMillis() : 0);
|
mIconAnimationDuration != null ? mIconAnimationDuration.toMillis() : 0);
|
||||||
view.mIconAnimationStart = mIconAnimationStart;
|
view.mIconAnimationStart = mIconAnimationStart;
|
||||||
view.mIconAnimationDuration = mIconAnimationDuration;
|
view.mIconAnimationDuration = mIconAnimationDuration;
|
||||||
} else {
|
} else if (mIconSize != 0) {
|
||||||
view.mIconView = view.findViewById(R.id.splashscreen_icon_view);
|
ImageView imageView = view.findViewById(R.id.splashscreen_icon_view);
|
||||||
if (mIconSize != 0) {
|
assert imageView != null;
|
||||||
final ViewGroup.LayoutParams params = view.mIconView.getLayoutParams();
|
|
||||||
params.width = mIconSize;
|
final ViewGroup.LayoutParams params = imageView.getLayoutParams();
|
||||||
params.height = mIconSize;
|
params.width = mIconSize;
|
||||||
view.mIconView.setLayoutParams(params);
|
params.height = mIconSize;
|
||||||
if (mIconDrawable != null) {
|
imageView.setLayoutParams(params);
|
||||||
view.mIconView.setBackground(mIconDrawable);
|
if (mIconDrawable != null) {
|
||||||
}
|
imageView.setImageDrawable(mIconDrawable);
|
||||||
}
|
}
|
||||||
|
if (mIconBackground != null) {
|
||||||
|
imageView.setBackground(mIconBackground);
|
||||||
|
}
|
||||||
|
view.mIconView = imageView;
|
||||||
}
|
}
|
||||||
if (mOverlayDrawable != null || mIconDrawable == null) {
|
if (mOverlayDrawable != null || mIconDrawable == null) {
|
||||||
view.setNotCopyable();
|
view.setNotCopyable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mParceledIconBitmap != null) {
|
view.mParceledIconBackgroundBitmap = mParceledIconBackgroundBitmap;
|
||||||
view.mParceledIconBitmap = mParceledIconBitmap;
|
view.mParceledIconBitmap = mParceledIconBitmap;
|
||||||
}
|
|
||||||
// branding image
|
// branding image
|
||||||
if (mBrandingImageHeight > 0 && mBrandingImageWidth > 0 && mBrandingDrawable != null) {
|
if (mBrandingImageHeight > 0 && mBrandingImageWidth > 0 && mBrandingDrawable != null) {
|
||||||
final ViewGroup.LayoutParams params = view.mBrandingImageView.getLayoutParams();
|
final ViewGroup.LayoutParams params = view.mBrandingImageView.getLayoutParams();
|
||||||
@@ -310,6 +318,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
private SurfaceView createSurfaceView(@NonNull SplashScreenView view) {
|
private SurfaceView createSurfaceView(@NonNull SplashScreenView view) {
|
||||||
final SurfaceView surfaceView = new SurfaceView(view.getContext());
|
final SurfaceView surfaceView = new SurfaceView(view.getContext());
|
||||||
surfaceView.setPadding(0, 0, 0, 0);
|
surfaceView.setPadding(0, 0, 0, 0);
|
||||||
|
surfaceView.setBackground(mIconBackground);
|
||||||
if (mSurfacePackage == null) {
|
if (mSurfacePackage == null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG,
|
Log.d(TAG,
|
||||||
@@ -475,7 +484,11 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
setVisibility(GONE);
|
setVisibility(GONE);
|
||||||
if (mParceledIconBitmap != null) {
|
if (mParceledIconBitmap != null) {
|
||||||
mIconView.setBackground(null);
|
if (mIconView instanceof ImageView) {
|
||||||
|
((ImageView) mIconView).setImageDrawable(null);
|
||||||
|
} else if (mIconView != null) {
|
||||||
|
mIconView.setBackground(null);
|
||||||
|
}
|
||||||
mParceledIconBitmap.recycle();
|
mParceledIconBitmap.recycle();
|
||||||
mParceledIconBitmap = null;
|
mParceledIconBitmap = null;
|
||||||
}
|
}
|
||||||
@@ -484,6 +497,13 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
mParceledBrandingBitmap.recycle();
|
mParceledBrandingBitmap.recycle();
|
||||||
mParceledBrandingBitmap = null;
|
mParceledBrandingBitmap = null;
|
||||||
}
|
}
|
||||||
|
if (mParceledIconBackgroundBitmap != null) {
|
||||||
|
if (mIconView != null) {
|
||||||
|
mIconView.setBackground(null);
|
||||||
|
}
|
||||||
|
mParceledIconBackgroundBitmap.recycle();
|
||||||
|
mParceledIconBackgroundBitmap = null;
|
||||||
|
}
|
||||||
if (mWindow != null) {
|
if (mWindow != null) {
|
||||||
final DecorView decorView = (DecorView) mWindow.peekDecorView();
|
final DecorView decorView = (DecorView) mWindow.peekDecorView();
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -599,15 +619,6 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
return mBrandingImageView;
|
return mBrandingImageView;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the icon background color
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
@TestApi
|
|
||||||
public @ColorInt int getIconBackgroundColor() {
|
|
||||||
return mInitIconBackgroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the initial background color of this view.
|
* Get the initial background color of this view.
|
||||||
* @hide
|
* @hide
|
||||||
@@ -637,7 +648,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
public static class SplashScreenViewParcelable implements Parcelable {
|
public static class SplashScreenViewParcelable implements Parcelable {
|
||||||
private int mIconSize;
|
private int mIconSize;
|
||||||
private int mBackgroundColor;
|
private int mBackgroundColor;
|
||||||
private int mIconBackground;
|
private Bitmap mIconBackground;
|
||||||
|
|
||||||
private Bitmap mIconBitmap = null;
|
private Bitmap mIconBitmap = null;
|
||||||
private int mBrandingWidth;
|
private int mBrandingWidth;
|
||||||
@@ -653,11 +664,11 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
public SplashScreenViewParcelable(SplashScreenView view) {
|
public SplashScreenViewParcelable(SplashScreenView view) {
|
||||||
mIconSize = view.mIconView.getWidth();
|
mIconSize = view.mIconView.getWidth();
|
||||||
mBackgroundColor = view.getInitBackgroundColor();
|
mBackgroundColor = view.getInitBackgroundColor();
|
||||||
mIconBackground = view.getIconBackgroundColor();
|
mIconBackground = copyDrawable(view.getIconView().getBackground());
|
||||||
mSurfacePackage = view.mSurfacePackageCopy;
|
mSurfacePackage = view.mSurfacePackageCopy;
|
||||||
if (mSurfacePackage == null) {
|
if (mSurfacePackage == null) {
|
||||||
// We only need to copy the drawable if we are not using a SurfaceView
|
// We only need to copy the drawable if we are not using a SurfaceView
|
||||||
mIconBitmap = copyDrawable(view.getIconView().getBackground());
|
mIconBitmap = copyDrawable(((ImageView) view.getIconView()).getDrawable());
|
||||||
}
|
}
|
||||||
mBrandingBitmap = copyDrawable(view.getBrandingView().getBackground());
|
mBrandingBitmap = copyDrawable(view.getBrandingView().getBackground());
|
||||||
|
|
||||||
@@ -703,7 +714,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
mBrandingBitmap = source.readTypedObject(Bitmap.CREATOR);
|
mBrandingBitmap = source.readTypedObject(Bitmap.CREATOR);
|
||||||
mIconAnimationStartMillis = source.readLong();
|
mIconAnimationStartMillis = source.readLong();
|
||||||
mIconAnimationDurationMillis = source.readLong();
|
mIconAnimationDurationMillis = source.readLong();
|
||||||
mIconBackground = source.readInt();
|
mIconBackground = source.readTypedObject(Bitmap.CREATOR);
|
||||||
mSurfacePackage = source.readTypedObject(SurfaceControlViewHost.SurfacePackage.CREATOR);
|
mSurfacePackage = source.readTypedObject(SurfaceControlViewHost.SurfacePackage.CREATOR);
|
||||||
mClientCallback = source.readTypedObject(RemoteCallback.CREATOR);
|
mClientCallback = source.readTypedObject(RemoteCallback.CREATOR);
|
||||||
}
|
}
|
||||||
@@ -723,7 +734,7 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
dest.writeTypedObject(mBrandingBitmap, flags);
|
dest.writeTypedObject(mBrandingBitmap, flags);
|
||||||
dest.writeLong(mIconAnimationStartMillis);
|
dest.writeLong(mIconAnimationStartMillis);
|
||||||
dest.writeLong(mIconAnimationDurationMillis);
|
dest.writeLong(mIconAnimationDurationMillis);
|
||||||
dest.writeInt(mIconBackground);
|
dest.writeTypedObject(mIconBackground, flags);
|
||||||
dest.writeTypedObject(mSurfacePackage, flags);
|
dest.writeTypedObject(mSurfacePackage, flags);
|
||||||
dest.writeTypedObject(mClientCallback, flags);
|
dest.writeTypedObject(mClientCallback, flags);
|
||||||
}
|
}
|
||||||
@@ -760,10 +771,6 @@ public final class SplashScreenView extends FrameLayout {
|
|||||||
return mBackgroundColor;
|
return mBackgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getIconBackground() {
|
|
||||||
return mIconBackground;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link RemoteCallback} that will be called by the client to notify the shell
|
* Sets the {@link RemoteCallback} that will be called by the client to notify the shell
|
||||||
* of the removal of the {@link SplashScreenView}.
|
* of the removal of the {@link SplashScreenView}.
|
||||||
|
|||||||
@@ -21,12 +21,11 @@
|
|||||||
android:padding="0dp"
|
android:padding="0dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<View android:id="@+id/splashscreen_icon_view"
|
<ImageView android:id="@+id/splashscreen_icon_view"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:padding="0dp"
|
android:padding="0dp"
|
||||||
android:background="@null"
|
|
||||||
android:contentDescription="@string/splash_screen_view_icon_description"/>
|
android:contentDescription="@string/splash_screen_view_icon_description"/>
|
||||||
|
|
||||||
<View android:id="@+id/splashscreen_branding_view"
|
<View android:id="@+id/splashscreen_branding_view"
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCRE
|
|||||||
import android.annotation.ColorInt;
|
import android.annotation.ColorInt;
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.app.ActivityThread;
|
import android.app.ActivityThread;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -315,7 +316,7 @@ public class SplashscreenContentDrawer {
|
|||||||
private Drawable mOverlayDrawable;
|
private Drawable mOverlayDrawable;
|
||||||
private int mSuggestType;
|
private int mSuggestType;
|
||||||
private int mThemeColor;
|
private int mThemeColor;
|
||||||
private Drawable mFinalIconDrawable;
|
private Drawable[] mFinalIconDrawables;
|
||||||
private int mFinalIconSize = mIconSize;
|
private int mFinalIconSize = mIconSize;
|
||||||
|
|
||||||
StartingWindowViewBuilder(@NonNull Context context, @NonNull ActivityInfo aInfo) {
|
StartingWindowViewBuilder(@NonNull Context context, @NonNull ActivityInfo aInfo) {
|
||||||
@@ -347,12 +348,13 @@ public class SplashscreenContentDrawer {
|
|||||||
animationDuration = 0;
|
animationDuration = 0;
|
||||||
mFinalIconSize = 0;
|
mFinalIconSize = 0;
|
||||||
} else if (mTmpAttrs.mSplashScreenIcon != null) {
|
} else if (mTmpAttrs.mSplashScreenIcon != null) {
|
||||||
// replaced icon, don't process
|
// Using the windowSplashScreenAnimatedIcon attribute
|
||||||
iconDrawable = mTmpAttrs.mSplashScreenIcon;
|
iconDrawable = mTmpAttrs.mSplashScreenIcon;
|
||||||
animationDuration = mTmpAttrs.mAnimationDuration;
|
animationDuration = mTmpAttrs.mAnimationDuration;
|
||||||
|
|
||||||
// There is no background below the icon, so scale the icon up
|
// There is no background below the icon, so scale the icon up
|
||||||
if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT) {
|
if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT
|
||||||
|
|| mTmpAttrs.mIconBgColor == mThemeColor) {
|
||||||
mFinalIconSize *= NO_BACKGROUND_SCALE;
|
mFinalIconSize *= NO_BACKGROUND_SCALE;
|
||||||
}
|
}
|
||||||
createIconDrawable(iconDrawable, false);
|
createIconDrawable(iconDrawable, false);
|
||||||
@@ -383,7 +385,7 @@ public class SplashscreenContentDrawer {
|
|||||||
animationDuration = 0;
|
animationDuration = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fillViewWithIcon(mFinalIconSize, mFinalIconDrawable, animationDuration);
|
return fillViewWithIcon(mFinalIconSize, mFinalIconDrawables, animationDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ShapeIconFactory extends BaseIconFactory {
|
private class ShapeIconFactory extends BaseIconFactory {
|
||||||
@@ -394,12 +396,11 @@ public class SplashscreenContentDrawer {
|
|||||||
|
|
||||||
private void createIconDrawable(Drawable iconDrawable, boolean legacy) {
|
private void createIconDrawable(Drawable iconDrawable, boolean legacy) {
|
||||||
if (legacy) {
|
if (legacy) {
|
||||||
mFinalIconDrawable = SplashscreenIconDrawableFactory.makeLegacyIconDrawable(
|
mFinalIconDrawables = SplashscreenIconDrawableFactory.makeLegacyIconDrawable(
|
||||||
iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
|
iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
|
||||||
} else {
|
} else {
|
||||||
mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable(
|
mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable(
|
||||||
mTmpAttrs.mIconBgColor != Color.TRANSPARENT
|
mTmpAttrs.mIconBgColor, mThemeColor,
|
||||||
? mTmpAttrs.mIconBgColor : mThemeColor,
|
|
||||||
iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
|
iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -461,18 +462,24 @@ public class SplashscreenContentDrawer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SplashScreenView fillViewWithIcon(int iconSize, Drawable iconDrawable,
|
private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable,
|
||||||
int animationDuration) {
|
int animationDuration) {
|
||||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon");
|
Drawable foreground = null;
|
||||||
final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext);
|
Drawable background = null;
|
||||||
builder.setBackgroundColor(mThemeColor);
|
|
||||||
builder.setOverlayDrawable(mOverlayDrawable);
|
|
||||||
if (iconDrawable != null) {
|
if (iconDrawable != null) {
|
||||||
builder.setIconSize(iconSize)
|
foreground = iconDrawable.length > 0 ? iconDrawable[0] : null;
|
||||||
.setIconBackground(mTmpAttrs.mIconBgColor)
|
background = iconDrawable.length > 1 ? iconDrawable[1] : null;
|
||||||
.setCenterViewDrawable(iconDrawable)
|
|
||||||
.setAnimationDurationMillis(animationDuration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon");
|
||||||
|
final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext)
|
||||||
|
.setBackgroundColor(mThemeColor)
|
||||||
|
.setOverlayDrawable(mOverlayDrawable)
|
||||||
|
.setIconSize(iconSize)
|
||||||
|
.setIconBackground(background)
|
||||||
|
.setCenterViewDrawable(foreground)
|
||||||
|
.setAnimationDurationMillis(animationDuration);
|
||||||
|
|
||||||
if (mSuggestType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
|
if (mSuggestType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
|
||||||
&& mTmpAttrs.mBrandingImage != null) {
|
&& mTmpAttrs.mBrandingImage != null) {
|
||||||
builder.setBrandingDrawable(mTmpAttrs.mBrandingImage, mBrandingImageWidth,
|
builder.setBrandingDrawable(mTmpAttrs.mBrandingImage, mBrandingImageWidth,
|
||||||
|
|||||||
@@ -22,9 +22,11 @@ import android.animation.Animator;
|
|||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.ColorInt;
|
import android.annotation.ColorInt;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.ColorFilter;
|
import android.graphics.ColorFilter;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
@@ -33,7 +35,6 @@ import android.graphics.PixelFormat;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.AdaptiveIconDrawable;
|
import android.graphics.drawable.AdaptiveIconDrawable;
|
||||||
import android.graphics.drawable.Animatable;
|
import android.graphics.drawable.Animatable;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
@@ -44,32 +45,55 @@ import com.android.internal.R;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creating a lightweight Drawable object used for splash screen.
|
* Creating a lightweight Drawable object used for splash screen.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class SplashscreenIconDrawableFactory {
|
public class SplashscreenIconDrawableFactory {
|
||||||
|
|
||||||
static Drawable makeIconDrawable(@ColorInt int backgroundColor,
|
/**
|
||||||
|
* @return An array containing the foreground drawable at index 0 and if needed a background
|
||||||
|
* drawable at index 1.
|
||||||
|
*/
|
||||||
|
static Drawable[] makeIconDrawable(@ColorInt int backgroundColor, @ColorInt int themeColor,
|
||||||
@NonNull Drawable foregroundDrawable, int srcIconSize, int iconSize,
|
@NonNull Drawable foregroundDrawable, int srcIconSize, int iconSize,
|
||||||
Handler splashscreenWorkerHandler) {
|
Handler splashscreenWorkerHandler) {
|
||||||
|
Drawable foreground;
|
||||||
|
Drawable background = null;
|
||||||
|
boolean drawBackground =
|
||||||
|
backgroundColor != Color.TRANSPARENT && backgroundColor != themeColor;
|
||||||
|
|
||||||
if (foregroundDrawable instanceof Animatable) {
|
if (foregroundDrawable instanceof Animatable) {
|
||||||
return new AnimatableIconAnimateListener(backgroundColor, foregroundDrawable);
|
foreground = new AnimatableIconAnimateListener(foregroundDrawable);
|
||||||
} else if (foregroundDrawable instanceof AdaptiveIconDrawable) {
|
} else if (foregroundDrawable instanceof AdaptiveIconDrawable) {
|
||||||
return new ImmobileIconDrawable(foregroundDrawable,
|
// If the icon is Adaptive, we already use the icon background.
|
||||||
|
drawBackground = false;
|
||||||
|
foreground = new ImmobileIconDrawable(foregroundDrawable,
|
||||||
srcIconSize, iconSize, splashscreenWorkerHandler);
|
srcIconSize, iconSize, splashscreenWorkerHandler);
|
||||||
} else {
|
} else {
|
||||||
// single layer icon
|
// Adaptive icon don't handle transparency so we draw the background of the adaptive
|
||||||
return new ImmobileIconDrawable(new AdaptiveIconDrawable(
|
// icon with the same color as the window background color instead of using two layers
|
||||||
new ColorDrawable(backgroundColor), foregroundDrawable),
|
foreground = new ImmobileIconDrawable(
|
||||||
|
new AdaptiveForegroundDrawable(foregroundDrawable),
|
||||||
srcIconSize, iconSize, splashscreenWorkerHandler);
|
srcIconSize, iconSize, splashscreenWorkerHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (drawBackground) {
|
||||||
|
background = new MaskBackgroundDrawable(backgroundColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Drawable[]{foreground, background};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Drawable makeLegacyIconDrawable(@NonNull Drawable iconDrawable, int srcIconSize,
|
static Drawable[] makeLegacyIconDrawable(@NonNull Drawable iconDrawable, int srcIconSize,
|
||||||
int iconSize, Handler splashscreenWorkerHandler) {
|
int iconSize, Handler splashscreenWorkerHandler) {
|
||||||
return new ImmobileIconDrawable(iconDrawable, srcIconSize, iconSize,
|
return new Drawable[]{new ImmobileIconDrawable(iconDrawable, srcIconSize, iconSize,
|
||||||
splashscreenWorkerHandler);
|
splashscreenWorkerHandler)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drawable pre-drawing the scaled icon in a separate thread to increase the speed of the
|
||||||
|
* final drawing.
|
||||||
|
*/
|
||||||
private static class ImmobileIconDrawable extends Drawable {
|
private static class ImmobileIconDrawable extends Drawable {
|
||||||
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
|
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
|
||||||
| Paint.FILTER_BITMAP_FLAG);
|
| Paint.FILTER_BITMAP_FLAG);
|
||||||
@@ -121,8 +145,10 @@ public class SplashscreenIconDrawableFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base class the draw the circle background
|
/**
|
||||||
private abstract static class MaskBackgroundDrawable extends Drawable {
|
* Base class the draw a background clipped by the system mask.
|
||||||
|
*/
|
||||||
|
public static class MaskBackgroundDrawable extends Drawable {
|
||||||
private static final float MASK_SIZE = AdaptiveIconDrawable.MASK_SIZE;
|
private static final float MASK_SIZE = AdaptiveIconDrawable.MASK_SIZE;
|
||||||
private static final float EXTRA_INSET_PERCENTAGE = 1 / 4f;
|
private static final float EXTRA_INSET_PERCENTAGE = 1 / 4f;
|
||||||
static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE);
|
static final float DEFAULT_VIEW_PORT_SCALE = 1f / (1 + 2 * EXTRA_INSET_PERCENTAGE);
|
||||||
@@ -132,17 +158,24 @@ public class SplashscreenIconDrawableFactory {
|
|||||||
private static Path sMask;
|
private static Path sMask;
|
||||||
private final Path mMaskScaleOnly;
|
private final Path mMaskScaleOnly;
|
||||||
private final Matrix mMaskMatrix;
|
private final Matrix mMaskMatrix;
|
||||||
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
|
|
||||||
| Paint.FILTER_BITMAP_FLAG);
|
|
||||||
|
|
||||||
MaskBackgroundDrawable(@ColorInt int backgroundColor) {
|
@Nullable
|
||||||
|
private final Paint mBackgroundPaint;
|
||||||
|
|
||||||
|
public MaskBackgroundDrawable(@ColorInt int backgroundColor) {
|
||||||
final Resources r = Resources.getSystem();
|
final Resources r = Resources.getSystem();
|
||||||
sMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
|
sMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
|
||||||
Path mask = new Path(sMask);
|
Path mask = new Path(sMask);
|
||||||
mMaskScaleOnly = new Path(mask);
|
mMaskScaleOnly = new Path(mask);
|
||||||
mMaskMatrix = new Matrix();
|
mMaskMatrix = new Matrix();
|
||||||
mPaint.setColor(backgroundColor);
|
if (backgroundColor != Color.TRANSPARENT) {
|
||||||
mPaint.setStyle(Paint.Style.FILL);
|
mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG
|
||||||
|
| Paint.FILTER_BITMAP_FLAG);
|
||||||
|
mBackgroundPaint.setColor(backgroundColor);
|
||||||
|
mBackgroundPaint.setStyle(Paint.Style.FILL);
|
||||||
|
} else {
|
||||||
|
mBackgroundPaint = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -162,40 +195,80 @@ public class SplashscreenIconDrawableFactory {
|
|||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas) {
|
public void draw(Canvas canvas) {
|
||||||
canvas.clipPath(mMaskScaleOnly);
|
canvas.clipPath(mMaskScaleOnly);
|
||||||
if (mMaskScaleOnly != null) {
|
if (mBackgroundPaint != null) {
|
||||||
canvas.drawPath(mMaskScaleOnly, mPaint);
|
canvas.drawPath(mMaskScaleOnly, mBackgroundPaint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAlpha(int alpha) {
|
public void setAlpha(int alpha) {
|
||||||
mPaint.setAlpha(alpha);
|
if (mBackgroundPaint != null) {
|
||||||
|
mBackgroundPaint.setAlpha(alpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOpacity() {
|
public int getOpacity() {
|
||||||
return PixelFormat.RGBA_8888;
|
return PixelFormat.RGBA_8888;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColorFilter(ColorFilter colorFilter) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class AdaptiveForegroundDrawable extends MaskBackgroundDrawable {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
protected final Drawable mForegroundDrawable;
|
||||||
|
private final Rect mTmpOutRect = new Rect();
|
||||||
|
|
||||||
|
AdaptiveForegroundDrawable(@NonNull Drawable foregroundDrawable) {
|
||||||
|
super(Color.TRANSPARENT);
|
||||||
|
mForegroundDrawable = foregroundDrawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateLayerBounds(Rect bounds) {
|
||||||
|
super.updateLayerBounds(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);
|
||||||
|
}
|
||||||
|
invalidateSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
super.draw(canvas);
|
||||||
|
mForegroundDrawable.draw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColorFilter(ColorFilter colorFilter) {
|
||||||
|
mForegroundDrawable.setColorFilter(colorFilter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A lightweight AdaptiveIconDrawable which support foreground to be Animatable, and keep this
|
* A lightweight AdaptiveIconDrawable which support foreground to be Animatable, and keep this
|
||||||
* drawable masked by config_icon_mask.
|
* drawable masked by config_icon_mask.
|
||||||
*/
|
*/
|
||||||
private static class AnimatableIconAnimateListener extends MaskBackgroundDrawable
|
private static class AnimatableIconAnimateListener extends AdaptiveForegroundDrawable
|
||||||
implements SplashScreenView.IconAnimateListener {
|
implements SplashScreenView.IconAnimateListener {
|
||||||
private final Drawable mForegroundDrawable;
|
|
||||||
private Animatable mAnimatableIcon;
|
private Animatable mAnimatableIcon;
|
||||||
private Animator mIconAnimator;
|
private Animator mIconAnimator;
|
||||||
private boolean mAnimationTriggered;
|
private boolean mAnimationTriggered;
|
||||||
private final Rect mTmpOutRect = new Rect();
|
|
||||||
|
|
||||||
AnimatableIconAnimateListener(@ColorInt int backgroundColor, Drawable foregroundDrawable) {
|
AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable) {
|
||||||
super(backgroundColor);
|
super(foregroundDrawable);
|
||||||
mForegroundDrawable = foregroundDrawable;
|
mForegroundDrawable.setCallback(mCallback);
|
||||||
if (mForegroundDrawable != null) {
|
|
||||||
mForegroundDrawable.setCallback(mCallback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -231,22 +304,6 @@ public class SplashscreenIconDrawableFactory {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void updateLayerBounds(Rect bounds) {
|
|
||||||
super.updateLayerBounds(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);
|
|
||||||
}
|
|
||||||
invalidateSelf();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Callback mCallback = new Callback() {
|
private final Callback mCallback = new Callback() {
|
||||||
@Override
|
@Override
|
||||||
public void invalidateDrawable(@NonNull Drawable who) {
|
public void invalidateDrawable(@NonNull Drawable who) {
|
||||||
@@ -276,19 +333,8 @@ public class SplashscreenIconDrawableFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas) {
|
public void draw(Canvas canvas) {
|
||||||
|
ensureAnimationStarted();
|
||||||
super.draw(canvas);
|
super.draw(canvas);
|
||||||
if (mForegroundDrawable != null) {
|
|
||||||
ensureAnimationStarted();
|
|
||||||
mForegroundDrawable.draw(canvas);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setColorFilter(ColorFilter colorFilter) {
|
|
||||||
if (mForegroundDrawable != null) {
|
|
||||||
mForegroundDrawable.setColorFilter(colorFilter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user