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 Diff line number Diff line
@@ -62,8 +62,6 @@
    <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. -->
    <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. -->
    <color name="recents_task_view_lock_to_app_button_background_color">#ffe6e6e6</color>
    <!-- The lock to task button foreground color. -->
+3 −3
Original line number Diff line number Diff line
@@ -198,16 +198,16 @@
    <dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>

    <!-- 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. -->
    <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. -->
    <dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>

    <!-- 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. -->
    <dimen name="recents_task_view_affiliate_group_enter_offset">64dp</dimen>
+5 −3
Original line number Diff line number Diff line
@@ -200,9 +200,11 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (w > 0 && h > 0) {
            mHeaderView.onTaskViewSizeChanged(w, h);
            mThumbnailView.onTaskViewSizeChanged(w, h);
        }
    }

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

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

package com.android.systemui.recents.views;

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

import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
@@ -55,6 +56,66 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
public class TaskViewHeader extends FrameLayout
        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;

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

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

    // 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 mFastOutLinearInInterpolator;
@@ -100,29 +162,26 @@ public class TaskViewHeader extends FrameLayout
        setWillNotDraw(false);

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

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

    @Override
@@ -139,16 +198,6 @@ public class TaskViewHeader extends FrameLayout
        if (mIconView.getBackground() instanceof RippleDrawable) {
            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.
     */
    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);
        boolean updateMoveTaskButton = mMoveTaskButton.getVisibility() != View.GONE;
        int appIconWidth = mIconView.getMeasuredWidth();
@@ -201,31 +255,39 @@ public class TaskViewHeader extends FrameLayout
    }

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

    @Override
    protected void onDraw(Canvas canvas) {
        // Draw the highlight at the top edge (but put the bottom edge just out of view)
        float offset = (float) Math.ceil(mHighlightHeight / 2f);
        float radius = mCornerRadius;
        int count = canvas.save(Canvas.CLIP_SAVE_FLAG);
        canvas.clipRect(0, 0, mTaskViewRect.width(), getMeasuredHeight());
        canvas.drawRoundRect(-offset, 0f, (float) mTaskViewRect.width() + offset,
                getMeasuredHeight() + radius, radius, radius, sHighlightPaint);
        canvas.restoreToCount(count);
    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, mCornerRadius, mDimLayerPaint);
    }

    /**
     * Sets the dim alpha, only used when we are not using hardware layers.
     * (see RecentsConfiguration.useHardwareLayers)
     */
    void setDimAlpha(int alpha) {
        mDimLayerPaint.setColor(Color.argb(alpha, 0, 0, 0));
    void setDimAlpha(float dimAlpha) {
        mDimAlpha = dimAlpha;
        updateBackgroundColor(dimAlpha);
        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 */
    public void rebindToTask(Task t) {
        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,
        // otherwise, we fall back to the application icon
        updateBackgroundColor(mDimAlpha);
        if (t.icon != null) {
            mIconView.setImageDrawable(t.icon);
        }
@@ -240,20 +303,8 @@ public class TaskViewHeader extends FrameLayout
            mTitleView.setText(t.title);
        }
        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 ?
                taskBarViewLightTextColor : taskBarViewDarkTextColor);
                mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
        mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
                mLightDismissDrawable : mDarkDismissDrawable);
        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_dark);
            }
            if (mMoveTaskButton.getVisibility() != View.VISIBLE) {
                mMoveTaskButton.setVisibility(View.VISIBLE);
            }
            mMoveTaskButton.setOnClickListener(this);
        }

@@ -328,15 +381,6 @@ public class TaskViewHeader extends FrameLayout
        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
    public void onClick(View v) {
        if (v == mIconView) {
+5 −0
Original line number Diff line number Diff line
@@ -93,6 +93,11 @@ public class TaskViewThumbnail extends View {
     * to match the frame changes.
     */
    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);
        updateThumbnailScale();
        invalidate();