зеркало из https://github.com/mozilla/gecko-dev.git
Bug 791263 - Disable screenshotting under low-memory conditions. r=blassey
This commit is contained in:
Родитель
cf8d576337
Коммит
c596790a8c
|
@ -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");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче