Merge "Screen magnifier should handle window rebuilds correctly." into jb-mr1-dev
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
index 00875ae..7d16e14 100644
--- a/core/java/android/view/WindowInfo.java
+++ b/core/java/android/view/WindowInfo.java
@@ -45,13 +45,15 @@
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 @@
parcel.writeFloat(compatibilityScale);
parcel.writeInt(visible ? 1 : 0);
parcel.writeInt(displayId);
+ parcel.writeInt(layer);
recycle();
}
@@ -82,6 +85,7 @@
compatibilityScale = parcel.readFloat();
visible = (parcel.readInt() == 1);
displayId = parcel.readInt();
+ layer = parcel.readInt();
}
public static WindowInfo obtain(WindowInfo other) {
@@ -90,9 +94,10 @@
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 @@
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 8301211..d6482fa 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.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 @@
}
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 @@
private final ArrayList<WindowInfo> mTempWindowInfoList = new ArrayList<WindowInfo>();
- 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 @@
recomputeBounds(false);
}
+ private final Comparator<WindowInfo> mWindowInfoInverseComparator =
+ new Comparator<WindowInfo>() {
+ @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<WindowInfo> 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;
}
- info.recycle();
+ 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;
+ }
}
} 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 6951879..b1e4f4b 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3153,6 +3153,7 @@
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;