Jeff Sharkey
2015-10-12 18:39:17 +00:00
committed by Android Git Automerger
3 changed files with 98 additions and 46 deletions

View File

@@ -16,11 +16,13 @@
package com.android.systemui.recents.model;
import android.animation.ObjectAnimator;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.misc.NamedCounter;
@@ -193,10 +195,37 @@ public class TaskStack {
BOTTOM(DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, 192,
new RectF(0, 0.7f, 1, 1), new RectF(0, 0.7f, 1, 1), new RectF(0, 0, 1, 0.3f));
// Represents the view state of this dock state
public class ViewState {
public final int dockAreaAlpha;
public final ColorDrawable dockAreaOverlay;
private ObjectAnimator dockAreaOverlayAnimator;
private ViewState(int alpha) {
dockAreaAlpha = alpha;
dockAreaOverlay = new ColorDrawable(0xFFffffff);
dockAreaOverlay.setAlpha(0);
}
/**
* Creates a new alpha animation.
*/
public void startAlphaAnimation(int alpha, int duration) {
if (dockAreaOverlay.getAlpha() != alpha) {
if (dockAreaOverlayAnimator != null) {
dockAreaOverlayAnimator.cancel();
}
dockAreaOverlayAnimator = ObjectAnimator.ofInt(dockAreaOverlay, "alpha", alpha);
dockAreaOverlayAnimator.setDuration(duration);
dockAreaOverlayAnimator.start();
}
}
}
public final int createMode;
public final int dockAreaAlpha;
private final RectF touchArea;
public final ViewState viewState;
private final RectF dockArea;
private final RectF touchArea;
private final RectF stackArea;
/**
@@ -207,9 +236,9 @@ public class TaskStack {
DockState(int createMode, int dockAreaAlpha, RectF touchArea, RectF dockArea,
RectF stackArea) {
this.createMode = createMode;
this.dockAreaAlpha = dockAreaAlpha;
this.touchArea = touchArea;
this.viewState = new ViewState(dockAreaAlpha);
this.dockArea = dockArea;
this.touchArea = touchArea;
this.stackArea = stackArea;
}

View File

@@ -16,19 +16,17 @@
package com.android.systemui.recents.views;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
@@ -38,7 +36,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManagerGlobal;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
@@ -91,8 +88,12 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
RecentsViewTouchHandler mTouchHandler;
DragView mDragView;
ColorDrawable mDockRegionOverlay;
ObjectAnimator mDockRegionOverlayAnimator;
TaskStack.DockState[] mVisibleDockStates = {
TaskStack.DockState.LEFT,
TaskStack.DockState.TOP,
TaskStack.DockState.RIGHT,
TaskStack.DockState.BOTTOM,
};
Interpolator mFastOutSlowInInterpolator;
@@ -118,9 +119,6 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.fast_out_slow_in);
mTouchHandler = new RecentsViewTouchHandler(this);
mDockRegionOverlay = new ColorDrawable(0xFFffffff);
mDockRegionOverlay.setAlpha(0);
mDockRegionOverlay.setCallback(this);
}
/** Sets the callbacks */
@@ -383,14 +381,23 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mDockRegionOverlay.getAlpha() > 0) {
mDockRegionOverlay.draw(canvas);
for (int i = mVisibleDockStates.length - 1; i >= 0; i--) {
Drawable d = mVisibleDockStates[i].viewState.dockAreaOverlay;
if (d.getAlpha() > 0) {
d.draw(canvas);
}
}
}
@Override
protected boolean verifyDrawable(Drawable who) {
return super.verifyDrawable(who) || who == mDockRegionOverlay;
for (int i = mVisibleDockStates.length - 1; i >= 0; i--) {
Drawable d = mVisibleDockStates[i].viewState.dockAreaOverlay;
if (d == who) {
return true;
}
}
return super.verifyDrawable(who);
}
/** Notifies each task view of the user interaction. */
@@ -775,11 +782,17 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
mDragView = event.dragView;
addView(mDragView);
updateDockRegion(TaskStack.DockState.NONE);
updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(),
TaskStack.DockState.NONE.viewState.dockAreaAlpha);
}
public final void onBusEvent(DragDockStateChangedEvent event) {
updateDockRegion(event.dockState);
if (event.dockState == TaskStack.DockState.NONE) {
updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(),
TaskStack.DockState.NONE.viewState.dockAreaAlpha);
} else {
updateVisibleDockRegions(new TaskStack.DockState[] {event.dockState}, -1);
}
}
public final void onBusEvent(final DragEndEvent event) {
@@ -790,8 +803,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
// Remove the drag view
removeView(mDragView);
mDragView = null;
mDockRegionOverlay.setAlpha(0);
invalidate();
updateVisibleDockRegions(null, -1);
// Dock the new task if we are hovering over a valid dock state
if (event.dockState != TaskStack.DockState.NONE) {
@@ -818,7 +830,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
.start();
// Animate the overlay alpha back to 0
updateDockRegionAlpha(0);
updateVisibleDockRegions(null, -1);
} else {
event.postAnimationTrigger.decrement();
}
@@ -827,24 +839,26 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
/**
* Updates the dock region to match the specified dock state.
*/
private void updateDockRegion(TaskStack.DockState dockState) {
TaskStack.DockState boundsDockState = dockState;
if (dockState == TaskStack.DockState.NONE) {
// If the dock state is null, then use the bounds of the preferred dock state for this
// orientation
boundsDockState = mTouchHandler.getPreferredDockStateForCurrentOrientation();
private void updateVisibleDockRegions(TaskStack.DockState[] newDockStates, int overrideAlpha) {
ArraySet<TaskStack.DockState> newDockStatesSet = new ArraySet<>();
if (newDockStates != null) {
for (TaskStack.DockState dockState : newDockStates) {
newDockStatesSet.add(dockState);
}
}
mDockRegionOverlay.setBounds(
boundsDockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight()));
updateDockRegionAlpha(dockState.dockAreaAlpha);
}
private void updateDockRegionAlpha(int alpha) {
if (mDockRegionOverlayAnimator != null) {
mDockRegionOverlayAnimator.cancel();
for (TaskStack.DockState dockState : mVisibleDockStates) {
TaskStack.DockState.ViewState viewState = dockState.viewState;
if (newDockStates == null || !newDockStatesSet.contains(dockState)) {
// This is no longer visible, so hide it
viewState.startAlphaAnimation(0, 150);
} else {
// This state is now visible, update the bounds and show it
int alpha = (overrideAlpha != -1 ? overrideAlpha : viewState.dockAreaAlpha);
viewState.dockAreaOverlay.setBounds(
dockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight()));
viewState.dockAreaOverlay.setCallback(this);
viewState.startAlphaAnimation(alpha, 150);
}
}
mDockRegionOverlayAnimator = ObjectAnimator.ofInt(mDockRegionOverlay, "alpha", alpha);
mDockRegionOverlayAnimator.setDuration(150);
mDockRegionOverlayAnimator.start();
}
}

View File

@@ -19,6 +19,7 @@ package com.android.systemui.recents.views;
import android.content.res.Configuration;
import android.graphics.Point;
import android.view.MotionEvent;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.ui.dragndrop.DragDockStateChangedEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
@@ -32,13 +33,17 @@ import com.android.systemui.recents.model.TaskStack;
* Represents the dock regions for each orientation.
*/
class DockRegion {
public static TaskStack.DockState[] LANDSCAPE = {
public static TaskStack.DockState[] PHONE_LANDSCAPE = {
TaskStack.DockState.LEFT, TaskStack.DockState.RIGHT
};
public static TaskStack.DockState[] PORTRAIT = {
public static TaskStack.DockState[] PHONE_PORTRAIT = {
// We only allow docking to the top for now
TaskStack.DockState.TOP
};
public static TaskStack.DockState[] TABLET_LANDSCAPE = {
TaskStack.DockState.LEFT, TaskStack.DockState.RIGHT
};
public static TaskStack.DockState[] TABLET_PORTRAIT = PHONE_PORTRAIT;
}
/**
@@ -60,12 +65,17 @@ class RecentsViewTouchHandler {
mRv = rv;
}
public TaskStack.DockState getPreferredDockStateForCurrentOrientation() {
/**
* Returns the preferred dock states for the current orientation.
*/
public TaskStack.DockState[] getDockStatesForCurrentOrientation() {
boolean isLandscape = mRv.getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_LANDSCAPE;
RecentsConfiguration config = RecentsConfiguration.getInstance();
TaskStack.DockState[] dockStates = isLandscape ?
DockRegion.LANDSCAPE : DockRegion.PORTRAIT;
return dockStates[0];
(config.isLargeScreen ? DockRegion.TABLET_LANDSCAPE : DockRegion.PHONE_LANDSCAPE) :
(config.isLargeScreen ? DockRegion.TABLET_PORTRAIT : DockRegion.PHONE_PORTRAIT);
return dockStates;
}
/** Touch preprocessing for handling below */
@@ -125,10 +135,9 @@ class RecentsViewTouchHandler {
float y = evY - mDragView.getTopLeftOffset().y;
// Update the dock state
TaskStack.DockState[] dockStates = isLandscape ?
DockRegion.LANDSCAPE : DockRegion.PORTRAIT;
TaskStack.DockState[] dockStates = getDockStatesForCurrentOrientation();
TaskStack.DockState foundDockState = TaskStack.DockState.NONE;
for (int i = 0; i < dockStates.length; i++) {
for (int i = dockStates.length - 1; i >= 0; i--) {
TaskStack.DockState state = dockStates[i];
if (state.touchAreaContainsPoint(width, height, evX, evY)) {
foundDockState = state;