зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central. r=merge a=merge
MozReview-Commit-ID: IrMqWiJhwan
This commit is contained in:
Коммит
ddd4030358
|
@ -2,7 +2,7 @@
|
||||||
support-files =
|
support-files =
|
||||||
head.js
|
head.js
|
||||||
[browser_appmenu_reflows.js]
|
[browser_appmenu_reflows.js]
|
||||||
skip-if = (os == 'mac' || os == 'win') && debug # Bug 1382809
|
skip-if = asan || debug # Bug 1382809, bug 1369959
|
||||||
[browser_startup.js]
|
[browser_startup.js]
|
||||||
[browser_startup_content.js]
|
[browser_startup_content.js]
|
||||||
skip-if = !e10s
|
skip-if = !e10s
|
||||||
|
|
|
@ -7,13 +7,12 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.importGlobalProperties(["fetch"]);
|
Cu.importGlobalProperties(["fetch"]);
|
||||||
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
|
|
||||||
"resource://gre/modules/Preferences.jsm");
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||||
"resource://gre/modules/Services.jsm");
|
"resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
const ACTIVITY_STREAM_ENABLED_PREF = "browser.newtabpage.activity-stream.enabled";
|
const ACTIVITY_STREAM_ENABLED_PREF = "browser.newtabpage.activity-stream.enabled";
|
||||||
const BROWSER_READY_NOTIFICATION = "sessionstore-windows-restored";
|
const BROWSER_READY_NOTIFICATION = "sessionstore-windows-restored";
|
||||||
|
const PREF_CHANGED_TOPIC = "nsPref:changed";
|
||||||
const REASON_SHUTDOWN_ON_PREF_CHANGE = "PREF_OFF";
|
const REASON_SHUTDOWN_ON_PREF_CHANGE = "PREF_OFF";
|
||||||
const REASON_STARTUP_ON_PREF_CHANGE = "PREF_ON";
|
const REASON_STARTUP_ON_PREF_CHANGE = "PREF_ON";
|
||||||
const RESOURCE_BASE = "resource://activity-stream";
|
const RESOURCE_BASE = "resource://activity-stream";
|
||||||
|
@ -84,10 +83,9 @@ function uninit(reason) {
|
||||||
/**
|
/**
|
||||||
* onPrefChanged - handler for changes to ACTIVITY_STREAM_ENABLED_PREF
|
* onPrefChanged - handler for changes to ACTIVITY_STREAM_ENABLED_PREF
|
||||||
*
|
*
|
||||||
* @param {bool} isEnabled Determines whether Activity Stream is enabled
|
|
||||||
*/
|
*/
|
||||||
function onPrefChanged(isEnabled) {
|
function onPrefChanged() {
|
||||||
if (isEnabled) {
|
if (Services.prefs.getBoolPref(ACTIVITY_STREAM_ENABLED_PREF, false)) {
|
||||||
init(REASON_STARTUP_ON_PREF_CHANGE);
|
init(REASON_STARTUP_ON_PREF_CHANGE);
|
||||||
} else {
|
} else {
|
||||||
uninit(REASON_SHUTDOWN_ON_PREF_CHANGE);
|
uninit(REASON_SHUTDOWN_ON_PREF_CHANGE);
|
||||||
|
@ -101,10 +99,10 @@ function onBrowserReady() {
|
||||||
waitingForBrowserReady = false;
|
waitingForBrowserReady = false;
|
||||||
|
|
||||||
// Listen for changes to the pref that enables Activity Stream
|
// Listen for changes to the pref that enables Activity Stream
|
||||||
Preferences.observe(ACTIVITY_STREAM_ENABLED_PREF, onPrefChanged);
|
Services.prefs.addObserver(ACTIVITY_STREAM_ENABLED_PREF, observe);
|
||||||
|
|
||||||
// Only initialize if the pref is true
|
// Only initialize if the pref is true
|
||||||
if (Preferences.get(ACTIVITY_STREAM_ENABLED_PREF)) {
|
if (Services.prefs.getBoolPref(ACTIVITY_STREAM_ENABLED_PREF, false)) {
|
||||||
init(startupReason);
|
init(startupReason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,6 +117,11 @@ function observe(subject, topic, data) {
|
||||||
// Avoid running synchronously during this event that's used for timing
|
// Avoid running synchronously during this event that's used for timing
|
||||||
Services.tm.dispatchToMainThread(() => onBrowserReady());
|
Services.tm.dispatchToMainThread(() => onBrowserReady());
|
||||||
break;
|
break;
|
||||||
|
case PREF_CHANGED_TOPIC:
|
||||||
|
if (data == ACTIVITY_STREAM_ENABLED_PREF) {
|
||||||
|
onPrefChanged();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +155,7 @@ this.shutdown = function shutdown(data, reason) {
|
||||||
Services.obs.removeObserver(observe, BROWSER_READY_NOTIFICATION);
|
Services.obs.removeObserver(observe, BROWSER_READY_NOTIFICATION);
|
||||||
} else {
|
} else {
|
||||||
// Stop listening to the pref that enables Activity Stream
|
// Stop listening to the pref that enables Activity Stream
|
||||||
Preferences.ignore(ACTIVITY_STREAM_ENABLED_PREF, onPrefChanged);
|
Services.prefs.removeObserver(ACTIVITY_STREAM_ENABLED_PREF, observe);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unload any add-on modules that might might have been imported
|
// Unload any add-on modules that might might have been imported
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
Cu.import("resource://gre/modules/UpdateUtils.jsm");
|
Cu.import("resource://gre/modules/UpdateUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/AppConstants.jsm");
|
Cu.import("resource://gre/modules/AppConstants.jsm");
|
||||||
|
@ -46,13 +46,13 @@ function defineCohort() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cohort = Preferences.get(PREF_COHORT_NAME);
|
let cohort = Services.prefs.getStringPref(PREF_COHORT_NAME);
|
||||||
|
|
||||||
if (!cohort) {
|
if (!cohort) {
|
||||||
// The cohort has not been defined yet: this is the first
|
// The cohort has not been defined yet: this is the first
|
||||||
// time that we're running. Let's see if the user has
|
// time that we're running. Let's see if the user has
|
||||||
// a non-default setting to avoid changing it.
|
// a non-default setting to avoid changing it.
|
||||||
let currentPluginState = Preferences.get(PREF_FLASH_STATE);
|
let currentPluginState = Services.prefs.getIntPref(PREF_FLASH_STATE);
|
||||||
switch (currentPluginState) {
|
switch (currentPluginState) {
|
||||||
case Ci.nsIPluginTag.STATE_CLICKTOPLAY:
|
case Ci.nsIPluginTag.STATE_CLICKTOPLAY:
|
||||||
cohort = "early-adopter-ctp";
|
cohort = "early-adopter-ctp";
|
||||||
|
@ -81,8 +81,8 @@ function defineCohort() {
|
||||||
|
|
||||||
if (userSample < testThreshold) {
|
if (userSample < testThreshold) {
|
||||||
cohort = "test";
|
cohort = "test";
|
||||||
let defaultPrefs = new Preferences({defaultBranch: true});
|
let defaultPrefs = Services.prefs.getDefaultBranch("");
|
||||||
defaultPrefs.set(PREF_FLASH_STATE, Ci.nsIPluginTag.STATE_CLICKTOPLAY);
|
defaultPrefs.setIntPref(PREF_FLASH_STATE, Ci.nsIPluginTag.STATE_CLICKTOPLAY);
|
||||||
} else if (userSample >= 1.0 - testThreshold) {
|
} else if (userSample >= 1.0 - testThreshold) {
|
||||||
cohort = "control";
|
cohort = "control";
|
||||||
} else {
|
} else {
|
||||||
|
@ -105,21 +105,19 @@ function defineCohort() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserSample() {
|
function getUserSample() {
|
||||||
let prefValue = Preferences.get(PREF_COHORT_SAMPLE, undefined);
|
let prefType = Services.prefs.getPrefType(PREF_COHORT_SAMPLE);
|
||||||
let value = 0.0;
|
|
||||||
|
|
||||||
if (typeof(prefValue) == "string") {
|
if (prefType == Ci.nsIPrefBranch.PREF_STRING) {
|
||||||
value = parseFloat(prefValue, 10);
|
return parseFloat(Services.prefs.getStringPref(PREF_COHORT_SAMPLE), 10);
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value = Math.random();
|
let value = Math.random();
|
||||||
Preferences.set(PREF_COHORT_SAMPLE, value.toString().substr(0, 8));
|
Services.prefs.setStringPref(PREF_COHORT_SAMPLE, value.toString().substr(0, 8));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCohort(cohortName) {
|
function setCohort(cohortName) {
|
||||||
Preferences.set(PREF_COHORT_NAME, cohortName);
|
Services.prefs.setStringPref(PREF_COHORT_NAME, cohortName);
|
||||||
TelemetryEnvironment.setExperimentActive("clicktoplay-rollout", cohortName);
|
TelemetryEnvironment.setExperimentActive("clicktoplay-rollout", cohortName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -130,10 +128,10 @@ function setCohort(cohortName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function watchForPrefChanges() {
|
function watchForPrefChanges() {
|
||||||
Preferences.observe(PREF_FLASH_STATE, function prefWatcher() {
|
Services.prefs.addObserver(PREF_FLASH_STATE, function prefWatcher() {
|
||||||
let currentCohort = Preferences.get(PREF_COHORT_NAME, "unknown");
|
let currentCohort = Services.prefs.getStringPref(PREF_COHORT_NAME, "unknown");
|
||||||
setCohort(`user-changed-from-${currentCohort}`);
|
setCohort(`user-changed-from-${currentCohort}`);
|
||||||
Preferences.ignore(PREF_FLASH_STATE, prefWatcher);
|
Services.prefs.removeObserver(PREF_FLASH_STATE, prefWatcher);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
Cu.import("resource://gre/modules/UpdateUtils.jsm");
|
Cu.import("resource://gre/modules/UpdateUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/AppConstants.jsm");
|
Cu.import("resource://gre/modules/AppConstants.jsm");
|
||||||
|
@ -111,13 +110,13 @@ function defineCohort() {
|
||||||
let addonPolicy = "unknown";
|
let addonPolicy = "unknown";
|
||||||
if (updateChannel in ADDON_ROLLOUT_POLICY) {
|
if (updateChannel in ADDON_ROLLOUT_POLICY) {
|
||||||
addonPolicy = ADDON_ROLLOUT_POLICY[updateChannel];
|
addonPolicy = ADDON_ROLLOUT_POLICY[updateChannel];
|
||||||
Preferences.set(PREF_E10S_ADDON_POLICY, addonPolicy);
|
Services.prefs.setStringPref(PREF_E10S_ADDON_POLICY, addonPolicy);
|
||||||
|
|
||||||
// This is also the proper place to set the blocklist pref
|
// This is also the proper place to set the blocklist pref
|
||||||
// in case it is necessary.
|
// in case it is necessary.
|
||||||
Preferences.set(PREF_E10S_ADDON_BLOCKLIST, "");
|
Services.prefs.setStringPref(PREF_E10S_ADDON_BLOCKLIST, "");
|
||||||
} else {
|
} else {
|
||||||
Preferences.reset(PREF_E10S_ADDON_POLICY);
|
Services.prefs.clearUserPref(PREF_E10S_ADDON_POLICY);
|
||||||
}
|
}
|
||||||
|
|
||||||
let userOptedOut = optedOut();
|
let userOptedOut = optedOut();
|
||||||
|
@ -125,7 +124,7 @@ function defineCohort() {
|
||||||
let disqualified = (Services.appinfo.multiprocessBlockPolicy != 0);
|
let disqualified = (Services.appinfo.multiprocessBlockPolicy != 0);
|
||||||
let testThreshold = TEST_THRESHOLD[updateChannel];
|
let testThreshold = TEST_THRESHOLD[updateChannel];
|
||||||
let testGroup = (getUserSample(false) < testThreshold);
|
let testGroup = (getUserSample(false) < testThreshold);
|
||||||
let hasNonExemptAddon = Preferences.get(PREF_E10S_HAS_NONEXEMPT_ADDON, false);
|
let hasNonExemptAddon = Services.prefs.getBoolPref(PREF_E10S_HAS_NONEXEMPT_ADDON, false);
|
||||||
let temporaryDisqualification = getTemporaryDisqualification();
|
let temporaryDisqualification = getTemporaryDisqualification();
|
||||||
let temporaryQualification = getTemporaryQualification();
|
let temporaryQualification = getTemporaryQualification();
|
||||||
|
|
||||||
|
@ -153,24 +152,24 @@ function defineCohort() {
|
||||||
// For these volatile disqualification reasons, however, we must not try
|
// For these volatile disqualification reasons, however, we must not try
|
||||||
// to activate e10s because the backend doesn't know about it. E10S_STATUS
|
// to activate e10s because the backend doesn't know about it. E10S_STATUS
|
||||||
// here will be accumulated as "2 - Disabled", which is fine too.
|
// here will be accumulated as "2 - Disabled", which is fine too.
|
||||||
Preferences.reset(PREF_TOGGLE_E10S);
|
Services.prefs.clearUserPref(PREF_TOGGLE_E10S);
|
||||||
Preferences.reset(PREF_E10S_PROCESSCOUNT + ".web");
|
Services.prefs.clearUserPref(PREF_E10S_PROCESSCOUNT + ".web");
|
||||||
setCohort(`temp-disqualified-${temporaryDisqualification}`);
|
setCohort(`temp-disqualified-${temporaryDisqualification}`);
|
||||||
} else if (!disqualified && testThreshold < 1.0 &&
|
} else if (!disqualified && testThreshold < 1.0 &&
|
||||||
temporaryQualification != "") {
|
temporaryQualification != "") {
|
||||||
// Users who are qualified for e10s and on channels where some population
|
// Users who are qualified for e10s and on channels where some population
|
||||||
// would not receive e10s can be pushed into e10s anyway via a temporary
|
// would not receive e10s can be pushed into e10s anyway via a temporary
|
||||||
// qualification which overrides the user sample value when non-empty.
|
// qualification which overrides the user sample value when non-empty.
|
||||||
Preferences.set(PREF_TOGGLE_E10S, true);
|
Services.prefs.setBoolPref.set(PREF_TOGGLE_E10S, true);
|
||||||
eligibleForMulti = true;
|
eligibleForMulti = true;
|
||||||
setCohort(`temp-qualified-${temporaryQualification}`);
|
setCohort(`temp-qualified-${temporaryQualification}`);
|
||||||
} else if (testGroup) {
|
} else if (testGroup) {
|
||||||
Preferences.set(PREF_TOGGLE_E10S, true);
|
Services.prefs.setBoolPref(PREF_TOGGLE_E10S, true);
|
||||||
eligibleForMulti = true;
|
eligibleForMulti = true;
|
||||||
setCohort(`${cohortPrefix}test`);
|
setCohort(`${cohortPrefix}test`);
|
||||||
} else {
|
} else {
|
||||||
Preferences.reset(PREF_TOGGLE_E10S);
|
Services.prefs.clearUserPref(PREF_TOGGLE_E10S);
|
||||||
Preferences.reset(PREF_E10S_PROCESSCOUNT + ".web");
|
Services.prefs.clearUserPref(PREF_E10S_PROCESSCOUNT + ".web");
|
||||||
setCohort(`${cohortPrefix}control`);
|
setCohort(`${cohortPrefix}control`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +188,7 @@ function defineCohort() {
|
||||||
!eligibleForMulti ||
|
!eligibleForMulti ||
|
||||||
userOptedIn.multi ||
|
userOptedIn.multi ||
|
||||||
disqualified) {
|
disqualified) {
|
||||||
Preferences.reset(PREF_E10S_PROCESSCOUNT + ".web");
|
Services.prefs.clearUserPref(PREF_E10S_PROCESSCOUNT + ".web");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +208,7 @@ function defineCohort() {
|
||||||
for (let sampleName of Object.getOwnPropertyNames(buckets)) {
|
for (let sampleName of Object.getOwnPropertyNames(buckets)) {
|
||||||
if (multiUserSample < buckets[sampleName]) {
|
if (multiUserSample < buckets[sampleName]) {
|
||||||
// NB: Coerce sampleName to an integer because this is an integer pref.
|
// NB: Coerce sampleName to an integer because this is an integer pref.
|
||||||
Preferences.set(PREF_E10S_PROCESSCOUNT + ".web", +sampleName);
|
Services.prefs.setIntPref(PREF_E10S_PROCESSCOUNT + ".web", +sampleName);
|
||||||
setCohort(`${cohortPrefix}multiBucket${sampleName}`);
|
setCohort(`${cohortPrefix}multiBucket${sampleName}`);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -224,27 +223,26 @@ function uninstall() {
|
||||||
|
|
||||||
function getUserSample(multi) {
|
function getUserSample(multi) {
|
||||||
let pref = multi ? (PREF_COHORT_SAMPLE + ".multi") : PREF_COHORT_SAMPLE;
|
let pref = multi ? (PREF_COHORT_SAMPLE + ".multi") : PREF_COHORT_SAMPLE;
|
||||||
let prefValue = Preferences.get(pref, undefined);
|
let prefType = Services.prefs.getPrefType(pref);
|
||||||
let value = 0.0;
|
|
||||||
|
|
||||||
if (typeof(prefValue) == "string") {
|
if (prefType == Ci.nsIPrefBranch.PREF_STRING) {
|
||||||
value = parseFloat(prefValue, 10);
|
return parseFloat(Services.prefs.getStringPref(pref), 10);
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof(prefValue) == "number") {
|
let value = 0.0;
|
||||||
|
if (prefType == Ci.nsIPrefBranch.PREF_INT) {
|
||||||
// convert old integer value
|
// convert old integer value
|
||||||
value = prefValue / 100;
|
value = Services.prefs.getIntPref(pref) / 100;
|
||||||
} else {
|
} else {
|
||||||
value = Math.random();
|
value = Math.random();
|
||||||
}
|
}
|
||||||
|
|
||||||
Preferences.set(pref, value.toString().substr(0, 8));
|
Services.prefs.setStringPref(pref, value.toString().substr(0, 8));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCohort(cohortName) {
|
function setCohort(cohortName) {
|
||||||
Preferences.set(PREF_COHORT_NAME, cohortName);
|
Services.prefs.setStringPref(PREF_COHORT_NAME, cohortName);
|
||||||
if (cohortName != "unsupportedChannel") {
|
if (cohortName != "unsupportedChannel") {
|
||||||
TelemetryEnvironment.setExperimentActive("e10sCohort", cohortName);
|
TelemetryEnvironment.setExperimentActive("e10sCohort", cohortName);
|
||||||
}
|
}
|
||||||
|
@ -256,10 +254,10 @@ function setCohort(cohortName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function optedIn() {
|
function optedIn() {
|
||||||
let e10s = Preferences.get(PREF_E10S_OPTED_IN, false) ||
|
let e10s = Services.prefs.getBoolPref(PREF_E10S_OPTED_IN, false) ||
|
||||||
Preferences.get(PREF_E10S_FORCE_ENABLED, false);
|
Services.prefs.getBoolPref(PREF_E10S_FORCE_ENABLED, false);
|
||||||
let multi = Preferences.isSet(PREF_E10S_PROCESSCOUNT) ||
|
let multi = Services.prefs.prefHasUserValue(PREF_E10S_PROCESSCOUNT) ||
|
||||||
!Preferences.get(PREF_USE_DEFAULT_PERF_SETTINGS, true);
|
!Services.prefs.getBoolPref(PREF_USE_DEFAULT_PERF_SETTINGS, true);
|
||||||
return { e10s, multi };
|
return { e10s, multi };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,10 +265,10 @@ function optedOut() {
|
||||||
// Users can also opt-out by toggling back the pref to false.
|
// Users can also opt-out by toggling back the pref to false.
|
||||||
// If they reset the pref instead they might be re-enabled if
|
// If they reset the pref instead they might be re-enabled if
|
||||||
// they are still part of the threshold.
|
// they are still part of the threshold.
|
||||||
let e10s = Preferences.get(PREF_E10S_FORCE_DISABLED, false) ||
|
let e10s = Services.prefs.getBoolPref(PREF_E10S_FORCE_DISABLED, false) ||
|
||||||
(Preferences.isSet(PREF_TOGGLE_E10S) &&
|
(Services.prefs.prefHasUserValue(PREF_TOGGLE_E10S) &&
|
||||||
Preferences.get(PREF_TOGGLE_E10S) == false);
|
Services.prefs.getBoolPref(PREF_TOGGLE_E10S) == false);
|
||||||
let multi = Preferences.get(PREF_E10S_MULTI_OPTOUT, 0) >=
|
let multi = Services.prefs.getIntPref(PREF_E10S_MULTI_OPTOUT, 0) >=
|
||||||
Services.appinfo.E10S_MULTI_EXPERIMENT;
|
Services.appinfo.E10S_MULTI_EXPERIMENT;
|
||||||
return { e10s, multi };
|
return { e10s, multi };
|
||||||
}
|
}
|
||||||
|
@ -297,7 +295,7 @@ function getTemporaryQualification() {
|
||||||
// system. If this pref is set, then it means the user has opened DevTools at
|
// system. If this pref is set, then it means the user has opened DevTools at
|
||||||
// some point in time.
|
// some point in time.
|
||||||
const PREF_OPENED_DEVTOOLS = "devtools.telemetry.tools.opened.version";
|
const PREF_OPENED_DEVTOOLS = "devtools.telemetry.tools.opened.version";
|
||||||
let hasOpenedDevTools = Preferences.isSet(PREF_OPENED_DEVTOOLS);
|
let hasOpenedDevTools = Services.prefs.prefHasUserValue(PREF_OPENED_DEVTOOLS);
|
||||||
if (hasOpenedDevTools) {
|
if (hasOpenedDevTools) {
|
||||||
return "devtools";
|
return "devtools";
|
||||||
}
|
}
|
||||||
|
@ -306,6 +304,6 @@ function getTemporaryQualification() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAddonsDisqualifyForMulti() {
|
function getAddonsDisqualifyForMulti() {
|
||||||
return Preferences.get("extensions.e10sMultiBlocksEnabling", false) &&
|
return Services.prefs.getBoolPref("extensions.e10sMultiBlocksEnabling", false) &&
|
||||||
Preferences.get("extensions.e10sMultiBlockedByAddons", false);
|
Services.prefs.getBoolPref("extensions.e10sMultiBlockedByAddons", false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,26 +5,26 @@
|
||||||
/* globals APP_STARTUP, ADDON_INSTALL */
|
/* globals APP_STARTUP, ADDON_INSTALL */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const {utils: Cu} = Components;
|
const {utils: Cu, interfaces: Ci} = Components;
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "OnboardingTourType",
|
XPCOMUtils.defineLazyModuleGetter(this, "OnboardingTourType",
|
||||||
"resource://onboarding/modules/OnboardingTourType.jsm");
|
"resource://onboarding/modules/OnboardingTourType.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
|
|
||||||
"resource://gre/modules/Preferences.jsm");
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||||
"resource://gre/modules/Services.jsm");
|
"resource://gre/modules/Services.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
|
XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
|
||||||
"resource://gre/modules/FxAccounts.jsm");
|
"resource://gre/modules/FxAccounts.jsm");
|
||||||
|
|
||||||
|
const {PREF_STRING, PREF_BOOL, PREF_INT} = Ci.nsIPrefBranch;
|
||||||
|
|
||||||
const BROWSER_READY_NOTIFICATION = "browser-delayed-startup-finished";
|
const BROWSER_READY_NOTIFICATION = "browser-delayed-startup-finished";
|
||||||
const BROWSER_SESSION_STORE_NOTIFICATION = "sessionstore-windows-restored";
|
const BROWSER_SESSION_STORE_NOTIFICATION = "sessionstore-windows-restored";
|
||||||
const PREF_WHITELIST = [
|
const PREF_WHITELIST = [
|
||||||
"browser.onboarding.enabled",
|
["browser.onboarding.enabled", PREF_BOOL],
|
||||||
"browser.onboarding.hidden",
|
["browser.onboarding.hidden", PREF_BOOL],
|
||||||
"browser.onboarding.notification.finished",
|
["browser.onboarding.notification.finished", PREF_BOOL],
|
||||||
"browser.onboarding.notification.prompt-count",
|
["browser.onboarding.notification.prompt-count", PREF_INT],
|
||||||
"browser.onboarding.notification.last-time-of-changing-tour-sec",
|
["browser.onboarding.notification.last-time-of-changing-tour-sec", PREF_INT],
|
||||||
"browser.onboarding.notification.tour-ids-queue"
|
["browser.onboarding.notification.tour-ids-queue", PREF_STRING],
|
||||||
];
|
];
|
||||||
|
|
||||||
[
|
[
|
||||||
|
@ -37,7 +37,7 @@ const PREF_WHITELIST = [
|
||||||
"onboarding-tour-search",
|
"onboarding-tour-search",
|
||||||
"onboarding-tour-singlesearch",
|
"onboarding-tour-singlesearch",
|
||||||
"onboarding-tour-sync",
|
"onboarding-tour-sync",
|
||||||
].forEach(tourId => PREF_WHITELIST.push(`browser.onboarding.tour.${tourId}.completed`));
|
].forEach(tourId => PREF_WHITELIST.push([`browser.onboarding.tour.${tourId}.completed`, PREF_BOOL]));
|
||||||
|
|
||||||
let waitingForBrowserReady = true;
|
let waitingForBrowserReady = true;
|
||||||
|
|
||||||
|
@ -53,8 +53,28 @@ let waitingForBrowserReady = true;
|
||||||
**/
|
**/
|
||||||
function setPrefs(prefs) {
|
function setPrefs(prefs) {
|
||||||
prefs.forEach(pref => {
|
prefs.forEach(pref => {
|
||||||
if (PREF_WHITELIST.includes(pref.name)) {
|
let prefObj = PREF_WHITELIST.find(([name, ]) => name == pref.name);
|
||||||
Preferences.set(pref.name, pref.value);
|
if (!prefObj) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [name, type] = prefObj;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case PREF_BOOL:
|
||||||
|
Services.prefs.setBoolPref(name, pref.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PREF_INT:
|
||||||
|
Services.prefs.setIntPref(name, pref.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PREF_STRING:
|
||||||
|
Services.prefs.setStringPref(name, pref.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new TypeError(`Unexpected type (${type}) for preference ${name}.`)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
|
||||||
|
|
||||||
const ONBOARDING_CSS_URL = "resource://onboarding/onboarding.css";
|
const ONBOARDING_CSS_URL = "resource://onboarding/onboarding.css";
|
||||||
const ABOUT_HOME_URL = "about:home";
|
const ABOUT_HOME_URL = "about:home";
|
||||||
|
@ -445,14 +445,14 @@ class Onboarding {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
for (let [name, callback] of this._prefsObserved) {
|
for (let [name, callback] of this._prefsObserved) {
|
||||||
Preferences.observe(name, callback);
|
Services.prefs.addObserver(name, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_clearPrefObserver() {
|
_clearPrefObserver() {
|
||||||
if (this._prefsObserved) {
|
if (this._prefsObserved) {
|
||||||
for (let [name, callback] of this._prefsObserved) {
|
for (let [name, callback] of this._prefsObserved) {
|
||||||
Preferences.ignore(name, callback);
|
Services.prefs.removeObserver(name, callback);
|
||||||
}
|
}
|
||||||
this._prefsObserved = null;
|
this._prefsObserved = null;
|
||||||
}
|
}
|
||||||
|
@ -556,7 +556,7 @@ class Onboarding {
|
||||||
}
|
}
|
||||||
|
|
||||||
isTourCompleted(tourId) {
|
isTourCompleted(tourId) {
|
||||||
return Preferences.get(`browser.onboarding.tour.${tourId}.completed`, false);
|
return Services.prefs.getBoolPref(`browser.onboarding.tour.${tourId}.completed`, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
setToursCompleted(tourIds) {
|
setToursCompleted(tourIds) {
|
||||||
|
@ -583,12 +583,12 @@ class Onboarding {
|
||||||
}
|
}
|
||||||
|
|
||||||
_muteNotificationOnFirstSession() {
|
_muteNotificationOnFirstSession() {
|
||||||
if (Preferences.isSet("browser.onboarding.notification.tour-ids-queue")) {
|
if (Services.prefs.prefHasUserValue("browser.onboarding.notification.tour-ids-queue")) {
|
||||||
// There is a queue. We had prompted before, this must not be the 1st session.
|
// There is a queue. We had prompted before, this must not be the 1st session.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let muteDuration = Preferences.get("browser.onboarding.notification.mute-duration-on-first-session-ms");
|
let muteDuration = Services.prefs.getIntPref("browser.onboarding.notification.mute-duration-on-first-session-ms");
|
||||||
if (muteDuration == 0) {
|
if (muteDuration == 0) {
|
||||||
// Don't mute when this is set to 0 on purpose.
|
// Don't mute when this is set to 0 on purpose.
|
||||||
return false;
|
return false;
|
||||||
|
@ -596,7 +596,7 @@ class Onboarding {
|
||||||
|
|
||||||
// Reuse the `last-time-of-changing-tour-sec` to save the time that
|
// Reuse the `last-time-of-changing-tour-sec` to save the time that
|
||||||
// we try to prompt on the 1st session.
|
// we try to prompt on the 1st session.
|
||||||
let lastTime = 1000 * Preferences.get("browser.onboarding.notification.last-time-of-changing-tour-sec", 0);
|
let lastTime = 1000 * Services.prefs.getIntPref("browser.onboarding.notification.last-time-of-changing-tour-sec", 0);
|
||||||
if (lastTime <= 0) {
|
if (lastTime <= 0) {
|
||||||
sendMessageToChrome("set-prefs", [{
|
sendMessageToChrome("set-prefs", [{
|
||||||
name: "browser.onboarding.notification.last-time-of-changing-tour-sec",
|
name: "browser.onboarding.notification.last-time-of-changing-tour-sec",
|
||||||
|
@ -608,14 +608,14 @@ class Onboarding {
|
||||||
}
|
}
|
||||||
|
|
||||||
_isTimeForNextTourNotification() {
|
_isTimeForNextTourNotification() {
|
||||||
let promptCount = Preferences.get("browser.onboarding.notification.prompt-count", 0);
|
let promptCount = Services.prefs.getIntPref("browser.onboarding.notification.prompt-count", 0);
|
||||||
let maxCount = Preferences.get("browser.onboarding.notification.max-prompt-count-per-tour");
|
let maxCount = Services.prefs.getIntPref("browser.onboarding.notification.max-prompt-count-per-tour");
|
||||||
if (promptCount >= maxCount) {
|
if (promptCount >= maxCount) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let lastTime = 1000 * Preferences.get("browser.onboarding.notification.last-time-of-changing-tour-sec", 0);
|
let lastTime = 1000 * Services.prefs.getIntPref("browser.onboarding.notification.last-time-of-changing-tour-sec", 0);
|
||||||
let maxTime = Preferences.get("browser.onboarding.notification.max-life-time-per-tour-ms");
|
let maxTime = Services.prefs.getIntPref("browser.onboarding.notification.max-life-time-per-tour-ms");
|
||||||
if (lastTime && Date.now() - lastTime >= maxTime) {
|
if (lastTime && Date.now() - lastTime >= maxTime) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -643,8 +643,8 @@ class Onboarding {
|
||||||
|
|
||||||
_getNotificationQueue() {
|
_getNotificationQueue() {
|
||||||
let queue = "";
|
let queue = "";
|
||||||
if (Preferences.isSet("browser.onboarding.notification.tour-ids-queue")) {
|
if (Services.prefs.prefHasUserValue("browser.onboarding.notification.tour-ids-queue")) {
|
||||||
queue = Preferences.get("browser.onboarding.notification.tour-ids-queue");
|
queue = Services.prefs.getStringPref("browser.onboarding.notification.tour-ids-queue");
|
||||||
} else {
|
} else {
|
||||||
// For each tour, it only gets 2 chances to prompt with notification
|
// For each tour, it only gets 2 chances to prompt with notification
|
||||||
// (each chance includes 8 impressions or 5-days max life time)
|
// (each chance includes 8 impressions or 5-days max life time)
|
||||||
|
@ -664,7 +664,7 @@ class Onboarding {
|
||||||
}
|
}
|
||||||
|
|
||||||
showNotification() {
|
showNotification() {
|
||||||
if (Preferences.get("browser.onboarding.notification.finished", false)) {
|
if (Services.prefs.getBoolPref("browser.onboarding.notification.finished", false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,7 +729,7 @@ class Onboarding {
|
||||||
value: queue.join(",")
|
value: queue.join(",")
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let promptCount = Preferences.get(PROMPT_COUNT_PREF, 0);
|
let promptCount = Services.prefs.getIntPref(PROMPT_COUNT_PREF, 0);
|
||||||
params.push({
|
params.push({
|
||||||
name: PROMPT_COUNT_PREF,
|
name: PROMPT_COUNT_PREF,
|
||||||
value: promptCount + 1
|
value: promptCount + 1
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
This is the PDF.js project output, https://github.com/mozilla/pdf.js
|
This is the PDF.js project output, https://github.com/mozilla/pdf.js
|
||||||
|
|
||||||
Current extension version is: 1.8.581
|
Current extension version is: 1.8.593
|
||||||
|
|
||||||
Taken from upstream commit: 343b4dc2
|
Taken from upstream commit: f62d0a10
|
||||||
|
|
|
@ -105,7 +105,7 @@ exports.unreachable = exports.warn = exports.utf8StringToString = exports.string
|
||||||
|
|
||||||
__w_pdfjs_require__(15);
|
__w_pdfjs_require__(15);
|
||||||
|
|
||||||
var _streamsLib = __w_pdfjs_require__(9);
|
var _streams_polyfill = __w_pdfjs_require__(16);
|
||||||
|
|
||||||
var globalScope = typeof window !== 'undefined' && window.Math === Math ? window : typeof global !== 'undefined' && global.Math === Math ? global : typeof self !== 'undefined' && self.Math === Math ? self : undefined;
|
var globalScope = typeof window !== 'undefined' && window.Math === Math ? window : typeof global !== 'undefined' && global.Math === Math ? global : typeof self !== 'undefined' && self.Math === Math ? self : undefined;
|
||||||
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
|
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
|
||||||
|
@ -1131,7 +1131,7 @@ MessageHandler.prototype = {
|
||||||
let streamId = this.streamId++;
|
let streamId = this.streamId++;
|
||||||
let sourceName = this.sourceName;
|
let sourceName = this.sourceName;
|
||||||
let targetName = this.targetName;
|
let targetName = this.targetName;
|
||||||
return new _streamsLib.ReadableStream({
|
return new _streams_polyfill.ReadableStream({
|
||||||
start: controller => {
|
start: controller => {
|
||||||
let startCapability = createPromiseCapability();
|
let startCapability = createPromiseCapability();
|
||||||
this.streamControllers[streamId] = {
|
this.streamControllers[streamId] = {
|
||||||
|
@ -1435,7 +1435,7 @@ exports.readInt8 = readInt8;
|
||||||
exports.readUint16 = readUint16;
|
exports.readUint16 = readUint16;
|
||||||
exports.readUint32 = readUint32;
|
exports.readUint32 = readUint32;
|
||||||
exports.removeNullCharacters = removeNullCharacters;
|
exports.removeNullCharacters = removeNullCharacters;
|
||||||
exports.ReadableStream = _streamsLib.ReadableStream;
|
exports.ReadableStream = _streams_polyfill.ReadableStream;
|
||||||
exports.setVerbosityLevel = setVerbosityLevel;
|
exports.setVerbosityLevel = setVerbosityLevel;
|
||||||
exports.shadow = shadow;
|
exports.shadow = shadow;
|
||||||
exports.string32 = string32;
|
exports.string32 = string32;
|
||||||
|
@ -2505,7 +2505,14 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
|
||||||
}
|
}
|
||||||
return worker.messageHandler.sendWithPromise('GetDocRequest', {
|
return worker.messageHandler.sendWithPromise('GetDocRequest', {
|
||||||
docId,
|
docId,
|
||||||
source,
|
source: {
|
||||||
|
data: source.data,
|
||||||
|
url: source.url,
|
||||||
|
password: source.password,
|
||||||
|
disableAutoFetch: source.disableAutoFetch,
|
||||||
|
rangeChunkSize: source.rangeChunkSize,
|
||||||
|
length: source.length
|
||||||
|
},
|
||||||
maxImageSize: (0, _dom_utils.getDefaultSetting)('maxImageSize'),
|
maxImageSize: (0, _dom_utils.getDefaultSetting)('maxImageSize'),
|
||||||
disableFontFace: (0, _dom_utils.getDefaultSetting)('disableFontFace'),
|
disableFontFace: (0, _dom_utils.getDefaultSetting)('disableFontFace'),
|
||||||
disableCreateObjectURL: (0, _dom_utils.getDefaultSetting)('disableCreateObjectURL'),
|
disableCreateObjectURL: (0, _dom_utils.getDefaultSetting)('disableCreateObjectURL'),
|
||||||
|
@ -3806,8 +3813,8 @@ var _UnsupportedManager = function UnsupportedManagerClosure() {
|
||||||
}();
|
}();
|
||||||
var version, build;
|
var version, build;
|
||||||
{
|
{
|
||||||
exports.version = version = '1.8.581';
|
exports.version = version = '1.8.593';
|
||||||
exports.build = build = '343b4dc2';
|
exports.build = build = 'f62d0a10';
|
||||||
}
|
}
|
||||||
exports.getDocument = getDocument;
|
exports.getDocument = getDocument;
|
||||||
exports.LoopbackPort = LoopbackPort;
|
exports.LoopbackPort = LoopbackPort;
|
||||||
|
@ -4857,8 +4864,8 @@ if (!_util.globalScope.PDFJS) {
|
||||||
}
|
}
|
||||||
var PDFJS = _util.globalScope.PDFJS;
|
var PDFJS = _util.globalScope.PDFJS;
|
||||||
{
|
{
|
||||||
PDFJS.version = '1.8.581';
|
PDFJS.version = '1.8.593';
|
||||||
PDFJS.build = '343b4dc2';
|
PDFJS.build = 'f62d0a10';
|
||||||
}
|
}
|
||||||
PDFJS.pdfBug = false;
|
PDFJS.pdfBug = false;
|
||||||
if (PDFJS.verbosity !== undefined) {
|
if (PDFJS.verbosity !== undefined) {
|
||||||
|
@ -10424,8 +10431,8 @@ exports.PDFDataTransportStream = PDFDataTransportStream;
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
var pdfjsVersion = '1.8.581';
|
var pdfjsVersion = '1.8.593';
|
||||||
var pdfjsBuild = '343b4dc2';
|
var pdfjsBuild = 'f62d0a10';
|
||||||
var pdfjsSharedUtil = __w_pdfjs_require__(0);
|
var pdfjsSharedUtil = __w_pdfjs_require__(0);
|
||||||
var pdfjsDisplayGlobal = __w_pdfjs_require__(8);
|
var pdfjsDisplayGlobal = __w_pdfjs_require__(8);
|
||||||
var pdfjsDisplayAPI = __w_pdfjs_require__(3);
|
var pdfjsDisplayAPI = __w_pdfjs_require__(3);
|
||||||
|
@ -10473,6 +10480,19 @@ exports.StatTimer = pdfjsSharedUtil.StatTimer;
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
/* 16 */
|
||||||
|
/***/ (function(module, exports, __w_pdfjs_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
if (typeof ReadableStream !== 'undefined') {
|
||||||
|
exports.ReadableStream = ReadableStream;
|
||||||
|
} else {
|
||||||
|
exports.ReadableStream = __w_pdfjs_require__(9).ReadableStream;
|
||||||
|
}
|
||||||
|
|
||||||
/***/ })
|
/***/ })
|
||||||
/******/ ]);
|
/******/ ]);
|
||||||
});
|
});
|
|
@ -105,7 +105,7 @@ exports.unreachable = exports.warn = exports.utf8StringToString = exports.string
|
||||||
|
|
||||||
__w_pdfjs_require__(36);
|
__w_pdfjs_require__(36);
|
||||||
|
|
||||||
var _streamsLib = __w_pdfjs_require__(18);
|
var _streams_polyfill = __w_pdfjs_require__(37);
|
||||||
|
|
||||||
var globalScope = typeof window !== 'undefined' && window.Math === Math ? window : typeof global !== 'undefined' && global.Math === Math ? global : typeof self !== 'undefined' && self.Math === Math ? self : undefined;
|
var globalScope = typeof window !== 'undefined' && window.Math === Math ? window : typeof global !== 'undefined' && global.Math === Math ? global : typeof self !== 'undefined' && self.Math === Math ? self : undefined;
|
||||||
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
|
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
|
||||||
|
@ -1131,7 +1131,7 @@ MessageHandler.prototype = {
|
||||||
let streamId = this.streamId++;
|
let streamId = this.streamId++;
|
||||||
let sourceName = this.sourceName;
|
let sourceName = this.sourceName;
|
||||||
let targetName = this.targetName;
|
let targetName = this.targetName;
|
||||||
return new _streamsLib.ReadableStream({
|
return new _streams_polyfill.ReadableStream({
|
||||||
start: controller => {
|
start: controller => {
|
||||||
let startCapability = createPromiseCapability();
|
let startCapability = createPromiseCapability();
|
||||||
this.streamControllers[streamId] = {
|
this.streamControllers[streamId] = {
|
||||||
|
@ -1435,7 +1435,7 @@ exports.readInt8 = readInt8;
|
||||||
exports.readUint16 = readUint16;
|
exports.readUint16 = readUint16;
|
||||||
exports.readUint32 = readUint32;
|
exports.readUint32 = readUint32;
|
||||||
exports.removeNullCharacters = removeNullCharacters;
|
exports.removeNullCharacters = removeNullCharacters;
|
||||||
exports.ReadableStream = _streamsLib.ReadableStream;
|
exports.ReadableStream = _streams_polyfill.ReadableStream;
|
||||||
exports.setVerbosityLevel = setVerbosityLevel;
|
exports.setVerbosityLevel = setVerbosityLevel;
|
||||||
exports.shadow = shadow;
|
exports.shadow = shadow;
|
||||||
exports.string32 = string32;
|
exports.string32 = string32;
|
||||||
|
@ -4176,11 +4176,7 @@ var CalRGBCS = function CalRGBCSClosure() {
|
||||||
dest[destOffset + 2] = Math.round(sB * 255);
|
dest[destOffset + 2] = Math.round(sB * 255);
|
||||||
}
|
}
|
||||||
CalRGBCS.prototype = {
|
CalRGBCS.prototype = {
|
||||||
getRgb: function CalRGBCS_getRgb(src, srcOffset) {
|
getRgb: ColorSpace.prototype.getRgb,
|
||||||
var rgb = new Uint8Array(3);
|
|
||||||
this.getRgbItem(src, srcOffset, rgb, 0);
|
|
||||||
return rgb;
|
|
||||||
},
|
|
||||||
getRgbItem: function CalRGBCS_getRgbItem(src, srcOffset, dest, destOffset) {
|
getRgbItem: function CalRGBCS_getRgbItem(src, srcOffset, dest, destOffset) {
|
||||||
convertToRgb(this, src, srcOffset, dest, destOffset, 1);
|
convertToRgb(this, src, srcOffset, dest, destOffset, 1);
|
||||||
},
|
},
|
||||||
|
@ -39838,8 +39834,8 @@ exports.Type1Parser = Type1Parser;
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
var pdfjsVersion = '1.8.581';
|
var pdfjsVersion = '1.8.593';
|
||||||
var pdfjsBuild = '343b4dc2';
|
var pdfjsBuild = 'f62d0a10';
|
||||||
var pdfjsCoreWorker = __w_pdfjs_require__(17);
|
var pdfjsCoreWorker = __w_pdfjs_require__(17);
|
||||||
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
||||||
|
|
||||||
|
@ -39852,6 +39848,19 @@ exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
/* 37 */
|
||||||
|
/***/ (function(module, exports, __w_pdfjs_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
if (typeof ReadableStream !== 'undefined') {
|
||||||
|
exports.ReadableStream = ReadableStream;
|
||||||
|
} else {
|
||||||
|
exports.ReadableStream = __w_pdfjs_require__(18).ReadableStream;
|
||||||
|
}
|
||||||
|
|
||||||
/***/ })
|
/***/ })
|
||||||
/******/ ]);
|
/******/ ]);
|
||||||
});
|
});
|
|
@ -1331,6 +1331,9 @@ let PDFViewerApplication = {
|
||||||
this.fallback();
|
this.fallback();
|
||||||
},
|
},
|
||||||
progress(level) {
|
progress(level) {
|
||||||
|
if (this.downloadComplete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let percent = Math.round(level * 100);
|
let percent = Math.round(level * 100);
|
||||||
if (percent > this.loadingBar.percent || isNaN(percent)) {
|
if (percent > this.loadingBar.percent || isNaN(percent)) {
|
||||||
this.loadingBar.percent = percent;
|
this.loadingBar.percent = percent;
|
||||||
|
|
|
@ -58,7 +58,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "CleanupManager", "resource://shield-rec
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "JSONFile", "resource://gre/modules/JSONFile.jsm");
|
XPCOMUtils.defineLazyModuleGetter(this, "JSONFile", "resource://gre/modules/JSONFile.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "LogManager", "resource://shield-recipe-client/lib/LogManager.jsm");
|
XPCOMUtils.defineLazyModuleGetter(this, "LogManager", "resource://shield-recipe-client/lib/LogManager.jsm");
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "Preferences", "resource://gre/modules/Preferences.jsm");
|
|
||||||
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryEnvironment", "resource://gre/modules/TelemetryEnvironment.jsm");
|
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryEnvironment", "resource://gre/modules/TelemetryEnvironment.jsm");
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["PreferenceExperiments"];
|
this.EXPORTED_SYMBOLS = ["PreferenceExperiments"];
|
||||||
|
@ -71,14 +70,15 @@ const PREFERENCE_TYPE_MAP = {
|
||||||
integer: Services.prefs.PREF_INT,
|
integer: Services.prefs.PREF_INT,
|
||||||
};
|
};
|
||||||
|
|
||||||
const DefaultPreferences = new Preferences({defaultBranch: true});
|
const UserPreferences = Services.prefs;
|
||||||
|
const DefaultPreferences = Services.prefs.getDefaultBranch("");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum storing Preference modules for each type of preference branch.
|
* Enum storing Preference modules for each type of preference branch.
|
||||||
* @enum {Object}
|
* @enum {Object}
|
||||||
*/
|
*/
|
||||||
const PreferenceBranchType = {
|
const PreferenceBranchType = {
|
||||||
user: Preferences,
|
user: UserPreferences,
|
||||||
default: DefaultPreferences,
|
default: DefaultPreferences,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,6 +101,41 @@ const log = LogManager.getLogger("preference-experiments");
|
||||||
let experimentObservers = new Map();
|
let experimentObservers = new Map();
|
||||||
CleanupManager.addCleanupHandler(() => PreferenceExperiments.stopAllObservers());
|
CleanupManager.addCleanupHandler(() => PreferenceExperiments.stopAllObservers());
|
||||||
|
|
||||||
|
function getPref(prefBranch, prefName, prefType, defaultVal) {
|
||||||
|
switch (prefType) {
|
||||||
|
case "boolean":
|
||||||
|
return prefBranch.getBoolPref(prefName, defaultVal);
|
||||||
|
|
||||||
|
case "string":
|
||||||
|
return prefBranch.getStringPref(prefName, defaultVal);
|
||||||
|
|
||||||
|
case "integer":
|
||||||
|
return prefBranch.getIntPref(prefName, defaultVal);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new TypeError(`Unexpected preference type (${prefType}) for ${prefName}.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPref(prefBranch, prefName, prefType, prefValue) {
|
||||||
|
switch (prefType) {
|
||||||
|
case "boolean":
|
||||||
|
prefBranch.setBoolPref(prefName, prefValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "string":
|
||||||
|
prefBranch.setStringPref(prefName, prefValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "integer":
|
||||||
|
prefBranch.setIntPref(prefName, prefValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new TypeError(`Unexpected preference type (${prefType}) for ${prefName}.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.PreferenceExperiments = {
|
this.PreferenceExperiments = {
|
||||||
/**
|
/**
|
||||||
* Set the default preference value for active experiments that use the
|
* Set the default preference value for active experiments that use the
|
||||||
|
@ -110,11 +145,11 @@ this.PreferenceExperiments = {
|
||||||
for (const experiment of await this.getAllActive()) {
|
for (const experiment of await this.getAllActive()) {
|
||||||
// Set experiment default preferences, since they don't persist between restarts
|
// Set experiment default preferences, since they don't persist between restarts
|
||||||
if (experiment.preferenceBranchType === "default") {
|
if (experiment.preferenceBranchType === "default") {
|
||||||
DefaultPreferences.set(experiment.preferenceName, experiment.preferenceValue);
|
setPref(DefaultPreferences, experiment.preferenceName, experiment.preferenceType, experiment.preferenceValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the current value of the preference is still what we set it to
|
// Check that the current value of the preference is still what we set it to
|
||||||
if (Preferences.get(experiment.preferenceName, undefined) !== experiment.preferenceValue) {
|
if (getPref(UserPreferences, experiment.preferenceName, experiment.preferenceType) !== experiment.preferenceValue) {
|
||||||
// if not, stop the experiment, and skip the remaining steps
|
// if not, stop the experiment, and skip the remaining steps
|
||||||
log.info(`Stopping experiment "${experiment.name}" because its value changed`);
|
log.info(`Stopping experiment "${experiment.name}" because its value changed`);
|
||||||
await this.stop(experiment.name, false);
|
await this.stop(experiment.name, false);
|
||||||
|
@ -125,7 +160,7 @@ this.PreferenceExperiments = {
|
||||||
TelemetryEnvironment.setExperimentActive(experiment.name, experiment.branch);
|
TelemetryEnvironment.setExperimentActive(experiment.name, experiment.branch);
|
||||||
|
|
||||||
// Watch for changes to the experiment's preference
|
// Watch for changes to the experiment's preference
|
||||||
this.startObserver(experiment.name, experiment.preferenceName, experiment.preferenceValue);
|
this.startObserver(experiment.name, experiment.preferenceName, experiment.preferenceType, experiment.preferenceValue);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -207,7 +242,7 @@ this.PreferenceExperiments = {
|
||||||
preferenceName,
|
preferenceName,
|
||||||
preferenceValue,
|
preferenceValue,
|
||||||
preferenceType,
|
preferenceType,
|
||||||
previousPreferenceValue: preferences.get(preferenceName, undefined),
|
previousPreferenceValue: getPref(preferences, preferenceName, preferenceType),
|
||||||
preferenceBranchType,
|
preferenceBranchType,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -225,8 +260,8 @@ this.PreferenceExperiments = {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
preferences.set(preferenceName, preferenceValue);
|
setPref(preferences, preferenceName, preferenceType, preferenceValue);
|
||||||
PreferenceExperiments.startObserver(name, preferenceName, preferenceValue);
|
PreferenceExperiments.startObserver(name, preferenceName, preferenceType, preferenceValue);
|
||||||
store.data[name] = experiment;
|
store.data[name] = experiment;
|
||||||
store.saveSoon();
|
store.saveSoon();
|
||||||
|
|
||||||
|
@ -242,7 +277,7 @@ this.PreferenceExperiments = {
|
||||||
* @throws {Error}
|
* @throws {Error}
|
||||||
* If an observer for the named experiment is already active.
|
* If an observer for the named experiment is already active.
|
||||||
*/
|
*/
|
||||||
startObserver(experimentName, preferenceName, preferenceValue) {
|
startObserver(experimentName, preferenceName, preferenceType, preferenceValue) {
|
||||||
log.debug(`PreferenceExperiments.startObserver(${experimentName})`);
|
log.debug(`PreferenceExperiments.startObserver(${experimentName})`);
|
||||||
|
|
||||||
if (experimentObservers.has(experimentName)) {
|
if (experimentObservers.has(experimentName)) {
|
||||||
|
@ -253,7 +288,8 @@ this.PreferenceExperiments = {
|
||||||
|
|
||||||
const observerInfo = {
|
const observerInfo = {
|
||||||
preferenceName,
|
preferenceName,
|
||||||
observer(newValue) {
|
observer() {
|
||||||
|
let newValue = getPref(UserPreferences, preferenceName, preferenceType);
|
||||||
if (newValue !== preferenceValue) {
|
if (newValue !== preferenceValue) {
|
||||||
PreferenceExperiments.stop(experimentName, false)
|
PreferenceExperiments.stop(experimentName, false)
|
||||||
.catch(Cu.reportError);
|
.catch(Cu.reportError);
|
||||||
|
@ -261,7 +297,7 @@ this.PreferenceExperiments = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
experimentObservers.set(experimentName, observerInfo);
|
experimentObservers.set(experimentName, observerInfo);
|
||||||
Preferences.observe(preferenceName, observerInfo.observer);
|
Services.prefs.addObserver(preferenceName, observerInfo.observer);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -288,7 +324,7 @@ this.PreferenceExperiments = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const {preferenceName, observer} = experimentObservers.get(experimentName);
|
const {preferenceName, observer} = experimentObservers.get(experimentName);
|
||||||
Preferences.ignore(preferenceName, observer);
|
Services.prefs.removeObserver(preferenceName, observer);
|
||||||
experimentObservers.delete(experimentName);
|
experimentObservers.delete(experimentName);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -298,7 +334,7 @@ this.PreferenceExperiments = {
|
||||||
stopAllObservers() {
|
stopAllObservers() {
|
||||||
log.debug("PreferenceExperiments.stopAllObservers()");
|
log.debug("PreferenceExperiments.stopAllObservers()");
|
||||||
for (const {preferenceName, observer} of experimentObservers.values()) {
|
for (const {preferenceName, observer} of experimentObservers.values()) {
|
||||||
Preferences.ignore(preferenceName, observer);
|
Services.prefs.removeObserver(preferenceName, observer);
|
||||||
}
|
}
|
||||||
experimentObservers.clear();
|
experimentObservers.clear();
|
||||||
},
|
},
|
||||||
|
@ -352,15 +388,15 @@ this.PreferenceExperiments = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resetValue) {
|
if (resetValue) {
|
||||||
const {preferenceName, previousPreferenceValue, preferenceBranchType} = experiment;
|
const {preferenceName, preferenceType, previousPreferenceValue, preferenceBranchType} = experiment;
|
||||||
const preferences = PreferenceBranchType[preferenceBranchType];
|
const preferences = PreferenceBranchType[preferenceBranchType];
|
||||||
if (previousPreferenceValue !== undefined) {
|
if (previousPreferenceValue !== undefined) {
|
||||||
preferences.set(preferenceName, previousPreferenceValue);
|
setPref(preferences, preferenceName, preferenceType, previousPreferenceValue);
|
||||||
} else {
|
} else {
|
||||||
// This does nothing if we're on the default branch, which is fine. The
|
// This does nothing if we're on the default branch, which is fine. The
|
||||||
// preference will be reset on next restart, and most preferences should
|
// preference will be reset on next restart, and most preferences should
|
||||||
// have had a default value set before the experiment anyway.
|
// have had a default value set before the experiment anyway.
|
||||||
preferences.reset(preferenceName);
|
preferences.clearUserPref(preferenceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,8 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const {utils: Cu} = Components;
|
const {utils: Cu, interfaces: Ci} = Components;
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
|
||||||
Cu.import("resource://gre/modules/Log.jsm");
|
Cu.import("resource://gre/modules/Log.jsm");
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
|
||||||
|
@ -20,6 +19,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "PreferenceExperiments",
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["ShieldRecipeClient"];
|
this.EXPORTED_SYMBOLS = ["ShieldRecipeClient"];
|
||||||
|
|
||||||
|
const {PREF_STRING, PREF_BOOL, PREF_INT} = Ci.nsIPrefBranch;
|
||||||
|
|
||||||
const REASONS = {
|
const REASONS = {
|
||||||
APP_STARTUP: 1, // The application is starting up.
|
APP_STARTUP: 1, // The application is starting up.
|
||||||
APP_SHUTDOWN: 2, // The application is shutting down.
|
APP_SHUTDOWN: 2, // The application is shutting down.
|
||||||
|
@ -32,14 +33,14 @@ const REASONS = {
|
||||||
};
|
};
|
||||||
const PREF_BRANCH = "extensions.shield-recipe-client.";
|
const PREF_BRANCH = "extensions.shield-recipe-client.";
|
||||||
const DEFAULT_PREFS = {
|
const DEFAULT_PREFS = {
|
||||||
api_url: "https://normandy.cdn.mozilla.net/api/v1",
|
api_url: ["https://normandy.cdn.mozilla.net/api/v1", PREF_STRING],
|
||||||
dev_mode: false,
|
dev_mode: [false, PREF_BOOL],
|
||||||
enabled: true,
|
enabled: [true, PREF_BOOL],
|
||||||
startup_delay_seconds: 300,
|
startup_delay_seconds: [300, PREF_INT],
|
||||||
"logging.level": Log.Level.Warn,
|
"logging.level": [Log.Level.Warn, PREF_INT],
|
||||||
user_id: "",
|
user_id: ["", PREF_STRING],
|
||||||
run_interval_seconds: 86400, // 24 hours
|
run_interval_seconds: [86400, PREF_INT], // 24 hours
|
||||||
first_run: true,
|
first_run: [true, PREF_BOOL],
|
||||||
};
|
};
|
||||||
const PREF_DEV_MODE = "extensions.shield-recipe-client.dev_mode";
|
const PREF_DEV_MODE = "extensions.shield-recipe-client.dev_mode";
|
||||||
const PREF_LOGGING_LEVEL = PREF_BRANCH + "logging.level";
|
const PREF_LOGGING_LEVEL = PREF_BRANCH + "logging.level";
|
||||||
|
@ -57,9 +58,9 @@ this.ShieldRecipeClient = {
|
||||||
|
|
||||||
// Setup logging and listen for changes to logging prefs
|
// Setup logging and listen for changes to logging prefs
|
||||||
LogManager.configure(Services.prefs.getIntPref(PREF_LOGGING_LEVEL));
|
LogManager.configure(Services.prefs.getIntPref(PREF_LOGGING_LEVEL));
|
||||||
Preferences.observe(PREF_LOGGING_LEVEL, LogManager.configure);
|
Services.prefs.addObserver(PREF_LOGGING_LEVEL, LogManager.configure);
|
||||||
CleanupManager.addCleanupHandler(
|
CleanupManager.addCleanupHandler(
|
||||||
() => Preferences.ignore(PREF_LOGGING_LEVEL, LogManager.configure),
|
() => Services.prefs.removeObserver(PREF_LOGGING_LEVEL, LogManager.configure),
|
||||||
);
|
);
|
||||||
log = LogManager.getLogger("bootstrap");
|
log = LogManager.getLogger("bootstrap");
|
||||||
|
|
||||||
|
@ -79,11 +80,26 @@ this.ShieldRecipeClient = {
|
||||||
},
|
},
|
||||||
|
|
||||||
setDefaultPrefs() {
|
setDefaultPrefs() {
|
||||||
for (const [key, val] of Object.entries(DEFAULT_PREFS)) {
|
for (const [key, [val, type]] of Object.entries(DEFAULT_PREFS)) {
|
||||||
const fullKey = PREF_BRANCH + key;
|
const fullKey = PREF_BRANCH + key;
|
||||||
// If someone beat us to setting a default, don't overwrite it.
|
// If someone beat us to setting a default, don't overwrite it.
|
||||||
if (!Preferences.isSet(fullKey)) {
|
if (!Services.prefs.prefHasUserValue(fullKey)) {
|
||||||
Preferences.set(fullKey, val);
|
switch (type) {
|
||||||
|
case PREF_BOOL:
|
||||||
|
Services.prefs.setBoolPref(fullKey, val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PREF_INT:
|
||||||
|
Services.prefs.setIntPref(fullKey, val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PREF_STRING:
|
||||||
|
Services.prefs.setStringPref(fullKey, val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new TypeError(`Unexpected type (${type}) for preference ${fullKey}.`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -97,7 +97,7 @@ add_task(withMockExperiments(withMockPreferences(async function(experiments, moc
|
||||||
});
|
});
|
||||||
ok("test" in experiments, "start saved the experiment");
|
ok("test" in experiments, "start saved the experiment");
|
||||||
ok(
|
ok(
|
||||||
startObserver.calledWith("test", "fake.preference", "newvalue"),
|
startObserver.calledWith("test", "fake.preference", "string", "newvalue"),
|
||||||
"start registered an observer",
|
"start registered an observer",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ add_task(withMockExperiments(withMockPreferences(async function(experiments, moc
|
||||||
preferenceBranchType: "user",
|
preferenceBranchType: "user",
|
||||||
});
|
});
|
||||||
ok(
|
ok(
|
||||||
startObserver.calledWith("test", "fake.preference", "newvalue"),
|
startObserver.calledWith("test", "fake.preference", "string", "newvalue"),
|
||||||
"start registered an observer",
|
"start registered an observer",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -194,9 +194,9 @@ add_task(withMockPreferences(async function(mockPreferences) {
|
||||||
// startObserver should throw if an observer for the experiment is already
|
// startObserver should throw if an observer for the experiment is already
|
||||||
// active.
|
// active.
|
||||||
add_task(withMockExperiments(async function() {
|
add_task(withMockExperiments(async function() {
|
||||||
PreferenceExperiments.startObserver("test", "fake.preference", "newvalue");
|
PreferenceExperiments.startObserver("test", "fake.preference", "string", "newvalue");
|
||||||
Assert.throws(
|
Assert.throws(
|
||||||
() => PreferenceExperiments.startObserver("test", "another.fake", "othervalue"),
|
() => PreferenceExperiments.startObserver("test", "another.fake", "string", "othervalue"),
|
||||||
"startObserver threw due to a conflicting active observer",
|
"startObserver threw due to a conflicting active observer",
|
||||||
);
|
);
|
||||||
PreferenceExperiments.stopAllObservers();
|
PreferenceExperiments.stopAllObservers();
|
||||||
|
@ -205,26 +205,34 @@ add_task(withMockExperiments(async function() {
|
||||||
// startObserver should register an observer that calls stop when a preference
|
// startObserver should register an observer that calls stop when a preference
|
||||||
// changes from its experimental value.
|
// changes from its experimental value.
|
||||||
add_task(withMockExperiments(withMockPreferences(async function(mockExperiments, mockPreferences) {
|
add_task(withMockExperiments(withMockPreferences(async function(mockExperiments, mockPreferences) {
|
||||||
const stop = sinon.stub(PreferenceExperiments, "stop");
|
let tests = [
|
||||||
mockPreferences.set("fake.preference", "startvalue");
|
["string", "startvalue", "experimentvalue", "newvalue"],
|
||||||
|
["boolean", false, true, false],
|
||||||
|
["integer", 1, 2, 42],
|
||||||
|
];
|
||||||
|
|
||||||
// NOTE: startObserver does not modify the pref
|
for (let [type, startvalue, experimentvalue, newvalue] of tests) {
|
||||||
PreferenceExperiments.startObserver("test", "fake.preference", "experimentvalue");
|
const stop = sinon.stub(PreferenceExperiments, "stop");
|
||||||
|
mockPreferences.set("fake.preference" + type, startvalue);
|
||||||
|
|
||||||
// Setting it to the experimental value should not trigger the call.
|
// NOTE: startObserver does not modify the pref
|
||||||
Preferences.set("fake.preference", "experimentvalue");
|
PreferenceExperiments.startObserver("test" + type, "fake.preference" + type, type, experimentvalue);
|
||||||
ok(!stop.called, "Changing to the experimental pref value did not trigger the observer");
|
|
||||||
|
|
||||||
// Setting it to something different should trigger the call.
|
// Setting it to the experimental value should not trigger the call.
|
||||||
Preferences.set("fake.preference", "newvalue");
|
Preferences.set("fake.preference" + type, experimentvalue);
|
||||||
ok(stop.called, "Changing to a different value triggered the observer");
|
ok(!stop.called, "Changing to the experimental pref value did not trigger the observer");
|
||||||
|
|
||||||
PreferenceExperiments.stopAllObservers();
|
// Setting it to something different should trigger the call.
|
||||||
stop.restore();
|
Preferences.set("fake.preference" + type, newvalue);
|
||||||
|
ok(stop.called, "Changing to a different value triggered the observer");
|
||||||
|
|
||||||
|
PreferenceExperiments.stopAllObservers();
|
||||||
|
stop.restore();
|
||||||
|
}
|
||||||
})));
|
})));
|
||||||
|
|
||||||
add_task(withMockExperiments(async function testHasObserver() {
|
add_task(withMockExperiments(async function testHasObserver() {
|
||||||
PreferenceExperiments.startObserver("test", "fake.preference", "experimentValue");
|
PreferenceExperiments.startObserver("test", "fake.preference", "string", "experimentValue");
|
||||||
|
|
||||||
ok(await PreferenceExperiments.hasObserver("test"), "hasObserver detects active observers");
|
ok(await PreferenceExperiments.hasObserver("test"), "hasObserver detects active observers");
|
||||||
ok(
|
ok(
|
||||||
|
@ -248,7 +256,7 @@ add_task(withMockExperiments(withMockPreferences(async function(mockExperiments,
|
||||||
const stop = sinon.stub(PreferenceExperiments, "stop");
|
const stop = sinon.stub(PreferenceExperiments, "stop");
|
||||||
mockPreferences.set("fake.preference", "startvalue");
|
mockPreferences.set("fake.preference", "startvalue");
|
||||||
|
|
||||||
PreferenceExperiments.startObserver("test", "fake.preference", "experimentvalue");
|
PreferenceExperiments.startObserver("test", "fake.preference", "string", "experimentvalue");
|
||||||
PreferenceExperiments.stopObserver("test");
|
PreferenceExperiments.stopObserver("test");
|
||||||
|
|
||||||
// Setting the preference now that the observer is stopped should not call
|
// Setting the preference now that the observer is stopped should not call
|
||||||
|
@ -259,7 +267,7 @@ add_task(withMockExperiments(withMockPreferences(async function(mockExperiments,
|
||||||
// Now that the observer is stopped, start should be able to start a new one
|
// Now that the observer is stopped, start should be able to start a new one
|
||||||
// without throwing.
|
// without throwing.
|
||||||
try {
|
try {
|
||||||
PreferenceExperiments.startObserver("test", "fake.preference", "experimentvalue");
|
PreferenceExperiments.startObserver("test", "fake.preference", "string", "experimentvalue");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ok(false, "startObserver did not throw an error for an observer that was already stopped");
|
ok(false, "startObserver did not throw an error for an observer that was already stopped");
|
||||||
}
|
}
|
||||||
|
@ -274,8 +282,8 @@ add_task(withMockExperiments(withMockPreferences(async function(mockExperiments,
|
||||||
mockPreferences.set("fake.preference", "startvalue");
|
mockPreferences.set("fake.preference", "startvalue");
|
||||||
mockPreferences.set("other.fake.preference", "startvalue");
|
mockPreferences.set("other.fake.preference", "startvalue");
|
||||||
|
|
||||||
PreferenceExperiments.startObserver("test", "fake.preference", "experimentvalue");
|
PreferenceExperiments.startObserver("test", "fake.preference", "string", "experimentvalue");
|
||||||
PreferenceExperiments.startObserver("test2", "other.fake.preference", "experimentvalue");
|
PreferenceExperiments.startObserver("test2", "other.fake.preference", "string", "experimentvalue");
|
||||||
PreferenceExperiments.stopAllObservers();
|
PreferenceExperiments.stopAllObservers();
|
||||||
|
|
||||||
// Setting the preference now that the observers are stopped should not call
|
// Setting the preference now that the observers are stopped should not call
|
||||||
|
@ -287,8 +295,8 @@ add_task(withMockExperiments(withMockPreferences(async function(mockExperiments,
|
||||||
// Now that the observers are stopped, start should be able to start new
|
// Now that the observers are stopped, start should be able to start new
|
||||||
// observers without throwing.
|
// observers without throwing.
|
||||||
try {
|
try {
|
||||||
PreferenceExperiments.startObserver("test", "fake.preference", "experimentvalue");
|
PreferenceExperiments.startObserver("test", "fake.preference", "string", "experimentvalue");
|
||||||
PreferenceExperiments.startObserver("test2", "other.fake.preference", "experimentvalue");
|
PreferenceExperiments.startObserver("test2", "other.fake.preference", "string", "experimentvalue");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ok(false, "startObserver did not throw an error for an observer that was already stopped");
|
ok(false, "startObserver did not throw an error for an observer that was already stopped");
|
||||||
}
|
}
|
||||||
|
@ -349,7 +357,7 @@ add_task(withMockExperiments(withMockPreferences(async function(experiments, moc
|
||||||
previousPreferenceValue: "oldvalue",
|
previousPreferenceValue: "oldvalue",
|
||||||
preferenceBranchType: "default",
|
preferenceBranchType: "default",
|
||||||
});
|
});
|
||||||
PreferenceExperiments.startObserver("test", "fake.preference", "experimentvalue");
|
PreferenceExperiments.startObserver("test", "fake.preference", "string", "experimentvalue");
|
||||||
|
|
||||||
await PreferenceExperiments.stop("test");
|
await PreferenceExperiments.stop("test");
|
||||||
ok(stopObserver.calledWith("test"), "stop removed an observer");
|
ok(stopObserver.calledWith("test"), "stop removed an observer");
|
||||||
|
@ -377,7 +385,7 @@ add_task(withMockExperiments(withMockPreferences(async function(experiments, moc
|
||||||
previousPreferenceValue: "oldvalue",
|
previousPreferenceValue: "oldvalue",
|
||||||
preferenceBranchType: "user",
|
preferenceBranchType: "user",
|
||||||
});
|
});
|
||||||
PreferenceExperiments.startObserver("test", "fake.preference", "experimentvalue");
|
PreferenceExperiments.startObserver("test", "fake.preference", "string", "experimentvalue");
|
||||||
|
|
||||||
await PreferenceExperiments.stop("test");
|
await PreferenceExperiments.stop("test");
|
||||||
ok(stopObserver.calledWith("test"), "stop removed an observer");
|
ok(stopObserver.calledWith("test"), "stop removed an observer");
|
||||||
|
@ -654,7 +662,7 @@ add_task(withMockExperiments(withMockPreferences(async function testInitRegister
|
||||||
await PreferenceExperiments.init();
|
await PreferenceExperiments.init();
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
startObserver.calledWith("test", "fake.preference", "experiment value"),
|
startObserver.calledWith("test", "fake.preference", "string", "experiment value"),
|
||||||
"init registered an observer",
|
"init registered an observer",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1696,7 +1696,10 @@ WebSocketImpl::Init(JSContext* aCx,
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(currentInnerWindow != innerWindow);
|
if (currentInnerWindow == innerWindow) {
|
||||||
|
// The opener may be the same outer window as the parent.
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
innerWindow = currentInnerWindow;
|
innerWindow = currentInnerWindow;
|
||||||
|
|
|
@ -1825,6 +1825,39 @@ nsDOMWindowUtils::GetBoundsWithoutFlushing(nsIDOMElement *aElement,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWindowUtils::NeedsFlush(int32_t aFlushType, bool* aResult)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aResult);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocument> doc = GetDocument();
|
||||||
|
NS_ENSURE_STATE(doc);
|
||||||
|
|
||||||
|
nsIPresShell* presShell = doc->GetShell();
|
||||||
|
NS_ENSURE_STATE(presShell);
|
||||||
|
|
||||||
|
FlushType flushType;
|
||||||
|
switch (aFlushType) {
|
||||||
|
case FLUSH_STYLE:
|
||||||
|
flushType = FlushType::Style;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FLUSH_LAYOUT:
|
||||||
|
flushType = FlushType::Layout;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FLUSH_DISPLAY:
|
||||||
|
flushType = FlushType::Display;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResult = presShell->NeedFlush(flushType);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult)
|
nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7814,9 +7814,10 @@ nsGlobalWindow::PromptOuter(const nsAString& aMessage,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAdoptingString outValue(inoutValue);
|
nsString outValue;
|
||||||
|
outValue.Adopt(inoutValue);
|
||||||
|
|
||||||
if (ok && outValue) {
|
if (ok && inoutValue) {
|
||||||
aReturn.Assign(outValue);
|
aReturn.Assign(outValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1097,7 +1097,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* A list of mutation observers
|
* A list of mutation observers
|
||||||
*/
|
*/
|
||||||
nsTObserverArray<nsIMutationObserver*> mMutationObservers;
|
nsAutoTObserverArray<nsIMutationObserver*, 1> mMutationObservers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object implementing nsIDOMNodeList for this content (childNodes)
|
* An object implementing nsIDOMNodeList for this content (childNodes)
|
||||||
|
@ -1954,7 +1954,7 @@ protected:
|
||||||
return GetExistingSlots();
|
return GetExistingSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsTObserverArray<nsIMutationObserver*> *GetMutationObservers()
|
nsAutoTObserverArray<nsIMutationObserver*, 1> *GetMutationObservers()
|
||||||
{
|
{
|
||||||
return HasSlots() ? &GetExistingSlots()->mMutationObservers : nullptr;
|
return HasSlots() ? &GetExistingSlots()->mMutationObservers : nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,8 +59,8 @@ using mozilla::AutoJSContext;
|
||||||
if (slots && !slots->mMutationObservers.IsEmpty()) { \
|
if (slots && !slots->mMutationObservers.IsEmpty()) { \
|
||||||
/* No need to explicitly notify the first observer first \
|
/* No need to explicitly notify the first observer first \
|
||||||
since that'll happen anyway. */ \
|
since that'll happen anyway. */ \
|
||||||
NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS( \
|
NS_OBSERVER_AUTO_ARRAY_NOTIFY_OBSERVERS( \
|
||||||
slots->mMutationObservers, nsIMutationObserver, \
|
slots->mMutationObservers, nsIMutationObserver, 1, \
|
||||||
func_, params_); \
|
func_, params_); \
|
||||||
} \
|
} \
|
||||||
ShadowRoot* shadow = ShadowRoot::FromNode(node); \
|
ShadowRoot* shadow = ShadowRoot::FromNode(node); \
|
||||||
|
@ -87,8 +87,8 @@ using mozilla::AutoJSContext;
|
||||||
if (slots && !slots->mMutationObservers.IsEmpty()) { \
|
if (slots && !slots->mMutationObservers.IsEmpty()) { \
|
||||||
/* No need to explicitly notify the first observer first \
|
/* No need to explicitly notify the first observer first \
|
||||||
since that'll happen anyway. */ \
|
since that'll happen anyway. */ \
|
||||||
NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS_WITH_QI( \
|
NS_OBSERVER_AUTO_ARRAY_NOTIFY_OBSERVERS_WITH_QI( \
|
||||||
slots->mMutationObservers, nsIMutationObserver, \
|
slots->mMutationObservers, nsIMutationObserver, 1, \
|
||||||
nsIAnimationObserver, func_, params_); \
|
nsIAnimationObserver, func_, params_); \
|
||||||
} \
|
} \
|
||||||
ShadowRoot* shadow = ShadowRoot::FromNode(node); \
|
ShadowRoot* shadow = ShadowRoot::FromNode(node); \
|
||||||
|
@ -292,9 +292,9 @@ nsNodeUtils::LastRelease(nsINode* aNode)
|
||||||
nsINode::nsSlots* slots = aNode->GetExistingSlots();
|
nsINode::nsSlots* slots = aNode->GetExistingSlots();
|
||||||
if (slots) {
|
if (slots) {
|
||||||
if (!slots->mMutationObservers.IsEmpty()) {
|
if (!slots->mMutationObservers.IsEmpty()) {
|
||||||
NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
|
NS_OBSERVER_AUTO_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
|
||||||
nsIMutationObserver,
|
nsIMutationObserver, 1,
|
||||||
NodeWillBeDestroyed, (aNode));
|
NodeWillBeDestroyed, (aNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aNode->IsElement()) {
|
if (aNode->IsElement()) {
|
||||||
|
|
|
@ -137,10 +137,10 @@ public:
|
||||||
{
|
{
|
||||||
nsINode::nsSlots* slots = aContent->GetExistingSlots();
|
nsINode::nsSlots* slots = aContent->GetExistingSlots();
|
||||||
if (slots && !slots->mMutationObservers.IsEmpty()) {
|
if (slots && !slots->mMutationObservers.IsEmpty()) {
|
||||||
NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
|
NS_OBSERVER_AUTO_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
|
||||||
nsIMutationObserver,
|
nsIMutationObserver, 1,
|
||||||
ParentChainChanged,
|
ParentChainChanged,
|
||||||
(aContent));
|
(aContent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<script>
|
||||||
|
onload = function() {
|
||||||
|
function done(success) {
|
||||||
|
var bc = new BroadcastChannel("test_channel");
|
||||||
|
bc.postMessage({success:success});
|
||||||
|
bc.close();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
new WebSocket("ws://mochi.test:8888/tests/dom/base/test/file_websocket_basic");
|
||||||
|
done(true); // no hang!
|
||||||
|
} catch (e) {
|
||||||
|
done(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
|
|
|
@ -65,6 +65,7 @@ support-files =
|
||||||
file_bug1091883_frame.html
|
file_bug1091883_frame.html
|
||||||
file_bug1091883_subframe.html
|
file_bug1091883_subframe.html
|
||||||
file_bug1091883_target.html
|
file_bug1091883_target.html
|
||||||
|
file_bug1384658.html
|
||||||
file_bug28293.sjs
|
file_bug28293.sjs
|
||||||
file_bug326337.xml
|
file_bug326337.xml
|
||||||
file_bug326337_inner.html
|
file_bug326337_inner.html
|
||||||
|
@ -251,6 +252,7 @@ support-files =
|
||||||
file3_setting_opener.html
|
file3_setting_opener.html
|
||||||
file4_setting_opener.html
|
file4_setting_opener.html
|
||||||
PASS.html
|
PASS.html
|
||||||
|
window_bug1384658.html
|
||||||
|
|
||||||
[test_anchor_area_referrer.html]
|
[test_anchor_area_referrer.html]
|
||||||
[test_anchor_area_referrer_changing.html]
|
[test_anchor_area_referrer_changing.html]
|
||||||
|
@ -621,6 +623,8 @@ skip-if = toolkit == 'android'
|
||||||
[test_bug1314032.html]
|
[test_bug1314032.html]
|
||||||
[test_bug1318303.html]
|
[test_bug1318303.html]
|
||||||
[test_bug1375050.html]
|
[test_bug1375050.html]
|
||||||
|
[test_bug1384658.html]
|
||||||
|
skip-if = toolkit == 'android'
|
||||||
[test_caretPositionFromPoint.html]
|
[test_caretPositionFromPoint.html]
|
||||||
[test_change_policy.html]
|
[test_change_policy.html]
|
||||||
[test_clearTimeoutIntervalNoArg.html]
|
[test_clearTimeoutIntervalNoArg.html]
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=1384658
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for Bug 1384658</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
/** Test for Bug 1384658 **/
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
var win = window.open("http://example.com/tests/dom/base/test/window_bug1384658.html",
|
||||||
|
"_blank", "width=100,height=100");
|
||||||
|
var bc = new BroadcastChannel("test_channel");
|
||||||
|
bc.onmessage = ev => {
|
||||||
|
ok(ev.data.success, "We didn't hang");
|
||||||
|
bc.close();
|
||||||
|
win.close();
|
||||||
|
SimpleTest.finish();
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1384658">Mozilla Bug 1384658</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
onload = function() {
|
||||||
|
if (window.location.search == "") {
|
||||||
|
window.open("window_bug1384658.html?opened", "_top", "");
|
||||||
|
} else {
|
||||||
|
var iframeURL = "http://mochi.test:8888/tests/dom/base/test/file_bug1384658.html";
|
||||||
|
var iframe = document.createElement("iframe");
|
||||||
|
iframe.src = iframeURL;
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -995,6 +995,15 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||||
*/
|
*/
|
||||||
nsIDOMClientRect getBoundsWithoutFlushing(in nsIDOMElement aElement);
|
nsIDOMClientRect getBoundsWithoutFlushing(in nsIDOMElement aElement);
|
||||||
|
|
||||||
|
const long FLUSH_STYLE = 0;
|
||||||
|
const long FLUSH_LAYOUT = 1;
|
||||||
|
const long FLUSH_DISPLAY = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if a flush of the given type is needed.
|
||||||
|
*/
|
||||||
|
bool needsFlush(in long aFlushtype);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the bounds of the window's currently loaded document. This will
|
* Returns the bounds of the window's currently loaded document. This will
|
||||||
* generally be (0, 0, pageWidth, pageHeight) but in some cases (e.g. RTL
|
* generally be (0, 0, pageWidth, pageHeight) but in some cases (e.g. RTL
|
||||||
|
|
|
@ -123,6 +123,6 @@ TEST_DIRS += [
|
||||||
'imptests',
|
'imptests',
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'cocoa', 'windows', 'android'):
|
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'cocoa', 'windows'):
|
||||||
TEST_DIRS += ['plugins/test']
|
TEST_DIRS += ['plugins/test']
|
||||||
|
|
||||||
|
|
|
@ -21,43 +21,10 @@ static int gNotOptimized;
|
||||||
#define CALLING_CONVENTION_HACK
|
#define CALLING_CONVENTION_HACK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
#include "AndroidBridge.h"
|
|
||||||
#include "android_npapi.h"
|
|
||||||
#include <android/log.h>
|
|
||||||
#undef ALOG
|
|
||||||
#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoJavaEnv", ## args)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#if defined(XP_UNIX) && !defined(XP_MACOSX)
|
||||||
nsresult
|
|
||||||
PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
|
|
||||||
NPPluginFuncs* pFuncs, NPError* error)
|
|
||||||
{
|
|
||||||
JNIEnv* env = jni::GetEnvForThread();
|
|
||||||
|
|
||||||
mozilla::AutoLocalJNIFrame jniFrame(env);
|
|
||||||
|
|
||||||
if (mNP_Initialize) {
|
|
||||||
*error = mNP_Initialize(bFuncs, pFuncs, env);
|
|
||||||
} else {
|
|
||||||
NP_InitializeFunc pfNP_Initialize = (NP_InitializeFunc)
|
|
||||||
PR_FindFunctionSymbol(mLibrary, "NP_Initialize");
|
|
||||||
if (!pfNP_Initialize)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
*error = pfNP_Initialize(bFuncs, pFuncs, env);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save pointers to functions that get called through PluginLibrary itself.
|
|
||||||
mNPP_New = pFuncs->newp;
|
|
||||||
mNPP_ClearSiteData = pFuncs->clearsitedata;
|
|
||||||
mNPP_GetSitesWithData = pFuncs->getsiteswithdata;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
#elif defined(XP_UNIX) && !defined(XP_MACOSX)
|
|
||||||
nsresult
|
nsresult
|
||||||
PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
|
PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
|
||||||
NPPluginFuncs* pFuncs, NPError* error)
|
NPPluginFuncs* pFuncs, NPError* error)
|
||||||
|
@ -191,7 +158,6 @@ PluginPRLibrary::NPP_New(NPMIMEType pluginType, NPP instance,
|
||||||
if (!mNPP_New)
|
if (!mNPP_New)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
MAIN_THREAD_JNI_REF_GUARD;
|
|
||||||
*error = mNPP_New(pluginType, instance, NP_EMBED, argc, argn, argv, saved);
|
*error = mNPP_New(pluginType, instance, NP_EMBED, argc, argn, argv, saved);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +170,6 @@ PluginPRLibrary::NPP_ClearSiteData(const char* site, uint64_t flags,
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
MAIN_THREAD_JNI_REF_GUARD;
|
|
||||||
NPError result = mNPP_ClearSiteData(site, flags, maxAge);
|
NPError result = mNPP_ClearSiteData(site, flags, maxAge);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
@ -232,7 +197,6 @@ PluginPRLibrary::NPP_GetSitesWithData(nsCOMPtr<nsIGetSitesWithDataCallback> call
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
MAIN_THREAD_JNI_REF_GUARD;
|
|
||||||
char** sites = mNPP_GetSitesWithData();
|
char** sites = mNPP_GetSitesWithData();
|
||||||
if (!sites) {
|
if (!sites) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -1,390 +0,0 @@
|
||||||
/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "base/basictypes.h"
|
|
||||||
#include "AndroidBridge.h"
|
|
||||||
|
|
||||||
#include <android/log.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "assert.h"
|
|
||||||
#include "ANPBase.h"
|
|
||||||
#include "nsIThread.h"
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "mozilla/Mutex.h"
|
|
||||||
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPluginsAudio" , ## args)
|
|
||||||
#define ASSIGN(obj, name) (obj)->name = anp_audio_##name
|
|
||||||
|
|
||||||
/* android.media.AudioTrack */
|
|
||||||
struct AudioTrack {
|
|
||||||
jclass at_class;
|
|
||||||
jmethodID constructor;
|
|
||||||
jmethodID flush;
|
|
||||||
jmethodID pause;
|
|
||||||
jmethodID play;
|
|
||||||
jmethodID setvol;
|
|
||||||
jmethodID stop;
|
|
||||||
jmethodID write;
|
|
||||||
jmethodID getpos;
|
|
||||||
jmethodID getstate;
|
|
||||||
jmethodID release;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum AudioTrackMode {
|
|
||||||
MODE_STATIC = 0,
|
|
||||||
MODE_STREAM = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
/* android.media.AudioManager */
|
|
||||||
enum AudioManagerStream {
|
|
||||||
STREAM_VOICE_CALL = 0,
|
|
||||||
STREAM_SYSTEM = 1,
|
|
||||||
STREAM_RING = 2,
|
|
||||||
STREAM_MUSIC = 3,
|
|
||||||
STREAM_ALARM = 4,
|
|
||||||
STREAM_NOTIFICATION = 5,
|
|
||||||
STREAM_DTMF = 8
|
|
||||||
};
|
|
||||||
|
|
||||||
/* android.media.AudioFormat */
|
|
||||||
enum AudioFormatChannel {
|
|
||||||
CHANNEL_OUT_MONO = 4,
|
|
||||||
CHANNEL_OUT_STEREO = 12
|
|
||||||
};
|
|
||||||
|
|
||||||
enum AudioFormatEncoding {
|
|
||||||
ENCODING_PCM_16BIT = 2,
|
|
||||||
ENCODING_PCM_8BIT = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
enum AudioFormatState {
|
|
||||||
STATE_UNINITIALIZED = 0,
|
|
||||||
STATE_INITIALIZED = 1,
|
|
||||||
STATE_NO_STATIC_DATA = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct AudioTrack at;
|
|
||||||
|
|
||||||
static jclass
|
|
||||||
init_jni_bindings(JNIEnv *jenv) {
|
|
||||||
jclass jc =
|
|
||||||
(jclass)jenv->NewGlobalRef(jenv->FindClass("android/media/AudioTrack"));
|
|
||||||
|
|
||||||
at.constructor = jenv->GetMethodID(jc, "<init>", "(IIIIII)V");
|
|
||||||
at.flush = jenv->GetMethodID(jc, "flush", "()V");
|
|
||||||
at.pause = jenv->GetMethodID(jc, "pause", "()V");
|
|
||||||
at.play = jenv->GetMethodID(jc, "play", "()V");
|
|
||||||
at.setvol = jenv->GetMethodID(jc, "setStereoVolume", "(FF)I");
|
|
||||||
at.stop = jenv->GetMethodID(jc, "stop", "()V");
|
|
||||||
at.write = jenv->GetMethodID(jc, "write", "([BII)I");
|
|
||||||
at.getpos = jenv->GetMethodID(jc, "getPlaybackHeadPosition", "()I");
|
|
||||||
at.getstate = jenv->GetMethodID(jc, "getState", "()I");
|
|
||||||
at.release = jenv->GetMethodID(jc, "release", "()V");
|
|
||||||
|
|
||||||
return jc;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ANPAudioTrack {
|
|
||||||
jobject output_unit;
|
|
||||||
jclass at_class;
|
|
||||||
|
|
||||||
unsigned int rate;
|
|
||||||
unsigned int channels;
|
|
||||||
unsigned int bufferSize;
|
|
||||||
unsigned int isStopped;
|
|
||||||
unsigned int keepGoing;
|
|
||||||
|
|
||||||
mozilla::Mutex lock;
|
|
||||||
|
|
||||||
void* user;
|
|
||||||
ANPAudioCallbackProc proc;
|
|
||||||
ANPSampleFormat format;
|
|
||||||
|
|
||||||
ANPAudioTrack() : lock("ANPAudioTrack") { }
|
|
||||||
};
|
|
||||||
|
|
||||||
class AudioRunnable : public mozilla::Runnable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_NSIRUNNABLE
|
|
||||||
|
|
||||||
AudioRunnable(ANPAudioTrack* aAudioTrack) :
|
|
||||||
Runnable("AudioRunnable")
|
|
||||||
{
|
|
||||||
mTrack = aAudioTrack;
|
|
||||||
}
|
|
||||||
|
|
||||||
ANPAudioTrack* mTrack;
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
AudioRunnable::Run()
|
|
||||||
{
|
|
||||||
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
|
|
||||||
|
|
||||||
mozilla::AutoLocalJNIFrame autoFrame(jenv, 2);
|
|
||||||
|
|
||||||
jbyteArray bytearray = jenv->NewByteArray(mTrack->bufferSize);
|
|
||||||
if (!bytearray) {
|
|
||||||
LOG("AudioRunnable:: Run. Could not create bytearray");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
jbyte *byte = jenv->GetByteArrayElements(bytearray, nullptr);
|
|
||||||
if (!byte) {
|
|
||||||
LOG("AudioRunnable:: Run. Could not create bytearray");
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ANPAudioBuffer buffer;
|
|
||||||
buffer.channelCount = mTrack->channels;
|
|
||||||
buffer.format = mTrack->format;
|
|
||||||
buffer.bufferData = (void*) byte;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// reset the buffer size
|
|
||||||
buffer.size = mTrack->bufferSize;
|
|
||||||
|
|
||||||
{
|
|
||||||
mozilla::MutexAutoLock lock(mTrack->lock);
|
|
||||||
|
|
||||||
if (!mTrack->keepGoing)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Get data from the plugin
|
|
||||||
mTrack->proc(kMoreData_ANPAudioEvent, mTrack->user, &buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer.size == 0) {
|
|
||||||
LOG("%p - kMoreData_ANPAudioEvent", mTrack);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t wroteSoFar = 0;
|
|
||||||
jint retval;
|
|
||||||
do {
|
|
||||||
retval = jenv->CallIntMethod(mTrack->output_unit,
|
|
||||||
at.write,
|
|
||||||
bytearray,
|
|
||||||
wroteSoFar,
|
|
||||||
buffer.size - wroteSoFar);
|
|
||||||
if (retval < 0) {
|
|
||||||
LOG("%p - Write failed %d", mTrack, retval);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
wroteSoFar += retval;
|
|
||||||
|
|
||||||
} while(wroteSoFar < buffer.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
jenv->CallVoidMethod(mTrack->output_unit, at.release);
|
|
||||||
|
|
||||||
jenv->DeleteGlobalRef(mTrack->output_unit);
|
|
||||||
jenv->DeleteGlobalRef(mTrack->at_class);
|
|
||||||
|
|
||||||
delete mTrack;
|
|
||||||
|
|
||||||
jenv->ReleaseByteArrayElements(bytearray, byte, 0);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ANPAudioTrack*
|
|
||||||
anp_audio_newTrack(uint32_t sampleRate, // sampling rate in Hz
|
|
||||||
ANPSampleFormat format,
|
|
||||||
int channelCount, // MONO=1, STEREO=2
|
|
||||||
ANPAudioCallbackProc proc,
|
|
||||||
void* user)
|
|
||||||
{
|
|
||||||
ANPAudioTrack *s = new ANPAudioTrack();
|
|
||||||
if (s == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
|
|
||||||
|
|
||||||
s->at_class = init_jni_bindings(jenv);
|
|
||||||
s->rate = sampleRate;
|
|
||||||
s->channels = channelCount;
|
|
||||||
s->bufferSize = s->rate * s->channels;
|
|
||||||
s->isStopped = true;
|
|
||||||
s->keepGoing = false;
|
|
||||||
s->user = user;
|
|
||||||
s->proc = proc;
|
|
||||||
s->format = format;
|
|
||||||
|
|
||||||
int jformat;
|
|
||||||
switch (format) {
|
|
||||||
case kPCM16Bit_ANPSampleFormat:
|
|
||||||
jformat = ENCODING_PCM_16BIT;
|
|
||||||
break;
|
|
||||||
case kPCM8Bit_ANPSampleFormat:
|
|
||||||
jformat = ENCODING_PCM_8BIT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG("Unknown audio format. defaulting to 16bit.");
|
|
||||||
jformat = ENCODING_PCM_16BIT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int jChannels;
|
|
||||||
switch (channelCount) {
|
|
||||||
case 1:
|
|
||||||
jChannels = CHANNEL_OUT_MONO;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
jChannels = CHANNEL_OUT_STEREO;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG("Unknown channel count. defaulting to mono.");
|
|
||||||
jChannels = CHANNEL_OUT_MONO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::AutoLocalJNIFrame autoFrame(jenv);
|
|
||||||
|
|
||||||
jobject obj = jenv->NewObject(s->at_class,
|
|
||||||
at.constructor,
|
|
||||||
STREAM_MUSIC,
|
|
||||||
s->rate,
|
|
||||||
jChannels,
|
|
||||||
jformat,
|
|
||||||
s->bufferSize,
|
|
||||||
MODE_STREAM);
|
|
||||||
|
|
||||||
if (autoFrame.CheckForException() || obj == nullptr) {
|
|
||||||
jenv->DeleteGlobalRef(s->at_class);
|
|
||||||
delete s;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
jint state = jenv->CallIntMethod(obj, at.getstate);
|
|
||||||
|
|
||||||
if (autoFrame.CheckForException() || state == STATE_UNINITIALIZED) {
|
|
||||||
jenv->DeleteGlobalRef(s->at_class);
|
|
||||||
delete s;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->output_unit = jenv->NewGlobalRef(obj);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_audio_deleteTrack(ANPAudioTrack* s)
|
|
||||||
{
|
|
||||||
if (s == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::MutexAutoLock lock(s->lock);
|
|
||||||
s->keepGoing = false;
|
|
||||||
|
|
||||||
// deallocation happens in the AudioThread. There is a
|
|
||||||
// potential leak if anp_audio_start is never called, but
|
|
||||||
// we do not see that from flash.
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_audio_start(ANPAudioTrack* s)
|
|
||||||
{
|
|
||||||
if (s == nullptr || s->output_unit == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->keepGoing) {
|
|
||||||
// we are already playing. Ignore.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
|
|
||||||
|
|
||||||
mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
|
|
||||||
jenv->CallVoidMethod(s->output_unit, at.play);
|
|
||||||
|
|
||||||
if (autoFrame.CheckForException()) {
|
|
||||||
jenv->DeleteGlobalRef(s->at_class);
|
|
||||||
delete s;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->isStopped = false;
|
|
||||||
s->keepGoing = true;
|
|
||||||
|
|
||||||
// AudioRunnable now owns the ANPAudioTrack
|
|
||||||
RefPtr<AudioRunnable> runnable = new AudioRunnable(s);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIThread> thread;
|
|
||||||
NS_NewNamedThread("Android Audio", getter_AddRefs(thread), runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_audio_pause(ANPAudioTrack* s)
|
|
||||||
{
|
|
||||||
if (s == nullptr || s->output_unit == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
|
|
||||||
|
|
||||||
mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
|
|
||||||
jenv->CallVoidMethod(s->output_unit, at.pause);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_audio_stop(ANPAudioTrack* s)
|
|
||||||
{
|
|
||||||
if (s == nullptr || s->output_unit == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->isStopped = true;
|
|
||||||
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
|
|
||||||
|
|
||||||
mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
|
|
||||||
jenv->CallVoidMethod(s->output_unit, at.stop);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
anp_audio_isStopped(ANPAudioTrack* s)
|
|
||||||
{
|
|
||||||
return s->isStopped;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
anp_audio_trackLatency(ANPAudioTrack* s) {
|
|
||||||
// Hardcode an estimate of the system's audio latency. Flash hardcodes
|
|
||||||
// similar latency estimates for pre-Honeycomb devices that do not support
|
|
||||||
// ANPAudioTrackInterfaceV1's trackLatency(). The Android stock browser
|
|
||||||
// calls android::AudioTrack::latency(), an internal Android API that is
|
|
||||||
// not available in the public NDK:
|
|
||||||
// https://github.com/android/platform_external_webkit/commit/49bf866973cb3b2a6c74c0eab864e9562e4cbab1
|
|
||||||
return 100; // milliseconds
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitAudioTrackInterfaceV0(ANPAudioTrackInterfaceV0 *i) {
|
|
||||||
_assert(i->inSize == sizeof(*i));
|
|
||||||
ASSIGN(i, newTrack);
|
|
||||||
ASSIGN(i, deleteTrack);
|
|
||||||
ASSIGN(i, start);
|
|
||||||
ASSIGN(i, pause);
|
|
||||||
ASSIGN(i, stop);
|
|
||||||
ASSIGN(i, isStopped);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitAudioTrackInterfaceV1(ANPAudioTrackInterfaceV1 *i) {
|
|
||||||
_assert(i->inSize == sizeof(*i));
|
|
||||||
ASSIGN(i, newTrack);
|
|
||||||
ASSIGN(i, deleteTrack);
|
|
||||||
ASSIGN(i, start);
|
|
||||||
ASSIGN(i, pause);
|
|
||||||
ASSIGN(i, stop);
|
|
||||||
ASSIGN(i, isStopped);
|
|
||||||
ASSIGN(i, trackLatency);
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "android_npapi.h"
|
|
||||||
#include "nsISupportsImpl.h"
|
|
||||||
|
|
||||||
#define NOT_IMPLEMENTED_FATAL() do { \
|
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "GeckoPlugins", \
|
|
||||||
"%s not implemented %s, %d", \
|
|
||||||
__PRETTY_FUNCTION__, __FILE__, __LINE__); \
|
|
||||||
abort(); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define NOT_IMPLEMENTED() \
|
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "GeckoPlugins", \
|
|
||||||
"!!!!!!!!!!!!!! %s not implemented %s, %d", \
|
|
||||||
__PRETTY_FUNCTION__, __FILE__, __LINE__); \
|
|
||||||
|
|
||||||
void InitAudioTrackInterfaceV0(ANPAudioTrackInterfaceV0 *i);
|
|
||||||
void InitAudioTrackInterfaceV1(ANPAudioTrackInterfaceV1* i);
|
|
||||||
void InitCanvasInterface(ANPCanvasInterfaceV0 *i);
|
|
||||||
void InitEventInterface(ANPEventInterfaceV0 *i);
|
|
||||||
void InitLogInterface(ANPLogInterfaceV0 *i);
|
|
||||||
void InitPaintInterface(ANPPaintInterfaceV0 *i);
|
|
||||||
void InitSurfaceInterface(ANPSurfaceInterfaceV0 *i);
|
|
||||||
void InitSystemInterfaceV1(ANPSystemInterfaceV1 *i);
|
|
||||||
void InitSystemInterfaceV2(ANPSystemInterfaceV2 *i);
|
|
||||||
void InitTypeFaceInterface(ANPTypefaceInterfaceV0 *i);
|
|
||||||
void InitWindowInterface(ANPWindowInterfaceV0 *i);
|
|
||||||
void InitWindowInterfaceV2(ANPWindowInterfaceV2 *i);
|
|
||||||
void InitVideoInterfaceV1(ANPVideoInterfaceV1 *i);
|
|
||||||
void InitOpenGLInterface(ANPOpenGLInterfaceV0 *i);
|
|
||||||
void InitNativeWindowInterface(ANPNativeWindowInterfaceV0 *i);
|
|
|
@ -1,31 +0,0 @@
|
||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "assert.h"
|
|
||||||
#include "ANPBase.h"
|
|
||||||
#include <android/log.h>
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "nsNPAPIPluginInstance.h"
|
|
||||||
#include "nsNPAPIPlugin.h"
|
|
||||||
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
||||||
#define ASSIGN(obj, name) (obj)->name = anp_event_##name
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_event_postEvent(NPP instance, const ANPEvent* event)
|
|
||||||
{
|
|
||||||
LOG("%s", __PRETTY_FUNCTION__);
|
|
||||||
|
|
||||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
pinst->PostEvent((void*) event);
|
|
||||||
|
|
||||||
LOG("returning from %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void InitEventInterface(ANPEventInterfaceV0 *i) {
|
|
||||||
_assert(i->inSize == sizeof(*i));
|
|
||||||
ASSIGN(i, postEvent);
|
|
||||||
}
|
|
|
@ -1,152 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2008, The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
||||||
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ANPKeyCodes_DEFINED
|
|
||||||
#define ANPKeyCodes_DEFINED
|
|
||||||
|
|
||||||
/* List the key codes that are set to a plugin in the ANPKeyEvent.
|
|
||||||
|
|
||||||
These exactly match the values in android/view/KeyEvent.java and the
|
|
||||||
corresponding .h file android/keycodes.h.
|
|
||||||
*/
|
|
||||||
enum ANPKeyCodes {
|
|
||||||
kUnknown_ANPKeyCode = 0,
|
|
||||||
|
|
||||||
kSoftLeft_ANPKeyCode = 1,
|
|
||||||
kSoftRight_ANPKeyCode = 2,
|
|
||||||
kHome_ANPKeyCode = 3,
|
|
||||||
kBack_ANPKeyCode = 4,
|
|
||||||
kCall_ANPKeyCode = 5,
|
|
||||||
kEndCall_ANPKeyCode = 6,
|
|
||||||
k0_ANPKeyCode = 7,
|
|
||||||
k1_ANPKeyCode = 8,
|
|
||||||
k2_ANPKeyCode = 9,
|
|
||||||
k3_ANPKeyCode = 10,
|
|
||||||
k4_ANPKeyCode = 11,
|
|
||||||
k5_ANPKeyCode = 12,
|
|
||||||
k6_ANPKeyCode = 13,
|
|
||||||
k7_ANPKeyCode = 14,
|
|
||||||
k8_ANPKeyCode = 15,
|
|
||||||
k9_ANPKeyCode = 16,
|
|
||||||
kStar_ANPKeyCode = 17,
|
|
||||||
kPound_ANPKeyCode = 18,
|
|
||||||
kDpadUp_ANPKeyCode = 19,
|
|
||||||
kDpadDown_ANPKeyCode = 20,
|
|
||||||
kDpadLeft_ANPKeyCode = 21,
|
|
||||||
kDpadRight_ANPKeyCode = 22,
|
|
||||||
kDpadCenter_ANPKeyCode = 23,
|
|
||||||
kVolumeUp_ANPKeyCode = 24,
|
|
||||||
kVolumeDown_ANPKeyCode = 25,
|
|
||||||
kPower_ANPKeyCode = 26,
|
|
||||||
kCamera_ANPKeyCode = 27,
|
|
||||||
kClear_ANPKeyCode = 28,
|
|
||||||
kA_ANPKeyCode = 29,
|
|
||||||
kB_ANPKeyCode = 30,
|
|
||||||
kC_ANPKeyCode = 31,
|
|
||||||
kD_ANPKeyCode = 32,
|
|
||||||
kE_ANPKeyCode = 33,
|
|
||||||
kF_ANPKeyCode = 34,
|
|
||||||
kG_ANPKeyCode = 35,
|
|
||||||
kH_ANPKeyCode = 36,
|
|
||||||
kI_ANPKeyCode = 37,
|
|
||||||
kJ_ANPKeyCode = 38,
|
|
||||||
kK_ANPKeyCode = 39,
|
|
||||||
kL_ANPKeyCode = 40,
|
|
||||||
kM_ANPKeyCode = 41,
|
|
||||||
kN_ANPKeyCode = 42,
|
|
||||||
kO_ANPKeyCode = 43,
|
|
||||||
kP_ANPKeyCode = 44,
|
|
||||||
kQ_ANPKeyCode = 45,
|
|
||||||
kR_ANPKeyCode = 46,
|
|
||||||
kS_ANPKeyCode = 47,
|
|
||||||
kT_ANPKeyCode = 48,
|
|
||||||
kU_ANPKeyCode = 49,
|
|
||||||
kV_ANPKeyCode = 50,
|
|
||||||
kW_ANPKeyCode = 51,
|
|
||||||
kX_ANPKeyCode = 52,
|
|
||||||
kY_ANPKeyCode = 53,
|
|
||||||
kZ_ANPKeyCode = 54,
|
|
||||||
kComma_ANPKeyCode = 55,
|
|
||||||
kPeriod_ANPKeyCode = 56,
|
|
||||||
kAltLeft_ANPKeyCode = 57,
|
|
||||||
kAltRight_ANPKeyCode = 58,
|
|
||||||
kShiftLeft_ANPKeyCode = 59,
|
|
||||||
kShiftRight_ANPKeyCode = 60,
|
|
||||||
kTab_ANPKeyCode = 61,
|
|
||||||
kSpace_ANPKeyCode = 62,
|
|
||||||
kSym_ANPKeyCode = 63,
|
|
||||||
kExplorer_ANPKeyCode = 64,
|
|
||||||
kEnvelope_ANPKeyCode = 65,
|
|
||||||
kNewline_ANPKeyCode = 66,
|
|
||||||
kDel_ANPKeyCode = 67,
|
|
||||||
kGrave_ANPKeyCode = 68,
|
|
||||||
kMinus_ANPKeyCode = 69,
|
|
||||||
kEquals_ANPKeyCode = 70,
|
|
||||||
kLeftBracket_ANPKeyCode = 71,
|
|
||||||
kRightBracket_ANPKeyCode = 72,
|
|
||||||
kBackslash_ANPKeyCode = 73,
|
|
||||||
kSemicolon_ANPKeyCode = 74,
|
|
||||||
kApostrophe_ANPKeyCode = 75,
|
|
||||||
kSlash_ANPKeyCode = 76,
|
|
||||||
kAt_ANPKeyCode = 77,
|
|
||||||
kNum_ANPKeyCode = 78,
|
|
||||||
kHeadSetHook_ANPKeyCode = 79,
|
|
||||||
kFocus_ANPKeyCode = 80,
|
|
||||||
kPlus_ANPKeyCode = 81,
|
|
||||||
kMenu_ANPKeyCode = 82,
|
|
||||||
kNotification_ANPKeyCode = 83,
|
|
||||||
kSearch_ANPKeyCode = 84,
|
|
||||||
kMediaPlayPause_ANPKeyCode = 85,
|
|
||||||
kMediaStop_ANPKeyCode = 86,
|
|
||||||
kMediaNext_ANPKeyCode = 87,
|
|
||||||
kMediaPrevious_ANPKeyCode = 88,
|
|
||||||
kMediaRewind_ANPKeyCode = 89,
|
|
||||||
kMediaFastForward_ANPKeyCode = 90,
|
|
||||||
kMute_ANPKeyCode = 91,
|
|
||||||
kPageUp_ANPKeyCode = 92,
|
|
||||||
kPageDown_ANPKeyCode = 93,
|
|
||||||
kPictsymbols_ANPKeyCode = 94,
|
|
||||||
kSwitchCharset_ANPKeyCode = 95,
|
|
||||||
kButtonA_ANPKeyCode = 96,
|
|
||||||
kButtonB_ANPKeyCode = 97,
|
|
||||||
kButtonC_ANPKeyCode = 98,
|
|
||||||
kButtonX_ANPKeyCode = 99,
|
|
||||||
kButtonY_ANPKeyCode = 100,
|
|
||||||
kButtonZ_ANPKeyCode = 101,
|
|
||||||
kButtonL1_ANPKeyCode = 102,
|
|
||||||
kButtonR1_ANPKeyCode = 103,
|
|
||||||
kButtonL2_ANPKeyCode = 104,
|
|
||||||
kButtonR2_ANPKeyCode = 105,
|
|
||||||
kButtonThumbL_ANPKeyCode = 106,
|
|
||||||
kButtonThumbR_ANPKeyCode = 107,
|
|
||||||
kButtonStart_ANPKeyCode = 108,
|
|
||||||
kButtonSelect_ANPKeyCode = 109,
|
|
||||||
kButtonMode_ANPKeyCode = 110,
|
|
||||||
|
|
||||||
// NOTE: If you add a new keycode here you must also add it to several other files.
|
|
||||||
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,26 +0,0 @@
|
||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "assert.h"
|
|
||||||
#include "ANPBase.h"
|
|
||||||
#include <android/log.h>
|
|
||||||
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
||||||
#define ASSIGN(obj, name) (obj)->name = anp_log_##name
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_log_log(ANPLogType type, const char format[], ...) {
|
|
||||||
|
|
||||||
va_list argp;
|
|
||||||
va_start(argp,format);
|
|
||||||
__android_log_vprint(type == kError_ANPLogType ? ANDROID_LOG_ERROR : type == kWarning_ANPLogType ?
|
|
||||||
ANDROID_LOG_WARN : ANDROID_LOG_INFO, "GeckoPluginLog", format, argp);
|
|
||||||
va_end(argp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitLogInterface(ANPLogInterfaceV0 *i) {
|
|
||||||
_assert(i->inSize == sizeof(*i));
|
|
||||||
ASSIGN(i, log);
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
// must include config.h first for webkit to fiddle with new/delete
|
|
||||||
#include <android/log.h>
|
|
||||||
#include "ANPBase.h"
|
|
||||||
#include "nsIPluginInstanceOwner.h"
|
|
||||||
#include "nsPluginInstanceOwner.h"
|
|
||||||
#include "nsNPAPIPluginInstance.h"
|
|
||||||
#include "gfxRect.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
|
||||||
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
||||||
#define ASSIGN(obj, name) (obj)->name = anp_native_window_##name
|
|
||||||
|
|
||||||
static ANPNativeWindow anp_native_window_acquireNativeWindow(NPP instance) {
|
|
||||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
return pinst->AcquireContentWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void anp_native_window_invertPluginContent(NPP instance, bool isContentInverted) {
|
|
||||||
// NativeWindow is TopLeft if uninverted.
|
|
||||||
gl::OriginPos newOriginPos = gl::OriginPos::TopLeft;
|
|
||||||
if (isContentInverted)
|
|
||||||
newOriginPos = gl::OriginPos::BottomLeft;
|
|
||||||
|
|
||||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
pinst->SetOriginPos(newOriginPos);
|
|
||||||
pinst->RedrawPlugin();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void InitNativeWindowInterface(ANPNativeWindowInterfaceV0* i) {
|
|
||||||
ASSIGN(i, acquireNativeWindow);
|
|
||||||
ASSIGN(i, invertPluginContent);
|
|
||||||
}
|
|
|
@ -1,266 +0,0 @@
|
||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <android/log.h>
|
|
||||||
#include "ANPBase.h"
|
|
||||||
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
||||||
#define ASSIGN(obj, name) (obj)->name = anp_surface_##name
|
|
||||||
|
|
||||||
#define CLEAR_EXCEPTION(env) if (env->ExceptionOccurred()) env->ExceptionClear();
|
|
||||||
|
|
||||||
#define ANDROID_REGION_SIZE 512
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PIXEL_FORMAT_RGBA_8888 = 1,
|
|
||||||
PIXEL_FORMAT_RGB_565 = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SurfaceInfo {
|
|
||||||
uint32_t w;
|
|
||||||
uint32_t h;
|
|
||||||
uint32_t s;
|
|
||||||
uint32_t usage;
|
|
||||||
uint32_t format;
|
|
||||||
unsigned char* bits;
|
|
||||||
uint32_t reserved[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct ARect {
|
|
||||||
int32_t left;
|
|
||||||
int32_t top;
|
|
||||||
int32_t right;
|
|
||||||
int32_t bottom;
|
|
||||||
} ARect;
|
|
||||||
|
|
||||||
|
|
||||||
// used to cache JNI method and field IDs for Surface Objects
|
|
||||||
static struct ANPSurfaceInterfaceJavaGlue {
|
|
||||||
bool initialized;
|
|
||||||
jmethodID getSurfaceHolder;
|
|
||||||
jmethodID getSurface;
|
|
||||||
jfieldID surfacePointer;
|
|
||||||
} gSurfaceJavaGlue;
|
|
||||||
|
|
||||||
static struct ANPSurfaceFunctions {
|
|
||||||
bool initialized;
|
|
||||||
|
|
||||||
int (* lock)(void*, SurfaceInfo*, void*);
|
|
||||||
int (* unlockAndPost)(void*);
|
|
||||||
|
|
||||||
void* (* regionConstructor)(void*);
|
|
||||||
void (* setRegion)(void*, ARect const&);
|
|
||||||
} gSurfaceFunctions;
|
|
||||||
|
|
||||||
|
|
||||||
static inline void* getSurface(JNIEnv* env, jobject view) {
|
|
||||||
if (!env || !view) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gSurfaceJavaGlue.initialized) {
|
|
||||||
|
|
||||||
jclass surfaceViewClass = env->FindClass("android/view/SurfaceView");
|
|
||||||
gSurfaceJavaGlue.getSurfaceHolder = env->GetMethodID(surfaceViewClass, "getHolder", "()Landroid/view/SurfaceHolder;");
|
|
||||||
|
|
||||||
jclass surfaceHolderClass = env->FindClass("android/view/SurfaceHolder");
|
|
||||||
gSurfaceJavaGlue.getSurface = env->GetMethodID(surfaceHolderClass, "getSurface", "()Landroid/view/Surface;");
|
|
||||||
|
|
||||||
jclass surfaceClass = env->FindClass("android/view/Surface");
|
|
||||||
gSurfaceJavaGlue.surfacePointer = env->GetFieldID(surfaceClass,
|
|
||||||
"mSurfacePointer", "I");
|
|
||||||
|
|
||||||
if (!gSurfaceJavaGlue.surfacePointer) {
|
|
||||||
CLEAR_EXCEPTION(env);
|
|
||||||
|
|
||||||
// It was something else in 2.2.
|
|
||||||
gSurfaceJavaGlue.surfacePointer = env->GetFieldID(surfaceClass,
|
|
||||||
"mSurface", "I");
|
|
||||||
|
|
||||||
if (!gSurfaceJavaGlue.surfacePointer) {
|
|
||||||
CLEAR_EXCEPTION(env);
|
|
||||||
|
|
||||||
// And something else in 2.3+
|
|
||||||
gSurfaceJavaGlue.surfacePointer = env->GetFieldID(surfaceClass,
|
|
||||||
"mNativeSurface", "I");
|
|
||||||
|
|
||||||
CLEAR_EXCEPTION(env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gSurfaceJavaGlue.surfacePointer) {
|
|
||||||
LOG("Failed to acquire surface pointer");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->DeleteLocalRef(surfaceClass);
|
|
||||||
env->DeleteLocalRef(surfaceViewClass);
|
|
||||||
env->DeleteLocalRef(surfaceHolderClass);
|
|
||||||
|
|
||||||
gSurfaceJavaGlue.initialized = (gSurfaceJavaGlue.surfacePointer != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
jobject holder = env->CallObjectMethod(view, gSurfaceJavaGlue.getSurfaceHolder);
|
|
||||||
jobject surface = env->CallObjectMethod(holder, gSurfaceJavaGlue.getSurface);
|
|
||||||
jint surfacePointer = env->GetIntField(surface, gSurfaceJavaGlue.surfacePointer);
|
|
||||||
|
|
||||||
env->DeleteLocalRef(holder);
|
|
||||||
env->DeleteLocalRef(surface);
|
|
||||||
|
|
||||||
return reinterpret_cast<void*>(uintptr_t(surfacePointer));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ANPBitmapFormat convertPixelFormat(int32_t format) {
|
|
||||||
switch (format) {
|
|
||||||
case PIXEL_FORMAT_RGBA_8888: return kRGBA_8888_ANPBitmapFormat;
|
|
||||||
case PIXEL_FORMAT_RGB_565: return kRGB_565_ANPBitmapFormat;
|
|
||||||
default: return kUnknown_ANPBitmapFormat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bytesPerPixel(int32_t format) {
|
|
||||||
switch (format) {
|
|
||||||
case PIXEL_FORMAT_RGBA_8888: return 4;
|
|
||||||
case PIXEL_FORMAT_RGB_565: return 2;
|
|
||||||
default: return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool init() {
|
|
||||||
if (gSurfaceFunctions.initialized)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
void* handle = dlopen("libsurfaceflinger_client.so", RTLD_LAZY);
|
|
||||||
|
|
||||||
if (!handle) {
|
|
||||||
LOG("Failed to open libsurfaceflinger_client.so");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
gSurfaceFunctions.lock = (int (*)(void*, SurfaceInfo*, void*))dlsym(handle, "_ZN7android7Surface4lockEPNS0_11SurfaceInfoEPNS_6RegionEb");
|
|
||||||
gSurfaceFunctions.unlockAndPost = (int (*)(void*))dlsym(handle, "_ZN7android7Surface13unlockAndPostEv");
|
|
||||||
|
|
||||||
|
|
||||||
if (!gSurfaceFunctions.lock) {
|
|
||||||
// Stuff changed in 3.0/4.0
|
|
||||||
handle = dlopen("libgui.so", RTLD_LAZY);
|
|
||||||
gSurfaceFunctions.lock = (int (*)(void*, SurfaceInfo*, void*))dlsym(handle, "_ZN7android7Surface4lockEPNS0_11SurfaceInfoEPNS_6RegionE");
|
|
||||||
gSurfaceFunctions.unlockAndPost = (int (*)(void*))dlsym(handle, "_ZN7android7Surface13unlockAndPostEv");
|
|
||||||
}
|
|
||||||
|
|
||||||
handle = dlopen("libui.so", RTLD_LAZY);
|
|
||||||
if (!handle) {
|
|
||||||
LOG("Failed to open libui.so");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
gSurfaceFunctions.regionConstructor = (void* (*)(void*))dlsym(handle, "_ZN7android6RegionC1Ev");
|
|
||||||
gSurfaceFunctions.setRegion = (void (*)(void*, ARect const&))dlsym(handle, "_ZN7android6Region3setERKNS_4RectE");
|
|
||||||
|
|
||||||
gSurfaceFunctions.initialized = (gSurfaceFunctions.lock && gSurfaceFunctions.unlockAndPost &&
|
|
||||||
gSurfaceFunctions.regionConstructor && gSurfaceFunctions.setRegion);
|
|
||||||
LOG("Initialized? %d\n", gSurfaceFunctions.initialized);
|
|
||||||
return gSurfaceFunctions.initialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: All of this should be changed to use the equivalent things in AndroidBridge, bug 758612
|
|
||||||
static bool anp_surface_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRectI* dirtyRect) {
|
|
||||||
if (!bitmap || !surfaceView) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* surface = getSurface(env, surfaceView);
|
|
||||||
|
|
||||||
if (!bitmap || !surface) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!init()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* region = nullptr;
|
|
||||||
if (dirtyRect) {
|
|
||||||
region = malloc(ANDROID_REGION_SIZE);
|
|
||||||
gSurfaceFunctions.regionConstructor(region);
|
|
||||||
|
|
||||||
ARect rect;
|
|
||||||
rect.left = dirtyRect->left;
|
|
||||||
rect.top = dirtyRect->top;
|
|
||||||
rect.right = dirtyRect->right;
|
|
||||||
rect.bottom = dirtyRect->bottom;
|
|
||||||
|
|
||||||
gSurfaceFunctions.setRegion(region, rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
SurfaceInfo info;
|
|
||||||
int err = gSurfaceFunctions.lock(surface, &info, region);
|
|
||||||
if (err < 0) {
|
|
||||||
LOG("Failed to lock surface");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the surface may have expanded the dirty region so we must to pass that
|
|
||||||
// information back to the plugin.
|
|
||||||
if (dirtyRect) {
|
|
||||||
ARect* dirtyBounds = (ARect*)region; // The bounds are the first member, so this should work!
|
|
||||||
|
|
||||||
dirtyRect->left = dirtyBounds->left;
|
|
||||||
dirtyRect->right = dirtyBounds->right;
|
|
||||||
dirtyRect->top = dirtyBounds->top;
|
|
||||||
dirtyRect->bottom = dirtyBounds->bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (region)
|
|
||||||
free(region);
|
|
||||||
|
|
||||||
int bpr = info.s * bytesPerPixel(info.format);
|
|
||||||
|
|
||||||
bitmap->format = convertPixelFormat(info.format);
|
|
||||||
bitmap->width = info.w;
|
|
||||||
bitmap->height = info.h;
|
|
||||||
bitmap->rowBytes = bpr;
|
|
||||||
|
|
||||||
if (info.w > 0 && info.h > 0) {
|
|
||||||
bitmap->baseAddr = info.bits;
|
|
||||||
} else {
|
|
||||||
bitmap->baseAddr = nullptr;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void anp_surface_unlock(JNIEnv* env, jobject surfaceView) {
|
|
||||||
if (!surfaceView) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!init()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* surface = getSurface(env, surfaceView);
|
|
||||||
|
|
||||||
if (!surface) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gSurfaceFunctions.unlockAndPost(surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void InitSurfaceInterface(ANPSurfaceInterfaceV0* i) {
|
|
||||||
ASSIGN(i, lock);
|
|
||||||
ASSIGN(i, unlock);
|
|
||||||
|
|
||||||
// setup the java glue struct
|
|
||||||
gSurfaceJavaGlue.initialized = false;
|
|
||||||
|
|
||||||
// setup the function struct
|
|
||||||
gSurfaceFunctions.initialized = false;
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "base/basictypes.h"
|
|
||||||
|
|
||||||
#include "ANPBase.h"
|
|
||||||
#include "GeneratedJNIWrappers.h"
|
|
||||||
#include "PluginPRLibrary.h"
|
|
||||||
#include "assert.h"
|
|
||||||
#include "nsNPAPIPluginInstance.h"
|
|
||||||
#include "nsNPAPIPlugin.h"
|
|
||||||
|
|
||||||
#include <android/log.h>
|
|
||||||
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
||||||
#define ASSIGN(obj, name) (obj)->name = anp_system_##name
|
|
||||||
|
|
||||||
const char*
|
|
||||||
anp_system_getApplicationDataDirectory(NPP instance)
|
|
||||||
{
|
|
||||||
static const char *dir = nullptr;
|
|
||||||
static const char *privateDir = nullptr;
|
|
||||||
|
|
||||||
bool isPrivate = false;
|
|
||||||
|
|
||||||
if (!dir) {
|
|
||||||
dir = getenv("ANDROID_PLUGIN_DATADIR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!privateDir) {
|
|
||||||
privateDir = getenv("ANDROID_PLUGIN_DATADIR_PRIVATE");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!instance) {
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
if (pinst && NS_SUCCEEDED(pinst->IsPrivateBrowsing(&isPrivate)) && isPrivate) {
|
|
||||||
return privateDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
|
||||||
anp_system_getApplicationDataDirectory()
|
|
||||||
{
|
|
||||||
return anp_system_getApplicationDataDirectory(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
jclass anp_system_loadJavaClass(NPP instance, const char* className)
|
|
||||||
{
|
|
||||||
LOG("%s", __PRETTY_FUNCTION__);
|
|
||||||
|
|
||||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
mozilla::PluginPRLibrary* lib = static_cast<mozilla::PluginPRLibrary*>(pinst->GetPlugin()->GetLibrary());
|
|
||||||
|
|
||||||
nsCString libName;
|
|
||||||
lib->GetLibraryPath(libName);
|
|
||||||
|
|
||||||
return mozilla::java::GeckoAppShell::LoadPluginClass(className, libName).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
void anp_system_setPowerState(NPP instance, ANPPowerState powerState)
|
|
||||||
{
|
|
||||||
nsNPAPIPluginInstance* pinst = nsNPAPIPluginInstance::GetFromNPP(instance);
|
|
||||||
|
|
||||||
if (pinst) {
|
|
||||||
pinst->SetWakeLock(powerState == kScreenOn_ANPPowerState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitSystemInterfaceV1(ANPSystemInterfaceV1 *i) {
|
|
||||||
_assert(i->inSize == sizeof(*i));
|
|
||||||
ASSIGN(i, getApplicationDataDirectory);
|
|
||||||
ASSIGN(i, loadJavaClass);
|
|
||||||
ASSIGN(i, setPowerState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitSystemInterfaceV2(ANPSystemInterfaceV2 *i) {
|
|
||||||
_assert(i->inSize == sizeof(*i));
|
|
||||||
ASSIGN(i, getApplicationDataDirectory);
|
|
||||||
ASSIGN(i, loadJavaClass);
|
|
||||||
ASSIGN(i, setPowerState);
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include <android/log.h>
|
|
||||||
#include "ANPBase.h"
|
|
||||||
#include "nsIPluginInstanceOwner.h"
|
|
||||||
#include "nsPluginInstanceOwner.h"
|
|
||||||
#include "nsNPAPIPluginInstance.h"
|
|
||||||
#include "gfxRect.h"
|
|
||||||
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
||||||
#define ASSIGN(obj, name) (obj)->name = anp_video_##name
|
|
||||||
|
|
||||||
using namespace mozilla;
|
|
||||||
|
|
||||||
typedef nsNPAPIPluginInstance::VideoInfo VideoInfo;
|
|
||||||
|
|
||||||
static ANPNativeWindow anp_video_acquireNativeWindow(NPP instance) {
|
|
||||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
|
|
||||||
return pinst->AcquireVideoWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void anp_video_setWindowDimensions(NPP instance, const ANPNativeWindow window,
|
|
||||||
const ANPRectF* dimensions) {
|
|
||||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
|
|
||||||
gfxRect rect(dimensions->left, dimensions->top,
|
|
||||||
dimensions->right - dimensions->left,
|
|
||||||
dimensions->bottom - dimensions->top);
|
|
||||||
|
|
||||||
pinst->SetVideoDimensions(window, rect);
|
|
||||||
pinst->RedrawPlugin();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void anp_video_releaseNativeWindow(NPP instance, ANPNativeWindow window) {
|
|
||||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
pinst->ReleaseVideoWindow(window);
|
|
||||||
pinst->RedrawPlugin();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void anp_video_setFramerateCallback(NPP instance, const ANPNativeWindow window, ANPVideoFrameCallbackProc callback) {
|
|
||||||
// Bug 722682
|
|
||||||
NOT_IMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void InitVideoInterfaceV1(ANPVideoInterfaceV1* i) {
|
|
||||||
ASSIGN(i, acquireNativeWindow);
|
|
||||||
ASSIGN(i, setWindowDimensions);
|
|
||||||
ASSIGN(i, releaseNativeWindow);
|
|
||||||
ASSIGN(i, setFramerateCallback);
|
|
||||||
}
|
|
|
@ -1,152 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "base/basictypes.h"
|
|
||||||
#include "assert.h"
|
|
||||||
#include "ANPBase.h"
|
|
||||||
#include <android/log.h>
|
|
||||||
#include "nsNPAPIPluginInstance.h"
|
|
||||||
#include "nsPluginInstanceOwner.h"
|
|
||||||
#include "nsWindow.h"
|
|
||||||
#include "mozilla/dom/ScreenOrientation.h"
|
|
||||||
|
|
||||||
#undef LOG
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
||||||
#define ASSIGN(obj, name) (obj)->name = anp_window_##name
|
|
||||||
|
|
||||||
using namespace mozilla;
|
|
||||||
using namespace mozilla::widget;
|
|
||||||
using namespace mozilla::dom;
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_window_setVisibleRects(NPP instance, const ANPRectI rects[], int32_t count)
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_window_clearVisibleRects(NPP instance)
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_window_showKeyboard(NPP instance, bool value)
|
|
||||||
{
|
|
||||||
InputContext context;
|
|
||||||
context.mIMEState.mEnabled = value ? IMEState::PLUGIN : IMEState::DISABLED;
|
|
||||||
context.mIMEState.mOpen = value ? IMEState::OPEN : IMEState::CLOSED;
|
|
||||||
context.mActionHint.Assign(EmptyString());
|
|
||||||
|
|
||||||
InputContextAction action;
|
|
||||||
action.mCause = InputContextAction::CAUSE_UNKNOWN;
|
|
||||||
action.mFocusChange = InputContextAction::FOCUS_NOT_CHANGED;
|
|
||||||
|
|
||||||
nsWindow* window = nsWindow::TopWindow();
|
|
||||||
if (!window) {
|
|
||||||
LOG("Couldn't get top window?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
window->SetInputContext(context, action);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_window_requestFullScreen(NPP instance)
|
|
||||||
{
|
|
||||||
nsNPAPIPluginInstance* inst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
|
|
||||||
RefPtr<nsPluginInstanceOwner> owner = inst->GetOwner();
|
|
||||||
if (!owner) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
owner->RequestFullScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_window_exitFullScreen(NPP instance)
|
|
||||||
{
|
|
||||||
nsNPAPIPluginInstance* inst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
|
|
||||||
RefPtr<nsPluginInstanceOwner> owner = inst->GetOwner();
|
|
||||||
if (!owner) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
owner->ExitFullScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
anp_window_requestCenterFitZoom(NPP instance)
|
|
||||||
{
|
|
||||||
NOT_IMPLEMENTED();
|
|
||||||
}
|
|
||||||
|
|
||||||
ANPRectI
|
|
||||||
anp_window_visibleRect(NPP instance)
|
|
||||||
{
|
|
||||||
ANPRectI rect = { 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
|
|
||||||
nsIntSize currentSize = pinst->CurrentSize();
|
|
||||||
rect.left = rect.top = 0;
|
|
||||||
rect.right = currentSize.width;
|
|
||||||
rect.bottom = currentSize.height;
|
|
||||||
|
|
||||||
return rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void anp_window_requestFullScreenOrientation(NPP instance, ANPScreenOrientation orientation)
|
|
||||||
{
|
|
||||||
short newOrientation;
|
|
||||||
|
|
||||||
// Convert to the ActivityInfo equivalent
|
|
||||||
switch (orientation) {
|
|
||||||
case kFixedLandscape_ANPScreenOrientation:
|
|
||||||
newOrientation = eScreenOrientation_LandscapePrimary;
|
|
||||||
break;
|
|
||||||
case kFixedPortrait_ANPScreenOrientation:
|
|
||||||
newOrientation = eScreenOrientation_PortraitPrimary;
|
|
||||||
break;
|
|
||||||
case kLandscape_ANPScreenOrientation:
|
|
||||||
newOrientation = eScreenOrientation_LandscapePrimary |
|
|
||||||
eScreenOrientation_LandscapeSecondary;
|
|
||||||
break;
|
|
||||||
case kPortrait_ANPScreenOrientation:
|
|
||||||
newOrientation = eScreenOrientation_PortraitPrimary |
|
|
||||||
eScreenOrientation_PortraitSecondary;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
newOrientation = eScreenOrientation_None;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
|
||||||
pinst->SetFullScreenOrientation(newOrientation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitWindowInterface(ANPWindowInterfaceV0 *i) {
|
|
||||||
_assert(i->inSize == sizeof(*i));
|
|
||||||
ASSIGN(i, setVisibleRects);
|
|
||||||
ASSIGN(i, clearVisibleRects);
|
|
||||||
ASSIGN(i, showKeyboard);
|
|
||||||
ASSIGN(i, requestFullScreen);
|
|
||||||
ASSIGN(i, exitFullScreen);
|
|
||||||
ASSIGN(i, requestCenterFitZoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitWindowInterfaceV2(ANPWindowInterfaceV2 *i) {
|
|
||||||
_assert(i->inSize == sizeof(*i));
|
|
||||||
ASSIGN(i, setVisibleRects);
|
|
||||||
ASSIGN(i, clearVisibleRects);
|
|
||||||
ASSIGN(i, showKeyboard);
|
|
||||||
ASSIGN(i, requestFullScreen);
|
|
||||||
ASSIGN(i, exitFullScreen);
|
|
||||||
ASSIGN(i, requestCenterFitZoom);
|
|
||||||
ASSIGN(i, visibleRect);
|
|
||||||
ASSIGN(i, requestFullScreenOrientation);
|
|
||||||
}
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,35 +0,0 @@
|
||||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
|
||||||
# vim: set filetype=python:
|
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
EXPORTS += [
|
|
||||||
'android_npapi.h',
|
|
||||||
'ANPKeyCodes.h',
|
|
||||||
]
|
|
||||||
|
|
||||||
SOURCES += [
|
|
||||||
'ANPAudio.cpp',
|
|
||||||
'ANPEvent.cpp',
|
|
||||||
'ANPLog.cpp',
|
|
||||||
'ANPNativeWindow.cpp',
|
|
||||||
'ANPSurface.cpp',
|
|
||||||
'ANPSystem.cpp',
|
|
||||||
'ANPVideo.cpp',
|
|
||||||
'ANPWindow.cpp',
|
|
||||||
]
|
|
||||||
|
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
|
||||||
LOCAL_INCLUDES += [
|
|
||||||
'/dom/plugins/base',
|
|
||||||
'/gfx/gl',
|
|
||||||
'/widget',
|
|
||||||
'/widget/android',
|
|
||||||
]
|
|
||||||
|
|
||||||
DEFINES['MOZ_APP_NAME'] = '"%s"' % CONFIG['MOZ_APP_NAME']
|
|
||||||
|
|
||||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
|
|
@ -4,9 +4,6 @@
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
|
||||||
DIRS += ['android']
|
|
||||||
|
|
||||||
XPIDL_SOURCES += [
|
XPIDL_SOURCES += [
|
||||||
'nsIHTTPHeaderListener.idl',
|
'nsIHTTPHeaderListener.idl',
|
||||||
'nsIPluginDocument.idl',
|
'nsIPluginDocument.idl',
|
||||||
|
@ -80,16 +77,10 @@ LOCAL_INCLUDES += [
|
||||||
'/layout/xul',
|
'/layout/xul',
|
||||||
'/netwerk/base',
|
'/netwerk/base',
|
||||||
'/widget',
|
'/widget',
|
||||||
'/widget/android',
|
|
||||||
'/widget/cocoa',
|
'/widget/cocoa',
|
||||||
'/xpcom/base',
|
'/xpcom/base',
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
|
||||||
LOCAL_INCLUDES += [
|
|
||||||
'/dom/plugins/base/android',
|
|
||||||
]
|
|
||||||
|
|
||||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'/xpcom/base',
|
'/xpcom/base',
|
||||||
|
@ -97,8 +88,6 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
||||||
|
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
||||||
DEFINES['SK_BUILD_FOR_ANDROID_NDK'] = True
|
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
||||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||||
|
|
|
@ -9,10 +9,6 @@
|
||||||
#include "npapi.h"
|
#include "npapi.h"
|
||||||
#include "npruntime.h"
|
#include "npruntime.h"
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
#include <jni.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef NPError (* NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);
|
typedef NPError (* NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);
|
||||||
typedef NPError (* NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);
|
typedef NPError (* NPP_DestroyProcPtr)(NPP instance, NPSavedData** save);
|
||||||
typedef NPError (* NPP_SetWindowProcPtr)(NPP instance, NPWindow* window);
|
typedef NPError (* NPP_SetWindowProcPtr)(NPP instance, NPWindow* window);
|
||||||
|
@ -261,14 +257,9 @@ NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs);
|
||||||
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
|
typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*);
|
||||||
NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);
|
||||||
#else
|
#else
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*, JNIEnv* pEnv);
|
|
||||||
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, JNIEnv* pEnv);
|
|
||||||
#else
|
|
||||||
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*);
|
typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*);
|
||||||
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);
|
NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
typedef NPError (*NP_ShutdownFunc)(void);
|
typedef NPError (*NP_ShutdownFunc)(void);
|
||||||
NP_EXPORT(NPError) NP_Shutdown(void);
|
NP_EXPORT(NPError) NP_Shutdown(void);
|
||||||
typedef NPError (*NP_GetValueFunc)(void *, NPPVariable, void *);
|
typedef NPError (*NP_GetValueFunc)(void *, NPPVariable, void *);
|
||||||
|
|
|
@ -96,16 +96,6 @@ using mozilla::plugins::PluginModuleContentParent;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
#include <android/log.h>
|
|
||||||
#include "android_npapi.h"
|
|
||||||
#include "ANPBase.h"
|
|
||||||
#include "FennecJNIWrappers.h"
|
|
||||||
#include "GeneratedJNIWrappers.h"
|
|
||||||
#undef LOG
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsIAudioChannelAgent.h"
|
#include "nsIAudioChannelAgent.h"
|
||||||
#include "AudioChannelService.h"
|
#include "AudioChannelService.h"
|
||||||
|
|
||||||
|
@ -236,11 +226,7 @@ nsNPAPIPlugin::PluginCrashed(const nsAString& pluginDumpID,
|
||||||
bool
|
bool
|
||||||
nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
|
nsNPAPIPlugin::RunPluginOOP(const nsPluginTag *aPluginTag)
|
||||||
{
|
{
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PluginLibrary*
|
inline PluginLibrary*
|
||||||
|
@ -282,7 +268,7 @@ nsNPAPIPlugin::CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
|
#if defined(XP_MACOSX)
|
||||||
if (!pluginLib->HasRequiredFunctions()) {
|
if (!pluginLib->HasRequiredFunctions()) {
|
||||||
NS_WARNING("Not all necessary functions exposed by plugin, it will not load.");
|
NS_WARNING("Not all necessary functions exposed by plugin, it will not load.");
|
||||||
delete pluginLib;
|
delete pluginLib;
|
||||||
|
@ -1782,159 +1768,6 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
case kLogInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get log interface");
|
|
||||||
ANPLogInterfaceV0 *i = (ANPLogInterfaceV0 *) result;
|
|
||||||
InitLogInterface(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kBitmapInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get bitmap interface");
|
|
||||||
return NPERR_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kMatrixInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get matrix interface");
|
|
||||||
return NPERR_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kPathInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get path interface");
|
|
||||||
return NPERR_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kTypefaceInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get typeface interface");
|
|
||||||
ANPTypefaceInterfaceV0 *i = (ANPTypefaceInterfaceV0 *) result;
|
|
||||||
InitTypeFaceInterface(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kPaintInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get paint interface");
|
|
||||||
ANPPaintInterfaceV0 *i = (ANPPaintInterfaceV0 *) result;
|
|
||||||
InitPaintInterface(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kCanvasInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get canvas interface");
|
|
||||||
ANPCanvasInterfaceV0 *i = (ANPCanvasInterfaceV0 *) result;
|
|
||||||
InitCanvasInterface(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kWindowInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get window interface");
|
|
||||||
ANPWindowInterfaceV0 *i = (ANPWindowInterfaceV0 *) result;
|
|
||||||
InitWindowInterface(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kAudioTrackInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get audio interface");
|
|
||||||
ANPAudioTrackInterfaceV0 *i = (ANPAudioTrackInterfaceV0 *) result;
|
|
||||||
InitAudioTrackInterfaceV0(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kEventInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get event interface");
|
|
||||||
ANPEventInterfaceV0 *i = (ANPEventInterfaceV0 *) result;
|
|
||||||
InitEventInterface(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kSystemInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get system interface");
|
|
||||||
return NPERR_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kSurfaceInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get surface interface");
|
|
||||||
ANPSurfaceInterfaceV0 *i = (ANPSurfaceInterfaceV0 *) result;
|
|
||||||
InitSurfaceInterface(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kSupportedDrawingModel_ANPGetValue: {
|
|
||||||
LOG("get supported drawing model");
|
|
||||||
return NPERR_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kJavaContext_ANPGetValue: {
|
|
||||||
LOG("get java context");
|
|
||||||
|
|
||||||
auto ret = npp && jni::IsFennec()
|
|
||||||
? java::GeckoApp::GetPluginContext()
|
|
||||||
: java::GeckoAppShell::GetApplicationContext();
|
|
||||||
if (!ret) {
|
|
||||||
return NPERR_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
*static_cast<jobject*>(result) = ret.Forget();
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kAudioTrackInterfaceV1_ANPGetValue: {
|
|
||||||
LOG("get audio interface v1");
|
|
||||||
ANPAudioTrackInterfaceV1 *i = (ANPAudioTrackInterfaceV1 *) result;
|
|
||||||
InitAudioTrackInterfaceV1(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kNativeWindowInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get native window interface v0");
|
|
||||||
ANPNativeWindowInterfaceV0* i = (ANPNativeWindowInterfaceV0 *) result;
|
|
||||||
InitNativeWindowInterface(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kOpenGLInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get openGL interface");
|
|
||||||
return NPERR_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kWindowInterfaceV1_ANPGetValue: {
|
|
||||||
LOG("get Window interface V1");
|
|
||||||
return NPERR_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kWindowInterfaceV2_ANPGetValue: {
|
|
||||||
LOG("get Window interface V2");
|
|
||||||
ANPWindowInterfaceV2 *i = (ANPWindowInterfaceV2 *) result;
|
|
||||||
InitWindowInterfaceV2(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kVideoInterfaceV0_ANPGetValue: {
|
|
||||||
LOG("get video interface V0");
|
|
||||||
return NPERR_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kVideoInterfaceV1_ANPGetValue: {
|
|
||||||
LOG("get video interface V1");
|
|
||||||
ANPVideoInterfaceV1 *i = (ANPVideoInterfaceV1*) result;
|
|
||||||
InitVideoInterfaceV1(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kSystemInterfaceV1_ANPGetValue: {
|
|
||||||
LOG("get system interface v1");
|
|
||||||
ANPSystemInterfaceV1* i = reinterpret_cast<ANPSystemInterfaceV1*>(result);
|
|
||||||
InitSystemInterfaceV1(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
case kSystemInterfaceV2_ANPGetValue: {
|
|
||||||
LOG("get system interface v2");
|
|
||||||
ANPSystemInterfaceV2* i = reinterpret_cast<ANPSystemInterfaceV2*>(result);
|
|
||||||
InitSystemInterfaceV2(i);
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// we no longer hand out any XPCOM objects
|
// we no longer hand out any XPCOM objects
|
||||||
case NPNVDOMElement:
|
case NPNVDOMElement:
|
||||||
case NPNVDOMWindow:
|
case NPNVDOMWindow:
|
||||||
|
@ -2030,8 +1863,6 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MOZ_WIDGET_ANDROID
|
|
||||||
// On android, their 'drawing model' uses the same constant!
|
|
||||||
case NPPVpluginDrawingModel: {
|
case NPPVpluginDrawingModel: {
|
||||||
if (inst) {
|
if (inst) {
|
||||||
inst->SetDrawingModel((NPDrawingModel)NS_PTR_TO_INT32(result));
|
inst->SetDrawingModel((NPDrawingModel)NS_PTR_TO_INT32(result));
|
||||||
|
@ -2039,7 +1870,6 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
||||||
}
|
}
|
||||||
return NPERR_GENERIC_ERROR;
|
return NPERR_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
case NPPVpluginEventModel: {
|
case NPPVpluginEventModel: {
|
||||||
|
@ -2051,14 +1881,6 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
|
||||||
return NPERR_GENERIC_ERROR;
|
return NPERR_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
case kRequestDrawingModel_ANPSetValue:
|
|
||||||
if (inst)
|
|
||||||
inst->SetANPDrawingModel(NS_PTR_TO_INT32(result));
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
case kAcceptEvents_ANPSetValue:
|
|
||||||
return NPERR_NO_ERROR;
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return NPERR_GENERIC_ERROR;
|
return NPERR_GENERIC_ERROR;
|
||||||
|
@ -2296,13 +2118,7 @@ _unscheduletimer(NPP instance, uint32_t timerID)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
// Sometimes Flash calls this with a dead NPP instance. Ensure the one we have
|
|
||||||
// here is valid and maps to a nsNPAPIPluginInstance.
|
|
||||||
nsNPAPIPluginInstance *inst = nsNPAPIPluginInstance::GetFromNPP(instance);
|
|
||||||
#else
|
|
||||||
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
|
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
|
||||||
#endif
|
|
||||||
if (!inst)
|
if (!inst)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,6 @@
|
||||||
|
|
||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
// For ScreenOrientation.h and Hal.h
|
|
||||||
#include "base/basictypes.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mozilla/Logging.h"
|
#include "mozilla/Logging.h"
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
#include "prenv.h"
|
#include "prenv.h"
|
||||||
|
@ -44,71 +39,6 @@
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
#include "ANPBase.h"
|
|
||||||
#include <android/log.h>
|
|
||||||
#include "android_npapi.h"
|
|
||||||
#include "mozilla/Mutex.h"
|
|
||||||
#include "mozilla/CondVar.h"
|
|
||||||
#include "mozilla/dom/ScreenOrientation.h"
|
|
||||||
#include "mozilla/Hal.h"
|
|
||||||
#include "GLContextProvider.h"
|
|
||||||
#include "GLContext.h"
|
|
||||||
#include "TexturePoolOGL.h"
|
|
||||||
#include "SurfaceTypes.h"
|
|
||||||
#include "EGLUtils.h"
|
|
||||||
#include "GeneratedJNIWrappers.h"
|
|
||||||
#include "GeneratedJNINatives.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
|
||||||
using namespace mozilla::gl;
|
|
||||||
|
|
||||||
typedef nsNPAPIPluginInstance::VideoInfo VideoInfo;
|
|
||||||
|
|
||||||
class PluginEventRunnable : public Runnable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PluginEventRunnable(nsNPAPIPluginInstance* instance, ANPEvent* event)
|
|
||||||
: Runnable("PluginEventRunnable"),
|
|
||||||
mInstance(instance),
|
|
||||||
mEvent(*event),
|
|
||||||
mCanceled(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual nsresult Run() {
|
|
||||||
if (mCanceled)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
mInstance->HandleEvent(&mEvent, nullptr);
|
|
||||||
mInstance->PopPostedEvent(this);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cancel() { mCanceled = true; }
|
|
||||||
private:
|
|
||||||
nsNPAPIPluginInstance* mInstance;
|
|
||||||
ANPEvent mEvent;
|
|
||||||
bool mCanceled;
|
|
||||||
};
|
|
||||||
|
|
||||||
static RefPtr<GLContext> sPluginContext = nullptr;
|
|
||||||
|
|
||||||
static bool EnsureGLContext()
|
|
||||||
{
|
|
||||||
if (!sPluginContext) {
|
|
||||||
const auto flags = CreateContextFlags::REQUIRE_COMPAT_PROFILE;
|
|
||||||
nsCString discardedFailureId;
|
|
||||||
sPluginContext = GLContextProvider::CreateHeadless(flags, &discardedFailureId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sPluginContext != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::map<NPP, nsNPAPIPluginInstance*> sPluginNPPMap;
|
|
||||||
|
|
||||||
#endif // MOZ_WIDGET_ANDROID
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::plugins::parent;
|
using namespace mozilla::plugins::parent;
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
|
@ -119,13 +49,6 @@ NS_IMPL_ISUPPORTS(nsNPAPIPluginInstance, nsIAudioChannelAgentCallback)
|
||||||
|
|
||||||
nsNPAPIPluginInstance::nsNPAPIPluginInstance()
|
nsNPAPIPluginInstance::nsNPAPIPluginInstance()
|
||||||
: mDrawingModel(kDefaultDrawingModel)
|
: mDrawingModel(kDefaultDrawingModel)
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
, mANPDrawingModel(0)
|
|
||||||
, mFullScreenOrientation(dom::eScreenOrientation_LandscapePrimary)
|
|
||||||
, mWakeLocked(false)
|
|
||||||
, mFullScreen(false)
|
|
||||||
, mOriginPos(gl::OriginPos::TopLeft)
|
|
||||||
#endif
|
|
||||||
, mRunning(NOT_STARTED)
|
, mRunning(NOT_STARTED)
|
||||||
, mWindowless(false)
|
, mWindowless(false)
|
||||||
, mTransparent(false)
|
, mTransparent(false)
|
||||||
|
@ -138,9 +61,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance()
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
, mCurrentPluginEvent(nullptr)
|
, mCurrentPluginEvent(nullptr)
|
||||||
#endif
|
#endif
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
, mHaveJavaC2PJSObjectQuirk(false)
|
||||||
, mOnScreen(true)
|
|
||||||
#endif
|
|
||||||
, mCachedParamLength(0)
|
, mCachedParamLength(0)
|
||||||
, mCachedParamNames(nullptr)
|
, mCachedParamNames(nullptr)
|
||||||
, mCachedParamValues(nullptr)
|
, mCachedParamValues(nullptr)
|
||||||
|
@ -150,20 +71,12 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance()
|
||||||
mNPP.ndata = this;
|
mNPP.ndata = this;
|
||||||
|
|
||||||
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this));
|
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this));
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
sPluginNPPMap[&mNPP] = this;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsNPAPIPluginInstance::~nsNPAPIPluginInstance()
|
nsNPAPIPluginInstance::~nsNPAPIPluginInstance()
|
||||||
{
|
{
|
||||||
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance dtor: this=%p\n",this));
|
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance dtor: this=%p\n",this));
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
sPluginNPPMap.erase(&mNPP);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mMIMEType) {
|
if (mMIMEType) {
|
||||||
free(mMIMEType);
|
free(mMIMEType);
|
||||||
mMIMEType = nullptr;
|
mMIMEType = nullptr;
|
||||||
|
@ -200,19 +113,6 @@ nsNPAPIPluginInstance::Destroy()
|
||||||
Stop();
|
Stop();
|
||||||
mPlugin = nullptr;
|
mPlugin = nullptr;
|
||||||
mAudioChannelAgent = nullptr;
|
mAudioChannelAgent = nullptr;
|
||||||
|
|
||||||
#if MOZ_WIDGET_ANDROID
|
|
||||||
if (mContentSurface) {
|
|
||||||
java::SurfaceAllocator::DisposeSurface(mContentSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<void*, VideoInfo*>::iterator it;
|
|
||||||
for (it = mVideos.begin(); it != mVideos.end(); it++) {
|
|
||||||
delete it->second;
|
|
||||||
}
|
|
||||||
mVideos.clear();
|
|
||||||
SetWakeLock(false);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeStamp
|
TimeStamp
|
||||||
|
@ -300,14 +200,6 @@ nsresult nsNPAPIPluginInstance::Stop()
|
||||||
}
|
}
|
||||||
mRunning = DESTROYED;
|
mRunning = DESTROYED;
|
||||||
|
|
||||||
#if MOZ_WIDGET_ANDROID
|
|
||||||
for (uint32_t i = 0; i < mPostedEvents.Length(); i++) {
|
|
||||||
mPostedEvents[i]->Cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
mPostedEvents.Clear();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsJSNPRuntime::OnPluginDestroy(&mNPP);
|
nsJSNPRuntime::OnPluginDestroy(&mNPP);
|
||||||
|
|
||||||
if (error != NPERR_NO_ERROR)
|
if (error != NPERR_NO_ERROR)
|
||||||
|
@ -398,13 +290,8 @@ nsNPAPIPluginInstance::Start()
|
||||||
mCachedParamValues[i] = ToNewUTF8String(attributes[i].mValue);
|
mCachedParamValues[i] = ToNewUTF8String(attributes[i].mValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Android expects and empty string instead of null.
|
|
||||||
mCachedParamNames[attributes.Length()] = ToNewUTF8String(NS_LITERAL_STRING("PARAM"));
|
mCachedParamNames[attributes.Length()] = ToNewUTF8String(NS_LITERAL_STRING("PARAM"));
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
mCachedParamValues[attributes.Length()] = nullptr;
|
||||||
mCachedParamValues[attributes.Length()] = ToNewUTF8String(NS_LITERAL_STRING(""));
|
|
||||||
#else
|
|
||||||
mCachedParamValues[attributes.Length()] = nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (uint32_t i = 0, pos = attributes.Length() + 1; i < params.Length(); i ++) {
|
for (uint32_t i = 0, pos = attributes.Length() + 1; i < params.Length(); i ++) {
|
||||||
mCachedParamNames[pos] = ToNewUTF8String(params[i].mName);
|
mCachedParamNames[pos] = ToNewUTF8String(params[i].mName);
|
||||||
|
@ -594,7 +481,6 @@ nsresult nsNPAPIPluginInstance::HandleEvent(void* event, int16_t* result,
|
||||||
NS_TRY_SAFE_CALL_RETURN(tmpResult, (*pluginFunctions->event)(&mNPP, event), this,
|
NS_TRY_SAFE_CALL_RETURN(tmpResult, (*pluginFunctions->event)(&mNPP, event), this,
|
||||||
aSafeToReenterGecko);
|
aSafeToReenterGecko);
|
||||||
#else
|
#else
|
||||||
MAIN_THREAD_JNI_REF_GUARD;
|
|
||||||
tmpResult = (*pluginFunctions->event)(&mNPP, event);
|
tmpResult = (*pluginFunctions->event)(&mNPP, event);
|
||||||
#endif
|
#endif
|
||||||
NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
NPP_PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
||||||
|
@ -700,270 +586,6 @@ void nsNPAPIPluginInstance::SetEventModel(NPEventModel aModel)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MOZ_WIDGET_ANDROID)
|
|
||||||
|
|
||||||
static void SendLifecycleEvent(nsNPAPIPluginInstance* aInstance, uint32_t aAction)
|
|
||||||
{
|
|
||||||
ANPEvent event;
|
|
||||||
event.inSize = sizeof(ANPEvent);
|
|
||||||
event.eventType = kLifecycle_ANPEventType;
|
|
||||||
event.data.lifecycle.action = aAction;
|
|
||||||
aInstance->HandleEvent(&event, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::NotifyForeground(bool aForeground)
|
|
||||||
{
|
|
||||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::SetForeground this=%p\n foreground=%d",this, aForeground));
|
|
||||||
if (RUNNING != mRunning)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SendLifecycleEvent(this, aForeground ? kResume_ANPLifecycleAction : kPause_ANPLifecycleAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::NotifyOnScreen(bool aOnScreen)
|
|
||||||
{
|
|
||||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::SetOnScreen this=%p\n onScreen=%d",this, aOnScreen));
|
|
||||||
if (RUNNING != mRunning || mOnScreen == aOnScreen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mOnScreen = aOnScreen;
|
|
||||||
SendLifecycleEvent(this, aOnScreen ? kOnScreen_ANPLifecycleAction : kOffScreen_ANPLifecycleAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::MemoryPressure()
|
|
||||||
{
|
|
||||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::MemoryPressure this=%p\n",this));
|
|
||||||
if (RUNNING != mRunning)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SendLifecycleEvent(this, kFreeMemory_ANPLifecycleAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::NotifyFullScreen(bool aFullScreen)
|
|
||||||
{
|
|
||||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::NotifyFullScreen this=%p\n",this));
|
|
||||||
|
|
||||||
if (RUNNING != mRunning || mFullScreen == aFullScreen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mFullScreen = aFullScreen;
|
|
||||||
SendLifecycleEvent(this, mFullScreen ? kEnterFullScreen_ANPLifecycleAction : kExitFullScreen_ANPLifecycleAction);
|
|
||||||
|
|
||||||
if (mFullScreen && mFullScreenOrientation != dom::eScreenOrientation_None) {
|
|
||||||
java::GeckoAppShell::LockScreenOrientation(mFullScreenOrientation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::NotifySize(nsIntSize size)
|
|
||||||
{
|
|
||||||
if (kOpenGL_ANPDrawingModel != GetANPDrawingModel() ||
|
|
||||||
size == mCurrentSize)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mCurrentSize = size;
|
|
||||||
|
|
||||||
ANPEvent event;
|
|
||||||
event.inSize = sizeof(ANPEvent);
|
|
||||||
event.eventType = kDraw_ANPEventType;
|
|
||||||
event.data.draw.model = kOpenGL_ANPDrawingModel;
|
|
||||||
event.data.draw.data.surfaceSize.width = size.width;
|
|
||||||
event.data.draw.data.surfaceSize.height = size.height;
|
|
||||||
|
|
||||||
HandleEvent(&event, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::SetANPDrawingModel(uint32_t aModel)
|
|
||||||
{
|
|
||||||
mANPDrawingModel = aModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* nsNPAPIPluginInstance::GetJavaSurface()
|
|
||||||
{
|
|
||||||
void* surface = nullptr;
|
|
||||||
nsresult rv = GetValueFromPlugin(kJavaSurface_ANPGetValue, &surface);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::PostEvent(void* event)
|
|
||||||
{
|
|
||||||
PluginEventRunnable *r = new PluginEventRunnable(this, (ANPEvent*)event);
|
|
||||||
mPostedEvents.AppendElement(RefPtr<PluginEventRunnable>(r));
|
|
||||||
|
|
||||||
NS_DispatchToMainThread(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::SetFullScreenOrientation(uint32_t orientation)
|
|
||||||
{
|
|
||||||
if (mFullScreenOrientation == orientation)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint32_t oldOrientation = mFullScreenOrientation;
|
|
||||||
mFullScreenOrientation = orientation;
|
|
||||||
|
|
||||||
if (mFullScreen) {
|
|
||||||
// We're already fullscreen so immediately apply the orientation change
|
|
||||||
|
|
||||||
if (mFullScreenOrientation != dom::eScreenOrientation_None) {
|
|
||||||
java::GeckoAppShell::LockScreenOrientation(mFullScreenOrientation);
|
|
||||||
} else if (oldOrientation != dom::eScreenOrientation_None) {
|
|
||||||
// We applied an orientation when we entered fullscreen, but
|
|
||||||
// we don't want it anymore
|
|
||||||
java::GeckoAppShell::UnlockScreenOrientation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::PopPostedEvent(PluginEventRunnable* r)
|
|
||||||
{
|
|
||||||
mPostedEvents.RemoveElement(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::SetWakeLock(bool aLocked)
|
|
||||||
{
|
|
||||||
if (aLocked == mWakeLocked)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mWakeLocked = aLocked;
|
|
||||||
hal::ModifyWakeLock(NS_LITERAL_STRING("screen"),
|
|
||||||
mWakeLocked ? hal::WAKE_LOCK_ADD_ONE : hal::WAKE_LOCK_REMOVE_ONE,
|
|
||||||
hal::WAKE_LOCK_NO_CHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLContext* nsNPAPIPluginInstance::GLContext()
|
|
||||||
{
|
|
||||||
if (!EnsureGLContext())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return sPluginContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
class PluginTextureListener
|
|
||||||
: public java::SurfaceTextureListener::Natives<PluginTextureListener>
|
|
||||||
{
|
|
||||||
using Base = java::SurfaceTextureListener::Natives<PluginTextureListener>;
|
|
||||||
|
|
||||||
const nsCOMPtr<nsIRunnable> mCallback;
|
|
||||||
public:
|
|
||||||
using Base::AttachNative;
|
|
||||||
using Base::DisposeNative;
|
|
||||||
|
|
||||||
PluginTextureListener(nsIRunnable* aCallback) : mCallback(aCallback) {}
|
|
||||||
|
|
||||||
void OnFrameAvailable()
|
|
||||||
{
|
|
||||||
if (NS_IsMainThread()) {
|
|
||||||
mCallback->Run();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NS_DispatchToMainThread(mCallback);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
java::GeckoSurface::LocalRef nsNPAPIPluginInstance::CreateSurface()
|
|
||||||
{
|
|
||||||
java::GeckoSurface::LocalRef surf = java::SurfaceAllocator::AcquireSurface(0, 0, false);
|
|
||||||
if (!surf) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> frameCallback = NewRunnableMethod("nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable",
|
|
||||||
this, &nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable);
|
|
||||||
|
|
||||||
java::SurfaceTextureListener::LocalRef listener = java::SurfaceTextureListener::New();
|
|
||||||
|
|
||||||
PluginTextureListener::AttachNative(listener, MakeUnique<PluginTextureListener>(frameCallback.get()));
|
|
||||||
|
|
||||||
java::GeckoSurfaceTexture::LocalRef gst = java::GeckoSurfaceTexture::Lookup(surf->GetHandle());
|
|
||||||
if (!gst) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& st = java::sdk::SurfaceTexture::Ref::From(gst);
|
|
||||||
st->SetOnFrameAvailableListener(listener);
|
|
||||||
|
|
||||||
return surf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::OnSurfaceTextureFrameAvailable()
|
|
||||||
{
|
|
||||||
if (mRunning == RUNNING && mOwner)
|
|
||||||
mOwner->Recomposite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void* nsNPAPIPluginInstance::AcquireContentWindow()
|
|
||||||
{
|
|
||||||
if (!mContentWindow.NativeWindow()) {
|
|
||||||
mContentSurface = CreateSurface();
|
|
||||||
if (!mContentSurface)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
mContentWindow = AndroidNativeWindow(mContentSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mContentWindow.NativeWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
java::GeckoSurface::Param
|
|
||||||
nsNPAPIPluginInstance::AsSurface()
|
|
||||||
{
|
|
||||||
return mContentSurface;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* nsNPAPIPluginInstance::AcquireVideoWindow()
|
|
||||||
{
|
|
||||||
java::GeckoSurface::LocalRef surface = CreateSurface();
|
|
||||||
VideoInfo* info = new VideoInfo(surface);
|
|
||||||
|
|
||||||
void* window = info->mNativeWindow.NativeWindow();
|
|
||||||
mVideos.insert(std::pair<void*, VideoInfo*>(window, info));
|
|
||||||
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::ReleaseVideoWindow(void* window)
|
|
||||||
{
|
|
||||||
std::map<void*, VideoInfo*>::iterator it = mVideos.find(window);
|
|
||||||
if (it == mVideos.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
delete it->second;
|
|
||||||
mVideos.erase(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::SetVideoDimensions(void* window, gfxRect aDimensions)
|
|
||||||
{
|
|
||||||
std::map<void*, VideoInfo*>::iterator it;
|
|
||||||
|
|
||||||
it = mVideos.find(window);
|
|
||||||
if (it == mVideos.end())
|
|
||||||
return;
|
|
||||||
|
|
||||||
it->second->mDimensions = aDimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsNPAPIPluginInstance::GetVideos(nsTArray<VideoInfo*>& aVideos)
|
|
||||||
{
|
|
||||||
std::map<void*, VideoInfo*>::iterator it;
|
|
||||||
for (it = mVideos.begin(); it != mVideos.end(); it++)
|
|
||||||
aVideos.AppendElement(it->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsNPAPIPluginInstance* nsNPAPIPluginInstance::GetFromNPP(NPP npp)
|
|
||||||
{
|
|
||||||
std::map<NPP, nsNPAPIPluginInstance*>::iterator it;
|
|
||||||
|
|
||||||
it = sPluginNPPMap.find(npp);
|
|
||||||
if (it == sPluginNPPMap.end())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsresult nsNPAPIPluginInstance::GetDrawingModel(int32_t* aModel)
|
nsresult nsNPAPIPluginInstance::GetDrawingModel(int32_t* aModel)
|
||||||
{
|
{
|
||||||
*aModel = (int32_t)mDrawingModel;
|
*aModel = (int32_t)mDrawingModel;
|
||||||
|
@ -1062,9 +684,8 @@ nsNPAPIPluginInstance::ShouldCache()
|
||||||
nsresult
|
nsresult
|
||||||
nsNPAPIPluginInstance::IsWindowless(bool* isWindowless)
|
nsNPAPIPluginInstance::IsWindowless(bool* isWindowless)
|
||||||
{
|
{
|
||||||
#if defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX)
|
#if defined(XP_MACOSX)
|
||||||
// All OS X plugins are windowless.
|
// All OS X plugins are windowless.
|
||||||
// On android, pre-honeycomb, all plugins are treated as windowless.
|
|
||||||
*isWindowless = true;
|
*isWindowless = true;
|
||||||
#else
|
#else
|
||||||
*isWindowless = mWindowless;
|
*isWindowless = mWindowless;
|
||||||
|
@ -1367,7 +988,6 @@ PluginTimerCallback(nsITimer *aTimer, void *aClosure)
|
||||||
|
|
||||||
PLUGIN_LOG(PLUGIN_LOG_NOISY, ("nsNPAPIPluginInstance running plugin timer callback this=%p\n", npp->ndata));
|
PLUGIN_LOG(PLUGIN_LOG_NOISY, ("nsNPAPIPluginInstance running plugin timer callback this=%p\n", npp->ndata));
|
||||||
|
|
||||||
MAIN_THREAD_JNI_REF_GUARD;
|
|
||||||
// Some plugins (Flash on Android) calls unscheduletimer
|
// Some plugins (Flash on Android) calls unscheduletimer
|
||||||
// from this callback.
|
// from this callback.
|
||||||
t->inCallback = true;
|
t->inCallback = true;
|
||||||
|
|
|
@ -18,14 +18,6 @@
|
||||||
#include <prinrval.h>
|
#include <prinrval.h>
|
||||||
#include "js/TypeDecls.h"
|
#include "js/TypeDecls.h"
|
||||||
#include "nsIAudioChannelAgent.h"
|
#include "nsIAudioChannelAgent.h"
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
#include "nsIRunnable.h"
|
|
||||||
#include "GLContextTypes.h"
|
|
||||||
#include "AndroidNativeWindow.h"
|
|
||||||
#include "AndroidBridge.h"
|
|
||||||
#include <map>
|
|
||||||
class PluginEventRunnable;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mozilla/EventForwards.h"
|
#include "mozilla/EventForwards.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
|
@ -164,92 +156,6 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
void NotifyForeground(bool aForeground);
|
|
||||||
void NotifyOnScreen(bool aOnScreen);
|
|
||||||
void MemoryPressure();
|
|
||||||
void NotifyFullScreen(bool aFullScreen);
|
|
||||||
void NotifySize(nsIntSize size);
|
|
||||||
|
|
||||||
nsIntSize CurrentSize() { return mCurrentSize; }
|
|
||||||
|
|
||||||
bool IsOnScreen() {
|
|
||||||
return mOnScreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t GetANPDrawingModel() { return mANPDrawingModel; }
|
|
||||||
void SetANPDrawingModel(uint32_t aModel);
|
|
||||||
|
|
||||||
void* GetJavaSurface();
|
|
||||||
|
|
||||||
void PostEvent(void* event);
|
|
||||||
|
|
||||||
// These are really mozilla::dom::ScreenOrientation, but it's
|
|
||||||
// difficult to include that here
|
|
||||||
uint32_t FullScreenOrientation() { return mFullScreenOrientation; }
|
|
||||||
void SetFullScreenOrientation(uint32_t orientation);
|
|
||||||
|
|
||||||
void SetWakeLock(bool aLock);
|
|
||||||
|
|
||||||
mozilla::gl::GLContext* GLContext();
|
|
||||||
|
|
||||||
// For ANPOpenGL
|
|
||||||
class TextureInfo {
|
|
||||||
public:
|
|
||||||
TextureInfo() :
|
|
||||||
mTexture(0), mWidth(0), mHeight(0), mInternalFormat(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureInfo(GLuint aTexture, int32_t aWidth, int32_t aHeight, GLuint aInternalFormat) :
|
|
||||||
mTexture(aTexture), mWidth(aWidth), mHeight(aHeight), mInternalFormat(aInternalFormat)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint mTexture;
|
|
||||||
int32_t mWidth;
|
|
||||||
int32_t mHeight;
|
|
||||||
GLuint mInternalFormat;
|
|
||||||
};
|
|
||||||
|
|
||||||
// For ANPNativeWindow
|
|
||||||
void* AcquireContentWindow();
|
|
||||||
|
|
||||||
mozilla::java::GeckoSurface::Param AsSurface();
|
|
||||||
|
|
||||||
// For ANPVideo
|
|
||||||
class VideoInfo {
|
|
||||||
public:
|
|
||||||
VideoInfo(mozilla::java::GeckoSurface::Param aSurface)
|
|
||||||
: mSurface(aSurface)
|
|
||||||
, mNativeWindow(aSurface)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~VideoInfo()
|
|
||||||
{
|
|
||||||
mozilla::java::SurfaceAllocator::DisposeSurface(mSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::java::GeckoSurface::GlobalRef mSurface;
|
|
||||||
mozilla::gl::AndroidNativeWindow mNativeWindow;
|
|
||||||
gfxRect mDimensions;
|
|
||||||
};
|
|
||||||
|
|
||||||
void* AcquireVideoWindow();
|
|
||||||
void ReleaseVideoWindow(void* aWindow);
|
|
||||||
void SetVideoDimensions(void* aWindow, gfxRect aDimensions);
|
|
||||||
|
|
||||||
void GetVideos(nsTArray<VideoInfo*>& aVideos);
|
|
||||||
|
|
||||||
void SetOriginPos(mozilla::gl::OriginPos aOriginPos) {
|
|
||||||
mOriginPos = aOriginPos;
|
|
||||||
}
|
|
||||||
mozilla::gl::OriginPos OriginPos() const { return mOriginPos; }
|
|
||||||
|
|
||||||
static nsNPAPIPluginInstance* GetFromNPP(NPP npp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsresult NewStreamListener(const char* aURL, void* notifyData,
|
nsresult NewStreamListener(const char* aURL, void* notifyData,
|
||||||
nsNPAPIPluginStreamListener** listener);
|
nsNPAPIPluginStreamListener** listener);
|
||||||
|
|
||||||
|
@ -342,24 +248,6 @@ protected:
|
||||||
|
|
||||||
NPDrawingModel mDrawingModel;
|
NPDrawingModel mDrawingModel;
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
uint32_t mANPDrawingModel;
|
|
||||||
|
|
||||||
friend class PluginEventRunnable;
|
|
||||||
|
|
||||||
nsTArray<RefPtr<PluginEventRunnable>> mPostedEvents;
|
|
||||||
void PopPostedEvent(PluginEventRunnable* r);
|
|
||||||
void OnSurfaceTextureFrameAvailable();
|
|
||||||
|
|
||||||
uint32_t mFullScreenOrientation;
|
|
||||||
bool mWakeLocked;
|
|
||||||
bool mFullScreen;
|
|
||||||
mozilla::gl::OriginPos mOriginPos;
|
|
||||||
|
|
||||||
mozilla::java::GeckoSurface::GlobalRef mContentSurface;
|
|
||||||
mozilla::gl::AndroidNativeWindow mContentWindow;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NOT_STARTED,
|
NOT_STARTED,
|
||||||
RUNNING,
|
RUNNING,
|
||||||
|
@ -406,13 +294,8 @@ private:
|
||||||
// This is only valid when the plugin is actually stopped!
|
// This is only valid when the plugin is actually stopped!
|
||||||
mozilla::TimeStamp mStopTime;
|
mozilla::TimeStamp mStopTime;
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
// is this instance Java and affected by bug 750480?
|
||||||
mozilla::java::GeckoSurface::LocalRef CreateSurface();
|
bool mHaveJavaC2PJSObjectQuirk;
|
||||||
std::map<void*, VideoInfo*> mVideos;
|
|
||||||
bool mOnScreen;
|
|
||||||
|
|
||||||
nsIntSize mCurrentSize;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static uint32_t gInUnsafePluginCalls;
|
static uint32_t gInUnsafePluginCalls;
|
||||||
|
|
||||||
|
@ -426,20 +309,11 @@ private:
|
||||||
bool mMuted;
|
bool mMuted;
|
||||||
};
|
};
|
||||||
|
|
||||||
// On Android, we need to guard against plugin code leaking entries in the local
|
|
||||||
// JNI ref table. See https://bugzilla.mozilla.org/show_bug.cgi?id=780831#c21
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
#define MAIN_THREAD_JNI_REF_GUARD mozilla::AutoLocalJNIFrame jniFrame
|
|
||||||
#else
|
|
||||||
#define MAIN_THREAD_JNI_REF_GUARD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState);
|
void NS_NotifyBeginPluginCall(NSPluginCallReentry aReentryState);
|
||||||
void NS_NotifyPluginCall(NSPluginCallReentry aReentryState);
|
void NS_NotifyPluginCall(NSPluginCallReentry aReentryState);
|
||||||
|
|
||||||
#define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst, pluginCallReentry) \
|
#define NS_TRY_SAFE_CALL_RETURN(ret, fun, pluginInst, pluginCallReentry) \
|
||||||
PR_BEGIN_MACRO \
|
PR_BEGIN_MACRO \
|
||||||
MAIN_THREAD_JNI_REF_GUARD; \
|
|
||||||
NS_NotifyBeginPluginCall(pluginCallReentry); \
|
NS_NotifyBeginPluginCall(pluginCallReentry); \
|
||||||
ret = fun; \
|
ret = fun; \
|
||||||
NS_NotifyPluginCall(pluginCallReentry); \
|
NS_NotifyPluginCall(pluginCallReentry); \
|
||||||
|
@ -447,7 +321,6 @@ PR_END_MACRO
|
||||||
|
|
||||||
#define NS_TRY_SAFE_CALL_VOID(fun, pluginInst, pluginCallReentry) \
|
#define NS_TRY_SAFE_CALL_VOID(fun, pluginInst, pluginCallReentry) \
|
||||||
PR_BEGIN_MACRO \
|
PR_BEGIN_MACRO \
|
||||||
MAIN_THREAD_JNI_REF_GUARD; \
|
|
||||||
NS_NotifyBeginPluginCall(pluginCallReentry); \
|
NS_NotifyBeginPluginCall(pluginCallReentry); \
|
||||||
fun; \
|
fun; \
|
||||||
NS_NotifyPluginCall(pluginCallReentry); \
|
NS_NotifyPluginCall(pluginCallReentry); \
|
||||||
|
|
|
@ -841,7 +841,6 @@ nsNPAPIPluginStreamListener::HandleRedirectNotification(nsIChannel *oldChannel,
|
||||||
NS_TRY_SAFE_CALL_VOID((*pluginFunctions->urlredirectnotify)(npp, spec.get(), static_cast<int32_t>(status), mNPStreamWrapper->mNPStream.notifyData), mInst,
|
NS_TRY_SAFE_CALL_VOID((*pluginFunctions->urlredirectnotify)(npp, spec.get(), static_cast<int32_t>(status), mNPStreamWrapper->mNPStream.notifyData), mInst,
|
||||||
NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
|
NS_PLUGIN_CALL_UNSAFE_TO_REENTER_GECKO);
|
||||||
#else
|
#else
|
||||||
MAIN_THREAD_JNI_REF_GUARD;
|
|
||||||
(*pluginFunctions->urlredirectnotify)(npp, spec.get(), static_cast<int32_t>(status), mNPStreamWrapper->mNPStream.notifyData);
|
(*pluginFunctions->urlredirectnotify)(npp, spec.get(), static_cast<int32_t>(status), mNPStreamWrapper->mNPStream.notifyData);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -103,11 +103,6 @@
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ANDROID
|
|
||||||
#include <android/log.h>
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MOZ_CRASHREPORTER
|
#if MOZ_CRASHREPORTER
|
||||||
#include "nsExceptionHandler.h"
|
#include "nsExceptionHandler.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -278,10 +273,6 @@ nsPluginHost::nsPluginHost()
|
||||||
if (obsService) {
|
if (obsService) {
|
||||||
obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
|
||||||
obsService->AddObserver(this, "blocklist-updated", false);
|
obsService->AddObserver(this, "blocklist-updated", false);
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
obsService->AddObserver(this, "application-foreground", false);
|
|
||||||
obsService->AddObserver(this, "application-background", false);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PLUGIN_LOGGING
|
#ifdef PLUGIN_LOGGING
|
||||||
|
@ -877,12 +868,6 @@ nsPluginHost::TrySetUpPluginInstance(const nsACString &aMimeType,
|
||||||
|
|
||||||
plugin->GetLibrary()->SetHasLocalInstance();
|
plugin->GetLibrary()->SetHasLocalInstance();
|
||||||
|
|
||||||
#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_CRASHREPORTER)
|
|
||||||
if (pluginTag->mIsFlashPlugin) {
|
|
||||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FlashVersion"), pluginTag->Version());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RefPtr<nsNPAPIPluginInstance> instance = new nsNPAPIPluginInstance();
|
RefPtr<nsNPAPIPluginInstance> instance = new nsNPAPIPluginInstance();
|
||||||
|
|
||||||
// This will create the owning reference. The connection must be made between the
|
// This will create the owning reference. The connection must be made between the
|
||||||
|
@ -2466,10 +2451,6 @@ nsresult nsPluginHost::FindPlugins(bool aCreatePluginList, bool * aPluginsChange
|
||||||
NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
NS_ITERATIVE_UNREF_LIST(RefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
#ifdef ANDROID
|
|
||||||
LOG("getting plugins dir failed");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mPluginsLoaded = true; // at this point 'some' plugins have been loaded,
|
mPluginsLoaded = true; // at this point 'some' plugins have been loaded,
|
||||||
|
@ -3060,14 +3041,6 @@ nsPluginHost::ReadPluginInfo()
|
||||||
if (!reader.NextLine())
|
if (!reader.NextLine())
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
#if MOZ_WIDGET_ANDROID
|
|
||||||
// Flash on Android does not populate the version field, but it is tacked on to the description.
|
|
||||||
// For example, "Shockwave Flash 11.1 r115"
|
|
||||||
if (PL_strncmp("Shockwave Flash ", description, 16) == 0 && description[16]) {
|
|
||||||
version = &description[16];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char *name = reader.LinePtr();
|
const char *name = reader.LinePtr();
|
||||||
if (!reader.NextLine())
|
if (!reader.NextLine())
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -3133,8 +3106,6 @@ nsPluginHost::ReadPluginInfo()
|
||||||
mCachedPlugins = tag;
|
mCachedPlugins = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On Android we always want to try to load a plugin again (Flash). Bug 935676.
|
|
||||||
#ifndef MOZ_WIDGET_ANDROID
|
|
||||||
if (!ReadSectionHeader(reader, "INVALID")) {
|
if (!ReadSectionHeader(reader, "INVALID")) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -3156,7 +3127,6 @@ nsPluginHost::ReadPluginInfo()
|
||||||
}
|
}
|
||||||
mInvalidPlugins = invalidTag;
|
mInvalidPlugins = invalidTag;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -3488,24 +3458,6 @@ NS_IMETHODIMP nsPluginHost::Observe(nsISupports *aSubject,
|
||||||
SendPluginsToContent();
|
SendPluginsToContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
if (!strcmp("application-background", aTopic)) {
|
|
||||||
for(uint32_t i = 0; i < mInstances.Length(); i++) {
|
|
||||||
mInstances[i]->NotifyForeground(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!strcmp("application-foreground", aTopic)) {
|
|
||||||
for(uint32_t i = 0; i < mInstances.Length(); i++) {
|
|
||||||
if (mInstances[i]->IsOnScreen())
|
|
||||||
mInstances[i]->NotifyForeground(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!strcmp("memory-pressure", aTopic)) {
|
|
||||||
for(uint32_t i = 0; i < mInstances.Length(); i++) {
|
|
||||||
mInstances[i]->MemoryPressure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,21 +86,6 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
#include "ANPBase.h"
|
|
||||||
#include "AndroidBridge.h"
|
|
||||||
#include "ClientLayerManager.h"
|
|
||||||
#include "FennecJNIWrappers.h"
|
|
||||||
#include "nsWindow.h"
|
|
||||||
|
|
||||||
static nsPluginInstanceOwner* sFullScreenInstance = nullptr;
|
|
||||||
|
|
||||||
using namespace mozilla::dom;
|
|
||||||
|
|
||||||
#include <android/log.h>
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
|
@ -163,30 +148,6 @@ nsPluginInstanceOwner::NotifyPaintWaiter(nsDisplayListBuilder* aBuilder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MOZ_WIDGET_ANDROID
|
|
||||||
static void
|
|
||||||
AttachToContainerAsSurface(ImageContainer* container,
|
|
||||||
nsNPAPIPluginInstance* instance,
|
|
||||||
const LayoutDeviceRect& rect,
|
|
||||||
RefPtr<Image>* out_image)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(out_image);
|
|
||||||
MOZ_ASSERT(!*out_image);
|
|
||||||
|
|
||||||
java::GeckoSurface::LocalRef surface = instance->AsSurface();
|
|
||||||
if (!surface) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RefPtr<Image> img = new SurfaceTextureImage(
|
|
||||||
surface->GetHandle(),
|
|
||||||
gfx::IntSize::Truncate(rect.width, rect.height),
|
|
||||||
true, // continuously update without a transaction
|
|
||||||
instance->OriginPos());
|
|
||||||
*out_image = img;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsPluginInstanceOwner::NeedsScrollImageLayer()
|
nsPluginInstanceOwner::NeedsScrollImageLayer()
|
||||||
{
|
{
|
||||||
|
@ -210,27 +171,6 @@ nsPluginInstanceOwner::GetImageContainer()
|
||||||
|
|
||||||
RefPtr<ImageContainer> container;
|
RefPtr<ImageContainer> container;
|
||||||
|
|
||||||
#if MOZ_WIDGET_ANDROID
|
|
||||||
LayoutDeviceRect r = GetPluginRect();
|
|
||||||
|
|
||||||
// NotifySize() causes Flash to do a bunch of stuff like ask for surfaces to render
|
|
||||||
// into, set y-flip flags, etc, so we do this at the beginning.
|
|
||||||
float resolution = mPluginFrame->PresContext()->PresShell()->GetCumulativeResolution();
|
|
||||||
ScreenSize screenSize = (r * LayoutDeviceToScreenScale(resolution)).Size();
|
|
||||||
mInstance->NotifySize(nsIntSize::Truncate(screenSize.width, screenSize.height));
|
|
||||||
|
|
||||||
container = LayerManager::CreateImageContainer();
|
|
||||||
|
|
||||||
if (r.width && r.height) {
|
|
||||||
// Try to get it as an EGLImage first.
|
|
||||||
RefPtr<Image> img;
|
|
||||||
AttachToContainerAsSurface(container, mInstance, r, &img);
|
|
||||||
|
|
||||||
if (img) {
|
|
||||||
container->SetCurrentImageInTransaction(img);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (NeedsScrollImageLayer()) {
|
if (NeedsScrollImageLayer()) {
|
||||||
// windowed plugin under e10s
|
// windowed plugin under e10s
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
|
@ -240,7 +180,6 @@ nsPluginInstanceOwner::GetImageContainer()
|
||||||
// async windowless rendering
|
// async windowless rendering
|
||||||
mInstance->GetImageContainer(getter_AddRefs(container));
|
mInstance->GetImageContainer(getter_AddRefs(container));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return container.forget();
|
return container.forget();
|
||||||
}
|
}
|
||||||
|
@ -357,11 +296,6 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
|
||||||
|
|
||||||
mWaitingForPaint = false;
|
mWaitingForPaint = false;
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
mFullScreen = false;
|
|
||||||
mJavaView = nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
mGotCompositionData = false;
|
mGotCompositionData = false;
|
||||||
mSentStartComposition = false;
|
mSentStartComposition = false;
|
||||||
|
@ -386,10 +320,6 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
|
||||||
PLUG_DeletePluginNativeWindow(mPluginWindow);
|
PLUG_DeletePluginNativeWindow(mPluginWindow);
|
||||||
mPluginWindow = nullptr;
|
mPluginWindow = nullptr;
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
RemovePluginView();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mInstance) {
|
if (mInstance) {
|
||||||
mInstance->SetOwner(nullptr);
|
mInstance->SetOwner(nullptr);
|
||||||
}
|
}
|
||||||
|
@ -412,10 +342,6 @@ nsPluginInstanceOwner::SetInstance(nsNPAPIPluginInstance *aInstance)
|
||||||
// from our destructor. This fixes bug 613376.
|
// from our destructor. This fixes bug 613376.
|
||||||
if (mInstance && !aInstance) {
|
if (mInstance && !aInstance) {
|
||||||
mInstance->SetOwner(nullptr);
|
mInstance->SetOwner(nullptr);
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
RemovePluginView();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mInstance = aInstance;
|
mInstance = aInstance;
|
||||||
|
@ -600,10 +526,9 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
|
||||||
if (!mPluginFrame || !invalidRect || !mWidgetVisible)
|
if (!mPluginFrame || !invalidRect || !mWidgetVisible)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
#if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
|
#if defined(XP_MACOSX)
|
||||||
// Each time an asynchronously-drawing plugin sends a new surface to display,
|
// Each time an asynchronously-drawing plugin sends a new surface to display,
|
||||||
// the image in the ImageContainer is updated and InvalidateRect is called.
|
// the image in the ImageContainer is updated and InvalidateRect is called.
|
||||||
// There are different side effects for (sync) Android plugins.
|
|
||||||
RefPtr<ImageContainer> container;
|
RefPtr<ImageContainer> container;
|
||||||
mInstance->GetImageContainer(getter_AddRefs(container));
|
mInstance->GetImageContainer(getter_AddRefs(container));
|
||||||
#endif
|
#endif
|
||||||
|
@ -1485,209 +1410,8 @@ nsPluginInstanceOwner::GetEventloopNestingLevel()
|
||||||
return currentLevel;
|
return currentLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
|
|
||||||
// Modified version of nsFrame::GetOffsetToCrossDoc that stops when it
|
|
||||||
// hits an element with a displayport (or runs out of frames). This is
|
|
||||||
// not really the right thing to do, but it's better than what was here before.
|
|
||||||
static nsPoint
|
|
||||||
GetOffsetRootContent(nsIFrame* aFrame)
|
|
||||||
{
|
|
||||||
// offset will hold the final offset
|
|
||||||
// docOffset holds the currently accumulated offset at the current APD, it
|
|
||||||
// will be converted and added to offset when the current APD changes.
|
|
||||||
nsPoint offset(0, 0), docOffset(0, 0);
|
|
||||||
const nsIFrame* f = aFrame;
|
|
||||||
int32_t currAPD = aFrame->PresContext()->AppUnitsPerDevPixel();
|
|
||||||
int32_t apd = currAPD;
|
|
||||||
while (f) {
|
|
||||||
if (f->GetContent() && nsLayoutUtils::HasDisplayPort(f->GetContent()))
|
|
||||||
break;
|
|
||||||
|
|
||||||
docOffset += f->GetPosition();
|
|
||||||
nsIFrame* parent = f->GetParent();
|
|
||||||
if (parent) {
|
|
||||||
f = parent;
|
|
||||||
} else {
|
|
||||||
nsPoint newOffset(0, 0);
|
|
||||||
f = nsLayoutUtils::GetCrossDocParentFrame(f, &newOffset);
|
|
||||||
int32_t newAPD = f ? f->PresContext()->AppUnitsPerDevPixel() : 0;
|
|
||||||
if (!f || newAPD != currAPD) {
|
|
||||||
// Convert docOffset to the right APD and add it to offset.
|
|
||||||
offset += docOffset.ScaleToOtherAppUnits(currAPD, apd);
|
|
||||||
docOffset.x = docOffset.y = 0;
|
|
||||||
}
|
|
||||||
currAPD = newAPD;
|
|
||||||
docOffset += newOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += docOffset.ScaleToOtherAppUnits(currAPD, apd);
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
LayoutDeviceRect nsPluginInstanceOwner::GetPluginRect()
|
|
||||||
{
|
|
||||||
// Get the offset of the content relative to the page
|
|
||||||
nsRect bounds = mPluginFrame->GetContentRectRelativeToSelf() + GetOffsetRootContent(mPluginFrame);
|
|
||||||
LayoutDeviceIntRect rect = LayoutDeviceIntRect::FromAppUnitsToNearest(bounds, mPluginFrame->PresContext()->AppUnitsPerDevPixel());
|
|
||||||
return LayoutDeviceRect(rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nsPluginInstanceOwner::AddPluginView(const LayoutDeviceRect& aRect /* = LayoutDeviceRect(0, 0, 0, 0) */)
|
|
||||||
{
|
|
||||||
if (!mJavaView) {
|
|
||||||
mJavaView = mInstance->GetJavaSurface();
|
|
||||||
|
|
||||||
if (!mJavaView)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
mJavaView = (void*)jni::GetGeckoThreadEnv()->NewGlobalRef((jobject)mJavaView);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mFullScreen && jni::IsFennec()) {
|
|
||||||
java::GeckoApp::AddPluginView(jni::Object::Ref::From(jobject(mJavaView)));
|
|
||||||
sFullScreenInstance = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsPluginInstanceOwner::RemovePluginView()
|
|
||||||
{
|
|
||||||
if (!mInstance || !mJavaView)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (mFullScreen && jni::IsFennec()) {
|
|
||||||
java::GeckoApp::RemovePluginView(jni::Object::Ref::From(jobject(mJavaView)));
|
|
||||||
}
|
|
||||||
jni::GetGeckoThreadEnv()->DeleteGlobalRef((jobject)mJavaView);
|
|
||||||
mJavaView = nullptr;
|
|
||||||
|
|
||||||
if (mFullScreen)
|
|
||||||
sFullScreenInstance = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsPluginInstanceOwner::GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos)
|
|
||||||
{
|
|
||||||
if (!mInstance)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mInstance->GetVideos(aVideos);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<ImageContainer>
|
|
||||||
nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo)
|
|
||||||
{
|
|
||||||
RefPtr<ImageContainer> container = LayerManager::CreateImageContainer();
|
|
||||||
|
|
||||||
if (aVideoInfo->mDimensions.width && aVideoInfo->mDimensions.height) {
|
|
||||||
RefPtr<Image> img = new SurfaceTextureImage(
|
|
||||||
aVideoInfo->mSurface->GetHandle(),
|
|
||||||
gfx::IntSize::Truncate(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height),
|
|
||||||
true, /* continuous */
|
|
||||||
gl::OriginPos::BottomLeft);
|
|
||||||
container->SetCurrentImageInTransaction(img);
|
|
||||||
}
|
|
||||||
|
|
||||||
return container.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsPluginInstanceOwner::Invalidate() {
|
|
||||||
NPRect rect;
|
|
||||||
rect.left = rect.top = 0;
|
|
||||||
rect.right = mPluginWindow->width;
|
|
||||||
rect.bottom = mPluginWindow->height;
|
|
||||||
InvalidateRect(&rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsPluginInstanceOwner::Recomposite() {
|
|
||||||
nsIWidget* const widget = mPluginFrame->GetNearestWidget();
|
|
||||||
NS_ENSURE_TRUE_VOID(widget);
|
|
||||||
|
|
||||||
LayerManager* const lm = widget->GetLayerManager();
|
|
||||||
NS_ENSURE_TRUE_VOID(lm);
|
|
||||||
|
|
||||||
ClientLayerManager* const clm = lm->AsClientLayerManager();
|
|
||||||
NS_ENSURE_TRUE_VOID(clm && clm->GetRoot());
|
|
||||||
|
|
||||||
clm->SendInvalidRegion(
|
|
||||||
clm->GetRoot()->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
|
|
||||||
clm->ScheduleComposite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsPluginInstanceOwner::RequestFullScreen() {
|
|
||||||
if (mFullScreen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Remove whatever view we currently have (if any, fullscreen or otherwise)
|
|
||||||
RemovePluginView();
|
|
||||||
|
|
||||||
mFullScreen = true;
|
|
||||||
AddPluginView();
|
|
||||||
|
|
||||||
mInstance->NotifyFullScreen(mFullScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsPluginInstanceOwner::ExitFullScreen() {
|
|
||||||
if (!mFullScreen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
RemovePluginView();
|
|
||||||
|
|
||||||
mFullScreen = false;
|
|
||||||
|
|
||||||
int32_t model = mInstance->GetANPDrawingModel();
|
|
||||||
|
|
||||||
if (model == kSurface_ANPDrawingModel) {
|
|
||||||
// We need to do this immediately, otherwise Flash
|
|
||||||
// sometimes causes a deadlock (bug 762407)
|
|
||||||
AddPluginView(GetPluginRect());
|
|
||||||
}
|
|
||||||
|
|
||||||
mInstance->NotifyFullScreen(mFullScreen);
|
|
||||||
|
|
||||||
// This will cause Paint() to be called, which is where
|
|
||||||
// we normally add/update views and layers
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsPluginInstanceOwner::ExitFullScreen(jobject view) {
|
|
||||||
JNIEnv* env = jni::GetGeckoThreadEnv();
|
|
||||||
|
|
||||||
if (sFullScreenInstance && sFullScreenInstance->mInstance &&
|
|
||||||
env->IsSameObject(view, (jobject)sFullScreenInstance->mInstance->GetJavaSurface())) {
|
|
||||||
sFullScreenInstance->ExitFullScreen();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
|
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
|
||||||
{
|
{
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
if (mInstance) {
|
|
||||||
ANPEvent event;
|
|
||||||
event.inSize = sizeof(ANPEvent);
|
|
||||||
event.eventType = kLifecycle_ANPEventType;
|
|
||||||
|
|
||||||
nsAutoString eventType;
|
|
||||||
aFocusEvent->GetType(eventType);
|
|
||||||
if (eventType.EqualsLiteral("focus")) {
|
|
||||||
event.data.lifecycle.action = kGainFocus_ANPLifecycleAction;
|
|
||||||
}
|
|
||||||
else if (eventType.EqualsLiteral("blur")) {
|
|
||||||
event.data.lifecycle.action = kLoseFocus_ANPLifecycleAction;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NS_ASSERTION(false, "nsPluginInstanceOwner::DispatchFocusToPlugin, wierd eventType");
|
|
||||||
}
|
|
||||||
mInstance->HandleEvent(&event, nullptr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef XP_MACOSX
|
#ifndef XP_MACOSX
|
||||||
if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow)) {
|
if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow)) {
|
||||||
// continue only for cases without child window
|
// continue only for cases without child window
|
||||||
|
@ -2748,96 +2472,6 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
|
||||||
rv = nsEventStatus_eConsumeNoDefault;
|
rv = nsEventStatus_eConsumeNoDefault;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
// this code supports windowless plugins
|
|
||||||
{
|
|
||||||
// The plugin needs focus to receive keyboard and touch events
|
|
||||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
|
||||||
if (fm) {
|
|
||||||
nsCOMPtr<nsIDOMElement> elem = do_QueryReferent(mContent);
|
|
||||||
fm->SetFocus(elem, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch(anEvent.mClass) {
|
|
||||||
case eMouseEventClass:
|
|
||||||
{
|
|
||||||
switch (anEvent.mMessage) {
|
|
||||||
case eMouseClick:
|
|
||||||
case eMouseDoubleClick:
|
|
||||||
case eMouseAuxClick:
|
|
||||||
// Button up/down events sent instead.
|
|
||||||
return rv;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get reference point relative to plugin origin.
|
|
||||||
const nsPresContext* presContext = mPluginFrame->PresContext();
|
|
||||||
nsPoint appPoint =
|
|
||||||
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
|
|
||||||
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
|
|
||||||
nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
|
|
||||||
presContext->AppUnitsToDevPixels(appPoint.y));
|
|
||||||
|
|
||||||
switch (anEvent.mMessage) {
|
|
||||||
case eMouseMove:
|
|
||||||
{
|
|
||||||
// are these going to be touch events?
|
|
||||||
// pluginPoint.x;
|
|
||||||
// pluginPoint.y;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case eMouseDown:
|
|
||||||
{
|
|
||||||
ANPEvent event;
|
|
||||||
event.inSize = sizeof(ANPEvent);
|
|
||||||
event.eventType = kMouse_ANPEventType;
|
|
||||||
event.data.mouse.action = kDown_ANPMouseAction;
|
|
||||||
event.data.mouse.x = pluginPoint.x;
|
|
||||||
event.data.mouse.y = pluginPoint.y;
|
|
||||||
mInstance->HandleEvent(&event, nullptr, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case eMouseUp:
|
|
||||||
{
|
|
||||||
ANPEvent event;
|
|
||||||
event.inSize = sizeof(ANPEvent);
|
|
||||||
event.eventType = kMouse_ANPEventType;
|
|
||||||
event.data.mouse.action = kUp_ANPMouseAction;
|
|
||||||
event.data.mouse.x = pluginPoint.x;
|
|
||||||
event.data.mouse.y = pluginPoint.y;
|
|
||||||
mInstance->HandleEvent(&event, nullptr, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case eKeyboardEventClass:
|
|
||||||
{
|
|
||||||
const WidgetKeyboardEvent& keyEvent = *anEvent.AsKeyboardEvent();
|
|
||||||
LOG("Firing eKeyboardEventClass %d %d\n",
|
|
||||||
keyEvent.mKeyCode, keyEvent.mCharCode);
|
|
||||||
// pluginEvent is initialized by nsWindow::InitKeyEvent().
|
|
||||||
const ANPEvent* pluginEvent = static_cast<const ANPEvent*>(keyEvent.mPluginEvent);
|
|
||||||
if (pluginEvent) {
|
|
||||||
MOZ_ASSERT(pluginEvent->inSize == sizeof(ANPEvent));
|
|
||||||
MOZ_ASSERT(pluginEvent->eventType == kKey_ANPEventType);
|
|
||||||
mInstance->HandleEvent(const_cast<ANPEvent*>(pluginEvent),
|
|
||||||
nullptr,
|
|
||||||
NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rv = nsEventStatus_eConsumeNoDefault;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2884,10 +2518,6 @@ nsPluginInstanceOwner::Destroy()
|
||||||
this, true);
|
this, true);
|
||||||
content->RemoveSystemEventListener(NS_LITERAL_STRING("text"), this, true);
|
content->RemoveSystemEventListener(NS_LITERAL_STRING("text"), this, true);
|
||||||
|
|
||||||
#if MOZ_WIDGET_ANDROID
|
|
||||||
RemovePluginView();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (mWidget) {
|
if (mWidget) {
|
||||||
if (mPluginWindow) {
|
if (mPluginWindow) {
|
||||||
mPluginWindow->SetPluginWidget(nullptr);
|
mPluginWindow->SetPluginWidget(nullptr);
|
||||||
|
@ -2957,72 +2587,6 @@ void nsPluginInstanceOwner::Paint(const RECT& aDirty, HDC aDC)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
|
|
||||||
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
|
||||||
const gfxRect& aFrameRect,
|
|
||||||
const gfxRect& aDirtyRect)
|
|
||||||
{
|
|
||||||
if (!mInstance || !mPluginFrame || !mPluginDocumentActiveState || mFullScreen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int32_t model = mInstance->GetANPDrawingModel();
|
|
||||||
|
|
||||||
if (model == kSurface_ANPDrawingModel) {
|
|
||||||
if (!AddPluginView(GetPluginRect())) {
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (model != kBitmap_ANPDrawingModel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef ANP_BITMAP_DRAWING_MODEL
|
|
||||||
static RefPtr<gfxImageSurface> pluginSurface;
|
|
||||||
|
|
||||||
if (pluginSurface == nullptr ||
|
|
||||||
aFrameRect.width != pluginSurface->Width() ||
|
|
||||||
aFrameRect.height != pluginSurface->Height()) {
|
|
||||||
|
|
||||||
pluginSurface = new gfxImageSurface(gfx::IntSize(aFrameRect.width, aFrameRect.height),
|
|
||||||
SurfaceFormat::A8R8G8B8_UINT32);
|
|
||||||
if (!pluginSurface)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clears buffer. I think this is needed.
|
|
||||||
gfxUtils::ClearThebesSurface(pluginSurface);
|
|
||||||
|
|
||||||
ANPEvent event;
|
|
||||||
event.inSize = sizeof(ANPEvent);
|
|
||||||
event.eventType = 4;
|
|
||||||
event.data.draw.model = 1;
|
|
||||||
|
|
||||||
event.data.draw.clip.top = 0;
|
|
||||||
event.data.draw.clip.left = 0;
|
|
||||||
event.data.draw.clip.bottom = aFrameRect.width;
|
|
||||||
event.data.draw.clip.right = aFrameRect.height;
|
|
||||||
|
|
||||||
event.data.draw.data.bitmap.format = kRGBA_8888_ANPBitmapFormat;
|
|
||||||
event.data.draw.data.bitmap.width = aFrameRect.width;
|
|
||||||
event.data.draw.data.bitmap.height = aFrameRect.height;
|
|
||||||
event.data.draw.data.bitmap.baseAddr = pluginSurface->Data();
|
|
||||||
event.data.draw.data.bitmap.rowBytes = aFrameRect.width * 4;
|
|
||||||
|
|
||||||
if (!mInstance)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mInstance->HandleEvent(&event, nullptr);
|
|
||||||
|
|
||||||
aContext->SetOp(gfx::CompositionOp::OP_SOURCE);
|
|
||||||
aContext->SetSource(pluginSurface, gfxPoint(aFrameRect.x, aFrameRect.y));
|
|
||||||
aContext->Clip(aFrameRect);
|
|
||||||
aContext->Paint();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MOZ_X11)
|
#if defined(MOZ_X11)
|
||||||
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
||||||
const gfxRect& aFrameRect,
|
const gfxRect& aFrameRect,
|
||||||
|
@ -3628,24 +3192,6 @@ nsPluginInstanceOwner::UpdateDocumentActiveState(bool aIsActive)
|
||||||
#ifndef XP_MACOSX
|
#ifndef XP_MACOSX
|
||||||
UpdateWindowPositionAndClipRect(true);
|
UpdateWindowPositionAndClipRect(true);
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
if (mInstance) {
|
|
||||||
if (!mPluginDocumentActiveState) {
|
|
||||||
RemovePluginView();
|
|
||||||
}
|
|
||||||
|
|
||||||
mInstance->NotifyOnScreen(mPluginDocumentActiveState);
|
|
||||||
|
|
||||||
// This is, perhaps, incorrect. It is supposed to be sent
|
|
||||||
// when "the webview has paused or resumed". The side effect
|
|
||||||
// is that Flash video players pause or resume (if they were
|
|
||||||
// playing before) based on the value here. I personally think
|
|
||||||
// we want that on Android when switching to another tab, so
|
|
||||||
// that's why we call it here.
|
|
||||||
mInstance->NotifyForeground(mPluginDocumentActiveState);
|
|
||||||
}
|
|
||||||
#endif // #ifdef MOZ_WIDGET_ANDROID
|
|
||||||
|
|
||||||
// We don't have a connection to PluginWidgetParent in the chrome
|
// We don't have a connection to PluginWidgetParent in the chrome
|
||||||
// process when dealing with tab visibility changes, so this needs
|
// process when dealing with tab visibility changes, so this needs
|
||||||
// to be forwarded over after the active state is updated. If we
|
// to be forwarded over after the active state is updated. If we
|
||||||
|
|
|
@ -29,7 +29,7 @@ class nsPluginDOMContextMenuListener;
|
||||||
class nsPluginFrame;
|
class nsPluginFrame;
|
||||||
class nsDisplayListBuilder;
|
class nsDisplayListBuilder;
|
||||||
|
|
||||||
#if defined(MOZ_X11) || defined(ANDROID)
|
#if defined(MOZ_X11)
|
||||||
class gfxContext;
|
class gfxContext;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ public:
|
||||||
void Paint(const gfxRect& aDirtyRect, CGContextRef cgContext);
|
void Paint(const gfxRect& aDirtyRect, CGContextRef cgContext);
|
||||||
void RenderCoreAnimation(CGContextRef aCGContext, int aWidth, int aHeight);
|
void RenderCoreAnimation(CGContextRef aCGContext, int aWidth, int aHeight);
|
||||||
void DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext);
|
void DoCocoaEventDrawRect(const gfxRect& aDrawRect, CGContextRef cgContext);
|
||||||
#elif defined(MOZ_X11) || defined(ANDROID)
|
#elif defined(MOZ_X11)
|
||||||
void Paint(gfxContext* aContext,
|
void Paint(gfxContext* aContext,
|
||||||
const gfxRect& aFrameRect,
|
const gfxRect& aFrameRect,
|
||||||
const gfxRect& aDirtyRect);
|
const gfxRect& aDirtyRect);
|
||||||
|
@ -254,21 +254,6 @@ public:
|
||||||
|
|
||||||
already_AddRefed<nsIURI> GetBaseURI() const;
|
already_AddRefed<nsIURI> GetBaseURI() const;
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
// Returns the image container for the specified VideoInfo
|
|
||||||
void GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos);
|
|
||||||
already_AddRefed<mozilla::layers::ImageContainer> GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo);
|
|
||||||
|
|
||||||
void Invalidate();
|
|
||||||
void Recomposite();
|
|
||||||
|
|
||||||
void RequestFullScreen();
|
|
||||||
void ExitFullScreen();
|
|
||||||
|
|
||||||
// Called from nsAppShell when we removed the fullscreen view.
|
|
||||||
static void ExitFullScreen(jobject view);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool GetCompositionString(uint32_t aIndex, nsTArray<uint8_t>* aString,
|
bool GetCompositionString(uint32_t aIndex, nsTArray<uint8_t>* aString,
|
||||||
int32_t* aLength);
|
int32_t* aLength);
|
||||||
bool SetCandidateWindow(
|
bool SetCandidateWindow(
|
||||||
|
@ -302,15 +287,6 @@ private:
|
||||||
size == nsIntSize(mPluginWindow->width, mPluginWindow->height);
|
size == nsIntSize(mPluginWindow->width, mPluginWindow->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
mozilla::LayoutDeviceRect GetPluginRect();
|
|
||||||
bool AddPluginView(const mozilla::LayoutDeviceRect& aRect = mozilla::LayoutDeviceRect(0, 0, 0, 0));
|
|
||||||
void RemovePluginView();
|
|
||||||
|
|
||||||
bool mFullScreen;
|
|
||||||
void* mJavaView;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(XP_WIN)
|
#if defined(XP_WIN)
|
||||||
nsIWidget* GetContainingWidgetIfOffset();
|
nsIWidget* GetContainingWidgetIfOffset();
|
||||||
already_AddRefed<mozilla::TextComposition> GetTextComposition();
|
already_AddRefed<mozilla::TextComposition> GetTextComposition();
|
||||||
|
|
|
@ -695,11 +695,6 @@ nsPluginTag::GetNiceName(nsACString & aResult)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsPluginTag::GetBlocklistState(uint32_t *aResult)
|
nsPluginTag::GetBlocklistState(uint32_t *aResult)
|
||||||
{
|
{
|
||||||
#if defined(MOZ_WIDGET_ANDROID)
|
|
||||||
*aResult = nsIBlocklistService::STATE_NOT_BLOCKED;
|
|
||||||
return NS_OK;
|
|
||||||
#else
|
|
||||||
|
|
||||||
// If we're in the content process, assume our cache state to always be valid,
|
// If we're in the content process, assume our cache state to always be valid,
|
||||||
// as the only way it can be updated is via a plugin list push from the
|
// as the only way it can be updated is via a plugin list push from the
|
||||||
// parent process.
|
// parent process.
|
||||||
|
@ -725,7 +720,6 @@ nsPluginTag::GetBlocklistState(uint32_t *aResult)
|
||||||
mCachedBlocklistState = (uint16_t) *aResult;
|
mCachedBlocklistState = (uint16_t) *aResult;
|
||||||
mCachedBlocklistStateValid = true;
|
mCachedBlocklistStateValid = true;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
#endif // defined(MOZ_WIDGET_ANDROID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -213,16 +213,6 @@ bool nsPluginsDir::IsPluginFile(nsIFile* file)
|
||||||
if (NS_FAILED(file->GetNativeLeafName(filename)))
|
if (NS_FAILED(file->GetNativeLeafName(filename)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#ifdef ANDROID
|
|
||||||
// It appears that if you load
|
|
||||||
// 'libstagefright_honeycomb.so' on froyo, or
|
|
||||||
// 'libstagefright_froyo.so' on honeycomb, we will abort.
|
|
||||||
// Since these are just helper libs, we can ignore.
|
|
||||||
const char *cFile = filename.get();
|
|
||||||
if (strstr(cFile, "libstagefright") != nullptr)
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NS_NAMED_LITERAL_CSTRING(dllSuffix, LOCAL_PLUGIN_DLL_SUFFIX);
|
NS_NAMED_LITERAL_CSTRING(dllSuffix, LOCAL_PLUGIN_DLL_SUFFIX);
|
||||||
if (filename.Length() > dllSuffix.Length() &&
|
if (filename.Length() > dllSuffix.Length() &&
|
||||||
StringEndsWith(filename, dllSuffix))
|
StringEndsWith(filename, dllSuffix))
|
||||||
|
|
|
@ -22,10 +22,6 @@ elif toolkit in ('gtk2', 'gtk3'):
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'nptest_gtk2.cpp',
|
'nptest_gtk2.cpp',
|
||||||
]
|
]
|
||||||
elif toolkit == 'android':
|
|
||||||
UNIFIED_SOURCES += [
|
|
||||||
'nptest_droid.cpp',
|
|
||||||
]
|
|
||||||
elif toolkit == 'windows':
|
elif toolkit == 'windows':
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'nptest_windows.cpp',
|
'nptest_windows.cpp',
|
||||||
|
|
|
@ -19,8 +19,6 @@ class nsACString;
|
||||||
class nsAString;
|
class nsAString;
|
||||||
class nsString;
|
class nsString;
|
||||||
class nsCString;
|
class nsCString;
|
||||||
class nsAdoptingString;
|
|
||||||
class nsAdoptingCString;
|
|
||||||
class nsXPIDLString;
|
class nsXPIDLString;
|
||||||
template<class T> class nsReadingIterator;
|
template<class T> class nsReadingIterator;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -133,10 +133,10 @@ SVGFilterElement::IsAttributeMapped(const nsIAtom* name) const
|
||||||
void
|
void
|
||||||
SVGFilterElement::Invalidate()
|
SVGFilterElement::Invalidate()
|
||||||
{
|
{
|
||||||
nsTObserverArray<nsIMutationObserver*> *observers = GetMutationObservers();
|
nsAutoTObserverArray<nsIMutationObserver*, 1> *observers = GetMutationObservers();
|
||||||
|
|
||||||
if (observers && !observers->IsEmpty()) {
|
if (observers && !observers->IsEmpty()) {
|
||||||
nsTObserverArray<nsIMutationObserver*>::ForwardIterator iter(*observers);
|
nsAutoTObserverArray<nsIMutationObserver*, 1>::ForwardIterator iter(*observers);
|
||||||
while (iter.HasMore()) {
|
while (iter.HasMore()) {
|
||||||
nsCOMPtr<nsIMutationObserver> obs(iter.GetNext());
|
nsCOMPtr<nsIMutationObserver> obs(iter.GetNext());
|
||||||
nsCOMPtr<nsISVGFilterReference> filter = do_QueryInterface(obs);
|
nsCOMPtr<nsISVGFilterReference> filter = do_QueryInterface(obs);
|
||||||
|
|
|
@ -128,7 +128,6 @@ using namespace widget;
|
||||||
|
|
||||||
EditorBase::EditorBase()
|
EditorBase::EditorBase()
|
||||||
: mPlaceholderName(nullptr)
|
: mPlaceholderName(nullptr)
|
||||||
, mSelState(nullptr)
|
|
||||||
, mModCount(0)
|
, mModCount(0)
|
||||||
, mFlags(0)
|
, mFlags(0)
|
||||||
, mUpdateCount(0)
|
, mUpdateCount(0)
|
||||||
|
@ -974,7 +973,7 @@ EditorBase::BeginPlaceHolderTransaction(nsIAtom* aName)
|
||||||
mPlaceholderName = aName;
|
mPlaceholderName = aName;
|
||||||
RefPtr<Selection> selection = GetSelection();
|
RefPtr<Selection> selection = GetSelection();
|
||||||
if (selection) {
|
if (selection) {
|
||||||
mSelState = MakeUnique<SelectionState>();
|
mSelState.emplace();
|
||||||
mSelState->SaveSelection(selection);
|
mSelState->SaveSelection(selection);
|
||||||
// Composition transaction can modify multiple nodes and it merges text
|
// Composition transaction can modify multiple nodes and it merges text
|
||||||
// node for ime into single text node.
|
// node for ime into single text node.
|
||||||
|
@ -1039,7 +1038,7 @@ EditorBase::EndPlaceHolderTransaction()
|
||||||
if (mPlaceholderName == nsGkAtoms::IMETxnName) {
|
if (mPlaceholderName == nsGkAtoms::IMETxnName) {
|
||||||
mRangeUpdater.DropSelectionState(*mSelState);
|
mRangeUpdater.DropSelectionState(*mSelState);
|
||||||
}
|
}
|
||||||
mSelState = nullptr;
|
mSelState.reset();
|
||||||
}
|
}
|
||||||
// We might have never made a placeholder if no action took place.
|
// We might have never made a placeholder if no action took place.
|
||||||
if (mPlaceholderTransaction) {
|
if (mPlaceholderTransaction) {
|
||||||
|
@ -2723,11 +2722,7 @@ nsresult
|
||||||
EditorBase::SetTextImpl(Selection& aSelection, const nsAString& aString,
|
EditorBase::SetTextImpl(Selection& aSelection, const nsAString& aString,
|
||||||
Text& aCharData)
|
Text& aCharData)
|
||||||
{
|
{
|
||||||
RefPtr<SetTextTransaction> transaction =
|
SetTextTransaction transaction(aCharData, aString, *this, &mRangeUpdater);
|
||||||
CreateTxnForSetText(aString, aCharData);
|
|
||||||
if (NS_WARN_IF(!transaction)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t length = aCharData.Length();
|
uint32_t length = aCharData.Length();
|
||||||
|
|
||||||
|
@ -2751,7 +2746,10 @@ EditorBase::SetTextImpl(Selection& aSelection, const nsAString& aString,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = DoTransaction(&aSelection, transaction);
|
// We don't support undo here, so we don't really need all of the transaction
|
||||||
|
// machinery, therefore we can run our transaction directly, breaking all of
|
||||||
|
// the rules!
|
||||||
|
nsresult rv = transaction.DoTransaction();
|
||||||
|
|
||||||
// Let listeners know what happened
|
// Let listeners know what happened
|
||||||
{
|
{
|
||||||
|
@ -2784,15 +2782,6 @@ EditorBase::CreateTxnForInsertText(const nsAString& aStringToInsert,
|
||||||
return transaction.forget();
|
return transaction.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<SetTextTransaction>
|
|
||||||
EditorBase::CreateTxnForSetText(const nsAString& aString,
|
|
||||||
Text& aTextNode)
|
|
||||||
{
|
|
||||||
RefPtr<SetTextTransaction> transaction =
|
|
||||||
new SetTextTransaction(aTextNode, aString, *this, &mRangeUpdater);
|
|
||||||
return transaction.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
EditorBase::DeleteText(nsGenericDOMDataNode& aCharData,
|
EditorBase::DeleteText(nsGenericDOMDataNode& aCharData,
|
||||||
uint32_t aOffset,
|
uint32_t aOffset,
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
#define mozilla_EditorBase_h
|
#define mozilla_EditorBase_h
|
||||||
|
|
||||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc.
|
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc.
|
||||||
|
#include "mozilla/Maybe.h" // for Maybe
|
||||||
#include "mozilla/OwningNonNull.h" // for OwningNonNull
|
#include "mozilla/OwningNonNull.h" // for OwningNonNull
|
||||||
#include "mozilla/SelectionState.h" // for RangeUpdater, etc.
|
#include "mozilla/SelectionState.h" // for RangeUpdater, etc.
|
||||||
#include "mozilla/StyleSheet.h" // for StyleSheet
|
#include "mozilla/StyleSheet.h" // for StyleSheet
|
||||||
#include "mozilla/UniquePtr.h"
|
|
||||||
#include "mozilla/WeakPtr.h" // for WeakPtr
|
#include "mozilla/WeakPtr.h" // for WeakPtr
|
||||||
#include "mozilla/dom/Text.h"
|
#include "mozilla/dom/Text.h"
|
||||||
#include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr
|
#include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr
|
||||||
|
@ -433,9 +433,6 @@ protected:
|
||||||
CreateTxnForInsertText(const nsAString& aStringToInsert, Text& aTextNode,
|
CreateTxnForInsertText(const nsAString& aStringToInsert, Text& aTextNode,
|
||||||
int32_t aOffset);
|
int32_t aOffset);
|
||||||
|
|
||||||
already_AddRefed<SetTextTransaction>
|
|
||||||
CreateTxnForSetText(const nsAString& aString, Text& aTextNode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Never returns null.
|
* Never returns null.
|
||||||
*/
|
*/
|
||||||
|
@ -1136,7 +1133,7 @@ protected:
|
||||||
// Name of placeholder transaction.
|
// Name of placeholder transaction.
|
||||||
nsIAtom* mPlaceholderName;
|
nsIAtom* mPlaceholderName;
|
||||||
// Saved selection state for placeholder transaction batching.
|
// Saved selection state for placeholder transaction batching.
|
||||||
mozilla::UniquePtr<SelectionState> mSelState;
|
mozilla::Maybe<SelectionState> mSelState;
|
||||||
// IME composition this is not null between compositionstart and
|
// IME composition this is not null between compositionstart and
|
||||||
// compositionend.
|
// compositionend.
|
||||||
RefPtr<TextComposition> mComposition;
|
RefPtr<TextComposition> mComposition;
|
||||||
|
|
|
@ -19,12 +19,12 @@ using namespace dom;
|
||||||
PlaceholderTransaction::PlaceholderTransaction(
|
PlaceholderTransaction::PlaceholderTransaction(
|
||||||
EditorBase& aEditorBase,
|
EditorBase& aEditorBase,
|
||||||
nsIAtom* aName,
|
nsIAtom* aName,
|
||||||
UniquePtr<SelectionState> aSelState)
|
Maybe<SelectionState>&& aSelState)
|
||||||
: mAbsorb(true)
|
: mAbsorb(true)
|
||||||
, mForwarding(nullptr)
|
, mForwarding(nullptr)
|
||||||
, mCompositionTransaction(nullptr)
|
, mCompositionTransaction(nullptr)
|
||||||
, mCommitted(false)
|
, mCommitted(false)
|
||||||
, mStartSel(Move(aSelState))
|
, mStartSel(Move(*aSelState))
|
||||||
, mEditorBase(&aEditorBase)
|
, mEditorBase(&aEditorBase)
|
||||||
{
|
{
|
||||||
mName = aName;
|
mName = aName;
|
||||||
|
@ -38,19 +38,15 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(PlaceholderTransaction)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PlaceholderTransaction,
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PlaceholderTransaction,
|
||||||
EditAggregateTransaction)
|
EditAggregateTransaction)
|
||||||
if (tmp->mStartSel) {
|
|
||||||
ImplCycleCollectionUnlink(*tmp->mStartSel);
|
|
||||||
}
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorBase);
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorBase);
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mStartSel);
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEndSel);
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEndSel);
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PlaceholderTransaction,
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PlaceholderTransaction,
|
||||||
EditAggregateTransaction)
|
EditAggregateTransaction)
|
||||||
if (tmp->mStartSel) {
|
|
||||||
ImplCycleCollectionTraverse(cb, *tmp->mStartSel, "mStartSel", 0);
|
|
||||||
}
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEditorBase);
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEditorBase);
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStartSel);
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEndSel);
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEndSel);
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
@ -78,12 +74,10 @@ PlaceholderTransaction::UndoTransaction()
|
||||||
nsresult rv = EditAggregateTransaction::UndoTransaction();
|
nsresult rv = EditAggregateTransaction::UndoTransaction();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
NS_ENSURE_TRUE(mStartSel, NS_ERROR_NULL_POINTER);
|
|
||||||
|
|
||||||
// now restore selection
|
// now restore selection
|
||||||
RefPtr<Selection> selection = mEditorBase->GetSelection();
|
RefPtr<Selection> selection = mEditorBase->GetSelection();
|
||||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||||
return mStartSel->RestoreSelection(selection);
|
return mStartSel.RestoreSelection(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -222,11 +216,11 @@ PlaceholderTransaction::StartSelectionEquals(SelectionState* aSelState,
|
||||||
// determine if starting selection matches the given selection state.
|
// determine if starting selection matches the given selection state.
|
||||||
// note that we only care about collapsed selections.
|
// note that we only care about collapsed selections.
|
||||||
NS_ENSURE_TRUE(aResult && aSelState, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(aResult && aSelState, NS_ERROR_NULL_POINTER);
|
||||||
if (!mStartSel->IsCollapsed() || !aSelState->IsCollapsed()) {
|
if (!mStartSel.IsCollapsed() || !aSelState->IsCollapsed()) {
|
||||||
*aResult = false;
|
*aResult = false;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
*aResult = mStartSel->IsEqual(aSelState);
|
*aResult = mStartSel.IsEqual(aSelState);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include "EditAggregateTransaction.h"
|
#include "EditAggregateTransaction.h"
|
||||||
#include "mozilla/EditorUtils.h"
|
#include "mozilla/EditorUtils.h"
|
||||||
#include "mozilla/UniquePtr.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "nsIAbsorbingTransaction.h"
|
#include "nsIAbsorbingTransaction.h"
|
||||||
#include "nsIDOMNode.h"
|
#include "nsIDOMNode.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
@ -33,7 +33,7 @@ public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
PlaceholderTransaction(EditorBase& aEditorBase, nsIAtom* aName,
|
PlaceholderTransaction(EditorBase& aEditorBase, nsIAtom* aName,
|
||||||
UniquePtr<SelectionState> aSelState);
|
Maybe<SelectionState>&& aSelState);
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PlaceholderTransaction,
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PlaceholderTransaction,
|
||||||
EditAggregateTransaction)
|
EditAggregateTransaction)
|
||||||
|
@ -81,8 +81,7 @@ protected:
|
||||||
// at the end. This is so that UndoTransaction() and RedoTransaction() can
|
// at the end. This is so that UndoTransaction() and RedoTransaction() can
|
||||||
// restore the selection properly.
|
// restore the selection properly.
|
||||||
|
|
||||||
// Use a pointer because this is constructed before we exist.
|
SelectionState mStartSel;
|
||||||
UniquePtr<SelectionState> mStartSel;
|
|
||||||
SelectionState mEndSel;
|
SelectionState mEndSel;
|
||||||
|
|
||||||
// The editor for this transaction.
|
// The editor for this transaction.
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "nsAString.h" // nsAString parameter
|
#include "nsAString.h" // nsAString parameter
|
||||||
#include "nsDebug.h" // for NS_ASSERTION, etc.
|
#include "nsDebug.h" // for NS_ASSERTION, etc.
|
||||||
#include "nsError.h" // for NS_OK, etc.
|
#include "nsError.h" // for NS_OK, etc.
|
||||||
#include "nsQueryObject.h" // for do_QueryObject
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
@ -31,24 +30,7 @@ SetTextTransaction::SetTextTransaction(Text& aTextNode,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SetTextTransaction::~SetTextTransaction()
|
nsresult
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(SetTextTransaction, EditTransactionBase,
|
|
||||||
mEditorBase,
|
|
||||||
mTextNode)
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(SetTextTransaction, EditTransactionBase)
|
|
||||||
NS_IMPL_RELEASE_INHERITED(SetTextTransaction, EditTransactionBase)
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SetTextTransaction)
|
|
||||||
if (aIID.Equals(NS_GET_IID(SetTextTransaction))) {
|
|
||||||
foundInterface = static_cast<nsITransaction*>(this);
|
|
||||||
} else
|
|
||||||
NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
SetTextTransaction::DoTransaction()
|
SetTextTransaction::DoTransaction()
|
||||||
{
|
{
|
||||||
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) {
|
if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) {
|
||||||
|
@ -82,28 +64,4 @@ SetTextTransaction::DoTransaction()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
SetTextTransaction::UndoTransaction()
|
|
||||||
{
|
|
||||||
return mTextNode->SetData(mPreviousData);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
SetTextTransaction::Merge(nsITransaction* aTransaction,
|
|
||||||
bool* aDidMerge)
|
|
||||||
{
|
|
||||||
// Set out param default value
|
|
||||||
*aDidMerge = false;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
SetTextTransaction::GetTxnDescription(nsAString& aString)
|
|
||||||
{
|
|
||||||
aString.AssignLiteral("SetTextTransaction: ");
|
|
||||||
aString += mStringToSet;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -7,19 +7,10 @@
|
||||||
#ifndef mozilla_SetTextTransaction_h
|
#ifndef mozilla_SetTextTransaction_h
|
||||||
#define mozilla_SetTextTransaction_h
|
#define mozilla_SetTextTransaction_h
|
||||||
|
|
||||||
#include "mozilla/EditTransactionBase.h" // base class
|
#include "mozilla/Attributes.h" // for MOZ_STACK_CLASS
|
||||||
#include "nsCycleCollectionParticipant.h" // various macros
|
|
||||||
#include "nsID.h" // NS_DECLARE_STATIC_IID_ACCESSOR
|
|
||||||
#include "nsISupportsImpl.h" // NS_DECL_ISUPPORTS_INHERITED
|
|
||||||
#include "nsString.h" // nsString members
|
#include "nsString.h" // nsString members
|
||||||
#include "nscore.h" // NS_IMETHOD, nsAString
|
#include "nscore.h" // NS_IMETHOD, nsAString
|
||||||
|
|
||||||
class nsITransaction;
|
|
||||||
|
|
||||||
#define NS_SETTEXTTXN_IID \
|
|
||||||
{ 0x568bac0b, 0xa42a, 0x4150, \
|
|
||||||
{ 0xbd, 0x90, 0x34, 0xd0, 0x2f, 0x32, 0x74, 0x2e } }
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class EditorBase;
|
class EditorBase;
|
||||||
|
@ -30,13 +21,13 @@ class Text;
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A transaction that inserts text into a content node.
|
* A fake transaction that inserts text into a content node.
|
||||||
|
*
|
||||||
|
* This class mimics a transaction class but it is not intended to be used as one.
|
||||||
*/
|
*/
|
||||||
class SetTextTransaction final : public EditTransactionBase
|
class MOZ_STACK_CLASS SetTextTransaction final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_SETTEXTTXN_IID)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param aTextNode The text content node.
|
* @param aTextNode The text content node.
|
||||||
* @param aString The new text to insert.
|
* @param aString The new text to insert.
|
||||||
|
@ -47,17 +38,9 @@ public:
|
||||||
const nsAString& aString, EditorBase& aEditorBase,
|
const nsAString& aString, EditorBase& aEditorBase,
|
||||||
RangeUpdater* aRangeUpdater);
|
RangeUpdater* aRangeUpdater);
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
nsresult DoTransaction();
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SetTextTransaction,
|
|
||||||
EditTransactionBase)
|
|
||||||
|
|
||||||
NS_DECL_EDITTRANSACTIONBASE
|
|
||||||
|
|
||||||
NS_IMETHOD Merge(nsITransaction* aTransaction, bool* aDidMerge) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ~SetTextTransaction();
|
|
||||||
|
|
||||||
// The Text node to operate upon.
|
// The Text node to operate upon.
|
||||||
RefPtr<dom::Text> mTextNode;
|
RefPtr<dom::Text> mTextNode;
|
||||||
|
|
||||||
|
@ -68,13 +51,11 @@ private:
|
||||||
nsString mPreviousData;
|
nsString mPreviousData;
|
||||||
|
|
||||||
// The editor, which we'll need to get the selection.
|
// The editor, which we'll need to get the selection.
|
||||||
RefPtr<EditorBase> mEditorBase;
|
EditorBase* MOZ_NON_OWNING_REF mEditorBase;
|
||||||
|
|
||||||
RangeUpdater* mRangeUpdater;
|
RangeUpdater* mRangeUpdater;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(SetTextTransaction, NS_SETTEXTTXN_IID)
|
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // #ifndef mozilla_SetTextTransaction_h
|
#endif // #ifndef mozilla_SetTextTransaction_h
|
||||||
|
|
|
@ -421,10 +421,22 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container->UseIntermediateSurface()) {
|
if (container->UseIntermediateSurface()) {
|
||||||
IntRect bounds = invalidateWholeLayer
|
Maybe<IntRect> bounds;
|
||||||
? mLayer->GetLocalVisibleRegion().ToUnknownRegion().GetBounds()
|
|
||||||
: result.GetBounds();
|
if (!invalidateWholeLayer) {
|
||||||
container->SetInvalidCompositeRect(bounds);
|
bounds = Some(result.GetBounds());
|
||||||
|
|
||||||
|
// Process changes in the visible region.
|
||||||
|
IntRegion newVisible = mLayer->GetLocalVisibleRegion().ToUnknownRegion();
|
||||||
|
if (!newVisible.IsEqual(mVisibleRegion)) {
|
||||||
|
newVisible.XorWith(mVisibleRegion);
|
||||||
|
bounds = bounds->SafeUnion(newVisible.GetBounds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bounds) {
|
||||||
|
bounds = Some(mLayer->GetLocalVisibleRegion().GetBounds().ToUnknownRect());
|
||||||
|
}
|
||||||
|
container->SetInvalidCompositeRect(bounds.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mLayer->Extend3DContext()) {
|
if (!mLayer->Extend3DContext()) {
|
||||||
|
|
|
@ -70,6 +70,12 @@ ClientPaintedLayer::CanRecordLayer(ReadbackProcessor* aReadback)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Component alpha layers aren't supported yet since we have to
|
||||||
|
// hold onto both the front/back buffer of a texture client.
|
||||||
|
if (GetSurfaceMode() == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return GetAncestorMaskLayerCount() == 0;
|
return GetAncestorMaskLayerCount() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "mozilla/layers/LayerMLGPU.h"
|
#include "mozilla/layers/LayerMLGPU.h"
|
||||||
#include "mozilla/layers/MemoryReportingMLGPU.h"
|
#include "mozilla/layers/MemoryReportingMLGPU.h"
|
||||||
#include "mozilla/layers/ShaderDefinitionsMLGPU.h"
|
#include "mozilla/layers/ShaderDefinitionsMLGPU.h"
|
||||||
|
#include "mozilla/layers/UtilityMLGPU.h"
|
||||||
#include "mozilla/widget/CompositorWidget.h"
|
#include "mozilla/widget/CompositorWidget.h"
|
||||||
#include "mozilla/widget/WinCompositorWidget.h"
|
#include "mozilla/widget/WinCompositorWidget.h"
|
||||||
#include "MLGShaders.h"
|
#include "MLGShaders.h"
|
||||||
|
|
|
@ -13,7 +13,7 @@ cbuffer VSBufSimple : register(b0)
|
||||||
float4x4 WorldTransform;
|
float4x4 WorldTransform;
|
||||||
float2 RenderTargetOffset;
|
float2 RenderTargetOffset;
|
||||||
int SortIndexOffset;
|
int SortIndexOffset;
|
||||||
float padding;
|
uint DebugFrameNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Layer {
|
struct Layer {
|
||||||
|
|
|
@ -19,8 +19,9 @@ namespace layers {
|
||||||
using namespace gfx;
|
using namespace gfx;
|
||||||
|
|
||||||
ContainerLayerMLGPU::ContainerLayerMLGPU(LayerManagerMLGPU* aManager)
|
ContainerLayerMLGPU::ContainerLayerMLGPU(LayerManagerMLGPU* aManager)
|
||||||
: ContainerLayer(aManager, nullptr)
|
: ContainerLayer(aManager, nullptr),
|
||||||
, LayerMLGPU(aManager)
|
LayerMLGPU(aManager),
|
||||||
|
mInvalidateEntireSurface(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +36,9 @@ bool
|
||||||
ContainerLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder)
|
ContainerLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder)
|
||||||
{
|
{
|
||||||
if (!UseIntermediateSurface()) {
|
if (!UseIntermediateSurface()) {
|
||||||
|
// Set this so we invalidate the entire cached render target (if any)
|
||||||
|
// if our container uses an intermediate surface again later.
|
||||||
|
mInvalidateEntireSurface = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,13 +68,19 @@ ContainerLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder)
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::IntRect viewport(gfx::IntPoint(0, 0), mTargetSize);
|
gfx::IntRect viewport(gfx::IntPoint(0, 0), mTargetSize);
|
||||||
if (!mRenderTarget || !gfxPrefs::AdvancedLayersUseInvalidation()) {
|
if (!mRenderTarget ||
|
||||||
|
!gfxPrefs::AdvancedLayersUseInvalidation() ||
|
||||||
|
mInvalidateEntireSurface)
|
||||||
|
{
|
||||||
// Fine-grained invalidation is disabled, invalidate everything.
|
// Fine-grained invalidation is disabled, invalidate everything.
|
||||||
mInvalidRect = viewport;
|
mInvalidRect = viewport;
|
||||||
} else {
|
} else {
|
||||||
// Clamp the invalid rect to the viewport.
|
// Clamp the invalid rect to the viewport.
|
||||||
|
mInvalidRect -= mTargetOffset;
|
||||||
mInvalidRect = mInvalidRect.Intersect(viewport);
|
mInvalidRect = mInvalidRect.Intersect(viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mInvalidateEntireSurface = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,16 +193,16 @@ void
|
||||||
ContainerLayerMLGPU::SetInvalidCompositeRect(const gfx::IntRect& aRect)
|
ContainerLayerMLGPU::SetInvalidCompositeRect(const gfx::IntRect& aRect)
|
||||||
{
|
{
|
||||||
// For simplicity we only track the bounds of the invalid area, since regions
|
// For simplicity we only track the bounds of the invalid area, since regions
|
||||||
// are expensive. We can adjust this in the future if needed.
|
// are expensive.
|
||||||
gfx::IntRect bounds = aRect;
|
//
|
||||||
bounds.MoveBy(-GetTargetOffset());
|
|
||||||
|
|
||||||
// Note we add the bounds to the invalid rect from the last frame, since we
|
// Note we add the bounds to the invalid rect from the last frame, since we
|
||||||
// only clear the area that we actually paint.
|
// only clear the area that we actually paint. If this overflows we use the
|
||||||
if (Maybe<gfx::IntRect> result = mInvalidRect.SafeUnion(bounds)) {
|
// last render target size, since if that changes we'll invalidate everything
|
||||||
|
// anyway.
|
||||||
|
if (Maybe<gfx::IntRect> result = mInvalidRect.SafeUnion(aRect)) {
|
||||||
mInvalidRect = result.value();
|
mInvalidRect = result.value();
|
||||||
} else {
|
} else {
|
||||||
mInvalidRect = gfx::IntRect(gfx::IntPoint(0, 0), GetTargetSize());
|
mInvalidateEntireSurface = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,8 +67,10 @@ private:
|
||||||
gfx::IntSize mTargetSize;
|
gfx::IntSize mTargetSize;
|
||||||
|
|
||||||
// The region of the container that needs to be recomposited if visible. We
|
// The region of the container that needs to be recomposited if visible. We
|
||||||
// store this as a rectangle instead of an nsIntRegion for efficiency.
|
// store this as a rectangle instead of an nsIntRegion for efficiency. This
|
||||||
|
// is in layer coordinates.
|
||||||
gfx::IntRect mInvalidRect;
|
gfx::IntRect mInvalidRect;
|
||||||
|
bool mInvalidateEntireSurface;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
|
|
|
@ -162,6 +162,7 @@ FrameBuilder::ProcessContainerLayer(ContainerLayer* aContainer,
|
||||||
gfx::IntRect boundingBox = layer->GetClippedBoundingBox(aView, Nothing());
|
gfx::IntRect boundingBox = layer->GetClippedBoundingBox(aView, Nothing());
|
||||||
const gfx::IntRect& invalidRect = aView->GetInvalidRect();
|
const gfx::IntRect& invalidRect = aView->GetInvalidRect();
|
||||||
if (boundingBox.IsEmpty() || !invalidRect.Intersects(boundingBox)) {
|
if (boundingBox.IsEmpty() || !invalidRect.Intersects(boundingBox)) {
|
||||||
|
AL_LOG("Culling ContainerLayer %p that does not need painting\n", aContainer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,8 @@ LayerManagerMLGPU::LayerManagerMLGPU(widget::CompositorWidget* aWidget)
|
||||||
: mWidget(aWidget),
|
: mWidget(aWidget),
|
||||||
mDrawDiagnostics(false),
|
mDrawDiagnostics(false),
|
||||||
mUsingInvalidation(false),
|
mUsingInvalidation(false),
|
||||||
mCurrentFrame(nullptr)
|
mCurrentFrame(nullptr),
|
||||||
|
mDebugFrameNumber(0)
|
||||||
{
|
{
|
||||||
if (!aWidget) {
|
if (!aWidget) {
|
||||||
return;
|
return;
|
||||||
|
@ -266,6 +267,9 @@ LayerManagerMLGPU::EndTransaction(const TimeStamp& aTimeStamp, EndTransactionFla
|
||||||
// Don't draw the diagnostic overlay if we want to snapshot the output.
|
// Don't draw the diagnostic overlay if we want to snapshot the output.
|
||||||
mDrawDiagnostics = gfxPrefs::LayersDrawFPS() && !mTarget;
|
mDrawDiagnostics = gfxPrefs::LayersDrawFPS() && !mTarget;
|
||||||
mUsingInvalidation = gfxPrefs::AdvancedLayersUseInvalidation();
|
mUsingInvalidation = gfxPrefs::AdvancedLayersUseInvalidation();
|
||||||
|
mDebugFrameNumber++;
|
||||||
|
|
||||||
|
AL_LOG("--- Compositing frame %d ---\n", mDebugFrameNumber);
|
||||||
|
|
||||||
// Compute transforms - and the changed area, if enabled.
|
// Compute transforms - and the changed area, if enabled.
|
||||||
mRoot->ComputeEffectiveTransforms(Matrix4x4());
|
mRoot->ComputeEffectiveTransforms(Matrix4x4());
|
||||||
|
|
|
@ -96,6 +96,9 @@ public:
|
||||||
const nsIntRegion& GetRegionToClear() const {
|
const nsIntRegion& GetRegionToClear() const {
|
||||||
return mRegionToClear;
|
return mRegionToClear;
|
||||||
}
|
}
|
||||||
|
uint32_t GetDebugFrameNumber() const {
|
||||||
|
return mDebugFrameNumber;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Composite();
|
void Composite();
|
||||||
|
@ -130,6 +133,10 @@ private:
|
||||||
gfx::IntRect mTargetRect;
|
gfx::IntRect mTargetRect;
|
||||||
FrameBuilder* mCurrentFrame;
|
FrameBuilder* mCurrentFrame;
|
||||||
|
|
||||||
|
// The debug frame number is incremented every frame and is included in the
|
||||||
|
// WorldConstants bound to vertex shaders. This allows us to correlate
|
||||||
|
// a frame in RenderDoc to spew in the console.
|
||||||
|
uint32_t mDebugFrameNumber;
|
||||||
RefPtr<MLGBuffer> mDiagnosticVertices;
|
RefPtr<MLGBuffer> mDiagnosticVertices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -354,5 +354,42 @@ MLGDevice::DrawClearRegion(const ClearRegionHelper& aHelper)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MLGDevice::WriteAsPNG(MLGTexture* aTexture, const char* aPath)
|
||||||
|
{
|
||||||
|
MLGMappedResource map;
|
||||||
|
if (!Map(aTexture, MLGMapType::READ, &map)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<DataSourceSurface> surface = Factory::CreateWrappingDataSourceSurface(
|
||||||
|
map.mData,
|
||||||
|
map.mStride,
|
||||||
|
aTexture->GetSize(),
|
||||||
|
SurfaceFormat::B8G8R8A8);
|
||||||
|
gfxUtils::WriteAsPNG(surface, aPath);
|
||||||
|
|
||||||
|
Unmap(aTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<MLGTexture>
|
||||||
|
MLGDevice::CopyAndCreateReadbackTexture(MLGTexture* aTexture)
|
||||||
|
{
|
||||||
|
RefPtr<MLGTexture> copy = CreateTexture(
|
||||||
|
aTexture->GetSize(),
|
||||||
|
SurfaceFormat::B8G8R8A8,
|
||||||
|
MLGUsage::Staging,
|
||||||
|
MLGTextureFlags::None);
|
||||||
|
if (!copy) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
CopyTexture(
|
||||||
|
copy,
|
||||||
|
IntPoint(0, 0),
|
||||||
|
aTexture,
|
||||||
|
IntRect(IntPoint(0, 0), aTexture->GetSize()));
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -430,6 +430,12 @@ public:
|
||||||
SetPSTexture(aSlot, nullTexture);
|
SetPSTexture(aSlot, nullTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debugging helper function for dumping an MLGTexture to a file.
|
||||||
|
void WriteAsPNG(MLGTexture* aTexture, const char* aPath);
|
||||||
|
|
||||||
|
// Debugging helper function for copying a texture for later dumping to a file.
|
||||||
|
RefPtr<MLGTexture> CopyAndCreateReadbackTexture(MLGTexture* aTexture);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~MLGDevice();
|
virtual ~MLGDevice();
|
||||||
|
|
||||||
|
|
|
@ -358,6 +358,7 @@ RenderViewMLGPU::Prepare()
|
||||||
memcpy(vsConstants.projection, &projection._11, 64);
|
memcpy(vsConstants.projection, &projection._11, 64);
|
||||||
vsConstants.targetOffset = Point(mTargetOffset);
|
vsConstants.targetOffset = Point(mTargetOffset);
|
||||||
vsConstants.sortIndexOffset = PrepareDepthBuffer();
|
vsConstants.sortIndexOffset = PrepareDepthBuffer();
|
||||||
|
vsConstants.debugFrameNumber = mBuilder->GetManager()->GetDebugFrameNumber();
|
||||||
|
|
||||||
SharedConstantBuffer* shared = mDevice->GetSharedVSBuffer();
|
SharedConstantBuffer* shared = mDevice->GetSharedVSBuffer();
|
||||||
if (!shared->Allocate(&mWorldConstants, vsConstants)) {
|
if (!shared->Allocate(&mWorldConstants, vsConstants)) {
|
||||||
|
|
|
@ -52,7 +52,7 @@ struct WorldConstants
|
||||||
float projection[4][4];
|
float projection[4][4];
|
||||||
gfx::Point targetOffset;
|
gfx::Point targetOffset;
|
||||||
int sortIndexOffset;
|
int sortIndexOffset;
|
||||||
float padding;
|
unsigned debugFrameNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClearConstants
|
struct ClearConstants
|
||||||
|
|
|
@ -130,6 +130,11 @@ DeviceManagerDx::CreateCompositorDevices()
|
||||||
FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
|
FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
|
||||||
MOZ_ASSERT(d3d11.IsEnabled());
|
MOZ_ASSERT(d3d11.IsEnabled());
|
||||||
|
|
||||||
|
if (int32_t sleepSec = gfxPrefs::Direct3D11SleepOnCreateDevice()) {
|
||||||
|
printf_stderr("Attach to PID: %d\n", GetCurrentProcessId());
|
||||||
|
Sleep(sleepSec * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
if (!LoadD3D11()) {
|
if (!LoadD3D11()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ std::string gfxPrefs::PrefGet(const char* aPref, std::string aDefault)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(IsPrefsServiceAvailable());
|
MOZ_ASSERT(IsPrefsServiceAvailable());
|
||||||
|
|
||||||
nsAdoptingCString result;
|
nsAutoCString result;
|
||||||
Preferences::GetCString(aPref, result);
|
Preferences::GetCString(aPref, result);
|
||||||
|
|
||||||
if (result.IsEmpty()) {
|
if (result.IsEmpty()) {
|
||||||
|
|
|
@ -441,6 +441,7 @@ private:
|
||||||
DECL_GFX_PREF(Live, "gfx.direct3d11.use-double-buffering", Direct3D11UseDoubleBuffering, bool, false);
|
DECL_GFX_PREF(Live, "gfx.direct3d11.use-double-buffering", Direct3D11UseDoubleBuffering, bool, false);
|
||||||
DECL_GFX_PREF(Once, "gfx.direct3d11.enable-debug-layer", Direct3D11EnableDebugLayer, bool, false);
|
DECL_GFX_PREF(Once, "gfx.direct3d11.enable-debug-layer", Direct3D11EnableDebugLayer, bool, false);
|
||||||
DECL_GFX_PREF(Once, "gfx.direct3d11.break-on-error", Direct3D11BreakOnError, bool, false);
|
DECL_GFX_PREF(Once, "gfx.direct3d11.break-on-error", Direct3D11BreakOnError, bool, false);
|
||||||
|
DECL_GFX_PREF(Once, "gfx.direct3d11.sleep-on-create-device", Direct3D11SleepOnCreateDevice, int32_t, 0);
|
||||||
DECL_GFX_PREF(Live, "gfx.downloadable_fonts.keep_variation_tables", KeepVariationTables, bool, false);
|
DECL_GFX_PREF(Live, "gfx.downloadable_fonts.keep_variation_tables", KeepVariationTables, bool, false);
|
||||||
DECL_GFX_PREF(Live, "gfx.downloadable_fonts.otl_validation", ValidateOTLTables, bool, true);
|
DECL_GFX_PREF(Live, "gfx.downloadable_fonts.otl_validation", ValidateOTLTables, bool, true);
|
||||||
DECL_GFX_PREF(Live, "gfx.draw-color-bars", CompositorDrawColorBars, bool, false);
|
DECL_GFX_PREF(Live, "gfx.draw-color-bars", CompositorDrawColorBars, bool, false);
|
||||||
|
|
|
@ -152,7 +152,7 @@ NS_IMETHODIMP nsTextToSubURI::UnEscapeURIForUI(const nsACString & aCharset,
|
||||||
|
|
||||||
// If there are any characters that are unsafe for URIs, reescape those.
|
// If there are any characters that are unsafe for URIs, reescape those.
|
||||||
if (mUnsafeChars.IsEmpty()) {
|
if (mUnsafeChars.IsEmpty()) {
|
||||||
nsAdoptingString blacklist;
|
nsAutoString blacklist;
|
||||||
nsresult rv = mozilla::Preferences::GetString("network.IDN.blacklist_chars",
|
nsresult rv = mozilla::Preferences::GetString("network.IDN.blacklist_chars",
|
||||||
blacklist);
|
blacklist);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
|
|
@ -1772,7 +1772,9 @@ class HashTable : private AllocPolicy
|
||||||
if (!EnsureHash<HashPolicy>(l))
|
if (!EnsureHash<HashPolicy>(l))
|
||||||
return AddPtr();
|
return AddPtr();
|
||||||
HashNumber keyHash = prepareHash(l);
|
HashNumber keyHash = prepareHash(l);
|
||||||
return AddPtr(lookup(l, keyHash, sCollisionBit), *this, keyHash);
|
Entry& entry = lookup(l, keyHash, sCollisionBit);
|
||||||
|
AddPtr p(entry, *this, keyHash);
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
|
|
|
@ -80,11 +80,6 @@ using mozilla::DefaultXDisplay;
|
||||||
#include <winuser.h>
|
#include <winuser.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
#include "AndroidBridge.h"
|
|
||||||
#include "GLContext.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mozilla/dom/TabChild.h"
|
#include "mozilla/dom/TabChild.h"
|
||||||
|
|
||||||
#ifdef CreateEvent // Thank you MS.
|
#ifdef CreateEvent // Thank you MS.
|
||||||
|
@ -938,55 +933,6 @@ nsDisplayPluginReadback::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
|
||||||
return GetDisplayItemBounds(aBuilder, this, mFrame);
|
return GetDisplayItemBounds(aBuilder, this, mFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
|
|
||||||
class nsDisplayPluginVideo : public nsDisplayItem {
|
|
||||||
public:
|
|
||||||
nsDisplayPluginVideo(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsNPAPIPluginInstance::VideoInfo* aVideoInfo)
|
|
||||||
: nsDisplayItem(aBuilder, aFrame), mVideoInfo(aVideoInfo)
|
|
||||||
{
|
|
||||||
MOZ_COUNT_CTOR(nsDisplayPluginVideo);
|
|
||||||
}
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
virtual ~nsDisplayPluginVideo() {
|
|
||||||
MOZ_COUNT_DTOR(nsDisplayPluginVideo);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
|
|
||||||
bool* aSnap) override;
|
|
||||||
|
|
||||||
NS_DISPLAY_DECL_NAME("PluginVideo", TYPE_PLUGIN_VIDEO)
|
|
||||||
|
|
||||||
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
|
|
||||||
LayerManager* aManager,
|
|
||||||
const ContainerLayerParameters& aContainerParameters) override
|
|
||||||
{
|
|
||||||
return static_cast<nsPluginFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
|
||||||
LayerManager* aManager,
|
|
||||||
const ContainerLayerParameters& aParameters) override
|
|
||||||
{
|
|
||||||
return LAYER_ACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsNPAPIPluginInstance::VideoInfo* VideoInfo() { return mVideoInfo; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsNPAPIPluginInstance::VideoInfo* mVideoInfo;
|
|
||||||
};
|
|
||||||
|
|
||||||
nsRect
|
|
||||||
nsDisplayPluginVideo::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
|
|
||||||
{
|
|
||||||
*aSnap = false;
|
|
||||||
return GetDisplayItemBounds(aBuilder, this, mFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsRect
|
nsRect
|
||||||
nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
|
nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
|
||||||
{
|
{
|
||||||
|
@ -1136,9 +1082,6 @@ nsPluginFrame::IsOpaque() const
|
||||||
{
|
{
|
||||||
#if defined(XP_MACOSX)
|
#if defined(XP_MACOSX)
|
||||||
return false;
|
return false;
|
||||||
#elif defined(MOZ_WIDGET_ANDROID)
|
|
||||||
// We don't know, so just assume transparent
|
|
||||||
return false;
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (mInstanceOwner && mInstanceOwner->UseAsyncRendering()) {
|
if (mInstanceOwner && mInstanceOwner->UseAsyncRendering()) {
|
||||||
|
@ -1238,29 +1181,12 @@ nsPluginFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
nsDisplayItem::ForceActiveLayers()) {
|
nsDisplayItem::ForceActiveLayers()) {
|
||||||
state = LAYER_ACTIVE;
|
state = LAYER_ACTIVE;
|
||||||
}
|
}
|
||||||
// We don't need this on Android, and it just confuses things
|
|
||||||
#if !MOZ_WIDGET_ANDROID
|
|
||||||
if (aBuilder->IsPaintingToWindow() &&
|
if (aBuilder->IsPaintingToWindow() &&
|
||||||
state == LAYER_ACTIVE &&
|
state == LAYER_ACTIVE &&
|
||||||
IsTransparentMode()) {
|
IsTransparentMode()) {
|
||||||
aLists.Content()->AppendNewToTop(new (aBuilder)
|
aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||||
nsDisplayPluginReadback(aBuilder, this));
|
nsDisplayPluginReadback(aBuilder, this));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MOZ_WIDGET_ANDROID
|
|
||||||
if (aBuilder->IsPaintingToWindow() &&
|
|
||||||
state == LAYER_ACTIVE) {
|
|
||||||
|
|
||||||
nsTArray<nsNPAPIPluginInstance::VideoInfo*> videos;
|
|
||||||
mInstanceOwner->GetVideos(videos);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < videos.Length(); i++) {
|
|
||||||
aLists.Content()->AppendNewToTop(new (aBuilder)
|
|
||||||
nsDisplayPluginVideo(aBuilder, this, videos[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
aLists.Content()->AppendNewToTop(new (aBuilder)
|
aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||||
nsDisplayPlugin(aBuilder, this));
|
nsDisplayPlugin(aBuilder, this));
|
||||||
|
@ -1396,10 +1322,6 @@ nsPluginFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
if (!mInstanceOwner)
|
if (!mInstanceOwner)
|
||||||
return LAYER_NONE;
|
return LAYER_NONE;
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
// We always want a layer on Honeycomb and later
|
|
||||||
return LAYER_ACTIVE;
|
|
||||||
#else
|
|
||||||
if (mInstanceOwner->NeedsScrollImageLayer()) {
|
if (mInstanceOwner->NeedsScrollImageLayer()) {
|
||||||
return LAYER_ACTIVE;
|
return LAYER_ACTIVE;
|
||||||
}
|
}
|
||||||
|
@ -1409,7 +1331,6 @@ nsPluginFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
}
|
}
|
||||||
|
|
||||||
return LAYER_ACTIVE_FORCE;
|
return LAYER_ACTIVE_FORCE;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PluginFrameDidCompositeObserver final : public DidCompositeObserver
|
class PluginFrameDidCompositeObserver final : public DidCompositeObserver
|
||||||
|
@ -1526,32 +1447,6 @@ nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||||
}
|
}
|
||||||
lm->AddDidCompositeObserver(mDidCompositeObserver.get());
|
lm->AddDidCompositeObserver(mDidCompositeObserver.get());
|
||||||
}
|
}
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
|
||||||
} else if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_VIDEO) {
|
|
||||||
nsDisplayPluginVideo* videoItem = reinterpret_cast<nsDisplayPluginVideo*>(aItem);
|
|
||||||
nsNPAPIPluginInstance::VideoInfo* videoInfo = videoItem->VideoInfo();
|
|
||||||
|
|
||||||
RefPtr<ImageContainer> container = mInstanceOwner->GetImageContainerForVideo(videoInfo);
|
|
||||||
if (!container)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (!layer) {
|
|
||||||
// Initialize ImageLayer
|
|
||||||
layer = aManager->CreateImageLayer();
|
|
||||||
if (!layer)
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageLayer* imglayer = static_cast<ImageLayer*>(layer.get());
|
|
||||||
imglayer->SetContainer(container);
|
|
||||||
|
|
||||||
layer->SetContentFlags(IsOpaque() ? Layer::CONTENT_OPAQUE : 0);
|
|
||||||
|
|
||||||
// Set the offset and size according to the video dimensions
|
|
||||||
r.MoveBy(videoInfo->mDimensions.TopLeft());
|
|
||||||
size.width = videoInfo->mDimensions.width;
|
|
||||||
size.height = videoInfo->mDimensions.height;
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
NS_ASSERTION(aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_READBACK,
|
NS_ASSERTION(aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_READBACK,
|
||||||
"Unknown item type");
|
"Unknown item type");
|
||||||
|
@ -1600,18 +1495,7 @@ nsPluginFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
|
||||||
gfxContext& aRenderingContext,
|
gfxContext& aRenderingContext,
|
||||||
const nsRect& aDirtyRect, const nsRect& aPluginRect)
|
const nsRect& aDirtyRect, const nsRect& aPluginRect)
|
||||||
{
|
{
|
||||||
#if defined(MOZ_WIDGET_ANDROID)
|
#if defined(DEBUG)
|
||||||
if (mInstanceOwner) {
|
|
||||||
gfxRect frameGfxRect =
|
|
||||||
PresContext()->AppUnitsToGfxUnits(aPluginRect);
|
|
||||||
gfxRect dirtyGfxRect =
|
|
||||||
PresContext()->AppUnitsToGfxUnits(aDirtyRect);
|
|
||||||
|
|
||||||
mInstanceOwner->Paint(&aRenderingContext, frameGfxRect, dirtyGfxRect);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
# if defined(DEBUG)
|
|
||||||
// On Desktop, we should have built a layer as we no longer support in-process
|
// On Desktop, we should have built a layer as we no longer support in-process
|
||||||
// plugins or synchronous painting. We can only get here for windowed plugins
|
// plugins or synchronous painting. We can only get here for windowed plugins
|
||||||
// (which draw themselves), or via some error/unload state.
|
// (which draw themselves), or via some error/unload state.
|
||||||
|
@ -1620,7 +1504,6 @@ nsPluginFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
|
||||||
mInstanceOwner->GetWindow(window);
|
mInstanceOwner->GetWindow(window);
|
||||||
MOZ_ASSERT(!window || window->type == NPWindowTypeWindow);
|
MOZ_ASSERT(!window || window->type == NPWindowTypeWindow);
|
||||||
}
|
}
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4104,7 +4104,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||||
if (itemClip.HasClip()) {
|
if (itemClip.HasClip()) {
|
||||||
itemContent.IntersectRect(itemContent, itemClip.GetClipRect());
|
itemContent.IntersectRect(itemContent, itemClip.GetClipRect());
|
||||||
clipRect = ViewAs<ParentLayerPixel>(ScaleToNearestPixels(itemClip.GetClipRect()));
|
clipRect = ViewAs<ParentLayerPixel>(ScaleToNearestPixels(itemClip.GetClipRect()));
|
||||||
if (!prerenderedTransform) {
|
if (!prerenderedTransform && !IsScrollThumbLayer(item)) {
|
||||||
itemDrawRect.IntersectRect(itemDrawRect, clipRect.ToUnknownRect());
|
itemDrawRect.IntersectRect(itemDrawRect, clipRect.ToUnknownRect());
|
||||||
}
|
}
|
||||||
clipRect.MoveBy(ViewAs<ParentLayerPixel>(mParameters.mOffset));
|
clipRect.MoveBy(ViewAs<ParentLayerPixel>(mParameters.mOffset));
|
||||||
|
|
|
@ -457,6 +457,9 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
|
||||||
// Restore the saved clip so it applies to the thumb container layer.
|
// Restore the saved clip so it applies to the thumb container layer.
|
||||||
thumbContentsClipState.Restore();
|
thumbContentsClipState.Restore();
|
||||||
|
|
||||||
|
nsDisplayListBuilder::AutoBuildingDisplayList
|
||||||
|
buildingDisplayList(aBuilder, this, dirty, false);
|
||||||
|
|
||||||
// Wrap the list to make it its own layer.
|
// Wrap the list to make it its own layer.
|
||||||
const ActiveScrolledRoot* ownLayerASR = contASRTracker.GetContainerASR();
|
const ActiveScrolledRoot* ownLayerASR = contASRTracker.GetContainerASR();
|
||||||
aLists.Content()->AppendNewToTop(new (aBuilder)
|
aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||||
|
|
|
@ -447,15 +447,9 @@ pref("browser.ui.scroll-toolbar-threshold", 10);
|
||||||
pref("browser.ui.selection.distance", 250);
|
pref("browser.ui.selection.distance", 250);
|
||||||
|
|
||||||
// plugins
|
// plugins
|
||||||
pref("plugin.disable", false);
|
pref("plugin.disable", true);
|
||||||
pref("dom.ipc.plugins.enabled", false);
|
pref("dom.ipc.plugins.enabled", false);
|
||||||
|
|
||||||
// This pref isn't actually used anymore, but we're leaving this here to avoid changing
|
|
||||||
// the default so that we can migrate a user-set pref. See bug 885357.
|
|
||||||
pref("plugins.click_to_play", true);
|
|
||||||
// The default value for nsIPluginTag.enabledState (STATE_CLICKTOPLAY = 1)
|
|
||||||
pref("plugin.default.state", 1);
|
|
||||||
|
|
||||||
// product URLs
|
// product URLs
|
||||||
// The breakpad report server to link to in about:crashes
|
// The breakpad report server to link to in about:crashes
|
||||||
pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/");
|
pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/");
|
||||||
|
|
|
@ -31,11 +31,6 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:scrollbars="none"/>
|
android:scrollbars="none"/>
|
||||||
|
|
||||||
<AbsoluteLayout android:id="@+id/plugin_container"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"/>
|
|
||||||
|
|
||||||
<org.mozilla.gecko.FormAssistPopup android:id="@+id/form_assist_popup"
|
<org.mozilla.gecko.FormAssistPopup android:id="@+id/form_assist_popup"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
|
@ -13,16 +13,6 @@
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="pref_plugins_entries">
|
|
||||||
<item>@string/pref_plugins_enabled</item>
|
|
||||||
<item>@string/pref_plugins_tap_to_play</item>
|
|
||||||
<item>@string/pref_plugins_disabled</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="pref_plugins_values">
|
|
||||||
<item>1</item>
|
|
||||||
<item>2</item>
|
|
||||||
<item>0</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="pref_char_encoding_entries">
|
<string-array name="pref_char_encoding_entries">
|
||||||
<item>@string/pref_char_encoding_on</item>
|
<item>@string/pref_char_encoding_on</item>
|
||||||
<item>@string/pref_char_encoding_off</item>
|
<item>@string/pref_char_encoding_off</item>
|
||||||
|
|
|
@ -54,12 +54,6 @@
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/pref_category_media">
|
<PreferenceCategory android:title="@string/pref_category_media">
|
||||||
|
|
||||||
<ListPreference android:key="plugin.enable"
|
|
||||||
android:title="@string/pref_plugins"
|
|
||||||
android:entries="@array/pref_plugins_entries"
|
|
||||||
android:entryValues="@array/pref_plugins_values"
|
|
||||||
android:persistent="false" />
|
|
||||||
|
|
||||||
<SwitchPreference android:key="media.autoplay.enabled"
|
<SwitchPreference android:key="media.autoplay.enabled"
|
||||||
android:title="@string/pref_media_autoplay_enabled"
|
android:title="@string/pref_media_autoplay_enabled"
|
||||||
android:summary="@string/pref_media_autoplay_enabled_summary" />
|
android:summary="@string/pref_media_autoplay_enabled_summary" />
|
||||||
|
|
|
@ -194,9 +194,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||||
|
|
||||||
protected GeckoView mLayerView;
|
protected GeckoView mLayerView;
|
||||||
|
|
||||||
private FullScreenHolder mFullScreenPluginContainer;
|
|
||||||
private View mFullScreenPluginView;
|
|
||||||
|
|
||||||
protected boolean mLastSessionCrashed;
|
protected boolean mLastSessionCrashed;
|
||||||
protected boolean mShouldRestore;
|
protected boolean mShouldRestore;
|
||||||
private boolean mSessionRestoreParsingFinished = false;
|
private boolean mSessionRestoreParsingFinished = false;
|
||||||
|
@ -809,11 +806,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||||
} else if ("Update:Install".equals(event)) {
|
} else if ("Update:Install".equals(event)) {
|
||||||
UpdateServiceHelper.applyUpdate(this);
|
UpdateServiceHelper.applyUpdate(this);
|
||||||
|
|
||||||
} else if ("PluginHelper:playFlash".equals(event)) {
|
|
||||||
final SharedPreferences prefs = getSharedPreferences();
|
|
||||||
int count = prefs.getInt(PREFS_FLASH_USAGE, 0);
|
|
||||||
prefs.edit().putInt(PREFS_FLASH_USAGE, ++count).apply();
|
|
||||||
|
|
||||||
} else if ("Mma:reader_available".equals(event)) {
|
} else if ("Mma:reader_available".equals(event)) {
|
||||||
MmaDelegate.track(READER_AVAILABLE);
|
MmaDelegate.track(READER_AVAILABLE);
|
||||||
|
|
||||||
|
@ -917,113 +909,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ void addFullScreenPluginView(View view) {
|
|
||||||
if (mFullScreenPluginView != null) {
|
|
||||||
Log.w(LOGTAG, "Already have a fullscreen plugin view");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setFullScreen(true);
|
|
||||||
|
|
||||||
view.setWillNotDraw(false);
|
|
||||||
if (view instanceof SurfaceView) {
|
|
||||||
((SurfaceView) view).setZOrderOnTop(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
mFullScreenPluginContainer = new FullScreenHolder(this);
|
|
||||||
|
|
||||||
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
Gravity.CENTER);
|
|
||||||
mFullScreenPluginContainer.addView(view, layoutParams);
|
|
||||||
|
|
||||||
|
|
||||||
FrameLayout decor = (FrameLayout)getWindow().getDecorView();
|
|
||||||
decor.addView(mFullScreenPluginContainer, layoutParams);
|
|
||||||
|
|
||||||
mFullScreenPluginView = view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@WrapForJNI(calledFrom = "gecko")
|
|
||||||
private static void addPluginView(final View view) {
|
|
||||||
final Activity activity = GeckoActivityMonitor.getInstance().getCurrentActivity();
|
|
||||||
if (!(activity instanceof GeckoApp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final GeckoApp geckoApp = (GeckoApp) activity;
|
|
||||||
if (ThreadUtils.isOnUiThread()) {
|
|
||||||
geckoApp.addFullScreenPluginView(view);
|
|
||||||
} else {
|
|
||||||
ThreadUtils.postToUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
geckoApp.addFullScreenPluginView(view);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* package */ void removeFullScreenPluginView(View view) {
|
|
||||||
if (mFullScreenPluginView == null) {
|
|
||||||
Log.w(LOGTAG, "Don't have a fullscreen plugin view");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mFullScreenPluginView != view) {
|
|
||||||
Log.w(LOGTAG, "Passed view is not the current full screen view");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mFullScreenPluginContainer.removeView(mFullScreenPluginView);
|
|
||||||
|
|
||||||
// We need do do this on the next iteration in order to avoid
|
|
||||||
// a deadlock, see comment below in FullScreenHolder
|
|
||||||
ThreadUtils.postToUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mLayerView.showSurface();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
FrameLayout decor = (FrameLayout)getWindow().getDecorView();
|
|
||||||
decor.removeView(mFullScreenPluginContainer);
|
|
||||||
|
|
||||||
mFullScreenPluginView = null;
|
|
||||||
|
|
||||||
GeckoScreenOrientation.getInstance().unlock();
|
|
||||||
setFullScreen(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@WrapForJNI(calledFrom = "gecko")
|
|
||||||
private static void removePluginView(final View view) {
|
|
||||||
final Activity activity = GeckoActivityMonitor.getInstance().getCurrentActivity();
|
|
||||||
if (!(activity instanceof GeckoApp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final GeckoApp geckoApp = (GeckoApp) activity;
|
|
||||||
if (ThreadUtils.isOnUiThread()) {
|
|
||||||
geckoApp.removeFullScreenPluginView(view);
|
|
||||||
} else {
|
|
||||||
ThreadUtils.postToUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
geckoApp.removeFullScreenPluginView(view);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@WrapForJNI(calledFrom = "ui", dispatchTo = "gecko")
|
|
||||||
private static native void onFullScreenPluginHidden(View view);
|
|
||||||
|
|
||||||
@WrapForJNI(calledFrom = "gecko")
|
|
||||||
private static Context getPluginContext() {
|
|
||||||
return GeckoActivityMonitor.getInstance().getCurrentActivity();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showSetImageResult(final boolean success, final int message, final String path) {
|
private void showSetImageResult(final boolean success, final int message, final String path) {
|
||||||
ThreadUtils.postToUiThread(new Runnable() {
|
ThreadUtils.postToUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -1303,7 +1188,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||||
EventDispatcher.getInstance().registerGeckoThreadListener(this,
|
EventDispatcher.getInstance().registerGeckoThreadListener(this,
|
||||||
"Accessibility:Ready",
|
"Accessibility:Ready",
|
||||||
"Gecko:Ready",
|
"Gecko:Ready",
|
||||||
"PluginHelper:playFlash",
|
|
||||||
null);
|
null);
|
||||||
|
|
||||||
EventDispatcher.getInstance().registerUiThreadListener(this,
|
EventDispatcher.getInstance().registerUiThreadListener(this,
|
||||||
|
@ -2330,7 +2214,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||||
EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
|
EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
|
||||||
"Accessibility:Ready",
|
"Accessibility:Ready",
|
||||||
"Gecko:Ready",
|
"Gecko:Ready",
|
||||||
"PluginHelper:playFlash",
|
|
||||||
null);
|
null);
|
||||||
|
|
||||||
EventDispatcher.getInstance().unregisterUiThreadListener(this,
|
EventDispatcher.getInstance().unregisterUiThreadListener(this,
|
||||||
|
@ -2545,12 +2428,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFullScreenPluginView != null) {
|
|
||||||
onFullScreenPluginHidden(mFullScreenPluginView);
|
|
||||||
removeFullScreenPluginView(mFullScreenPluginView);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mLayerView != null && mLayerView.isFullScreen()) {
|
if (mLayerView != null && mLayerView.isFullScreen()) {
|
||||||
EventDispatcher.getInstance().dispatch("FullScreen:Exit", null);
|
EventDispatcher.getInstance().dispatch("FullScreen:Exit", null);
|
||||||
return;
|
return;
|
||||||
|
@ -2683,71 +2560,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FullScreenHolder extends FrameLayout {
|
|
||||||
|
|
||||||
public FullScreenHolder(Context ctx) {
|
|
||||||
super(ctx);
|
|
||||||
setBackgroundColor(0xff000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addView(View view, int index) {
|
|
||||||
/**
|
|
||||||
* This normally gets called when Flash adds a separate SurfaceView
|
|
||||||
* for the video. It is unhappy if we have the LayerView underneath
|
|
||||||
* it for some reason so we need to hide that. Hiding the LayerView causes
|
|
||||||
* its surface to be destroyed, which causes a pause composition
|
|
||||||
* event to be sent to Gecko. We synchronously wait for that to be
|
|
||||||
* processed. Simultaneously, however, Flash is waiting on a mutex so
|
|
||||||
* the post() below is an attempt to avoid a deadlock.
|
|
||||||
*/
|
|
||||||
super.addView(view, index);
|
|
||||||
|
|
||||||
ThreadUtils.postToUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mLayerView.hideSurface();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The methods below are simply copied from what Android WebKit does.
|
|
||||||
* It wasn't ever called in my testing, but might as well
|
|
||||||
* keep it in case it is for some reason. The methods
|
|
||||||
* all return true because we don't want any events
|
|
||||||
* leaking out from the fullscreen view.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
||||||
if (event.isSystem()) {
|
|
||||||
return super.onKeyDown(keyCode, event);
|
|
||||||
}
|
|
||||||
mFullScreenPluginView.onKeyDown(keyCode, event);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
|
||||||
if (event.isSystem()) {
|
|
||||||
return super.onKeyUp(keyCode, event);
|
|
||||||
}
|
|
||||||
mFullScreenPluginView.onKeyUp(keyCode, event);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTrackballEvent(MotionEvent event) {
|
|
||||||
mFullScreenPluginView.onTrackballEvent(event);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getVersionCode() {
|
private int getVersionCode() {
|
||||||
int versionCode = 0;
|
int versionCode = 0;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -69,7 +69,6 @@ public class Tab {
|
||||||
private int mFaviconLoadId;
|
private int mFaviconLoadId;
|
||||||
private String mContentType;
|
private String mContentType;
|
||||||
private boolean mHasTouchListeners;
|
private boolean mHasTouchListeners;
|
||||||
private final ArrayList<View> mPluginViews;
|
|
||||||
private int mState;
|
private int mState;
|
||||||
private Bitmap mThumbnailBitmap;
|
private Bitmap mThumbnailBitmap;
|
||||||
private boolean mDesktopMode;
|
private boolean mDesktopMode;
|
||||||
|
@ -129,7 +128,6 @@ public class Tab {
|
||||||
mTitle = title == null ? "" : title;
|
mTitle = title == null ? "" : title;
|
||||||
mSiteIdentity = new SiteIdentity();
|
mSiteIdentity = new SiteIdentity();
|
||||||
mContentType = "";
|
mContentType = "";
|
||||||
mPluginViews = new ArrayList<View>();
|
|
||||||
mState = shouldShowProgress(url) ? STATE_LOADING : STATE_SUCCESS;
|
mState = shouldShowProgress(url) ? STATE_LOADING : STATE_SUCCESS;
|
||||||
mLoadProgress = LOAD_PROGRESS_INIT;
|
mLoadProgress = LOAD_PROGRESS_INIT;
|
||||||
mIconRequestBuilder = Icons.with(mAppContext).pageUrl(mUrl);
|
mIconRequestBuilder = Icons.with(mAppContext).pageUrl(mUrl);
|
||||||
|
@ -736,18 +734,6 @@ public class Tab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPluginView(View view) {
|
|
||||||
mPluginViews.add(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removePluginView(View view) {
|
|
||||||
mPluginViews.remove(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
public View[] getPluginViews() {
|
|
||||||
return mPluginViews.toArray(new View[mPluginViews.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDesktopMode(boolean enabled) {
|
public void setDesktopMode(boolean enabled) {
|
||||||
mDesktopMode = enabled;
|
mDesktopMode = enabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,10 +361,6 @@
|
||||||
<!ENTITY pref_clear_on_exit_title3 "Clear private data on exit">
|
<!ENTITY pref_clear_on_exit_title3 "Clear private data on exit">
|
||||||
<!ENTITY pref_clear_on_exit_summary2 "&brandShortName; will automatically clear your data whenever you select \u0022Quit\u0022 from the main menu">
|
<!ENTITY pref_clear_on_exit_summary2 "&brandShortName; will automatically clear your data whenever you select \u0022Quit\u0022 from the main menu">
|
||||||
<!ENTITY pref_clear_on_exit_dialog_title "Select which data to clear">
|
<!ENTITY pref_clear_on_exit_dialog_title "Select which data to clear">
|
||||||
<!ENTITY pref_plugins "Plugins">
|
|
||||||
<!ENTITY pref_plugins_enabled "Enabled">
|
|
||||||
<!ENTITY pref_plugins_tap_to_play2 "Touch to play">
|
|
||||||
<!ENTITY pref_plugins_disabled "Disabled">
|
|
||||||
<!ENTITY pref_restore_tabs "Restore tabs">
|
<!ENTITY pref_restore_tabs "Restore tabs">
|
||||||
<!ENTITY pref_restore_always "Always restore">
|
<!ENTITY pref_restore_always "Always restore">
|
||||||
<!ENTITY pref_restore_quit "Don\'t restore after quitting &brandShortName;">
|
<!ENTITY pref_restore_quit "Don\'t restore after quitting &brandShortName;">
|
||||||
|
|
|
@ -261,10 +261,6 @@
|
||||||
<string name="pref_clear_on_exit_title">&pref_clear_on_exit_title3;</string>
|
<string name="pref_clear_on_exit_title">&pref_clear_on_exit_title3;</string>
|
||||||
<string name="pref_clear_on_exit_summary2">&pref_clear_on_exit_summary2;</string>
|
<string name="pref_clear_on_exit_summary2">&pref_clear_on_exit_summary2;</string>
|
||||||
<string name="pref_clear_on_exit_dialog_title">&pref_clear_on_exit_dialog_title;</string>
|
<string name="pref_clear_on_exit_dialog_title">&pref_clear_on_exit_dialog_title;</string>
|
||||||
<string name="pref_plugins">&pref_plugins;</string>
|
|
||||||
<string name="pref_plugins_enabled">&pref_plugins_enabled;</string>
|
|
||||||
<string name="pref_plugins_tap_to_play">&pref_plugins_tap_to_play2;</string>
|
|
||||||
<string name="pref_plugins_disabled">&pref_plugins_disabled;</string>
|
|
||||||
<string name="pref_use_system_font_size">&pref_use_system_font_size;</string>
|
<string name="pref_use_system_font_size">&pref_use_system_font_size;</string>
|
||||||
<string name="pref_use_system_font_size_summary">&pref_use_system_font_size_summary;</string>
|
<string name="pref_use_system_font_size_summary">&pref_use_system_font_size_summary;</string>
|
||||||
<string name="pref_media_autoplay_enabled">&pref_media_autoplay_enabled;</string>
|
<string name="pref_media_autoplay_enabled">&pref_media_autoplay_enabled;</string>
|
||||||
|
|
|
@ -129,7 +129,6 @@ var WindowEventDispatcher = EventDispatcher.for(window);
|
||||||
|
|
||||||
var lazilyLoadedBrowserScripts = [
|
var lazilyLoadedBrowserScripts = [
|
||||||
["MasterPassword", "chrome://browser/content/MasterPassword.js"],
|
["MasterPassword", "chrome://browser/content/MasterPassword.js"],
|
||||||
["PluginHelper", "chrome://browser/content/PluginHelper.js"],
|
|
||||||
["OfflineApps", "chrome://browser/content/OfflineApps.js"],
|
["OfflineApps", "chrome://browser/content/OfflineApps.js"],
|
||||||
["Linkifier", "chrome://browser/content/Linkify.js"],
|
["Linkifier", "chrome://browser/content/Linkify.js"],
|
||||||
["CastingApps", "chrome://browser/content/CastingApps.js"],
|
["CastingApps", "chrome://browser/content/CastingApps.js"],
|
||||||
|
@ -1014,13 +1013,6 @@ var BrowserApp = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentUIVersion < 1) {
|
if (currentUIVersion < 1) {
|
||||||
// Migrate user-set "plugins.click_to_play" pref. See bug 884694.
|
|
||||||
// Because the default value is true, a user-set pref means that the pref was set to false.
|
|
||||||
if (Services.prefs.prefHasUserValue("plugins.click_to_play")) {
|
|
||||||
Services.prefs.setIntPref("plugin.default.state", Ci.nsIPluginTag.STATE_ENABLED);
|
|
||||||
Services.prefs.clearUserPref("plugins.click_to_play");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Migrate the "privacy.donottrackheader.value" pref. See bug 1042135.
|
// Migrate the "privacy.donottrackheader.value" pref. See bug 1042135.
|
||||||
if (Services.prefs.prefHasUserValue("privacy.donottrackheader.value")) {
|
if (Services.prefs.prefHasUserValue("privacy.donottrackheader.value")) {
|
||||||
// Make sure the doNotTrack value conforms to the conversion from
|
// Make sure the doNotTrack value conforms to the conversion from
|
||||||
|
@ -1955,12 +1947,6 @@ var BrowserApp = {
|
||||||
aSubject.QueryInterface(Ci.nsIWritableVariant);
|
aSubject.QueryInterface(Ci.nsIWritableVariant);
|
||||||
|
|
||||||
switch (aData) {
|
switch (aData) {
|
||||||
// The plugin pref is actually two separate prefs, so
|
|
||||||
// we need to handle it differently
|
|
||||||
case "plugin.enable":
|
|
||||||
aSubject.setAsAString(PluginHelper.getPluginPreference());
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Handle master password
|
// Handle master password
|
||||||
case "privacy.masterpassword.enabled":
|
case "privacy.masterpassword.enabled":
|
||||||
aSubject.setAsBool(MasterPassword.enabled);
|
aSubject.setAsBool(MasterPassword.enabled);
|
||||||
|
@ -1991,13 +1977,6 @@ var BrowserApp = {
|
||||||
let value = aSubject.QueryInterface(Ci.nsIVariant);
|
let value = aSubject.QueryInterface(Ci.nsIVariant);
|
||||||
|
|
||||||
switch (aData) {
|
switch (aData) {
|
||||||
// The plugin pref is actually two separate prefs, so we need to
|
|
||||||
// handle it differently.
|
|
||||||
case "plugin.enable":
|
|
||||||
PluginHelper.setPluginPreference(value);
|
|
||||||
aSubject.setAsEmpty();
|
|
||||||
break;
|
|
||||||
|
|
||||||
// MasterPassword pref is not real, we just need take action and leave
|
// MasterPassword pref is not real, we just need take action and leave
|
||||||
case "privacy.masterpassword.enabled":
|
case "privacy.masterpassword.enabled":
|
||||||
if (MasterPassword.enabled) {
|
if (MasterPassword.enabled) {
|
||||||
|
@ -3473,9 +3452,6 @@ function Tab(aURL, aParams) {
|
||||||
this._parentId = -1;
|
this._parentId = -1;
|
||||||
this.lastTouchedAt = Date.now();
|
this.lastTouchedAt = Date.now();
|
||||||
this.contentDocumentIsDisplayed = true;
|
this.contentDocumentIsDisplayed = true;
|
||||||
this.pluginDoorhangerTimeout = null;
|
|
||||||
this.shouldShowPluginDoorhanger = true;
|
|
||||||
this.clickToPlayPluginsActivated = false;
|
|
||||||
this.desktopMode = false;
|
this.desktopMode = false;
|
||||||
this.originalURI = null;
|
this.originalURI = null;
|
||||||
this.hasTouchListener = false;
|
this.hasTouchListener = false;
|
||||||
|
@ -3643,7 +3619,6 @@ Tab.prototype = {
|
||||||
this.browser.addEventListener("DOMWindowFocus", this, true);
|
this.browser.addEventListener("DOMWindowFocus", this, true);
|
||||||
|
|
||||||
// Note that the XBL binding is untrusted
|
// Note that the XBL binding is untrusted
|
||||||
this.browser.addEventListener("PluginBindingAttached", this, true, true);
|
|
||||||
this.browser.addEventListener("VideoBindingAttached", this, true, true);
|
this.browser.addEventListener("VideoBindingAttached", this, true, true);
|
||||||
this.browser.addEventListener("VideoBindingCast", this, true, true);
|
this.browser.addEventListener("VideoBindingCast", this, true, true);
|
||||||
|
|
||||||
|
@ -3758,7 +3733,6 @@ Tab.prototype = {
|
||||||
this.browser.removeEventListener("TabPreZombify", this, true);
|
this.browser.removeEventListener("TabPreZombify", this, true);
|
||||||
this.browser.removeEventListener("DOMWindowFocus", this, true);
|
this.browser.removeEventListener("DOMWindowFocus", this, true);
|
||||||
|
|
||||||
this.browser.removeEventListener("PluginBindingAttached", this, true, true);
|
|
||||||
this.browser.removeEventListener("VideoBindingAttached", this, true, true);
|
this.browser.removeEventListener("VideoBindingAttached", this, true, true);
|
||||||
this.browser.removeEventListener("VideoBindingCast", this, true, true);
|
this.browser.removeEventListener("VideoBindingCast", this, true, true);
|
||||||
|
|
||||||
|
@ -4271,11 +4245,6 @@ Tab.prototype = {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "PluginBindingAttached": {
|
|
||||||
PluginHelper.handlePluginBindingAttached(this, aEvent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "VideoBindingAttached": {
|
case "VideoBindingAttached": {
|
||||||
CastingApps.handleVideoBindingAttached(this, aEvent);
|
CastingApps.handleVideoBindingAttached(this, aEvent);
|
||||||
break;
|
break;
|
||||||
|
@ -4454,12 +4423,6 @@ Tab.prototype = {
|
||||||
this.browser.messageManager.sendAsyncMessage("Reader:PushState", {isArticle: this.browser.isArticle});
|
this.browser.messageManager.sendAsyncMessage("Reader:PushState", {isArticle: this.browser.isArticle});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset state of click-to-play plugin notifications.
|
|
||||||
clearTimeout(this.pluginDoorhangerTimeout);
|
|
||||||
this.pluginDoorhangerTimeout = null;
|
|
||||||
this.shouldShowPluginDoorhanger = true;
|
|
||||||
this.clickToPlayPluginsActivated = false;
|
|
||||||
|
|
||||||
let baseDomain = "";
|
let baseDomain = "";
|
||||||
// For recognized scheme, get base domain from host.
|
// For recognized scheme, get base domain from host.
|
||||||
let principalURI = contentWin.document.nodePrincipal.URI;
|
let principalURI = contentWin.document.nodePrincipal.URI;
|
||||||
|
@ -5919,7 +5882,7 @@ var IdentityHandler = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We also allow "about:" by allowing the selector to be empty (i.e. '(|.....|...|...)'
|
// We also allow "about:" by allowing the selector to be empty (i.e. '(|.....|...|...)'
|
||||||
let whitelist = /^about:($|about|accounts|addons|buildconfig|cache|config|crashes|devices|downloads|fennec|firefox|feedback|healthreport|home|license|logins|logo|memory|mozilla|networking|plugins|privatebrowsing|rights|serviceworkers|support|telemetry|webrtc)($|\?)/i;
|
let whitelist = /^about:($|about|accounts|addons|buildconfig|cache|config|crashes|devices|downloads|fennec|firefox|feedback|healthreport|home|license|logins|logo|memory|mozilla|networking|privatebrowsing|rights|serviceworkers|support|telemetry|webrtc)($|\?)/i;
|
||||||
if (uri.schemeIs("about") && whitelist.test(uri.spec)) {
|
if (uri.schemeIs("about") && whitelist.test(uri.spec)) {
|
||||||
return this.IDENTITY_MODE_CHROMEUI;
|
return this.IDENTITY_MODE_CHROMEUI;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,8 @@ PromptService.prototype = {
|
||||||
this.inputWidgetHelper = this.loadSubscript(
|
this.inputWidgetHelper = this.loadSubscript(
|
||||||
"InputWidgetHelper", "chrome://browser/content/InputWidgetHelper.js");
|
"InputWidgetHelper", "chrome://browser/content/InputWidgetHelper.js");
|
||||||
}
|
}
|
||||||
win.addEventListener("click", this.selectHelper); // non-capture
|
win.addEventListener("click", this.selectHelper, /* capture */ true);
|
||||||
win.addEventListener("click", this.inputWidgetHelper); // non-capture
|
win.addEventListener("click", this.inputWidgetHelper, /* capture */ true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1407,229 +1407,6 @@ public class GeckoAppShell
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A plugin that wish to be loaded in the WebView must provide this permission
|
|
||||||
* in their AndroidManifest.xml.
|
|
||||||
*/
|
|
||||||
public static final String PLUGIN_ACTION = "android.webkit.PLUGIN";
|
|
||||||
public static final String PLUGIN_PERMISSION = "android.webkit.permission.PLUGIN";
|
|
||||||
|
|
||||||
private static final String PLUGIN_SYSTEM_LIB = "/system/lib/plugins/";
|
|
||||||
|
|
||||||
private static final String PLUGIN_TYPE = "type";
|
|
||||||
private static final String TYPE_NATIVE = "native";
|
|
||||||
public static final ArrayList<PackageInfo> mPackageInfoCache = new ArrayList<>();
|
|
||||||
|
|
||||||
// Returns null if plugins are blocked on the device.
|
|
||||||
static String[] getPluginDirectories() {
|
|
||||||
|
|
||||||
// Block on Pixel C.
|
|
||||||
if ((new File("/system/lib/hw/power.dragon.so")).exists()) {
|
|
||||||
Log.w(LOGTAG, "Blocking plugins because of Pixel C device (bug 1255122)");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// An awful hack to detect Tegra devices. Easiest way to do it without spinning up a EGL context.
|
|
||||||
boolean isTegra = (new File("/system/lib/hw/gralloc.tegra.so")).exists() ||
|
|
||||||
(new File("/system/lib/hw/gralloc.tegra3.so")).exists() ||
|
|
||||||
(new File("/sys/class/nvidia-gpu")).exists();
|
|
||||||
if (isTegra) {
|
|
||||||
// disable on KitKat (bug 957694)
|
|
||||||
if (Build.VERSION.SDK_INT >= 19) {
|
|
||||||
Log.w(LOGTAG, "Blocking plugins because of Tegra (bug 957694)");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// disable Flash on Tegra ICS with CM9 and other custom firmware (bug 736421)
|
|
||||||
final File vfile = new File("/proc/version");
|
|
||||||
try {
|
|
||||||
if (vfile.canRead()) {
|
|
||||||
final BufferedReader reader = new BufferedReader(new FileReader(vfile));
|
|
||||||
try {
|
|
||||||
final String version = reader.readLine();
|
|
||||||
if (version.indexOf("CM9") != -1 ||
|
|
||||||
version.indexOf("cyanogen") != -1 ||
|
|
||||||
version.indexOf("Nova") != -1) {
|
|
||||||
Log.w(LOGTAG, "Blocking plugins because of Tegra 2 + unofficial ICS bug (bug 736421)");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
reader.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<String> directories = new ArrayList<String>();
|
|
||||||
PackageManager pm = getApplicationContext().getPackageManager();
|
|
||||||
List<ResolveInfo> plugins = pm.queryIntentServices(new Intent(PLUGIN_ACTION),
|
|
||||||
PackageManager.GET_META_DATA);
|
|
||||||
|
|
||||||
synchronized (mPackageInfoCache) {
|
|
||||||
|
|
||||||
// clear the list of existing packageInfo objects
|
|
||||||
mPackageInfoCache.clear();
|
|
||||||
|
|
||||||
|
|
||||||
for (ResolveInfo info : plugins) {
|
|
||||||
|
|
||||||
// retrieve the plugin's service information
|
|
||||||
ServiceInfo serviceInfo = info.serviceInfo;
|
|
||||||
if (serviceInfo == null) {
|
|
||||||
Log.w(LOGTAG, "Ignoring bad plugin.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blacklist HTC's flash lite.
|
|
||||||
// See bug #704516 - We're not quite sure what Flash Lite does,
|
|
||||||
// but loading it causes Flash to give errors and fail to draw.
|
|
||||||
if (serviceInfo.packageName.equals("com.htc.flashliteplugin")) {
|
|
||||||
Log.w(LOGTAG, "Skipping HTC's flash lite plugin");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Retrieve information from the plugin's manifest.
|
|
||||||
PackageInfo pkgInfo;
|
|
||||||
try {
|
|
||||||
pkgInfo = pm.getPackageInfo(serviceInfo.packageName,
|
|
||||||
PackageManager.GET_PERMISSIONS
|
|
||||||
| PackageManager.GET_SIGNATURES);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.w(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pkgInfo == null) {
|
|
||||||
Log.w(LOGTAG, "Not loading plugin: " + serviceInfo.packageName + ". Could not load package information.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* find the location of the plugin's shared library. The default
|
|
||||||
* is to assume the app is either a user installed app or an
|
|
||||||
* updated system app. In both of these cases the library is
|
|
||||||
* stored in the app's data directory.
|
|
||||||
*/
|
|
||||||
String directory = pkgInfo.applicationInfo.dataDir + "/lib";
|
|
||||||
final int appFlags = pkgInfo.applicationInfo.flags;
|
|
||||||
final int updatedSystemFlags = ApplicationInfo.FLAG_SYSTEM |
|
|
||||||
ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
|
|
||||||
|
|
||||||
// preloaded system app with no user updates
|
|
||||||
if ((appFlags & updatedSystemFlags) == ApplicationInfo.FLAG_SYSTEM) {
|
|
||||||
directory = PLUGIN_SYSTEM_LIB + pkgInfo.packageName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the plugin has the required permissions
|
|
||||||
String permissions[] = pkgInfo.requestedPermissions;
|
|
||||||
if (permissions == null) {
|
|
||||||
Log.w(LOGTAG, "Not loading plugin: " + serviceInfo.packageName + ". Does not have required permission.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
boolean permissionOk = false;
|
|
||||||
for (String permit : permissions) {
|
|
||||||
if (PLUGIN_PERMISSION.equals(permit)) {
|
|
||||||
permissionOk = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!permissionOk) {
|
|
||||||
Log.w(LOGTAG, "Not loading plugin: " + serviceInfo.packageName + ". Does not have required permission (2).");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check to ensure the plugin is properly signed
|
|
||||||
Signature signatures[] = pkgInfo.signatures;
|
|
||||||
if (signatures == null) {
|
|
||||||
Log.w(LOGTAG, "Not loading plugin: " + serviceInfo.packageName + ". Not signed.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine the type of plugin from the manifest
|
|
||||||
if (serviceInfo.metaData == null) {
|
|
||||||
Log.e(LOGTAG, "The plugin '" + serviceInfo.name + "' has no defined type.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String pluginType = serviceInfo.metaData.getString(PLUGIN_TYPE);
|
|
||||||
if (!TYPE_NATIVE.equals(pluginType)) {
|
|
||||||
Log.e(LOGTAG, "Unrecognized plugin type: " + pluginType);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class<?> cls = getPluginClass(serviceInfo.packageName, serviceInfo.name);
|
|
||||||
|
|
||||||
//TODO implement any requirements of the plugin class here!
|
|
||||||
boolean classFound = true;
|
|
||||||
|
|
||||||
if (!classFound) {
|
|
||||||
Log.e(LOGTAG, "The plugin's class' " + serviceInfo.name + "' does not extend the appropriate class.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (NameNotFoundException e) {
|
|
||||||
Log.e(LOGTAG, "Can't find plugin: " + serviceInfo.packageName);
|
|
||||||
continue;
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
Log.e(LOGTAG, "Can't find plugin's class: " + serviceInfo.name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if all checks have passed then make the plugin available
|
|
||||||
mPackageInfoCache.add(pkgInfo);
|
|
||||||
directories.add(directory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return directories.toArray(new String[directories.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String getPluginPackage(String pluginLib) {
|
|
||||||
|
|
||||||
if (pluginLib == null || pluginLib.length() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mPackageInfoCache) {
|
|
||||||
for (PackageInfo pkgInfo : mPackageInfoCache) {
|
|
||||||
if (pluginLib.contains(pkgInfo.packageName)) {
|
|
||||||
return pkgInfo.packageName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Class<?> getPluginClass(String packageName, String className)
|
|
||||||
throws NameNotFoundException, ClassNotFoundException {
|
|
||||||
Context pluginContext = getApplicationContext().createPackageContext(packageName,
|
|
||||||
Context.CONTEXT_INCLUDE_CODE |
|
|
||||||
Context.CONTEXT_IGNORE_SECURITY);
|
|
||||||
ClassLoader pluginCL = pluginContext.getClassLoader();
|
|
||||||
return pluginCL.loadClass(className);
|
|
||||||
}
|
|
||||||
|
|
||||||
@WrapForJNI
|
|
||||||
private static Class<?> loadPluginClass(String className, String libName) {
|
|
||||||
try {
|
|
||||||
final String packageName = getPluginPackage(libName);
|
|
||||||
final int contextFlags = Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY;
|
|
||||||
final Context pluginContext = getApplicationContext().createPackageContext(
|
|
||||||
packageName, contextFlags);
|
|
||||||
return pluginContext.getClassLoader().loadClass(className);
|
|
||||||
} catch (java.lang.ClassNotFoundException cnfe) {
|
|
||||||
Log.w(LOGTAG, "Couldn't find plugin class " + className, cnfe);
|
|
||||||
return null;
|
|
||||||
} catch (android.content.pm.PackageManager.NameNotFoundException nnfe) {
|
|
||||||
Log.w(LOGTAG, "Couldn't find package.", nnfe);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Context sApplicationContext;
|
private static Context sApplicationContext;
|
||||||
|
|
||||||
@WrapForJNI
|
@WrapForJNI
|
||||||
|
|
|
@ -259,15 +259,8 @@ public class GeckoThread extends Thread {
|
||||||
res.updateConfiguration(config, null);
|
res.updateConfiguration(config, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] pluginDirs = null;
|
|
||||||
try {
|
|
||||||
pluginDirs = GeckoAppShell.getPluginDirectories();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.w(LOGTAG, "Caught exception getting plugin dirs.", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
final String resourcePath = context.getPackageResourcePath();
|
final String resourcePath = context.getPackageResourcePath();
|
||||||
GeckoLoader.setupGeckoEnvironment(context, pluginDirs, context.getFilesDir().getPath());
|
GeckoLoader.setupGeckoEnvironment(context, context.getFilesDir().getPath());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loadGeckoLibs(context, resourcePath);
|
loadGeckoLibs(context, resourcePath);
|
||||||
|
|
|
@ -57,34 +57,6 @@ public final class GeckoLoader {
|
||||||
return sGREDir;
|
return sGREDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setupPluginEnvironment(Context context, String[] pluginDirs) {
|
|
||||||
// setup plugin path directories
|
|
||||||
try {
|
|
||||||
// Check to see if plugins were blocked.
|
|
||||||
if (pluginDirs == null) {
|
|
||||||
putenv("MOZ_PLUGINS_BLOCKED=1");
|
|
||||||
putenv("MOZ_PLUGIN_PATH=");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder pluginSearchPath = new StringBuilder();
|
|
||||||
for (int i = 0; i < pluginDirs.length; i++) {
|
|
||||||
pluginSearchPath.append(pluginDirs[i]);
|
|
||||||
pluginSearchPath.append(":");
|
|
||||||
}
|
|
||||||
putenv("MOZ_PLUGIN_PATH=" + pluginSearchPath);
|
|
||||||
|
|
||||||
File pluginDataDir = context.getDir("plugins", 0);
|
|
||||||
putenv("ANDROID_PLUGIN_DATADIR=" + pluginDataDir.getPath());
|
|
||||||
|
|
||||||
File pluginPrivateDataDir = context.getDir("plugins_private", 0);
|
|
||||||
putenv("ANDROID_PLUGIN_DATADIR_PRIVATE=" + pluginPrivateDataDir.getPath());
|
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.w(LOGTAG, "Caught exception getting plugin dirs.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setupDownloadEnvironment(final Context context) {
|
private static void setupDownloadEnvironment(final Context context) {
|
||||||
try {
|
try {
|
||||||
File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||||
|
@ -134,7 +106,7 @@ public final class GeckoLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setupGeckoEnvironment(Context context, String[] pluginDirs, String profilePath) {
|
public static void setupGeckoEnvironment(Context context, String profilePath) {
|
||||||
// if we have an intent (we're being launched by an activity)
|
// if we have an intent (we're being launched by an activity)
|
||||||
// read in any environmental variables from it here
|
// read in any environmental variables from it here
|
||||||
final SafeIntent intent = sIntent;
|
final SafeIntent intent = sIntent;
|
||||||
|
@ -155,7 +127,6 @@ public final class GeckoLoader {
|
||||||
|
|
||||||
putenv("MOZ_ANDROID_PACKAGE_NAME=" + context.getPackageName());
|
putenv("MOZ_ANDROID_PACKAGE_NAME=" + context.getPackageName());
|
||||||
|
|
||||||
setupPluginEnvironment(context, pluginDirs);
|
|
||||||
setupDownloadEnvironment(context);
|
setupDownloadEnvironment(context);
|
||||||
|
|
||||||
// profile home path
|
// profile home path
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
<html style="margin: 0; padding: 0">
|
|
||||||
<head>
|
|
||||||
<title>Adobe Flash Test</title>
|
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
</head>
|
|
||||||
<body style="margin: 0; padding: 0">
|
|
||||||
<object width="100" height="100"
|
|
||||||
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
|
|
||||||
codebase="http://fpdownload.macromedia.com/
|
|
||||||
pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0">
|
|
||||||
<param name="SRC" value="green.swf">
|
|
||||||
<embed src="green.swf" width="100" height="100">
|
|
||||||
</embed>
|
|
||||||
</object>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -81,7 +81,6 @@ public class StringHelper {
|
||||||
public final String ROBOCOP_PICTURE_LINK_URL = "/robocop/robocop_picture_link.html";
|
public final String ROBOCOP_PICTURE_LINK_URL = "/robocop/robocop_picture_link.html";
|
||||||
public final String ROBOCOP_SEARCH_URL = "/robocop/robocop_search.html";
|
public final String ROBOCOP_SEARCH_URL = "/robocop/robocop_search.html";
|
||||||
public final String ROBOCOP_TEXT_PAGE_URL = "/robocop/robocop_text_page.html";
|
public final String ROBOCOP_TEXT_PAGE_URL = "/robocop/robocop_text_page.html";
|
||||||
public final String ROBOCOP_ADOBE_FLASH_URL = "/robocop/robocop_adobe_flash.html";
|
|
||||||
public final String ROBOCOP_INPUT_URL = "/robocop/robocop_input.html";
|
public final String ROBOCOP_INPUT_URL = "/robocop/robocop_input.html";
|
||||||
public final String ROBOCOP_READER_MODE_BASIC_ARTICLE = "/robocop/reader_mode_pages/basic_article.html";
|
public final String ROBOCOP_READER_MODE_BASIC_ARTICLE = "/robocop/reader_mode_pages/basic_article.html";
|
||||||
public final String ROBOCOP_LINK_TO_SLOW_LOADING = "/robocop/robocop_link_to_slow_loading.html";
|
public final String ROBOCOP_LINK_TO_SLOW_LOADING = "/robocop/robocop_link_to_slow_loading.html";
|
||||||
|
@ -218,8 +217,6 @@ public class StringHelper {
|
||||||
public final String ADVANCED;
|
public final String ADVANCED;
|
||||||
public final String DONT_SHOW_MENU;
|
public final String DONT_SHOW_MENU;
|
||||||
public final String SHOW_MENU;
|
public final String SHOW_MENU;
|
||||||
public final String DISABLED;
|
|
||||||
public final String TAP_TO_PLAY;
|
|
||||||
public final String HIDE_TITLE_BAR;
|
public final String HIDE_TITLE_BAR;
|
||||||
public final String RESTORE_TABS_LABEL;
|
public final String RESTORE_TABS_LABEL;
|
||||||
|
|
||||||
|
@ -401,8 +398,6 @@ public class StringHelper {
|
||||||
ADVANCED = res.getString(R.string.pref_category_advanced);
|
ADVANCED = res.getString(R.string.pref_category_advanced);
|
||||||
DONT_SHOW_MENU = res.getString(R.string.pref_char_encoding_off);
|
DONT_SHOW_MENU = res.getString(R.string.pref_char_encoding_off);
|
||||||
SHOW_MENU = res.getString(R.string.pref_char_encoding_on);
|
SHOW_MENU = res.getString(R.string.pref_char_encoding_on);
|
||||||
DISABLED = res.getString(R.string.pref_plugins_disabled );
|
|
||||||
TAP_TO_PLAY = res.getString(R.string.pref_plugins_tap_to_play);
|
|
||||||
HIDE_TITLE_BAR = res.getString(R.string.pref_scroll_title_bar_summary );
|
HIDE_TITLE_BAR = res.getString(R.string.pref_scroll_title_bar_summary );
|
||||||
RESTORE_TABS_LABEL = res.getString(R.string.pref_restore);
|
RESTORE_TABS_LABEL = res.getString(R.string.pref_restore);
|
||||||
|
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
package org.mozilla.gecko.tests;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.mozilla.gecko.PaintedSurface;
|
|
||||||
|
|
||||||
import android.os.Build;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests that Flash is working
|
|
||||||
* - loads a page containing a Flash plugin
|
|
||||||
* - verifies it rendered properly
|
|
||||||
*/
|
|
||||||
public class testAdobeFlash extends PixelTest {
|
|
||||||
public void testLoad() {
|
|
||||||
// Enable plugins
|
|
||||||
setPreferenceAndWaitForChange("plugin.enable", "1");
|
|
||||||
|
|
||||||
blockForGeckoReady();
|
|
||||||
|
|
||||||
String url = getAbsoluteUrl(mStringHelper.ROBOCOP_ADOBE_FLASH_URL);
|
|
||||||
PaintedSurface painted = loadAndGetPainted(url);
|
|
||||||
|
|
||||||
mAsserter.ispixel(painted.getPixelAt(0, 0), 0, 0xff, 0, "Pixel at 0, 0");
|
|
||||||
mAsserter.ispixel(painted.getPixelAt(50, 50), 0, 0xff, 0, "Pixel at 50, 50");
|
|
||||||
mAsserter.ispixel(painted.getPixelAt(101, 0), 0xff, 0xff, 0xff, "Pixel at 101, 0");
|
|
||||||
mAsserter.ispixel(painted.getPixelAt(0, 101), 0xff, 0xff, 0xff, "Pixel at 0, 101");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5738,12 +5738,11 @@ pref("layout.css.servo.enabled", false);
|
||||||
// HSTS Priming
|
// HSTS Priming
|
||||||
// If a request is mixed-content, send an HSTS priming request to attempt to
|
// If a request is mixed-content, send an HSTS priming request to attempt to
|
||||||
// see if it is available over HTTPS.
|
// see if it is available over HTTPS.
|
||||||
#ifdef RELEASE
|
|
||||||
// Don't change the order of evaluation of mixed-content and HSTS upgrades in
|
// Don't change the order of evaluation of mixed-content and HSTS upgrades in
|
||||||
// order to be most compatible with current standards
|
// order to be most compatible with current standards in Release
|
||||||
pref("security.mixed_content.send_hsts_priming", false);
|
pref("security.mixed_content.send_hsts_priming", false);
|
||||||
pref("security.mixed_content.use_hsts", false);
|
pref("security.mixed_content.use_hsts", false);
|
||||||
#else
|
#ifdef EARLY_BETA_OR_EARLIER
|
||||||
// Change the order of evaluation so HSTS upgrades happen before
|
// Change the order of evaluation so HSTS upgrades happen before
|
||||||
// mixed-content blocking
|
// mixed-content blocking
|
||||||
pref("security.mixed_content.send_hsts_priming", true);
|
pref("security.mixed_content.send_hsts_priming", true);
|
||||||
|
|
|
@ -332,7 +332,7 @@ nsFileStreamBase::DoOpen()
|
||||||
// Result doesn't need to be checked. If the file's parent path does not
|
// Result doesn't need to be checked. If the file's parent path does not
|
||||||
// exist, make it. If it does exist, do nothing.
|
// exist, make it. If it does exist, do nothing.
|
||||||
if (parent) {
|
if (parent) {
|
||||||
Unused << parent->Create(nsIFile::DIRECTORY_TYPE, 0644);
|
Unused << parent->Create(nsIFile::DIRECTORY_TYPE, 0755);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1411,7 +1411,9 @@ nsStandardURL::GetSpecIgnoringRef(nsACString &result)
|
||||||
URLSegment noRef(0, mRef.mPos - 1);
|
URLSegment noRef(0, mRef.mPos - 1);
|
||||||
result = Segment(noRef);
|
result = Segment(noRef);
|
||||||
|
|
||||||
if (!gPunycodeHost && mCheckedIfHostA && !mDisplayHost.IsEmpty()) {
|
CheckIfHostIsAscii();
|
||||||
|
MOZ_ASSERT(mCheckedIfHostA);
|
||||||
|
if (!gPunycodeHost && !mDisplayHost.IsEmpty()) {
|
||||||
result.Replace(mHost.mPos, mHost.mLen, mDisplayHost);
|
result.Replace(mHost.mPos, mHost.mLen, mDisplayHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1419,11 +1421,43 @@ nsStandardURL::GetSpecIgnoringRef(nsACString &result)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsStandardURL::CheckIfHostIsAscii()
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
if (mCheckedIfHostA) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCheckedIfHostA = true;
|
||||||
|
|
||||||
|
// If the hostname doesn't begin with `xn--` we are sure it is ASCII.
|
||||||
|
if (!StringBeginsWith(Host(), NS_LITERAL_CSTRING("xn--"))) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gIDN) {
|
||||||
|
return NS_ERROR_NOT_INITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAscii;
|
||||||
|
rv = gIDN->ConvertToDisplayIDN(Host(), &isAscii, mDisplayHost);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
mDisplayHost.Truncate();
|
||||||
|
mCheckedIfHostA = false;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsStandardURL::GetDisplaySpec(nsACString &aUnicodeSpec)
|
nsStandardURL::GetDisplaySpec(nsACString &aUnicodeSpec)
|
||||||
{
|
{
|
||||||
|
CheckIfHostIsAscii();
|
||||||
aUnicodeSpec.Assign(mSpec);
|
aUnicodeSpec.Assign(mSpec);
|
||||||
if (mCheckedIfHostA && !mDisplayHost.IsEmpty()) {
|
MOZ_ASSERT(mCheckedIfHostA);
|
||||||
|
if (!mDisplayHost.IsEmpty()) {
|
||||||
aUnicodeSpec.Replace(mHost.mPos, mHost.mLen, mDisplayHost);
|
aUnicodeSpec.Replace(mHost.mPos, mHost.mLen, mDisplayHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1458,29 +1492,13 @@ nsStandardURL::GetDisplayHostPort(nsACString &aUnicodeHostPort)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsStandardURL::GetDisplayHost(nsACString &aUnicodeHost)
|
nsStandardURL::GetDisplayHost(nsACString &aUnicodeHost)
|
||||||
{
|
{
|
||||||
if (mCheckedIfHostA) {
|
CheckIfHostIsAscii();
|
||||||
if (mDisplayHost.IsEmpty()) {
|
MOZ_ASSERT(mCheckedIfHostA);
|
||||||
return GetAsciiHost(aUnicodeHost);
|
if (mDisplayHost.IsEmpty()) {
|
||||||
} else {
|
return GetAsciiHost(aUnicodeHost);
|
||||||
aUnicodeHost = mDisplayHost;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gIDN) {
|
|
||||||
return NS_ERROR_NOT_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv = gIDN->ConvertACEtoUTF8(Host(), aUnicodeHost);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
mCheckedIfHostA = true;
|
|
||||||
if (aUnicodeHost != Host()) {
|
|
||||||
mDisplayHost = aUnicodeHost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aUnicodeHost = mDisplayHost;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1490,7 +1508,9 @@ NS_IMETHODIMP
|
||||||
nsStandardURL::GetPrePath(nsACString &result)
|
nsStandardURL::GetPrePath(nsACString &result)
|
||||||
{
|
{
|
||||||
result = Prepath();
|
result = Prepath();
|
||||||
if (!gPunycodeHost && mCheckedIfHostA && !mDisplayHost.IsEmpty()) {
|
CheckIfHostIsAscii();
|
||||||
|
MOZ_ASSERT(mCheckedIfHostA);
|
||||||
|
if (!gPunycodeHost && !mDisplayHost.IsEmpty()) {
|
||||||
result.Replace(mHost.mPos, mHost.mLen, mDisplayHost);
|
result.Replace(mHost.mPos, mHost.mLen, mDisplayHost);
|
||||||
}
|
}
|
||||||
CALL_RUST_GETTER_STR(result, GetPrePath, result);
|
CALL_RUST_GETTER_STR(result, GetPrePath, result);
|
||||||
|
|
|
@ -189,6 +189,7 @@ private:
|
||||||
bool ValidIPv6orHostname(const char *host, uint32_t aLen);
|
bool ValidIPv6orHostname(const char *host, uint32_t aLen);
|
||||||
static bool IsValidOfBase(unsigned char c, const uint32_t base);
|
static bool IsValidOfBase(unsigned char c, const uint32_t base);
|
||||||
nsresult NormalizeIDN(const nsACString& host, nsCString& result);
|
nsresult NormalizeIDN(const nsACString& host, nsCString& result);
|
||||||
|
nsresult CheckIfHostIsAscii();
|
||||||
void CoalescePath(netCoalesceFlags coalesceFlag, char *path);
|
void CoalescePath(netCoalesceFlags coalesceFlag, char *path);
|
||||||
|
|
||||||
uint32_t AppendSegmentToBuf(char *, uint32_t, const char *,
|
uint32_t AppendSegmentToBuf(char *, uint32_t, const char *,
|
||||||
|
|
|
@ -547,9 +547,9 @@ nsDNSService::Init()
|
||||||
int proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
|
int proxyType = nsIProtocolProxyService::PROXYCONFIG_DIRECT;
|
||||||
bool notifyResolution = false;
|
bool notifyResolution = false;
|
||||||
|
|
||||||
nsAdoptingCString ipv4OnlyDomains;
|
nsCString ipv4OnlyDomains;
|
||||||
nsAdoptingCString localDomains;
|
nsCString localDomains;
|
||||||
nsAdoptingCString forceResolve;
|
nsCString forceResolve;
|
||||||
|
|
||||||
// read prefs
|
// read prefs
|
||||||
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||||
|
@ -618,7 +618,7 @@ nsDNSService::Init()
|
||||||
MutexAutoLock lock(mLock);
|
MutexAutoLock lock(mLock);
|
||||||
mResolver = res;
|
mResolver = res;
|
||||||
mIDN = idn;
|
mIDN = idn;
|
||||||
mIPv4OnlyDomains = ipv4OnlyDomains; // exchanges buffer ownership
|
mIPv4OnlyDomains = ipv4OnlyDomains;
|
||||||
mOfflineLocalhost = offlineLocalhost;
|
mOfflineLocalhost = offlineLocalhost;
|
||||||
mDisableIPv6 = disableIPv6;
|
mDisableIPv6 = disableIPv6;
|
||||||
mBlockDotOnion = blockDotOnion;
|
mBlockDotOnion = blockDotOnion;
|
||||||
|
@ -629,7 +629,7 @@ nsDNSService::Init()
|
||||||
mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
|
mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
|
||||||
|
|
||||||
mLocalDomains.Clear();
|
mLocalDomains.Clear();
|
||||||
if (localDomains) {
|
if (!localDomains.IsVoid()) {
|
||||||
nsCCharSeparatedTokenizer tokenizer(localDomains, ',',
|
nsCCharSeparatedTokenizer tokenizer(localDomains, ',',
|
||||||
nsCCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
|
nsCCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
|
||||||
|
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче