summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java4
-rw-r--r--services/core/java/com/android/server/wm/DockedStackDividerController.java98
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java22
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java15
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java18
6 files changed, 143 insertions, 21 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ede377de0b14..5c639330831b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -567,10 +567,10 @@ class DisplayContent {
return "Display " + mDisplayId + " info=" + mDisplayInfo + " stacks=" + mStacks;
}
- TaskStack getDockedStack() {
+ TaskStack getDockedStackLocked() {
for (int i = mStacks.size() - 1; i >= 0; i--) {
TaskStack stack = mStacks.get(i);
- if (stack.mStackId == DOCKED_STACK_ID) {
+ if (stack.mStackId == DOCKED_STACK_ID && stack.isVisibleLocked()) {
return stack;
}
}
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index ad207d4b8939..8c5d319439ba 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_SPLIT_TOUCH;
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 @@ import android.view.WindowManagerGlobal;
/**
* 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 @@ public class DockedStackDividerController {
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 @@ public class DockedStackDividerController {
}
private void removeDivider() {
+ mView.setOnTouchListener(null);
WindowManagerGlobal manager = WindowManagerGlobal.getInstance();
manager.removeView(mView, true /* immediate */);
mView = null;
@@ -75,7 +93,7 @@ public class DockedStackDividerController {
}
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 @@ public class DockedStackDividerController {
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 @@ public class DockedStackDividerController {
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;
+ }
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 4244205aabf8..6c391ade60cc 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
import android.app.ActivityManagerNative;
import android.graphics.Rect;
@@ -170,7 +171,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
private void addInputWindowHandleLw(final InputWindowHandle inputWindowHandle,
final WindowState child, int flags, final int type, final boolean isVisible,
- final boolean hasFocus, final boolean hasWallpaper) {
+ final boolean hasFocus, final boolean hasWallpaper, DisplayContent displayContent) {
// Add a window to our list of input windows.
inputWindowHandle.name = child.toString();
final boolean modal = (flags & (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
@@ -202,6 +203,20 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
inputWindowHandle.frameTop = frame.top;
inputWindowHandle.frameRight = frame.right;
inputWindowHandle.frameBottom = frame.bottom;
+ if (child.mAttrs.type == TYPE_DOCK_DIVIDER) {
+ // We need to determine if the divider is horizontal or vertical and adjust its handle
+ // frame accordingly.
+ int adjustment = displayContent.mDividerControllerLocked.getWidthAdjustment();
+ if (inputWindowHandle.frameRight - inputWindowHandle.frameLeft >
+ inputWindowHandle.frameTop - inputWindowHandle.frameBottom) {
+ // Horizontal divider.
+ inputWindowHandle.frameTop -= adjustment;
+ inputWindowHandle.frameBottom += adjustment;
+ } else {
+ inputWindowHandle.frameLeft -= adjustment;
+ inputWindowHandle.frameRight += adjustment;
+ }
+ }
if (child.mGlobalScale != 1) {
// If we are scaling the window, input coordinates need
@@ -277,7 +292,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
final int numDisplays = mService.mDisplayContents.size();
final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- WindowList windows = mService.mDisplayContents.valueAt(displayNdx).getWindowList();
+ final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
+ final WindowList windows = displayContent.getWindowList();
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
final WindowState child = windows.get(winNdx);
final InputChannel inputChannel = child.mInputChannel;
@@ -315,7 +331,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks {
}
addInputWindowHandleLw(inputWindowHandle, child, flags, type, isVisible, hasFocus,
- hasWallpaper);
+ hasWallpaper, displayContent);
}
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 96fcf93b5981..1d9126d06189 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -86,6 +86,7 @@ public class TaskStack implements DimLayer.DimLayerUser {
static final int DOCKED_TOP = 2;
static final int DOCKED_RIGHT = 3;
static final int DOCKED_BOTTOM = 4;
+
@IntDef({
DOCKED_INVALID,
DOCKED_LEFT,
@@ -353,7 +354,7 @@ public class TaskStack implements DimLayer.DimLayerUser {
bounds = new Rect();
displayContent.getLogicalDisplayRect(mTmpRect);
getInitialDockedStackBounds(mTmpRect, bounds, mStackId,
- mDisplayContent.mDividerControllerLocked.getWidth() / 2);
+ mDisplayContent.mDividerControllerLocked.getWidthAdjustment());
}
updateDisplayInfo(bounds);
@@ -566,4 +567,16 @@ public class TaskStack implements DimLayer.DimLayerUser {
return DOCKED_INVALID;
}
}
+
+ boolean isVisibleLocked() {
+ for (int i = mTasks.size() - 1; i >= 0; i--) {
+ Task task = mTasks.get(i);
+ for (int j = task.mAppTokens.size() - 1; j >= 0; j--) {
+ if (!task.mAppTokens.get(j).hidden) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 22f9f50fe6dd..8126a4706ce2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -24,6 +24,7 @@ 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.INPUT_FEATURE_NO_INPUT_CHANNEL;
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;
@@ -1894,13 +1895,13 @@ public class WindowManagerService extends IWindowManager.Stub
return res;
}
- if (outInputChannel != null && (attrs.inputFeatures
- & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
+ final boolean openInputChannels = (outInputChannel != null
+ && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
+ if (openInputChannels) {
String name = win.makeInputChannelName();
InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
win.setInputChannel(inputChannels[0]);
inputChannels[1].transferTo(outInputChannel);
-
mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c73dbaf607eb..d49e3a761c51 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -34,6 +34,7 @@ import static com.android.server.wm.WindowManagerService.DEBUG_POWER;
import static com.android.server.wm.WindowManagerService.DEBUG_RESIZE;
import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.os.PowerManager;
import android.os.RemoteCallbackList;
@@ -129,7 +130,6 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mAttachedHidden; // is our parent window hidden?
boolean mWallpaperVisible; // for wallpaper, what was last vis report?
boolean mDragResizing;
- boolean mDragResizeChanging;
RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks;
@@ -1701,13 +1701,23 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
boolean isDragResizeChanged() {
+ return mDragResizing != computeDragResizing();
+ }
+
+ private boolean computeDragResizing() {
final Task task = getTask();
- return task != null && mDragResizing != task.isDragResizing();
+ if (task == null) {
+ return false;
+ }
+ if (task.isDragResizing()) {
+ return true;
+ }
+ return mDisplayContent.mDividerControllerLocked.isResizing() &&
+ !task.inFreeformWorkspace() && !task.isFullscreen();
}
void setDragResizing() {
- final Task task = getTask();
- mDragResizing = task != null && task.isDragResizing();
+ mDragResizing = computeDragResizing();
}
boolean isDragResizing() {