Merge changes Ie59ed72c,Ie763a2a6,I7f830e5c,Ife637438 into nyc-dev am: fe1886f
am: 843fcb0
* commit '843fcb079ec1d3aae6a431af57530dfa2d385552':
Should not update initial state at all on resize.
Adding logging to track down bitmap issues.
Moving the background to the window.
Adding clear-all button.
Change-Id: I27ed2e95a43b77e45aa15a7ae1de9c54c4a0d78e
This commit is contained in:
@@ -209,6 +209,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
private Drawable mResizingBackgroundDrawable;
|
||||
private Drawable mCaptionBackgroundDrawable;
|
||||
private Drawable mUserCaptionBackgroundDrawable;
|
||||
private Drawable mOriginalBackgroundDrawable;
|
||||
|
||||
private float mAvailableWidth;
|
||||
|
||||
@@ -888,6 +889,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
mBackgroundPadding.setEmpty();
|
||||
}
|
||||
drawableChanged();
|
||||
|
||||
// Make sure we don't reset to the old drawable when finishing resizing.
|
||||
if (mResizeMode != RESIZE_MODE_INVALID) {
|
||||
mOriginalBackgroundDrawable = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1950,6 +1956,9 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
updateElevation();
|
||||
|
||||
updateColorViews(null /* insets */, false);
|
||||
|
||||
mOriginalBackgroundDrawable = getBackground();
|
||||
setBackgroundDrawable(null);
|
||||
}
|
||||
mResizeMode = resizeMode;
|
||||
getViewRootImpl().requestInvalidateRootRenderNode();
|
||||
@@ -1961,6 +1970,10 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
|
||||
updateColorViews(null /* insets */, false);
|
||||
mResizeMode = RESIZE_MODE_INVALID;
|
||||
getViewRootImpl().requestInvalidateRootRenderNode();
|
||||
if (mOriginalBackgroundDrawable != null) {
|
||||
setBackgroundDrawable(mOriginalBackgroundDrawable);
|
||||
mOriginalBackgroundDrawable = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
android:textSize="14sp"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textAllCaps="true"
|
||||
android:drawableStart="@drawable/ic_history"
|
||||
android:drawablePadding="6dp"
|
||||
android:shadowColor="#99000000"
|
||||
android:shadowDx="0"
|
||||
android:shadowDy="2"
|
||||
|
||||
@@ -153,6 +153,9 @@
|
||||
<!-- The animation duration for animating the removal of a task view. -->
|
||||
<integer name="recents_animate_task_view_remove_duration">175</integer>
|
||||
|
||||
<!-- The base animation duration for animating the removal of all task views. -->
|
||||
<integer name="recents_animate_task_views_remove_all_duration">300</integer>
|
||||
|
||||
<!-- The animation duration for scrolling the stack to a particular item. -->
|
||||
<integer name="recents_animate_task_stack_scroll_duration">200</integer>
|
||||
|
||||
|
||||
@@ -574,10 +574,12 @@
|
||||
<dimen name="recents_layout_bottom_margin">16dp</dimen>
|
||||
<dimen name="recents_layout_side_margin_phone">16dp</dimen>
|
||||
<dimen name="recents_layout_side_margin_tablet">48dp</dimen>
|
||||
<dimen name="recents_layout_side_margin_tablet_docked">16dp</dimen>
|
||||
<dimen name="recents_layout_side_margin_tablet_xlarge">64dp</dimen>
|
||||
<dimen name="recents_layout_side_margin_tablet_xlarge_docked">16dp</dimen>
|
||||
|
||||
<!-- The height between the top margin and the top of the focused task. -->
|
||||
<dimen name="recents_layout_top_peek_size">56dp</dimen>
|
||||
<dimen name="recents_layout_top_peek_size">48dp</dimen>
|
||||
<!-- The height between the bottom margin and the top of task in front of the focused task. -->
|
||||
<dimen name="recents_layout_bottom_peek_size">56dp</dimen>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui;
|
||||
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
@@ -32,6 +33,7 @@ public class Interpolators {
|
||||
public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
|
||||
public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
|
||||
public static final Interpolator LINEAR = new LinearInterpolator();
|
||||
public static final Interpolator ACCELERATE = new AccelerateInterpolator();
|
||||
public static final Interpolator ACCELERATE_DECELERATE = new AccelerateDecelerateInterpolator();
|
||||
public static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f);
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
|
||||
private RecentsPackageMonitor mPackageMonitor;
|
||||
private long mLastTabKeyEventTime;
|
||||
private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
|
||||
private boolean mFinishedOnStartup;
|
||||
private boolean mIgnoreAltTabRelease;
|
||||
private boolean mIsVisible;
|
||||
@@ -266,6 +267,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
getWindow().getAttributes().privateFlags |=
|
||||
WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
|
||||
|
||||
mLastOrientation = getResources().getConfiguration().orientation;
|
||||
mFocusTimerDuration = getResources().getInteger(R.integer.recents_auto_advance_duration);
|
||||
mIterateTrigger = new DozeTrigger(mFocusTimerDuration, new Runnable() {
|
||||
@Override
|
||||
@@ -274,6 +276,9 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
}
|
||||
});
|
||||
|
||||
// Set the window background
|
||||
getWindow().setBackgroundDrawable(mRecentsView.getBackgroundScrim());
|
||||
|
||||
// Create the home intent runnable
|
||||
mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
mHomeIntent.addCategory(Intent.CATEGORY_HOME);
|
||||
@@ -415,13 +420,18 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
||||
// Update the nav bar for the current orientation
|
||||
updateNavBarScrim(false /* animateNavBarScrim */, AnimationProps.IMMEDIATE);
|
||||
|
||||
EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */));
|
||||
// Notify of the config change
|
||||
int newOrientation = getResources().getConfiguration().orientation;
|
||||
EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */,
|
||||
(mLastOrientation != newOrientation)));
|
||||
mLastOrientation = newOrientation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMultiWindowChanged(boolean inMultiWindow) {
|
||||
super.onMultiWindowChanged(inMultiWindow);
|
||||
EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */));
|
||||
EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */,
|
||||
false /* fromOrientationChange */));
|
||||
|
||||
if (mRecentsView != null) {
|
||||
// Reload the task stack completely
|
||||
|
||||
@@ -36,7 +36,7 @@ public class RecentsDebugFlags implements TunerService.Tunable {
|
||||
// Enables the task affiliations
|
||||
public static final boolean EnableAffiliatedTaskGroups = false;
|
||||
// TODO: To be repurposed
|
||||
public static final boolean EnableStackActionButton = false;
|
||||
public static final boolean EnableStackActionButton = true;
|
||||
// Overrides the Tuner flags and enables the timeout
|
||||
private static final boolean EnableFastToggleTimeout = false;
|
||||
// Overrides the Tuner flags and enables the paging via the Recents button
|
||||
|
||||
@@ -663,13 +663,18 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
@Override
|
||||
public void run() {
|
||||
final Bitmap transitionBitmap = drawThumbnailTransitionBitmap(toTask, toTransform);
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mThumbnailTransitionBitmapCache = transitionBitmap;
|
||||
mThumbnailTransitionBitmapCacheKey = toTask;
|
||||
}
|
||||
});
|
||||
if (transitionBitmap != null) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mThumbnailTransitionBitmapCache = transitionBitmap;
|
||||
mThumbnailTransitionBitmapCacheKey = toTask;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.e(TAG, "Could not load thumbnail for task: " + toTask + " at transform: " +
|
||||
toTransform);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -774,7 +779,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
// Get the transform for the running task
|
||||
stackView.updateLayoutAlgorithm(true /* boundScroll */);
|
||||
stackView.updateToInitialState(true /* scrollToInitialState */);
|
||||
mTmpTransform = stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask,
|
||||
stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask,
|
||||
stackView.getScroller().getStackScroll(), mTmpTransform, null);
|
||||
return mTmpTransform;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,10 @@ import com.android.systemui.recents.events.EventBus;
|
||||
public class ConfigurationChangedEvent extends EventBus.AnimatedEvent {
|
||||
|
||||
public final boolean fromMultiWindow;
|
||||
public final boolean fromOrientationChange;
|
||||
|
||||
public ConfigurationChangedEvent(boolean fromMultiWindow) {
|
||||
public ConfigurationChangedEvent(boolean fromMultiWindow, boolean fromOrientationChange) {
|
||||
this.fromMultiWindow = fromMultiWindow;
|
||||
this.fromOrientationChange = fromOrientationChange;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
package com.android.systemui.recents.events.ui;
|
||||
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
import com.android.systemui.recents.views.TaskView;
|
||||
|
||||
/**
|
||||
* This is sent to reset the background scrim back to the initial state.
|
||||
* This event is sent to request that all the {@link TaskView}s are dismissed.
|
||||
*/
|
||||
public class ResetBackgroundScrimEvent extends EventBus.Event {
|
||||
public class DismissAllTaskViewsEvent extends EventBus.AnimatedEvent {
|
||||
// Simple event
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.systemui.recents.events.ui;
|
||||
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
import com.android.systemui.recents.model.Task;
|
||||
import com.android.systemui.recents.views.TaskView;
|
||||
|
||||
/**
|
||||
@@ -26,10 +25,8 @@ import com.android.systemui.recents.views.TaskView;
|
||||
public class DismissTaskViewEvent extends EventBus.AnimatedEvent {
|
||||
|
||||
public final TaskView taskView;
|
||||
public final Task task;
|
||||
|
||||
public DismissTaskViewEvent(TaskView taskView, Task task) {
|
||||
public DismissTaskViewEvent(TaskView taskView) {
|
||||
this.taskView = taskView;
|
||||
this.task = task;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.events.ui;
|
||||
|
||||
import com.android.systemui.recents.events.EventBus;
|
||||
|
||||
/**
|
||||
* This is sent to request an update to the background scrim.
|
||||
*/
|
||||
public class UpdateBackgroundScrimEvent extends EventBus.Event {
|
||||
|
||||
public final float alpha;
|
||||
|
||||
public UpdateBackgroundScrimEvent(float alpha) {
|
||||
this.alpha = alpha;
|
||||
}
|
||||
}
|
||||
@@ -221,6 +221,11 @@ public class TaskStack {
|
||||
void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
|
||||
Task newFrontMostTask, AnimationProps animation, boolean fromDockGesture);
|
||||
|
||||
/**
|
||||
* Notifies when all tasks have been removed from the stack.
|
||||
*/
|
||||
void onStackTasksRemoved(TaskStack stack);
|
||||
|
||||
/**
|
||||
* Notifies when tasks in the stack have been updated.
|
||||
*/
|
||||
@@ -509,6 +514,22 @@ public class TaskStack {
|
||||
mRawTaskList.remove(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all tasks from the stack.
|
||||
*/
|
||||
public void removeAllTasks() {
|
||||
ArrayList<Task> tasks = mStackTaskList.getTasks();
|
||||
for (int i = tasks.size() - 1; i >= 0; i--) {
|
||||
Task t = tasks.get(i);
|
||||
removeTaskImpl(mStackTaskList, t);
|
||||
mRawTaskList.remove(t);
|
||||
}
|
||||
if (mCb != null) {
|
||||
// Notify that all tasks have been removed
|
||||
mCb.onStackTasksRemoved(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a few tasks in one go, without calling any callbacks.
|
||||
*
|
||||
|
||||
@@ -157,6 +157,11 @@ public class TaskStackHorizontalGridView extends HorizontalGridView implements T
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStackTasksRemoved(TaskStack stack) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStackTasksUpdated(TaskStack stack) {
|
||||
// Do nothing
|
||||
|
||||
@@ -28,11 +28,13 @@ import android.app.ActivityOptions.OnAnimationStartedListener;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.AppTransitionAnimationSpec;
|
||||
import android.view.IAppTransitionAnimationSpecsFuture;
|
||||
|
||||
@@ -252,12 +254,13 @@ public class RecentsTransitionHelper {
|
||||
/**
|
||||
* Composes the transition spec when docking a task, which includes a full task bitmap.
|
||||
*/
|
||||
public List<AppTransitionAnimationSpec> composeDockAnimationSpec(
|
||||
TaskView taskView, Rect transform) {
|
||||
TaskViewTransform viewTransform = new TaskViewTransform();
|
||||
viewTransform.fillIn(taskView);
|
||||
return Collections.singletonList(new AppTransitionAnimationSpec(taskView.getTask().key.id,
|
||||
RecentsTransitionHelper.composeTaskBitmap(taskView, viewTransform), transform));
|
||||
public List<AppTransitionAnimationSpec> composeDockAnimationSpec(TaskView taskView,
|
||||
Rect bounds) {
|
||||
mTmpTransform.fillIn(taskView);
|
||||
Task task = taskView.getTask();
|
||||
Bitmap thumbnail = RecentsTransitionHelper.composeTaskBitmap(taskView, mTmpTransform);
|
||||
return Collections.singletonList(new AppTransitionAnimationSpec(task.key.id, thumbnail,
|
||||
bounds));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -336,18 +339,27 @@ public class RecentsTransitionHelper {
|
||||
float scale = transform.scale;
|
||||
int fromWidth = (int) (transform.rect.width() * scale);
|
||||
int fromHeight = (int) (transform.rect.height() * scale);
|
||||
Bitmap b = Bitmap.createBitmap(fromWidth, fromHeight,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
if (fromWidth == 0 || fromHeight == 0) {
|
||||
Log.e(TAG, "Could not compose thumbnail for task: " + taskView.getTask() +
|
||||
" at transform: " + transform);
|
||||
|
||||
if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
|
||||
b.eraseColor(0xFFff0000);
|
||||
Bitmap b = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
|
||||
b.eraseColor(Color.TRANSPARENT);
|
||||
return b;
|
||||
} else {
|
||||
Canvas c = new Canvas(b);
|
||||
c.scale(scale, scale);
|
||||
taskView.draw(c);
|
||||
c.setBitmap(null);
|
||||
Bitmap b = Bitmap.createBitmap(fromWidth, fromHeight,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
|
||||
if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
|
||||
b.eraseColor(0xFFff0000);
|
||||
} else {
|
||||
Canvas c = new Canvas(b);
|
||||
c.scale(scale, scale);
|
||||
taskView.draw(c);
|
||||
c.setBitmap(null);
|
||||
}
|
||||
return b.createAshmemBitmap();
|
||||
}
|
||||
return b.createAshmemBitmap();
|
||||
}
|
||||
|
||||
private static Bitmap composeHeaderBitmap(TaskView taskView,
|
||||
|
||||
@@ -58,10 +58,11 @@ import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationC
|
||||
import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
|
||||
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
|
||||
import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
|
||||
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
|
||||
import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
|
||||
import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
|
||||
import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
|
||||
import com.android.systemui.recents.events.ui.DraggingInRecentsEvent;
|
||||
import com.android.systemui.recents.events.ui.ResetBackgroundScrimEvent;
|
||||
import com.android.systemui.recents.events.ui.UpdateBackgroundScrimEvent;
|
||||
import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
|
||||
import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
|
||||
import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
|
||||
@@ -87,6 +88,9 @@ public class RecentsView extends FrameLayout {
|
||||
private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200;
|
||||
private static final float DEFAULT_SCRIM_ALPHA = 0.33f;
|
||||
|
||||
private static final int SHOW_STACK_ACTION_BUTTON_DURATION = 150;
|
||||
private static final int HIDE_STACK_ACTION_BUTTON_DURATION = 100;
|
||||
|
||||
private TaskStack mStack;
|
||||
private TaskStackView mTaskStackView;
|
||||
private TextView mStackActionButton;
|
||||
@@ -99,7 +103,8 @@ public class RecentsView extends FrameLayout {
|
||||
private Rect mSystemInsets = new Rect();
|
||||
private int mDividerSize;
|
||||
|
||||
private ColorDrawable mBackgroundScrim = new ColorDrawable(Color.BLACK);
|
||||
private Drawable mBackgroundScrim = new ColorDrawable(
|
||||
Color.argb((int) (DEFAULT_SCRIM_ALPHA * 255), 0, 0, 0)).mutate();
|
||||
private Animator mBackgroundScrimAnimator;
|
||||
|
||||
private RecentsTransitionHelper mTransitionHelper;
|
||||
@@ -135,10 +140,11 @@ public class RecentsView extends FrameLayout {
|
||||
R.dimen.recents_task_view_rounded_corners_radius);
|
||||
mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
|
||||
this, false);
|
||||
mStackActionButton.forceHasOverlappingRendering(false);
|
||||
mStackActionButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// TODO: To be implemented
|
||||
EventBus.getDefault().send(new DismissAllTaskViewsEvent());
|
||||
}
|
||||
});
|
||||
addView(mStackActionButton);
|
||||
@@ -152,8 +158,6 @@ public class RecentsView extends FrameLayout {
|
||||
}
|
||||
mEmptyView = (TextView) inflater.inflate(R.layout.recents_empty, this, false);
|
||||
addView(mEmptyView);
|
||||
|
||||
setBackground(mBackgroundScrim);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,14 +183,14 @@ public class RecentsView extends FrameLayout {
|
||||
|
||||
if (isResumingFromVisible) {
|
||||
// If we are already visible, then restore the background scrim
|
||||
animateBackgroundScrim(DEFAULT_SCRIM_ALPHA, DEFAULT_UPDATE_SCRIM_DURATION);
|
||||
animateBackgroundScrim(1f, DEFAULT_UPDATE_SCRIM_DURATION);
|
||||
} else {
|
||||
// If we are already occluded by the app, then set the final background scrim alpha now.
|
||||
// Otherwise, defer until the enter animation completes to animate the scrim alpha with
|
||||
// the tasks for the home animation.
|
||||
if (launchState.launchedViaDockGesture || launchState.launchedFromApp
|
||||
|| isTaskStackEmpty) {
|
||||
mBackgroundScrim.setAlpha((int) (DEFAULT_SCRIM_ALPHA * 255));
|
||||
mBackgroundScrim.setAlpha(255);
|
||||
} else {
|
||||
mBackgroundScrim.setAlpha(0);
|
||||
}
|
||||
@@ -215,6 +219,13 @@ public class RecentsView extends FrameLayout {
|
||||
return mStack;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the window background scrim.
|
||||
*/
|
||||
public Drawable getBackgroundScrim() {
|
||||
return mBackgroundScrim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the last task launched was in the freeform stack or not.
|
||||
*/
|
||||
@@ -566,17 +577,21 @@ public class RecentsView extends FrameLayout {
|
||||
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
|
||||
if (!launchState.launchedViaDockGesture && !launchState.launchedFromApp
|
||||
&& mStack.getTaskCount() > 0) {
|
||||
animateBackgroundScrim(DEFAULT_SCRIM_ALPHA,
|
||||
animateBackgroundScrim(1f,
|
||||
TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
public final void onBusEvent(UpdateBackgroundScrimEvent event) {
|
||||
animateBackgroundScrim(event.alpha, DEFAULT_UPDATE_SCRIM_DURATION);
|
||||
public final void onBusEvent(AllTaskViewsDismissedEvent event) {
|
||||
hideStackActionButton(HIDE_STACK_ACTION_BUTTON_DURATION, true /* translate */);
|
||||
}
|
||||
|
||||
public final void onBusEvent(ResetBackgroundScrimEvent event) {
|
||||
animateBackgroundScrim(DEFAULT_SCRIM_ALPHA, DEFAULT_UPDATE_SCRIM_DURATION);
|
||||
public final void onBusEvent(DismissAllTaskViewsEvent event) {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
if (!ssp.hasDockedTask()) {
|
||||
// Animate the background away only if we are dismissing Recents to home
|
||||
animateBackgroundScrim(0f, DEFAULT_UPDATE_SCRIM_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
public final void onBusEvent(ShowStackActionButtonEvent event) {
|
||||
@@ -584,7 +599,7 @@ public class RecentsView extends FrameLayout {
|
||||
return;
|
||||
}
|
||||
|
||||
showStackActionButton(150, event.translate);
|
||||
showStackActionButton(SHOW_STACK_ACTION_BUTTON_DURATION, event.translate);
|
||||
}
|
||||
|
||||
public final void onBusEvent(HideStackActionButtonEvent event) {
|
||||
@@ -592,7 +607,7 @@ public class RecentsView extends FrameLayout {
|
||||
return;
|
||||
}
|
||||
|
||||
hideStackActionButton(100, true /* translate */);
|
||||
hideStackActionButton(HIDE_STACK_ACTION_BUTTON_DURATION, true /* translate */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -623,7 +638,6 @@ public class RecentsView extends FrameLayout {
|
||||
.alpha(1f)
|
||||
.setDuration(duration)
|
||||
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
|
||||
.withLayer()
|
||||
.start();
|
||||
}
|
||||
});
|
||||
@@ -669,7 +683,6 @@ public class RecentsView extends FrameLayout {
|
||||
postAnimationTrigger.decrement();
|
||||
}
|
||||
})
|
||||
.withLayer()
|
||||
.start();
|
||||
postAnimationTrigger.increment();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
|
||||
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
|
||||
import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
|
||||
|
||||
/** Manages the scrims for the various system bars. */
|
||||
public class SystemBarScrimViews {
|
||||
@@ -107,4 +108,14 @@ public class SystemBarScrimViews {
|
||||
animateNavBarScrimVisibility(false, animation);
|
||||
}
|
||||
}
|
||||
|
||||
public final void onBusEvent(DismissAllTaskViewsEvent event) {
|
||||
if (mHasNavBarScrim) {
|
||||
AnimationProps animation = new AnimationProps()
|
||||
.setDuration(AnimationProps.BOUNDS,
|
||||
TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION)
|
||||
.setInterpolator(AnimationProps.BOUNDS, Interpolators.FAST_OUT_SLOW_IN);
|
||||
animateNavBarScrimVisibility(false, animation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.recents.RecentsActivityLaunchState;
|
||||
import com.android.systemui.recents.RecentsConfiguration;
|
||||
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
|
||||
import com.android.systemui.recents.misc.Utilities;
|
||||
import com.android.systemui.recents.model.Task;
|
||||
import com.android.systemui.recents.model.TaskStack;
|
||||
|
||||
@@ -277,7 +278,6 @@ public class TaskStackAnimationHelper {
|
||||
public void startExitToHomeAnimation(boolean animated,
|
||||
ReferenceCountedTrigger postAnimationTrigger) {
|
||||
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
|
||||
TaskStackViewScroller stackScroller = mStackView.getScroller();
|
||||
TaskStack stack = mStackView.getStack();
|
||||
|
||||
// Break early if there are no tasks
|
||||
@@ -313,8 +313,7 @@ public class TaskStackAnimationHelper {
|
||||
taskAnimation = AnimationProps.IMMEDIATE;
|
||||
}
|
||||
|
||||
stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
|
||||
null);
|
||||
mTmpTransform.fillIn(tv);
|
||||
mTmpTransform.alpha = 0f;
|
||||
mTmpTransform.rect.offset(0, offscreenYOffset);
|
||||
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
|
||||
@@ -328,8 +327,6 @@ public class TaskStackAnimationHelper {
|
||||
public void startLaunchTaskAnimation(TaskView launchingTaskView, boolean screenPinningRequested,
|
||||
final ReferenceCountedTrigger postAnimationTrigger) {
|
||||
Resources res = mStackView.getResources();
|
||||
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
|
||||
TaskStackViewScroller stackScroller = mStackView.getScroller();
|
||||
|
||||
int taskViewExitToAppDuration = res.getInteger(
|
||||
R.integer.recents_task_exit_to_app_duration);
|
||||
@@ -362,8 +359,7 @@ public class TaskStackAnimationHelper {
|
||||
postAnimationTrigger.decrementOnAnimationEnd());
|
||||
postAnimationTrigger.increment();
|
||||
|
||||
stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
|
||||
null);
|
||||
mTmpTransform.fillIn(tv);
|
||||
mTmpTransform.alpha = 0f;
|
||||
mTmpTransform.rect.offset(0, taskViewAffiliateGroupEnterOffset);
|
||||
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
|
||||
@@ -374,16 +370,14 @@ public class TaskStackAnimationHelper {
|
||||
/**
|
||||
* Starts the delete animation for the specified {@link TaskView}.
|
||||
*/
|
||||
public void startDeleteTaskAnimation(Task deleteTask, final TaskView deleteTaskView,
|
||||
public void startDeleteTaskAnimation(final TaskView deleteTaskView,
|
||||
final ReferenceCountedTrigger postAnimationTrigger) {
|
||||
Resources res = mStackView.getResources();
|
||||
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
|
||||
TaskStackViewScroller stackScroller = mStackView.getScroller();
|
||||
|
||||
int taskViewRemoveAnimDuration = res.getInteger(
|
||||
R.integer.recents_animate_task_view_remove_duration);
|
||||
int taskViewRemoveAnimTranslationXPx = res.getDimensionPixelSize(
|
||||
R.dimen.recents_task_view_remove_anim_translation_x);
|
||||
int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left;
|
||||
|
||||
// Disabling clipping with the stack while the view is animating away, this will get
|
||||
// restored when the task is next picked up from the view pool
|
||||
@@ -399,13 +393,57 @@ public class TaskStackAnimationHelper {
|
||||
});
|
||||
postAnimationTrigger.increment();
|
||||
|
||||
stackLayout.getStackTransform(deleteTask, stackScroller.getStackScroll(), mTmpTransform,
|
||||
null);
|
||||
mTmpTransform.fillIn(deleteTaskView);
|
||||
mTmpTransform.alpha = 0f;
|
||||
mTmpTransform.rect.offset(taskViewRemoveAnimTranslationXPx, 0);
|
||||
mTmpTransform.rect.offset(offscreenXOffset, 0);
|
||||
mStackView.updateTaskViewToTransform(deleteTaskView, mTmpTransform, taskAnimation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the delete animation for all the {@link TaskView}s.
|
||||
*/
|
||||
public void startDeleteAllTasksAnimation(final List<TaskView> taskViews,
|
||||
final ReferenceCountedTrigger postAnimationTrigger) {
|
||||
Resources res = mStackView.getResources();
|
||||
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
|
||||
|
||||
int taskViewRemoveAnimDuration = res.getInteger(
|
||||
R.integer.recents_animate_task_views_remove_all_duration);
|
||||
int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left;
|
||||
|
||||
int taskViewCount = taskViews.size();
|
||||
int startDelayMax = 125;
|
||||
|
||||
for (int i = taskViewCount - 1; i >= 0; i--) {
|
||||
TaskView tv = taskViews.get(i);
|
||||
int indexFromFront = taskViewCount - i - 1;
|
||||
float x = Interpolators.ACCELERATE.getInterpolation((float) indexFromFront /
|
||||
taskViewCount);
|
||||
int startDelay = (int) Utilities.mapRange(x, 0, startDelayMax);
|
||||
|
||||
// Disabling clipping with the stack while the view is animating away
|
||||
tv.setClipViewInStack(false);
|
||||
|
||||
// Compose the new animation and transform and star the animation
|
||||
AnimationProps taskAnimation = new AnimationProps(startDelay,
|
||||
taskViewRemoveAnimDuration, Interpolators.FAST_OUT_LINEAR_IN,
|
||||
new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
postAnimationTrigger.decrement();
|
||||
|
||||
// Re-enable clipping with the stack (we will reuse this view)
|
||||
tv.setClipViewInStack(true);
|
||||
}
|
||||
});
|
||||
postAnimationTrigger.increment();
|
||||
|
||||
mTmpTransform.fillIn(tv);
|
||||
mTmpTransform.rect.offset(offscreenXOffset, 0);
|
||||
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the animation to focus the next {@link TaskView} when paging through recents.
|
||||
*
|
||||
|
||||
@@ -557,15 +557,17 @@ public class TaskStackLayoutAlgorithm {
|
||||
mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
|
||||
mInitialNormX = null;
|
||||
} else {
|
||||
float normX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
|
||||
mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP, (mNumStackTasks - 2)) -
|
||||
Math.max(0, mUnfocusedRange.getAbsoluteX(normX)));
|
||||
// We are overriding the initial two task positions, so set the initial scroll
|
||||
// position to match the second task (aka focused task) position
|
||||
float initialTopNormX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
|
||||
mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP, (mNumStackTasks - 2))
|
||||
- Math.max(0, mUnfocusedRange.getAbsoluteX(initialTopNormX)));
|
||||
|
||||
// Set the initial scroll to the predefined state (which differs from the stack)
|
||||
mInitialNormX = new float[] {
|
||||
getNormalizedXFromUnfocusedY(mSystemInsets.bottom + mInitialBottomOffset,
|
||||
FROM_BOTTOM),
|
||||
normX
|
||||
initialTopNormX
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ import com.android.systemui.recents.events.activity.PackagesChangedEvent;
|
||||
import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
|
||||
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
|
||||
import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
|
||||
import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
|
||||
import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
|
||||
import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
|
||||
import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
|
||||
@@ -1322,7 +1323,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
}
|
||||
|
||||
// Update the stack action button visibility
|
||||
if (mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
|
||||
if (mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
|
||||
mStack.getTaskCount() > 0) {
|
||||
EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
|
||||
} else {
|
||||
EventBus.getDefault().send(new HideStackActionButtonEvent());
|
||||
@@ -1446,6 +1448,26 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStackTasksRemoved(TaskStack stack) {
|
||||
// Reset the focused task
|
||||
resetFocusedTask(getFocusedTask());
|
||||
|
||||
// Return all the views to the pool
|
||||
List<TaskView> taskViews = new ArrayList<>();
|
||||
taskViews.addAll(getTaskViews());
|
||||
for (int i = taskViews.size() - 1; i >= 0; i--) {
|
||||
mViewPool.returnViewToPool(taskViews.get(i));
|
||||
}
|
||||
|
||||
// Remove all the ignore tasks
|
||||
mIgnoreTasks.clear();
|
||||
|
||||
// If there are no remaining tasks, then just close recents
|
||||
EventBus.getDefault().send(new AllTaskViewsDismissedEvent(
|
||||
R.string.recents_empty_message_dismissed_all));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStackTasksUpdated(TaskStack stack) {
|
||||
// Update the layout and immediately layout
|
||||
@@ -1597,7 +1619,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
|
||||
if (mEnterAnimationComplete) {
|
||||
if (prevScroll > SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
|
||||
curScroll <= SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
|
||||
curScroll <= SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
|
||||
mStack.getTaskCount() > 0) {
|
||||
EventBus.getDefault().send(new ShowStackActionButtonEvent(true /* translate */));
|
||||
} else if (prevScroll < HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
|
||||
curScroll >= HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
|
||||
@@ -1705,14 +1728,42 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
}
|
||||
}
|
||||
|
||||
public final void onBusEvent(final DismissTaskViewEvent event) {
|
||||
public final void onBusEvent(DismissTaskViewEvent event) {
|
||||
// For visible children, defer removing the task until after the animation
|
||||
mAnimationHelper.startDeleteTaskAnimation(event.task, event.taskView,
|
||||
event.getAnimationTrigger());
|
||||
mAnimationHelper.startDeleteTaskAnimation(event.taskView, event.getAnimationTrigger());
|
||||
}
|
||||
|
||||
public final void onBusEvent(final DismissAllTaskViewsEvent event) {
|
||||
// Keep track of the tasks which will have their data removed
|
||||
ArrayList<Task> tasks = new ArrayList<>(mStack.getStackTasks());
|
||||
mAnimationHelper.startDeleteAllTasksAnimation(getTaskViews(), event.getAnimationTrigger());
|
||||
event.addPostAnimationCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Announce for accessibility
|
||||
announceForAccessibility(getContext().getString(
|
||||
R.string.accessibility_recents_all_items_dismissed));
|
||||
|
||||
// Remove all tasks and delete the task data for all tasks
|
||||
mStack.removeAllTasks();
|
||||
for (int i = tasks.size() - 1; i >= 0; i--) {
|
||||
EventBus.getDefault().send(new DeleteTaskDataEvent(tasks.get(i)));
|
||||
}
|
||||
|
||||
MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS_ALL);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public final void onBusEvent(TaskViewDismissedEvent event) {
|
||||
removeTaskViewFromStack(event.taskView, event.task);
|
||||
// Announce for accessibility
|
||||
announceForAccessibility(getContext().getString(
|
||||
R.string.accessibility_recents_item_dismissed, event.task.title));
|
||||
|
||||
// Remove the task from the stack
|
||||
mStack.removeTask(event.task, new AnimationProps(DEFAULT_SYNC_STACK_DURATION,
|
||||
Interpolators.FAST_OUT_SLOW_IN), false /* fromDockGesture */);
|
||||
EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
|
||||
|
||||
MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS,
|
||||
@@ -1948,27 +1999,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger a new layout and scroll to the initial state
|
||||
mInitialState = event.fromMultiWindow
|
||||
? INITIAL_STATE_UPDATE_ALL
|
||||
: INITIAL_STATE_UPDATE_LAYOUT_ONLY;
|
||||
// Trigger a new layout and update to the initial state if necessary
|
||||
if (event.fromMultiWindow) {
|
||||
mInitialState = INITIAL_STATE_UPDATE_ALL;
|
||||
} else if (event.fromOrientationChange) {
|
||||
mInitialState = INITIAL_STATE_UPDATE_LAYOUT_ONLY;
|
||||
}
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the task from the stack, and updates the focus to the next task in the stack if the
|
||||
* removed TaskView was focused.
|
||||
*/
|
||||
private void removeTaskViewFromStack(TaskView tv, Task task) {
|
||||
// Announce for accessibility
|
||||
tv.announceForAccessibility(getContext().getString(
|
||||
R.string.accessibility_recents_item_dismissed, task.title));
|
||||
|
||||
// Remove the task from the stack
|
||||
mStack.removeTask(task, new AnimationProps(DEFAULT_SYNC_STACK_DURATION,
|
||||
Interpolators.FAST_OUT_SLOW_IN), false /* fromDockGesture */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an alpha animation on the freeform workspace background.
|
||||
*/
|
||||
|
||||
@@ -356,6 +356,11 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disallow tapping above and below the stack to dismiss recents
|
||||
if (x > mSv.mLayoutAlgorithm.mStackRect.left && x < mSv.mLayoutAlgorithm.mStackRect.right) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If tapping on the freeform workspace background, just launch the first freeform task
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
if (ssp.hasFreeformWorkspaceSupport()) {
|
||||
@@ -507,13 +512,13 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
|
||||
tv.setClipViewInStack(true);
|
||||
// Re-enable touch events from this task view
|
||||
tv.setTouchEnabled(true);
|
||||
// Remove the task view from the stack
|
||||
EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv));
|
||||
// Update the scroll to the final scroll position from onBeginDrag()
|
||||
mSv.getScroller().setStackScroll(mTargetStackScroll, null);
|
||||
// Update the focus state to the final focus state
|
||||
mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
|
||||
mSv.getStackAlgorithm().clearUnfocusedTaskOverrides();
|
||||
// Remove the task view from the stack
|
||||
EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv));
|
||||
// Stop tracking this deletion animation
|
||||
mSwipeHelperAnimations.remove(v);
|
||||
// Keep track of deletions by keyboard
|
||||
|
||||
@@ -384,7 +384,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
|
||||
void dismissTask() {
|
||||
// Animate out the view and call the callback
|
||||
final TaskView tv = this;
|
||||
DismissTaskViewEvent dismissEvent = new DismissTaskViewEvent(tv, mTask);
|
||||
DismissTaskViewEvent dismissEvent = new DismissTaskViewEvent(tv);
|
||||
dismissEvent.addPostAnimationCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
@@ -226,4 +226,9 @@ public class TaskViewTransform {
|
||||
v.getViewBounds().setClipBottom(0);
|
||||
v.setLeftTopRightBottom(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "R: " + rect + " V: " + visible;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2017,6 +2017,9 @@ message MetricsEvent {
|
||||
// action pass package name of calling package.
|
||||
ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_PACKAGE = 356;
|
||||
|
||||
// Logged when a user dismisses all task in overview
|
||||
OVERVIEW_DISMISS_ALL = 357;
|
||||
|
||||
// Add new aosp constants above this line.
|
||||
// END OF AOSP CONSTANTS
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user