mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-11 08:13:35 +00:00
merge fx-team to mozilla-central
This commit is contained in:
commit
31ed44be3f
@ -635,7 +635,7 @@
|
||||
<method name="handleEvent">
|
||||
<parameter name="aEvent"/>
|
||||
<body><![CDATA[
|
||||
if (aEvent.type == "resize" && aEvent.eventPhase == aEvent.BUBBLING_PHASE) {
|
||||
if (aEvent.type == "resize") {
|
||||
this.resize();
|
||||
}
|
||||
]]></body>
|
||||
@ -682,10 +682,10 @@
|
||||
this.nub.removeAttribute("activity");
|
||||
]]></handler>
|
||||
<handler event="load"><![CDATA[
|
||||
window.addEventListener("resize", this);
|
||||
window.addEventListener("resize", this, true);
|
||||
]]></handler>
|
||||
<handler event="unload"><![CDATA[
|
||||
window.removeEventListener("resize", this);
|
||||
window.removeEventListener("resize", this, true);
|
||||
]]></handler>
|
||||
|
||||
<handler event="dragstart"><![CDATA[
|
||||
|
@ -514,23 +514,19 @@ function resizeWindowToChatAreaWidth(desired, cb, count = 0) {
|
||||
return;
|
||||
}
|
||||
function resize_handler(event) {
|
||||
// for whatever reason, sometimes we get called twice for different event
|
||||
// phases, only handle one of them.
|
||||
if (event.eventPhase != event.AT_TARGET)
|
||||
return;
|
||||
// we did resize - but did we get far enough to be able to continue?
|
||||
let newSize = window.SocialChatBar.chatbar.getBoundingClientRect().width;
|
||||
let sizedOk = widthDeltaCloseEnough(newSize - desired);
|
||||
if (!sizedOk)
|
||||
return;
|
||||
window.removeEventListener("resize", resize_handler);
|
||||
window.removeEventListener("resize", resize_handler, true);
|
||||
info(count + ": resized window width is " + newSize);
|
||||
executeSoon(function() {
|
||||
cb(sizedOk);
|
||||
});
|
||||
}
|
||||
// Otherwise we request resize and expect a resize event
|
||||
window.addEventListener("resize", resize_handler);
|
||||
window.addEventListener("resize", resize_handler, true);
|
||||
window.resizeBy(delta, 0);
|
||||
}
|
||||
|
||||
|
@ -219,15 +219,20 @@ public class Tab {
|
||||
return mThumbnailBitmap;
|
||||
}
|
||||
|
||||
public void updateThumbnail(final Bitmap b) {
|
||||
public void updateThumbnail(final Bitmap b, final ThumbnailHelper.CachePolicy cachePolicy) {
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (b != null) {
|
||||
try {
|
||||
mThumbnail = new BitmapDrawable(mAppContext.getResources(), b);
|
||||
if (mState == Tab.STATE_SUCCESS)
|
||||
if (mState == Tab.STATE_SUCCESS && cachePolicy == ThumbnailHelper.CachePolicy.STORE) {
|
||||
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) {
|
||||
Log.w(LOGTAG, "Unable to create/scale bitmap.", oom);
|
||||
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) {
|
||||
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 enum CachePolicy {
|
||||
STORE,
|
||||
NO_STORE
|
||||
}
|
||||
|
||||
// static singleton stuff
|
||||
|
||||
private static ThumbnailHelper sInstance;
|
||||
@ -63,7 +68,7 @@ public final class ThumbnailHelper {
|
||||
|
||||
public void getAndProcessThumbnailFor(Tab tab) {
|
||||
if (AboutPages.isAboutHome(tab.getURL())) {
|
||||
tab.updateThumbnail(null);
|
||||
tab.updateThumbnail(null, CachePolicy.NO_STORE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -72,7 +77,8 @@ public final class ThumbnailHelper {
|
||||
if (url != null) {
|
||||
byte[] thumbnail = BrowserDB.getThumbnailForUrl(GeckoAppShell.getContext().getContentResolver(), url);
|
||||
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;
|
||||
@ -155,11 +161,11 @@ public final class ThumbnailHelper {
|
||||
|
||||
/* This method is invoked by JNI once the thumbnail data is ready. */
|
||||
@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);
|
||||
ThumbnailHelper helper = ThumbnailHelper.getInstance();
|
||||
if (success && tab != null) {
|
||||
helper.handleThumbnailData(tab, data);
|
||||
helper.handleThumbnailData(tab, data, shouldStore ? CachePolicy.STORE : CachePolicy.NO_STORE);
|
||||
}
|
||||
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());
|
||||
if (data != mBuffer) {
|
||||
// This should never happen, but log it and recover gracefully
|
||||
@ -189,18 +195,18 @@ public final class ThumbnailHelper {
|
||||
}
|
||||
|
||||
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);
|
||||
data.position(0);
|
||||
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 (compressed == 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);
|
||||
}
|
||||
tab.updateThumbnail(bitmap);
|
||||
tab.updateThumbnail(bitmap, cachePolicy);
|
||||
}
|
||||
|
||||
private boolean shouldUpdateThumbnail(Tab tab) {
|
||||
|
@ -838,6 +838,13 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
||||
@Override
|
||||
public void updateThumbnailForUrl(ContentResolver cr, String uri,
|
||||
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();
|
||||
|
||||
byte[] data = null;
|
||||
@ -849,8 +856,8 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Thumbnails.DATA, data);
|
||||
values.put(Thumbnails.URL, uri);
|
||||
values.put(Thumbnails.DATA, data);
|
||||
|
||||
Uri thumbnailsUri = mThumbnailsUriWithProfile.buildUpon().
|
||||
appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true").build();
|
||||
|
@ -10,6 +10,7 @@ pref("datareporting.policy.dataSubmissionPolicyResponseType", "");
|
||||
pref("datareporting.policy.dataSubmissionPolicyResponseTime", "0");
|
||||
pref("datareporting.policy.firstRunTime", "0");
|
||||
|
||||
pref("datareporting.policy.currentPolicyVersion", 2);
|
||||
pref("datareporting.policy.minimumPolicyVersion", 1);
|
||||
pref("datareporting.policy.minimumPolicyVersion.channel-beta", 2);
|
||||
|
||||
|
@ -38,8 +38,6 @@ const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||
// implemented in 2012, so any earlier dates indicate an incorrect clock.
|
||||
const OLDEST_ALLOWED_YEAR = 2012;
|
||||
|
||||
const CURRENT_POLICY_VERSION = 2;
|
||||
|
||||
/**
|
||||
* Represents a request to display data policy.
|
||||
*
|
||||
@ -292,8 +290,19 @@ this.DataReportingPolicy = function (prefs, healthReportPrefs, listener) {
|
||||
this._healthReportPrefs = healthReportPrefs;
|
||||
this._listener = listener;
|
||||
|
||||
// If we've never run before, record the current time.
|
||||
if (!this.firstRunDate.getTime()) {
|
||||
// If the policy version has changed, reset all preferences, so that
|
||||
// the notification reappears.
|
||||
let acceptedVersion = this._prefs.get("dataSubmissionPolicyAcceptedVersion");
|
||||
if (typeof(acceptedVersion) == "number" &&
|
||||
acceptedVersion < this.minimumPolicyVersion) {
|
||||
this._log.info("policy version has changed - resetting all prefs");
|
||||
// We don't want to delay the notification in this case.
|
||||
let firstRunToRestore = this.firstRunDate;
|
||||
this._prefs.resetBranch();
|
||||
this.firstRunDate = firstRunToRestore.getTime() ?
|
||||
firstRunToRestore : this.now();
|
||||
} else if (!this.firstRunDate.getTime()) {
|
||||
// If we've never run before, record the current time.
|
||||
this.firstRunDate = this.now();
|
||||
}
|
||||
|
||||
@ -517,20 +526,17 @@ this.DataReportingPolicy.prototype = Object.freeze({
|
||||
*/
|
||||
get dataSubmissionPolicyAccepted() {
|
||||
// Be conservative and default to false.
|
||||
let enabled = this._prefs.get("dataSubmissionPolicyAccepted", false);
|
||||
if (!enabled)
|
||||
return false;
|
||||
|
||||
let acceptedVersion = this._prefs.get("dataSubmissionPolicyAcceptedVersion");
|
||||
return acceptedVersion >= this.minimumPolicyVersion;
|
||||
return this._prefs.get("dataSubmissionPolicyAccepted", false);
|
||||
},
|
||||
|
||||
set dataSubmissionPolicyAccepted(value) {
|
||||
this._prefs.set("dataSubmissionPolicyAccepted", !!value);
|
||||
if (!!value)
|
||||
this._prefs.set("dataSubmissionPolicyAcceptedVersion", CURRENT_POLICY_VERSION);
|
||||
else
|
||||
if (!!value) {
|
||||
let currentPolicyVersion = this._prefs.get("currentPolicyVersion", 1);
|
||||
this._prefs.set("dataSubmissionPolicyAcceptedVersion", currentPolicyVersion);
|
||||
} else {
|
||||
this._prefs.reset("dataSubmissionPolicyAcceptedVersion");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -8,10 +8,26 @@ const {utils: Cu} = Components;
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/services/datareporting/policy.jsm");
|
||||
Cu.import("resource://testing-common/services/datareporting/mocks.jsm");
|
||||
Cu.import("resource://gre/modules/UpdateChannel.jsm");
|
||||
|
||||
|
||||
function getPolicy(name) {
|
||||
function getPolicy(name,
|
||||
aCurrentPolicyVersion = 1,
|
||||
aMinimumPolicyVersion = 1,
|
||||
aBranchMinimumVersionOverride) {
|
||||
let branch = "testing.datareporting." + name;
|
||||
|
||||
// The version prefs should not be removed on reset, so set them in the
|
||||
// default branch.
|
||||
let defaultPolicyPrefs = new Preferences({ branch: branch + ".policy."
|
||||
, defaultBranch: true });
|
||||
defaultPolicyPrefs.set("currentPolicyVersion", aCurrentPolicyVersion);
|
||||
defaultPolicyPrefs.set("minimumPolicyVersion", aMinimumPolicyVersion);
|
||||
let branchOverridePrefName = "minimumPolicyVersion.channel-" + UpdateChannel.get(false);
|
||||
if (aBranchMinimumVersionOverride !== undefined)
|
||||
defaultPolicyPrefs.set(branchOverridePrefName, aBranchMinimumVersionOverride);
|
||||
else
|
||||
defaultPolicyPrefs.reset(branchOverridePrefName);
|
||||
|
||||
let policyPrefs = new Preferences(branch + ".policy.");
|
||||
let healthReportPrefs = new Preferences(branch + ".healthreport.");
|
||||
|
||||
@ -776,3 +792,72 @@ add_test(function test_pref_change_initiates_deletion() {
|
||||
hrPrefs.set("uploadEnabled", false);
|
||||
});
|
||||
|
||||
add_task(function* test_policy_version() {
|
||||
let policy, policyPrefs, hrPrefs, listener, now, firstRunTime;
|
||||
function createPolicy(shouldBeAccepted = false,
|
||||
currentPolicyVersion = 1, minimumPolicyVersion = 1,
|
||||
branchMinimumVersionOverride) {
|
||||
[policy, policyPrefs, hrPrefs, listener] =
|
||||
getPolicy("policy_version_test", currentPolicyVersion,
|
||||
minimumPolicyVersion, branchMinimumVersionOverride);
|
||||
let firstRun = now === undefined;
|
||||
if (firstRun) {
|
||||
firstRunTime = policy.firstRunDate.getTime();
|
||||
do_check_true(firstRunTime > 0);
|
||||
now = new Date(policy.firstRunDate.getTime() +
|
||||
policy.SUBMISSION_NOTIFY_INTERVAL_MSEC);
|
||||
}
|
||||
else {
|
||||
// The first-run time should not be reset even after policy-version
|
||||
// upgrades.
|
||||
do_check_eq(policy.firstRunDate.getTime(), firstRunTime);
|
||||
}
|
||||
defineNow(policy, now);
|
||||
do_check_eq(policy.dataSubmissionPolicyAccepted, shouldBeAccepted);
|
||||
}
|
||||
|
||||
function* triggerPolicyCheckAndEnsureNotified(notified = true, accept = true) {
|
||||
policy.checkStateAndTrigger();
|
||||
do_check_eq(listener.notifyUserCount, Number(notified));
|
||||
if (notified) {
|
||||
yield listener.lastNotifyRequest.onUserNotifyComplete();
|
||||
if (accept) {
|
||||
listener.lastNotifyRequest.onUserAccept("because,");
|
||||
do_check_true(policy.dataSubmissionPolicyAccepted);
|
||||
do_check_eq(policyPrefs.get("dataSubmissionPolicyAcceptedVersion"),
|
||||
policyPrefs.get("currentPolicyVersion"));
|
||||
}
|
||||
else {
|
||||
do_check_false(policyPrefs.has("dataSubmissionPolicyAcceptedVersion"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createPolicy();
|
||||
yield triggerPolicyCheckAndEnsureNotified();
|
||||
|
||||
// We shouldn't be notified again if the current version is still valid;
|
||||
createPolicy(true);
|
||||
yield triggerPolicyCheckAndEnsureNotified(false);
|
||||
|
||||
// Just increasing the current version isn't enough. The minimum
|
||||
// version must be changed.
|
||||
let currentPolicyVersion = policyPrefs.get("currentPolicyVersion");
|
||||
let minimumPolicyVersion = policyPrefs.get("minimumPolicyVersion");
|
||||
createPolicy(true, ++currentPolicyVersion, minimumPolicyVersion);
|
||||
yield triggerPolicyCheckAndEnsureNotified(false);
|
||||
do_check_true(policy.dataSubmissionPolicyAccepted);
|
||||
do_check_eq(policyPrefs.get("dataSubmissionPolicyAcceptedVersion"),
|
||||
minimumPolicyVersion);
|
||||
|
||||
// Increase the minimum policy version and check if we're notified.
|
||||
createPolicy(false, currentPolicyVersion, ++minimumPolicyVersion);
|
||||
do_check_false(policyPrefs.has("dataSubmissionPolicyAcceptedVersion"));
|
||||
yield triggerPolicyCheckAndEnsureNotified();
|
||||
|
||||
// Test increasing the minimum version just on the current channel.
|
||||
createPolicy(true, currentPolicyVersion, minimumPolicyVersion);
|
||||
yield triggerPolicyCheckAndEnsureNotified(false);
|
||||
createPolicy(false, ++currentPolicyVersion, minimumPolicyVersion, minimumPolicyVersion + 1);
|
||||
yield triggerPolicyCheckAndEnsureNotified(true);
|
||||
});
|
||||
|
@ -11,28 +11,7 @@ const CACHE_MAX_GROUP_ENTRIES = 100;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
/**
|
||||
* Remotes the service. All the remoting/electrolysis code is in here,
|
||||
* so the regular service code below remains uncluttered and maintainable.
|
||||
*/
|
||||
function electrolify(service) {
|
||||
// FIXME: For now, use the wrappedJSObject hack, until bug
|
||||
// 593407 which will clean that up.
|
||||
// Note that we also use this in the xpcshell tests, separately.
|
||||
service.wrappedJSObject = service;
|
||||
|
||||
var appInfo = Cc["@mozilla.org/xre/app-info;1"];
|
||||
if (appInfo && appInfo.getService(Ci.nsIXULRuntime).processType !=
|
||||
Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT)
|
||||
{
|
||||
// Child process
|
||||
service._dbInit = function(){}; // No local DB
|
||||
}
|
||||
}
|
||||
|
||||
function ContentPrefService() {
|
||||
electrolify(this);
|
||||
|
||||
// If this throws an exception, it causes the getService call to fail,
|
||||
// but the next time a consumer tries to retrieve the service, we'll try
|
||||
// to initialize the database again, which might work if the failure
|
||||
@ -72,7 +51,6 @@ ContentPrefService.prototype = {
|
||||
QueryInterface: function CPS_QueryInterface(iid) {
|
||||
let supportedIIDs = [
|
||||
Ci.nsIContentPrefService,
|
||||
Ci.nsIFrameMessageListener,
|
||||
Ci.nsISupports,
|
||||
];
|
||||
if (supportedIIDs.some(function (i) iid.equals(i)))
|
||||
|
@ -2,5 +2,4 @@ component {e3f772f3-023f-4b32-b074-36cf0fd5d414} nsContentPrefService.js
|
||||
contract @mozilla.org/content-pref/service;1 {e3f772f3-023f-4b32-b074-36cf0fd5d414}
|
||||
component {8df290ae-dcaa-4c11-98a5-2429a4dc97bb} nsContentPrefService.js
|
||||
contract @mozilla.org/content-pref/hostname-grouper;1 {8df290ae-dcaa-4c11-98a5-2429a4dc97bb}
|
||||
category wakeup-request nsContentPrefService @mozilla.org/content-pref/service;1,nsIContentPrefService,getService,ContentPref:getPref,ContentPref:setPref
|
||||
|
||||
|
@ -322,7 +322,7 @@ Preferences.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
resetBranch: function(prefBranch) {
|
||||
resetBranch: function(prefBranch = "") {
|
||||
try {
|
||||
this._prefSvc.resetBranch(prefBranch);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <android/log.h>
|
||||
#include <dlfcn.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "mozilla/Hal.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
@ -40,6 +41,7 @@
|
||||
#include "NativeJSContainer.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget::android;
|
||||
@ -305,6 +307,68 @@ AutoGlobalWrappedJavaObject::~AutoGlobalWrappedJavaObject() {
|
||||
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
|
||||
getHandlersFromStringArray(JNIEnv *aJNIEnv, jobjectArray jArr, jsize aLen,
|
||||
nsIMutableArray *aHandlersArray,
|
||||
@ -1694,7 +1758,7 @@ AndroidBridge::GetFrameNameJavaProfiling(uint32_t aThreadId, uint32_t aSampleId,
|
||||
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;
|
||||
float scale = 1.0;
|
||||
@ -1744,10 +1808,16 @@ nsresult AndroidBridge::CaptureThumbnail(nsIDOMWindow *window, int32_t bufW, int
|
||||
if (!win)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsRefPtr<nsPresContext> presContext;
|
||||
|
||||
nsIDocShell* docshell = win->GetDocShell();
|
||||
|
||||
// Decide if callers should store this thumbnail for later use.
|
||||
shouldStore = ShouldStoreThumbnail(docshell);
|
||||
|
||||
if (docshell) {
|
||||
docshell->GetPresContext(getter_AddRefs(presContext));
|
||||
}
|
||||
|
||||
if (!presContext)
|
||||
return NS_ERROR_FAILURE;
|
||||
nscolor bgColor = NS_RGB(255, 255, 255);
|
||||
|
@ -195,7 +195,7 @@ public:
|
||||
bool GetThreadNameJavaProfiling(uint32_t aThreadId, 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 ContentDocumentChanged();
|
||||
bool IsContentDocumentDisplayed();
|
||||
|
@ -1534,7 +1534,7 @@ void ThumbnailHelper::InitStubs(JNIEnv *jEnv) {
|
||||
initInit();
|
||||
|
||||
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) {
|
||||
@ -1544,17 +1544,18 @@ ThumbnailHelper* ThumbnailHelper::Wrap(jobject obj) {
|
||||
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();
|
||||
if (env->PushLocalFrame(1) != 0) {
|
||||
AndroidBridge::HandleUncaughtException(env);
|
||||
MOZ_CRASH("Exception should have caused crash.");
|
||||
}
|
||||
|
||||
jvalue args[3];
|
||||
jvalue args[4];
|
||||
args[0].l = a0;
|
||||
args[1].i = a1;
|
||||
args[2].z = a2;
|
||||
args[3].z = a3;
|
||||
|
||||
env->CallStaticVoidMethodA(mThumbnailHelperClass, jSendThumbnail, args);
|
||||
AndroidBridge::HandleUncaughtException(env);
|
||||
|
@ -260,7 +260,7 @@ public:
|
||||
static void InitStubs(JNIEnv *jEnv);
|
||||
static ThumbnailHelper* Wrap(jobject obj);
|
||||
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() {};
|
||||
protected:
|
||||
static jclass mThumbnailHelperClass;
|
||||
|
@ -85,20 +85,21 @@ public:
|
||||
nsCOMPtr<nsIBrowserTab> tab;
|
||||
mBrowserApp->GetBrowserTab(mTabId, getter_AddRefs(tab));
|
||||
if (!tab) {
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false);
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false, false);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
tab->GetWindow(getter_AddRefs(domWindow));
|
||||
if (!domWindow) {
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false);
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, false, false);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
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);
|
||||
mozilla::widget::android::ThumbnailHelper::SendThumbnail(buffer, mTabId, NS_SUCCEEDED(rv));
|
||||
bool shouldStore = true;
|
||||
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;
|
||||
}
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user