Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1af8eda6 authored by Winson Chung's avatar Winson Chung Committed by Winson
Browse files

Drawing thumbnail background color for empty space in view.



Change-Id: I2e8dfbe9c11a61876956658eff0674adb26d855d

Signed-off-by: default avatarWinson <winsonc@google.com>
parent 7f036f8b
Loading
Loading
Loading
Loading
+60 −21
Original line number Diff line number Diff line
@@ -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;
        }
+57 −21
Original line number Diff line number Diff line
@@ -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) {
@@ -956,6 +962,18 @@ public class ActivityManager {
            mColorPrimary = primaryColor;
        }

        /**
         * 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;
        }
    }

+8 −8
Original line number Diff line number Diff line
@@ -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;
    }

+2 −0
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@

    <!-- The default recents task bar background color. -->
    <color name="recents_task_bar_default_background_color">#ffe6e6e6</color>
    <!-- The default recents task view background color. -->
    <color name="recents_task_view_default_background_color">#fff3f3f3</color>
    <!-- The recents task bar light text color to be drawn on top of dark backgrounds. -->
    <color name="recents_task_bar_light_text_color">#ffeeeeee</color>
    <!-- The recents task bar dark text color to be drawn on top of light backgrounds. -->
+2 −1
Original line number Diff line number Diff line
@@ -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();
Loading