Notify client side of window movement.
Add a one way method to notify Views that the window has moved
on the screen. Fixes issues arising from the IME popping up and
translating the window that uses it. Accessibility was left unaware
of these movements and was drawing the box around the wrong widgets.
Similarly PopupWindow used getLocationOnScreen to determine how
much screen real estate was above and below the anchor point to
determine where to put an anchored window.
Fixes bug 6623031.
Change-Id: I4731a94d5424c1ec77bf1729fba8fc9ea34cae46
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 3e0942c..3b26af7 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -98,6 +98,7 @@
private static final int MSG_WALLPAPER_OFFSETS = 10020;
private static final int MSG_WALLPAPER_COMMAND = 10025;
private static final int MSG_WINDOW_RESIZED = 10030;
+ private static final int MSG_WINDOW_MOVED = 10035;
private static final int MSG_TOUCH_EVENT = 10040;
private Looper mCallbackLooper;
@@ -259,7 +260,13 @@
reportDraw ? 1 : 0);
mCaller.sendMessage(msg);
}
-
+
+ @Override
+ public void moved(int newX, int newY) {
+ Message msg = mCaller.obtainMessageII(MSG_WINDOW_MOVED, newX, newY);
+ mCaller.sendMessage(msg);
+ }
+
@Override
public void dispatchAppVisibility(boolean visible) {
// We don't do this in preview mode; we'll let the preview
@@ -290,7 +297,8 @@
}
}
}
-
+
+ @Override
public void dispatchWallpaperCommand(String action, int x, int y,
int z, Bundle extras, boolean sync) {
synchronized (mLock) {
@@ -1044,6 +1052,9 @@
mEngine.updateSurface(true, false, reportDraw);
mEngine.doOffsetsChanged(true);
} break;
+ case MSG_WINDOW_MOVED: {
+ // Do nothing. What does it mean for a Wallpaper to move?
+ } break;
case MSG_TOUCH_EVENT: {
boolean skip = false;
MotionEvent ev = (MotionEvent)message.obj;
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index b4caad3..9f22870 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -47,6 +47,7 @@
void resized(int w, int h, in Rect contentInsets,
in Rect visibleInsets, boolean reportDraw, in Configuration newConfig);
+ void moved(int newX, int newY);
void dispatchAppVisibility(boolean visible);
void dispatchGetNewSurface();
void dispatchScreenState(boolean on);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a6a5427..e7f4cc5 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4891,9 +4891,9 @@
* @hide
*/
public int getActualAndReportedWindowLeftDelta() {
- if (mAttachInfo != null) {
- return mAttachInfo.mActualWindowLeft - mAttachInfo.mWindowLeft;
- }
+// if (mAttachInfo != null) {
+// return mAttachInfo.mActualWindowLeft - mAttachInfo.mWindowLeft;
+// }
return 0;
}
@@ -4903,9 +4903,9 @@
* @hide
*/
public int getActualAndReportedWindowTopDelta() {
- if (mAttachInfo != null) {
- return mAttachInfo.mActualWindowTop - mAttachInfo.mWindowTop;
- }
+// if (mAttachInfo != null) {
+// return mAttachInfo.mActualWindowTop - mAttachInfo.mWindowTop;
+// }
return 0;
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 17783a4..97488bc 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2724,6 +2724,7 @@
private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 22;
private final static int MSG_DISPATCH_DONE_ANIMATING = 23;
private final static int MSG_INVALIDATE_WORLD = 24;
+ private final static int MSG_WINDOW_MOVED = 25;
final class ViewRootHandler extends Handler {
@Override
@@ -2775,6 +2776,8 @@
return "MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST";
case MSG_DISPATCH_DONE_ANIMATING:
return "MSG_DISPATCH_DONE_ANIMATING";
+ case MSG_WINDOW_MOVED:
+ return "MSG_WINDOW_MOVED";
}
return super.getMessageName(message);
}
@@ -2819,6 +2822,7 @@
if (config != null) {
updateConfiguration(config, false);
}
+ // TODO: Should left/top stay unchanged and only change the right/bottom?
mWinFrame.left = 0;
mWinFrame.right = msg.arg1;
mWinFrame.top = 0;
@@ -2835,6 +2839,23 @@
requestLayout();
}
break;
+ case MSG_WINDOW_MOVED:
+ if (mAdded) {
+ final int w = mWinFrame.width();
+ final int h = mWinFrame.height();
+ final int l = msg.arg1;
+ final int t = msg.arg2;
+ mWinFrame.left = l;
+ mWinFrame.right = l + w;
+ mWinFrame.top = t;
+ mWinFrame.bottom = t + h;
+
+ if (mView != null) {
+ forceLayout(mView);
+ }
+ requestLayout();
+ }
+ break;
case MSG_WINDOW_FOCUS_CHANGED: {
if (mAdded) {
boolean hasWindowFocus = msg.arg1 != 0;
@@ -4054,6 +4075,18 @@
mHandler.sendMessage(msg);
}
+ public void dispatchMoved(int newX, int newY) {
+ if (DEBUG_LAYOUT) Log.v(TAG, "Window moved " + this + ": newX=" + newX + " newY=" + newY);
+ if (mTranslator != null) {
+ PointF point = new PointF(newX, newY);
+ mTranslator.translatePointInScreenToAppWindow(point);
+ newX = (int) (point.x + 0.5);
+ newY = (int) (point.y + 0.5);
+ }
+ Message msg = mHandler.obtainMessage(MSG_WINDOW_MOVED, newX, newY);
+ mHandler.sendMessage(msg);
+ }
+
/**
* Represents a pending input event that is waiting in a queue.
*
@@ -4693,6 +4726,14 @@
}
}
+ @Override
+ public void moved(int newX, int newY) {
+ final ViewRootImpl viewAncestor = mViewAncestor.get();
+ if (viewAncestor != null) {
+ viewAncestor.dispatchMoved(newX, newY);
+ }
+ }
+
public void dispatchAppVisibility(boolean visible) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 4c34d73..ac1d594 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -28,11 +28,12 @@
public class BaseIWindow extends IWindow.Stub {
private IWindowSession mSession;
public int mSeq;
-
+
public void setSession(IWindowSession session) {
mSession = session;
}
-
+
+ @Override
public void resized(int w, int h, Rect contentInsets,
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
if (reportDraw) {
@@ -43,24 +44,35 @@
}
}
+ @Override
+ public void moved(int newX, int newY) {
+ }
+
+ @Override
public void dispatchAppVisibility(boolean visible) {
}
+ @Override
public void dispatchGetNewSurface() {
}
+ @Override
public void dispatchScreenState(boolean on) {
}
+ @Override
public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
}
+ @Override
public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
}
-
+
+ @Override
public void closeSystemDialogs(String reason) {
}
-
+
+ @Override
public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep, boolean sync) {
if (sync) {
try {
@@ -70,14 +82,17 @@
}
}
+ @Override
public void dispatchDragEvent(DragEvent event) {
}
+ @Override
public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
int localValue, int localChanges) {
mSeq = seq;
}
+ @Override
public void dispatchWallpaperCommand(String action, int x, int y,
int z, Bundle extras, boolean sync) {
if (sync) {
@@ -88,6 +103,7 @@
}
}
+ @Override
public void doneAnimating() {
}
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 4ef5fd6..bd32dc5 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -8591,6 +8591,10 @@
winAnimator.setAnimation(a);
winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+ try {
+ w.mClient.moved(w.mFrame.left, w.mFrame.top);
+ } catch (RemoteException e) {
+ }
}
//Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");