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

Commit 2624b192 authored by Eric Lin's avatar Eric Lin Committed by Android (Google) Code Review
Browse files

Merge "Refactor BubbleUtils with Kotlin extensions." into main

parents 135d3e90 598415b0
Loading
Loading
Loading
Loading
+8 −16
Original line number Diff line number Diff line
@@ -14,9 +14,6 @@
 * limitations under the License.
 */

// Exports bubble task utilities (e.g., `isBubbleToFullscreen`) for Java interop.
@file:JvmName("BubbleTaskUtils")

package com.android.wm.shell.bubbles

import android.app.ActivityManager
@@ -25,6 +22,7 @@ import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.bubbles.util.BubbleUtils.getExitBubbleTransaction
import com.android.wm.shell.bubbles.util.BubbleUtils.isBubbleToFullscreen
import com.android.wm.shell.bubbles.util.BubbleUtils.isBubbleToSplit
import com.android.wm.shell.common.TaskStackListenerCallback
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES_NOISY
@@ -63,9 +61,9 @@ class BubbleTaskStackListener(
            taskId)
        bubbleData.getBubbleInStackWithTaskId(taskId)?.let { bubble ->
            when {
                isBubbleToFullscreen(task) -> moveCollapsedInStackBubbleToFullscreen(bubble, task)
                isBubbleToSplit(task) -> return // skip split task restarts
                !isAppBubbleMovingToFront(task) -> selectAndExpandInStackBubble(bubble, task)
                task.isBubbleToFullscreen() -> moveCollapsedInStackBubbleToFullscreen(bubble, task)
                task.isBubbleToSplit(splitScreenController) -> return // skip split task restarts
                !task.isAppBubbleMovingToFront() -> selectAndExpandInStackBubble(bubble, task)
            }
        }
    }
