diff options
| author | 2015-09-14 12:54:50 -0700 | |
|---|---|---|
| committer | 2015-09-14 15:37:47 -0700 | |
| commit | 59a73ca331a786f95e08a99bbd16fbdf59280ae0 (patch) | |
| tree | bd8fbc6d39ecdf53f6d5ac7e315e06e090aaf4b1 | |
| parent | 228d40474dc74289e5796a28c8e4c0b1a7ead40c (diff) | |
Support creating docked stack at top/left/bottom/right half of screen
Change-Id: Id8d6f639ed67baadb856ce84a20af8929e04cb2e
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. |