Merge "Call setSize to sync Surface to SurfaceFlinger. DO NOT MERGE" into jb-mr1.1-dev
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 550a740..0a81a71 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -225,6 +225,9 @@
     // non compatibility mode.
     private Matrix mCompatibleMatrix;
 
+    private int mWidth;
+    private int mHeight;
+
     private native void nativeCreate(SurfaceSession session, String name,
             int w, int h, int format, int flags)
             throws OutOfResourcesException;
@@ -330,6 +333,8 @@
         checkHeadless();
 
         mName = name;
+        mWidth = w;
+        mHeight = h;
         nativeCreate(session, name, w, h, format, flags);
 
         mCloseGuard.open("release");
@@ -538,7 +543,7 @@
 
     /** @hide */
     public void setPosition(int x, int y) {
-        nativeSetPosition((float)x, (float)y);
+        nativeSetPosition(x, y);
     }
 
     /** @hide */
@@ -548,10 +553,22 @@
 
     /** @hide */
     public void setSize(int w, int h) {
+        mWidth = w;
+        mHeight = h;
         nativeSetSize(w, h);
     }
 
     /** @hide */
+    public int getWidth() {
+        return mWidth;
+    }
+
+    /** @hide */
+    public int getHeight() {
+        return mHeight;
+    }
+
+    /** @hide */
     public void hide() {
         nativeSetFlags(SURFACE_HIDDEN, SURFACE_HIDDEN);
     }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 409480f..49dc220 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -12327,7 +12327,7 @@
                 }
                 newConfig.seq = mConfigurationSeq;
                 mConfiguration = newConfig;
-                Slog.i(TAG, "Config changed: " + newConfig);
+                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
 
                 final Configuration configCopy = new Configuration(mConfiguration);
                 
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 003f4db..746254e 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5800,50 +5800,64 @@
             // Figure out the part of the screen that is actually the app.
             boolean including = false;
             final WindowList windows = displayContent.getWindowList();
-            for (int i = windows.size() - 1; i >= 0; i--) {
-                WindowState ws = windows.get(i);
-                if (!ws.mHasSurface) {
-                    continue;
-                }
-                if (ws.mLayer >= aboveAppLayer) {
-                    continue;
-                }
-                // When we will skip windows: when we are not including
-                // ones behind a window we didn't skip, and we are actually
-                // taking a screenshot of a specific app.
-                if (!including && appToken != null) {
-                    // Also, we can possibly skip this window if it is not
-                    // an IME target or the application for the screenshot
-                    // is not the current IME target.
-                    if (!ws.mIsImWindow || !isImeTarget) {
-                        // And finally, this window is of no interest if it
-                        // is not associated with the screenshot app.
-                        if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
-                            continue;
+            try {
+                Surface.openTransaction();
+                for (int i = windows.size() - 1; i >= 0; i--) {
+                    WindowState ws = windows.get(i);
+                    if (!ws.mHasSurface) {
+                        continue;
+                    }
+                    if (ws.mLayer >= aboveAppLayer) {
+                        continue;
+                    }
+                    // When we will skip windows: when we are not including
+                    // ones behind a window we didn't skip, and we are actually
+                    // taking a screenshot of a specific app.
+                    if (!including && appToken != null) {
+                        // Also, we can possibly skip this window if it is not
+                        // an IME target or the application for the screenshot
+                        // is not the current IME target.
+                        if (!ws.mIsImWindow || !isImeTarget) {
+                            // And finally, this window is of no interest if it
+                            // is not associated with the screenshot app.
+                            if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
+                                continue;
+                            }
                         }
                     }
-                }
 
-                // We keep on including windows until we go past a full-screen
-                // window.
-                including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
+                    // We keep on including windows until we go past a full-screen
+                    // window.
+                    including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
 
-                if (maxLayer < ws.mWinAnimator.mSurfaceLayer) {
-                    maxLayer = ws.mWinAnimator.mSurfaceLayer;
+                    final WindowStateAnimator winAnimator = ws.mWinAnimator;
+
+                    // The setSize() method causes all previous Surface transactions to sync to
+                    // the SurfaceFlinger. This will force any outstanding setLayer calls to be
+                    // synced as well for screen capture. Without this we can get black bitmaps.
+                    Surface surface = winAnimator.mSurface;
+                    surface.setSize(surface.getWidth(), surface.getHeight());
+
+
+                    if (maxLayer < winAnimator.mSurfaceLayer) {
+                        maxLayer = winAnimator.mSurfaceLayer;
+                    }
+
+                    // Don't include wallpaper in bounds calculation
+                    if (!ws.mIsWallpaper) {
+                        final Rect wf = ws.mFrame;
+                        final Rect cr = ws.mContentInsets;
+                        int left = wf.left + cr.left;
+                        int top = wf.top + cr.top;
+                        int right = wf.right - cr.right;
+                        int bottom = wf.bottom - cr.bottom;
+                        frame.union(left, top, right, bottom);
+                    }
                 }
-                
-                // Don't include wallpaper in bounds calculation
-                if (!ws.mIsWallpaper) {
-                    final Rect wf = ws.mFrame;
-                    final Rect cr = ws.mContentInsets;
-                    int left = wf.left + cr.left;
-                    int top = wf.top + cr.top;
-                    int right = wf.right - cr.right;
-                    int bottom = wf.bottom - cr.bottom;
-                    frame.union(left, top, right, bottom);
-                }
+            } finally {
+                Surface.closeTransaction();
+                Binder.restoreCallingIdentity(ident);
             }
-            Binder.restoreCallingIdentity(ident);
 
             // Constrain frame to the screen size.
             frame.intersect(0, 0, dw, dh);