Bug 996129 - Don't thumbnail sites with cache control headers set. r=kats
This commit is contained in:
@@ -219,15 +219,20 @@ public class Tab {
|
|||||||
return mThumbnailBitmap;
|
return mThumbnailBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateThumbnail(final Bitmap b) {
|
public void updateThumbnail(final Bitmap b, final ThumbnailHelper.CachePolicy cachePolicy) {
|
||||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (b != null) {
|
if (b != null) {
|
||||||
try {
|
try {
|
||||||
mThumbnail = new BitmapDrawable(mAppContext.getResources(), b);
|
mThumbnail = new BitmapDrawable(mAppContext.getResources(), b);
|
||||||
if (mState == Tab.STATE_SUCCESS)
|
if (mState == Tab.STATE_SUCCESS && cachePolicy == ThumbnailHelper.CachePolicy.STORE) {
|
||||||
saveThumbnailToDB();
|
saveThumbnailToDB();
|
||||||
|
} else {
|
||||||
|
// If the page failed to load, or requested that we not cache info about it, clear any previous
|
||||||
|
// thumbnails we've stored.
|
||||||
|
clearThumbnailFromDB();
|
||||||
|
}
|
||||||
} catch (OutOfMemoryError oom) {
|
} catch (OutOfMemoryError oom) {
|
||||||
Log.w(LOGTAG, "Unable to create/scale bitmap.", oom);
|
Log.w(LOGTAG, "Unable to create/scale bitmap.", oom);
|
||||||
mThumbnail = null;
|
mThumbnail = null;
|
||||||
@@ -717,6 +722,19 @@ public class Tab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clearThumbnailFromDB() {
|
||||||
|
try {
|
||||||
|
String url = getURL();
|
||||||
|
if (url == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Passing in a null thumbnail will delete the stored thumbnail for this url
|
||||||
|
BrowserDB.updateThumbnailForUrl(getContentResolver(), url, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addPluginView(View view) {
|
public void addPluginView(View view) {
|
||||||
mPluginViews.add(view);
|
mPluginViews.add(view);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ public final class ThumbnailHelper {
|
|||||||
|
|
||||||
public static final float THUMBNAIL_ASPECT_RATIO = 0.571f; // this is a 4:7 ratio (as per UX decision)
|
public static final float THUMBNAIL_ASPECT_RATIO = 0.571f; // this is a 4:7 ratio (as per UX decision)
|
||||||
|
|
||||||
|
public static enum CachePolicy {
|
||||||
|
STORE,
|
||||||
|
NO_STORE
|
||||||
|
}
|
||||||
|
|
||||||
// static singleton stuff
|
// static singleton stuff
|
||||||
|
|
||||||
private static ThumbnailHelper sInstance;
|
private static ThumbnailHelper sInstance;
|
||||||
@@ -63,7 +68,7 @@ public final class ThumbnailHelper {
|
|||||||
|
|
||||||
public void getAndProcessThumbnailFor(Tab tab) {
|
public void getAndProcessThumbnailFor(Tab tab) {
|
||||||
if (AboutPages.isAboutHome(tab.getURL())) {
|
if (AboutPages.isAboutHome(tab.getURL())) {
|
||||||
tab.updateThumbnail(null);
|
tab.updateThumbnail(null, CachePolicy.NO_STORE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +77,8 @@ public final class ThumbnailHelper {
|
|||||||
if (url != null) {
|
if (url != null) {
|
||||||
byte[] thumbnail = BrowserDB.getThumbnailForUrl(GeckoAppShell.getContext().getContentResolver(), url);
|
byte[] thumbnail = BrowserDB.getThumbnailForUrl(GeckoAppShell.getContext().getContentResolver(), url);
|
||||||
if (thumbnail != null) {
|
if (thumbnail != null) {
|
||||||
setTabThumbnail(tab, null, thumbnail);
|
// Since this thumbnail is from the database, its ok to store it
|
||||||
|
setTabThumbnail(tab, null, thumbnail, CachePolicy.STORE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -155,11 +161,11 @@ public final class ThumbnailHelper {
|
|||||||
|
|
||||||
/* This method is invoked by JNI once the thumbnail data is ready. */
|
/* This method is invoked by JNI once the thumbnail data is ready. */
|
||||||
@WrapElementForJNI(stubName = "SendThumbnail")
|
@WrapElementForJNI(stubName = "SendThumbnail")
|
||||||
public static void notifyThumbnail(ByteBuffer data, int tabId, boolean success) {
|
public static void notifyThumbnail(ByteBuffer data, int tabId, boolean success, boolean shouldStore) {
|
||||||
Tab tab = Tabs.getInstance().getTab(tabId);
|
Tab tab = Tabs.getInstance().getTab(tabId);
|
||||||
ThumbnailHelper helper = ThumbnailHelper.getInstance();
|
ThumbnailHelper helper = ThumbnailHelper.getInstance();
|
||||||
if (success && tab != null) {
|
if (success && tab != null) {
|
||||||
helper.handleThumbnailData(tab, data);
|
helper.handleThumbnailData(tab, data, shouldStore ? CachePolicy.STORE : CachePolicy.NO_STORE);
|
||||||
}
|
}
|
||||||
helper.processNextThumbnail(tab);
|
helper.processNextThumbnail(tab);
|
||||||
}
|
}
|
||||||
@@ -181,7 +187,7 @@ public final class ThumbnailHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleThumbnailData(Tab tab, ByteBuffer data) {
|
private void handleThumbnailData(Tab tab, ByteBuffer data, CachePolicy cachePolicy) {
|
||||||
Log.d(LOGTAG, "handleThumbnailData: " + data.capacity());
|
Log.d(LOGTAG, "handleThumbnailData: " + data.capacity());
|
||||||
if (data != mBuffer) {
|
if (data != mBuffer) {
|
||||||
// This should never happen, but log it and recover gracefully
|
// This should never happen, but log it and recover gracefully
|
||||||
@@ -189,18 +195,18 @@ public final class ThumbnailHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (shouldUpdateThumbnail(tab)) {
|
if (shouldUpdateThumbnail(tab)) {
|
||||||
processThumbnailData(tab, data);
|
processThumbnailData(tab, data, cachePolicy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processThumbnailData(Tab tab, ByteBuffer data) {
|
private void processThumbnailData(Tab tab, ByteBuffer data, CachePolicy cachePolicy) {
|
||||||
Bitmap b = tab.getThumbnailBitmap(mWidth, mHeight);
|
Bitmap b = tab.getThumbnailBitmap(mWidth, mHeight);
|
||||||
data.position(0);
|
data.position(0);
|
||||||
b.copyPixelsFromBuffer(data);
|
b.copyPixelsFromBuffer(data);
|
||||||
setTabThumbnail(tab, b, null);
|
setTabThumbnail(tab, b, null, cachePolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTabThumbnail(Tab tab, Bitmap bitmap, byte[] compressed) {
|
private void setTabThumbnail(Tab tab, Bitmap bitmap, byte[] compressed, CachePolicy cachePolicy) {
|
||||||
if (bitmap == null) {
|
if (bitmap == null) {
|
||||||
if (compressed == null) {
|
if (compressed == null) {
|
||||||
Log.w(LOGTAG, "setTabThumbnail: one of bitmap or compressed must be non-null!");
|
Log.w(LOGTAG, "setTabThumbnail: one of bitmap or compressed must be non-null!");
|
||||||
@@ -208,7 +214,7 @@ public final class ThumbnailHelper {
|
|||||||
}
|
}
|
||||||
bitmap = BitmapUtils.decodeByteArray(compressed);
|
bitmap = BitmapUtils.decodeByteArray(compressed);
|
||||||
}
|
}
|
||||||
tab.updateThumbnail(bitmap);
|
tab.updateThumbnail(bitmap, cachePolicy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldUpdateThumbnail(Tab tab) {
|
private boolean shouldUpdateThumbnail(Tab tab) {
|
||||||
|
|||||||
@@ -838,6 +838,13 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
|||||||
@Override
|
@Override
|
||||||
public void updateThumbnailForUrl(ContentResolver cr, String uri,
|
public void updateThumbnailForUrl(ContentResolver cr, String uri,
|
||||||
BitmapDrawable thumbnail) {
|
BitmapDrawable thumbnail) {
|
||||||
|
|
||||||
|
// If a null thumbnail was passed in, delete the stored thumbnail for this url.
|
||||||
|
if (thumbnail == null) {
|
||||||
|
cr.delete(mThumbnailsUriWithProfile, Thumbnails.URL + " == ?", new String[] { uri });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Bitmap bitmap = thumbnail.getBitmap();
|
Bitmap bitmap = thumbnail.getBitmap();
|
||||||
|
|
||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
@@ -849,8 +856,8 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(Thumbnails.DATA, data);
|
|
||||||
values.put(Thumbnails.URL, uri);
|
values.put(Thumbnails.URL, uri);
|
||||||
|
values.put(Thumbnails.DATA, data);
|
||||||
|
|
||||||
Uri thumbnailsUri = mThumbnailsUriWithProfile.buildUpon().
|
Uri thumbnailsUri = mThumbnailsUriWithProfile.buildUpon().
|
||||||
appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true").build();
|
appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true").build();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "mozilla/Hal.h"
|
#include "mozilla/Hal.h"
|
||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
#include "NativeJSContainer.h"
|
#include "NativeJSContainer.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
|
#include "nsIHttpChannel.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::widget::android;
|
using namespace mozilla::widget::android;
|
||||||
@@ -305,6 +307,68 @@ AutoGlobalWrappedJavaObject::~AutoGlobalWrappedJavaObject() {
|
|||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decides if we should store thumbnails for a given docshell based on the presence
|
||||||
|
// of a Cache-Control: no-store header and the "browser.cache.disk_cache_ssl" pref.
|
||||||
|
static bool ShouldStoreThumbnail(nsIDocShell* docshell) {
|
||||||
|
if (!docshell) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIChannel> channel;
|
||||||
|
|
||||||
|
docshell->GetCurrentDocumentChannel(getter_AddRefs(channel));
|
||||||
|
if (!channel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpChannel> httpChannel;
|
||||||
|
rv = channel->QueryInterface(NS_GET_IID(nsIHttpChannel), getter_AddRefs(httpChannel));
|
||||||
|
if (!NS_SUCCEEDED(rv)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't store thumbnails for sites that didn't load
|
||||||
|
uint32_t responseStatus;
|
||||||
|
rv = httpChannel->GetResponseStatus(&responseStatus);
|
||||||
|
if (!NS_SUCCEEDED(rv) || floor((double) (responseStatus / 100)) != 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache-Control: no-store.
|
||||||
|
bool isNoStoreResponse = false;
|
||||||
|
httpChannel->IsNoStoreResponse(&isNoStoreResponse);
|
||||||
|
if (isNoStoreResponse) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deny storage if we're viewing a HTTPS page with a
|
||||||
|
// 'Cache-Control' header having a value that is not 'public'.
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
rv = channel->GetURI(getter_AddRefs(uri));
|
||||||
|
if (!NS_SUCCEEDED(rv)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't capture HTTPS pages unless the user enabled it
|
||||||
|
// or the page has a Cache-Control:public header.
|
||||||
|
bool isHttps = false;
|
||||||
|
uri->SchemeIs("https", &isHttps);
|
||||||
|
if (isHttps && !Preferences::GetBool("browser.cache.disk_cache_ssl", false)) {
|
||||||
|
nsAutoCString cacheControl;
|
||||||
|
rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Cache-Control"), cacheControl);
|
||||||
|
if (!NS_SUCCEEDED(rv)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cacheControl.IsEmpty() && !cacheControl.LowerCaseEqualsLiteral("public")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen,
|
getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen,
|
||||||
nsIMutableArray *aHandlersArray,
|
nsIMutableArray *aHandlersArray,
|
||||||
@@ -1694,7 +1758,7 @@ AndroidBridge::GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer)
|
nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer, bool &shouldStore)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
float scale = 1.0;
|
float scale = 1.0;
|
||||||
@@ -1744,10 +1808,16 @@ nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int
|
|||||||
if (!win)
|
if (!win)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
nsRefPtr<nsPresContext> presContext;
|
nsRefPtr<nsPresContext> presContext;
|
||||||
|
|
||||||
nsIDocShell* docshell = win->GetDocShell();
|
nsIDocShell* docshell = win->GetDocShell();
|
||||||
|
|
||||||
|
// Decide if callers should store this thumbnail for later use.
|
||||||
|
shouldStore = ShouldStoreThumbnail(docshell);
|
||||||
|
|
||||||
if (docshell) {
|
if (docshell) {
|
||||||
docshell->GetPresContext(getter_AddRefs(presContext));
|
docshell->GetPresContext(getter_AddRefs(presContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!presContext)
|
if (!presContext)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
nscolor bgColor = NS_RGB(255, 255, 255);
|
nscolor bgColor = NS_RGB(255, 255, 255);
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ public:
|
|||||||
bool GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult);
|
bool GetThreadNameJavaProfiling(uint32_t aThreadId, nsCString & aResult);
|
||||||
bool GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId, uint32_t aFrameId, nsCString & aResult);
|
bool GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId, uint32_t aFrameId, nsCString & aResult);
|
||||||
|
|
||||||
nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer);
|
nsresult CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int32_t bufH, int32_t tabId, jobject buffer, bool &shouldStore);
|
||||||
void GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
|
void GetDisplayPort(bool aPageSizeUpdate, bool aIsBrowserContentDisplayed, int32_t tabId, nsIAndroidViewport* metrics, nsIAndroidDisplayport** displayPort);
|
||||||
void ContentDocumentChanged();
|
void ContentDocumentChanged();
|
||||||
bool IsContentDocumentDisplayed();
|
bool IsContentDocumentDisplayed();
|
||||||
|
|||||||
@@ -1534,7 +1534,7 @@ void ThumbnailHelper::InitStubs(JNIEnv *jEnv) {
|
|||||||
initInit();
|
initInit();
|
||||||
|
|
||||||
mThumbnailHelperClass = getClassGlobalRef("org/mozilla/gecko/ThumbnailHelper");
|
mThumbnailHelperClass = getClassGlobalRef("org/mozilla/gecko/ThumbnailHelper");
|
||||||
jSendThumbnail = getStaticMethod("notifyThumbnail", "(Ljava/nio/ByteBuffer;IZ)V");
|
jSendThumbnail = getStaticMethod("notifyThumbnail", "(Ljava/nio/ByteBuffer;IZZ)V");
|
||||||
}
|
}
|
||||||
|
|
||||||
ThumbnailHelper* ThumbnailHelper::Wrap(jobject obj) {
|
ThumbnailHelper* ThumbnailHelper::Wrap(jobject obj) {
|
||||||
@@ -1544,17 +1544,18 @@ ThumbnailHelper* ThumbnailHelper::Wrap(jobject obj) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThumbnailHelper::SendThumbnail(jobject a0, int32_t a1, bool a2) {
|
void ThumbnailHelper::SendThumbnail(jobject a0, int32_t a1, bool a2, bool a3) {
|
||||||
JNIEnv *env = AndroidBridge::GetJNIEnv();
|
JNIEnv *env = AndroidBridge::GetJNIEnv();
|
||||||
if (env->PushLocalFrame(1) != 0) {
|
if (env->PushLocalFrame(1) != 0) {
|
||||||
AndroidBridge::HandleUncaughtException(env);
|
AndroidBridge::HandleUncaughtException(env);
|
||||||
MOZ_CRASH("Exception should have caused crash.");
|
MOZ_CRASH("Exception should have caused crash.");
|
||||||
}
|
}
|
||||||
|
|
||||||
jvalue args[3];
|
jvalue args[4];
|
||||||
args[0].l = a0;
|
args[0].l = a0;
|
||||||
args[1].i = a1;
|
args[1].i = a1;
|
||||||
args[2].z = a2;
|
args[2].z = a2;
|
||||||
|
args[3].z = a3;
|
||||||
|
|
||||||
env->CallStaticVoidMethodA(mThumbnailHelperClass, jSendThumbnail, args);
|
env->CallStaticVoidMethodA(mThumbnailHelperClass, jSendThumbnail, args);
|
||||||
AndroidBridge::HandleUncaughtException(env);
|
AndroidBridge::HandleUncaughtException(env);
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ public:
|
|||||||
static void InitStubs(JNIEnv *jEnv);
|
static void InitStubs(JNIEnv *jEnv);
|
||||||
static ThumbnailHelper* Wrap(jobject obj);
|
static ThumbnailHelper* Wrap(jobject obj);
|
||||||
ThumbnailHelper(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
|
ThumbnailHelper(jobject obj, JNIEnv* env) : AutoGlobalWrappedJavaObject(obj, env) {};
|
||||||
static void SendThumbnail(jobject a0, int32_t a1, bool a2);
|
static void SendThumbnail(jobject a0, int32_t a1, bool a2, bool a3);
|
||||||
ThumbnailHelper() : AutoGlobalWrappedJavaObject() {};
|
ThumbnailHelper() : AutoGlobalWrappedJavaObject() {};
|
||||||
protected:
|
protected:
|
||||||
static jclass mThumbnailHelperClass;
|
static jclass mThumbnailHelperClass;
|
||||||
|
|||||||
@@ -85,20 +85,21 @@ public:
|
|||||||
nsCOMPtr<nsIBrowserTab> tab;
|
nsCOMPtr<nsIBrowserTab> tab;
|
||||||
mBrowserApp->GetBrowserTab(mTabId, getter_AddRefs(tab));
|
mBrowserApp->GetBrowserTab(mTabId, getter_AddRefs(tab));
|
||||||
if (!tab) {
|
if (!tab) {
|
||||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false);
|
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false, false);
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tab->GetWindow(getter_AddRefs(domWindow));
|
tab->GetWindow(getter_AddRefs(domWindow));
|
||||||
if (!domWindow) {
|
if (!domWindow) {
|
||||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false);
|
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false, false);
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(mPoints.Length() == 1, "Thumbnail event does not have enough coordinates");
|
NS_ASSERTION(mPoints.Length() == 1, "Thumbnail event does not have enough coordinates");
|
||||||
|
|
||||||
nsresult rv = AndroidBridge::Bridge()->CaptureThumbnail(domWindow, mPoints[0].x, mPoints[0].y, mTabId, buffer);
|
bool shouldStore = true;
|
||||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv));
|
nsresult rv = AndroidBridge::Bridge()->CaptureThumbnail(domWindow, mPoints[0].x, mPoints[0].y, mTabId, buffer, shouldStore);
|
||||||
|
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv), shouldStore);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user