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
Родитель cf8d576337
Коммит c596790a8c
3 изменённых файлов: 59 добавлений и 18 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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