Bug 791263 - Disable screenshotting under low-memory conditions. r=blassey

This commit is contained in:
Kartikaya Gupta 2012-09-25 15:46:17 -04:00
parent e00d2f38e0
commit ed2336ecaf
3 changed files with 59 additions and 18 deletions

View File

@ -148,17 +148,27 @@ class MemoryMonitor extends BroadcastReceiver {
if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) {
GeckoAppShell.onLowMemory();
}
ScreenshotHandler.disableScreenshot();
GeckoAppShell.geckoEventSync();
}
}
private synchronized boolean decreaseMemoryPressure() {
if (mMemoryPressure > 0) {
mMemoryPressure--;
Log.d(LOGTAG, "Decreased memory pressure to " + mMemoryPressure);
return true;
private boolean decreaseMemoryPressure() {
int newLevel;
synchronized (this) {
if (mMemoryPressure <= 0) {
return false;
}
newLevel = --mMemoryPressure;
}
return false;
Log.d(LOGTAG, "Decreased memory pressure to " + newLevel);
if (newLevel == MEMORY_PRESSURE_NONE) {
ScreenshotHandler.enableScreenshot();
}
return true;
}
class PressureDecrementer implements Runnable {

View File

@ -17,6 +17,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.opengl.GLES20;
import android.util.FloatMath;
import android.util.Log;
import java.nio.ByteBuffer;
import java.util.Iterator;
@ -39,7 +40,7 @@ public final class ScreenshotHandler implements Runnable {
private final int mMaxPixels;
private final Queue<PendingScreenshot> mPendingScreenshots;
private final ByteBuffer mBuffer;
private ByteBuffer mBuffer;
private int mBufferWidth;
private int mBufferHeight;
private RectF mPageRect;
@ -51,11 +52,16 @@ public final class ScreenshotHandler implements Runnable {
private boolean mIsRepaintRunnablePosted;
private static synchronized ScreenshotHandler getInstance() {
if (sDisableScreenshot) {
return null;
}
if (sInstance == null) {
try {
sInstance = new ScreenshotHandler();
} catch (UnsupportedOperationException e) {
// initialization failed, fall through and return null
// initialization failed, fall through and return null.
// also set the disable flag so we don't try again.
sDisableScreenshot = true;
}
}
return sInstance;
@ -76,13 +82,34 @@ public final class ScreenshotHandler implements Runnable {
clearDirtyRect();
}
private void cleanup() {
discardPendingScreenshots();
mBuffer = DirectBufferAllocator.free(mBuffer);
}
// Invoked via reflection from robocop test
public static void disableScreenshot() {
public static synchronized void disableScreenshot() {
if (sDisableScreenshot) {
return;
}
sDisableScreenshot = true;
if (sInstance != null) {
sInstance.cleanup();
sInstance = null;
}
Log.i(LOGTAG, "Screenshotting disabled");
}
public static synchronized void enableScreenshot() {
if (!sDisableScreenshot) {
return;
}
sDisableScreenshot = false;
Log.i(LOGTAG, "Screenshotting enabled");
}
public static void screenshotWholePage(Tab tab) {
if (sDisableScreenshot || GeckoApp.mAppContext.isApplicationInBackground()) {
if (GeckoApp.mAppContext.isApplicationInBackground()) {
return;
}
ScreenshotHandler handler = getInstance();
@ -93,6 +120,14 @@ public final class ScreenshotHandler implements Runnable {
handler.screenshotWholePage(tab.getId());
}
private void discardPendingScreenshots() {
synchronized (mPendingScreenshots) {
for (Iterator<PendingScreenshot> i = mPendingScreenshots.iterator(); i.hasNext(); ) {
i.next().discard();
}
}
}
private void screenshotWholePage(int tabId) {
LayerView layerView = GeckoApp.mAppContext.getLayerView();
if (layerView == null) {
@ -111,11 +146,7 @@ public final class ScreenshotHandler implements Runnable {
mTabId = tabId;
clearDirtyRect();
}
synchronized (mPendingScreenshots) {
for (Iterator<PendingScreenshot> i = mPendingScreenshots.iterator(); i.hasNext(); ) {
i.next().discard();
}
}
discardPendingScreenshots();
int dstx = 0;
int dsty = 0;
@ -140,9 +171,6 @@ public final class ScreenshotHandler implements Runnable {
// Called from native code by JNI
public static void notifyPaintedRect(float top, float left, float bottom, float right) {
if (sDisableScreenshot) {
return;
}
ScreenshotHandler handler = getInstance();
if (handler == null) {
return;

View File

@ -2480,6 +2480,9 @@ nsresult AndroidBridge::TakeScreenshot(nsIDOMWindow *window, int32_t srcX, int32
uint32_t stride = bufW * 2 /* 16 bpp */;
void* data = env->GetDirectBufferAddress(buffer);
if (!data)
return NS_ERROR_FAILURE;
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(static_cast<unsigned char*>(data), nsIntSize(bufW, bufH), stride, gfxASurface::ImageFormatRGB16_565);
if (surf->CairoStatus() != 0) {
ALOG_BRIDGE("Error creating gfxImageSurface");