blob: deb9df3ed67eb3dcf095555dfa98a5097e5235f8 [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.recents.views;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
/* The task bar view */
class TaskBarView extends FrameLayout {
RecentsConfiguration mConfig;
Task mTask;
ImageView mDismissButton;
ImageView mApplicationIcon;
TextView mActivityDescription;
Drawable mLightDismissDrawable;
Drawable mDarkDismissDrawable;
Paint mLayerPaint = new Paint();
static Paint sHighlightPaint;
public TaskBarView(Context context) {
this(context, null);
}
public TaskBarView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TaskBarView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public TaskBarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mConfig = RecentsConfiguration.getInstance();
setWillNotDraw(false);
// Load the dismiss resources
Resources res = context.getResources();
mLightDismissDrawable = res.getDrawable(R.drawable.recents_dismiss_light);
mDarkDismissDrawable = res.getDrawable(R.drawable.recents_dismiss_dark);
// Configure the highlight paint
if (sHighlightPaint == null) {
sHighlightPaint = new Paint();
sHighlightPaint.setStyle(Paint.Style.STROKE);
sHighlightPaint.setStrokeWidth(mConfig.taskViewHighlightPx);
sHighlightPaint.setColor(mConfig.taskBarViewHighlightColor);
sHighlightPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
sHighlightPaint.setAntiAlias(true);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// We ignore taps on the task bar except on the filter and dismiss buttons
if (!Constants.DebugFlags.App.EnableTaskBarTouchEvents) return true;
return super.onTouchEvent(event);
}
@Override
protected void onFinishInflate() {
// Initialize the icon and description views
mApplicationIcon = (ImageView) findViewById(R.id.application_icon);
mActivityDescription = (TextView) findViewById(R.id.activity_description);
mDismissButton = (ImageView) findViewById(R.id.dismiss_task);
// Hide the backgrounds if they are ripple drawables
if (!Constants.DebugFlags.App.EnableTaskFiltering) {
if (mApplicationIcon.getBackground() instanceof RippleDrawable) {
mApplicationIcon.setBackground(null);
}
}
}
@Override
protected void onDraw(Canvas canvas) {
// Draw the highlight at the top edge (but put the bottom edge just out of view)
float offset = mConfig.taskViewHighlightPx / 2f;
float radius = mConfig.taskViewRoundedCornerRadiusPx;
canvas.drawRoundRect(-offset, 0f, (float) getMeasuredWidth() + offset,
getMeasuredHeight() + radius, radius, radius, sHighlightPaint);
}
/** Synchronizes this bar view's properties with the task's transform */
void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration) {
if (duration > 0 && (mDismissButton.getVisibility() == View.VISIBLE)) {
ViewPropertyAnimator anim = mDismissButton.animate();
// Animate to the final state
if (toTransform.hasDismissAlphaChangedFrom(mDismissButton.getAlpha())) {
anim.alpha(toTransform.dismissAlpha)
.setStartDelay(0)
.setDuration(duration)
.setInterpolator(mConfig.fastOutSlowInInterpolator)
.withLayer()
.start();
}
} else {
// Set the changed properties
if (toTransform.hasDismissAlphaChangedFrom(mDismissButton.getAlpha())) {
mDismissButton.setAlpha(toTransform.dismissAlpha);
}
}
}
@Override
public boolean hasOverlappingRendering() {
return false;
}
/** Binds the bar view to the task */
void rebindToTask(Task t) {
mTask = t;
// 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
if (t.activityIcon != null) {
mApplicationIcon.setImageDrawable(t.activityIcon);
} else if (t.applicationIcon != null) {
mApplicationIcon.setImageDrawable(t.applicationIcon);
}
if (!mActivityDescription.getText().toString().equals(t.activityLabel)) {
mActivityDescription.setText(t.activityLabel);
}
// Try and apply the system ui tint
setBackgroundColor(t.colorPrimary);
mActivityDescription.setTextColor(t.useLightOnPrimaryColor ?
mConfig.taskBarViewLightTextColor : mConfig.taskBarViewDarkTextColor);
mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
mLightDismissDrawable : mDarkDismissDrawable);
}
/** Unbinds the bar view from the task */
void unbindFromTask() {
mTask = null;
mApplicationIcon.setImageDrawable(null);
}
/** Prepares this task view for the enter-recents animations. This is called earlier in the
* first layout because the actual animation into recents may take a long time. */
public void prepareEnterRecentsAnimation() {
setVisibility(View.INVISIBLE);
}
/** Animates this task bar as it enters recents */
public void startEnterRecentsAnimation(int delay, Runnable postAnimRunnable) {
// Animate the task bar of the first task view
setVisibility(View.VISIBLE);
setTranslationY(-getMeasuredHeight());
animate()
.translationY(0)
.setStartDelay(delay)
.setInterpolator(mConfig.fastOutSlowInInterpolator)
.setDuration(mConfig.taskBarEnterAnimDuration)
.withEndAction(postAnimRunnable)
.start();
}
/** Animates this task bar as it exits recents */
public void startLaunchTaskAnimation(Runnable preAnimRunnable, final Runnable postAnimRunnable) {
// Animate the task bar out of the first task view
animate()
.translationY(-getMeasuredHeight())
.setStartDelay(0)
.setInterpolator(mConfig.fastOutLinearInInterpolator)
.setDuration(mConfig.taskBarExitAnimDuration)
.withStartAction(preAnimRunnable)
.withEndAction(new Runnable() {
@Override
public void run() {
post(postAnimRunnable);
}
})
.start();
}
/** Animates this task bar dismiss button when launching a task. */
public void startLaunchTaskDismissAnimation() {
if (mDismissButton.getVisibility() == View.VISIBLE) {
mDismissButton.animate().cancel();
mDismissButton.animate()
.alpha(0f)
.setStartDelay(0)
.setInterpolator(mConfig.fastOutSlowInInterpolator)
.setDuration(mConfig.taskBarExitAnimDuration)
.withLayer()
.start();
}
}
/** Animates this task bar if the user does not interact with the stack after a certain time. */
public void startNoUserInteractionAnimation() {
mDismissButton.setVisibility(View.VISIBLE);
mDismissButton.setAlpha(0f);
mDismissButton.animate()
.alpha(1f)
.setStartDelay(0)
.setInterpolator(mConfig.fastOutLinearInInterpolator)
.setDuration(mConfig.taskBarEnterAnimDuration)
.withLayer()
.start();
}
/** Mark this task view that the user does has not interacted with the stack after a certain time. */
public void setNoUserInteractionState() {
if (mDismissButton.getVisibility() != View.VISIBLE) {
mDismissButton.animate().cancel();
mDismissButton.setVisibility(View.VISIBLE);
mDismissButton.setAlpha(1f);
}
}
/** Enable the hw layers on this task view */
void enableHwLayers() {
mDismissButton.setLayerType(View.LAYER_TYPE_HARDWARE, mLayerPaint);
}
/** Disable the hw layers on this task view */
void disableHwLayers() {
mDismissButton.setLayerType(View.LAYER_TYPE_NONE, mLayerPaint);
}
}