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

Commit 990c1495 authored by Ben Lin's avatar Ben Lin
Browse files

Bring other Desktop apps to front when opening a new one.

This enables the launcher to bring all desktop apps to the front when
launching a new app. This is only enabled when Desktop Mode feature flag
is enabled and Shell transition is enabled.

Bug: None
Test: Manual, launch new apps from launcher
Change-Id: I5ae3941c7d27db3180ea6725a37868416b6649fb
parent f12d6c28
Loading
Loading
Loading
Loading
+45 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.wm.shell.desktopmode;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_OPEN;

import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
@@ -29,13 +30,18 @@ import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArraySet;
import android.view.SurfaceControl;
import android.window.DisplayAreaInfo;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction;

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

import com.android.internal.annotations.VisibleForTesting;
@@ -55,7 +61,8 @@ import java.util.Comparator;
/**
 * Handles windowing changes when desktop mode system setting changes
 */
public class DesktopModeController implements RemoteCallable<DesktopModeController> {
public class DesktopModeController implements RemoteCallable<DesktopModeController>,
        Transitions.TransitionHandler {

    private final Context mContext;
    private final ShellTaskOrganizer mShellTaskOrganizer;
@@ -89,6 +96,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
        if (DesktopModeStatus.isActive(mContext)) {
            updateDesktopModeActive(true);
        }
        mTransitions.addHandler(this);
    }

    @Override
@@ -157,7 +165,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
    /**
     * Show apps on desktop
     */
    public void showDesktopApps() {
    WindowContainerTransaction showDesktopApps() {
        ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks();
        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size());
        ArrayList<RunningTaskInfo> taskInfos = new ArrayList<>();
@@ -173,9 +181,14 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
        for (RunningTaskInfo task : taskInfos) {
            wct.reorder(task.token, true);
        }

        if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
            mShellTaskOrganizer.applyTransaction(wct);
        }

        return wct;
    }

    /**
     * Turn desktop mode on or off
     * @param active the desired state for desktop mode setting
@@ -195,6 +208,35 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
                .configuration.windowConfiguration.getWindowingMode();
    }

    @Override
    public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
            @NonNull SurfaceControl.Transaction startTransaction,
            @NonNull SurfaceControl.Transaction finishTransaction,
            @NonNull Transitions.TransitionFinishCallback finishCallback) {
        // This handler should never be the sole handler, so should not animate anything.
        return false;
    }

    @Nullable
    @Override
    public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request) {

        // Only do anything if we are in desktop mode and opening a task/app
        if (!DesktopModeStatus.isActive(mContext) || request.getType() != TRANSIT_OPEN) {
            return null;
        }

        WindowContainerTransaction wct = mTransitions.dispatchRequest(transition, request, this);
        if (wct == null) {
            wct = new WindowContainerTransaction();
        }
        wct.merge(showDesktopApps(), true /* transfer */);
        wct.reorder(request.getTriggerTask().token, true /* onTop */);

        return wct;
    }

    /**
     * A {@link ContentObserver} for listening to changes to {@link Settings.System#DESKTOP_MODE}
     */
+16 −0
Original line number Diff line number Diff line
@@ -542,6 +542,22 @@ public class Transitions implements RemoteCallable<Transitions> {
                "This shouldn't happen, maybe the default handler is broken.");
    }

    /**
     * Gives every handler (in order) a chance to handle request until one consumes the transition.
     * @return the WindowContainerTransaction given by the handler which consumed the transition.
     */
    public WindowContainerTransaction dispatchRequest(@NonNull IBinder transition,
            @NonNull TransitionRequestInfo request, @Nullable TransitionHandler skip) {
        for (int i = mHandlers.size() - 1; i >= 0; --i) {
            if (mHandlers.get(i) == skip) continue;
            WindowContainerTransaction wct = mHandlers.get(i).handleRequest(transition, request);
            if (wct != null) {
                return wct;
            }
        }
        return null;
    }

    /** Special version of finish just for dealing with no-op/invalid transitions. */
    private void onAbort(IBinder transition) {
        onFinish(transition, null /* wct */, null /* wctCB */, true /* abort */);