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

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20068761

Change-Id: Ica4f89cc7ede0c9b8b00e9f3bb64f9aabb05eff4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Ben Lin
2022-10-06 19:56:55 +00:00
committed by Automerger Merge Worker
2 changed files with 61 additions and 3 deletions

View File

@@ -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_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.TRANSIT_CHANGE; 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.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; 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.database.ContentObserver;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.util.ArraySet; import android.util.ArraySet;
import android.view.SurfaceControl;
import android.window.DisplayAreaInfo; import android.window.DisplayAreaInfo;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction;
import androidx.annotation.BinderThread; import androidx.annotation.BinderThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
@@ -55,7 +61,8 @@ import java.util.Comparator;
/** /**
* Handles windowing changes when desktop mode system setting changes * 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 Context mContext;
private final ShellTaskOrganizer mShellTaskOrganizer; private final ShellTaskOrganizer mShellTaskOrganizer;
@@ -89,6 +96,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
if (DesktopModeStatus.isActive(mContext)) { if (DesktopModeStatus.isActive(mContext)) {
updateDesktopModeActive(true); updateDesktopModeActive(true);
} }
mTransitions.addHandler(this);
} }
@Override @Override
@@ -157,7 +165,7 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
/** /**
* Show apps on desktop * Show apps on desktop
*/ */
public void showDesktopApps() { WindowContainerTransaction showDesktopApps() {
ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks(); ArraySet<Integer> activeTasks = mDesktopModeTaskRepository.getActiveTasks();
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size()); ProtoLog.d(WM_SHELL_DESKTOP_MODE, "bringDesktopAppsToFront: tasks=%s", activeTasks.size());
ArrayList<RunningTaskInfo> taskInfos = new ArrayList<>(); ArrayList<RunningTaskInfo> taskInfos = new ArrayList<>();
@@ -173,9 +181,14 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
for (RunningTaskInfo task : taskInfos) { for (RunningTaskInfo task : taskInfos) {
wct.reorder(task.token, true); wct.reorder(task.token, true);
} }
if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
mShellTaskOrganizer.applyTransaction(wct); mShellTaskOrganizer.applyTransaction(wct);
} }
return wct;
}
/** /**
* Turn desktop mode on or off * Turn desktop mode on or off
* @param active the desired state for desktop mode setting * @param active the desired state for desktop mode setting
@@ -195,6 +208,35 @@ public class DesktopModeController implements RemoteCallable<DesktopModeControll
.configuration.windowConfiguration.getWindowingMode(); .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} * A {@link ContentObserver} for listening to changes to {@link Settings.System#DESKTOP_MODE}
*/ */

View File

@@ -546,6 +546,22 @@ public class Transitions implements RemoteCallable<Transitions> {
"This shouldn't happen, maybe the default handler is broken."); "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. */ /** Special version of finish just for dealing with no-op/invalid transitions. */
private void onAbort(IBinder transition) { private void onAbort(IBinder transition) {
onFinish(transition, null /* wct */, null /* wctCB */, true /* abort */); onFinish(transition, null /* wct */, null /* wctCB */, true /* abort */);