mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge fx-team to mozilla-central a=merge
This commit is contained in:
commit
ad0f429b28
@ -182,6 +182,9 @@ pref("app.update.metro.enabled", true);
|
||||
// If set to true, the Update Service will present no UI for any event.
|
||||
pref("app.update.silent", false);
|
||||
|
||||
// If set to true, the hamburger button will show badges for update events.
|
||||
pref("app.update.badge", false);
|
||||
|
||||
// If set to true, the Update Service will apply updates in the background
|
||||
// when it finishes downloading them.
|
||||
pref("app.update.staging.enabled", true);
|
||||
|
@ -1324,6 +1324,8 @@ var gBrowserInit = {
|
||||
// Add Devtools menuitems and listeners
|
||||
gDevToolsBrowser.registerBrowserWindow(window);
|
||||
|
||||
gMenuButtonUpdateBadge.init();
|
||||
|
||||
window.addEventListener("mousemove", MousePosTracker, false);
|
||||
window.addEventListener("dragover", MousePosTracker, false);
|
||||
|
||||
@ -1470,6 +1472,8 @@ var gBrowserInit = {
|
||||
|
||||
DevEdition.uninit();
|
||||
|
||||
gMenuButtonUpdateBadge.uninit();
|
||||
|
||||
var enumerator = Services.wm.getEnumerator(null);
|
||||
enumerator.getNext();
|
||||
if (!enumerator.hasMoreElements()) {
|
||||
@ -2439,6 +2443,118 @@ function PageProxyClickHandler(aEvent)
|
||||
middleMousePaste(aEvent);
|
||||
}
|
||||
|
||||
// Setup the hamburger button badges for updates, if enabled.
|
||||
let gMenuButtonUpdateBadge = {
|
||||
enabled: false,
|
||||
|
||||
init: function () {
|
||||
try {
|
||||
this.enabled = Services.prefs.getBoolPref("app.update.badge");
|
||||
} catch (e) {}
|
||||
if (this.enabled) {
|
||||
PanelUI.menuButton.classList.add("badged-button");
|
||||
Services.obs.addObserver(this, "update-staged", false);
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
if (this.enabled) {
|
||||
Services.obs.removeObserver(this, "update-staged");
|
||||
PanelUI.panel.removeEventListener("popupshowing", this, true);
|
||||
this.enabled = false;
|
||||
}
|
||||
},
|
||||
|
||||
onMenuPanelCommand: function(event) {
|
||||
if (event.originalTarget.getAttribute("update-status") === "succeeded") {
|
||||
// restart the app
|
||||
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
|
||||
.createInstance(Ci.nsISupportsPRBool);
|
||||
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
|
||||
|
||||
if (!cancelQuit.data) {
|
||||
Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart);
|
||||
}
|
||||
} else {
|
||||
// open the page for manual update
|
||||
let url = Services.urlFormatter.formatURLPref("app.update.url.manual");
|
||||
openUILinkIn(url, "tab");
|
||||
}
|
||||
},
|
||||
|
||||
observe: function (subject, topic, status) {
|
||||
const STATE_DOWNLOADING = "downloading";
|
||||
const STATE_PENDING = "pending";
|
||||
const STATE_PENDING_SVC = "pending-service";
|
||||
const STATE_APPLIED = "applied";
|
||||
const STATE_APPLIED_SVC = "applied-service";
|
||||
const STATE_FAILED = "failed";
|
||||
|
||||
let updateButton = document.getElementById("PanelUI-update-status");
|
||||
|
||||
let updateButtonText;
|
||||
let stringId;
|
||||
|
||||
// Update the UI when the background updater is finished.
|
||||
switch (status) {
|
||||
case STATE_APPLIED:
|
||||
case STATE_APPLIED_SVC:
|
||||
case STATE_PENDING:
|
||||
case STATE_PENDING_SVC:
|
||||
// If the update is successfully applied, or if the updater has fallen back
|
||||
// to non-staged updates, add a badge to the hamburger menu to indicate an
|
||||
// update will be applied once the browser restarts.
|
||||
let badge = document.getAnonymousElementByAttribute(PanelUI.menuButton,
|
||||
"class",
|
||||
"toolbarbutton-badge");
|
||||
badge.style.backgroundColor = 'green';
|
||||
PanelUI.menuButton.setAttribute("badge", "\u2605");
|
||||
|
||||
let brandBundle = document.getElementById("bundle_brand");
|
||||
let brandShortName = brandBundle.getString("brandShortName");
|
||||
stringId = "appmenu.restartNeeded.description";
|
||||
updateButtonText = gNavigatorBundle.getFormattedString(stringId,
|
||||
[brandShortName]);
|
||||
|
||||
updateButton.label = updateButtonText;
|
||||
updateButton.hidden = false;
|
||||
updateButton.setAttribute("update-status", "succeeded");
|
||||
|
||||
PanelUI.panel.addEventListener("popupshowing", this, true);
|
||||
|
||||
break;
|
||||
case STATE_FAILED:
|
||||
// Background update has failed, let's show the UI responsible for
|
||||
// prompting the user to update manually.
|
||||
PanelUI.menuButton.setAttribute("badge", "!");
|
||||
|
||||
stringId = "appmenu.updateFailed.description";
|
||||
updateButtonText = gNavigatorBundle.getString(stringId);
|
||||
|
||||
updateButton.label = updateButtonText;
|
||||
updateButton.hidden = false;
|
||||
updateButton.setAttribute("update-status", "failed");
|
||||
|
||||
PanelUI.panel.addEventListener("popupshowing", this, true);
|
||||
|
||||
break;
|
||||
case STATE_DOWNLOADING:
|
||||
// We've fallen back to downloading the full update because the partial
|
||||
// update failed to get staged in the background. Therefore we need to keep
|
||||
// our observer.
|
||||
return;
|
||||
}
|
||||
this.uninit();
|
||||
},
|
||||
|
||||
handleEvent: function(e) {
|
||||
if (e.type === "popupshowing") {
|
||||
PanelUI.menuButton.removeAttribute("badge");
|
||||
PanelUI.panel.removeEventListener("popupshowing", this, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle command events bubbling up from error page content
|
||||
* or from about:newtab or from remote error pages that invoke
|
||||
|
@ -213,12 +213,11 @@ let gSearch = {
|
||||
|
||||
if (uri) {
|
||||
this._nodes.logo.style.backgroundImage = "url(" + uri + ")";
|
||||
this._nodes.text.placeholder = "";
|
||||
}
|
||||
else {
|
||||
this._nodes.logo.style.backgroundImage = "";
|
||||
this._nodes.text.placeholder = engine.name;
|
||||
}
|
||||
this._nodes.text.placeholder = engine.placeholder;
|
||||
|
||||
// Set up the suggestion controller.
|
||||
if (!this._suggestionController) {
|
||||
|
@ -140,7 +140,7 @@ skip-if = e10s
|
||||
[browser_bug356571.js]
|
||||
[browser_bug380960.js]
|
||||
[browser_bug386835.js]
|
||||
skip-if = e10s # Bug 691614 - no e10s zoom support yet
|
||||
skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
|
||||
[browser_bug405137.js]
|
||||
[browser_bug406216.js]
|
||||
[browser_bug409481.js]
|
||||
@ -148,11 +148,11 @@ skip-if = e10s # Bug 691614 - no e10s zoom support yet
|
||||
skip-if = e10s
|
||||
[browser_bug413915.js]
|
||||
[browser_bug416661.js]
|
||||
skip-if = e10s # Bug 691614 - no e10s zoom support yet
|
||||
skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
|
||||
[browser_bug417483.js]
|
||||
skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
|
||||
[browser_bug419612.js]
|
||||
skip-if = e10s # Bug 691614 - no e10s zoom support yet
|
||||
skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
|
||||
[browser_bug422590.js]
|
||||
[browser_bug846489.js]
|
||||
[browser_bug423833.js]
|
||||
@ -168,7 +168,7 @@ skip-if = e10s # Bug ?????? - test directly manipulates content (eg, var expertD
|
||||
[browser_bug435325.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content
|
||||
[browser_bug441778.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 691614 - no e10s zoom support yet
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
|
||||
[browser_bug455852.js]
|
||||
skip-if = e10s
|
||||
[browser_bug460146.js]
|
||||
@ -176,11 +176,11 @@ skip-if = e10s # Bug 866413 - PageInfo doesn't work in e10s
|
||||
[browser_bug462289.js]
|
||||
skip-if = toolkit == "cocoa" || e10s # Bug ?????? - not sure why this is timing out and crashing!!
|
||||
[browser_bug462673.js]
|
||||
skip-if = e10s # Bug 924260 - "Window is closed"
|
||||
skip-if = e10s # Bug 1093404 - test expects sync window opening from content and is disappointed in that expectation
|
||||
[browser_bug477014.js]
|
||||
skip-if = e10s # Bug 1093206 - need to re-enable tests relying on swapFrameLoaders et al for e10s
|
||||
[browser_bug479408.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 918663 - DOMLinkAdded events don't make their way to chrome
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_bug481560.js]
|
||||
skip-if = e10s # Bug ????? - This bug attached an event listener directly to the content
|
||||
[browser_bug484315.js]
|
||||
@ -195,23 +195,20 @@ skip-if = e10s # Bug 866413 - PageInfo doesn't work in e10s
|
||||
skip-if = e10s # Bug ?????? - some weird timing issue with progress listeners that fails intermittently
|
||||
[browser_bug520538.js]
|
||||
[browser_bug521216.js]
|
||||
skip-if = e10s # Bug 918663 - DOMLinkAdded events don't make their way to chrome
|
||||
[browser_bug533232.js]
|
||||
[browser_bug537013.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 1093206 - need to re-enable tests relying on swapFrameLoaders et al for e10s (test calls replaceTabWithWindow)
|
||||
[browser_bug537474.js]
|
||||
skip-if = e10s # Bug ?????? - test doesn't wait for document to be created before it checks it
|
||||
[browser_bug550565.js]
|
||||
skip-if = e10s # Bug 918663 - DOMLinkAdded events don't make their way to chrome (which is how gBrowser.getIcon works)
|
||||
[browser_bug553455.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 1066070 - I don't think either popup notifications nor addon install stuff works?
|
||||
[browser_bug555224.js]
|
||||
skip-if = e10s # Bug 691614 - no e10s zoom support yet
|
||||
skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
|
||||
[browser_bug555767.js]
|
||||
skip-if = e10s # Bug 916974 - Session history doesn't work in e10s
|
||||
skip-if = e10s # Bug 1093373 - relies on browser.sessionHistory
|
||||
[browser_bug556061.js]
|
||||
[browser_bug559991.js]
|
||||
skip-if = e10s # Bug 691614 - no e10s zoom support yet
|
||||
[browser_bug561623.js]
|
||||
skip-if = e10s
|
||||
[browser_bug561636.js]
|
||||
@ -227,7 +224,7 @@ run-if = toolkit == "cocoa"
|
||||
skip-if = e10s
|
||||
[browser_bug575561.js]
|
||||
[browser_bug575830.js]
|
||||
skip-if = e10s # Bug 691614 - no e10s zoom support yet
|
||||
skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
|
||||
[browser_bug577121.js]
|
||||
[browser_bug578534.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content
|
||||
@ -260,7 +257,7 @@ skip-if = e10s # Bug ?????? - URLBar issues (apparently issues with redirection)
|
||||
[browser_bug633691.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (eg, var expertDiv = gBrowser.contentDocument.getElementById("expertContent");)
|
||||
[browser_bug647886.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 916974 - Session history doesn't work in e10s
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 1093373 - Relies on browser.sessionHistory
|
||||
[browser_bug655584.js]
|
||||
skip-if = e10s
|
||||
[browser_bug664672.js]
|
||||
@ -271,7 +268,7 @@ skip-if = e10s # Bug ?????? - Obscure non-windows failures ("Snapshot array has
|
||||
[browser_bug710878.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (doc.querySelector)
|
||||
[browser_bug719271.js]
|
||||
skip-if = e10s # Bug 691614 - no e10s zoom support yet
|
||||
skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
|
||||
[browser_bug724239.js]
|
||||
skip-if = e10s # Bug 1077738
|
||||
[browser_bug734076.js]
|
||||
@ -287,7 +284,7 @@ skip-if = e10s # Bug ?????? - test reports a leaked nsGlobalWindow with e10s ena
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content
|
||||
[browser_bug783614.js]
|
||||
[browser_bug816527.js]
|
||||
skip-if = e10s # Bug 916974 - Session history doesn't work in e10s
|
||||
skip-if = e10s # Bug 1093373 - relies on browser.sessionHistory
|
||||
[browser_bug817947.js]
|
||||
[browser_bug822367.js]
|
||||
[browser_bug832435.js]
|
||||
@ -301,7 +298,7 @@ skip-if = buildapp == "mulet" || e10s # Bug ?????? - test directly manipulates c
|
||||
[browser_bug970746.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (directly gets elements from the content)
|
||||
[browser_bug1015721.js]
|
||||
skip-if = os == 'win' || e10s # Bug 1056146 - FullZoomHelper uses promiseTabLoadEvent() which isn't e10s friendly
|
||||
skip-if = os == 'win' || e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
|
||||
[browser_bug1064280_changeUrlInPinnedTab.js]
|
||||
[browser_canonizeURL.js]
|
||||
skip-if = e10s # Bug ?????? - [JavaScript Error: "Error in AboutHome.sendAboutHomeData TypeError: target.messageManager is undefined" {file: "resource:///modules/AboutHome.jsm" line: 208}]
|
||||
@ -321,7 +318,6 @@ skip-if = buildapp == 'mulet' || (os == "linux" && debug) || e10s # linux: bug 9
|
||||
[browser_devices_get_user_media_about_urls.js]
|
||||
skip-if = e10s # Bug 1071623
|
||||
[browser_discovery.js]
|
||||
skip-if = e10s # Bug 918663 - DOMLinkAdded events don't make their way to chrome
|
||||
[browser_double_close_tab.js]
|
||||
skip-if = e10s
|
||||
[browser_duplicateIDs.js]
|
||||
|
@ -16,6 +16,10 @@
|
||||
</vbox>
|
||||
|
||||
<footer id="PanelUI-footer">
|
||||
<toolbarbutton id="PanelUI-update-status"
|
||||
oncommand="gMenuButtonUpdateBadge.onMenuPanelCommand(event);"
|
||||
wrap="true"
|
||||
hidden="true"/>
|
||||
<toolbarbutton id="PanelUI-fxa-status"
|
||||
defaultlabel="&fxaSignIn.label;"
|
||||
errorlabel="&fxaSignInError.label;"
|
||||
|
@ -27,6 +27,7 @@
|
||||
window.OTProperties.configURL = window.OTProperties.assetURL + 'js/dynamic_config.min.js';
|
||||
window.OTProperties.cssURL = window.OTProperties.assetURL + 'css/ot.css';
|
||||
</script>
|
||||
<script type="text/javascript" src="js/multiplexGum.js"></script>
|
||||
<script type="text/javascript" src="shared/libs/sdk.js"></script>
|
||||
<script type="text/javascript" src="libs/l10n-gaia-02ca67948fe8.js"></script>
|
||||
<script type="text/javascript" src="shared/libs/react-0.11.2.js"></script>
|
||||
|
150
browser/components/loop/standalone/content/js/multiplexGum.js
Normal file
150
browser/components/loop/standalone/content/js/multiplexGum.js
Normal file
@ -0,0 +1,150 @@
|
||||
/* 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/. */
|
||||
|
||||
|
||||
var loop = loop || {};
|
||||
|
||||
/**
|
||||
* Monkeypatch getUserMedia in a way that prevents additional camera and
|
||||
* microphone prompts, at the cost of ignoring all constraints other than
|
||||
* the first set passed in.
|
||||
*
|
||||
* The first call to navigator.getUserMedia (also now aliased to
|
||||
* multiplexGum.getPermsAndCacheMedia to allow for explicit calling code)
|
||||
* will cause the underlying gUM implementation to be called.
|
||||
*
|
||||
* While permission is pending, subsequent calls will result in the callbacks
|
||||
* being queued. Once the call succeeds or fails, all queued success or
|
||||
* failure callbacks will be invoked. Subsequent calls to either function will
|
||||
* cause the success or failure callback to be invoked immediately.
|
||||
*/
|
||||
loop.standaloneMedia = (function() {
|
||||
"use strict";
|
||||
|
||||
function patchSymbolIfExtant(objectName, propertyName, replacement) {
|
||||
var object;
|
||||
if (window[objectName]) {
|
||||
object = window[objectName];
|
||||
}
|
||||
if (object && object[propertyName]) {
|
||||
object[propertyName] = replacement;
|
||||
}
|
||||
}
|
||||
|
||||
// originalGum _must_ be on navigator; otherwise things blow up
|
||||
navigator.originalGum = navigator.getUserMedia ||
|
||||
navigator.mozGetUserMedia ||
|
||||
navigator.webkitGetUserMedia ||
|
||||
(window["TBPlugin"] && TBPlugin.getUserMedia);
|
||||
|
||||
function _MultiplexGum() {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
_MultiplexGum.prototype = {
|
||||
/**
|
||||
* @see The docs at the top of this file for overall semantics,
|
||||
* & http://developer.mozilla.org/en-US/docs/NavigatorUserMedia.getUserMedia
|
||||
* for params, since this is intended to be purely a passthrough to gUM.
|
||||
*/
|
||||
getPermsAndCacheMedia: function(constraints, onSuccess, onError) {
|
||||
function handleResult(callbacks, param) {
|
||||
// Operate on a copy of the array in case any of the callbacks
|
||||
// calls reset, which would cause an infinite-recursion.
|
||||
this.userMedia.successCallbacks = [];
|
||||
this.userMedia.errorCallbacks = [];
|
||||
callbacks.forEach(function(cb) {
|
||||
if (typeof cb == "function") {
|
||||
cb(param);
|
||||
}
|
||||
})
|
||||
}
|
||||
function handleSuccess(localStream) {
|
||||
this.userMedia.pending = false;
|
||||
this.userMedia.localStream = localStream;
|
||||
this.userMedia.error = null;
|
||||
handleResult.call(this, this.userMedia.successCallbacks.slice(0), localStream);
|
||||
}
|
||||
|
||||
function handleError(error) {
|
||||
this.userMedia.pending = false;
|
||||
this.userMedia.error = error;
|
||||
handleResult.call(this, this.userMedia.errorCallbacks.slice(0), error);
|
||||
this.error = null;
|
||||
}
|
||||
|
||||
if (this.userMedia.localStream &&
|
||||
this.userMedia.localStream.ended) {
|
||||
this.userMedia.localStream = null;
|
||||
}
|
||||
|
||||
this.userMedia.errorCallbacks.push(onError);
|
||||
this.userMedia.successCallbacks.push(onSuccess);
|
||||
|
||||
if (this.userMedia.localStream) {
|
||||
handleSuccess.call(this, this.userMedia.localStream);
|
||||
return;
|
||||
} else if (this.userMedia.error) {
|
||||
handleError.call(this, this.userMedia.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.userMedia.pending) {
|
||||
return;
|
||||
}
|
||||
this.userMedia.pending = true;
|
||||
|
||||
navigator.originalGum(constraints, handleSuccess.bind(this),
|
||||
handleError.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset the cached permissions, callbacks, and media to their default
|
||||
* state and call any error callbacks to let any waiting callers know
|
||||
* not to ever expect any more callbacks. We use "PERMISSION_DENIED",
|
||||
* for lack of a better, more specific gUM code that callers are likely
|
||||
* to be prepared to handle.
|
||||
*/
|
||||
reset: function() {
|
||||
// When called from the ctor, userMedia is not created yet.
|
||||
if (this.userMedia) {
|
||||
this.userMedia.errorCallbacks.forEach(function(cb) {
|
||||
if (typeof cb == "function") {
|
||||
cb("PERMISSION_DENIED");
|
||||
}
|
||||
});
|
||||
if (this.userMedia.localStream &&
|
||||
typeof this.userMedia.localStream.stop == "function") {
|
||||
this.userMedia.localStream.stop();
|
||||
}
|
||||
}
|
||||
this.userMedia = {
|
||||
error: null,
|
||||
localStream: null,
|
||||
pending: false,
|
||||
errorCallbacks: [],
|
||||
successCallbacks: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
var singletonMultiplexGum = new _MultiplexGum();
|
||||
function myGetUserMedia() {
|
||||
// This function is needed to pull in the instance
|
||||
// of the singleton for tests to overwrite the used instance.
|
||||
singletonMultiplexGum.getPermsAndCacheMedia.apply(singletonMultiplexGum, arguments);
|
||||
};
|
||||
patchSymbolIfExtant("navigator", "mozGetUserMedia", myGetUserMedia);
|
||||
patchSymbolIfExtant("navigator", "webkitGetUserMedia", myGetUserMedia);
|
||||
patchSymbolIfExtant("navigator", "getUserMedia", myGetUserMedia);
|
||||
patchSymbolIfExtant("TBPlugin", "getUserMedia", myGetUserMedia);
|
||||
|
||||
return {
|
||||
multiplexGum: singletonMultiplexGum,
|
||||
_MultiplexGum: _MultiplexGum,
|
||||
setSingleton: function(singleton) {
|
||||
singletonMultiplexGum = singleton;
|
||||
},
|
||||
};
|
||||
})();
|
@ -19,11 +19,14 @@ loop.webapp = (function($, _, OT, mozL10n) {
|
||||
var sharedViews = loop.shared.views;
|
||||
var sharedUtils = loop.shared.utils;
|
||||
|
||||
var multiplexGum = loop.standaloneMedia.multiplexGum;
|
||||
|
||||
/**
|
||||
* Homepage view.
|
||||
*/
|
||||
var HomeView = React.createClass({displayName: 'HomeView',
|
||||
render: function() {
|
||||
loop.standaloneMedia.multiplexGum.reset();
|
||||
return (
|
||||
React.DOM.p(null, mozL10n.get("welcome", {clientShortname: mozL10n.get("clientShortname2")}))
|
||||
);
|
||||
@ -287,6 +290,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
|
||||
},
|
||||
|
||||
_cancelOutgoingCall: function() {
|
||||
loop.standaloneMedia.multiplexGum.reset();
|
||||
this.props.websocket.cancel();
|
||||
},
|
||||
|
||||
@ -448,8 +452,15 @@ loop.webapp = (function($, _, OT, mozL10n) {
|
||||
*/
|
||||
startCall: function(callType) {
|
||||
return function() {
|
||||
this.props.conversation.setupOutgoingCall(callType);
|
||||
this.setState({disableCallButton: true});
|
||||
multiplexGum.getPermsAndCacheMedia({audio:true, video:true},
|
||||
function(localStream) {
|
||||
this.props.conversation.setupOutgoingCall(callType);
|
||||
this.setState({disableCallButton: true});
|
||||
}.bind(this),
|
||||
function(errorCode) {
|
||||
multiplexGum.reset();
|
||||
}.bind(this)
|
||||
);
|
||||
}.bind(this);
|
||||
},
|
||||
|
||||
|
@ -19,11 +19,14 @@ loop.webapp = (function($, _, OT, mozL10n) {
|
||||
var sharedViews = loop.shared.views;
|
||||
var sharedUtils = loop.shared.utils;
|
||||
|
||||
var multiplexGum = loop.standaloneMedia.multiplexGum;
|
||||
|
||||
/**
|
||||
* Homepage view.
|
||||
*/
|
||||
var HomeView = React.createClass({
|
||||
render: function() {
|
||||
loop.standaloneMedia.multiplexGum.reset();
|
||||
return (
|
||||
<p>{mozL10n.get("welcome", {clientShortname: mozL10n.get("clientShortname2")})}</p>
|
||||
);
|
||||
@ -287,6 +290,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
|
||||
},
|
||||
|
||||
_cancelOutgoingCall: function() {
|
||||
loop.standaloneMedia.multiplexGum.reset();
|
||||
this.props.websocket.cancel();
|
||||
},
|
||||
|
||||
@ -448,8 +452,15 @@ loop.webapp = (function($, _, OT, mozL10n) {
|
||||
*/
|
||||
startCall: function(callType) {
|
||||
return function() {
|
||||
this.props.conversation.setupOutgoingCall(callType);
|
||||
this.setState({disableCallButton: true});
|
||||
multiplexGum.getPermsAndCacheMedia({audio:true, video:true},
|
||||
function(localStream) {
|
||||
this.props.conversation.setupOutgoingCall(callType);
|
||||
this.setState({disableCallButton: true});
|
||||
}.bind(this),
|
||||
function(errorCode) {
|
||||
multiplexGum.reset();
|
||||
}.bind(this)
|
||||
);
|
||||
}.bind(this);
|
||||
},
|
||||
|
||||
|
@ -37,11 +37,13 @@
|
||||
<script src="../../content/shared/js/views.js"></script>
|
||||
<script src="../../content/shared/js/websocket.js"></script>
|
||||
<script src="../../content/shared/js/feedbackApiClient.js"></script>
|
||||
<script src="../../standalone/content/js/multiplexGum.js"></script>
|
||||
<script src="../../standalone/content/js/standaloneClient.js"></script>
|
||||
<script src="../../standalone/content/js/webapp.js"></script>
|
||||
<!-- Test scripts -->
|
||||
<script src="standalone_client_test.js"></script>
|
||||
<script src="webapp_test.js"></script>
|
||||
<script src="multiplexGum_test.js"></script>
|
||||
<script>
|
||||
mocha.run(function () {
|
||||
$("#mocha").append("<p id='complete'>Complete.</p>");
|
||||
|
370
browser/components/loop/test/standalone/multiplexGum_test.js
Normal file
370
browser/components/loop/test/standalone/multiplexGum_test.js
Normal file
@ -0,0 +1,370 @@
|
||||
/* 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/. */
|
||||
|
||||
/*global loop, sinon, it, beforeEach, afterEach, describe*/
|
||||
|
||||
var expect = chai.expect;
|
||||
|
||||
describe("loop.standaloneMedia._MultiplexGum", function() {
|
||||
"use strict";
|
||||
|
||||
var defaultGum =
|
||||
navigator.getUserMedia ||
|
||||
navigator.mozGetUserMedia ||
|
||||
navigator.webkitGetUserMedia ||
|
||||
(window["TBPlugin"] && TBPlugin.getUserMedia);
|
||||
|
||||
var sandbox;
|
||||
var multiplexGum;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
multiplexGum = new loop.standaloneMedia._MultiplexGum();
|
||||
loop.standaloneMedia.setSingleton(multiplexGum);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe("#constructor", function() {
|
||||
it("pending should default to false", function() {
|
||||
expect(multiplexGum.userMedia.pending).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("default getUserMedia", function() {
|
||||
it("should call getPermsAndCacheMedia", function() {
|
||||
var fakeOptions = {audio: true, video: true};
|
||||
var successCB = function() {};
|
||||
var errorCB = function() {};
|
||||
sandbox.stub(navigator, "originalGum");
|
||||
sandbox.stub(loop.standaloneMedia._MultiplexGum.prototype,
|
||||
"getPermsAndCacheMedia");
|
||||
multiplexGum = new loop.standaloneMedia._MultiplexGum();
|
||||
|
||||
defaultGum(fakeOptions, successCB, errorCB);
|
||||
|
||||
sinon.assert.calledOnce(multiplexGum.getPermsAndCacheMedia);
|
||||
sinon.assert.calledWithExactly(multiplexGum.getPermsAndCacheMedia,
|
||||
fakeOptions, successCB, errorCB);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#getPermsAndCacheMedia", function() {
|
||||
beforeEach(function() {
|
||||
sandbox.stub(navigator, "originalGum");
|
||||
});
|
||||
|
||||
it("should change pending to true", function() {
|
||||
multiplexGum.getPermsAndCacheMedia();
|
||||
|
||||
expect(multiplexGum.userMedia.pending).to.equal(true);
|
||||
});
|
||||
|
||||
it("should call originalGum", function() {
|
||||
multiplexGum.getPermsAndCacheMedia();
|
||||
|
||||
sinon.assert.calledOnce(navigator.originalGum);
|
||||
});
|
||||
|
||||
it("should reset the pending state when the error callback is called",
|
||||
function(done) {
|
||||
var fakeError = new Error();
|
||||
navigator.originalGum.callsArgWith(2, fakeError);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null, null, function onError(error) {
|
||||
expect(multiplexGum.userMedia.pending).to.equal(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should reset the pending state when the success callback is called",
|
||||
function(done) {
|
||||
var fakeLocalStream = {};
|
||||
navigator.originalGum.callsArgWith(1, fakeLocalStream);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null,
|
||||
function onSuccess(localStream) {
|
||||
expect(multiplexGum.userMedia.pending).to.equal(false);
|
||||
done();
|
||||
}, null);
|
||||
});
|
||||
|
||||
it("should call the error callback when originalGum calls back an error",
|
||||
function(done) {
|
||||
var fakeError = new Error();
|
||||
navigator.originalGum.callsArgWith(2, fakeError);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null, null, function onError(error) {
|
||||
expect(error).to.eql(fakeError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should propagate the success callback when originalGum succeeds",
|
||||
function(done) {
|
||||
var fakeLocalStream = {};
|
||||
navigator.originalGum.callsArgWith(1, fakeLocalStream);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null,
|
||||
function onSuccess(localStream) {
|
||||
expect(localStream).to.eql(fakeLocalStream);
|
||||
done();
|
||||
}, null);
|
||||
});
|
||||
|
||||
it("should call the success callback when the stream is cached",
|
||||
function(done) {
|
||||
var fakeLocalStream = {};
|
||||
multiplexGum.userMedia.localStream = fakeLocalStream;
|
||||
sinon.assert.notCalled(navigator.originalGum);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null,
|
||||
function onSuccess(localStream) {
|
||||
expect(localStream).to.eql(fakeLocalStream);
|
||||
done();
|
||||
}, null);
|
||||
});
|
||||
|
||||
it("should call the error callback when an error is cached",
|
||||
function(done) {
|
||||
var fakeError = new Error();
|
||||
multiplexGum.userMedia.error = fakeError;
|
||||
sinon.assert.notCalled(navigator.originalGum);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null, null, function onError(error) {
|
||||
expect(error).to.eql(fakeError);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should clear the error when success is called back", function(done) {
|
||||
var fakeError = new Error();
|
||||
var fakeLocalStream = {};
|
||||
multiplexGum.userMedia.localStream = fakeLocalStream;
|
||||
multiplexGum.userMedia.error = fakeError;
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null, function onSuccess(localStream) {
|
||||
expect(multiplexGum.userMedia.error).to.not.eql(fakeError);
|
||||
expect(localStream).to.eql(fakeLocalStream);
|
||||
done();
|
||||
}, null);
|
||||
});
|
||||
|
||||
it("should call all success callbacks when success is achieved",
|
||||
function(done) {
|
||||
var fakeLocalStream = {};
|
||||
var calls = 0;
|
||||
// Async is needed so that the callbacks can be queued up.
|
||||
navigator.originalGum.callsArgWithAsync(1, fakeLocalStream);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null, function onSuccess(localStream) {
|
||||
calls += 1;
|
||||
expect(localStream).to.eql(fakeLocalStream);
|
||||
}, null);
|
||||
|
||||
expect(multiplexGum.userMedia).to.have.property('pending', true);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null, function onSuccess(localStream) {
|
||||
calls += 10;
|
||||
expect(localStream).to.eql(fakeLocalStream);
|
||||
expect(calls).to.equal(11);
|
||||
done();
|
||||
}, null);
|
||||
});
|
||||
|
||||
it("should call all error callbacks when error is encountered",
|
||||
function(done) {
|
||||
var fakeError = new Error();
|
||||
var calls = 0;
|
||||
// Async is needed so that the callbacks can be queued up.
|
||||
navigator.originalGum.callsArgWithAsync(2, fakeError);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null, null, function onError(error) {
|
||||
calls += 1;
|
||||
expect(error).to.eql(fakeError);
|
||||
});
|
||||
|
||||
expect(multiplexGum.userMedia).to.have.property('pending', true);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null, null, function onError(error) {
|
||||
calls += 10;
|
||||
expect(error).to.eql(fakeError);
|
||||
expect(calls).to.eql(11);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should not call a getPermsAndCacheMedia success callback at the time" +
|
||||
" of gUM success callback fires",
|
||||
function(done) {
|
||||
var fakeLocalStream = {};
|
||||
multiplexGum.userMedia.localStream = fakeLocalStream;
|
||||
navigator.originalGum.callsArgWith(1, fakeLocalStream);
|
||||
var calledOnce = false;
|
||||
var promiseCalledOnce = new Promise(function(resolve, reject) {
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null,
|
||||
function gPACMSuccess(localStream) {
|
||||
expect(localStream).to.eql(fakeLocalStream);
|
||||
expect(multiplexGum.userMedia).to.have.property('pending', false);
|
||||
expect(multiplexGum.userMedia.successCallbacks.length).to.equal(0);
|
||||
if (calledOnce) {
|
||||
sinon.assert.fail("original callback was called twice");
|
||||
}
|
||||
calledOnce = true;
|
||||
resolve();
|
||||
}, function() {
|
||||
sinon.assert.fail("error callback should not have fired");
|
||||
reject();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
promiseCalledOnce.then(function() {
|
||||
defaultGum(null, function gUMSuccess(localStream2) {
|
||||
expect(localStream2).to.eql(fakeLocalStream);
|
||||
expect(multiplexGum.userMedia).to.have.property('pending', false);
|
||||
expect(multiplexGum.userMedia.successCallbacks.length).to.equal(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should not call a getPermsAndCacheMedia error callback when the " +
|
||||
" gUM error callback fires",
|
||||
function(done) {
|
||||
var fakeError = "monkeys ate the stream";
|
||||
multiplexGum.userMedia.error = fakeError;
|
||||
navigator.originalGum.callsArgWith(2, fakeError);
|
||||
var calledOnce = false;
|
||||
var promiseCalledOnce = new Promise(function(resolve, reject) {
|
||||
multiplexGum.getPermsAndCacheMedia(null, function() {
|
||||
sinon.assert.fail("success callback should not have fired");
|
||||
reject();
|
||||
done();
|
||||
}, function gPACMError(errString) {
|
||||
expect(errString).to.eql(fakeError);
|
||||
expect(multiplexGum.userMedia).to.have.property('pending', false);
|
||||
if (calledOnce) {
|
||||
sinon.assert.fail("original error callback was called twice");
|
||||
}
|
||||
calledOnce = true;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
promiseCalledOnce.then(function() {
|
||||
defaultGum(null, function() {},
|
||||
function gUMError(errString) {
|
||||
expect(errString).to.eql(fakeError);
|
||||
expect(multiplexGum.userMedia).to.have.property('pending', false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should call the success callback with a new stream, " +
|
||||
" when a new stream is available",
|
||||
function(done) {
|
||||
var endedStream = {ended: true};
|
||||
var newStream = {};
|
||||
multiplexGum.userMedia.localStream = endedStream;
|
||||
navigator.originalGum.callsArgWith(1, newStream);
|
||||
|
||||
multiplexGum.getPermsAndCacheMedia(null, function onSuccess(localStream) {
|
||||
expect(localStream).to.eql(newStream);
|
||||
done();
|
||||
}, null);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#reset", function () {
|
||||
it("should reset all userMedia state to default", function() {
|
||||
// If userMedia is defined, then it needs to have all of
|
||||
// the properties that multipleGum will depend on. It is
|
||||
// easier to simply delete the object than to setup a fake
|
||||
// state of the object.
|
||||
delete multiplexGum.userMedia;
|
||||
|
||||
multiplexGum.reset();
|
||||
|
||||
expect(multiplexGum.userMedia).to.deep.equal({
|
||||
error: null,
|
||||
localStream: null,
|
||||
pending: false,
|
||||
errorCallbacks: [],
|
||||
successCallbacks: [],
|
||||
});
|
||||
});
|
||||
|
||||
it("should call all queued error callbacks with 'PERMISSION_DENIED'",
|
||||
function(done) {
|
||||
sandbox.stub(navigator, "originalGum");
|
||||
multiplexGum.getPermsAndCacheMedia(null, function(localStream) {
|
||||
sinon.assert.fail(
|
||||
"The success callback shouldn't be called due to reset");
|
||||
}, function(error) {
|
||||
expect(error).to.equal("PERMISSION_DENIED");
|
||||
done();
|
||||
});
|
||||
multiplexGum.reset();
|
||||
});
|
||||
|
||||
it("should call MST.stop() on the stream tracks", function() {
|
||||
var stopStub = sandbox.stub();
|
||||
multiplexGum.userMedia.localStream = {stop: stopStub};
|
||||
|
||||
multiplexGum.reset();
|
||||
|
||||
sinon.assert.calledOnce(stopStub);
|
||||
});
|
||||
|
||||
it("should not call MST.stop() on the stream tracks if .stop() doesn't exist",
|
||||
function() {
|
||||
multiplexGum.userMedia.localStream = {};
|
||||
|
||||
try {
|
||||
multiplexGum.reset();
|
||||
} catch (ex) {
|
||||
sinon.assert.fail(
|
||||
"reset shouldn't throw when a stream doesn't implement stop(): "
|
||||
+ ex);
|
||||
}
|
||||
});
|
||||
|
||||
it("should not get stuck in recursion if the error callback calls 'reset'",
|
||||
function() {
|
||||
sandbox.stub(navigator, "originalGum");
|
||||
navigator.originalGum.callsArgWith(2, "PERMISSION_DENIED");
|
||||
|
||||
var calledOnce = false;
|
||||
multiplexGum.getPermsAndCacheMedia(null, null, function() {
|
||||
if (calledOnce) {
|
||||
sinon.assert.fail("reset should only be called once");
|
||||
}
|
||||
calledOnce = true;
|
||||
multiplexGum.reset.bind(multiplexGum)();
|
||||
});
|
||||
});
|
||||
|
||||
it("should not get stuck in recursion if the success callback calls 'reset'",
|
||||
function() {
|
||||
sandbox.stub(navigator, "originalGum");
|
||||
navigator.originalGum.callsArgWith(1, {});
|
||||
|
||||
var calledOnce = false;
|
||||
multiplexGum.getPermsAndCacheMedia(null, function() {
|
||||
calledOnce = true;
|
||||
multiplexGum.reset.bind(multiplexGum)();
|
||||
}, function() {
|
||||
if (calledOnce) {
|
||||
sinon.assert.fail("reset should only be called once");
|
||||
}
|
||||
calledOnce = true;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -13,9 +13,11 @@ describe("loop.webapp", function() {
|
||||
var sharedModels = loop.shared.models,
|
||||
sharedViews = loop.shared.views,
|
||||
sharedUtils = loop.shared.utils,
|
||||
standaloneMedia = loop.standaloneMedia,
|
||||
sandbox,
|
||||
notifications,
|
||||
feedbackApiClient;
|
||||
feedbackApiClient,
|
||||
stubGetPermsAndCacheMedia;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
@ -23,6 +25,9 @@ describe("loop.webapp", function() {
|
||||
feedbackApiClient = new loop.FeedbackAPIClient("http://invalid", {
|
||||
product: "Loop"
|
||||
});
|
||||
|
||||
stubGetPermsAndCacheMedia = sandbox.stub(
|
||||
loop.standaloneMedia._MultiplexGum.prototype, "getPermsAndCacheMedia");
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
@ -610,6 +615,19 @@ describe("loop.webapp", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("HomeView", function() {
|
||||
it("should call loop.standaloneMedia.reset", function() {
|
||||
var multiplexGum = new standaloneMedia._MultiplexGum();
|
||||
standaloneMedia.setSingleton(multiplexGum);
|
||||
sandbox.stub(standaloneMedia._MultiplexGum.prototype, "reset");
|
||||
|
||||
TestUtils.renderIntoDocument(loop.webapp.HomeView());
|
||||
|
||||
sinon.assert.calledOnce(multiplexGum.reset);
|
||||
sinon.assert.calledWithExactly(multiplexGum.reset);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PendingConversationView", function() {
|
||||
var view, websocket, fakeAudio;
|
||||
|
||||
@ -652,6 +670,18 @@ describe("loop.webapp", function() {
|
||||
|
||||
sinon.assert.calledOnce(websocket.cancel);
|
||||
});
|
||||
|
||||
it("should call multiplexGum.reset to release the camera", function() {
|
||||
var multiplexGum = new standaloneMedia._MultiplexGum();
|
||||
standaloneMedia.setSingleton(multiplexGum);
|
||||
sandbox.stub(standaloneMedia._MultiplexGum.prototype, "reset");
|
||||
|
||||
var button = view.getDOMNode().querySelector(".btn-cancel");
|
||||
React.addons.TestUtils.Simulate.click(button);
|
||||
|
||||
sinon.assert.calledOnce(multiplexGum.reset);
|
||||
sinon.assert.calledWithExactly(multiplexGum.reset);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Events", function() {
|
||||
@ -697,8 +727,27 @@ describe("loop.webapp", function() {
|
||||
client: standaloneClientStub
|
||||
})
|
||||
);
|
||||
|
||||
// default to succeeding with a null local media object
|
||||
stubGetPermsAndCacheMedia.callsArgWith(1, {});
|
||||
});
|
||||
|
||||
it("should fire multiplexGum.reset when getPermsAndCacheMedia calls" +
|
||||
" back an error",
|
||||
function() {
|
||||
var setupOutgoingCall = sinon.stub(conversation, "setupOutgoingCall");
|
||||
var multiplexGum = new standaloneMedia._MultiplexGum();
|
||||
standaloneMedia.setSingleton(multiplexGum);
|
||||
sandbox.stub(standaloneMedia._MultiplexGum.prototype, "reset");
|
||||
stubGetPermsAndCacheMedia.callsArgWith(2, "FAKE_ERROR");
|
||||
|
||||
var button = view.getDOMNode().querySelector(".btn-accept");
|
||||
React.addons.TestUtils.Simulate.click(button);
|
||||
|
||||
sinon.assert.calledOnce(multiplexGum.reset);
|
||||
sinon.assert.calledWithExactly(multiplexGum.reset);
|
||||
});
|
||||
|
||||
it("should start the audio-video conversation establishment process",
|
||||
function() {
|
||||
var setupOutgoingCall = sinon.stub(conversation, "setupOutgoingCall");
|
||||
@ -1002,6 +1051,9 @@ describe("loop.webapp", function() {
|
||||
client: standaloneClientStub
|
||||
})
|
||||
);
|
||||
|
||||
// default to succeeding with a null local media object
|
||||
stubGetPermsAndCacheMedia.callsArgWith(1, {});
|
||||
});
|
||||
|
||||
it("should start the conversation establishment process", function() {
|
||||
|
@ -26,6 +26,7 @@
|
||||
window.OTProperties.configURL = window.OTProperties.assetURL + 'js/dynamic_config.min.js';
|
||||
window.OTProperties.cssURL = window.OTProperties.assetURL + 'css/ot.css';
|
||||
</script>
|
||||
<script src="../content/js/multiplexGum.js"></script>
|
||||
<script src="../content/shared/libs/sdk.js"></script>
|
||||
<script src="../content/shared/libs/react-0.11.2.js"></script>
|
||||
<script src="../content/shared/libs/jquery-2.1.0.js"></script>
|
||||
|
@ -413,14 +413,52 @@ BrowserGlue.prototype = {
|
||||
case "nsPref:changed":
|
||||
if (data == POLARIS_ENABLED) {
|
||||
let enabled = Services.prefs.getBoolPref(POLARIS_ENABLED);
|
||||
Services.prefs.setBoolPref("privacy.donottrackheader.enabled", enabled);
|
||||
Services.prefs.setBoolPref("privacy.trackingprotection.enabled", enabled);
|
||||
Services.prefs.setBoolPref("privacy.trackingprotection.ui.enabled", enabled);
|
||||
if (enabled) {
|
||||
let e10sEnabled = Services.appinfo.browserTabsRemoteAutostart;
|
||||
let shouldRestart = e10sEnabled && this._promptForE10sRestart();
|
||||
// Only set the related prefs if e10s is not enabled or the user
|
||||
// saw a notification that e10s would be disabled on restart.
|
||||
if (!e10sEnabled || shouldRestart) {
|
||||
Services.prefs.setBoolPref("privacy.donottrackheader.enabled", enabled);
|
||||
Services.prefs.setBoolPref("privacy.trackingprotection.enabled", enabled);
|
||||
Services.prefs.setBoolPref("privacy.trackingprotection.ui.enabled", enabled);
|
||||
if (shouldRestart) {
|
||||
Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit |
|
||||
Ci.nsIAppStartup.eRestart);
|
||||
}
|
||||
} else {
|
||||
// The user chose not to disable E10s which is temporarily
|
||||
// incompatible with Polaris.
|
||||
Services.prefs.clearUserPref(POLARIS_ENABLED);
|
||||
}
|
||||
} else {
|
||||
// Don't reset DNT because its visible pref is independent of
|
||||
// Polaris and may have been previously set.
|
||||
Services.prefs.clearUserPref("privacy.trackingprotection.enabled");
|
||||
Services.prefs.clearUserPref("privacy.trackingprotection.ui.enabled");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
},
|
||||
|
||||
_promptForE10sRestart: function () {
|
||||
let win = this.getMostRecentBrowserWindow();
|
||||
let brandBundle = win.document.getElementById("bundle_brand");
|
||||
let brandName = brandBundle.getString("brandShortName");
|
||||
let prefBundle = win.document.getElementById("bundle_preferences");
|
||||
let msg = "Multiprocess Nightly (e10s) does not yet support tracking protection. Multiprocessing will be disabled if you restart Firefox. Would you like to continue?";
|
||||
let title = prefBundle.getFormattedString("shouldRestartTitle", [brandName]);
|
||||
let shouldRestart = Services.prompt.confirm(win, title, msg);
|
||||
if (shouldRestart) {
|
||||
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
|
||||
.createInstance(Ci.nsISupportsPRBool);
|
||||
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
|
||||
shouldRestart = !cancelQuit.data;
|
||||
}
|
||||
return shouldRestart;
|
||||
},
|
||||
|
||||
_syncSearchEngines: function () {
|
||||
// Only do this if the search service is already initialized. This function
|
||||
// gets called in finalUIStartup and from a browser-search-service observer,
|
||||
|
@ -4,3 +4,4 @@
|
||||
skip-if = e10s # Bug ?????? - child process crash, but only when run as part of the suite (ie, probably not actually this tests fault!?)
|
||||
|
||||
[browser_polaris_prefs.js]
|
||||
skip-if = e10s # Bug 1089774 - Tracking protection and e10s are incompatible.
|
||||
|
@ -45,7 +45,12 @@ add_task(function* test_changing_pref_changes_tracking() {
|
||||
Services.prefs.setBoolPref(POLARIS_ENABLED, true);
|
||||
yield assertPref(pref, true);
|
||||
Services.prefs.setBoolPref(POLARIS_ENABLED, false);
|
||||
yield assertPref(pref, false);
|
||||
// We don't clear the DNT pref if Polaris is disabled.
|
||||
if (pref != PREF_DNT) {
|
||||
yield assertPref(pref, false);
|
||||
} else {
|
||||
yield assertPref(pref, true);
|
||||
}
|
||||
Services.prefs.setBoolPref(POLARIS_ENABLED, true);
|
||||
yield assertPref(pref, true);
|
||||
}
|
||||
@ -63,8 +68,10 @@ add_task(function* test_prefs_can_be_changed_individually() {
|
||||
Services.prefs.setBoolPref(pref, false);
|
||||
yield assertPref(pref, false);
|
||||
yield assertPref(POLARIS_ENABLED, true);
|
||||
|
||||
Services.prefs.setBoolPref(POLARIS_ENABLED, false);
|
||||
yield assertPref(pref, false);
|
||||
|
||||
Services.prefs.setBoolPref(pref, true);
|
||||
yield assertPref(pref, true);
|
||||
yield assertPref(POLARIS_ENABLED, false);
|
||||
|
@ -19,7 +19,7 @@ window.addEventListener("load", function onLoad() {
|
||||
// Buttons
|
||||
document.querySelector("#close").onclick = CloseUI;
|
||||
document.querySelector("#restore").onclick = RestoreDefaults;
|
||||
document.querySelector("#manageSimulators").onclick = ShowAddons;
|
||||
document.querySelector("#manageComponents").onclick = ShowAddons;
|
||||
|
||||
// Initialize the controls
|
||||
FillForm();
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
<div id="controls">
|
||||
<a id="restore">&prefs_restore;</a>
|
||||
<a id="manageSimulators">&prefs_simulators;</a>
|
||||
<a id="manageComponents">&prefs_manage_components;</a>
|
||||
<a id="close">&deck_close;</a>
|
||||
</div>
|
||||
|
||||
|
@ -68,6 +68,7 @@
|
||||
<menuitem command="cmd_removeProject" accesskey="&projectMenu_remove_accesskey;"/>
|
||||
<menuseparator/>
|
||||
<menuitem command="cmd_showPrefs" label="&projectMenu_showPrefs_label;" accesskey="&projectMenu_showPrefs_accesskey;"/>
|
||||
<menuitem command="cmd_showAddons" label="&projectMenu_manageComponents_label;" accesskey="&projectMenu_manageComponents_accesskey;"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
@ -85,7 +86,6 @@
|
||||
<menu id="menu-view" label="&viewMenu_label;" accesskey="&viewMenu_accesskey;">
|
||||
<menupopup id="menu-ViewPopup">
|
||||
<menuitem command="cmd_toggleEditor" key="key_toggleEditor" accesskey="&viewMenu_toggleEditor_accesskey;"/>
|
||||
<menuitem command="cmd_showAddons" label="&viewMenu_showAddons_label;" accesskey="&viewMenu_showAddons_accesskey;"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
<!ENTITY projectMenu_remove_accesskey "R">
|
||||
<!ENTITY projectMenu_showPrefs_label "Preferences">
|
||||
<!ENTITY projectMenu_showPrefs_accesskey "e">
|
||||
<!ENTITY projectMenu_manageComponents_label "Manage Extra Components">
|
||||
<!ENTITY projectMenu_manageComponents_accesskey "M">
|
||||
|
||||
<!ENTITY runtimeMenu_label "Runtime">
|
||||
<!ENTITY runtimeMenu_accesskey "R">
|
||||
@ -42,8 +44,6 @@
|
||||
<!ENTITY viewMenu_accesskey "V">
|
||||
<!ENTITY viewMenu_toggleEditor_label "Toggle Editor">
|
||||
<!ENTITY viewMenu_toggleEditor_accesskey "E">
|
||||
<!ENTITY viewMenu_showAddons_label "Manage Simulators">
|
||||
<!ENTITY viewMenu_showAddons_accesskey "M">
|
||||
|
||||
<!ENTITY projectButton_label "Open App">
|
||||
<!ENTITY runtimeButton_label "Select Runtime">
|
||||
@ -100,7 +100,7 @@
|
||||
<!ENTITY prefs_editor_title "Editor">
|
||||
<!ENTITY prefs_general_title "General">
|
||||
<!ENTITY prefs_restore "Restore Defaults">
|
||||
<!ENTITY prefs_simulators "Manage Simulators">
|
||||
<!ENTITY prefs_manage_components "Manage Extra Components">
|
||||
<!ENTITY prefs_options_rememberlastproject "Remember last project">
|
||||
<!ENTITY prefs_options_rememberlastproject_tooltip "Restore previous project when WebIDE starts">
|
||||
<!ENTITY prefs_options_templatesurl "Templates URL">
|
||||
|
@ -96,6 +96,7 @@ this.ContentSearch = {
|
||||
addMessageListener(INBOUND_MESSAGE, this);
|
||||
Services.obs.addObserver(this, "browser-search-engine-modified", false);
|
||||
Services.obs.addObserver(this, "shutdown-leaks-before-check", false);
|
||||
this._stringBundle = Services.strings.createBundle("chrome://global/locale/autocomplete.properties");
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
@ -391,8 +392,11 @@ this.ContentSearch = {
|
||||
let favicon = engine.getIconURLBySize(16, 16);
|
||||
let uri1x = engine.getIconURLBySize(65, 26);
|
||||
let uri2x = engine.getIconURLBySize(130, 52);
|
||||
let placeholder = this._stringBundle.formatStringFromName(
|
||||
"searchWithEngine", [engine.name], 1);
|
||||
let obj = {
|
||||
name: engine.name,
|
||||
placeholder: placeholder,
|
||||
iconBuffer: yield this._arrayBufferFromDataURI(favicon),
|
||||
logoBuffer: yield this._arrayBufferFromDataURI(uri1x),
|
||||
logo2xBuffer: yield this._arrayBufferFromDataURI(uri2x),
|
||||
|
@ -388,8 +388,10 @@ let currentEngineObj = Task.async(function* () {
|
||||
let uri1x = engine.getIconURLBySize(65, 26);
|
||||
let uri2x = engine.getIconURLBySize(130, 52);
|
||||
let uriFavicon = engine.getIconURLBySize(16, 16);
|
||||
let bundle = Services.strings.createBundle("chrome://global/locale/autocomplete.properties");
|
||||
return {
|
||||
name: engine.name,
|
||||
placeholder: bundle.formatStringFromName("searchWithEngine", [engine.name], 1),
|
||||
logoBuffer: yield arrayBufferFromDataURI(uri1x),
|
||||
logo2xBuffer: yield arrayBufferFromDataURI(uri2x),
|
||||
iconBuffer: yield arrayBufferFromDataURI(uriFavicon),
|
||||
|
@ -1413,6 +1413,7 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-ic
|
||||
-moz-image-region: rect(0px, 192px, 32px, 160px);
|
||||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-icon,
|
||||
#PanelUI-fxa-status > .toolbarbutton-icon,
|
||||
#PanelUI-quit > .toolbarbutton-icon,
|
||||
#PanelUI-customize > .toolbarbutton-icon,
|
||||
|
@ -22,6 +22,10 @@
|
||||
linear-gradient(rgba(255,255,255,0.3), transparent);
|
||||
}
|
||||
|
||||
#PanelUI-update-status {
|
||||
list-style-image: url(chrome://branding/content/icon32.png);
|
||||
}
|
||||
|
||||
#PanelUI-fxa-status {
|
||||
list-style-image: url(chrome://browser/skin/sync-horizontalbar@2x.png);
|
||||
}
|
||||
|
@ -381,6 +381,7 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"] > iframe {
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-contents-scroller > #PanelUI-contents > .panel-wide-item,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-contents-scroller > #PanelUI-contents > .toolbarbutton-1:not([panel-multiview-anchor="true"]),
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-fxa-status,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-update-status,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > toolbarseparator,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > #PanelUI-customize,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > #PanelUI-help:not([panel-multiview-anchor="true"]) {
|
||||
@ -493,6 +494,7 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#PanelUI-update-status,
|
||||
#PanelUI-help,
|
||||
#PanelUI-fxa-status,
|
||||
#PanelUI-customize,
|
||||
@ -509,12 +511,14 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
-moz-box-orient: horizontal;
|
||||
}
|
||||
|
||||
#PanelUI-update-status,
|
||||
#PanelUI-fxa-status {
|
||||
border-top: 1px solid hsla(210,4%,10%,.14);
|
||||
border-bottom: 1px solid transparent;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-text,
|
||||
#PanelUI-fxa-status > .toolbarbutton-text {
|
||||
width: 0; /* Fancy cropping solution for flexbox. */
|
||||
}
|
||||
@ -524,6 +528,7 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
min-width: 46px;
|
||||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-text,
|
||||
#PanelUI-fxa-status > .toolbarbutton-text,
|
||||
#PanelUI-customize > .toolbarbutton-text {
|
||||
margin: 0;
|
||||
@ -536,6 +541,7 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-icon,
|
||||
#PanelUI-fxa-status > .toolbarbutton-icon,
|
||||
#PanelUI-customize > .toolbarbutton-icon,
|
||||
#PanelUI-help > .toolbarbutton-icon,
|
||||
@ -550,6 +556,16 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
-moz-border-start-style: none;
|
||||
}
|
||||
|
||||
#PanelUI-update-status {
|
||||
width: calc(@menuPanelWidth@ + 30px);
|
||||
-moz-padding-start: 15px;
|
||||
-moz-border-start-style: none;
|
||||
}
|
||||
|
||||
#PanelUI-update-status {
|
||||
list-style-image: url(chrome://branding/content/icon16.png);
|
||||
}
|
||||
|
||||
#PanelUI-fxa-status {
|
||||
list-style-image: url(chrome://browser/skin/sync-horizontalbar.png);
|
||||
}
|
||||
@ -625,6 +641,32 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="succeeded"] {
|
||||
background-color: hsla(96, 65%, 75%, 0.1);
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="succeeded"]:not([disabled]):hover {
|
||||
background-color: hsla(96, 65%, 75%, 0.4);
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="succeeded"]:not([disabled]):hover:active {
|
||||
background-color: hsla(96, 65%, 75%, 0.6);
|
||||
box-shadow: 0 1px 0 hsla(210,4%,10%,.05) inset;
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="failed"] {
|
||||
background-color: hsla(359, 69%, 84%, 0.1);
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="failed"]:not([disabled]):hover {
|
||||
background-color: hsla(359, 69%, 84%, 0.4);
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status="failed"]:not([disabled]):hover:active {
|
||||
background-color: hsla(359, 69%, 84%, 0.6);
|
||||
box-shadow: 0 1px 0 hsla(210,4%,10%,.05) inset;
|
||||
}
|
||||
|
||||
#PanelUI-quit:not([disabled]):hover {
|
||||
background-color: #d94141;
|
||||
outline-color: #c23a3a;
|
||||
|
@ -412,26 +412,6 @@ case "$target" in
|
||||
;;
|
||||
esac
|
||||
|
||||
MOZ_ARG_DISABLE_BOOL(android-include-fonts,
|
||||
[ --disable-android-include-fonts
|
||||
disable the inclusion of fonts into the final APK],
|
||||
MOZ_ANDROID_EXCLUDE_FONTS=1)
|
||||
|
||||
if test -n "$MOZ_ANDROID_EXCLUDE_FONTS"; then
|
||||
AC_DEFINE(MOZ_ANDROID_EXCLUDE_FONTS, $MOZ_ANDROID_EXCLUDE_FONTS)
|
||||
AC_SUBST(MOZ_ANDROID_EXCLUDE_FONTS)
|
||||
fi
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(android-resource-constrained,
|
||||
[ --enable-android-resource-constrained
|
||||
exclude hi-res images and similar from the final APK],
|
||||
MOZ_ANDROID_RESOURCE_CONSTRAINED=1)
|
||||
|
||||
if test -n "$MOZ_ANDROID_RESOURCE_CONSTRAINED"; then
|
||||
AC_DEFINE(MOZ_ANDROID_RESOURCE_CONSTRAINED, $MOZ_ANDROID_RESOURCE_CONSTRAINED)
|
||||
AC_SUBST(MOZ_ANDROID_RESOURCE_CONSTRAINED)
|
||||
fi
|
||||
|
||||
MOZ_ARG_WITH_STRING(android-min-sdk,
|
||||
[ --with-android-min-sdk=[VER] Impose a minimum Firefox for Android SDK version],
|
||||
[ MOZ_ANDROID_MIN_SDK_VERSION=$withval ])
|
||||
|
24
configure.in
24
configure.in
@ -4094,6 +4094,30 @@ fi
|
||||
AC_SUBST(MOZ_BING_API_CLIENTID)
|
||||
AC_SUBST(MOZ_BING_API_KEY)
|
||||
|
||||
# Whether to include optional-but-large font files in the final APK.
|
||||
# We want this in mobile/android/confvars.sh, so it goes early.
|
||||
MOZ_ARG_DISABLE_BOOL(android-include-fonts,
|
||||
[ --disable-android-include-fonts
|
||||
Disable the inclusion of fonts into the final APK],
|
||||
MOZ_ANDROID_EXCLUDE_FONTS=1)
|
||||
|
||||
if test -n "$MOZ_ANDROID_EXCLUDE_FONTS"; then
|
||||
AC_DEFINE(MOZ_ANDROID_EXCLUDE_FONTS)
|
||||
fi
|
||||
AC_SUBST(MOZ_ANDROID_EXCLUDE_FONTS)
|
||||
|
||||
# Whether this APK is destined for resource constrained devices.
|
||||
# We want this in mobile/android/confvars.sh, so it goes early.
|
||||
MOZ_ARG_ENABLE_BOOL(android-resource-constrained,
|
||||
[ --enable-android-resource-constrained
|
||||
Exclude hi-res images and similar from the final APK],
|
||||
MOZ_ANDROID_RESOURCE_CONSTRAINED=1)
|
||||
|
||||
if test -n "$MOZ_ANDROID_RESOURCE_CONSTRAINED"; then
|
||||
AC_DEFINE(MOZ_ANDROID_RESOURCE_CONSTRAINED)
|
||||
fi
|
||||
AC_SUBST(MOZ_ANDROID_RESOURCE_CONSTRAINED)
|
||||
|
||||
# Allow the application to influence configure with a confvars.sh script.
|
||||
AC_MSG_CHECKING([if app-specific confvars.sh exists])
|
||||
if test -f "${srcdir}/${MOZ_BUILD_APP}/confvars.sh" ; then
|
||||
|
@ -48,6 +48,25 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
private MirrorChannel mMirrorChannel;
|
||||
private boolean mApplicationStarted = false;
|
||||
|
||||
// EventCallback which is actually a GeckoEventCallback is sometimes being invoked more
|
||||
// than once. That causes the IllegalStateException to be thrown. To prevent a crash,
|
||||
// catch the exception and report it as an error to the log.
|
||||
private static void sendSuccess(final EventCallback callback, final String msg) {
|
||||
try {
|
||||
callback.sendSuccess(msg);
|
||||
} catch (final IllegalStateException e) {
|
||||
Log.e(LOGTAG, "Attempting to invoke callback.sendSuccess more than once.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendError(final EventCallback callback, final String msg) {
|
||||
try {
|
||||
callback.sendError(msg);
|
||||
} catch (final IllegalStateException e) {
|
||||
Log.e(LOGTAG, "Attempting to invoke callback.sendError more than once.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Callback to start playback of a url on a remote device
|
||||
private class VideoPlayCallback implements ResultCallback<ApplicationConnectionResult>,
|
||||
RemoteMediaPlayer.OnStatusUpdatedListener,
|
||||
@ -101,7 +120,7 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
|
||||
startPlayback();
|
||||
} else {
|
||||
callback.sendError(status.toString());
|
||||
sendError(callback, status.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,13 +137,13 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
@Override
|
||||
public void onResult(MediaChannelResult result) {
|
||||
if (result.getStatus().isSuccess()) {
|
||||
callback.sendSuccess(null);
|
||||
sendSuccess(callback, null);
|
||||
debug("Media loaded successfully");
|
||||
return;
|
||||
}
|
||||
|
||||
debug("Media load failed " + result.getStatus());
|
||||
callback.sendError(result.getStatus().toString());
|
||||
sendError(callback, result.getStatus().toString());
|
||||
}
|
||||
});
|
||||
|
||||
@ -135,7 +154,7 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
debug("Problem opening media during loading", e);
|
||||
}
|
||||
|
||||
callback.sendError("");
|
||||
sendError(callback, "");
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,7 +217,7 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
// Sometimes apiClient is null here. See bug 1061032
|
||||
if (apiClient != null && !apiClient.isConnected()) {
|
||||
debug("Connection failed");
|
||||
callback.sendError("Not connected");
|
||||
sendError(callback, "Not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -223,13 +242,13 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
@Override
|
||||
public void start(final EventCallback callback) {
|
||||
// Nothing to be done here
|
||||
callback.sendSuccess(null);
|
||||
sendSuccess(callback, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(final EventCallback callback) {
|
||||
// Nothing to be done here
|
||||
callback.sendSuccess(null);
|
||||
sendSuccess(callback, null);
|
||||
}
|
||||
|
||||
public boolean verifySession(final EventCallback callback) {
|
||||
@ -245,7 +264,7 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
if (msg != null) {
|
||||
debug(msg);
|
||||
if (callback != null) {
|
||||
callback.sendError(msg);
|
||||
sendError(callback, msg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -266,15 +285,15 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
Status status = result.getStatus();
|
||||
if (!status.isSuccess()) {
|
||||
debug("Unable to play: " + status.getStatusCode());
|
||||
callback.sendError(status.toString());
|
||||
sendError(callback, status.toString());
|
||||
} else {
|
||||
callback.sendSuccess(null);
|
||||
sendSuccess(callback, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch(IllegalStateException ex) {
|
||||
// The media player may throw if the session has been killed. For now, we're just catching this here.
|
||||
callback.sendError("Error playing");
|
||||
sendError(callback, "Error playing");
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,15 +310,15 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
Status status = result.getStatus();
|
||||
if (!status.isSuccess()) {
|
||||
debug("Unable to pause: " + status.getStatusCode());
|
||||
callback.sendError(status.toString());
|
||||
sendError(callback, status.toString());
|
||||
} else {
|
||||
callback.sendSuccess(null);
|
||||
sendSuccess(callback, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch(IllegalStateException ex) {
|
||||
// The media player may throw if the session has been killed. For now, we're just catching this here.
|
||||
callback.sendError("Error pausing");
|
||||
sendError(callback, "Error pausing");
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,7 +341,7 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
apiClient = null;
|
||||
|
||||
if (callback != null) {
|
||||
callback.sendSuccess(null);
|
||||
sendSuccess(callback, null);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -332,13 +351,13 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
}
|
||||
|
||||
if (callback != null) {
|
||||
callback.sendError(result.getStatus().toString());
|
||||
sendError(callback, result.getStatus().toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch(IllegalStateException ex) {
|
||||
// The media player may throw if the session has been killed. For now, we're just catching this here.
|
||||
callback.sendError("Error stopping");
|
||||
sendError(callback, "Error stopping");
|
||||
}
|
||||
}
|
||||
|
||||
@ -376,9 +395,7 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
}
|
||||
}
|
||||
private class MirrorCallback implements ResultCallback<ApplicationConnectionResult> {
|
||||
// See Bug 1055562, callback is set to null after it has been
|
||||
// invoked so that it will not be called a second time.
|
||||
EventCallback callback;
|
||||
final EventCallback callback;
|
||||
MirrorCallback(final EventCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
@ -386,10 +403,6 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
|
||||
@Override
|
||||
public void onResult(ApplicationConnectionResult result) {
|
||||
if (callback == null) {
|
||||
Log.e(LOGTAG, "Attempting to invoke MirrorChannel callback more than once.");
|
||||
return;
|
||||
}
|
||||
Status status = result.getStatus();
|
||||
if (status.isSuccess()) {
|
||||
ApplicationMetadata applicationMetadata = result.getApplicationMetadata();
|
||||
@ -406,16 +419,14 @@ class ChromeCast implements GeckoMediaPlayer {
|
||||
mMirrorChannel
|
||||
.getNamespace(),
|
||||
mMirrorChannel);
|
||||
callback.sendSuccess(null);
|
||||
callback = null;
|
||||
sendSuccess(callback, null);
|
||||
} catch (IOException e) {
|
||||
Log.e(LOGTAG, "Exception while creating channel", e);
|
||||
}
|
||||
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Casting:Mirror", route.getId()));
|
||||
} else {
|
||||
callback.sendError(status.toString());
|
||||
callback = null;
|
||||
sendError(callback, status.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,15 @@ var WebcompatReporter = {
|
||||
menuItemEnabled: null,
|
||||
init: function() {
|
||||
Services.obs.addObserver(this, "DesktopMode:Change", false);
|
||||
Services.obs.addObserver(this, "content-page-shown", false);
|
||||
Services.obs.addObserver(this, "chrome-document-global-created", false);
|
||||
Services.obs.addObserver(this, "content-document-global-created", false);
|
||||
this.addMenuItem();
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
Services.obs.removeObserver(this, "DesktopMode:Change");
|
||||
Services.obs.removeObserver(this, "chrome-document-global-created");
|
||||
Services.obs.removeObserver(this, "content-document-global-created");
|
||||
|
||||
if (this.menuItem) {
|
||||
NativeWindow.menu.remove(this.menuItem);
|
||||
@ -27,8 +30,15 @@ var WebcompatReporter = {
|
||||
},
|
||||
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic === "content-page-shown") {
|
||||
let currentURI = subject.documentURI;
|
||||
if (topic == "content-document-global-created" || topic == "chrome-document-global-created") {
|
||||
let win = subject;
|
||||
let currentURI = win.document.documentURI;
|
||||
|
||||
// Ignore non top-level documents
|
||||
if (currentURI !== win.top.location.href) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.menuItemEnabled && this.isReportableUrl(currentURI)) {
|
||||
NativeWindow.menu.update(this.menuItem, {enabled: true});
|
||||
this.menuItemEnabled = true;
|
||||
|
@ -66,8 +66,11 @@ MOZ_LOCALE_SWITCHER=1
|
||||
# Enable second screen and casting support for external devices.
|
||||
MOZ_DEVICES=1
|
||||
|
||||
# Enable second screen using native Android libraries
|
||||
MOZ_NATIVE_DEVICES=1
|
||||
# Enable second screen using native Android libraries, provided we're
|
||||
# not resource constrained.
|
||||
if test -z "$MOZ_ANDROID_RESOURCE_CONSTRAINED"; then
|
||||
MOZ_NATIVE_DEVICES=1
|
||||
fi
|
||||
|
||||
# Mark as WebGL conformant
|
||||
MOZ_WEBGL_CONFORMANT=1
|
||||
|
@ -30,7 +30,7 @@
|
||||
@BINPATH@/dictionaries/*
|
||||
@BINPATH@/hyphenation/*
|
||||
|
||||
[assets destdir="assets"]
|
||||
[assets destdir="assets/@ANDROID_CPU_ARCH@"]
|
||||
#ifndef MOZ_STATIC_JS
|
||||
@BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@
|
||||
#endif
|
||||
|
@ -219,8 +219,8 @@ loadGeckoLibs(const char *apkName)
|
||||
|
||||
RefPtr<Zip> zip = ZipCollection::GetZip(apkName);
|
||||
|
||||
char *file = new char[strlen(apkName) + sizeof("!/assets/libxul.so")];
|
||||
sprintf(file, "%s!/assets/libxul.so", apkName);
|
||||
char *file = new char[strlen(apkName) + sizeof("!/assets/" ANDROID_CPU_ARCH "/libxul.so")];
|
||||
sprintf(file, "%s!/assets/" ANDROID_CPU_ARCH "/libxul.so", apkName);
|
||||
xul_handle = __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
|
||||
delete[] file;
|
||||
|
||||
@ -278,8 +278,8 @@ loadSQLiteLibs(const char *apkName)
|
||||
lib_mapping = (struct mapping_info *)calloc(MAX_MAPPING_INFO, sizeof(*lib_mapping));
|
||||
}
|
||||
|
||||
char *file = new char[strlen(apkName) + sizeof("!/assets/libmozsqlite3.so")];
|
||||
sprintf(file, "%s!/assets/libmozsqlite3.so", apkName);
|
||||
char *file = new char[strlen(apkName) + sizeof("!/assets/" ANDROID_CPU_ARCH "/libmozsqlite3.so")];
|
||||
sprintf(file, "%s!/assets/" ANDROID_CPU_ARCH "/libmozsqlite3.so", apkName);
|
||||
sqlite_handle = __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
|
||||
delete [] file;
|
||||
|
||||
@ -306,19 +306,19 @@ loadNSSLibs(const char *apkName)
|
||||
lib_mapping = (struct mapping_info *)calloc(MAX_MAPPING_INFO, sizeof(*lib_mapping));
|
||||
}
|
||||
|
||||
char *file = new char[strlen(apkName) + sizeof("!/assets/libnss3.so")];
|
||||
sprintf(file, "%s!/assets/libnss3.so", apkName);
|
||||
char *file = new char[strlen(apkName) + sizeof("!/assets/" ANDROID_CPU_ARCH "/libnss3.so")];
|
||||
sprintf(file, "%s!/assets/" ANDROID_CPU_ARCH "/libnss3.so", apkName);
|
||||
nss_handle = __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
|
||||
delete [] file;
|
||||
|
||||
#ifndef MOZ_FOLD_LIBS
|
||||
file = new char[strlen(apkName) + sizeof("!/assets/libnspr4.so")];
|
||||
sprintf(file, "%s!/assets/libnspr4.so", apkName);
|
||||
file = new char[strlen(apkName) + sizeof("!/assets/" ANDROID_CPU_ARCH "/libnspr4.so")];
|
||||
sprintf(file, "%s!/assets/" ANDROID_CPU_ARCH "/libnspr4.so", apkName);
|
||||
nspr_handle = __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
|
||||
delete [] file;
|
||||
|
||||
file = new char[strlen(apkName) + sizeof("!/assets/libplc4.so")];
|
||||
sprintf(file, "%s!/assets/libplc4.so", apkName);
|
||||
file = new char[strlen(apkName) + sizeof("!/assets/" ANDROID_CPU_ARCH "/libplc4.so")];
|
||||
sprintf(file, "%s!/assets/" ANDROID_CPU_ARCH "/libplc4.so", apkName);
|
||||
plc_handle = __wrap_dlopen(file, RTLD_GLOBAL | RTLD_LAZY);
|
||||
delete [] file;
|
||||
#endif
|
||||
|
@ -21,7 +21,9 @@ FAIL_ON_WARNINGS = True
|
||||
|
||||
FINAL_LIBRARY = 'mozglue'
|
||||
|
||||
DEFINES['ANDROID_PACKAGE_NAME'] = '"%s"' % CONFIG['ANDROID_PACKAGE_NAME']
|
||||
for var in ('ANDROID_PACKAGE_NAME',
|
||||
'ANDROID_CPU_ARCH'):
|
||||
DEFINES[var] = '"%s"' % CONFIG[var]
|
||||
|
||||
if CONFIG['MOZ_FOLD_LIBS']:
|
||||
DEFINES['MOZ_FOLD_LIBS'] = True
|
||||
|
@ -31,12 +31,13 @@
|
||||
#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef __BIONIC_UCONTEXT_H
|
||||
#include <ucontext.h>
|
||||
#ifdef __BIONIC_HAVE_UCONTEXT_H
|
||||
# include_next <ucontext.h>
|
||||
#else
|
||||
|
||||
#include <sys/ucontext.h>
|
||||
# include <sys/ucontext.h>
|
||||
#endif // __BIONIC_UCONTEXT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -51,6 +52,4 @@ int breakpad_getcontext(ucontext_t* ucp);
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __BIONIC_UCONTEXT_H
|
||||
|
||||
#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H
|
||||
|
@ -266,7 +266,6 @@ this.DebuggerClient = function (aTransport)
|
||||
this._activeRequests = new Map;
|
||||
this._eventsEnabled = true;
|
||||
|
||||
this.compat = new ProtocolCompatibility(this, []);
|
||||
this.traits = {};
|
||||
|
||||
this.request = this.request.bind(this);
|
||||
@ -858,81 +857,73 @@ DebuggerClient.prototype = {
|
||||
*
|
||||
* @param aPacket object
|
||||
* The incoming packet.
|
||||
* @param aIgnoreCompatibility boolean
|
||||
* Set true to not pass the packet through the compatibility layer.
|
||||
*/
|
||||
onPacket: function (aPacket, aIgnoreCompatibility=false) {
|
||||
let packet = aIgnoreCompatibility
|
||||
? aPacket
|
||||
: this.compat.onPacket(aPacket);
|
||||
onPacket: function (aPacket) {
|
||||
if (!aPacket.from) {
|
||||
DevToolsUtils.reportException(
|
||||
"onPacket",
|
||||
new Error("Server did not specify an actor, dropping packet: " +
|
||||
JSON.stringify(aPacket)));
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(packet).then(aPacket => {
|
||||
if (!aPacket.from) {
|
||||
DevToolsUtils.reportException(
|
||||
"onPacket",
|
||||
new Error("Server did not specify an actor, dropping packet: " +
|
||||
JSON.stringify(aPacket)));
|
||||
// If we have a registered Front for this actor, let it handle the packet
|
||||
// and skip all the rest of this unpleasantness.
|
||||
let front = this.getActor(aPacket.from);
|
||||
if (front) {
|
||||
front.onPacket(aPacket);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._clients.has(aPacket.from) && aPacket.type) {
|
||||
let client = this._clients.get(aPacket.from);
|
||||
let type = aPacket.type;
|
||||
if (client.events.indexOf(type) != -1) {
|
||||
client.emit(type, aPacket);
|
||||
// we ignore the rest, as the client is expected to handle this packet.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a registered Front for this actor, let it handle the packet
|
||||
// and skip all the rest of this unpleasantness.
|
||||
let front = this.getActor(aPacket.from);
|
||||
if (front) {
|
||||
front.onPacket(aPacket);
|
||||
return;
|
||||
}
|
||||
let activeRequest;
|
||||
// See if we have a handler function waiting for a reply from this
|
||||
// actor. (Don't count unsolicited notifications or pauses as
|
||||
// replies.)
|
||||
if (this._activeRequests.has(aPacket.from) &&
|
||||
!(aPacket.type in UnsolicitedNotifications) &&
|
||||
!(aPacket.type == ThreadStateTypes.paused &&
|
||||
aPacket.why.type in UnsolicitedPauses)) {
|
||||
activeRequest = this._activeRequests.get(aPacket.from);
|
||||
this._activeRequests.delete(aPacket.from);
|
||||
}
|
||||
|
||||
if (this._clients.has(aPacket.from) && aPacket.type) {
|
||||
let client = this._clients.get(aPacket.from);
|
||||
let type = aPacket.type;
|
||||
if (client.events.indexOf(type) != -1) {
|
||||
client.emit(type, aPacket);
|
||||
// we ignore the rest, as the client is expected to handle this packet.
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Packets that indicate thread state changes get special treatment.
|
||||
if (aPacket.type in ThreadStateTypes &&
|
||||
this._clients.has(aPacket.from) &&
|
||||
typeof this._clients.get(aPacket.from)._onThreadState == "function") {
|
||||
this._clients.get(aPacket.from)._onThreadState(aPacket);
|
||||
}
|
||||
// On navigation the server resumes, so the client must resume as well.
|
||||
// We achieve that by generating a fake resumption packet that triggers
|
||||
// the client's thread state change listeners.
|
||||
if (aPacket.type == UnsolicitedNotifications.tabNavigated &&
|
||||
this._clients.has(aPacket.from) &&
|
||||
this._clients.get(aPacket.from).thread) {
|
||||
let thread = this._clients.get(aPacket.from).thread;
|
||||
let resumption = { from: thread._actor, type: "resumed" };
|
||||
thread._onThreadState(resumption);
|
||||
}
|
||||
// Only try to notify listeners on events, not responses to requests
|
||||
// that lack a packet type.
|
||||
if (aPacket.type) {
|
||||
this.emit(aPacket.type, aPacket);
|
||||
}
|
||||
|
||||
let activeRequest;
|
||||
// See if we have a handler function waiting for a reply from this
|
||||
// actor. (Don't count unsolicited notifications or pauses as
|
||||
// replies.)
|
||||
if (this._activeRequests.has(aPacket.from) &&
|
||||
!(aPacket.type in UnsolicitedNotifications) &&
|
||||
!(aPacket.type == ThreadStateTypes.paused &&
|
||||
aPacket.why.type in UnsolicitedPauses)) {
|
||||
activeRequest = this._activeRequests.get(aPacket.from);
|
||||
this._activeRequests.delete(aPacket.from);
|
||||
}
|
||||
if (activeRequest) {
|
||||
activeRequest.emit("json-reply", aPacket);
|
||||
}
|
||||
|
||||
// Packets that indicate thread state changes get special treatment.
|
||||
if (aPacket.type in ThreadStateTypes &&
|
||||
this._clients.has(aPacket.from) &&
|
||||
typeof this._clients.get(aPacket.from)._onThreadState == "function") {
|
||||
this._clients.get(aPacket.from)._onThreadState(aPacket);
|
||||
}
|
||||
// On navigation the server resumes, so the client must resume as well.
|
||||
// We achieve that by generating a fake resumption packet that triggers
|
||||
// the client's thread state change listeners.
|
||||
if (aPacket.type == UnsolicitedNotifications.tabNavigated &&
|
||||
this._clients.has(aPacket.from) &&
|
||||
this._clients.get(aPacket.from).thread) {
|
||||
let thread = this._clients.get(aPacket.from).thread;
|
||||
let resumption = { from: thread._actor, type: "resumed" };
|
||||
thread._onThreadState(resumption);
|
||||
}
|
||||
// Only try to notify listeners on events, not responses to requests
|
||||
// that lack a packet type.
|
||||
if (aPacket.type) {
|
||||
this.emit(aPacket.type, aPacket);
|
||||
}
|
||||
|
||||
if (activeRequest) {
|
||||
activeRequest.emit("json-reply", aPacket);
|
||||
}
|
||||
|
||||
this._sendRequests();
|
||||
}, ex => DevToolsUtils.reportException("onPacket handler", ex));
|
||||
this._sendRequests();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1096,156 +1087,6 @@ Request.prototype = {
|
||||
|
||||
};
|
||||
|
||||
// Constants returned by `FeatureCompatibilityShim.onPacketTest`.
|
||||
const SUPPORTED = 1;
|
||||
const NOT_SUPPORTED = 2;
|
||||
const SKIP = 3;
|
||||
|
||||
/**
|
||||
* This object provides an abstraction layer over all of our backwards
|
||||
* compatibility, feature detection, and shimming with regards to the remote
|
||||
* debugging prototcol.
|
||||
*
|
||||
* @param aFeatures Array
|
||||
* An array of FeatureCompatibilityShim objects
|
||||
*/
|
||||
function ProtocolCompatibility(aClient, aFeatures) {
|
||||
this._client = aClient;
|
||||
this._featuresWithUnknownSupport = new Set(aFeatures);
|
||||
this._featuresWithoutSupport = new Set();
|
||||
|
||||
this._featureDeferreds = Object.create(null)
|
||||
for (let f of aFeatures) {
|
||||
this._featureDeferreds[f.name] = defer();
|
||||
}
|
||||
}
|
||||
|
||||
ProtocolCompatibility.prototype = {
|
||||
/**
|
||||
* Returns a promise that resolves to true if the RDP supports the feature,
|
||||
* and is rejected otherwise.
|
||||
*
|
||||
* @param aFeatureName String
|
||||
* The name of the feature we are testing.
|
||||
*/
|
||||
supportsFeature: function (aFeatureName) {
|
||||
return this._featureDeferreds[aFeatureName].promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Force a feature to be considered unsupported.
|
||||
*
|
||||
* @param aFeatureName String
|
||||
* The name of the feature we are testing.
|
||||
*/
|
||||
rejectFeature: function (aFeatureName) {
|
||||
this._featureDeferreds[aFeatureName].reject(false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called for each packet received over the RDP from the server. Tests for
|
||||
* protocol features and shims packets to support needed features.
|
||||
*
|
||||
* @param aPacket Object
|
||||
* Packet received over the RDP from the server.
|
||||
*/
|
||||
onPacket: function (aPacket) {
|
||||
this._detectFeatures(aPacket);
|
||||
return this._shimPacket(aPacket);
|
||||
},
|
||||
|
||||
/**
|
||||
* For each of the features we don't know whether the server supports or not,
|
||||
* attempt to detect support based on the packet we just received.
|
||||
*/
|
||||
_detectFeatures: function (aPacket) {
|
||||
for (let feature of this._featuresWithUnknownSupport) {
|
||||
try {
|
||||
switch (feature.onPacketTest(aPacket)) {
|
||||
case SKIP:
|
||||
break;
|
||||
case SUPPORTED:
|
||||
this._featuresWithUnknownSupport.delete(feature);
|
||||
this._featureDeferreds[feature.name].resolve(true);
|
||||
break;
|
||||
case NOT_SUPPORTED:
|
||||
this._featuresWithUnknownSupport.delete(feature);
|
||||
this._featuresWithoutSupport.add(feature);
|
||||
this.rejectFeature(feature.name);
|
||||
break;
|
||||
default:
|
||||
DevToolsUtils.reportException(
|
||||
"PC__detectFeatures",
|
||||
new Error("Bad return value from `onPacketTest` for feature '"
|
||||
+ feature.name + "'"));
|
||||
}
|
||||
} catch (ex) {
|
||||
DevToolsUtils.reportException("PC__detectFeatures", ex);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Go through each of the features that we know are unsupported by the current
|
||||
* server and attempt to shim support.
|
||||
*/
|
||||
_shimPacket: function (aPacket) {
|
||||
let extraPackets = [];
|
||||
|
||||
let loop = (aFeatures, aPacket) => {
|
||||
if (aFeatures.length === 0) {
|
||||
for (let packet of extraPackets) {
|
||||
this._client.onPacket(packet, true);
|
||||
}
|
||||
return aPacket;
|
||||
} else {
|
||||
let replacePacket = function (aNewPacket) {
|
||||
return aNewPacket;
|
||||
};
|
||||
let extraPacket = function (aExtraPacket) {
|
||||
extraPackets.push(aExtraPacket);
|
||||
return aPacket;
|
||||
};
|
||||
let keepPacket = function () {
|
||||
return aPacket;
|
||||
};
|
||||
let newPacket = aFeatures[0].translatePacket(aPacket,
|
||||
replacePacket,
|
||||
extraPacket,
|
||||
keepPacket);
|
||||
return resolve(newPacket).then(loop.bind(null, aFeatures.slice(1)));
|
||||
}
|
||||
};
|
||||
|
||||
return loop([f for (f of this._featuresWithoutSupport)],
|
||||
aPacket);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface defining what methods a feature compatibility shim should have.
|
||||
*/
|
||||
const FeatureCompatibilityShim = {
|
||||
// The name of the feature
|
||||
name: null,
|
||||
|
||||
/**
|
||||
* Takes a packet and returns boolean (or promise of boolean) indicating
|
||||
* whether the server supports the RDP feature we are possibly shimming.
|
||||
*/
|
||||
onPacketTest: function (aPacket) {
|
||||
throw new Error("Not yet implemented");
|
||||
},
|
||||
|
||||
/**
|
||||
* Takes a packet actually sent from the server and decides whether to replace
|
||||
* it with a new packet, create an extra packet, or keep it.
|
||||
*/
|
||||
translatePacket: function (aPacket, aReplacePacket, aExtraPacket, aKeepPacket) {
|
||||
throw new Error("Not yet implemented");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a tab client for the remote debugging protocol server. This client
|
||||
* is a front to the tab actor created in the server side, hiding the protocol
|
||||
@ -1503,7 +1344,6 @@ ThreadClient.prototype = {
|
||||
_actor: null,
|
||||
get actor() { return this._actor; },
|
||||
|
||||
get compat() { return this.client.compat; },
|
||||
get _transport() { return this.client._transport; },
|
||||
|
||||
_assertPaused: function (aCommand) {
|
||||
|
@ -272,7 +272,7 @@ PendingErrors.addObserver(function(details) {
|
||||
}
|
||||
error.init(
|
||||
/*message*/ generalDescription +
|
||||
"Date: " + details.date + "\nFull Message: " + details.message,
|
||||
"Date: " + details.date + "\nFull Message: " + message,
|
||||
/*sourceName*/ details.fileName,
|
||||
/*sourceLine*/ details.lineNumber?("" + details.lineNumber):0,
|
||||
/*lineNumber*/ details.lineNumber || 0,
|
||||
|
@ -380,14 +380,15 @@ DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so \
|
||||
endif
|
||||
|
||||
SO_LIBRARIES := $(filter %.so,$(DIST_FILES))
|
||||
# These libraries are placed in the assets/ directory by packager.py.
|
||||
ASSET_SO_LIBRARIES := $(addprefix assets/,$(filter-out libmozglue.so $(MOZ_CHILD_PROCESS_NAME),$(SO_LIBRARIES)))
|
||||
# These libraries are placed in the assets/$(ANDROID_CPU_ARCH) directory by packager.py.
|
||||
ASSET_SO_LIBRARIES := $(addprefix assets/$(ANDROID_CPU_ARCH)/,$(filter-out libmozglue.so $(MOZ_CHILD_PROCESS_NAME),$(SO_LIBRARIES)))
|
||||
|
||||
DIST_FILES := $(filter-out $(SO_LIBRARIES),$(DIST_FILES))
|
||||
NON_DIST_FILES += libmozglue.so $(MOZ_CHILD_PROCESS_NAME) $(ASSET_SO_LIBRARIES)
|
||||
|
||||
ifdef MOZ_ENABLE_SZIP
|
||||
# These libraries are szipped in-place in the assets/ directory.
|
||||
# These libraries are szipped in-place in the
|
||||
# assets/$(ANDROID_CPU_ARCH) directory.
|
||||
SZIP_LIBRARIES := $(ASSET_SO_LIBRARIES)
|
||||
endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user