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

Commit c13fc2d2 authored by Ben Lin's avatar Ben Lin Committed by Android (Google) Code Review
Browse files

Merge "Bring other Desktop apps to front when opening a new one." into tm-qpr-dev

parents 02c2b63b 990c1495
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
@@ -546,6 +546,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 */);