Merge "Fix for bug 7358703 Gmail ANR when trying to compose a message" into jb-mr1-dev
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 @@
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/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 9fb61e4..4d16bb4 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -228,25 +228,22 @@
texture->height = bitmap->height();
glBindTexture(GL_TEXTURE_2D, texture->id);
- if (!regenerate) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
- }
switch (bitmap->getConfig()) {
case SkBitmap::kA8_Config:
- if (!regenerate) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- }
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height,
GL_UNSIGNED_BYTE, bitmap->getPixels());
texture->blend = true;
break;
case SkBitmap::kRGB_565_Config:
+ glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
uploadToTexture(resize, GL_RGB, bitmap->rowBytesAsPixels(), texture->height,
GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels());
texture->blend = false;
break;
case SkBitmap::kARGB_8888_Config:
+ glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
uploadToTexture(resize, GL_RGBA, bitmap->rowBytesAsPixels(), texture->height,
GL_UNSIGNED_BYTE, bitmap->getPixels());
// Do this after calling getPixels() to make sure Skia's deferred
@@ -255,6 +252,7 @@
break;
case SkBitmap::kARGB_4444_Config:
case SkBitmap::kIndex8_Config:
+ glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
uploadLoFiTexture(resize, bitmap, texture->width, texture->height);
texture->blend = !bitmap->isOpaque();
break;
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 6877cba..0958f70 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -31,8 +31,10 @@
import android.renderscript.Matrix4f;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
+import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
+import android.view.WindowManager;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
@@ -108,6 +110,7 @@
Bitmap mBackground;
int mBackgroundWidth = -1, mBackgroundHeight = -1;
+ int mLastRotation = -1;
float mXOffset;
float mYOffset;
@@ -156,7 +159,7 @@
mBackgroundWidth = mBackgroundHeight = -1;
mBackground = null;
mRedrawNeeded = true;
- drawFrameLocked(false);
+ drawFrameLocked();
}
}
}
@@ -225,7 +228,7 @@
@Override
public void onVisibilityChanged(boolean visible) {
if (DEBUG) {
- Log.d(TAG, "onVisibilityChanged: visible=" + visible);
+ Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible);
}
synchronized (mLock) {
@@ -234,7 +237,7 @@
Log.d(TAG, "Visibility changed to visible=" + visible);
}
mVisible = visible;
- drawFrameLocked(false);
+ drawFrameLocked();
}
}
}
@@ -263,7 +266,7 @@
mYOffset = yOffset;
mOffsetsChanged = true;
}
- drawFrameLocked(false);
+ drawFrameLocked();
}
}
@@ -276,80 +279,81 @@
super.onSurfaceChanged(holder, format, width, height);
synchronized (mLock) {
- mRedrawNeeded = true;
- mBackgroundWidth = mBackgroundHeight = -1;
- drawFrameLocked(true);
+ drawFrameLocked();
}
}
@Override
+ public void onSurfaceDestroyed(SurfaceHolder holder) {
+ super.onSurfaceDestroyed(holder);
+ mBackgroundWidth = mBackgroundHeight = -1;
+ }
+
+ @Override
+ public void onSurfaceCreated(SurfaceHolder holder) {
+ super.onSurfaceCreated(holder);
+ mBackgroundWidth = mBackgroundHeight = -1;
+ }
+
+ @Override
public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
if (DEBUG) {
- Log.d(TAG, "onSurfaceRedrawNeeded:");
+ Log.d(TAG, "onSurfaceRedrawNeeded");
}
super.onSurfaceRedrawNeeded(holder);
synchronized (mLock) {
- mRedrawNeeded = true;
- drawFrameLocked(false);
+ drawFrameLocked();
}
}
- void drawFrameLocked(boolean force) {
- if (!force) {
- if (!mVisible) {
- if (DEBUG) {
- Log.d(TAG, "Suppressed drawFrame since wallpaper is not visible.");
- }
- return;
- }
- if (!mRedrawNeeded && !mOffsetsChanged) {
- if (DEBUG) {
- Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
- + "and offsets have not changed.");
- }
- return;
- }
- }
- // If we don't yet know the size of the wallpaper bitmap,
- // we need to get it now.
- boolean updateWallpaper = mBackgroundWidth < 0 || mBackgroundHeight < 0 ;
-
- // If we somehow got to this point after we have last flushed
- // the wallpaper, well we really need it to draw again. So
- // seems like we need to reload it. Ouch.
- updateWallpaper = updateWallpaper || mBackground == null;
-
- if (updateWallpaper) {
- updateWallpaperLocked();
- }
-
+ void drawFrameLocked() {
SurfaceHolder sh = getSurfaceHolder();
final Rect frame = sh.getSurfaceFrame();
final int dw = frame.width();
final int dh = frame.height();
+ int newRotation = ((WindowManager) getSystemService(WINDOW_SERVICE)).
+ getDefaultDisplay().getRotation();
+
+ boolean redrawNeeded = dw != mBackgroundWidth || dh != mBackgroundHeight ||
+ newRotation != mLastRotation;
+ if (!redrawNeeded && !mOffsetsChanged) {
+ if (DEBUG) {
+ Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
+ + "and offsets have not changed.");
+ }
+ return;
+ }
+ mLastRotation = newRotation;
+
+ // Load bitmap if it is not yet loaded or if it was loaded at a different size
+ if (mBackground == null || dw != mBackgroundWidth || dw != mBackgroundHeight) {
+ if (DEBUG) {
+ Log.d(TAG, "Reloading bitmap");
+ }
+ mWallpaperManager.forgetLoadedWallpaper();
+ updateWallpaperLocked();
+ }
+
final int availw = dw - mBackgroundWidth;
final int availh = dh - mBackgroundHeight;
int xPixels = availw < 0 ? (int)(availw * mXOffset + .5f) : (availw / 2);
int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);
mOffsetsChanged = false;
- if (!force && !mRedrawNeeded
- && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
+ mRedrawNeeded = false;
+ mLastXTranslation = xPixels;
+ mLastYTranslation = yPixels;
+ if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
if (DEBUG) {
Log.d(TAG, "Suppressed drawFrame since the image has not "
+ "actually moved an integral number of pixels.");
}
return;
}
- mRedrawNeeded = false;
- mLastXTranslation = xPixels;
- mLastYTranslation = yPixels;
if (DEBUG) {
- Log.d(TAG, "drawFrameUnlocked(" + force + "): mBackgroundWxH=" + mBackgroundWidth + "x"
- + mBackgroundHeight + " SurfaceFrame=" + frame.toShortString()
- + " X,YOffset=" + mXOffset + "," + mYOffset);
+ Log.d(TAG, "Redrawing wallpaper");
}
if (mIsHwAccelerated) {
if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) {
@@ -429,7 +433,6 @@
final float bottom = top + mBackgroundHeight;
final Rect frame = sh.getSurfaceFrame();
-
final Matrix4f ortho = new Matrix4f();
ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f);
@@ -437,7 +440,7 @@
final int texture = loadTexture(mBackground);
final int program = buildProgram(sSimpleVS, sSimpleFS);
-
+
final int attribPosition = glGetAttribLocation(program, "position");
final int attribTexCoords = glGetAttribLocation(program, "texCoords");
final int uniformTexture = glGetUniformLocation(program, "texture");
@@ -460,7 +463,7 @@
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
-
+
// drawQuad
triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false,
@@ -471,12 +474,12 @@
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
+
if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
throw new RuntimeException("Cannot swap buffers");
}
checkEglError();
-
+
finishGL();
return true;
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 @@
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 @@
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 @@
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 @@
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 1b3137e..fa450ae 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -6569,6 +6569,36 @@
}
}
+ 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);
@@ -7215,12 +7245,13 @@
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;
@@ -7692,6 +7723,12 @@
break;
}
+ case NOTIFY_WINDOW_LAYERS_CHANGED: {
+ DisplayContent displayContent = (DisplayContent) msg.obj;
+ handleNotifyWindowLayersChanged(displayContent);
+ break;
+ }
+
case DO_DISPLAY_ADDED:
synchronized (mWindowMap) {
handleDisplayAddedLocked(msg.arg1);
@@ -8068,6 +8105,8 @@
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;
@@ -8083,6 +8122,7 @@
}
if (w.mLayer != oldLayer) {
layerChanged = true;
+ anyLayerChanged = true;
}
oldLayer = winAnimator.mAnimLayer;
if (w.mTargetAppToken != null) {
@@ -8101,6 +8141,7 @@
}
if (winAnimator.mAnimLayer != oldLayer) {
layerChanged = true;
+ anyLayerChanged = true;
}
if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) {
// Force an animation pass just to update the mDimAnimator layer.
@@ -8115,6 +8156,10 @@
//System.out.println(
// "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
}
+
+ if (anyLayerChanged) {
+ scheduleNotifyWindowLayersChangedIfNeededLocked(getDefaultDisplayContentLocked());
+ }
}
private final void performLayoutAndPlaceSurfacesLocked() {