Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b46f3c7 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Implement transition for docking task in recents #2

- Put window into resizing mode when docking it from recents,
so it fills the "void".
- Send whole task bitmap window as the thumbnail, to make
the transition smoother.

Bug: 27607141
Change-Id: Ib647d44d9777f1155deab818d1fd5425c1bdd3d1
parent 192086eb
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -403,13 +403,14 @@ public class SystemServicesProxy {

    /** Docks a task to the side of the screen and starts it. */
    public void startTaskInDockedMode(Context context, View view, int taskId, int createMode,
            Handler handler, OnAnimationStartedListener startedListener) {
            Bitmap headerBitmap, Handler handler, OnAnimationStartedListener startedListener) {
        if (mIam == null) return;

        try {
            // TODO: Determine what animation we want for the incoming task
            final ActivityOptions options = ActivityOptions.makeThumbnailAspectScaleUpAnimation(
                    view, null, 0, 0, view.getWidth(), view.getHeight(), handler, startedListener);
                    view, headerBitmap, 0, 0, (int) (view.getWidth() * view.getScaleX()),
                    (int) (view.getHeight() * view.getScaleY()), handler, startedListener);
            options.setDockCreateMode(createMode);
            options.setLaunchStackId(DOCKED_STACK_ID);
            mIam.startActivityFromRecents(taskId, options.toBundle());
+38 −15
Original line number Diff line number Diff line
@@ -319,17 +319,30 @@ public class RecentsTransitionHelper {
        return new AppTransitionAnimationSpec(task.key.id, null, taskRect);
    }

    /**
     * Composes a single animation spec for the given {@link TaskView}
     */
    private static AppTransitionAnimationSpec composeAnimationSpec(TaskStackView stackView,
            TaskView taskView, TaskViewTransform transform, boolean addHeaderBitmap) {
        Bitmap b = null;
        if (addHeaderBitmap) {
    public static Bitmap composeTaskBitmap(TaskView taskView, TaskViewTransform transform) {
        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 (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();
    }

    private static Bitmap composeHeaderBitmap(TaskView taskView,
            TaskViewTransform transform) {
        float scale = transform.scale;
        int fromHeaderWidth = (int) (transform.rect.width());
        int fromHeaderHeight = (int) (taskView.mHeaderView.getMeasuredHeight() * scale);
            b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
        Bitmap b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
                Bitmap.Config.ARGB_8888);

        if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
@@ -340,7 +353,17 @@ public class RecentsTransitionHelper {
            taskView.mHeaderView.draw(c);
            c.setBitmap(null);
        }
            b = b.createAshmemBitmap();
        return b.createAshmemBitmap();
    }

    /**
     * Composes a single animation spec for the given {@link TaskView}
     */
    private static AppTransitionAnimationSpec composeAnimationSpec(TaskStackView stackView,
            TaskView taskView, TaskViewTransform transform, boolean addHeaderBitmap) {
        Bitmap b = null;
        if (addHeaderBitmap) {
            b = composeHeaderBitmap(taskView, transform);
        }

        Rect taskRect = new Rect();
+5 −3
Original line number Diff line number Diff line
@@ -52,10 +52,8 @@ import com.android.systemui.recents.RecentsActivityLaunchState;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.RecentsDebugFlags;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.EventBus.Event;
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
@@ -493,7 +491,7 @@ public class RecentsView extends FrameLayout {
            stackLayout.getStackTransform(event.task, stackScroller.getStackScroll(), tmpTransform,
                    null);
            tmpTransform.alpha = 0;
            tmpTransform.scale = 1f;
            tmpTransform.scale = TaskStackView.DRAG_SCALE_FACTOR;
            tmpTransform.rect.set(taskViewRect);
            final OnAnimationStartedListener startedListener = new OnAnimationStartedListener() {
                @Override
@@ -510,8 +508,12 @@ public class RecentsView extends FrameLayout {
                                public void onAnimationEnd(Animator animation) {
                                    // Dock the task and launch it
                                    SystemServicesProxy ssp = Recents.getSystemServices();
                                    TaskViewTransform transform = new TaskViewTransform();
                                    transform.fillIn(event.taskView);
                                    ssp.startTaskInDockedMode(getContext(), event.taskView,
                                            event.task.key.id, dockState.createMode,
                                            RecentsTransitionHelper.composeTaskBitmap(
                                                    event.taskView, transform),
                                            mHandler, startedListener);
                                }
                            }));
+1 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal

    public static final int DEFAULT_SYNC_STACK_DURATION = 200;
    private static final int DRAG_SCALE_DURATION = 175;
    private static final float DRAG_SCALE_FACTOR = 1.05f;
    static final float DRAG_SCALE_FACTOR = 1.05f;

    private static final int LAUNCH_NEXT_SCROLL_BASE_DURATION = 216;
    private static final int LAUNCH_NEXT_SCROLL_INCR_DURATION = 32;
+12 −57
Original line number Diff line number Diff line
@@ -4494,63 +4494,12 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
        final long origId = Binder.clearCallingIdentity();
        try {
            return startActivityFromRecentsInner(taskId, bOptions);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }
    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
        final TaskRecord task;
        final int callingUid;
        final String callingPackage;
        final Intent intent;
        final int userId;
            synchronized (this) {
            final ActivityOptions activityOptions = (bOptions != null)
                    ? new ActivityOptions(bOptions) : null;
            final int launchStackId = (activityOptions != null)
                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
            if (launchStackId == HOME_STACK_ID) {
                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
                        + taskId + " can't be launch in the home stack.");
            }
            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
            if (task == null) {
                throw new IllegalArgumentException(
                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
            }
            if (launchStackId != INVALID_STACK_ID) {
                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
                    mWindowManager.setDockedStackCreateState(
                            activityOptions.getDockCreateMode(), null /* initialBounds */);
                    mStackSupervisor.deferUpdateBounds(HOME_STACK_ID);
                    mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
            }
                if (task.stack.mStackId != launchStackId) {
                    mStackSupervisor.moveTaskToStackLocked(
                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
                            ANIMATE);
                }
            }
            // If the user must confirm credentials (e.g. when first launching a work app and the
            // Work Challenge is present) let startActivityInPackage handle the intercepting.
            if (!mUserController.shouldConfirmCredentials(task.userId)
                    && task.getRootActivity() != null) {
                moveTaskToFrontLocked(task.taskId, 0, bOptions);
                return ActivityManager.START_TASK_TO_FRONT;
            }
            callingUid = task.mCallingUid;
            callingPackage = task.mCallingPackage;
            intent = task.intent;
            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
            userId = task.userId;
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
                bOptions, userId, null, task);
    }
    final int startActivityInPackage(int uid, String callingPackage,
@@ -21053,12 +21002,16 @@ public final class ActivityManagerService extends ActivityManagerNative
        @Override
        public void notifyAppTransitionFinished() {
            mStackSupervisor.continueUpdateBounds(HOME_STACK_ID);
            synchronized (ActivityManagerService.this) {
                mStackSupervisor.notifyAppTransitionDone();
            }
        }
        @Override
        public void notifyAppTransitionCancelled() {
            mStackSupervisor.continueUpdateBounds(HOME_STACK_ID);
            synchronized (ActivityManagerService.this) {
                mStackSupervisor.notifyAppTransitionDone();
            }
        }
    }
@@ -21148,7 +21101,9 @@ public final class ActivityManagerService extends ActivityManagerNative
            // Will bring task to front if it already has a root activity.
            final long origId = Binder.clearCallingIdentity();
            try {
                startActivityFromRecentsInner(mTaskId, null);
                synchronized (this) {
                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
                }
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
Loading