@@ -78,15 +76,9 @@ class BubbleTaskStackListener(
            taskId)
        bubbleData.getBubbleInStackWithTaskId(taskId)?.let { bubble ->
            when {
                isBubbleToFullscreen(task) -> moveCollapsedInStackBubbleToFullscreen(bubble, task)
            }
                task.isBubbleToFullscreen() -> moveCollapsedInStackBubbleToFullscreen(bubble, task)
            }
        }

    private fun isBubbleToSplit(task: ActivityManager.RunningTaskInfo): Boolean {
        return task.hasParentTask() && splitScreenController.get()
            .map { it.isTaskRootOrStageRoot(task.parentTaskId) }
            .orElse(false)
    }

    /**
@@ -95,9 +87,9 @@ class BubbleTaskStackListener(
     * This occurs when a startActivity call resolves to an existing activity, causing the
     * task to move to front, and the mixed transition will then expand the bubble.
     */
    private fun isAppBubbleMovingToFront(task: ActivityManager.RunningTaskInfo): Boolean {
        return task.activityType == ACTIVITY_TYPE_STANDARD
                && bubbleController.shouldBeAppBubble(task)
    private fun ActivityManager.RunningTaskInfo?.isAppBubbleMovingToFront(): Boolean {
        return this?.activityType == ACTIVITY_TYPE_STANDARD
                && bubbleController.shouldBeAppBubble(this)
    }

    /** Selects and expands a bubble that is currently in the stack. */
+2 −1
Original line number Diff line number Diff line
@@ -108,7 +108,8 @@ class BubbleTaskView(val taskView: TaskView, executor: Executor) {
     * This should be called after all other cleanup animations have finished.
     */
    fun cleanup() {
        if (isBubbleToFullscreen(taskView.taskInfo)) {
        val task = taskView.taskInfo
        if (task.isBubbleToFullscreen()) {
            taskView.unregisterTask()
        } else {
            taskView.removeTask()
+11 −11
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID;

import static com.android.wm.shell.Flags.enableEnterSplitRemoveBubble;
import static com.android.wm.shell.bubbles.util.BubbleUtils.getExitBubbleTransaction;
import static com.android.wm.shell.bubbles.util.BubbleUtils.isBubbleToSplit;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES_NOISY;

import android.app.ActivityManager;
@@ -159,29 +160,28 @@ public class BubblesTransitionObserver implements Transitions.TransitionObserver

    private void removeBubbleIfLaunchingToSplit(@NonNull TransitionInfo info) {
        if (mSplitScreenController.get().isEmpty()) return;
        SplitScreenController splitScreenController = mSplitScreenController.get().get();
        for (TransitionInfo.Change change : info.getChanges()) {
            ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
        for (final TransitionInfo.Change change : info.getChanges()) {
            final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
            if (taskInfo == null) continue;
            Bubble bubble = mBubbleData.getBubbleInStackWithTaskId(taskInfo.taskId);
            final Bubble bubble = mBubbleData.getBubbleInStackWithTaskId(taskInfo.taskId);
            if (bubble == null) continue;
            if (!splitScreenController.isTaskRootOrStageRoot(taskInfo.parentTaskId)) continue;
            if (!isBubbleToSplit(taskInfo, mSplitScreenController)) continue;
            // There is a bubble task that is moving to split screen
            ProtoLog.d(WM_SHELL_BUBBLES_NOISY, "BubblesTransitionObserver.onTransitionReady(): "
                    + "removing bubble for task launching into split taskId=%d", taskInfo.taskId);
            TaskViewTaskController taskViewTaskController = bubble.getTaskView().getController();
            ShellTaskOrganizer taskOrganizer = taskViewTaskController.getTaskOrganizer();
            WindowContainerTransaction wct = getExitBubbleTransaction(taskInfo.token,
            final TaskViewTaskController controller = bubble.getTaskView().getController();
            final ShellTaskOrganizer taskOrganizer = controller.getTaskOrganizer();
            final WindowContainerTransaction wct = getExitBubbleTransaction(taskInfo.token,
                    bubble.getTaskView().getCaptionInsetsOwner());

            // Notify the task removal, but block all TaskViewTransitions during removal so we can
            // clear them without triggering
            final IBinder gate = new Binder();
            mTaskViewTransitions.enqueueExternal(taskViewTaskController, () -> gate);
            mTaskViewTransitions.enqueueExternal(controller, () -> gate);

            taskOrganizer.applyTransaction(wct);
            taskViewTaskController.notifyTaskRemovalStarted(taskInfo);
            mTaskViewTransitions.removePendingTransitions(taskViewTaskController);
            controller.notifyTaskRemovalStarted(taskInfo);
            mTaskViewTransitions.removePendingTransitions(controller);
            mTaskViewTransitions.onExternalDone(gate);
        }
    }
+18 −4
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@ import android.view.WindowInsets
import android.window.WindowContainerToken
import android.window.WindowContainerTransaction
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper
import com.android.wm.shell.splitscreen.SplitScreenController
import dagger.Lazy
import java.util.Optional

object BubbleUtils {

@@ -126,13 +129,24 @@ object BubbleUtils {

    /** Returns true if the task is valid for Bubble. */
    @JvmStatic
    fun isValidToBubble(taskInfo: ActivityManager.RunningTaskInfo?): Boolean {
        return taskInfo != null && taskInfo.supportsMultiWindow
    fun ActivityManager.RunningTaskInfo?.isValidToBubble(): Boolean {
        return this?.supportsMultiWindow == true
    }

    /** Determines if a bubble task is moving to fullscreen based on its windowing mode. */
    fun isBubbleToFullscreen(task: ActivityManager.RunningTaskInfo?): Boolean {
    @JvmStatic
    fun ActivityManager.RunningTaskInfo?.isBubbleToFullscreen(): Boolean {
        return BubbleAnythingFlagHelper.enableCreateAnyBubble()
                && task?.windowingMode == WINDOWING_MODE_FULLSCREEN
                && this?.windowingMode == WINDOWING_MODE_FULLSCREEN
    }

    /** Determines if a bubble task is moving to split-screen based on its parent task. */
    @JvmStatic
    fun ActivityManager.RunningTaskInfo?.isBubbleToSplit(
        splitScreenController: Lazy<Optional<SplitScreenController>>,
    ): Boolean {
        return this?.hasParentTask() == true && splitScreenController.get()
            .map { it.isTaskRootOrStageRoot(parentTaskId) }
            .orElse(false)
    }
}