diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java index 00875ae0e310b..7d16e147d2937 100644 --- a/core/java/android/view/WindowInfo.java +++ b/core/java/android/view/WindowInfo.java @@ -45,13 +45,15 @@ public class WindowInfo implements Parcelable { public final Rect touchableRegion = new Rect(); - public int type; + public int type = UNDEFINED; - public float compatibilityScale; + public float compatibilityScale = UNDEFINED; public boolean visible; - public int displayId; + public int displayId = UNDEFINED; + + public int layer = UNDEFINED; private WindowInfo() { /* do nothing - reduce visibility */ @@ -71,6 +73,7 @@ public class WindowInfo implements Parcelable { parcel.writeFloat(compatibilityScale); parcel.writeInt(visible ? 1 : 0); parcel.writeInt(displayId); + parcel.writeInt(layer); recycle(); } @@ -82,6 +85,7 @@ public class WindowInfo implements Parcelable { compatibilityScale = parcel.readFloat(); visible = (parcel.readInt() == 1); displayId = parcel.readInt(); + layer = parcel.readInt(); } public static WindowInfo obtain(WindowInfo other) { @@ -90,9 +94,10 @@ public class WindowInfo implements Parcelable { info.frame.set(other.frame); info.touchableRegion.set(other.touchableRegion); info.type = other.type; - info.displayId = other.displayId; info.compatibilityScale = other.compatibilityScale; info.visible = other.visible; + info.displayId = other.displayId; + info.layer = other.layer; return info; } @@ -131,8 +136,25 @@ public class WindowInfo implements Parcelable { frame.setEmpty(); touchableRegion.setEmpty(); type = UNDEFINED; - displayId = UNDEFINED; + compatibilityScale = UNDEFINED; visible = false; + displayId = UNDEFINED; + layer = UNDEFINED; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Window [token:").append((token != null) ? token.hashCode() : null); + builder.append(", displayId:").append(displayId); + builder.append(", type:").append(type); + builder.append(", visible:").append(visible); + builder.append(", layer:").append(layer); + builder.append(", compatibilityScale:").append(compatibilityScale); + builder.append(", frame:").append(frame); + builder.append(", touchableRegion:").append(touchableRegion); + builder.append("]"); + return builder.toString(); } /** diff --git a/services/java/com/android/server/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java index 830121141afca..d6482fa0c6320 100644 --- a/services/java/com/android/server/accessibility/ScreenMagnifier.java +++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java @@ -67,6 +67,8 @@ import com.android.internal.R; import com.android.internal.os.SomeArgs; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; /** * This class handles the screen magnification when accessibility is enabled. @@ -1020,7 +1022,9 @@ public final class ScreenMagnifier implements EventStreamTransformation { } if (info.type == WindowManager.LayoutParams.TYPE_NAVIGATION_BAR || info.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD - || info.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG) { + || info.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG + || info.type == WindowManager.LayoutParams.TYPE_KEYGUARD + || info.type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) { switch (transition) { case WindowManagerPolicy.TRANSIT_ENTER: case WindowManagerPolicy.TRANSIT_SHOW: @@ -1473,7 +1477,9 @@ public final class ScreenMagnifier implements EventStreamTransformation { private final ArrayList mTempWindowInfoList = new ArrayList(); - private final Rect mTempRect = new Rect(); + private final Rect mTempRect1 = new Rect(); + private final Rect mTempRect2 = new Rect(); + private final Rect mTempRect3 = new Rect(); private final IWindowManager mWindowManagerService; private final DisplayProvider mDisplayProvider; @@ -1542,31 +1548,83 @@ public final class ScreenMagnifier implements EventStreamTransformation { recomputeBounds(false); } + private final Comparator mWindowInfoInverseComparator = + new Comparator() { + @Override + public int compare(WindowInfo lhs, WindowInfo rhs) { + if (lhs.layer != rhs.layer) { + return rhs.layer - lhs.layer; + } + if (lhs.touchableRegion.top != rhs.touchableRegion.top) { + return rhs.touchableRegion.top - lhs.touchableRegion.top; + } + if (lhs.touchableRegion.left != rhs.touchableRegion.left) { + return rhs.touchableRegion.left - lhs.touchableRegion.left; + } + if (lhs.touchableRegion.right != rhs.touchableRegion.right) { + return rhs.touchableRegion.right - lhs.touchableRegion.right; + } + if (lhs.touchableRegion.bottom != rhs.touchableRegion.bottom) { + return rhs.touchableRegion.bottom - lhs.touchableRegion.bottom; + } + return 0; + } + }; + public void recomputeBounds(boolean animate) { - Rect frame = mTempRect; - frame.set(0, 0, mDisplayProvider.getDisplayInfo().logicalWidth, - mDisplayProvider.getDisplayInfo().logicalHeight); + Rect magnifiedFrame = mTempRect1; + magnifiedFrame.set(0, 0, 0, 0); + + Rect notMagnifiedFrame = mTempRect2; + notMagnifiedFrame.set(0, 0, 0, 0); + ArrayList infos = mTempWindowInfoList; infos.clear(); + int windowCount = 0; try { mWindowManagerService.getVisibleWindowsForDisplay( mDisplayProvider.getDisplay().getDisplayId(), infos); - final int windowCount = infos.size(); + Collections.sort(infos, mWindowInfoInverseComparator); + windowCount = infos.size(); for (int i = 0; i < windowCount; i++) { WindowInfo info = infos.get(i); - if (info.type == WindowManager.LayoutParams.TYPE_NAVIGATION_BAR - || info.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD - || info.type == WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG) { - subtract(frame, info.touchableRegion); + if (info.type == WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY) { + continue; + } + if (isWindowMagnified(info.type)) { + Rect clippedFrame = mTempRect3; + clippedFrame.set(info.touchableRegion); + subtract(clippedFrame, notMagnifiedFrame); + magnifiedFrame.union(clippedFrame); + } else { + Rect clippedFrame = mTempRect3; + clippedFrame.set(info.touchableRegion); + subtract(clippedFrame, magnifiedFrame); + notMagnifiedFrame.union(clippedFrame); + } + if (magnifiedFrame.bottom >= notMagnifiedFrame.top) { + break; } - info.recycle(); } } catch (RemoteException re) { /* ignore */ } finally { - infos.clear(); + for (int i = windowCount - 1; i >= 0; i--) { + infos.remove(i).recycle(); + } } - resize(frame, animate); + + final int displayWidth = mDisplayProvider.getDisplayInfo().logicalWidth; + final int displayHeight = mDisplayProvider.getDisplayInfo().logicalHeight; + magnifiedFrame.intersect(0, 0, displayWidth, displayHeight); + + resize(magnifiedFrame, animate); + } + + private boolean isWindowMagnified(int type) { + return (type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR + && type != WindowManager.LayoutParams.TYPE_INPUT_METHOD + && type != WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG); } public void rotationChanged() { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 6951879ba3848..b1e4f4b547142 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -3153,6 +3153,7 @@ public class WindowManagerService extends IWindowManager.Stub info.compatibilityScale = window.mGlobalScale; info.visible = window.isVisibleLw() || info.type == WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND; + info.layer = window.mLayer; window.getTouchableRegion(mTempRegion); mTempRegion.getBounds(info.touchableRegion); return info;