Loading core/java/android/view/IWindowSession.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -260,4 +260,6 @@ interface IWindowSession { * Returns true if the move started successfully; false otherwise. */ boolean startMovingTask(IWindow window, float startX, float startY); void updatePointerIcon(IWindow window); } core/java/android/view/View.java +7 −0 Original line number Diff line number Diff line Loading @@ -21581,6 +21581,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setPointerIcon(PointerIcon pointerIcon) { mPointerIcon = pointerIcon; if (mAttachInfo == null) { return; } try { mAttachInfo.mSession.updatePointerIcon(mAttachInfo.mWindow); } catch (RemoteException e) { } } /** services/core/java/com/android/server/wm/DragState.java +6 −85 Original line number Diff line number Diff line Loading @@ -378,7 +378,9 @@ class DragState { private void cleanUpDragLw() { broadcastDragEndedLw(); restorePointerIconLw(); if (isFromSource(InputDevice.SOURCE_MOUSE)) { mService.restorePointerIconLocked(mDisplay, mCurrentX, mCurrentY); } // stop intercepting input unregister(); Loading Loading @@ -416,7 +418,7 @@ class DragState { void notifyLocationLw(float x, float y) { // Tell the affected window WindowState touchedWin = getTouchedWinAtPointLw(x, y); WindowState touchedWin = mService.getTouchableWinAtPointLocked(mDisplay, x, y); if (touchedWin == null) { if (DEBUG_DRAG) Slog.d(TAG_WM, "No touched win at x=" + x + " y=" + y); return; Loading Loading @@ -461,10 +463,6 @@ class DragState { mTargetWindow = touchedWin; } WindowState getDropTargetWinLw(float x, float y) { return getTouchedWinAtPointLw(x, y); } // Tell the drop target about the data. Returns 'true' if we can immediately // dispatch the global drag-ended message, 'false' if we need to wait for a // result from the recipient. Loading Loading @@ -512,77 +510,17 @@ class DragState { return false; } // Find the visible, touch-deliverable window under the given point private WindowState getTouchedWinAtPointLw(float xf, float yf) { WindowState touchedWin = null; final int x = (int) xf; final int y = (int) yf; final WindowList windows = mService.getWindowListLocked(mDisplay); if (windows == null) { return null; } final int N = windows.size(); for (int i = N - 1; i >= 0; i--) { WindowState child = windows.get(i); final int flags = child.mAttrs.flags; if (!child.isVisibleLw()) { // not visible == don't tell about drags continue; } if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) { // not touchable == don't tell about drags continue; } child.getVisibleBounds(mTmpRect); if (!mTmpRect.contains(x, y)) { // outside of this window's activity stack == don't tell about drags continue; } child.getTouchableRegion(mTmpRegion); final int touchFlags = flags & (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); if (mTmpRegion.contains(x, y) || touchFlags == 0) { // Found it touchedWin = child; break; } } return touchedWin; } private static DragEvent obtainDragEvent(WindowState win, int action, float x, float y, Object localState, ClipDescription description, ClipData data, IDropPermissions dropPermissions, boolean result) { final float winX = translateToWindowX(win, x); final float winY = translateToWindowY(win, y); final float winX = win.translateToWindowX(x); final float winY = win.translateToWindowY(y); return DragEvent.obtain(action, winX, winY, localState, description, data, dropPermissions, result); } private static float translateToWindowX(WindowState win, float x) { float winX = x - win.mFrame.left; if (win.mEnforceSizeCompat) { winX *= win.mGlobalScale; } return winX; } private static float translateToWindowY(WindowState win, float y) { float winY = y - win.mFrame.top; if (win.mEnforceSizeCompat) { winY *= win.mGlobalScale; } return winY; } boolean stepAnimationLocked(long currentTimeMs) { if (mAnimation == null) { return false; Loading Loading @@ -638,21 +576,4 @@ class DragState { InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_GRAB); } } private void restorePointerIconLw() { if (isFromSource(InputDevice.SOURCE_MOUSE)) { WindowState touchWin = getTouchedWinAtPointLw(mCurrentX, mCurrentY); if (touchWin != null) { try { touchWin.mClient.updatePointerIcon( translateToWindowX(touchWin, mCurrentX), translateToWindowY(touchWin, mCurrentY)); return; } catch (RemoteException e) { Slog.w(TAG_WM, "unable to restore pointer icon"); } } InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_DEFAULT); } } } services/core/java/com/android/server/wm/Session.java +10 −0 Original line number Diff line number Diff line Loading @@ -528,6 +528,16 @@ final class Session extends IWindowSession.Stub } } @Override public void updatePointerIcon(IWindow window) { final long identity = Binder.clearCallingIdentity(); try { mService.updatePointerIcon(window); } finally { Binder.restoreCallingIdentity(identity); } } void windowAddedLocked() { if (mSurfaceSession == null) { if (WindowManagerService.localLOGV) Slog.v( Loading services/core/java/com/android/server/wm/WindowManagerService.java +128 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.graphics.Rect; import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerInternal; import android.hardware.input.InputManager; import android.net.Uri; import android.os.Binder; import android.os.Build; Loading Loading @@ -81,6 +82,7 @@ import android.view.Choreographer; import android.view.Display; import android.view.DisplayInfo; import android.view.Gravity; import android.view.PointerIcon; import android.view.IAppTransitionAnimationSpecsFuture; import android.view.IApplicationToken; import android.view.IDockedStackListener; Loading Loading @@ -466,6 +468,7 @@ public class WindowManagerService extends IWindowManager.Stub final float[] mTmpFloats = new float[9]; final Rect mTmpRect = new Rect(); final Rect mTmpRect2 = new Rect(); final Region mTmpRegion = new Region(); boolean mDisplayReady; boolean mSafeMode; Loading Loading @@ -758,7 +761,7 @@ public class WindowManagerService extends IWindowManager.Stub } private boolean completeDropLw(float x, float y) { WindowState dropTargetWin = mDragState.getDropTargetWinLw(x, y); WindowState dropTargetWin = getTouchableWinAtPointLocked(mDragState.mDisplay, x, y); DropPermissionsHandler dropPermissions = null; if (dropTargetWin != null && Loading Loading @@ -10170,6 +10173,7 @@ public class WindowManagerService extends IWindowManager.Stub if (displayId == Display.DEFAULT_DISPLAY) { displayContent.mTapDetector = new TaskTapPointerEventListener(this, displayContent); registerPointerEventListener(displayContent.mTapDetector); registerPointerEventListener(mMousePositionTracker); } return displayContent; Loading Loading @@ -10262,6 +10266,7 @@ public class WindowManagerService extends IWindowManager.Stub displayContent.close(); if (displayId == Display.DEFAULT_DISPLAY) { unregisterPointerEventListener(displayContent.mTapDetector); unregisterPointerEventListener(mMousePositionTracker); } } mAnimator.removeDisplayLocked(displayId); Loading Loading @@ -10461,6 +10466,128 @@ public class WindowManagerService extends IWindowManager.Stub } } /** * Find the visible, touch-deliverable window under the given point */ WindowState getTouchableWinAtPointLocked(Display display, float xf, float yf) { WindowState touchedWin = null; final int x = (int) xf; final int y = (int) yf; final WindowList windows = getWindowListLocked(display); if (windows == null) { return null; } final int N = windows.size(); for (int i = N - 1; i >= 0; i--) { WindowState child = windows.get(i); final int flags = child.mAttrs.flags; if (!child.isVisibleLw()) { continue; } if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) { continue; } child.getTouchableRegion(mTmpRegion); final int touchFlags = flags & (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); if (mTmpRegion.contains(x, y) || touchFlags == 0) { touchedWin = child; break; } } return touchedWin; } private MousePositionTracker mMousePositionTracker = new MousePositionTracker(); private static class MousePositionTracker implements PointerEventListener { private boolean mLatestEventWasMouse; private float mLatestMouseX; private float mLatestMouseY; void updatePosition(float x, float y) { synchronized (this) { mLatestEventWasMouse = true; mLatestMouseX = x; mLatestMouseY = y; } } @Override public void onPointerEvent(MotionEvent motionEvent) { if (motionEvent.isFromSource(InputDevice.SOURCE_MOUSE)) { updatePosition(motionEvent.getRawX(), motionEvent.getRawY()); } else { synchronized (this) { mLatestEventWasMouse = false; } } } }; void updatePointerIcon(IWindow client) { float mouseX, mouseY; synchronized(mMousePositionTracker) { if (!mMousePositionTracker.mLatestEventWasMouse) { return; } mouseX = mMousePositionTracker.mLatestMouseX; mouseY = mMousePositionTracker.mLatestMouseY; } synchronized (mWindowMap) { if (mDragState != null) { // Drag cursor overrides the app cursor. return; } WindowState callingWin = windowForClientLocked(null, client, false); if (callingWin == null) { Slog.w(TAG_WM, "Bad requesting window " + client); return; } final DisplayContent displayContent = callingWin.getDisplayContent(); if (displayContent == null) { return; } Display display = displayContent.getDisplay(); WindowState windowUnderPointer = getTouchableWinAtPointLocked(display, mouseX, mouseY); if (windowUnderPointer != callingWin) { return; } try { windowUnderPointer.mClient.updatePointerIcon( windowUnderPointer.translateToWindowX(mouseX), windowUnderPointer.translateToWindowY(mouseY)); } catch (RemoteException e) { Slog.w(TAG_WM, "unable to update pointer icon"); } } } void restorePointerIconLocked(Display display, float latestX, float latestY) { // Mouse position tracker has not been getting updates while dragging, update it now. mMousePositionTracker.updatePosition(latestX, latestY); WindowState windowUnderPointer = getTouchableWinAtPointLocked(display, latestX, latestY); if (windowUnderPointer != null) { try { windowUnderPointer.mClient.updatePointerIcon( windowUnderPointer.translateToWindowX(latestX), windowUnderPointer.translateToWindowY(latestY)); } catch (RemoteException e) { Slog.w(TAG_WM, "unable to restore pointer icon"); } } else { InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_DEFAULT); } } private final class LocalService extends WindowManagerInternal { @Override public void requestTraversalFromDisplayManager() { Loading Loading
core/java/android/view/IWindowSession.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -260,4 +260,6 @@ interface IWindowSession { * Returns true if the move started successfully; false otherwise. */ boolean startMovingTask(IWindow window, float startX, float startY); void updatePointerIcon(IWindow window); }
core/java/android/view/View.java +7 −0 Original line number Diff line number Diff line Loading @@ -21581,6 +21581,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setPointerIcon(PointerIcon pointerIcon) { mPointerIcon = pointerIcon; if (mAttachInfo == null) { return; } try { mAttachInfo.mSession.updatePointerIcon(mAttachInfo.mWindow); } catch (RemoteException e) { } } /**
services/core/java/com/android/server/wm/DragState.java +6 −85 Original line number Diff line number Diff line Loading @@ -378,7 +378,9 @@ class DragState { private void cleanUpDragLw() { broadcastDragEndedLw(); restorePointerIconLw(); if (isFromSource(InputDevice.SOURCE_MOUSE)) { mService.restorePointerIconLocked(mDisplay, mCurrentX, mCurrentY); } // stop intercepting input unregister(); Loading Loading @@ -416,7 +418,7 @@ class DragState { void notifyLocationLw(float x, float y) { // Tell the affected window WindowState touchedWin = getTouchedWinAtPointLw(x, y); WindowState touchedWin = mService.getTouchableWinAtPointLocked(mDisplay, x, y); if (touchedWin == null) { if (DEBUG_DRAG) Slog.d(TAG_WM, "No touched win at x=" + x + " y=" + y); return; Loading Loading @@ -461,10 +463,6 @@ class DragState { mTargetWindow = touchedWin; } WindowState getDropTargetWinLw(float x, float y) { return getTouchedWinAtPointLw(x, y); } // Tell the drop target about the data. Returns 'true' if we can immediately // dispatch the global drag-ended message, 'false' if we need to wait for a // result from the recipient. Loading Loading @@ -512,77 +510,17 @@ class DragState { return false; } // Find the visible, touch-deliverable window under the given point private WindowState getTouchedWinAtPointLw(float xf, float yf) { WindowState touchedWin = null; final int x = (int) xf; final int y = (int) yf; final WindowList windows = mService.getWindowListLocked(mDisplay); if (windows == null) { return null; } final int N = windows.size(); for (int i = N - 1; i >= 0; i--) { WindowState child = windows.get(i); final int flags = child.mAttrs.flags; if (!child.isVisibleLw()) { // not visible == don't tell about drags continue; } if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) { // not touchable == don't tell about drags continue; } child.getVisibleBounds(mTmpRect); if (!mTmpRect.contains(x, y)) { // outside of this window's activity stack == don't tell about drags continue; } child.getTouchableRegion(mTmpRegion); final int touchFlags = flags & (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); if (mTmpRegion.contains(x, y) || touchFlags == 0) { // Found it touchedWin = child; break; } } return touchedWin; } private static DragEvent obtainDragEvent(WindowState win, int action, float x, float y, Object localState, ClipDescription description, ClipData data, IDropPermissions dropPermissions, boolean result) { final float winX = translateToWindowX(win, x); final float winY = translateToWindowY(win, y); final float winX = win.translateToWindowX(x); final float winY = win.translateToWindowY(y); return DragEvent.obtain(action, winX, winY, localState, description, data, dropPermissions, result); } private static float translateToWindowX(WindowState win, float x) { float winX = x - win.mFrame.left; if (win.mEnforceSizeCompat) { winX *= win.mGlobalScale; } return winX; } private static float translateToWindowY(WindowState win, float y) { float winY = y - win.mFrame.top; if (win.mEnforceSizeCompat) { winY *= win.mGlobalScale; } return winY; } boolean stepAnimationLocked(long currentTimeMs) { if (mAnimation == null) { return false; Loading Loading @@ -638,21 +576,4 @@ class DragState { InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_GRAB); } } private void restorePointerIconLw() { if (isFromSource(InputDevice.SOURCE_MOUSE)) { WindowState touchWin = getTouchedWinAtPointLw(mCurrentX, mCurrentY); if (touchWin != null) { try { touchWin.mClient.updatePointerIcon( translateToWindowX(touchWin, mCurrentX), translateToWindowY(touchWin, mCurrentY)); return; } catch (RemoteException e) { Slog.w(TAG_WM, "unable to restore pointer icon"); } } InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_DEFAULT); } } }
services/core/java/com/android/server/wm/Session.java +10 −0 Original line number Diff line number Diff line Loading @@ -528,6 +528,16 @@ final class Session extends IWindowSession.Stub } } @Override public void updatePointerIcon(IWindow window) { final long identity = Binder.clearCallingIdentity(); try { mService.updatePointerIcon(window); } finally { Binder.restoreCallingIdentity(identity); } } void windowAddedLocked() { if (mSurfaceSession == null) { if (WindowManagerService.localLOGV) Slog.v( Loading
services/core/java/com/android/server/wm/WindowManagerService.java +128 −1 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.graphics.Rect; import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerInternal; import android.hardware.input.InputManager; import android.net.Uri; import android.os.Binder; import android.os.Build; Loading Loading @@ -81,6 +82,7 @@ import android.view.Choreographer; import android.view.Display; import android.view.DisplayInfo; import android.view.Gravity; import android.view.PointerIcon; import android.view.IAppTransitionAnimationSpecsFuture; import android.view.IApplicationToken; import android.view.IDockedStackListener; Loading Loading @@ -466,6 +468,7 @@ public class WindowManagerService extends IWindowManager.Stub final float[] mTmpFloats = new float[9]; final Rect mTmpRect = new Rect(); final Rect mTmpRect2 = new Rect(); final Region mTmpRegion = new Region(); boolean mDisplayReady; boolean mSafeMode; Loading Loading @@ -758,7 +761,7 @@ public class WindowManagerService extends IWindowManager.Stub } private boolean completeDropLw(float x, float y) { WindowState dropTargetWin = mDragState.getDropTargetWinLw(x, y); WindowState dropTargetWin = getTouchableWinAtPointLocked(mDragState.mDisplay, x, y); DropPermissionsHandler dropPermissions = null; if (dropTargetWin != null && Loading Loading @@ -10170,6 +10173,7 @@ public class WindowManagerService extends IWindowManager.Stub if (displayId == Display.DEFAULT_DISPLAY) { displayContent.mTapDetector = new TaskTapPointerEventListener(this, displayContent); registerPointerEventListener(displayContent.mTapDetector); registerPointerEventListener(mMousePositionTracker); } return displayContent; Loading Loading @@ -10262,6 +10266,7 @@ public class WindowManagerService extends IWindowManager.Stub displayContent.close(); if (displayId == Display.DEFAULT_DISPLAY) { unregisterPointerEventListener(displayContent.mTapDetector); unregisterPointerEventListener(mMousePositionTracker); } } mAnimator.removeDisplayLocked(displayId); Loading Loading @@ -10461,6 +10466,128 @@ public class WindowManagerService extends IWindowManager.Stub } } /** * Find the visible, touch-deliverable window under the given point */ WindowState getTouchableWinAtPointLocked(Display display, float xf, float yf) { WindowState touchedWin = null; final int x = (int) xf; final int y = (int) yf; final WindowList windows = getWindowListLocked(display); if (windows == null) { return null; } final int N = windows.size(); for (int i = N - 1; i >= 0; i--) { WindowState child = windows.get(i); final int flags = child.mAttrs.flags; if (!child.isVisibleLw()) { continue; } if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) { continue; } child.getTouchableRegion(mTmpRegion); final int touchFlags = flags & (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); if (mTmpRegion.contains(x, y) || touchFlags == 0) { touchedWin = child; break; } } return touchedWin; } private MousePositionTracker mMousePositionTracker = new MousePositionTracker(); private static class MousePositionTracker implements PointerEventListener { private boolean mLatestEventWasMouse; private float mLatestMouseX; private float mLatestMouseY; void updatePosition(float x, float y) { synchronized (this) { mLatestEventWasMouse = true; mLatestMouseX = x; mLatestMouseY = y; } } @Override public void onPointerEvent(MotionEvent motionEvent) { if (motionEvent.isFromSource(InputDevice.SOURCE_MOUSE)) { updatePosition(motionEvent.getRawX(), motionEvent.getRawY()); } else { synchronized (this) { mLatestEventWasMouse = false; } } } }; void updatePointerIcon(IWindow client) { float mouseX, mouseY; synchronized(mMousePositionTracker) { if (!mMousePositionTracker.mLatestEventWasMouse) { return; } mouseX = mMousePositionTracker.mLatestMouseX; mouseY = mMousePositionTracker.mLatestMouseY; } synchronized (mWindowMap) { if (mDragState != null) { // Drag cursor overrides the app cursor. return; } WindowState callingWin = windowForClientLocked(null, client, false); if (callingWin == null) { Slog.w(TAG_WM, "Bad requesting window " + client); return; } final DisplayContent displayContent = callingWin.getDisplayContent(); if (displayContent == null) { return; } Display display = displayContent.getDisplay(); WindowState windowUnderPointer = getTouchableWinAtPointLocked(display, mouseX, mouseY); if (windowUnderPointer != callingWin) { return; } try { windowUnderPointer.mClient.updatePointerIcon( windowUnderPointer.translateToWindowX(mouseX), windowUnderPointer.translateToWindowY(mouseY)); } catch (RemoteException e) { Slog.w(TAG_WM, "unable to update pointer icon"); } } } void restorePointerIconLocked(Display display, float latestX, float latestY) { // Mouse position tracker has not been getting updates while dragging, update it now. mMousePositionTracker.updatePosition(latestX, latestY); WindowState windowUnderPointer = getTouchableWinAtPointLocked(display, latestX, latestY); if (windowUnderPointer != null) { try { windowUnderPointer.mClient.updatePointerIcon( windowUnderPointer.translateToWindowX(latestX), windowUnderPointer.translateToWindowY(latestY)); } catch (RemoteException e) { Slog.w(TAG_WM, "unable to restore pointer icon"); } } else { InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_DEFAULT); } } private final class LocalService extends WindowManagerInternal { @Override public void requestTraversalFromDisplayManager() { Loading