diff options
author | Svetoslav Ganov <svetoslavganov@google.com> | 2012-10-15 15:09:02 -0700 |
---|---|---|
committer | Svetoslav Ganov <svetoslavganov@google.com> | 2012-10-16 11:11:39 -0700 |
commit | 55468c64bc4f3c4b16bf144f66907d75bb656b0a (patch) | |
tree | 0977cd195ff4c83b385c5e4973f2586fba1013c6 | |
parent | 7789c9bbfca079655e9285173d6175b94bc774b0 (diff) | |
download | frameworks_base-55468c64bc4f3c4b16bf144f66907d75bb656b0a.zip frameworks_base-55468c64bc4f3c4b16bf144f66907d75bb656b0a.tar.gz frameworks_base-55468c64bc4f3c4b16bf144f66907d75bb656b0a.tar.bz2 |
Occasionally triple tap on the keyboard toggles screen magnification.
1. Sometimes unlocking the device when the IME is up and triple tapping on the keyboard
toggles screen magnification. The core reason is that when the kayguard window is
shown we hide all other windows and when it is hidden we show these windows. We did
not notify the screen magnifier for windows being shown and hidden. Also when the
windows are shown we may reassign layers to put the IME or the wallpaper in the
right Z order. The screen magnifier is now notified upon such layer reassignment
since window layers are used when computing the magnified region.
bug:7351531
Change-Id: I0931f4ba6cfa565d8eb1e3c432268ba1818feea6
3 files changed, 61 insertions, 22 deletions
diff --git a/core/java/android/view/IDisplayContentChangeListener.aidl b/core/java/android/view/IDisplayContentChangeListener.aidl index 8f23ff6..ef7edea 100644 --- a/core/java/android/view/IDisplayContentChangeListener.aidl +++ b/core/java/android/view/IDisplayContentChangeListener.aidl @@ -28,5 +28,6 @@ import android.graphics.Rect; oneway interface IDisplayContentChangeListener { void onWindowTransition(int displayId, int transition, in WindowInfo info); void onRectangleOnScreenRequested(int displayId, in Rect rectangle, boolean immediate); + void onWindowLayersChanged(int displayId); void onRotationChanged(int rotation); } diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java index c8931f4..d5a8537 100644 --- a/services/java/com/android/server/accessibility/ScreenMagnifier.java +++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java @@ -850,6 +850,7 @@ public final class ScreenMagnifier implements EventStreamTransformation { private static final int MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED = 3; private static final int MESSAGE_ON_WINDOW_TRANSITION = 4; private static final int MESSAGE_ON_ROTATION_CHANGED = 5; + private static final int MESSAGE_ON_WINDOW_LAYERS_CHANGED = 6; private final Handler mHandler = new MyHandler(); @@ -880,24 +881,8 @@ public final class ScreenMagnifier implements EventStreamTransformation { mDisplayContentChangeListener = new IDisplayContentChangeListener.Stub() { @Override public void onWindowTransition(int displayId, int transition, WindowInfo info) { - Message message = mHandler.obtainMessage(MESSAGE_ON_WINDOW_TRANSITION, - transition, 0, WindowInfo.obtain(info)); - // TODO: This makes me quite unhappy but for the time being the - // least risky fix for cases where the keyguard is removed but - // the windows it force hides are not made visible yet. Hence, - // we would compute the magnified frame before we have a stable - // state. One more reason to move the magnified frame computation - // in the window manager! - if (info.type == WindowManager.LayoutParams.TYPE_KEYGUARD - || info.type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG - && (transition == WindowManagerPolicy.TRANSIT_EXIT - || transition == WindowManagerPolicy.TRANSIT_HIDE)) { - final long delay = (long) (2 * mLongAnimationDuration - * mWindowAnimationScale); - mHandler.sendMessageDelayed(message, delay); - } else { - message.sendToTarget(); - } + mHandler.obtainMessage(MESSAGE_ON_WINDOW_TRANSITION, + transition, 0, WindowInfo.obtain(info)).sendToTarget(); } @Override @@ -917,6 +902,11 @@ public final class ScreenMagnifier implements EventStreamTransformation { mHandler.obtainMessage(MESSAGE_ON_ROTATION_CHANGED, rotation, 0) .sendToTarget(); } + + @Override + public void onWindowLayersChanged(int displayId) throws RemoteException { + mHandler.sendEmptyMessage(MESSAGE_ON_WINDOW_LAYERS_CHANGED); + } }; try { @@ -1192,6 +1182,9 @@ public final class ScreenMagnifier implements EventStreamTransformation { final int rotation = message.arg1; handleOnRotationChanged(rotation); } break; + case MESSAGE_ON_WINDOW_LAYERS_CHANGED: { + mViewport.recomputeBounds(mMagnificationController.isMagnifying()); + } break; default: { throw new IllegalArgumentException("Unknown message: " + action); } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 77d815b..d15c051 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -6576,6 +6576,36 @@ public class WindowManagerService extends IWindowManager.Stub } } + private void scheduleNotifyWindowLayersChangedIfNeededLocked(DisplayContent displayContent) { + if (displayContent.mDisplayContentChangeListeners != null + && displayContent.mDisplayContentChangeListeners.getRegisteredCallbackCount() > 0) { + mH.obtainMessage(H.NOTIFY_WINDOW_LAYERS_CHANGED, displayContent) .sendToTarget(); + } + } + + private void handleNotifyWindowLayersChanged(DisplayContent displayContent) { + RemoteCallbackList<IDisplayContentChangeListener> callbacks = null; + synchronized (mWindowMap) { + callbacks = displayContent.mDisplayContentChangeListeners; + if (callbacks == null) { + return; + } + } + try { + final int watcherCount = callbacks.beginBroadcast(); + for (int i = 0; i < watcherCount; i++) { + try { + callbacks.getBroadcastItem(i).onWindowLayersChanged( + displayContent.getDisplayId()); + } catch (RemoteException re) { + /* ignore */ + } + } + } finally { + callbacks.finishBroadcast(); + } + } + public void addWindowChangeListener(WindowChangeListener listener) { synchronized(mWindowMap) { mWindowChangeListeners.add(listener); @@ -7222,12 +7252,13 @@ public class WindowManagerService extends IWindowManager.Stub public static final int NOTIFY_ROTATION_CHANGED = 28; public static final int NOTIFY_WINDOW_TRANSITION = 29; public static final int NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 30; + public static final int NOTIFY_WINDOW_LAYERS_CHANGED = 31; - public static final int DO_DISPLAY_ADDED = 31; - public static final int DO_DISPLAY_REMOVED = 32; - public static final int DO_DISPLAY_CHANGED = 33; + public static final int DO_DISPLAY_ADDED = 32; + public static final int DO_DISPLAY_REMOVED = 33; + public static final int DO_DISPLAY_CHANGED = 34; - public static final int CLIENT_FREEZE_TIMEOUT = 34; + public static final int CLIENT_FREEZE_TIMEOUT = 35; public static final int ANIMATOR_WHAT_OFFSET = 100000; public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1; @@ -7699,6 +7730,12 @@ public class WindowManagerService extends IWindowManager.Stub break; } + case NOTIFY_WINDOW_LAYERS_CHANGED: { + DisplayContent displayContent = (DisplayContent) msg.obj; + handleNotifyWindowLayersChanged(displayContent); + break; + } + case DO_DISPLAY_ADDED: synchronized (mWindowMap) { handleDisplayAddedLocked(msg.arg1); @@ -8075,6 +8112,8 @@ public class WindowManagerService extends IWindowManager.Stub Slog.v(TAG, "Assigning layers", here); } + boolean anyLayerChanged = false; + for (i=0; i<N; i++) { final WindowState w = windows.get(i); final WindowStateAnimator winAnimator = w.mWinAnimator; @@ -8090,6 +8129,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (w.mLayer != oldLayer) { layerChanged = true; + anyLayerChanged = true; } oldLayer = winAnimator.mAnimLayer; if (w.mTargetAppToken != null) { @@ -8108,6 +8148,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (winAnimator.mAnimLayer != oldLayer) { layerChanged = true; + anyLayerChanged = true; } if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) { // Force an animation pass just to update the mDimAnimator layer. @@ -8122,6 +8163,10 @@ public class WindowManagerService extends IWindowManager.Stub //System.out.println( // "Assigned layer " + curLayer + " to " + w.mClient.asBinder()); } + + if (anyLayerChanged) { + scheduleNotifyWindowLayersChangedIfNeededLocked(getDefaultDisplayContentLocked()); + } } private boolean mInLayout = false; |