Merge "Add ability to cancel task window transitions."

This commit is contained in:
Winson Chung
2015-11-02 18:17:12 +00:00
committed by Android (Google) Code Review
6 changed files with 88 additions and 21 deletions

View File

@@ -201,6 +201,11 @@ interface IWindowManager
*/
void setScreenCaptureDisabled(int userId, boolean disabled);
/**
* Cancels the window transitions for the given task.
*/
void cancelTaskWindowTransition(int taskId);
// These can only be called with the SET_ORIENTATION permission.
/**
* Update the current screen rotation based on the current state of

View File

@@ -517,6 +517,15 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
boolean hasRepKeyTimeElapsed = (SystemClock.elapsedRealtime() -
mLastTabKeyEventTime) > altTabKeyDelay;
if (event.getRepeatCount() <= 0 || hasRepKeyTimeElapsed) {
// As we iterate to the next/previous task, cancel any current/lagging window
// transition animations
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
if (launchState.launchedToTaskId != -1) {
SystemServicesProxy ssp = Recents.getSystemServices();
ssp.cancelWindowTransition(launchState.launchedToTaskId);
}
// Focus the next task in the stack
final boolean backward = event.isShiftPressed();
if (backward) {

View File

@@ -57,6 +57,7 @@ import android.util.MutableBoolean;
import android.util.Pair;
import android.view.Display;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.app.AssistUtils;
import com.android.internal.os.BackgroundThread;
@@ -335,6 +336,19 @@ public class SystemServicesProxy {
return stackInfo != null;
}
/**
* Cancels the current window transtion to/from Recents for the given task id.
*/
public void cancelWindowTransition(int taskId) {
if (mWm == null) return;
try {
WindowManagerGlobal.getWindowManagerService().cancelTaskWindowTransition(taskId);
} catch (RemoteException e) {
e.printStackTrace();
}
}
/** Returns the top task thumbnail for the given task id */
public Bitmap getTaskThumbnail(int taskId) {
if (mAm == null) return null;

View File

@@ -44,6 +44,7 @@ import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsActivity;
import com.android.systemui.recents.RecentsActivityLaunchState;
import com.android.systemui.recents.RecentsAppWidgetHostView;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.events.EventBus;
@@ -587,6 +588,20 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
return new AppTransitionAnimationSpec(taskId, b, rect);
}
/**
* Cancels any running window transitions for the launched task (the task animating into
* Recents).
*/
private void cancelLaunchedTaskWindowTransition(final Task task) {
SystemServicesProxy ssp = Recents.getSystemServices();
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
if (launchState.launchedToTaskId != -1 &&
launchState.launchedToTaskId != task.key.id) {
ssp.cancelWindowTransition(launchState.launchedToTaskId);
}
}
/**** TaskStackView.TaskStackCallbacks Implementation ****/
@Override
@@ -617,34 +632,37 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
// Compute the thumbnail to scale up from
final SystemServicesProxy ssp = Recents.getSystemServices();
boolean screenPinningRequested = false;
ActivityOptions opts = null;
ActivityOptions.OnAnimationStartedListener animStartedListener = null;
if (task.thumbnail != null && task.thumbnail.getWidth() > 0 &&
task.thumbnail.getHeight() > 0) {
if (lockToTask) {
animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
boolean mTriggered = false;
@Override
public void onAnimationStarted() {
if (!mTriggered) {
postDelayed(new Runnable() {
@Override
public void run() {
EventBus.getDefault().send(new ScreenPinningRequestEvent(
getContext(), ssp));
}
}, 350);
mTriggered = true;
}
animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
@Override
public void onAnimationStarted() {
// If we are launching into another task, cancel the previous task's
// window transition
cancelLaunchedTaskWindowTransition(task);
if (lockToTask) {
// Request screen pinning after the animation runs
postDelayed(new Runnable() {
@Override
public void run() {
EventBus.getDefault().send(new ScreenPinningRequestEvent(
getContext(), ssp));
}
}, 350);
}
};
}
}
};
postDrawHeaderThumbnailTransitionRunnable(stackView, tv, offsetX, offsetY, stackScroll,
animStartedListener, destinationStack);
opts = ActivityOptions.makeThumbnailAspectScaleUpAnimation(sourceView,
Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8).createAshmemBitmap(),
offsetX, offsetY, (int) transform.rect.width(), (int) transform.rect.height(),
sourceView.getHandler(), animStartedListener);
screenPinningRequested = true;
} else {
opts = ActivityOptions.makeBasic();
}
@@ -652,7 +670,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
opts.setBounds(bounds.isEmpty() ? null : bounds);
}
final ActivityOptions launchOpts = opts;
final boolean screenPinningRequested = (animStartedListener == null) && lockToTask;
final boolean finalScreenPinningRequested = screenPinningRequested;
final Runnable launchRunnable = new Runnable() {
@Override
public void run() {
@@ -660,9 +678,11 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
// Bring an active task to the foreground
ssp.moveTaskToFront(task.key.id, launchOpts);
} else {
if (ssp.startActivityFromRecents(getContext(), task.key.id,
task.activityLabel, launchOpts)) {
if (screenPinningRequested) {
if (ssp.startActivityFromRecents(getContext(), task.key.id, task.activityLabel,
launchOpts)) {
if (!finalScreenPinningRequested) {
// If we have not requested this already to be run after the window
// transition, then just run it now
EventBus.getDefault().send(new ScreenPinningRequestEvent(
getContext(), ssp));
}

View File

@@ -320,6 +320,15 @@ class Task implements DimLayer.DimLayerUser {
}
}
/**
* Cancels any running app transitions associated with the task.
*/
void cancelTaskWindowTransition() {
for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
mAppTokens.get(activityNdx).mAppAnimator.clearAnimation();
}
}
boolean showForAllUsers() {
final int tokensCount = mAppTokens.size();
return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showForAllUsers;

View File

@@ -4607,6 +4607,16 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
@Override
public void cancelTaskWindowTransition(int taskId) {
synchronized (mWindowMap) {
Task task = mTaskIdToTask.get(taskId);
if (task != null) {
task.cancelTaskWindowTransition();
}
}
}
public void addTask(int taskId, int stackId, boolean toTop) {
synchronized (mWindowMap) {
if (DEBUG_STACK) Slog.i(TAG, "addTask: adding taskId=" + taskId