Resizing docked stack by dragging dock divider.
Change-Id: Icc9df00446780f8cd81df4654ace07f33346e901
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index ad207d4..8c5d319 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.ActivityManager.DOCKED_STACK_ID;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
@@ -23,11 +24,19 @@
import static android.view.WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static com.android.server.wm.TaskStack.DOCKED_BOTTOM;
+import static com.android.server.wm.TaskStack.DOCKED_INVALID;
+import static com.android.server.wm.TaskStack.DOCKED_LEFT;
+import static com.android.server.wm.TaskStack.DOCKED_RIGHT;
+import static com.android.server.wm.TaskStack.DOCKED_TOP;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.os.RemoteException;
+import android.util.Slog;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
@@ -35,13 +44,20 @@
/**
* Controls showing and hiding of a docked stack divider on the display.
*/
-public class DockedStackDividerController {
+public class DockedStackDividerController implements View.OnTouchListener {
private static final String TAG = "DockedStackDivider";
private final Context mContext;
private final int mDividerWidth;
private final DisplayContent mDisplayContent;
private View mView;
private Rect mTmpRect = new Rect();
+ private Rect mLastResizeRect = new Rect();
+ private int mStartX;
+ private int mStartY;
+ private TaskStack mTaskStack;
+ private Rect mOriginalRect = new Rect();
+ private int mDockSide;
+
DockedStackDividerController(Context context, DisplayContent displayContent) {
mContext = context;
@@ -53,6 +69,7 @@
private void addDivider() {
View view = LayoutInflater.from(mContext).inflate(
com.android.internal.R.layout.docked_stack_divider, null);
+ view.setOnTouchListener(this);
WindowManagerGlobal manager = WindowManagerGlobal.getInstance();
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
mDividerWidth, MATCH_PARENT, TYPE_DOCK_DIVIDER,
@@ -65,6 +82,7 @@
}
private void removeDivider() {
+ mView.setOnTouchListener(null);
WindowManagerGlobal manager = WindowManagerGlobal.getInstance();
manager.removeView(mView, true /* immediate */);
mView = null;
@@ -75,7 +93,7 @@
}
void update() {
- TaskStack stack = mDisplayContent.getDockedStack();
+ TaskStack stack = mDisplayContent.getDockedStackLocked();
if (stack != null && mView == null) {
addDivider();
} else if (stack == null && mView != null) {
@@ -87,9 +105,8 @@
return mDividerWidth;
}
-
void positionDockedStackedDivider(Rect frame) {
- TaskStack stack = mDisplayContent.getDockedStack();
+ TaskStack stack = mDisplayContent.getDockedStackLocked();
if (stack == null) {
// Unfortunately we might end up with still having a divider, even though the underlying
// stack was already removed. This is because we are on AM thread and the removal of the
@@ -99,19 +116,84 @@
final @TaskStack.DockSide int side = stack.getDockSide();
stack.getBounds(mTmpRect);
switch (side) {
- case TaskStack.DOCKED_LEFT:
+ case DOCKED_LEFT:
frame.set(mTmpRect.right, frame.top, mTmpRect.right + frame.width(), frame.bottom);
break;
- case TaskStack.DOCKED_TOP:
+ case DOCKED_TOP:
frame.set(frame.left, mTmpRect.bottom, mTmpRect.right,
mTmpRect.bottom + frame.height());
break;
- case TaskStack.DOCKED_RIGHT:
+ case DOCKED_RIGHT:
frame.set(mTmpRect.left - frame.width(), frame.top, mTmpRect.left, frame.bottom);
break;
- case TaskStack.DOCKED_BOTTOM:
+ case DOCKED_BOTTOM:
frame.set(frame.left, mTmpRect.top - frame.height(), frame.right, mTmpRect.top);
break;
}
}
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ final int action = event.getAction() & MotionEvent.ACTION_MASK;
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ // We use raw values, because getX/Y() would give us results relative to the
+ // dock divider bounds.
+ mStartX = (int) event.getRawX();
+ mStartY = (int) event.getRawY();
+ synchronized (mDisplayContent.mService.mWindowMap) {
+ mTaskStack = mDisplayContent.getDockedStackLocked();
+ mTaskStack.getBounds(mOriginalRect);
+ mDockSide = mTaskStack.getDockSide();
+ }
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (mTaskStack != null) {
+ resizeStack(event);
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mTaskStack = null;
+ mDockSide = TaskStack.DOCKED_INVALID;
+ break;
+ }
+ return true;
+ }
+
+ private void resizeStack(MotionEvent event) {
+ mTmpRect.set(mOriginalRect);
+ final int deltaX = (int) event.getRawX() - mStartX;
+ final int deltaY = (int) event.getRawY() - mStartY;
+ switch (mDockSide) {
+ case DOCKED_LEFT:
+ mTmpRect.right += deltaX;
+ break;
+ case DOCKED_TOP:
+ mTmpRect.bottom += deltaY;
+ break;
+ case DOCKED_RIGHT:
+ mTmpRect.left += deltaX;
+ break;
+ case DOCKED_BOTTOM:
+ mTmpRect.top += deltaY;
+ break;
+ }
+ if (mTmpRect.equals(mLastResizeRect)) {
+ return;
+ }
+ mLastResizeRect.set(mTmpRect);
+ try {
+ mDisplayContent.mService.mActivityManager.resizeStack(DOCKED_STACK_ID, mTmpRect);
+ } catch (RemoteException e) {
+ }
+ }
+
+ boolean isResizing() {
+ return mTaskStack != null;
+ }
+
+ int getWidthAdjustment() {
+ return getWidth() / 2;
+ }
}