Merge "Correct # of cells estimation that can fit horizontally in widgets picker" into sc-v2-dev
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 090fd01..6226fb0 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -33,6 +33,7 @@
import android.os.UserHandle;
import android.util.Log;
import android.view.MotionEvent;
+import android.view.RemoteAnimationAdapter;
import android.view.SurfaceControl;
import com.android.launcher3.util.MainThreadInitializedObject;
@@ -562,6 +563,22 @@
}
}
+ /**
+ * Start multiple tasks in split-screen simultaneously.
+ */
+ public void startTasksWithLegacyTransition(int mainTaskId, Bundle mainOptions, int sideTaskId,
+ Bundle sideOptions, @SplitConfigurationOptions.StagePosition int sidePosition,
+ RemoteAnimationAdapter adapter) {
+ if (mSystemUiProxy != null) {
+ try {
+ mSplitScreen.startTasksWithLegacyTransition(mainTaskId, mainOptions, sideTaskId,
+ sideOptions, sidePosition, adapter);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call startTasksWithLegacyTransition");
+ }
+ }
+ }
+
public void startShortcut(String packageName, String shortcutId, int stage, int position,
Bundle options, UserHandle user) {
if (mSplitScreen != null) {
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 37fda73..a85a24d 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -405,77 +405,39 @@
}
/** Legacy version (until shell transitions are enabled) */
- public static void composeRecentsSplitLaunchAnimatorLegacy(@NonNull AnimatorSet anim,
+ public static void composeRecentsSplitLaunchAnimatorLegacy(@NonNull TaskView initialView,
@NonNull TaskView v, @NonNull RemoteAnimationTargetCompat[] appTargets,
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
- @NonNull RemoteAnimationTargetCompat[] nonAppTargets, boolean launcherClosing,
- @NonNull StateManager stateManager, @NonNull DepthController depthController,
- int targetStage) {
- PendingAnimation out = new PendingAnimation(RECENTS_LAUNCH_DURATION);
- boolean isRunningTask = v.isRunningTask();
- TransformParams params = null;
- TaskViewSimulator tvs = null;
- RecentsView recentsView = v.getRecentsView();
- if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask) {
- params = recentsView.getLiveTileParams();
- tvs = recentsView.getLiveTileTaskViewSimulator();
+ @NonNull RemoteAnimationTargetCompat[] nonAppTargets,
+ @NonNull Runnable finishCallback) {
+
+ final int[] splitRoots = new int[2];
+ for (int i = 0; i < appTargets.length; ++i) {
+ final int taskId = appTargets[i].taskInfo != null ? appTargets[i].taskInfo.taskId : -1;
+ final int mode = appTargets[i].mode;
+ if (taskId == initialView.getTask().key.id || taskId == v.getTask().key.id) {
+ if (mode != MODE_OPENING) {
+ throw new IllegalStateException(
+ "Expected task to be opening, but it is " + mode);
+ }
+ splitRoots[taskId == initialView.getTask().key.id ? 0 : 1] = i;
+ }
}
- boolean inLiveTileMode =
- ENABLE_QUICKSTEP_LIVE_TILE.get() && recentsView.getRunningTaskIndex() != -1;
- final RemoteAnimationTargets targets =
- new RemoteAnimationTargets(appTargets, wallpaperTargets, nonAppTargets,
- inLiveTileMode ? MODE_CLOSING : MODE_OPENING);
+ SurfaceControl.Transaction t = new SurfaceControl.Transaction();
- if (params == null) {
- SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v);
- targets.addReleaseCheck(applier);
-
- params = new TransformParams()
- .setSyncTransactionApplier(applier)
- .setTargetSet(targets);
+ // This is where we should animate the split roots. For now, though, just make them visible.
+ for (int i = 0; i < 2; ++i) {
+ t.show(appTargets[splitRoots[i]].leash.getSurfaceControl());
+ t.setAlpha(appTargets[splitRoots[i]].leash.getSurfaceControl(), 1.f);
}
- Rect crop = new Rect();
- Context context = v.getContext();
- DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
- if (tvs == null && targets.apps.length > 0) {
- tvs = new TaskViewSimulator(recentsView.getContext(), recentsView.getSizeStrategy());
- tvs.setDp(dp);
+ // This contains the initial state (before animation), so apply this at the beginning of
+ // the animation.
+ t.apply();
- // RecentsView never updates the display rotation until swipe-up so the value may
- // be stale. Use the display value instead.
- int displayRotation = DisplayController.INSTANCE.get(recentsView.getContext())
- .getInfo().rotation;
- tvs.getOrientationState().update(displayRotation, displayRotation);
-
- tvs.setPreview(targets.apps[targets.apps.length - 1]);
- tvs.fullScreenProgress.value = 0;
- tvs.recentsViewScale.value = 1;
-// tvs.setScroll(startScroll);
-
- // Fade in the task during the initial 20% of the animation
- out.addFloat(params, TransformParams.TARGET_ALPHA, 0, 1,
- clampToProgress(LINEAR, 0, 0.2f));
- }
-
- TaskViewSimulator topMostSimulator = null;
-
- if (tvs != null) {
- out.setFloat(tvs.fullScreenProgress,
- AnimatedFloat.VALUE, 1, TOUCH_RESPONSE_INTERPOLATOR);
- out.setFloat(tvs.recentsViewScale,
- AnimatedFloat.VALUE, tvs.getFullScreenScale(), TOUCH_RESPONSE_INTERPOLATOR);
- out.setFloat(tvs.recentsViewScroll,
- AnimatedFloat.VALUE, 0, TOUCH_RESPONSE_INTERPOLATOR);
-
- TaskViewSimulator finalTsv = tvs;
- TransformParams finalParams = params;
- out.addOnFrameCallback(() -> finalTsv.apply(finalParams));
- topMostSimulator = tvs;
- }
-
- anim.play(out.buildAnim());
+ // Once there is an animation, this should be called AFTER the animation completes.
+ finishCallback.run();
}
public static void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index a147b68..2351a4e 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -22,33 +22,26 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
-import android.animation.AnimatorSet;
-import android.app.ActivityOptions;
+import android.app.ActivityThread;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
-import android.util.Pair;
import android.view.Gravity;
+import android.view.RemoteAnimationAdapter;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
import androidx.annotation.Nullable;
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InsettableFrameLayout;
-import com.android.launcher3.LauncherAnimationRunner;
-import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory;
import com.android.launcher3.R;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.TaskViewUtils;
import com.android.quickstep.views.TaskView;
-import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -92,37 +85,27 @@
? new int[]{mInitialTaskView.getTask().key.id, taskView.getTask().key.id}
: new int[]{taskView.getTask().key.id, mInitialTaskView.getTask().key.id};
- RemoteSplitLaunchAnimationRunner animationRunner =
- new RemoteSplitLaunchAnimationRunner(mInitialTaskView, taskView);
+ RemoteSplitLaunchTransitionRunner animationRunner =
+ new RemoteSplitLaunchTransitionRunner(mInitialTaskView, taskView);
mSystemUiProxy.startTasks(taskIds[0], null /* mainOptions */, taskIds[1],
null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT,
new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR));
- return;
+ } else {
+ // Assume initial task is for top/left part of screen
+ final int[] taskIds = mInitialPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT
+ ? new int[]{mInitialTaskView.getTask().key.id, taskView.getTask().key.id}
+ : new int[]{taskView.getTask().key.id, mInitialTaskView.getTask().key.id};
+
+ RemoteSplitLaunchAnimationRunner animationRunner =
+ new RemoteSplitLaunchAnimationRunner(mInitialTaskView, taskView);
+ final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
+ RemoteAnimationAdapterCompat.wrapRemoteAnimationRunner(animationRunner),
+ 300, 150,
+ ActivityThread.currentActivityThread().getApplicationThread());
+
+ mSystemUiProxy.startTasksWithLegacyTransition(taskIds[0], null /* mainOptions */,
+ taskIds[1], null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT, adapter);
}
- // Assume initial mInitialTaskId is for top/left part of screen
- RemoteAnimationFactory initialSplitRunnerWrapped = new SplitLaunchAnimationRunner(
- mInitialTaskView, 0);
- RemoteAnimationFactory secondarySplitRunnerWrapped = new SplitLaunchAnimationRunner(
- taskView, 1);
- RemoteAnimationRunnerCompat initialSplitRunner = new LauncherAnimationRunner(
- new Handler(Looper.getMainLooper()), initialSplitRunnerWrapped,
- true /* startAtFrontOfQueue */);
- RemoteAnimationRunnerCompat secondarySplitRunner = new LauncherAnimationRunner(
- new Handler(Looper.getMainLooper()), secondarySplitRunnerWrapped,
- true /* startAtFrontOfQueue */);
- ActivityOptions initialOptions = ActivityOptionsCompat.makeRemoteAnimation(
- new RemoteAnimationAdapterCompat(initialSplitRunner, 300, 150));
- ActivityOptions secondaryOptions = ActivityOptionsCompat.makeRemoteAnimation(
- new RemoteAnimationAdapterCompat(secondarySplitRunner, 300, 150));
- mSystemUiProxy.startTask(mInitialTaskView.getTask().key.id, mInitialPosition.mStageType,
- mInitialPosition.mStagePosition,
- /*null*/ initialOptions.toBundle());
- Pair<Integer, Integer> compliment = getComplimentaryStageAndPosition(mInitialPosition);
- mSystemUiProxy.startTask(taskView.getTask().key.id, compliment.first,
- compliment.second,
- /*null*/ secondaryOptions.toBundle());
- // After successful launch, call resetState
- resetState();
}
/**
@@ -153,12 +136,12 @@
/**
* Requires Shell Transitions
*/
- private class RemoteSplitLaunchAnimationRunner implements RemoteTransitionRunner {
+ private class RemoteSplitLaunchTransitionRunner implements RemoteTransitionRunner {
private final TaskView mInitialTaskView;
private final TaskView mTaskView;
- RemoteSplitLaunchAnimationRunner(TaskView initialTaskView, TaskView taskView) {
+ RemoteSplitLaunchTransitionRunner(TaskView initialTaskView, TaskView taskView) {
mInitialTaskView = initialTaskView;
mTaskView = taskView;
}
@@ -175,48 +158,34 @@
/**
* LEGACY
- * @return the opposite stage and position from the {@param position} provided as first and
- * second object, respectively
- * Ex. If position is has stage = Main and position = Top/Left, this will return
- * Pair(stage=Side, position=Bottom/Left)
- */
- private Pair<Integer, Integer> getComplimentaryStageAndPosition(SplitPositionOption position) {
- // Right now this is as simple as flipping between 0 and 1
- int complimentStageType = position.mStageType ^ 1;
- int complimentStagePosition = position.mStagePosition ^ 1;
- return new Pair<>(complimentStageType, complimentStagePosition);
- }
-
- /**
- * LEGACY
* Remote animation runner for animation to launch an app.
*/
- private class SplitLaunchAnimationRunner implements RemoteAnimationFactory {
+ private class RemoteSplitLaunchAnimationRunner implements RemoteAnimationRunnerCompat {
- private final TaskView mV;
- private final int mTargetState;
+ private final TaskView mInitialTaskView;
+ private final TaskView mTaskView;
- SplitLaunchAnimationRunner(TaskView v, int targetState) {
- mV = v;
- mTargetState = targetState;
+ RemoteSplitLaunchAnimationRunner(TaskView initialTaskView, TaskView taskView) {
+ mInitialTaskView = initialTaskView;
+ mTaskView = taskView;
}
@Override
- public void onCreateAnimation(int transit,
- RemoteAnimationTargetCompat[] appTargets,
- RemoteAnimationTargetCompat[] wallpaperTargets,
- RemoteAnimationTargetCompat[] nonAppTargets,
- LauncherAnimationRunner.AnimationResult result) {
- AnimatorSet anim = new AnimatorSet();
- BaseQuickstepLauncher activity = BaseActivity.fromContext(mV.getContext());
- TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(anim, mV,
- appTargets, wallpaperTargets, nonAppTargets, true, activity.getStateManager(),
- activity.getDepthController(), mTargetState);
- result.setAnimation(anim, activity);
+ public void onAnimationStart(int transit, RemoteAnimationTargetCompat[] apps,
+ RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps,
+ Runnable finishedCallback) {
+ TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTaskView, mTaskView, apps,
+ wallpapers, nonApps, finishedCallback);
+ // After successful launch, call resetState
+ resetState();
+ }
+
+ @Override
+ public void onAnimationCancelled() {
+ resetState();
}
}
-
/**
* To be called if split select was cancelled
*/
diff --git a/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java b/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java
index c18e26c..1090d1e 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java
@@ -52,15 +52,15 @@
@RunWith(RobolectricTestRunner.class)
public class CachingWidgetPreviewLoaderTest {
- private static final Size SIZE_10_10 = new Size(10, 10);
- private static final Size SIZE_20_20 = new Size(20, 20);
+ private final Size SIZE_10_10 = new Size(10, 10);
+ private final Size SIZE_20_20 = new Size(20, 20);
private static final String TEST_PACKAGE = "com.example.test";
- private static final ComponentName TEST_PROVIDER =
+ private final ComponentName TEST_PROVIDER =
new ComponentName(TEST_PACKAGE, ".WidgetProvider");
- private static final ComponentName TEST_PROVIDER2 =
+ private final ComponentName TEST_PROVIDER2 =
new ComponentName(TEST_PACKAGE, ".WidgetProvider2");
- private static final Bitmap BITMAP = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
- private static final Bitmap BITMAP2 = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_8888);
+ private final Bitmap BITMAP = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
+ private final Bitmap BITMAP2 = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_8888);
@Mock private CancellationSignal mCancellationSignal;