merge mozilla-inbound to mozilla-central. r=merge a=merge

MozReview-Commit-ID: IrMqWiJhwan
This commit is contained in:
Sebastian Hengst 2017-08-01 11:23:57 +02:00
Родитель 5eecb0df0a 8a7e6af123
Коммит ddd4030358
139 изменённых файлов: 942 добавлений и 5879 удалений

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

@ -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);
}); });
} }

64
browser/extensions/e10srollout/bootstrap.js поставляемый
Просмотреть файл

@ -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);
} }

44
browser/extensions/onboarding/bootstrap.js поставляемый
Просмотреть файл

@ -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);

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше