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

Commit 42007e34 authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Simplifying the task header highlight drawing."

parents 9d46b3ef 94a0e89a
Loading
Loading
Loading
Loading
+0 −2
Original line number Original line Diff line number Diff line
@@ -62,8 +62,6 @@
    <color name="recents_task_bar_light_icon_color">#ffeeeeee</color>
    <color name="recents_task_bar_light_icon_color">#ffeeeeee</color>
    <!-- The recents task bar dark dismiss icon color to be drawn on top of light backgrounds. -->
    <!-- The recents task bar dark dismiss icon color to be drawn on top of light backgrounds. -->
    <color name="recents_task_bar_dark_icon_color">#99000000</color>
    <color name="recents_task_bar_dark_icon_color">#99000000</color>
    <!-- The recents task bar highlight color. -->
    <color name="recents_task_bar_highlight_color">#28ffffff</color>
    <!-- The lock to task button background color. -->
    <!-- The lock to task button background color. -->
    <color name="recents_task_view_lock_to_app_button_background_color">#ffe6e6e6</color>
    <color name="recents_task_view_lock_to_app_button_background_color">#ffe6e6e6</color>
    <!-- The lock to task button foreground color. -->
    <!-- The lock to task button foreground color. -->
+3 −3
Original line number Original line Diff line number Diff line
@@ -198,16 +198,16 @@
    <dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
    <dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>


    <!-- The min translation in the Z index for the last task. -->
    <!-- The min translation in the Z index for the last task. -->
    <dimen name="recents_task_view_z_min">20dp</dimen>
    <dimen name="recents_task_view_z_min">16dp</dimen>


    <!-- The max translation in the Z index for the last task. -->
    <!-- The max translation in the Z index for the last task. -->
    <dimen name="recents_task_view_z_max">80dp</dimen>
    <dimen name="recents_task_view_z_max">48dp</dimen>


    <!-- The amount to translate when animating the removal of a task. -->
    <!-- The amount to translate when animating the removal of a task. -->
    <dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>
    <dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>


    <!-- The amount of highlight to make on each task view. -->
    <!-- The amount of highlight to make on each task view. -->
    <dimen name="recents_task_view_highlight">1.5dp</dimen>
    <dimen name="recents_task_view_highlight">1dp</dimen>


    <!-- The amount to offset when animating into an affiliate group. -->
    <!-- The amount to offset when animating into an affiliate group. -->
    <dimen name="recents_task_view_affiliate_group_enter_offset">64dp</dimen>
    <dimen name="recents_task_view_affiliate_group_enter_offset">64dp</dimen>
+5 −3
Original line number Original line Diff line number Diff line
@@ -200,9 +200,11 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
    @Override
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        super.onSizeChanged(w, h, oldw, oldh);
        if (w > 0 && h > 0) {
            mHeaderView.onTaskViewSizeChanged(w, h);
            mHeaderView.onTaskViewSizeChanged(w, h);
            mThumbnailView.onTaskViewSizeChanged(w, h);
            mThumbnailView.onTaskViewSizeChanged(w, h);
        }
        }
    }


    @Override
    @Override
    public boolean hasOverlappingRendering() {
    public boolean hasOverlappingRendering() {
@@ -378,7 +380,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
        } else {
        } else {
            float dimAlpha = mDimAlpha / 255.0f;
            float dimAlpha = mDimAlpha / 255.0f;
            mThumbnailView.setDimAlpha(dimAlpha);
            mThumbnailView.setDimAlpha(dimAlpha);
            mHeaderView.setDimAlpha(dim);
            mHeaderView.setDimAlpha(dimAlpha);
        }
        }
    }
    }


+116 −72
Original line number Original line Diff line number Diff line
@@ -16,18 +16,18 @@


package com.android.systemui.recents.views;
package com.android.systemui.recents.views;


import android.annotation.Nullable;
import android.content.Context;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PixelFormat;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.RippleDrawable;
import android.graphics.drawable.RippleDrawable;
import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.util.AttributeSet;
import android.view.View;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.AnimationUtils;
@@ -36,6 +36,7 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsLogger;

