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

Commit 031bb5d8 authored by Jeff Pierce's avatar Jeff Pierce
Browse files

Update the split screen APIs used by the launcher

Makes the following changes:
1. Adds a boolean visible parameter to the onTaskChanged method of
SplitScreenListener to allow the launcher to determine which task is
on top of a stage
2. Allows the launcher to specify a fill-in intent when asking to open
a PendingIntent on the main or side stages.
3. Allows the launcher to ask to remove a task from the side stage.

Bug: 179176511
Test: manually tested against the foldable taskbar launcher.
Change-Id: I9fa530f546af58779ccf71d0753d9b6d3479fd0b
parent 6d5cc398
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -234,8 +234,8 @@ public class DragAndDropPolicy {
            final UserHandle user = intent.getParcelableExtra(EXTRA_USER);
            mStarter.startShortcut(packageName, id, stage, position, opts, user);
        } else {
            mStarter.startIntent(intent.getParcelableExtra(EXTRA_PENDING_INTENT), stage, position,
                    opts);
            mStarter.startIntent(intent.getParcelableExtra(EXTRA_PENDING_INTENT),
                    mContext, null, stage, position, opts);
        }
    }

@@ -295,7 +295,8 @@ public class DragAndDropPolicy {
                @Nullable Bundle options);
        void startShortcut(String packageName, String shortcutId, @StageType int stage,
                @StagePosition int position, @Nullable Bundle options, UserHandle user);
        void startIntent(PendingIntent intent, @StageType int stage, @StagePosition int position,
        void startIntent(PendingIntent intent, Context context, Intent fillInIntent,
                @StageType int stage, @StagePosition int position,
                @Nullable Bundle options);
        void enterSplitScreen(int taskId, boolean leftOrTop);
        void exitSplitScreen();
@@ -336,10 +337,11 @@ public class DragAndDropPolicy {
        }

        @Override
        public void startIntent(PendingIntent intent, int stage, int position,
        public void startIntent(PendingIntent intent, Context context,
                @Nullable Intent fillInIntent, int stage, int position,
                @Nullable Bundle options) {
            try {
                intent.send(null, 0, null, null, null, null, options);
                intent.send(mContext, 0, fillInIntent, null, null, null, options);
            } catch (PendingIntent.CanceledException e) {
                Slog.e(TAG, "Failed to launch activity", e);
            }
+6 −6
Original line number Diff line number Diff line
@@ -19,18 +19,17 @@ package com.android.wm.shell.splitscreen;
import android.annotation.IntDef;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.UserHandle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.draganddrop.DragAndDropPolicy;

import java.io.PrintWriter;

/**
 * Interface to engage split-screen feature.
 * TODO: Figure out which of these are actually needed outside of the Shell
@@ -87,7 +86,7 @@ public interface SplitScreen extends DragAndDropPolicy.Starter {
    /** Callback interface for listening to changes in a split-screen stage. */
    interface SplitScreenListener {
        void onStagePositionChanged(@StageType int stage, @StagePosition int position);
        void onTaskStageChanged(int taskId, @StageType int stage);
        void onTaskStageChanged(int taskId, @StageType int stage, boolean visible);
    }

    /** @return {@code true} if split-screen is currently visible. */
@@ -118,6 +117,7 @@ public interface SplitScreen extends DragAndDropPolicy.Starter {
            @StageType int stage, @StagePosition int position, @Nullable Bundle options);
    void startShortcut(String packageName, String shortcutId, @StageType int stage,
            @StagePosition int position, @Nullable Bundle options, UserHandle user);
    void startIntent(PendingIntent intent,
            @StageType int stage, @StagePosition int position, @Nullable Bundle options);
    void startIntent(PendingIntent intent, Context context,
            @Nullable Intent fillInIntent, @StageType int stage,
            @StagePosition int position, @Nullable Bundle options);
}
+8 −5
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.graphics.Rect;
import android.os.Bundle;
@@ -171,12 +172,13 @@ public class SplitScreenController implements DragAndDropPolicy.Starter {
        }
    }

    public void startIntent(PendingIntent intent, @SplitScreen.StageType int stage,
    public void startIntent(PendingIntent intent, Context context,
            Intent fillInIntent, @SplitScreen.StageType int stage,
            @SplitScreen.StagePosition int position, @Nullable Bundle options) {
        options = resolveStartStage(stage, position, options);

        try {
            intent.send(null, 0, null, null, null, null, options);
            intent.send(context, 0, fillInIntent, null, null, null, options);
        } catch (PendingIntent.CanceledException e) {
            Slog.e(TAG, "Failed to launch activity", e);
        }
@@ -348,10 +350,11 @@ public class SplitScreenController implements DragAndDropPolicy.Starter {
        }

        @Override
        public void startIntent(PendingIntent intent, int stage, int position,
                @Nullable Bundle options) {
        public void startIntent(PendingIntent intent, Context context, Intent fillInIntent,
                int stage, int position, @Nullable Bundle options) {
            mMainExecutor.execute(() -> {
                SplitScreenController.this.startIntent(intent, stage, position, options);
                SplitScreenController.this.startIntent(intent, context, fillInIntent, stage,
                        position, options);
            });
        }
    }
+4 −4
Original line number Diff line number Diff line
@@ -225,7 +225,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
    }

    private void onStageChildTaskStatusChanged(
            StageListenerImpl stageListener, int taskId, boolean present) {
            StageListenerImpl stageListener, int taskId, boolean present, boolean visible) {

        int stage;
        if (present) {
@@ -236,7 +236,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
        }

        for (int i = mListeners.size() - 1; i >= 0; --i) {
            mListeners.get(i).onTaskStageChanged(taskId, stage);
            mListeners.get(i).onTaskStageChanged(taskId, stage, visible);
        }
    }

@@ -494,8 +494,8 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener,
        }

        @Override
        public void onChildTaskStatusChanged(int taskId, boolean present) {
            StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present);
        public void onChildTaskStatusChanged(int taskId, boolean present, boolean visible) {
            StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present, visible);
        }

        @Override
