Merge "Fixing issue with the lock-to-app setting not being refreshed when entering recents." into lmp-dev

This commit is contained in:
Winson Chung
2014-07-23 21:53:22 +00:00
committed by Android (Google) Code Review
9 changed files with 105 additions and 102 deletions

View File

@@ -67,8 +67,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/recents_task_view_lock_to_app_button_height"
android:layout_gravity="center_horizontal|bottom"
android:background="@drawable/recents_lock_to_task_button_bg"
android:visibility="invisible">
android:background="@drawable/recents_lock_to_task_button_bg">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"

View File

@@ -431,6 +431,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
super.onNewIntent(intent);
setIntent(intent);
// Reinitialize the configuration
RecentsConfiguration.reinitialize(this, RecentsTaskLoader.getInstance().getSystemServicesProxy());
// Clear any debug rects
if (mDebugOverlay != null) {
mDebugOverlay.clear();

View File

@@ -305,6 +305,11 @@ public class RecentsConfiguration {
(!transposeRecentsLayoutWithOrientation || !isLandscape);
}
/** Returns whether the current layout is horizontal. */
public boolean hasHorizontalLayout() {
return isLandscape && transposeRecentsLayoutWithOrientation;
}
/**
* Returns the task stack bounds in the current orientation. These bounds do not account for
* the system insets.

View File

@@ -17,6 +17,7 @@
package com.android.systemui.recents.views;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.graphics.Outline;
import android.graphics.Rect;
import android.view.View;
@@ -34,6 +35,7 @@ public class AnimateableViewBounds extends ViewOutlineProvider {
int mCornerRadius;
ObjectAnimator mClipTopAnimator;
ObjectAnimator mClipRightAnimator;
ObjectAnimator mClipBottomAnimator;
public AnimateableViewBounds(View source, int cornerRadius) {
@@ -42,6 +44,7 @@ public class AnimateableViewBounds extends ViewOutlineProvider {
mCornerRadius = cornerRadius;
mSourceView.setClipToOutline(true);
setClipTop(getClipTop());
setClipRight(getClipRight());
setClipBottom(getClipBottom());
setOutlineClipBottom(getOutlineClipBottom());
}
@@ -56,7 +59,7 @@ public class AnimateableViewBounds extends ViewOutlineProvider {
}
/** Animates the top clip. */
void animateClipTop(int top, int duration) {
void animateClipTop(int top, int duration, ValueAnimator.AnimatorUpdateListener updateListener) {
if (mClipTopAnimator != null) {
mClipTopAnimator.removeAllListeners();
mClipTopAnimator.cancel();
@@ -64,6 +67,9 @@ public class AnimateableViewBounds extends ViewOutlineProvider {
mClipTopAnimator = ObjectAnimator.ofInt(this, "clipTop", top);
mClipTopAnimator.setDuration(duration);
mClipTopAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
if (updateListener != null) {
mClipTopAnimator.addUpdateListener(updateListener);
}
mClipTopAnimator.start();
}
@@ -80,16 +86,41 @@ public class AnimateableViewBounds extends ViewOutlineProvider {
return mClipRect.top;
}
/** Animates the right clip. */
void animateClipRight(int right, int duration) {
if (mClipRightAnimator != null) {
mClipRightAnimator.removeAllListeners();
mClipRightAnimator.cancel();
}
mClipRightAnimator = ObjectAnimator.ofInt(this, "clipRight", right);
mClipRightAnimator.setDuration(duration);
mClipRightAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
mClipRightAnimator.start();
}
/** Sets the right clip. */
public void setClipRight(int right) {
if (right != mClipRect.right) {
mClipRect.right = right;
mSourceView.invalidateOutline();
}
}
/** Returns the right clip. */
public int getClipRight() {
return mClipRect.right;
}
/** Animates the bottom clip. */
void animateClipBottom(int bottom, int duration) {
if (mClipTopAnimator != null) {
mClipTopAnimator.removeAllListeners();
mClipTopAnimator.cancel();
if (mClipBottomAnimator != null) {
mClipBottomAnimator.removeAllListeners();
mClipBottomAnimator.cancel();
}
mClipTopAnimator = ObjectAnimator.ofInt(this, "clipBottom", bottom);
mClipTopAnimator.setDuration(duration);
mClipTopAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
mClipTopAnimator.start();
mClipBottomAnimator = ObjectAnimator.ofInt(this, "clipBottom", bottom);
mClipBottomAnimator.setDuration(duration);
mClipBottomAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
mClipBottomAnimator.start();
}
/** Sets the bottom clip. */
@@ -105,6 +136,7 @@ public class AnimateableViewBounds extends ViewOutlineProvider {
return mClipRect.bottom;
}
/** Sets the outline bottom clip. */
public void setOutlineClipBottom(int bottom) {
if (bottom != mOutlineClipRect.bottom) {
mOutlineClipRect.bottom = bottom;
@@ -112,6 +144,7 @@ public class AnimateableViewBounds extends ViewOutlineProvider {
}
}
/** Gets the outline bottom clip. */
public int getOutlineClipBottom() {
return mOutlineClipRect.bottom;
}

View File

@@ -16,12 +16,9 @@
package com.android.systemui.recents.views;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import com.android.systemui.recents.RecentsConfiguration;
@@ -82,9 +79,6 @@ public class TaskFooterView extends FrameLayout {
void animateFooterVisibility(final boolean visible, int duration) {
// Return early if there is no footer
if (mMaxFooterHeight <= 0) return;
// Return early if we are already in the final state
if (!visible && getVisibility() != View.VISIBLE) return;
if (visible && getVisibility() == View.VISIBLE) return;
// Cancel the previous animation
if (mFooterAnimator != null) {
@@ -93,25 +87,12 @@ public class TaskFooterView extends FrameLayout {
}
int finalHeight = visible ? mMaxFooterHeight : 0;
if (duration > 0) {
// Make the view visible for the animation
if (visible && getVisibility() != View.VISIBLE) {
setVisibility(View.VISIBLE);
}
mFooterAnimator = ObjectAnimator.ofInt(this, "footerHeight", finalHeight);
mFooterAnimator.setDuration(duration);
mFooterAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator);
mFooterAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (!visible) {
setVisibility(View.INVISIBLE);
}
}
});
mFooterAnimator.start();
} else {
setFooterHeight(finalHeight);
setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
}
}
}

View File

@@ -83,7 +83,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
int mFocusedTaskIndex = -1;
OverScroller mScroller;
ObjectAnimator mScrollAnimator;
boolean mEnableStackClipping = true;
// Optimizations
ReferenceCountedTrigger mHwLayersTrigger;
@@ -93,8 +92,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
boolean mStartEnterAnimationRequestedAfterLayout;
ViewAnimation.TaskViewEnterContext mStartEnterAnimationContext;
int[] mTmpVisibleRange = new int[2];
Rect mTmpRect = new Rect();
Rect mTmpRect2 = new Rect();
TaskViewTransform mTmpTransform = new TaskViewTransform();
HashMap<Task, TaskView> mTmpTaskViewMap = new HashMap<Task, TaskView>();
LayoutInflater mInflater;
@@ -189,7 +186,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
int stackScroll,
int[] visibleRangeOut,
boolean boundTranslationsToRect) {
// XXX: We should be intelligent about wheee to look for the visible stack range using the
// XXX: We should be intelligent about where to look for the visible stack range using the
// current stack scroll.
// XXX: We should log extra cases like the ones below where we don't expect to hit very often
// XXX: Print out approximately how many indices we have to go through to find the first visible transform
@@ -199,8 +196,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
int frontMostVisibleIndex = -1;
int backMostVisibleIndex = -1;
// We can reuse the task transforms where possible to reduce object allocation
if (taskTransformCount < taskCount) {
// If there are less transforms than tasks, then add as many transforms as necessary
@@ -290,6 +285,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
if (tv == null) {
tv = mViewPool.pickUpViewFromPool(task, task);
if (mStackViewsAnimationDuration > 0) {
// For items in the list, put them in start animating them from the
// approriate ends of the list where they are expected to appear
@@ -319,7 +315,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
/** Updates the clip for each of the task views. */
void clipTaskViews() {
// Update the clip on each task child
if (Constants.DebugFlags.App.EnableTaskStackClipping && mEnableStackClipping) {
if (Constants.DebugFlags.App.EnableTaskStackClipping) {
int childCount = getChildCount();
for (int i = 0; i < childCount - 1; i++) {
TaskView tv = (TaskView) getChildAt(i);
@@ -341,12 +337,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// stacked and we can make assumptions about the visibility of the this
// task relative to the ones in front of it.
if (nextTv != null) {
// We calculate the bottom clip independent of the footer (since we animate
// that)
int scaledMaxFooterHeight = (int) (tv.getMaxFooterHeight() * tv.getScaleX());
tv.getHitRect(mTmpRect);
nextTv.getHitRect(mTmpRect2);
clipBottom = (mTmpRect.bottom - scaledMaxFooterHeight - mTmpRect2.top);
// We can reuse the current task transforms to find the task rects
TaskViewTransform transform = mCurrentTaskTransforms.get(mStack.indexOfTask(tv.getTask()));
TaskViewTransform nextTransform = mCurrentTaskTransforms.get(mStack.indexOfTask(nextTv.getTask()));
clipBottom = transform.rect.bottom - nextTransform.rect.top - 200;
}
}
tv.getViewBounds().setClipBottom(clipBottom);
@@ -359,18 +353,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
}
/** Enables/Disables clipping of the tasks in the stack. */
void setStackClippingEnabled(boolean stackClippingEnabled) {
if (!stackClippingEnabled) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
TaskView tv = (TaskView) getChildAt(i);
tv.getViewBounds().setClipBottom(0);
}
}
mEnableStackClipping = stackClippingEnabled;
}
/** The stack insets to apply to the stack contents */
public void setStackInsetRect(Rect r) {
mTaskStackBounds.set(r);
@@ -634,18 +616,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
setStackScrollToInitialState();
requestSynchronizeStackViewsWithModel();
synchronizeStackViewsWithModel();
// Find the first task and mark it as full screen
if (mConfig.launchedFromAppWithScreenshot) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
TaskView tv = (TaskView) getChildAt(i);
if (tv.getTask().isLaunchTarget) {
tv.setIsFullScreen(true);
break;
}
}
}
}
// Measure each of the TaskViews
@@ -925,6 +895,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
public void prepareViewToLeavePool(TaskView tv, Task task, boolean isNewView) {
// Rebind the task and request that this task's data be filled into the TaskView
tv.onTaskBound(task);
// Mark the launch task as fullscreen
if (Constants.DebugFlags.App.EnableScreenshotAppTransition && mAwaitingFirstLayout) {
if (task.isLaunchTarget) {
tv.setIsFullScreen(true);
}
}
// Load the task data
RecentsTaskLoader.getInstance().loadTaskData(task);
// Sanity check, the task view should always be clipping against the stack at this point,

View File

@@ -82,7 +82,7 @@ public class TaskStackViewLayoutAlgorithm {
// Compute the min and max scroll values
int numTasks = Math.max(1, tasks.size());
int taskHeight = mTaskRect.height();
int stackHeight = mStackRect.height();
int stackHeight = mStackRectSansPeek.height();
if (numTasks <= 1) {
// If there is only one task, then center the task in the stack rect (sans peek)

View File

@@ -263,7 +263,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
int velocity = (int) velocityTracker.getYVelocity(mActivePointerId);
if (mIsScrolling && (Math.abs(velocity) > mMinimumVelocity)) {
// XXX: Make this animation a function of the velocity AND distance
int overscrollRange = (int) (Math.min(1f,
Math.abs((float) velocity / mMaximumVelocity)) *
Constants.Values.TaskStackView.TaskStackOverscrollRange);
@@ -277,7 +276,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
mSv.invalidate(mSv.mStackAlgorithm.mStackRect);
} else if (mSv.isScrollOutOfBounds()) {
// Animate the scroll back into bounds
// XXX: Make this animation a function of the velocity OR distance
mSv.animateBoundScroll();
}
@@ -303,7 +301,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
case MotionEvent.ACTION_CANCEL: {
if (mSv.isScrollOutOfBounds()) {
// Animate the scroll back into bounds
// XXX: Make this animation a function of the velocity OR distance
mSv.animateBoundScroll();
}
mActivePointerId = INACTIVE_POINTER_ID;

View File

@@ -21,7 +21,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
@@ -60,7 +59,6 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
boolean mTaskDataLoaded;
boolean mIsFocused;
boolean mIsFullScreenView;
boolean mIsStub;
boolean mClipViewInStack;
AnimateableViewBounds mViewBounds;
Paint mLayerPaint = new Paint();
@@ -123,7 +121,11 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
mBarView = (TaskBarView) findViewById(R.id.task_view_bar);
mThumbnailView = (TaskThumbnailView) findViewById(R.id.task_view_thumbnail);
mFooterView = (TaskFooterView) findViewById(R.id.lock_to_app);
mFooterView.setCallbacks(this);
if (mConfig.lockToAppEnabled) {
mFooterView.setCallbacks(this);
} else {
mFooterView.setVisibility(View.GONE);
}
}
@Override
@@ -147,6 +149,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY));
}
setMeasuredDimension(width, height);
invalidateOutline();
}
/** Synchronizes this view's properties with the task's transform */
@@ -201,9 +204,9 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
if (mConfig.launchedFromAppWithScreenshot) {
if (isTaskViewLaunchTargetTask) {
// Also hide the front most task bar view so we can animate it in
mBarView.prepareEnterRecentsAnimation();
// mBarView.prepareEnterRecentsAnimation();
} else {
// Don't do anything for the side views
// Don't do anything for the side views when animating in
}
} else if (mConfig.launchedFromAppWithThumbnail) {
@@ -232,17 +235,32 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
if (mConfig.launchedFromAppWithScreenshot) {
if (mTask.isLaunchTarget) {
// XXX: We would have to animate the trasnlationY of the task view bar along with the clip and
// reset it at the bottom
int duration = mConfig.taskViewEnterFromHomeDuration * 5;
int windowInsetTop = mConfig.systemInsets.top; // XXX: Should be for the window
float taskScale = ((float) taskRect.width() / getMeasuredWidth()) * transform.scale;
float taskTranslationY = taskRect.top + transform.translationY - windowInsetTop;
// XXX: This should actually be the inset on the current app...
mViewBounds.animateClipTop(taskRect.top, mConfig.taskViewEnterFromHomeDuration * 5);
mViewBounds.animateClipBottom(getMeasuredHeight() - taskRect.bottom, mConfig.taskViewEnterFromHomeDuration * 5);
animate().scaleX(((float) taskRect.width() / getMeasuredWidth()) * transform.scale)
.scaleY(((float) taskRect.width() / getMeasuredWidth()) * transform.scale)
.translationY(taskRect.top + transform.translationY)
.setDuration(mConfig.taskViewEnterFromHomeDuration * 5)
// Animate the top clip
mViewBounds.animateClipTop(windowInsetTop, duration,
new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int y = (Integer) animation.getAnimatedValue();
mBarView.setTranslationY(y);
}
});
// Animate the bottom or right clip
int size = Math.round((taskRect.width() / taskScale));
if (mConfig.hasHorizontalLayout()) {
mViewBounds.animateClipRight(getMeasuredWidth() - size, duration);
} else {
mViewBounds.animateClipBottom(getMeasuredHeight() - (windowInsetTop + size), duration);
}
animate()
.scaleX(taskScale)
.scaleY(taskScale)
.translationY(taskTranslationY)
.setDuration(duration)
.withEndAction(new Runnable() {
@Override
public void run() {
@@ -424,11 +442,6 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
return mIsFullScreenView;
}
/** Sets the stubbed state of this task view. */
void setStubState(boolean isStub) {
mIsStub = isStub;
}
/**
* Returns whether this view should be clipped, or any views below should clip against this
* view.
@@ -447,7 +460,11 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
/** Gets the max footer height. */
public int getMaxFooterHeight() {
return mFooterView.mMaxFooterHeight;
if (mConfig.lockToAppEnabled) {
return mFooterView.mMaxFooterHeight;
} else {
return 0;
}
}
/** Animates the footer into and out of view. */
@@ -488,17 +505,6 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
setDim(getDimOverlayFromScale());
}
/**** View drawing ****/
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (mIsStub && (child != mBarView)) {
// Skip the thumbnail view if we are in stub mode
return false;
}
return super.drawChild(canvas, child, drawingTime);
}
/**** View focus state ****/
/**