Merge "Fix a memory leak" into sc-dev am: 29c1e8437e
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/13961425 Change-Id: Ibe9df851507b75b835ac9cd37d5352e6443ea767
This commit is contained in:
@@ -22,7 +22,6 @@ import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
|
||||
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
|
||||
import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
@@ -97,8 +96,8 @@ import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.util.ActivityInitListener;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.InputConsumerProxy;
|
||||
import com.android.quickstep.util.InputProxyHandlerFactory;
|
||||
import com.android.quickstep.util.MotionPauseDetector;
|
||||
import com.android.quickstep.util.MultiValueUpdateListener;
|
||||
import com.android.quickstep.util.ProtoTracer;
|
||||
import com.android.quickstep.util.RecentsOrientedState;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
@@ -113,12 +112,10 @@ import com.android.systemui.shared.system.InputConsumerController;
|
||||
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
|
||||
import com.android.systemui.shared.system.LatencyTrackerCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
|
||||
import com.android.systemui.shared.system.TaskInfoCompat;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@@ -255,7 +252,10 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mActivityInterface = gestureState.getActivityInterface();
|
||||
mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit);
|
||||
mInputConsumerProxy =
|
||||
new InputConsumerProxy(inputConsumer, this::createNewInputProxyHandler);
|
||||
new InputConsumerProxy(inputConsumer, () -> {
|
||||
endRunningWindowAnim(mGestureState.getEndTarget() == HOME /* cancel */);
|
||||
endLauncherTransitionController();
|
||||
}, new InputProxyHandlerFactory(mActivityInterface, mGestureState));
|
||||
mTaskAnimationManager = taskAnimationManager;
|
||||
mTouchTimeMs = touchTimeMs;
|
||||
mContinuingLastGesture = continuingLastGesture;
|
||||
@@ -783,19 +783,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
handleNormalGestureEnd(endVelocity, isFling, velocity, false /* isCancel */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to create a input proxy for the running task
|
||||
*/
|
||||
@UiThread
|
||||
protected InputConsumer createNewInputProxyHandler() {
|
||||
endRunningWindowAnim(mGestureState.getEndTarget() == HOME /* cancel */);
|
||||
endLauncherTransitionController();
|
||||
|
||||
StatefulActivity activity = mActivityInterface.getCreatedActivity();
|
||||
return activity == null ? InputConsumer.NO_OP
|
||||
: new OverviewInputConsumer(mGestureState, activity, null, true);
|
||||
}
|
||||
|
||||
private void endRunningWindowAnim(boolean cancel) {
|
||||
if (mRunningWindowAnim != null) {
|
||||
if (cancel) {
|
||||
@@ -1338,6 +1325,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mInputConsumerProxy.destroy();
|
||||
mTaskAnimationManager.setLiveTileCleanUpHandler(null);
|
||||
}
|
||||
mInputConsumerProxy.unregisterCallback();
|
||||
endRunningWindowAnim(false /* cancel */);
|
||||
|
||||
if (mGestureEndCallback != null) {
|
||||
@@ -1502,36 +1490,13 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
protected abstract void finishRecentsControllerToHome(Runnable callback);
|
||||
|
||||
private final TaskStackChangeListener mLiveTileRestartListener = new TaskStackChangeListener() {
|
||||
@Override
|
||||
public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
|
||||
boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
|
||||
if (mRecentsView.getRunningTaskIndex() != -1
|
||||
&& mRecentsView.getRunningTaskId() == task.taskId
|
||||
&& mRecentsAnimationTargets.hasTask(task.taskId)) {
|
||||
launchOtherTaskInLiveTileMode(task.taskId, mRecentsAnimationTargets.apps);
|
||||
}
|
||||
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(
|
||||
mLiveTileRestartListener);
|
||||
}
|
||||
};
|
||||
|
||||
private void setupLauncherUiAfterSwipeUpToRecentsAnimation() {
|
||||
endLauncherTransitionController();
|
||||
mActivityInterface.onSwipeUpToRecentsComplete();
|
||||
mRecentsView.onSwipeUpAnimationSuccess();
|
||||
if (LIVE_TILE.get()) {
|
||||
mTaskAnimationManager.setLaunchOtherTaskInLiveTileModeHandler(
|
||||
appearedTaskTarget -> {
|
||||
RemoteAnimationTargetCompat[] apps = Arrays.copyOf(
|
||||
mRecentsAnimationTargets.apps,
|
||||
mRecentsAnimationTargets.apps.length + 1);
|
||||
apps[apps.length - 1] = appearedTaskTarget;
|
||||
launchOtherTaskInLiveTileMode(appearedTaskTarget.taskId, apps);
|
||||
});
|
||||
mTaskAnimationManager.setLiveTileCleanUpHandler(mInputConsumerProxy::destroy);
|
||||
ActivityManagerWrapper.getInstance().registerTaskStackListener(
|
||||
mLiveTileRestartListener);
|
||||
mTaskAnimationManager.enableLiveTileRestartListener();
|
||||
}
|
||||
|
||||
SystemUiProxy.INSTANCE.get(mContext).onOverviewShown(false, TAG);
|
||||
@@ -1539,65 +1504,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
reset();
|
||||
}
|
||||
|
||||
private void launchOtherTaskInLiveTileMode(int taskId, RemoteAnimationTargetCompat[] apps) {
|
||||
AnimatorSet anim = new AnimatorSet();
|
||||
TaskView taskView = mRecentsView.getTaskView(taskId);
|
||||
if (taskView == null || !mRecentsView.isTaskViewVisible(taskView)) {
|
||||
// TODO: Refine this animation.
|
||||
SurfaceTransactionApplier surfaceApplier =
|
||||
new SurfaceTransactionApplier(mActivity.getDragLayer());
|
||||
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
|
||||
appAnimator.setDuration(RECENTS_LAUNCH_DURATION);
|
||||
appAnimator.setInterpolator(ACCEL_DEACCEL);
|
||||
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
|
||||
@Override
|
||||
public void onUpdate(float percent) {
|
||||
SurfaceParams.Builder builder = new SurfaceParams.Builder(
|
||||
apps[apps.length - 1].leash);
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(percent, percent);
|
||||
matrix.postTranslate(mDp.widthPx * (1 - percent) / 2,
|
||||
mDp.heightPx * (1 - percent) / 2);
|
||||
builder.withAlpha(percent).withMatrix(matrix);
|
||||
surfaceApplier.scheduleApply(builder.build());
|
||||
}
|
||||
});
|
||||
anim.play(appAnimator);
|
||||
} else {
|
||||
TaskViewUtils.composeRecentsLaunchAnimator(
|
||||
anim, taskView, apps,
|
||||
mRecentsAnimationTargets.wallpapers, true /* launcherClosing */,
|
||||
mActivity.getStateManager(), mRecentsView,
|
||||
mActivityInterface.getDepthController());
|
||||
}
|
||||
anim.addListener(new AnimatorListenerAdapter(){
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
cleanUp(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animator) {
|
||||
cleanUp(true);
|
||||
}
|
||||
|
||||
private void cleanUp(boolean canceled) {
|
||||
if (mRecentsAnimationController != null) {
|
||||
mRecentsAnimationController.finish(false /* toRecents */,
|
||||
null /* onFinishComplete */);
|
||||
if (canceled) {
|
||||
mRecentsAnimationController = null;
|
||||
} else {
|
||||
mActivityInterface.onLaunchTaskSuccess();
|
||||
}
|
||||
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false);
|
||||
}
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
}
|
||||
|
||||
private static boolean isNotInRecents(RemoteAnimationTargetCompat app) {
|
||||
return app.isNotInRecents
|
||||
|| app.activityType == ACTIVITY_TYPE_HOME;
|
||||
|
||||
@@ -41,13 +41,4 @@ public class RecentsAnimationTargets extends RemoteAnimationTargets {
|
||||
public boolean hasTargets() {
|
||||
return unfilteredApps.length != 0;
|
||||
}
|
||||
|
||||
public boolean hasTask(int taskId) {
|
||||
for (RemoteAnimationTargetCompat target : unfilteredApps) {
|
||||
if (target.taskId == taskId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,11 @@ package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
|
||||
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED;
|
||||
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED;
|
||||
import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
@@ -31,13 +32,13 @@ import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.system.RemoteTransitionCompat;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||
|
||||
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
|
||||
public static final boolean ENABLE_SHELL_TRANSITIONS =
|
||||
@@ -49,10 +50,24 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
// Temporary until we can hook into gesture state events
|
||||
private GestureState mLastGestureState;
|
||||
private RemoteAnimationTargetCompat mLastAppearedTaskTarget;
|
||||
private Consumer<RemoteAnimationTargetCompat> mLaunchOtherTaskHandler;
|
||||
private Runnable mLiveTileCleanUpHandler;
|
||||
private Context mCtx;
|
||||
|
||||
private final TaskStackChangeListener mLiveTileRestartListener = new TaskStackChangeListener() {
|
||||
@Override
|
||||
public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
|
||||
boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
|
||||
BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
|
||||
if (LIVE_TILE.get() && activityInterface.isInLiveTileMode()
|
||||
&& activityInterface.getCreatedActivity() != null) {
|
||||
RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel();
|
||||
recentsView.launchSideTaskInLiveTileModeForRestartedApp(task.taskId);
|
||||
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(
|
||||
mLiveTileRestartListener);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TaskAnimationManager(Context ctx) {
|
||||
mCtx = ctx;
|
||||
}
|
||||
@@ -114,9 +129,14 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
|
||||
@Override
|
||||
public void onTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
|
||||
if (mLaunchOtherTaskHandler != null
|
||||
&& mLastGestureState.getEndTarget() == RECENTS) {
|
||||
mLaunchOtherTaskHandler.accept(appearedTaskTarget);
|
||||
BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
|
||||
if (LIVE_TILE.get() && activityInterface.isInLiveTileMode()
|
||||
&& activityInterface.getCreatedActivity() != null) {
|
||||
RecentsView recentsView =
|
||||
activityInterface.getCreatedActivity().getOverviewPanel();
|
||||
RemoteAnimationTargetCompat[] apps = new RemoteAnimationTargetCompat[1];
|
||||
apps[0] = appearedTaskTarget;
|
||||
recentsView.launchSideTaskInLiveTileMode(appearedTaskTarget.taskId, apps);
|
||||
return;
|
||||
}
|
||||
if (mController != null) {
|
||||
@@ -161,17 +181,12 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
return mCallbacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* The passed-in handler is used to render side task launch animation in recents in live tile
|
||||
* mode.
|
||||
*/
|
||||
public void setLaunchOtherTaskInLiveTileModeHandler(
|
||||
Consumer<RemoteAnimationTargetCompat> handler) {
|
||||
mLaunchOtherTaskHandler = handler;
|
||||
public void setLiveTileCleanUpHandler(Runnable cleanUpHandler) {
|
||||
mLiveTileCleanUpHandler = cleanUpHandler;
|
||||
}
|
||||
|
||||
public void setLiveTileCleanUpHandler(Runnable runnable) {
|
||||
mLiveTileCleanUpHandler = runnable;
|
||||
public void enableLiveTileRestartListener() {
|
||||
ActivityManagerWrapper.getInstance().registerTaskStackListener(mLiveTileRestartListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,6 +230,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
mLiveTileCleanUpHandler.run();
|
||||
mLiveTileCleanUpHandler = null;
|
||||
}
|
||||
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mLiveTileRestartListener);
|
||||
|
||||
// Release all the target leashes
|
||||
if (mTargets != null) {
|
||||
@@ -231,7 +247,6 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
||||
mTargets = null;
|
||||
mLastGestureState = null;
|
||||
mLastAppearedTaskTarget = null;
|
||||
mLaunchOtherTaskHandler = null;
|
||||
}
|
||||
|
||||
public void dump() {
|
||||
|
||||
@@ -38,7 +38,8 @@ public class InputConsumerProxy {
|
||||
private static final String TAG = "InputConsumerProxy";
|
||||
|
||||
private final InputConsumerController mInputConsumerController;
|
||||
private final Supplier<InputConsumer> mConsumerSupplier;
|
||||
private Runnable mCallback;
|
||||
private Supplier<InputConsumer> mConsumerSupplier;
|
||||
|
||||
// The consumer is created lazily on demand.
|
||||
private InputConsumer mInputConsumer;
|
||||
@@ -48,8 +49,9 @@ public class InputConsumerProxy {
|
||||
private boolean mDestroyPending = false;
|
||||
|
||||
public InputConsumerProxy(InputConsumerController inputConsumerController,
|
||||
Supplier<InputConsumer> consumerSupplier) {
|
||||
Runnable callback, Supplier<InputConsumer> consumerSupplier) {
|
||||
mInputConsumerController = inputConsumerController;
|
||||
mCallback = callback;
|
||||
mConsumerSupplier = consumerSupplier;
|
||||
}
|
||||
|
||||
@@ -64,9 +66,7 @@ public class InputConsumerProxy {
|
||||
if (ev instanceof MotionEvent) {
|
||||
onInputConsumerMotionEvent((MotionEvent) ev);
|
||||
} else if (ev instanceof KeyEvent) {
|
||||
if (mInputConsumer == null) {
|
||||
mInputConsumer = mConsumerSupplier.get();
|
||||
}
|
||||
initInputConsumerIfNeeded();
|
||||
mInputConsumer.onKeyEvent((KeyEvent) ev);
|
||||
return true;
|
||||
}
|
||||
@@ -89,9 +89,7 @@ public class InputConsumerProxy {
|
||||
|
||||
if (action == ACTION_DOWN) {
|
||||
mTouchInProgress = true;
|
||||
if (mInputConsumer == null) {
|
||||
mInputConsumer = mConsumerSupplier.get();
|
||||
}
|
||||
initInputConsumerIfNeeded();
|
||||
} else if (action == ACTION_CANCEL || action == ACTION_UP) {
|
||||
// Finish any pending actions
|
||||
mTouchInProgress = false;
|
||||
@@ -115,4 +113,18 @@ public class InputConsumerProxy {
|
||||
mDestroyed = true;
|
||||
mInputConsumerController.setInputListener(null);
|
||||
}
|
||||
|
||||
public void unregisterCallback() {
|
||||
mCallback = null;
|
||||
}
|
||||
|
||||
private void initInputConsumerIfNeeded() {
|
||||
if (mInputConsumer == null) {
|
||||
if (mCallback != null) {
|
||||
mCallback.run();
|
||||
}
|
||||
mInputConsumer = mConsumerSupplier.get();
|
||||
mConsumerSupplier = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.quickstep.util;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.quickstep.BaseActivityInterface;
|
||||
import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.InputConsumer;
|
||||
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A factory that creates a input consumer for
|
||||
* {@link com.android.quickstep.util.InputConsumerProxy}.
|
||||
*/
|
||||
public class InputProxyHandlerFactory implements Supplier<InputConsumer> {
|
||||
|
||||
private final BaseActivityInterface mActivityInterface;
|
||||
private final GestureState mGestureState;
|
||||
|
||||
@UiThread
|
||||
public InputProxyHandlerFactory(BaseActivityInterface activityInterface,
|
||||
GestureState gestureState) {
|
||||
mActivityInterface = activityInterface;
|
||||
mGestureState = gestureState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to create a input proxy for the running task
|
||||
*/
|
||||
@Override
|
||||
public InputConsumer get() {
|
||||
StatefulActivity activity = mActivityInterface.getCreatedActivity();
|
||||
return activity == null ? InputConsumer.NO_OP
|
||||
: new OverviewInputConsumer(mGestureState, activity, null, true);
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
|
||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
|
||||
import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION;
|
||||
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
|
||||
import static com.android.launcher3.Utilities.mapToRange;
|
||||
import static com.android.launcher3.Utilities.squaredHypot;
|
||||
@@ -34,6 +35,7 @@ import static com.android.launcher3.Utilities.squaredTouchSlop;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL;
|
||||
@@ -50,6 +52,7 @@ import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
|
||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.LayoutTransition;
|
||||
import android.animation.LayoutTransition.TransitionListener;
|
||||
@@ -61,6 +64,7 @@ import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
@@ -129,8 +133,11 @@ import com.android.quickstep.RecentsModel.TaskVisualsChangeListener;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TaskOverlayFactory;
|
||||
import com.android.quickstep.TaskThumbnailCache;
|
||||
import com.android.quickstep.TaskViewUtils;
|
||||
import com.android.quickstep.ViewUtils;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.MultiValueUpdateListener;
|
||||
import com.android.quickstep.util.RecentsOrientedState;
|
||||
import com.android.quickstep.util.SplitScreenBounds;
|
||||
import com.android.quickstep.util.SurfaceTransactionApplier;
|
||||
@@ -142,6 +149,8 @@ import com.android.systemui.shared.recents.model.Task.TaskKey;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.PackageManagerWrapper;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||
import com.android.wm.shell.pip.IPipAnimationListener;
|
||||
|
||||
@@ -715,6 +724,72 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
|
||||
super.draw(canvas);
|
||||
}
|
||||
|
||||
public void launchSideTaskInLiveTileModeForRestartedApp(int taskId) {
|
||||
if (mRunningTaskId != -1 && mRunningTaskId == taskId &&
|
||||
getLiveTileParams().getTargetSet().findTask(taskId) != null) {
|
||||
launchSideTaskInLiveTileMode(taskId, getLiveTileParams().getTargetSet().apps);
|
||||
}
|
||||
}
|
||||
|
||||
public void launchSideTaskInLiveTileMode(int taskId, RemoteAnimationTargetCompat[] apps) {
|
||||
AnimatorSet anim = new AnimatorSet();
|
||||
TaskView taskView = getTaskView(taskId);
|
||||
if (taskView == null || !isTaskViewVisible(taskView)) {
|
||||
// TODO: Refine this animation.
|
||||
SurfaceTransactionApplier surfaceApplier =
|
||||
new SurfaceTransactionApplier(mActivity.getDragLayer());
|
||||
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
|
||||
appAnimator.setDuration(RECENTS_LAUNCH_DURATION);
|
||||
appAnimator.setInterpolator(ACCEL_DEACCEL);
|
||||
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
|
||||
@Override
|
||||
public void onUpdate(float percent) {
|
||||
SurfaceParams.Builder builder = new SurfaceParams.Builder(
|
||||
apps[apps.length - 1].leash);
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(percent, percent);
|
||||
matrix.postTranslate(mActivity.getDeviceProfile().widthPx * (1 - percent) / 2,
|
||||
mActivity.getDeviceProfile().heightPx * (1 - percent) / 2);
|
||||
builder.withAlpha(percent).withMatrix(matrix);
|
||||
surfaceApplier.scheduleApply(builder.build());
|
||||
}
|
||||
});
|
||||
anim.play(appAnimator);
|
||||
} else {
|
||||
TaskViewUtils.composeRecentsLaunchAnimator(
|
||||
anim, taskView, apps,
|
||||
mLiveTileParams.getTargetSet().wallpapers, true /* launcherClosing */,
|
||||
mActivity.getStateManager(), this,
|
||||
getDepthController());
|
||||
}
|
||||
anim.addListener(new AnimatorListenerAdapter(){
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
cleanUp(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animator) {
|
||||
cleanUp(true);
|
||||
}
|
||||
|
||||
private void cleanUp(boolean canceled) {
|
||||
if (mRecentsAnimationController != null) {
|
||||
mRecentsAnimationController.finish(false /* toRecents */,
|
||||
null /* onFinishComplete */);
|
||||
if (canceled) {
|
||||
mRecentsAnimationController = null;
|
||||
} else {
|
||||
mSizeStrategy.onLaunchTaskSuccess();
|
||||
}
|
||||
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false);
|
||||
}
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
}
|
||||
|
||||
private void updateTaskStartIndex(View affectingView) {
|
||||
if (!(affectingView instanceof TaskView) && !(affectingView instanceof ClearAllButton)) {
|
||||
int childCount = getChildCount();
|
||||
|
||||
Reference in New Issue
Block a user