+8 −4
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
    public interface StageListenerCallbacks {
        void onRootTaskAppeared();
        void onStatusChanged(boolean visible, boolean hasChildren);
        void onChildTaskStatusChanged(int taskId, boolean present);
        void onChildTaskStatusChanged(int taskId, boolean present, boolean visible);
        void onRootTaskVanished();
    }
    private final StageListenerCallbacks mCallbacks;
@@ -88,7 +88,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
            mChildrenLeashes.put(taskId, leash);
            mChildrenTaskInfo.put(taskId, taskInfo);
            updateChildTaskSurface(taskInfo, leash, true /* firstAppeared */);
            mCallbacks.onChildTaskStatusChanged(taskId, true /* present */);
            mCallbacks.onChildTaskStatusChanged(taskId, true /* present */, taskInfo.isVisible);
        } else {
            throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
                    + "\n mRootTaskInfo: " + mRootTaskInfo);
@@ -105,6 +105,8 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
            mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);
            updateChildTaskSurface(
                    taskInfo, mChildrenLeashes.get(taskInfo.taskId), false /* firstAppeared */);
            mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */,
                    taskInfo.isVisible);
        } else {
            throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
                    + "\n mRootTaskInfo: " + mRootTaskInfo);
@@ -123,7 +125,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
            mChildrenTaskInfo.remove(taskId);
            mChildrenLeashes.remove(taskId);
            sendStatusChanged();
            mCallbacks.onChildTaskStatusChanged(taskId, false /* present */);
            mCallbacks.onChildTaskStatusChanged(taskId, false /* present */, taskInfo.isVisible);
        } else {
            throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo
                    + "\n mRootTaskInfo: " + mRootTaskInfo);
@@ -152,7 +154,9 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
    void onSplitScreenListenerRegistered(SplitScreen.SplitScreenListener listener,
            @SplitScreen.StageType int stage) {
        for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
            listener.onTaskStageChanged(mChildrenTaskInfo.keyAt(i), stage);
            int taskId = mChildrenTaskInfo.keyAt(i);
            listener.onTaskStageChanged(taskId, stage,
                    mChildrenTaskInfo.get(taskId).isVisible);
        }
    }

Loading