Add API for show branding image on splash screen.(4/N)
Add API windowSplashScreenBrandingImage to attach branding image on splash screen. Bug: 73289295 Test: build and flash Test: StartingSurfaceDrawerTests SplashscreenTests Change-Id: I15ab799d4e7bb74ce6814fa9375334db18022f3a
This commit is contained in:
@@ -1658,6 +1658,7 @@ package android {
|
||||
field public static final int windowSplashScreenAnimatedIcon = 16844333; // 0x101062d
|
||||
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 windowSplashscreenContent = 16844132; // 0x1010564
|
||||
field @Deprecated public static final int windowSwipeToDismiss = 16843763; // 0x10103f3
|
||||
field public static final int windowTitleBackgroundStyle = 16842844; // 0x101005c
|
||||
|
||||
@@ -2730,6 +2730,7 @@ package android.window {
|
||||
}
|
||||
|
||||
public final class SplashScreenView extends android.widget.FrameLayout {
|
||||
method @Nullable public android.view.View getBrandingView();
|
||||
method public boolean isIconAnimating();
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,9 @@ public final class SplashScreenView extends FrameLayout {
|
||||
private boolean mNotCopyable;
|
||||
private int mInitBackgroundColor;
|
||||
private View mIconView;
|
||||
private Bitmap mParceledBitmap;
|
||||
private Bitmap mParceledIconBitmap;
|
||||
private View mBrandingImageView;
|
||||
private Bitmap mParceledBrandingBitmap;
|
||||
|
||||
private Animatable mAnimatableIcon;
|
||||
private ValueAnimator mAnimator;
|
||||
@@ -88,9 +90,13 @@ public final class SplashScreenView extends FrameLayout {
|
||||
private final Context mContext;
|
||||
private int mIconSize;
|
||||
private @ColorInt int mBackgroundColor;
|
||||
private Bitmap mParceledBitmap;
|
||||
private Bitmap mParceledIconBitmap;
|
||||
private Drawable mIconDrawable;
|
||||
private int mIconAnimationDuration;
|
||||
private int mBrandingImageWidth;
|
||||
private int mBrandingImageHeight;
|
||||
private Drawable mBrandingDrawable;
|
||||
private Bitmap mParceledBrandingBitmap;
|
||||
|
||||
public Builder(@NonNull Context context) {
|
||||
mContext = context;
|
||||
@@ -103,9 +109,15 @@ public final class SplashScreenView extends FrameLayout {
|
||||
public Builder createFromParcel(SplashScreenViewParcelable parcelable) {
|
||||
mIconSize = parcelable.getIconSize();
|
||||
mBackgroundColor = parcelable.getBackgroundColor();
|
||||
if (parcelable.getBitmap() != null) {
|
||||
mIconDrawable = new BitmapDrawable(mContext.getResources(), parcelable.getBitmap());
|
||||
mParceledBitmap = parcelable.getBitmap();
|
||||
if (parcelable.mIconBitmap != null) {
|
||||
mIconDrawable = new BitmapDrawable(mContext.getResources(), parcelable.mIconBitmap);
|
||||
mParceledIconBitmap = parcelable.mIconBitmap;
|
||||
}
|
||||
if (parcelable.mBrandingBitmap != null) {
|
||||
setBrandingDrawable(new BitmapDrawable(mContext.getResources(),
|
||||
parcelable.mBrandingBitmap), parcelable.mBrandingWidth,
|
||||
parcelable.mBrandingHeight);
|
||||
mParceledBrandingBitmap = parcelable.mBrandingBitmap;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -142,6 +154,16 @@ public final class SplashScreenView extends FrameLayout {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Drawable object and size for the branding view.
|
||||
*/
|
||||
public Builder setBrandingDrawable(Drawable branding, int width, int height) {
|
||||
mBrandingDrawable = branding;
|
||||
mBrandingImageWidth = width;
|
||||
mBrandingImageHeight = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create SplashScreenWindowView object from materials.
|
||||
*/
|
||||
@@ -152,6 +174,8 @@ public final class SplashScreenView extends FrameLayout {
|
||||
view.mInitBackgroundColor = mBackgroundColor;
|
||||
view.setBackgroundColor(mBackgroundColor);
|
||||
view.mIconView = view.findViewById(R.id.splashscreen_icon_view);
|
||||
view.mBrandingImageView = view.findViewById(R.id.splashscreen_branding_view);
|
||||
// center icon
|
||||
if (mIconSize != 0) {
|
||||
final ViewGroup.LayoutParams params = view.mIconView.getLayoutParams();
|
||||
params.width = mIconSize;
|
||||
@@ -162,12 +186,27 @@ public final class SplashScreenView extends FrameLayout {
|
||||
view.mIconView.setBackground(mIconDrawable);
|
||||
view.initIconAnimation(mIconDrawable, mIconAnimationDuration);
|
||||
}
|
||||
if (mParceledBitmap != null) {
|
||||
view.mParceledBitmap = mParceledBitmap;
|
||||
if (mParceledIconBitmap != null) {
|
||||
view.mParceledIconBitmap = mParceledIconBitmap;
|
||||
}
|
||||
// branding image
|
||||
if (mBrandingImageHeight > 0 && mBrandingImageWidth > 0) {
|
||||
final ViewGroup.LayoutParams params = view.mBrandingImageView.getLayoutParams();
|
||||
params.width = mBrandingImageWidth;
|
||||
params.height = mBrandingImageHeight;
|
||||
view.mBrandingImageView.setLayoutParams(params);
|
||||
}
|
||||
if (mBrandingDrawable != null) {
|
||||
view.mBrandingImageView.setBackground(mBrandingDrawable);
|
||||
}
|
||||
if (mParceledBrandingBitmap != null) {
|
||||
view.mParceledBrandingBitmap = mParceledBrandingBitmap;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, " build " + view + " center view? " + view.mIconView
|
||||
+ " iconSize " + mIconSize);
|
||||
Log.d(TAG, " build " + view + " Icon: view: " + view.mIconView + " drawable: "
|
||||
+ mIconDrawable + " size: " + mIconSize + "\n Branding: view: "
|
||||
+ view.mBrandingImageView + " drawable: " + mBrandingDrawable
|
||||
+ " size w: " + mBrandingImageWidth + " h: " + mBrandingImageHeight);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
@@ -266,10 +305,15 @@ public final class SplashScreenView extends FrameLayout {
|
||||
*/
|
||||
public void remove() {
|
||||
setVisibility(GONE);
|
||||
if (mParceledBitmap != null) {
|
||||
if (mParceledIconBitmap != null) {
|
||||
mIconView.setBackground(null);
|
||||
mParceledBitmap.recycle();
|
||||
mParceledBitmap = null;
|
||||
mParceledIconBitmap.recycle();
|
||||
mParceledIconBitmap = null;
|
||||
}
|
||||
if (mParceledBrandingBitmap != null) {
|
||||
mBrandingImageView.setBackground(null);
|
||||
mParceledBrandingBitmap.recycle();
|
||||
mParceledBrandingBitmap = null;
|
||||
}
|
||||
if (mWindow != null) {
|
||||
final DecorView decorView = (DecorView) mWindow.peekDecorView();
|
||||
@@ -329,6 +373,15 @@ public final class SplashScreenView extends FrameLayout {
|
||||
return mIconView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the branding image view.
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public @Nullable View getBrandingView() {
|
||||
return mBrandingImageView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the initial background color of this view.
|
||||
* @hide
|
||||
@@ -344,27 +397,40 @@ public final class SplashScreenView extends FrameLayout {
|
||||
public static class SplashScreenViewParcelable implements Parcelable {
|
||||
private int mIconSize;
|
||||
private int mBackgroundColor;
|
||||
private Bitmap mBitmap;
|
||||
|
||||
private Bitmap mIconBitmap;
|
||||
private int mBrandingWidth;
|
||||
private int mBrandingHeight;
|
||||
private Bitmap mBrandingBitmap;
|
||||
|
||||
public SplashScreenViewParcelable(SplashScreenView view) {
|
||||
final ViewGroup.LayoutParams params = view.getIconView().getLayoutParams();
|
||||
ViewGroup.LayoutParams params = view.getIconView().getLayoutParams();
|
||||
mIconSize = params.height;
|
||||
mBackgroundColor = view.getInitBackgroundColor();
|
||||
|
||||
final Drawable background = view.getIconView().getBackground();
|
||||
if (background != null) {
|
||||
final Rect initialBounds = background.copyBounds();
|
||||
mIconBitmap = copyDrawable(view.getIconView().getBackground());
|
||||
mBrandingBitmap = copyDrawable(view.getBrandingView().getBackground());
|
||||
params = view.getBrandingView().getLayoutParams();
|
||||
mBrandingWidth = params.width;
|
||||
mBrandingHeight = params.height;
|
||||
|
||||
}
|
||||
|
||||
private Bitmap copyDrawable(Drawable drawable) {
|
||||
if (drawable != null) {
|
||||
final Rect initialBounds = drawable.copyBounds();
|
||||
final int width = initialBounds.width();
|
||||
final int height = initialBounds.height();
|
||||
|
||||
final Bitmap iconSnapshot = Bitmap.createBitmap(width, height,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
final Canvas bmpCanvas = new Canvas(iconSnapshot);
|
||||
background.setBounds(0, 0, width, height);
|
||||
background.draw(bmpCanvas);
|
||||
mBitmap = iconSnapshot.createAshmemBitmap();
|
||||
iconSnapshot.recycle();
|
||||
final Bitmap snapshot = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
final Canvas bmpCanvas = new Canvas(snapshot);
|
||||
drawable.setBounds(0, 0, width, height);
|
||||
drawable.draw(bmpCanvas);
|
||||
final Bitmap copyBitmap = snapshot.createAshmemBitmap();
|
||||
snapshot.recycle();
|
||||
return copyBitmap;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private SplashScreenViewParcelable(@NonNull Parcel source) {
|
||||
@@ -374,7 +440,10 @@ public final class SplashScreenView extends FrameLayout {
|
||||
private void readParcel(@NonNull Parcel source) {
|
||||
mIconSize = source.readInt();
|
||||
mBackgroundColor = source.readInt();
|
||||
mBitmap = source.readTypedObject(Bitmap.CREATOR);
|
||||
mIconBitmap = source.readTypedObject(Bitmap.CREATOR);
|
||||
mBrandingWidth = source.readInt();
|
||||
mBrandingHeight = source.readInt();
|
||||
mBrandingBitmap = source.readTypedObject(Bitmap.CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -386,7 +455,10 @@ public final class SplashScreenView extends FrameLayout {
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(mIconSize);
|
||||
dest.writeInt(mBackgroundColor);
|
||||
dest.writeTypedObject(mBitmap, flags);
|
||||
dest.writeTypedObject(mIconBitmap, flags);
|
||||
dest.writeInt(mBrandingWidth);
|
||||
dest.writeInt(mBrandingHeight);
|
||||
dest.writeTypedObject(mBrandingBitmap, flags);
|
||||
}
|
||||
|
||||
public static final @NonNull Parcelable.Creator<SplashScreenViewParcelable> CREATOR =
|
||||
@@ -403,9 +475,13 @@ public final class SplashScreenView extends FrameLayout {
|
||||
* Release the bitmap if another process cannot handle it.
|
||||
*/
|
||||
public void clearIfNeeded() {
|
||||
if (mBitmap != null) {
|
||||
mBitmap.recycle();
|
||||
mBitmap = null;
|
||||
if (mIconBitmap != null) {
|
||||
mIconBitmap.recycle();
|
||||
mIconBitmap = null;
|
||||
}
|
||||
if (mBrandingBitmap != null) {
|
||||
mBrandingBitmap.recycle();
|
||||
mBrandingBitmap = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,9 +492,5 @@ public final class SplashScreenView extends FrameLayout {
|
||||
int getBackgroundColor() {
|
||||
return mBackgroundColor;
|
||||
}
|
||||
|
||||
Bitmap getBitmap() {
|
||||
return mBitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,4 +25,10 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
<View android:id="@+id/splashscreen_branding_view"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:layout_marginBottom="60dp"/>
|
||||
|
||||
</android.window.SplashScreenView>
|
||||
@@ -2262,6 +2262,7 @@
|
||||
-->
|
||||
<enum name="always" value="3" />
|
||||
</attr>
|
||||
|
||||
<!-- The background color for the splash screen, if not specify then system will
|
||||
calculate from windowBackground. -->
|
||||
<attr name="windowSplashScreenBackground" format="color"/>
|
||||
@@ -2274,6 +2275,10 @@
|
||||
when playing the splash screen starting window. The maximum animation duration should
|
||||
be limited below 1000ms. -->
|
||||
<attr name="windowSplashScreenAnimationDuration" format="integer"/>
|
||||
|
||||
<!-- 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"/>
|
||||
</declare-styleable>
|
||||
|
||||
<!-- The set of attributes that describe a AlertDialog's theme. -->
|
||||
|
||||
@@ -3069,6 +3069,7 @@
|
||||
<public name="windowSplashScreenBackground"/>
|
||||
<public name="windowSplashScreenAnimatedIcon"/>
|
||||
<public name="windowSplashScreenAnimationDuration"/>
|
||||
<public name="windowSplashScreenBrandingImage"/>
|
||||
</public-group>
|
||||
|
||||
<public-group type="drawable" first-id="0x010800b5">
|
||||
|
||||
@@ -1820,6 +1820,7 @@
|
||||
<java-symbol type="dimen" name="cross_profile_apps_thumbnail_size" />
|
||||
<java-symbol type="layout" name="splash_screen_view" />
|
||||
<java-symbol type="id" name="splashscreen_icon_view" />
|
||||
<java-symbol type="id" name="splashscreen_branding_view" />
|
||||
|
||||
<!-- From services -->
|
||||
<java-symbol type="anim" name="screen_rotate_0_enter" />
|
||||
|
||||
@@ -169,6 +169,7 @@ please see themes_device_defaults.xml.
|
||||
<item name="windowBackgroundFallback">?attr/colorBackground</item>
|
||||
<item name="windowSplashScreenBackground">@color/transparent</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@null</item>
|
||||
<item name="windowSplashScreenBrandingImage">@null</item>
|
||||
<item name="windowClipToOutline">false</item>
|
||||
<item name="windowFrame">@null</item>
|
||||
<item name="windowNoTitle">false</item>
|
||||
|
||||
@@ -173,4 +173,10 @@
|
||||
|
||||
<!-- The width/height of the icon view on staring surface. -->
|
||||
<dimen name="starting_surface_icon_size">108dp</dimen>
|
||||
|
||||
<!-- The width of the brand image on staring surface. -->
|
||||
<dimen name="starting_surface_brand_image_width">200dp</dimen>
|
||||
|
||||
<!-- The height of the brand image on staring surface. -->
|
||||
<dimen name="starting_surface_brand_image_height">80dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -59,6 +59,8 @@ public class SplashscreenContentDrawer {
|
||||
private final int mMaxIconAnimationDuration;
|
||||
|
||||
private int mIconSize;
|
||||
private int mBrandingImageWidth;
|
||||
private int mBrandingImageHeight;
|
||||
|
||||
SplashscreenContentDrawer(Context context, int maxIconAnimationDuration) {
|
||||
mContext = context;
|
||||
@@ -68,6 +70,10 @@ public class SplashscreenContentDrawer {
|
||||
private void updateDensity() {
|
||||
mIconSize = mContext.getResources().getDimensionPixelSize(
|
||||
com.android.wm.shell.R.dimen.starting_surface_icon_size);
|
||||
mBrandingImageWidth = mContext.getResources().getDimensionPixelSize(
|
||||
com.android.wm.shell.R.dimen.starting_surface_brand_image_width);
|
||||
mBrandingImageHeight = mContext.getResources().getDimensionPixelSize(
|
||||
com.android.wm.shell.R.dimen.starting_surface_brand_image_height);
|
||||
}
|
||||
|
||||
private int getSystemBGColor() {
|
||||
@@ -124,13 +130,15 @@ public class SplashscreenContentDrawer {
|
||||
.setContext(context)
|
||||
.setThemeDrawable(themeBGDrawable)
|
||||
.setIconDrawable(iconDrawable)
|
||||
.setIconAnimationDuration(animationDuration).build();
|
||||
.setIconAnimationDuration(animationDuration)
|
||||
.setBrandingDrawable(attrs.mBrandingImage).build();
|
||||
}
|
||||
|
||||
private static class SplashScreenWindowAttrs {
|
||||
private int mWindowBgResId = 0;
|
||||
private int mWindowBgColor = Color.TRANSPARENT;
|
||||
private Drawable mReplaceIcon = null;
|
||||
private Drawable mBrandingImage = null;
|
||||
private int mAnimationDuration = 0;
|
||||
|
||||
static SplashScreenWindowAttrs createWindowAttrs(Context context) {
|
||||
@@ -144,11 +152,14 @@ public class SplashscreenContentDrawer {
|
||||
R.styleable.Window_windowSplashScreenAnimatedIcon);
|
||||
attrs.mAnimationDuration = typedArray.getInt(
|
||||
R.styleable.Window_windowSplashScreenAnimationDuration, 0);
|
||||
attrs.mBrandingImage = typedArray.getDrawable(
|
||||
R.styleable.Window_windowSplashScreenBrandingImage);
|
||||
typedArray.recycle();
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "window attributes color: "
|
||||
+ Integer.toHexString(attrs.mWindowBgColor)
|
||||
+ " icon " + attrs.mReplaceIcon + " duration " + attrs.mAnimationDuration);
|
||||
+ " icon " + attrs.mReplaceIcon + " duration " + attrs.mAnimationDuration
|
||||
+ " brandImage " + attrs.mBrandingImage);
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
@@ -160,6 +171,7 @@ public class SplashscreenContentDrawer {
|
||||
private Window mWindow;
|
||||
private int mIconAnimationDuration;
|
||||
private Context mContext;
|
||||
private Drawable mBrandingDrawable;
|
||||
|
||||
// result
|
||||
private boolean mBuildComplete = false;
|
||||
@@ -192,6 +204,12 @@ public class SplashscreenContentDrawer {
|
||||
return this;
|
||||
}
|
||||
|
||||
StartingWindowViewBuilder setBrandingDrawable(Drawable branding) {
|
||||
mBrandingDrawable = branding;
|
||||
mBuildComplete = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
StartingWindowViewBuilder setContext(Context context) {
|
||||
mContext = context;
|
||||
mBuildComplete = false;
|
||||
@@ -302,6 +320,10 @@ public class SplashscreenContentDrawer {
|
||||
builder.setCenterViewDrawable(iconDrawable);
|
||||
}
|
||||
builder.setAnimationDuration(mIconAnimationDuration);
|
||||
if (mBrandingDrawable != null) {
|
||||
builder.setBrandingDrawable(mBrandingDrawable, mBrandingImageWidth,
|
||||
mBrandingImageHeight);
|
||||
}
|
||||
final SplashScreenView splashScreenView = builder.build();
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "fillViewWithIcon surfaceWindowView " + splashScreenView);
|
||||
|
||||
Reference in New Issue
Block a user