diff options
7 files changed, 121 insertions, 35 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index eeae20fa1ccf..9ef51c8554d3 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -452,6 +452,22 @@ public class ActivityManager {       */      public static final int FIRST_DYNAMIC_STACK_ID = LAST_STATIC_STACK_ID + 1; +    /** +     * Input parameter to {@link android.app.IActivityManager#moveTaskToDockedStack} which +     * specifies the position of the created docked stack at the top half of the screen if +     * in portrait mode or at the left half of the screen if in landscape mode. +     * @hide +     */ +    public static final int DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT = 0; + +    /** +     * Input parameter to {@link android.app.IActivityManager#moveTaskToDockedStack} which +     * specifies the position of the created docked stack at the bottom half of the screen if +     * in portrait mode or at the right half of the screen if in landscape mode. +     * @hide +     */ +    public static final int DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT = 1; +      /** @hide */      public int getFrontActivityScreenCompatMode() {          try { diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index d1c73bc945ff..d79716cb03e8 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -743,6 +743,16 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM              return true;          } +        case MOVE_TASK_TO_DOCKED_STACK_TRANSACTION: { +            data.enforceInterface(IActivityManager.descriptor); +            int taskId = data.readInt(); +            int createMode = data.readInt(); +            boolean toTop = data.readInt() != 0; +            moveTaskToDockedStack(taskId, createMode, toTop); +            reply.writeNoException(); +            return true; +        } +          case RESIZE_STACK_TRANSACTION: {              data.enforceInterface(IActivityManager.descriptor);              int stackId = data.readInt(); @@ -3510,6 +3520,21 @@ class ActivityManagerProxy implements IActivityManager          reply.recycle();      }      @Override +    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop) +            throws RemoteException +    { +        Parcel data = Parcel.obtain(); +        Parcel reply = Parcel.obtain(); +        data.writeInterfaceToken(IActivityManager.descriptor); +        data.writeInt(taskId); +        data.writeInt(createMode); +        data.writeInt(toTop ? 1 : 0); +        mRemote.transact(MOVE_TASK_TO_DOCKED_STACK_TRANSACTION, data, reply, 0); +        reply.readException(); +        data.recycle(); +        reply.recycle(); +    } +    @Override      public void resizeStack(int stackId, Rect r) throws RemoteException      {          Parcel data = Parcel.obtain(); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 66fa79639256..3b30d71cde70 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -140,6 +140,8 @@ public interface IActivityManager extends IInterface {      public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException;      public void moveTaskBackwards(int task) throws RemoteException;      public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException; +    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop) +            throws RemoteException;      public void resizeStack(int stackId, Rect bounds) throws RemoteException;      public void positionTaskInStack(int taskId, int stackId, int position) throws RemoteException;      public List<StackInfo> getAllStackInfos() throws RemoteException; @@ -888,4 +890,5 @@ public interface IActivityManager extends IInterface {      int GET_ACTIVITY_STACK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 343;      int MOVE_ACTIVITY_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 344;      int REPORT_SIZE_CONFIGURATIONS = IBinder.FIRST_CALL_TRANSACTION + 345; +    int MOVE_TASK_TO_DOCKED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 346;  } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 14376d1bdb80..dc6f3d69d366 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -19,7 +19,6 @@ package com.android.server.am;  import static android.Manifest.permission.INTERACT_ACROSS_USERS;  import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;  import static android.Manifest.permission.START_TASKS_FROM_RECENTS; -import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;  import static android.app.ActivityManager.DOCKED_STACK_ID;  import static android.app.ActivityManager.HOME_STACK_ID;  import static android.app.ActivityManager.INVALID_STACK_ID; @@ -215,7 +214,6 @@ import android.os.ServiceManager;  import android.os.StrictMode;  import android.os.SystemClock;  import android.os.SystemProperties; -import android.os.Trace;  import android.os.UpdateLock;  import android.os.UserHandle;  import android.os.UserManager; @@ -9053,6 +9051,35 @@ public final class ActivityManagerService extends ActivityManagerNative          }      } +    /** +     * Moves the input task to the docked stack. +     * +     * @param taskId Id of task to move. +     * @param createMode The mode the docked stack should be created in if it doesn't exist +     *                   already. See +     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT} +     *                   and +     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT} +     * @param toTop If the task and stack should be moved to the top. +     */ +    @Override +    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop) { +        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, +                "moveTaskToDockedStack()"); +        synchronized (this) { +            long ident = Binder.clearCallingIdentity(); +            try { +                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId +                        + " to createMode=" + createMode + " toTop=" + toTop); +                mWindowManager.setDockedStackCreateMode(createMode); +                mStackSupervisor.moveTaskToStackLocked( +                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS); +            } finally { +                Binder.restoreCallingIdentity(ident); +            } +        } +    } +      @Override      public void resizeStack(int stackId, Rect bounds) {          enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java index 7901bee92120..876e9aaa7db6 100644 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ b/services/core/java/com/android/server/wm/TaskPositioner.java @@ -16,8 +16,9 @@  package com.android.server.wm; +import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT; +import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;  import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID; -import static android.app.ActivityManager.DOCKED_STACK_ID;  import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;  import static com.android.server.wm.WindowManagerService.DEBUG_TASK_POSITIONING;  import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS; @@ -154,8 +155,11 @@ class TaskPositioner implements DimLayer.DimLayerUser {                      // event handler for the last finishInputEvent()!                      mService.mH.sendEmptyMessage(H.FINISH_TASK_POSITIONING);                      if (mCurrentDimSide != CTRL_NONE) { -                        mService.mActivityManager.moveTaskToStack( -                                mTaskId, DOCKED_STACK_ID, true /*toTop*/); +                        final int createMode = mCurrentDimSide == CTRL_LEFT +                                ? DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT +                                : DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT; +                        mService.mActivityManager.moveTaskToDockedStack( +                                mTaskId, createMode, true /*toTop*/);                      }                  }                  handled = true; diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index ae3bb9b20b04..1e6fab600594 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -353,11 +353,13 @@ public class TaskStack implements DimLayer.DimLayerUser {      private static void getInitialDockedStackBounds(              Rect displayRect, Rect outBounds, int stackId) {          // Docked stack start off occupying half the screen space. -        // TODO(multi-window): Need to support the selecting which half of the screen the -        // docked stack uses for snapping windows to the edge of the screen.          final boolean splitHorizontally = displayRect.width() > displayRect.height(); +        final boolean topOrLeftCreateMode = +                WindowManagerService.sDockedStackCreateMode == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; +        final boolean placeTopOrLeft = (stackId == DOCKED_STACK_ID && topOrLeftCreateMode) +                || (stackId != DOCKED_STACK_ID && !topOrLeftCreateMode);          outBounds.set(displayRect); -        if (stackId == DOCKED_STACK_ID) { +        if (placeTopOrLeft) {              if (splitHorizontally) {                  outBounds.right = displayRect.centerX();              } else { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 69440b883d00..8719ddb8186c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -16,6 +16,34 @@  package com.android.server.wm; +import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; +import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; +import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; +import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; +import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; +import static android.view.WindowManager.LayoutParams.FLAG_SECURE; +import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; +import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; +import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; +import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; +import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS; +import static android.view.WindowManager.LayoutParams.TYPE_DREAM; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; +import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; +import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; +import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; +import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; +import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; + +import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH; +  import android.Manifest;  import android.animation.ValueAnimator;  import android.app.ActivityManagerNative; @@ -110,9 +138,7 @@ import android.view.WindowManagerPolicy;  import android.view.WindowManagerPolicy.PointerEventListener;  import android.view.animation.Animation; -import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;  import com.android.internal.app.IAssistScreenshotReceiver; -import com.android.internal.app.IBatteryStats;  import com.android.internal.util.FastPrintWriter;  import com.android.internal.view.IInputContext;  import com.android.internal.view.IInputMethodClient; @@ -149,31 +175,6 @@ import java.util.HashMap;  import java.util.Iterator;  import java.util.List; -import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; -import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; -import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; -import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; -import static android.view.WindowManager.LayoutParams.FLAG_SECURE; -import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; -import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; -import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; -import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; -import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; -import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; -import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS; -import static android.view.WindowManager.LayoutParams.TYPE_DREAM; -import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; -import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; -import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION; -import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; -import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; -import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; -import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; -  /** {@hide} */  public class WindowManagerService extends IWindowManager.Stub          implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs { @@ -458,6 +459,8 @@ public class WindowManagerService extends IWindowManager.Stub      private boolean mKeyguardWaitingForActivityDrawn; +    static int sDockedStackCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; +      class RotationWatcher {          IRotationWatcher watcher;          IBinder.DeathRecipient deathRecipient; @@ -4448,6 +4451,12 @@ public class WindowManagerService extends IWindowManager.Stub          }      } +    public void setDockedStackCreateMode(int mode) { +        synchronized (mWindowMap) { +            sDockedStackCreateMode = mode; +        } +    } +      /**       * Create a new TaskStack and place it on a DisplayContent.       * @param stackId The unique identifier of the new stack.  |