Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5341f377 authored by Craig Mautner's avatar Craig Mautner Committed by Android (Google) Code Review
Browse files

Merge "Reduce situations where black thumbnail occurs." into jb-mr2-dev

parents 88a0765d 24d88747
Loading
Loading
Loading
Loading
+181 −103
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
@@ -282,6 +283,8 @@ public class WindowManagerService extends IWindowManager.Stub
    private static final String SYSTEM_SECURE = "ro.secure";
    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";

    private static final int MAX_SCREENSHOT_RETRIES = 3;

    final private KeyguardDisableHandler mKeyguardDisableHandler;

    private final boolean mHeadless;
@@ -5277,18 +5280,36 @@ public class WindowManagerService extends IWindowManager.Stub
            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
        }

        Bitmap rawss;
        Bitmap rawss = null;

        int maxLayer = 0;
        final Rect frame = new Rect();

        float scale;
        float scale = 0;
        int dw, dh;
        int rot;
        int rot = Surface.ROTATION_0;

        synchronized(mWindowMap) {
            long ident = Binder.clearCallingIdentity();
        boolean screenshotReady;
        int minLayer;
        if (appToken == null) {
            screenshotReady = true;
            minLayer = 0;
        } else {
            screenshotReady = false;
            minLayer = Integer.MAX_VALUE;
        }

        int retryCount = 0;
        WindowState appWin = null;

        do {
            if (retryCount++ > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
            }
            synchronized(mWindowMap) {
                final DisplayContent displayContent = getDisplayContentLocked(displayId);
                if (displayContent == null) {
                    return null;
@@ -5308,6 +5329,7 @@ public class WindowManagerService extends IWindowManager.Stub

                // Figure out the part of the screen that is actually the app.
                boolean including = false;
                appWin = null;
                final WindowList windows = displayContent.getWindowList();
                for (int i = windows.size() - 1; i >= 0; i--) {
                    WindowState ws = windows.get(i);
@@ -5330,15 +5352,18 @@ public class WindowManagerService extends IWindowManager.Stub
                            if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
                                continue;
                            }
                            appWin = ws;
                        }
                    }

                    // We keep on including windows until we go past a full-screen
                    // window.
                including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
                    boolean fullscreen = ws.isFullscreen(dw, dh);
                    including = !ws.mIsImWindow && !fullscreen;

                if (maxLayer < ws.mWinAnimator.mSurfaceLayer) {
                    maxLayer = ws.mWinAnimator.mSurfaceLayer;
                    final WindowStateAnimator winAnim = ws.mWinAnimator;
                    if (maxLayer < winAnim.mSurfaceLayer) {
                        maxLayer = winAnim.mSurfaceLayer;
                    }

                    // Don't include wallpaper in bounds calculation
@@ -5351,13 +5376,41 @@ public class WindowManagerService extends IWindowManager.Stub
                        int bottom = wf.bottom - cr.bottom;
                        frame.union(left, top, right, bottom);
                    }

                    if (ws.mAppToken != null && ws.mAppToken.token == appToken) {
                        if (minLayer > ws.mWinAnimator.mSurfaceLayer) {
                            minLayer = ws.mWinAnimator.mSurfaceLayer;
                        }
                        if (ws.isDisplayedLw()) {
                            screenshotReady = true;
                        }
                        if (fullscreen) {
                            // No point in continuing down through windows.
                            break;
                        }
                    }
                }

                if (appToken != null && appWin == null) {
                    // Can't find a window to snapshot.
                    if (DEBUG_SCREENSHOT) Slog.i(TAG,
                            "Screenshot: Couldn't find a surface matching " + appToken);
                    return null;
                }
                if (!screenshotReady) {
                    // Delay and hope that window gets drawn.
                    if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot: No image ready for " + appToken
                            + ", " + appWin + " drawState=" + appWin.mWinAnimator.mDrawState);
                    continue;
                }
            Binder.restoreCallingIdentity(ident);

                // Constrain frame to the screen size.
                frame.intersect(0, 0, dw, dh);

                if (frame.isEmpty() || maxLayer == 0) {
                    if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
                            + ": returning null frame=" + frame.toShortString() + " maxLayer="
                            + maxLayer);
                    return null;
                }

@@ -5396,7 +5449,8 @@ public class WindowManagerService extends IWindowManager.Stub
                    rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
                }
                if (DEBUG_SCREENSHOT) {
                Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from 0 to " + maxLayer);
                    Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
                            + maxLayer + " appToken=" + appToken);
                    for (int i = 0; i < windows.size(); i++) {
                        WindowState win = windows.get(i);
                        Slog.i(TAG, win + ": " + win.mLayer
@@ -5404,7 +5458,13 @@ public class WindowManagerService extends IWindowManager.Stub
                                + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
                    }
                }
            rawss = SurfaceControl.screenshot(dw, dh, 0, maxLayer);
                rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer);
            }
        } while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
        if (DEBUG_SCREENSHOT && retryCount > MAX_SCREENSHOT_RETRIES) {
            Slog.i(TAG, "Screenshot max retries " + retryCount + " of " + appToken + " appWin="
                    + (appWin == null ? "null" : (appWin + " drawState="
                            + appWin.mWinAnimator.mDrawState)));
        }

        if (rawss == null) {
@@ -5421,6 +5481,23 @@ public class WindowManagerService extends IWindowManager.Stub
        canvas.drawBitmap(rawss, matrix, null);
        canvas.setBitmap(null);

        if (DEBUG_SCREENSHOT) {
            // TEST IF IT's ALL BLACK
            int[] buffer = new int[bm.getWidth() * bm.getHeight()];
            bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
            boolean allBlack = true;
            for (int i = 0; i < buffer.length; i++) {
                if (buffer[i] != Color.BLACK) {
                    allBlack = false;
                    break;
                }
            }
            if (allBlack) {
                Slog.i(TAG, "Screenshot " + appWin + " was all black! mSurfaceLayer=" +
                        (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null"));
            }
        }

        rawss.recycle();
        return bm;
    }
@@ -7408,6 +7485,7 @@ public class WindowManagerService extends IWindowManager.Stub
        performLayoutAndPlaceSurfacesLocked();
    }

    @Override
    public void setOverscan(int displayId, int left, int top, int right, int bottom) {
        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.WRITE_SECURE_SETTINGS) !=