import com.android.systemui.R;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.Recents;
@@ -55,6 +56,66 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
public class TaskViewHeader extends FrameLayout
public class TaskViewHeader extends FrameLayout
        implements View.OnClickListener, View.OnLongClickListener {
        implements View.OnClickListener, View.OnLongClickListener {


    private static final float HIGHLIGHT_LIGHTNESS_INCREMENT = 0.125f;

    /**
     * A color drawable that draws a slight highlight at the top to help it stand out.
     */
    private class HighlightColorDrawable extends Drawable {

        private Paint mHighlightPaint = new Paint();
        private Paint mBackgroundPaint = new Paint();

        private float[] mTmpHSL = new float[3];

        public HighlightColorDrawable() {
            mBackgroundPaint.setColor(Color.argb(255, 0, 0, 0));
            mBackgroundPaint.setAntiAlias(true);
            mHighlightPaint.setColor(Color.argb(255, 255, 255, 255));
            mHighlightPaint.setAntiAlias(true);
        }

        public void setColorAndDim(int color, float dimAlpha) {
            mBackgroundPaint.setColor(color);

            ColorUtils.colorToHSL(color, mTmpHSL);
            // TODO: Consider using the saturation of the color to adjust the lightness as well
            mTmpHSL[2] = Math.min(1f,
                    mTmpHSL[2] + HIGHLIGHT_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
            mHighlightPaint.setColor(ColorUtils.HSLToColor(mTmpHSL));

            invalidateSelf();
        }

        @Override
        public void setColorFilter(@Nullable ColorFilter colorFilter) {
            // Do nothing
        }

        @Override
        public void setAlpha(int alpha) {
            // Do nothing
        }

        @Override
        public void draw(Canvas canvas) {
            // Draw the highlight at the top edge (but put the bottom edge just out of view)
            canvas.drawRoundRect(0, 0, mTaskViewRect.width(),
                    2 * Math.max(mHighlightHeight, mCornerRadius),
                    mCornerRadius, mCornerRadius, mHighlightPaint);

            // Draw the background with the rounded corners
            canvas.drawRoundRect(0, mHighlightHeight, mTaskViewRect.width(),
                    getHeight() + mCornerRadius,
                    mCornerRadius, mCornerRadius, mBackgroundPaint);
        }

        @Override
        public int getOpacity() {
            return PixelFormat.OPAQUE;
        }
    }

    Task mTask;
    Task mTask;


    // Header views
    // Header views
@@ -68,17 +129,18 @@ public class TaskViewHeader extends FrameLayout
    Rect mTaskViewRect = new Rect();
    Rect mTaskViewRect = new Rect();
    int mCornerRadius;
    int mCornerRadius;
    int mHighlightHeight;
    int mHighlightHeight;
    float mDimAlpha;
    Drawable mLightDismissDrawable;
    Drawable mLightDismissDrawable;
    Drawable mDarkDismissDrawable;
    Drawable mDarkDismissDrawable;
    RippleDrawable mBackground;
    int mTaskBarViewLightTextColor;
    GradientDrawable mBackgroundColorDrawable;
    int mTaskBarViewDarkTextColor;
    String mDismissContentDescription;
    String mDismissContentDescription;


    // Static highlight that we draw at the top of each view
    // Header background
    static Paint sHighlightPaint;
    private HighlightColorDrawable mBackground;


    // Header dim, which is only used when task view hardware layers are not used
    // Header dim, which is only used when task view hardware layers are not used
    Paint mDimLayerPaint = new Paint();
    private Paint mDimLayerPaint = new Paint();


    Interpolator mFastOutSlowInInterpolator;
    Interpolator mFastOutSlowInInterpolator;
    Interpolator mFastOutLinearInInterpolator;
    Interpolator mFastOutLinearInInterpolator;
@@ -100,29 +162,26 @@ public class TaskViewHeader extends FrameLayout
        setWillNotDraw(false);
        setWillNotDraw(false);


        // Load the dismiss resources
        // Load the dismiss resources
        mDimLayerPaint.setColor(Color.argb(0, 0, 0, 0));
        Resources res = context.getResources();
        mLightDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_light);
        mLightDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_light);
        mDarkDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_dark);
        mDarkDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_dark);
        mDismissContentDescription =
        mDismissContentDescription = context.getString(
                context.getString(R.string.accessibility_recents_item_will_be_dismissed);
                R.string.accessibility_recents_item_will_be_dismissed);
        mCornerRadius = getResources().getDimensionPixelSize(
        mCornerRadius = res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
                R.dimen.recents_task_view_rounded_corners_radius);
        mHighlightHeight = res.getDimensionPixelSize(R.dimen.recents_task_view_highlight);
        mHighlightHeight = getResources().getDimensionPixelSize(
        mTaskBarViewLightTextColor = context.getColor(R.color.recents_task_bar_light_text_color);
                R.dimen.recents_task_view_highlight);
        mTaskBarViewDarkTextColor = context.getColor(R.color.recents_task_bar_dark_text_color);
        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                com.android.internal.R.interpolator.fast_out_slow_in);
                com.android.internal.R.interpolator.fast_out_slow_in);
        mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
        mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
                com.android.internal.R.interpolator.fast_out_linear_in);
                com.android.internal.R.interpolator.fast_out_linear_in);


        // Configure the highlight paint
        // Configure the background and dim
        if (sHighlightPaint == null) {
        mBackground = new HighlightColorDrawable();
            sHighlightPaint = new Paint();
        mBackground.setColorAndDim(Color.argb(255, 0, 0, 0), 0f);
            sHighlightPaint.setStyle(Paint.Style.STROKE);
        setBackground(mBackground);
            sHighlightPaint.setStrokeWidth(mHighlightHeight);
        mDimLayerPaint.setColor(Color.argb(255, 0, 0, 0));
            sHighlightPaint.setColor(context.getColor(R.color.recents_task_bar_highlight_color));
        mDimLayerPaint.setAntiAlias(true);
            sHighlightPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
            sHighlightPaint.setAntiAlias(true);
        }
    }
    }


    @Override
    @Override
