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

Commit 1b4e3f0e authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Add mechanism for a task to be hidden as a part of starting a drag" into main

parents 4395f03a b51bba4b
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -135,6 +135,14 @@ public class ClipDescription implements Parcelable {
    public static final String EXTRA_LOGGING_INSTANCE_ID =
            "android.intent.extra.LOGGING_INSTANCE_ID";

    /**
     * The id of the task containing the window that initiated the drag that should be hidden.
     * Only provided to internal drag handlers as a part of the DRAG_START event.
     * @hide
     */
    public static final String EXTRA_HIDE_DRAG_SOURCE_TASK_ID =
            "android.intent.extra.HIDE_DRAG_SOURCE_TASK_ID";

    /**
     * Indicates that a ClipData contains potentially sensitive information, such as a
     * password or credit card number.
+8 −0
Original line number Diff line number Diff line
@@ -5511,6 +5511,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    @FlaggedApi(FLAG_DELEGATE_UNHANDLED_DRAGS)
    public static final int DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG = 1 << 13;
    /**
     * Flag indicating that this drag will result in the caller activity's task to be hidden for the
     * duration of the drag, this means that the source activity will not receive drag events for
     * the current drag gesture. Only the current voice interaction service may use this flag.
     * @hide
     */
    public static final int DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START = 1 << 14;
    /**
     * Vertical scroll factor cached by {@link #getVerticalScrollFactor}.
     */
+16 −0
Original line number Diff line number Diff line
@@ -699,6 +699,22 @@ public class ShellTaskOrganizer extends TaskOrganizer {
        }
    }

    /**
     * Shows/hides the given task surface.  Not for general use as changing the task visibility may
     * conflict with other Transitions.  This is currently ONLY used to temporarily hide a task
     * while a drag is in session.
     */
    public void setTaskSurfaceVisibility(int taskId, boolean visible) {
        synchronized (mLock) {
            final TaskAppearedInfo info = mTasks.get(taskId);
            if (info != null) {
                SurfaceControl.Transaction t = new SurfaceControl.Transaction();
                t.setVisibility(info.getLeash(), visible);
                t.apply();
            }
        }
    }

    private boolean updateTaskListenerIfNeeded(RunningTaskInfo taskInfo, SurfaceControl leash,
            TaskListener oldListener, TaskListener newListener) {
        if (oldListener == newListener) return false;
+24 −1
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;

import androidx.annotation.BinderThread;
@@ -353,6 +354,12 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
                pd.dragSession.initialize();
                pd.activeDragCount++;
                pd.dragLayout.prepare(pd.dragSession, mLogger.logStart(pd.dragSession));
                if (pd.dragSession.hideDragSourceTaskId != -1) {
                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
                            "Hiding task surface: taskId=%d", pd.dragSession.hideDragSourceTaskId);
                    mShellTaskOrganizer.setTaskSurfaceVisibility(
                            pd.dragSession.hideDragSourceTaskId, false /* visible */);
                }
                setDropTargetWindowVisibility(pd, View.VISIBLE);
                notifyListeners(l -> {
                    l.onDragStarted();
@@ -382,6 +389,13 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
                if (pd.dragLayout.hasDropped()) {
                    mLogger.logDrop();
                } else {
                    if (pd.dragSession.hideDragSourceTaskId != -1) {
                        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
                                "Re-showing task surface: taskId=%d",
                                pd.dragSession.hideDragSourceTaskId);
                        mShellTaskOrganizer.setTaskSurfaceVisibility(
                                pd.dragSession.hideDragSourceTaskId, true /* visible */);
                    }
                    pd.activeDragCount--;
                    pd.dragLayout.hide(event, () -> {
                        if (pd.activeDragCount == 0) {
@@ -435,7 +449,16 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
    private boolean handleDrop(DragEvent event, PerDisplay pd) {
        final SurfaceControl dragSurface = event.getDragSurface();
        pd.activeDragCount--;
        return pd.dragLayout.drop(event, dragSurface, () -> {
        // Find the token of the task to hide as a part of entering split
        WindowContainerToken hideTaskToken = null;
        if (pd.dragSession.hideDragSourceTaskId != -1) {
            ActivityManager.RunningTaskInfo info = mShellTaskOrganizer.getRunningTaskInfo(
                    pd.dragSession.hideDragSourceTaskId);
            if (info != null) {
                hideTaskToken = info.token;
            }
        }
        return pd.dragLayout.drop(event, dragSurface, hideTaskToken, () -> {
            if (pd.activeDragCount == 0) {
                // Hide the window if another drag hasn't been started while animating the drop
                setDropTargetWindowVisibility(pd, View.INVISIBLE);
+36 −12
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
import android.window.WindowContainerToken;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
@@ -234,8 +235,13 @@ public class DragAndDropPolicy {
        return null;
    }

    /**
     * Handles the drop on a given {@param target}.  If a {@param hideTaskToken} is set, then the
     * handling of the drop will attempt to hide the given task as a part of the same window
     * container transaction if possible.
     */
    @VisibleForTesting
    void handleDrop(Target target) {
    void handleDrop(Target target, @Nullable WindowContainerToken hideTaskToken) {
        if (target == null || !mTargets.contains(target)) {
            return;
        }
@@ -254,16 +260,17 @@ public class DragAndDropPolicy {
                ? mFullscreenStarter
                : mSplitscreenStarter;
        if (mSession.appData != null) {
            launchApp(mSession, starter, position);
            launchApp(mSession, starter, position, hideTaskToken);
        } else {
            launchIntent(mSession, starter, position);
            launchIntent(mSession, starter, position, hideTaskToken);
        }
    }

    /**
     * Launches an app provided by SysUI.
     */
    private void launchApp(DragSession session, Starter starter, @SplitPosition int position) {
    private void launchApp(DragSession session, Starter starter, @SplitPosition int position,
            @Nullable WindowContainerToken hideTaskToken) {
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Launching app data at position=%d",
                position);
        final ClipDescription description = session.getClipDescription();
@@ -283,8 +290,12 @@ public class DragAndDropPolicy {

        if (isTask) {
            final int taskId = session.appData.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID);
            starter.startTask(taskId, position, opts);
            starter.startTask(taskId, position, opts, hideTaskToken);
        } else if (isShortcut) {
            if (hideTaskToken != null) {
                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
                        "Can not hide task token with starting shortcut");
            }
            final String packageName = session.appData.getStringExtra(EXTRA_PACKAGE_NAME);
            final String id = session.appData.getStringExtra(EXTRA_SHORTCUT_ID);
            starter.startShortcut(packageName, id, position, opts, user);
@@ -297,14 +308,15 @@ public class DragAndDropPolicy {
                }
            }
            starter.startIntent(launchIntent, user.getIdentifier(), null /* fillIntent */,
                    position, opts);
                    position, opts, hideTaskToken);
        }
    }

    /**
     * Launches an intent sender provided by an application.
     */
    private void launchIntent(DragSession session, Starter starter, @SplitPosition int position) {
    private void launchIntent(DragSession session, Starter starter, @SplitPosition int position,
            @Nullable WindowContainerToken hideTaskToken) {
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Launching intent at position=%d",
                position);
        final ActivityOptions baseActivityOpts = ActivityOptions.makeBasic();
@@ -319,18 +331,20 @@ public class DragAndDropPolicy {
        final Bundle opts = baseActivityOpts.toBundle();
        starter.startIntent(session.launchableIntent,
                session.launchableIntent.getCreatorUserHandle().getIdentifier(),
                null /* fillIntent */, position, opts);
                null /* fillIntent */, position, opts, hideTaskToken);
    }

    /**
     * Interface for actually committing the task launches.
     */
    public interface Starter {
        void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options);
        void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options,
                @Nullable WindowContainerToken hideTaskToken);
        void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
                @Nullable Bundle options, UserHandle user);
        void startIntent(PendingIntent intent, int userId, Intent fillInIntent,
                @SplitPosition int position, @Nullable Bundle options);
                @SplitPosition int position, @Nullable Bundle options,
                @Nullable WindowContainerToken hideTaskToken);
        void enterSplitScreen(int taskId, boolean leftOrTop);

        /**
@@ -352,7 +366,12 @@ public class DragAndDropPolicy {
        }

        @Override
        public void startTask(int taskId, int position, @Nullable Bundle options) {
        public void startTask(int taskId, int position, @Nullable Bundle options,
                @Nullable WindowContainerToken hideTaskToken) {
            if (hideTaskToken != null) {
                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
                        "Default starter does not support hide task token");
            }
            try {
                ActivityTaskManager.getService().startActivityFromRecents(taskId, options);
            } catch (RemoteException e) {
@@ -375,7 +394,12 @@ public class DragAndDropPolicy {

        @Override
        public void startIntent(PendingIntent intent, int userId, @Nullable Intent fillInIntent,
                int position, @Nullable Bundle options) {
                int position, @Nullable Bundle options,
                @Nullable WindowContainerToken hideTaskToken) {
            if (hideTaskToken != null) {
                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
                        "Default starter does not support hide task token");
            }
            try {
                intent.send(mContext, 0, fillInIntent, null, null, null, options);
            } catch (PendingIntent.CanceledException e) {
Loading