Merge "Fixing occasional jump when launching certain apps from Recents." into oc-dr1-dev

This commit is contained in:
Winson Chung
2017-07-24 20:25:07 +00:00
committed by Android (Google) Code Review
7 changed files with 144 additions and 21 deletions

View File

@@ -31,4 +31,5 @@ oneway interface IRecentsSystemUserCallbacks {
void sendRecentsDrawnEvent(); void sendRecentsDrawnEvent();
void sendDockingTopTaskEvent(int dragMode, in Rect initialRect); void sendDockingTopTaskEvent(int dragMode, in Rect initialRect);
void sendLaunchRecentsEvent(); void sendLaunchRecentsEvent();
void setWaitingForTransitionStartEvent(boolean waitingForTransitionStart);
} }

View File

@@ -57,6 +57,7 @@ import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent; import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent; import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent; import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
import com.android.systemui.recents.events.component.ShowUserToastEvent; import com.android.systemui.recents.events.component.ShowUserToastEvent;
import com.android.systemui.recents.events.ui.RecentsDrawnEvent; import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -711,6 +712,25 @@ public class Recents extends SystemUI
} }
} }
public final void onBusEvent(SetWaitingForTransitionStartEvent event) {
int processUser = sSystemServicesProxy.getProcessUser();
if (sSystemServicesProxy.isSystemUser(processUser)) {
mImpl.setWaitingForTransitionStart(event.waitingForTransitionStart);
} else {
postToSystemUser(new Runnable() {
@Override
public void run() {
try {
mUserToSystemCallbacks.setWaitingForTransitionStartEvent(
event.waitingForTransitionStart);
} catch (RemoteException e) {
Log.e(TAG, "Callback failed", e);
}
}
});
}
}
/** /**
* Attempts to register with the system user. * Attempts to register with the system user.
*/ */

View File

@@ -24,12 +24,11 @@ import static android.view.View.MeasureSpec;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManager.TaskSnapshot; import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.app.ActivityOptions.OnAnimationStartedListener;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.GraphicBuffer; import android.graphics.GraphicBuffer;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
@@ -208,6 +207,20 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
protected static RecentsTaskLoadPlan sInstanceLoadPlan; protected static RecentsTaskLoadPlan sInstanceLoadPlan;
// Stores the last pinned task time // Stores the last pinned task time
protected static long sLastPipTime = -1; protected static long sLastPipTime = -1;
// Stores whether we are waiting for a transition to/from recents to start. During this time,
// we disallow the user from manually toggling recents until the transition has started.
private static boolean mWaitingForTransitionStart = false;
// Stores whether or not the user toggled while we were waiting for a transition to/from
// recents. In this case, we defer the toggle state until then and apply it immediately after.
private static boolean mToggleFollowingTransitionStart = true;
private ActivityOptions.OnAnimationStartedListener mResetToggleFlagListener =
new OnAnimationStartedListener() {
@Override
public void onAnimationStarted() {
setWaitingForTransitionStart(false);
}
};
protected Context mContext; protected Context mContext;
protected Handler mHandler; protected Handler mHandler;
@@ -365,6 +378,11 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
return; return;
} }
if (mWaitingForTransitionStart) {
mToggleFollowingTransitionStart = true;
return;
}
mDraggingInRecents = false; mDraggingInRecents = false;
mLaunchedWhileDocking = false; mLaunchedWhileDocking = false;
mTriggeredFromAltTab = false; mTriggeredFromAltTab = false;
@@ -638,6 +656,18 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
} }
} }
public void setWaitingForTransitionStart(boolean waitingForTransitionStart) {
if (mWaitingForTransitionStart == waitingForTransitionStart) {
return;
}
mWaitingForTransitionStart = waitingForTransitionStart;
if (!waitingForTransitionStart && mToggleFollowingTransitionStart) {
toggleRecents(DividerView.INVALID_RECENTS_GROW_TARGET);
}
mToggleFollowingTransitionStart = false;
}
/** /**
* Returns the preloaded load plan and invalidates it. * Returns the preloaded load plan and invalidates it.
*/ */
@@ -865,8 +895,9 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
} }
AppTransitionAnimationSpec[] specsArray = new AppTransitionAnimationSpec[specs.size()]; AppTransitionAnimationSpec[] specsArray = new AppTransitionAnimationSpec[specs.size()];
specs.toArray(specsArray); specs.toArray(specsArray);
return new Pair<>(ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView, return new Pair<>(ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
specsArray, mHandler, null, this), null); specsArray, mHandler, mResetToggleFlagListener, this), null);
} else { } else {
// Update the destination rect // Update the destination rect
Task toTask = new Task(); Task toTask = new Task();
@@ -884,8 +915,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
return Lists.newArrayList(new AppTransitionAnimationSpec( return Lists.newArrayList(new AppTransitionAnimationSpec(
toTask.key.id, thumbnail, rect)); toTask.key.id, thumbnail, rect));
}); });
return new Pair<>(ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext, return new Pair<>(ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
mHandler, future.getFuture(), null, false /* scaleUp */), future); mHandler, future.getFuture(), mResetToggleFlagListener, false /* scaleUp */),
future);
} }
} }
@@ -991,6 +1024,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
launchState.launchedToTaskId = runningTaskId; launchState.launchedToTaskId = runningTaskId;
launchState.launchedWithAltTab = mTriggeredFromAltTab; launchState.launchedWithAltTab = mTriggeredFromAltTab;
// Disable toggling of recents between starting the activity and it is visible and the app
// has started its transition into recents.
setWaitingForTransitionStart(useThumbnailTransition);
// Preload the icon (this will be a null-op if we have preloaded the icon already in // Preload the icon (this will be a null-op if we have preloaded the icon already in
// preloadRecents()) // preloadRecents())
preloadIcon(runningTaskId); preloadIcon(runningTaskId);