@@ -139,16 +198,6 @@ public class TaskViewHeader extends FrameLayout
        if (mIconView.getBackground() instanceof RippleDrawable) {
        if (mIconView.getBackground() instanceof RippleDrawable) {
            mIconView.setBackground(null);
            mIconView.setBackground(null);
        }
        }

        mBackgroundColorDrawable = (GradientDrawable) getContext().getDrawable(
                R.drawable.recents_task_view_header_bg_color);
        // Copy the ripple drawable since we are going to be manipulating it
        mBackground = (RippleDrawable)
                getContext().getDrawable(R.drawable.recents_task_view_header_bg);
        mBackground = (RippleDrawable) mBackground.mutate().getConstantState().newDrawable();
        mBackground.setColor(ColorStateList.valueOf(0));
        mBackground.setDrawableByLayerId(mBackground.getId(0), mBackgroundColorDrawable);
        setBackground(mBackground);
    }
    }


    /**
    /**
@@ -156,6 +205,11 @@ public class TaskViewHeader extends FrameLayout
     * to match the frame changes.
     * to match the frame changes.
     */
     */
    public void onTaskViewSizeChanged(int width, int height) {
    public void onTaskViewSizeChanged(int width, int height) {
        // Return early if the bounds have not changed
        if (mTaskViewRect.width() == width && mTaskViewRect.height() == height) {
            return;
        }

        mTaskViewRect.set(0, 0, width, height);
        mTaskViewRect.set(0, 0, width, height);
        boolean updateMoveTaskButton = mMoveTaskButton.getVisibility() != View.GONE;
        boolean updateMoveTaskButton = mMoveTaskButton.getVisibility() != View.GONE;
        int appIconWidth = mIconView.getMeasuredWidth();
        int appIconWidth = mIconView.getMeasuredWidth();
@@ -201,31 +255,39 @@ public class TaskViewHeader extends FrameLayout
    }
    }


    @Override
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    protected boolean verifyDrawable(Drawable who) {
        onTaskViewSizeChanged(mTaskViewRect.width(), mTaskViewRect.height());
        return super.verifyDrawable(who) || (who == mBackground);
    }
    }


    @Override
    @Override
    protected void onDraw(Canvas canvas) {
    protected void dispatchDraw(Canvas canvas) {
        // Draw the highlight at the top edge (but put the bottom edge just out of view)
        super.dispatchDraw(canvas);
        float offset = (float) Math.ceil(mHighlightHeight / 2f);

        float radius = mCornerRadius;
        // Draw the dim layer with the rounded corners
        int count = canvas.save(Canvas.CLIP_SAVE_FLAG);
        canvas.drawRoundRect(0, 0, mTaskViewRect.width(), getHeight() + mCornerRadius,
        canvas.clipRect(0, 0, mTaskViewRect.width(), getMeasuredHeight());
                mCornerRadius, mCornerRadius, mDimLayerPaint);
        canvas.drawRoundRect(-offset, 0f, (float) mTaskViewRect.width() + offset,
                getMeasuredHeight() + radius, radius, radius, sHighlightPaint);
        canvas.restoreToCount(count);
    }
    }


    /**
    /**
     * Sets the dim alpha, only used when we are not using hardware layers.
     * Sets the dim alpha, only used when we are not using hardware layers.
     * (see RecentsConfiguration.useHardwareLayers)
     * (see RecentsConfiguration.useHardwareLayers)
     */
     */
    void setDimAlpha(int alpha) {
    void setDimAlpha(float dimAlpha) {
        mDimLayerPaint.setColor(Color.argb(alpha, 0, 0, 0));
        mDimAlpha = dimAlpha;
        updateBackgroundColor(dimAlpha);
        invalidate();
        invalidate();
    }
    }


    /**
     * Updates the background and highlight colors for this header.
     */
    private void updateBackgroundColor(float dimAlpha) {
        if (mTask != null) {
            mBackground.setColorAndDim(mTask.colorPrimary, dimAlpha);
            mDimLayerPaint.setAlpha((int) (dimAlpha * 255));
        }
    }

    /** Binds the bar view to the task */
    /** Binds the bar view to the task */
    public void rebindToTask(Task t) {
    public void rebindToTask(Task t) {
        SystemServicesProxy ssp = Recents.getSystemServices();
        SystemServicesProxy ssp = Recents.getSystemServices();
@@ -233,6 +295,7 @@ public class TaskViewHeader extends FrameLayout


        // If an activity icon is defined, then we use that as the primary icon to show in the bar,
        // If an activity icon is defined, then we use that as the primary icon to show in the bar,
        // otherwise, we fall back to the application icon
        // otherwise, we fall back to the application icon
        updateBackgroundColor(mDimAlpha);
        if (t.icon != null) {
        if (t.icon != null) {
            mIconView.setImageDrawable(t.icon);
            mIconView.setImageDrawable(t.icon);
        }
        }
@@ -240,20 +303,8 @@ public class TaskViewHeader extends FrameLayout
            mTitleView.setText(t.title);
            mTitleView.setText(t.title);
        }
        }
        mTitleView.setContentDescription(t.contentDescription);
        mTitleView.setContentDescription(t.contentDescription);

        // Try and apply the system ui tint
        int existingBgColor = (getBackground() instanceof ColorDrawable) ?
                ((ColorDrawable) getBackground()).getColor() : 0;
        if (existingBgColor != t.colorPrimary) {
            mBackgroundColorDrawable.setColor(t.colorPrimary);
        }

        int taskBarViewLightTextColor = getResources().getColor(
                R.color.recents_task_bar_light_text_color);
        int taskBarViewDarkTextColor = getResources().getColor(
                R.color.recents_task_bar_dark_text_color);
        mTitleView.setTextColor(t.useLightOnPrimaryColor ?
        mTitleView.setTextColor(t.useLightOnPrimaryColor ?
                taskBarViewLightTextColor : taskBarViewDarkTextColor);
                mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
        mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
        mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
                mLightDismissDrawable : mDarkDismissDrawable);
                mLightDismissDrawable : mDarkDismissDrawable);
        mDismissButton.setContentDescription(String.format(mDismissContentDescription,
        mDismissButton.setContentDescription(String.format(mDismissContentDescription,
@@ -273,7 +324,9 @@ public class TaskViewHeader extends FrameLayout
                        ? R.drawable.recents_move_task_freeform_light
                        ? R.drawable.recents_move_task_freeform_light
                        : R.drawable.recents_move_task_freeform_dark);
                        : R.drawable.recents_move_task_freeform_dark);
            }
            }
            if (mMoveTaskButton.getVisibility() != View.VISIBLE) {
                mMoveTaskButton.setVisibility(View.VISIBLE);
                mMoveTaskButton.setVisibility(View.VISIBLE);
            }
            mMoveTaskButton.setOnClickListener(this);
            mMoveTaskButton.setOnClickListener(this);
        }
        }


@@ -328,15 +381,6 @@ public class TaskViewHeader extends FrameLayout
        return new int[] {};
        return new int[] {};
    }
    }


    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);

        // Draw the dim layer with the rounded corners
        canvas.drawRoundRect(0, 0, mTaskViewRect.width(), getHeight(),
                mCornerRadius, mCornerRadius, mDimLayerPaint);
    }

    @Override
    @Override
    public void onClick(View v) {
    public void onClick(View v) {
        if (v == mIconView) {
        if (v == mIconView) {
+5 −0
Original line number Original line Diff line number Diff line
@@ -93,6 +93,11 @@ public class TaskViewThumbnail extends View {
     * to match the frame changes.
     * to match the frame changes.
     */
     */
    public void onTaskViewSizeChanged(int width, int height) {
    public void onTaskViewSizeChanged(int width, int height) {
        // Return early if the bounds have not changed
        if (mTaskViewRect.width() == width && mTaskViewRect.height() == height) {
            return;
        }

        mTaskViewRect.set(0, 0, width, height);
        mTaskViewRect.set(0, 0, width, height);
        updateThumbnailScale();
        updateThumbnailScale();
        invalidate();
        invalidate();