From 1af8eda6ea1c89d44123b2bfd5fa0293bb9d68cb Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 5 Feb 2016 17:55:56 +0000 Subject: [PATCH] Drawing thumbnail background color for empty space in view. Change-Id: I2e8dfbe9c11a61876956658eff0674adb26d855d Signed-off-by: Winson --- core/java/android/app/Activity.java | 81 ++++++++++++++++------ core/java/android/app/ActivityManager.java | 78 +++++++++++++++------ .../com/android/internal/policy/DecorView.java | 16 ++--- packages/SystemUI/res/values/colors.xml | 2 + .../systemui/recents/misc/SystemServicesProxy.java | 3 +- .../recents/model/RecentsTaskLoadPlan.java | 3 +- .../systemui/recents/model/RecentsTaskLoader.java | 15 +++- .../com/android/systemui/recents/model/Task.java | 7 +- .../systemui/recents/views/TaskViewThumbnail.java | 46 ++++++++++-- .../java/com/android/server/am/TaskRecord.java | 7 +- 10 files changed, 197 insertions(+), 61 deletions(-) diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 622012ecf2e2..ea58e292e545 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -16,6 +16,8 @@ package android.app; +import static java.lang.Character.MIN_VALUE; + import android.annotation.CallSuper; import android.annotation.DrawableRes; import android.annotation.IdRes; @@ -26,20 +28,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.StyleRes; -import android.os.PersistableBundle; -import android.transition.Scene; -import android.transition.TransitionManager; -import android.util.ArrayMap; -import android.util.SuperNotCalledException; -import android.view.DragEvent; -import android.view.DropPermissions; -import android.view.Window.WindowControllerCallback; -import android.widget.Toolbar; - -import com.android.internal.app.IVoiceInteractor; -import com.android.internal.app.WindowDecorActionBar; -import com.android.internal.app.ToolbarActionBar; - import android.annotation.SystemApi; import android.app.admin.DevicePolicyManager; import android.app.assist.AssistContent; @@ -61,7 +49,12 @@ import android.content.res.TypedArray; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.InsetDrawable; +import android.graphics.drawable.LayerDrawable; +import android.graphics.drawable.ShapeDrawable; import android.media.AudioManager; import android.media.session.MediaController; import android.net.Uri; @@ -71,6 +64,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Parcelable; +import android.os.PersistableBundle; import android.os.RemoteException; import android.os.StrictMode; import android.os.UserHandle; @@ -78,16 +72,22 @@ import android.text.Selection; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.method.TextKeyListener; +import android.transition.Scene; +import android.transition.TransitionManager; +import android.util.ArrayMap; import android.util.AttributeSet; import android.util.EventLog; import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; +import android.util.SuperNotCalledException; import android.view.ActionMode; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextThemeWrapper; +import android.view.DragEvent; +import android.view.DropPermissions; import android.view.KeyEvent; import android.view.KeyboardShortcutGroup; import android.view.KeyboardShortcutInfo; @@ -104,11 +104,17 @@ import android.view.ViewGroup.LayoutParams; import android.view.ViewManager; import android.view.ViewRootImpl; import android.view.Window; +import android.view.Window.WindowControllerCallback; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.widget.AdapterView; +import android.widget.Toolbar; +import com.android.internal.app.IVoiceInteractor; +import com.android.internal.app.ToolbarActionBar; +import com.android.internal.app.WindowDecorActionBar; +import com.android.internal.policy.DecorView; import com.android.internal.policy.PhoneWindow; import java.io.FileDescriptor; @@ -119,8 +125,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import static java.lang.Character.MIN_VALUE; - /** * An activity is a single, focused thing that the user can do. Almost all * activities interact with the user, so the Activity class takes care of @@ -3974,14 +3978,49 @@ public class Activity extends ContextThemeWrapper // Get the primary color and update the TaskDescription for this activity if (theme != null) { TypedArray a = theme.obtainStyledAttributes(com.android.internal.R.styleable.Theme); + int windowBgResourceId = a.getResourceId( + com.android.internal.R.styleable.Window_windowBackground, 0); + int windowBgFallbackResourceId = a.getResourceId( + com.android.internal.R.styleable.Window_windowBackgroundFallback, 0); int colorPrimary = a.getColor(com.android.internal.R.styleable.Theme_colorPrimary, 0); + int colorBg = tryExtractColorFromDrawable(DecorView.getResizingBackgroundDrawable(this, + windowBgResourceId, windowBgFallbackResourceId)); a.recycle(); if (colorPrimary != 0) { - ActivityManager.TaskDescription v = new ActivityManager.TaskDescription(null, null, - colorPrimary); - setTaskDescription(v); + ActivityManager.TaskDescription td = new ActivityManager.TaskDescription(); + td.setPrimaryColor(colorPrimary); + td.setBackgroundColor(colorBg); + setTaskDescription(td); + } + } + } + + /** + * Attempts to extract the color from a given drawable. + * + * @return the extracted color or 0 if no color could be extracted. + */ + private int tryExtractColorFromDrawable(Drawable drawable) { + if (drawable instanceof ColorDrawable) { + return ((ColorDrawable) drawable).getColor(); + } else if (drawable instanceof InsetDrawable) { + return tryExtractColorFromDrawable(((InsetDrawable) drawable).getDrawable()); + } else if (drawable instanceof ShapeDrawable) { + Paint p = ((ShapeDrawable) drawable).getPaint(); + if (p != null) { + return p.getColor(); + } + } else if (drawable instanceof LayerDrawable) { + LayerDrawable ld = (LayerDrawable) drawable; + int numLayers = ld.getNumberOfLayers(); + for (int i = 0; i < numLayers; i++) { + int color = tryExtractColorFromDrawable(ld.getDrawable(i)); + if (color != 0) { + return color; + } } } + return 0; } /** @@ -5612,8 +5651,8 @@ public class Activity extends ContextThemeWrapper if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) { final int size = ActivityManager.getLauncherLargeIconSizeInner(this); final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size, true); - td = new ActivityManager.TaskDescription(taskDescription.getLabel(), icon, - taskDescription.getPrimaryColor()); + td = new ActivityManager.TaskDescription(taskDescription); + td.setIcon(icon); } else { td = taskDescription; } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 1eb2fe2c89ec..f64765cb3ddd 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -863,8 +863,10 @@ public class ActivityManager { public static final String ATTR_TASKDESCRIPTION_PREFIX = "task_description_"; private static final String ATTR_TASKDESCRIPTIONLABEL = ATTR_TASKDESCRIPTION_PREFIX + "label"; - private static final String ATTR_TASKDESCRIPTIONCOLOR = + private static final String ATTR_TASKDESCRIPTIONCOLOR_PRIMARY = ATTR_TASKDESCRIPTION_PREFIX + "color"; + private static final String ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND = + ATTR_TASKDESCRIPTION_PREFIX + "colorBackground"; private static final String ATTR_TASKDESCRIPTIONICONFILENAME = ATTR_TASKDESCRIPTION_PREFIX + "icon_filename"; @@ -872,28 +874,21 @@ public class ActivityManager { private Bitmap mIcon; private String mIconFilename; private int mColorPrimary; + private int mColorBackground; /** * Creates the TaskDescription to the specified values. * * @param label A label and description of the current state of this task. * @param icon An icon that represents the current state of this task. - * @param colorPrimary A color to override the theme's primary color. This color must be opaque. + * @param colorPrimary A color to override the theme's primary color. This color must be + * opaque. */ public TaskDescription(String label, Bitmap icon, int colorPrimary) { + this(label, icon, null, colorPrimary, 0); if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) { throw new RuntimeException("A TaskDescription's primary color should be opaque"); } - - mLabel = label; - mIcon = icon; - mColorPrimary = colorPrimary; - } - - /** @hide */ - public TaskDescription(String label, int colorPrimary, String iconFilename) { - this(label, null, colorPrimary); - mIconFilename = iconFilename; } /** @@ -903,7 +898,7 @@ public class ActivityManager { * @param icon An icon that represents the current state of this activity. */ public TaskDescription(String label, Bitmap icon) { - this(label, icon, 0); + this(label, icon, null, 0, 0); } /** @@ -912,14 +907,24 @@ public class ActivityManager { * @param label A label and description of the current state of this activity. */ public TaskDescription(String label) { - this(label, null, 0); + this(label, null, null, 0, 0); } /** * Creates an empty TaskDescription. */ public TaskDescription() { - this(null, null, 0); + this(null, null, null, 0, 0); + } + + /** @hide */ + public TaskDescription(String label, Bitmap icon, String iconFilename, int colorPrimary, + int colorBackground) { + mLabel = label; + mIcon = icon; + mIconFilename = iconFilename; + mColorPrimary = colorPrimary; + mColorBackground = colorBackground; } /** @@ -928,8 +933,9 @@ public class ActivityManager { public TaskDescription(TaskDescription td) { mLabel = td.mLabel; mIcon = td.mIcon; - mColorPrimary = td.mColorPrimary; mIconFilename = td.mIconFilename; + mColorPrimary = td.mColorPrimary; + mColorBackground = td.mColorBackground; } private TaskDescription(Parcel source) { @@ -957,6 +963,18 @@ public class ActivityManager { } /** + * Sets the background color for this task description. + * @hide + */ + public void setBackgroundColor(int backgroundColor) { + // Ensure that the given color is valid + if ((backgroundColor != 0) && (Color.alpha(backgroundColor) != 255)) { + throw new RuntimeException("A TaskDescription's background color should be opaque"); + } + mColorBackground = backgroundColor; + } + + /** * Sets the icon for this task description. * @hide */ @@ -1005,8 +1023,8 @@ public class ActivityManager { public static Bitmap loadTaskDescriptionIcon(String iconFilename, int userId) { if (iconFilename != null) { try { - return ActivityManagerNative.getDefault(). - getTaskDescriptionIcon(iconFilename, userId); + return ActivityManagerNative.getDefault().getTaskDescriptionIcon(iconFilename, + userId); } catch (RemoteException e) { } } @@ -1020,13 +1038,26 @@ public class ActivityManager { return mColorPrimary; } + /** + * @return The background color. + * @hide + */ + public int getBackgroundColor() { + return mColorBackground; + } + /** @hide */ public void saveToXml(XmlSerializer out) throws IOException { if (mLabel != null) { out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, mLabel); } if (mColorPrimary != 0) { - out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(mColorPrimary)); + out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR_PRIMARY, + Integer.toHexString(mColorPrimary)); + } + if (mColorBackground != 0) { + out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND, + Integer.toHexString(mColorBackground)); } if (mIconFilename != null) { out.attribute(null, ATTR_TASKDESCRIPTIONICONFILENAME, mIconFilename); @@ -1037,8 +1068,10 @@ public class ActivityManager { public void restoreFromXml(String attrName, String attrValue) { if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) { setLabel(attrValue); - } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) { + } else if (ATTR_TASKDESCRIPTIONCOLOR_PRIMARY.equals(attrName)) { setPrimaryColor((int) Long.parseLong(attrValue, 16)); + } else if (ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND.equals(attrName)) { + setBackgroundColor((int) Long.parseLong(attrValue, 16)); } else if (ATTR_TASKDESCRIPTIONICONFILENAME.equals(attrName)) { setIconFilename(attrValue); } @@ -1064,6 +1097,7 @@ public class ActivityManager { mIcon.writeToParcel(dest, 0); } dest.writeInt(mColorPrimary); + dest.writeInt(mColorBackground); if (mIconFilename == null) { dest.writeInt(0); } else { @@ -1076,6 +1110,7 @@ public class ActivityManager { mLabel = source.readInt() > 0 ? source.readString() : null; mIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null; mColorPrimary = source.readInt(); + mColorBackground = source.readInt(); mIconFilename = source.readInt() > 0 ? source.readString() : null; } @@ -1092,7 +1127,8 @@ public class ActivityManager { @Override public String toString() { return "TaskDescription Label: " + mLabel + " Icon: " + mIcon + - " colorPrimary: " + mColorPrimary; + " IconFilename: " + mIconFilename + " colorPrimary: " + mColorPrimary + + " colorBackground: " + mColorBackground; } } diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index 88af920df2d4..f1c79fa60db9 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -1718,8 +1718,13 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind private void loadBackgroundDrawablesIfNeeded() { if (mResizingBackgroundDrawable == null) { - mResizingBackgroundDrawable = getResizingBackgroundDrawable( + mResizingBackgroundDrawable = getResizingBackgroundDrawable(getContext(), mWindow.mBackgroundResource, mWindow.mBackgroundFallbackResource); + if (mResizingBackgroundDrawable == null) { + // We shouldn't really get here as the background fallback should be always + // available since it is defaulted by the system. + Log.w(mLogTag, "Failed to find background drawable for PhoneWindow=" + mWindow); + } } if (mCaptionBackgroundDrawable == null) { mCaptionBackgroundDrawable = getContext().getDrawable( @@ -1817,9 +1822,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind * Returns the color used to fill areas the app has not rendered content to yet when the * user is resizing the window of an activity in multi-window mode. */ - private Drawable getResizingBackgroundDrawable(int backgroundRes, int backgroundFallbackRes) { - final Context context = getContext(); - + public static Drawable getResizingBackgroundDrawable(Context context, int backgroundRes, + int backgroundFallbackRes) { if (backgroundRes != 0) { final Drawable drawable = context.getDrawable(backgroundRes); if (drawable != null) { @@ -1833,10 +1837,6 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind return fallbackDrawable; } } - - // We shouldn't really get here as the background fallback should be always available since - // it is defaulted by the system. - Log.w(mLogTag, "Failed to find background drawable for PhoneWindow=" + mWindow); return null; } diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index a9b8df2934c7..a49a9f203c45 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -54,6 +54,8 @@ #ffe6e6e6 + + #fff3f3f3 #ffeeeeee diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index 22ab79430cd2..a3d84c56f5b9 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -187,7 +187,8 @@ public class SystemServicesProxy { rti.firstActiveTime = rti.lastActiveTime = i; if (i % 2 == 0) { rti.taskDescription = new ActivityManager.TaskDescription(description, - Bitmap.createBitmap(mDummyIcon), + Bitmap.createBitmap(mDummyIcon), null, + 0xFF000000 | (0xFFFFFF & new Random().nextInt()), 0xFF000000 | (0xFFFFFF & new Random().nextInt())); } else { rti.taskDescription = new ActivityManager.TaskDescription(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java index c51aa7ce38c9..9510ec015269 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java @@ -188,11 +188,12 @@ public class RecentsTaskLoadPlan { : null; Bitmap thumbnail = loader.getAndUpdateThumbnail(taskKey, false); int activityColor = loader.getActivityPrimaryColor(t.taskDescription); + int backgroundColor = loader.getActivityBackgroundColor(t.taskDescription); // Add the task to the stack Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, icon, thumbnail, title, contentDescription, dismissDescription, activityColor, - !isStackTask, isLaunchTarget, t.bounds, t.taskDescription); + backgroundColor, !isStackTask, isLaunchTarget, t.bounds, t.taskDescription); allTasks.add(task); affiliatedTaskCounts.put(taskKey.id, affiliatedTaskCounts.get(taskKey.id, 0) + 1); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java index 26130abc138b..7c121af7181a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java @@ -264,13 +264,16 @@ public class RecentsTaskLoader { private int mNumVisibleThumbnailsLoaded; int mDefaultTaskBarBackgroundColor; + int mDefaultTaskViewBackgroundColor; BitmapDrawable mDefaultIcon; Bitmap mDefaultThumbnail; public RecentsTaskLoader(Context context) { Resources res = context.getResources(); mDefaultTaskBarBackgroundColor = - res.getColor(R.color.recents_task_bar_default_background_color); + context.getColor(R.color.recents_task_bar_default_background_color); + mDefaultTaskViewBackgroundColor = + context.getColor(R.color.recents_task_view_default_background_color); mMaxThumbnailCacheSize = res.getInteger(R.integer.config_recents_max_thumbnail_count); mMaxIconCacheSize = res.getInteger(R.integer.config_recents_max_icon_count); int iconCacheSize = RecentsDebugFlags.Static.DisableBackgroundCache ? 1 : @@ -556,6 +559,16 @@ public class RecentsTaskLoader { } /** + * Returns the task's background color if possible. + */ + int getActivityBackgroundColor(ActivityManager.TaskDescription td) { + if (td != null && td.getBackgroundColor() != 0) { + return td.getBackgroundColor(); + } + return mDefaultTaskViewBackgroundColor; + } + + /** * Returns the activity info for the given task key, retrieving one from the system if the * task key is expired. */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java index 1c277d5a3d92..c7430e5aac62 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java @@ -128,6 +128,7 @@ public class Task { public String contentDescription; public String dismissDescription; public int colorPrimary; + public int colorBackground; public boolean useLightOnPrimaryColor; /** @@ -154,8 +155,8 @@ public class Task { public Task(TaskKey key, int affiliationTaskId, int affiliationColor, Drawable icon, Bitmap thumbnail, String title, String contentDescription, - String dismissDescription, int colorPrimary, boolean isHistorical, - boolean isLaunchTarget, Rect bounds, + String dismissDescription, int colorPrimary, int colorBackground, + boolean isHistorical, boolean isLaunchTarget, Rect bounds, ActivityManager.TaskDescription taskDescription) { boolean isInAffiliationGroup = (affiliationTaskId != key.id); boolean hasAffiliationGroupColor = isInAffiliationGroup && (affiliationColor != 0); @@ -168,6 +169,7 @@ public class Task { this.contentDescription = contentDescription; this.dismissDescription = dismissDescription; this.colorPrimary = hasAffiliationGroupColor ? affiliationColor : colorPrimary; + this.colorBackground = colorBackground; this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary, Color.WHITE) > 3f; this.bounds = bounds; @@ -188,6 +190,7 @@ public class Task { this.contentDescription = o.contentDescription; this.dismissDescription = o.dismissDescription; this.colorPrimary = o.colorPrimary; + this.colorBackground = o.colorBackground; this.useLightOnPrimaryColor = o.useLightOnPrimaryColor; this.bounds = o.bounds; this.isLaunchTarget = o.isLaunchTarget; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java index f90951e4ccd1..5ee4b0437c41 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java @@ -25,6 +25,7 @@ import android.graphics.LightingColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; +import android.graphics.Region; import android.graphics.Shader; import android.util.AttributeSet; import android.view.View; @@ -48,6 +49,7 @@ public class TaskViewThumbnail extends View { float mDimAlpha; Matrix mScaleMatrix = new Matrix(); Paint mDrawPaint = new Paint(); + Paint mBgFillPaint = new Paint(); BitmapShader mBitmapShader; LightingColorFilter mLightingColorFilter = new LightingColorFilter(0xffffffff, 0); @@ -79,6 +81,7 @@ public class TaskViewThumbnail extends View { mDrawPaint.setAntiAlias(true); mCornerRadius = getResources().getDimensionPixelSize( R.dimen.recents_task_view_rounded_corners_radius); + mBgFillPaint.setColor(Color.WHITE); } /** @@ -100,10 +103,39 @@ public class TaskViewThumbnail extends View { if (mInvisible) { return; } - // Draw the thumbnail with the rounded corners - canvas.drawRoundRect(0, 0, mTaskViewRect.width(), mTaskViewRect.height(), - mCornerRadius, - mCornerRadius, mDrawPaint); + + int thumbnailHeight = (int) (((float) mTaskViewRect.width() / mThumbnailRect.width()) * + mThumbnailRect.height()); + if (thumbnailHeight >= mTaskViewRect.height()) { + // The thumbnail fills the full task view bounds, so just draw it + canvas.drawRoundRect(0, 0, mTaskViewRect.width(), mTaskViewRect.height(), + mCornerRadius, mCornerRadius, mDrawPaint); + } else { + int count = 0; + if (thumbnailHeight > 0) { + // The thumbnail only covers part of the task view bounds, so fill in the + // non-thumbnail space with the default background color. This is the equivalent of + // the GL border texture mode. + count = canvas.save(); + + // Since we only want the top corners to be rounded, draw slightly beyond the + // thumbnail height, but clip to the thumbnail height + canvas.clipRect(0, 0, mTaskViewRect.width(), thumbnailHeight, Region.Op.REPLACE); + canvas.drawRoundRect(0, 0, mTaskViewRect.width(), thumbnailHeight + mCornerRadius, + mCornerRadius, mCornerRadius, mDrawPaint); + } + + // In the remaining space, draw the background color + canvas.clipRect(0, thumbnailHeight, mTaskViewRect.width(), mTaskViewRect.height(), + Region.Op.REPLACE); + canvas.drawRoundRect(0, Math.max(0, thumbnailHeight - mCornerRadius), + mTaskViewRect.width(), mTaskViewRect.height(), mCornerRadius, mCornerRadius, + mBgFillPaint); + + if (thumbnailHeight > 0) { + canvas.restoreToCount(count); + } + } } /** Sets the thumbnail to a given bitmap. */ @@ -130,7 +162,8 @@ public class TaskViewThumbnail extends View { if (mBitmapShader != null) { mLightingColorFilter.setColorMultiply(Color.argb(255, mul, mul, mul)); mDrawPaint.setColorFilter(mLightingColorFilter); - mDrawPaint.setColor(0xffffffff); + mDrawPaint.setColor(0xFFffffff); + mBgFillPaint.setColorFilter(mLightingColorFilter); } else { int grey = mul; mDrawPaint.setColorFilter(null); @@ -200,6 +233,9 @@ public class TaskViewThumbnail extends View { mTask = t; if (t.thumbnail != null) { setThumbnail(t.thumbnail); + if (t.colorBackground != 0) { + mBgFillPaint.setColor(t.colorBackground); + } } else { setThumbnail(null); } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 98a7ead339df..2deb0d24e3d9 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -1011,6 +1011,7 @@ final class TaskRecord { String label = null; String iconFilename = null; int colorPrimary = 0; + int colorBackground = 0; for (--activityNdx; activityNdx >= 0; --activityNdx) { final ActivityRecord r = mActivities.get(activityNdx); if (r.taskDescription != null) { @@ -1023,9 +1024,13 @@ final class TaskRecord { if (colorPrimary == 0) { colorPrimary = r.taskDescription.getPrimaryColor(); } + if (colorBackground == 0) { + colorBackground = r.taskDescription.getBackgroundColor(); + } } } - lastTaskDescription = new TaskDescription(label, colorPrimary, iconFilename); + lastTaskDescription = new TaskDescription(label, null, iconFilename, colorPrimary, + colorBackground); // Update the task affiliation color if we are the parent of the group if (taskId == mAffiliatedTaskId) { mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor(); -- 2.11.0