/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.testing;
import javax.annotation.Nullable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Looper;
import android.widget.FrameLayout;
/**
* A FrameLayout that allows you to access the result of the last time its hierarchy was drawn. It
* accomplishes this by drawing its hierarchy into a software Canvas, saving the resulting Bitmap
* and then drawing that Bitmap to the actual Canvas provided by the system.
*/
public class ScreenshotingFrameLayout extends FrameLayout {
private @Nullable Bitmap mBitmap;
private Canvas mCanvas;
public ScreenshotingFrameLayout(Context context) {
super(context);
mCanvas = new Canvas();
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (mBitmap == null) {
mBitmap = createNewBitmap(canvas);
mCanvas.setBitmap(mBitmap);
} else if (mBitmap.getWidth() != canvas.getWidth() ||
mBitmap.getHeight() != canvas.getHeight()) {
mBitmap.recycle();
mBitmap = createNewBitmap(canvas);
mCanvas.setBitmap(mBitmap);
}
super.dispatchDraw(mCanvas);
canvas.drawBitmap(mBitmap, 0, 0, null);
}
private static Bitmap createNewBitmap(Canvas canvas) {
return Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
}
public Bitmap getLastDrawnBitmap() {
if (mBitmap == null) {
throw new RuntimeException("View has not been drawn yet!");
}
if (Looper.getMainLooper() != Looper.myLooper()) {
throw new RuntimeException(
"Must access screenshots from main thread or you may get partially drawn Bitmaps");
}
if (!isScreenshotReady()) {
throw new RuntimeException("Trying to get screenshot, but the view is dirty or needs layout");
}
return Bitmap.createBitmap(mBitmap);
}
public boolean isScreenshotReady() {
return !isDirty() && !isLayoutRequested();
}
}