View File

@@ -29,6 +29,7 @@ import com.android.systemui.EventLogTags;
import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.DockedTopTaskEvent; import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent; import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
import com.android.systemui.recents.events.ui.RecentsDrawnEvent; import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
import com.android.systemui.recents.misc.ForegroundThread; import com.android.systemui.recents.misc.ForegroundThread;
@@ -105,4 +106,10 @@ public class RecentsSystemUser extends IRecentsSystemUserCallbacks.Stub {
public void sendLaunchRecentsEvent() throws RemoteException { public void sendLaunchRecentsEvent() throws RemoteException {
EventBus.getDefault().post(new RecentsActivityStartingEvent()); EventBus.getDefault().post(new RecentsActivityStartingEvent());
} }
@Override
public void setWaitingForTransitionStartEvent(boolean waitingForTransitionStart) {
EventBus.getDefault().post(new SetWaitingForTransitionStartEvent(
waitingForTransitionStart));
}
} }

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2017 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.component;
import com.android.systemui.recents.events.EventBus;
/**
* This is sent when we are setting/resetting the flag to wait for the transition to start.
*/
public class SetWaitingForTransitionStartEvent extends EventBus.Event {
public final boolean waitingForTransitionStart;
public SetWaitingForTransitionStartEvent(boolean waitingForTransitionStart) {
this.waitingForTransitionStart = waitingForTransitionStart;
}
}

View File

@@ -54,6 +54,7 @@ import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent; import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent; import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent; import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent;
import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.model.TaskStack;
@@ -117,31 +118,58 @@ public class RecentsTransitionHelper {
final Rect windowRect = Recents.getSystemServices().getWindowRect(); final Rect windowRect = Recents.getSystemServices().getWindowRect();
transitionFuture = getAppTransitionFuture( transitionFuture = getAppTransitionFuture(
() -> composeAnimationSpecs(task, stackView, destinationStack, windowRect)); () -> composeAnimationSpecs(task, stackView, destinationStack, windowRect));
animStartedListener = () -> { animStartedListener = new OnAnimationStartedListener() {
// If we are launching into another task, cancel the previous task's private boolean mHandled;
// window transition
EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
stackView.cancelAllTaskViewAnimations();
if (screenPinningRequested) { @Override
// Request screen pinning after the animation runs public void onAnimationStarted() {
mStartScreenPinningRunnable.taskId = task.key.id; if (mHandled) {
mHandler.postDelayed(mStartScreenPinningRunnable, 350); return;
}
mHandled = true;
// If we are launching into another task, cancel the previous task's
// window transition
EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
stackView.cancelAllTaskViewAnimations();
if (screenPinningRequested) {
// Request screen pinning after the animation runs
mStartScreenPinningRunnable.taskId = task.key.id;
mHandler.postDelayed(mStartScreenPinningRunnable, 350);
}
// Reset the state where we are waiting for the transition to start
EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
} }
}; };
} else { } else {
// This is only the case if the task is not on screen (scrolled offscreen for example) // This is only the case if the task is not on screen (scrolled offscreen for example)
transitionFuture = null; transitionFuture = null;
animStartedListener = () -> { animStartedListener = new OnAnimationStartedListener() {
// If we are launching into another task, cancel the previous task's private boolean mHandled;
// window transition
EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task)); @Override
EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent()); public void onAnimationStarted() {
stackView.cancelAllTaskViewAnimations(); if (mHandled) {
return;
}
mHandled = true;
// If we are launching into another task, cancel the previous task's
// window transition
EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task));
EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent());
stackView.cancelAllTaskViewAnimations();
// Reset the state where we are waiting for the transition to start
EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false));
}
}; };
} }
EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(true));
final ActivityOptions opts = ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext, final ActivityOptions opts = ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext,
mHandler, transitionFuture != null ? transitionFuture.future : null, mHandler, transitionFuture != null ? transitionFuture.future : null,
animStartedListener, true /* scaleUp */); animStartedListener, true /* scaleUp */);

View File

@@ -13365,7 +13365,6 @@ public class ActivityManagerService extends IActivityManager.Stub
final ActivityRecord r = ActivityRecord.isInStackLocked(token); final ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r != null) { if (r != null) {
final ActivityOptions activityOptions = r.pendingOptions; final ActivityOptions activityOptions = r.pendingOptions;
r.pendingOptions = null;
return activityOptions == null ? null : activityOptions.toBundle(); return activityOptions == null ? null : activityOptions.toBundle();
} }
return null; return null;