зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to fx-team
This commit is contained in:
Коммит
0ad19c5f56
|
@ -360,6 +360,7 @@ pref("browser.dom.window.dump.enabled", false);
|
|||
|
||||
// Default Content Security Policy to apply to privileged and certified apps
|
||||
pref("security.apps.privileged.CSP.default", "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'");
|
||||
// If you change this CSP, make sure to update the fast path in nsCSPService.cpp
|
||||
pref("security.apps.certified.CSP.default", "default-src *; script-src 'self'; object-src 'none'; style-src 'self'");
|
||||
|
||||
// Temporarily force-enable GL compositing. This is default-disabled
|
||||
|
@ -388,9 +389,6 @@ pref("dom.ipc.browser_frames.oop_by_default", false);
|
|||
|
||||
// SMS/MMS
|
||||
pref("dom.sms.enabled", true);
|
||||
pref("dom.sms.strict7BitEncoding", false); // Disabled by default.
|
||||
pref("dom.sms.requestStatusReport", true); // Enabled by default.
|
||||
pref("dom.mms.requestStatusReport", true); // Enabled by default.
|
||||
|
||||
//The waiting time in network manager.
|
||||
pref("network.gonk.ms-release-mms-connection", 30000);
|
||||
|
@ -434,7 +432,6 @@ pref("services.push.udp.wakeupEnabled", true);
|
|||
// NetworkStats
|
||||
#ifdef MOZ_B2G_RIL
|
||||
pref("dom.mozNetworkStats.enabled", true);
|
||||
pref("ril.cellbroadcast.disabled", false);
|
||||
pref("dom.webapps.firstRunWithSIM", true);
|
||||
#endif
|
||||
|
||||
|
@ -730,10 +727,6 @@ pref("font.size.inflation.disabledInMasterProcess", true);
|
|||
// consumption when applications are sent to the background.
|
||||
pref("memory.free_dirty_pages", true);
|
||||
|
||||
// UAProfile settings
|
||||
pref("wap.UAProf.url", "");
|
||||
pref("wap.UAProf.tagname", "x-wap-profile");
|
||||
|
||||
pref("layout.imagevisibility.enabled", false);
|
||||
pref("layout.imagevisibility.numscrollportwidths", 1);
|
||||
pref("layout.imagevisibility.numscrollportheights", 1);
|
||||
|
@ -824,6 +817,19 @@ pref("gfx.canvas.azure.accelerated", true);
|
|||
// Enable Telephony API
|
||||
pref("dom.telephony.enabled", true);
|
||||
|
||||
// Cell Broadcast API
|
||||
pref("dom.cellbroadcast.enabled", true);
|
||||
pref("ril.cellbroadcast.disabled", false);
|
||||
|
||||
// ICC API
|
||||
pref("dom.icc.enabled", true);
|
||||
|
||||
// Mobile Connection API
|
||||
pref("dom.mobileconnection.enabled", true);
|
||||
|
||||
// Voice Mail API
|
||||
pref("dom.voicemail.enabled", true);
|
||||
|
||||
// The url of the page used to display network error details.
|
||||
pref("b2g.neterror.url", "app://system.gaiamobile.org/net_error.html");
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"revision": "563d1aa93586165246ab2ab9d40566a598f56387",
|
||||
"revision": "154bb18c48ff06e41fb7ba24d8f72d520919646f",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
],
|
||||
"env": {
|
||||
"VARIANT": "user",
|
||||
"MOZILLA_OFFICIAL": "1",
|
||||
"B2GUPDATER": "1"
|
||||
"MOZILLA_OFFICIAL": "1"
|
||||
},
|
||||
"b2g_manifest": "hamachi.xml",
|
||||
"b2g_manifest_branch": "master",
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
"env": {
|
||||
"VARIANT": "user",
|
||||
"MOZILLA_OFFICIAL": "1",
|
||||
"B2GUPDATER": "1",
|
||||
"ANDROIDFS_DIR": "{workdir}/helix-ics"
|
||||
},
|
||||
"b2g_manifest": "helix.xml",
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
],
|
||||
"env": {
|
||||
"VARIANT": "user",
|
||||
"MOZILLA_OFFICIAL": "1",
|
||||
"B2GUPDATER": "1"
|
||||
"MOZILLA_OFFICIAL": "1"
|
||||
},
|
||||
"b2g_manifest": "inari.xml",
|
||||
"b2g_manifest_branch": "master",
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
],
|
||||
"env": {
|
||||
"VARIANT": "user",
|
||||
"MOZILLA_OFFICIAL": "1",
|
||||
"B2GUPDATER": "1"
|
||||
"MOZILLA_OFFICIAL": "1"
|
||||
},
|
||||
"b2g_manifest": "leo.xml",
|
||||
"b2g_manifest_branch": "master",
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
],
|
||||
"env": {
|
||||
"VARIANT": "user",
|
||||
"MOZILLA_OFFICIAL": "1",
|
||||
"B2GUPDATER": "1"
|
||||
"MOZILLA_OFFICIAL": "1"
|
||||
},
|
||||
"b2g_manifest": "nexus-4.xml",
|
||||
"b2g_manifest_branch": "master",
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
],
|
||||
"env": {
|
||||
"VARIANT": "user",
|
||||
"MOZILLA_OFFICIAL": "1",
|
||||
"B2GUPDATER": "1"
|
||||
"MOZILLA_OFFICIAL": "1"
|
||||
},
|
||||
"gecko_l10n_root": "http://hg.mozilla.org/l10n-central",
|
||||
"gaia": {
|
||||
|
|
|
@ -129,8 +129,9 @@ pref("app.update.cert.maxErrors", 5);
|
|||
// the |app.update.url.override| preference should ONLY be used for testing.
|
||||
// IMPORTANT! metro.js should also be updated for updates to certs.X.issuerName
|
||||
|
||||
// Nightly builds have switched over to aus4.mozilla.org, but we don't want anything else to yet.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
// Non-release builds (Nightly, Aurora, etc.) have been switched over to aus4.mozilla.org.
|
||||
// This condition protects us against accidentally using it for release builds.
|
||||
#ifndef RELEASE_BUILD
|
||||
pref("app.update.certs.1.issuerName", "CN=DigiCert Secure Server CA,O=DigiCert Inc,C=US");
|
||||
pref("app.update.certs.1.commonName", "aus4.mozilla.org");
|
||||
|
||||
|
@ -172,7 +173,7 @@ pref("app.update.silent", false);
|
|||
pref("app.update.staging.enabled", true);
|
||||
|
||||
// Update service URL:
|
||||
#ifdef NIGHTLY_BUILD
|
||||
#ifndef RELEASE_BUILD
|
||||
pref("app.update.url", "https://aus4.mozilla.org/update/3/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");
|
||||
#else
|
||||
pref("app.update.url", "https://aus3.mozilla.org/update/3/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");
|
||||
|
|
|
@ -778,27 +778,6 @@ var gBrowserInit = {
|
|||
window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
|
||||
new nsBrowserAccess();
|
||||
|
||||
// Manually hook up session and global history for the first browser
|
||||
// so that we don't have to load global history before bringing up a
|
||||
// window.
|
||||
// Wire up session and global history before any possible
|
||||
// progress notifications for back/forward button updating
|
||||
gBrowser.webNavigation.sessionHistory = Cc["@mozilla.org/browser/shistory;1"].
|
||||
createInstance(Ci.nsISHistory);
|
||||
Services.obs.addObserver(gBrowser.browsers[0], "browser:purge-session-history", false);
|
||||
|
||||
// remove the disablehistory attribute so the browser cleans up, as
|
||||
// though it had done this work itself
|
||||
gBrowser.browsers[0].removeAttribute("disablehistory");
|
||||
|
||||
// enable global history
|
||||
try {
|
||||
if (!gMultiProcessBrowser)
|
||||
gBrowser.docShell.useGlobalHistory = true;
|
||||
} catch(ex) {
|
||||
Cu.reportError("Places database may be locked: " + ex);
|
||||
}
|
||||
|
||||
// hook up UI through progress listener
|
||||
gBrowser.addProgressListener(window.XULBrowserWindow);
|
||||
gBrowser.addTabsProgressListener(window.TabsProgressListener);
|
||||
|
|
|
@ -1045,7 +1045,7 @@
|
|||
|
||||
<splitter id="sidebar-splitter" class="chromeclass-extrachrome sidebar-splitter" hidden="true"/>
|
||||
<vbox id="appcontent" flex="1">
|
||||
<tabbrowser id="content" disablehistory="true"
|
||||
<tabbrowser id="content"
|
||||
flex="1" contenttooltip="aHTMLTooltip"
|
||||
tabcontainer="tabbrowser-tabs"
|
||||
contentcontextmenu="contentAreaContextMenu"
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<xul:hbox flex="1" class="browserSidebarContainer">
|
||||
<xul:vbox flex="1" class="browserContainer">
|
||||
<xul:stack flex="1" class="browserStack" anonid="browserStack">
|
||||
<xul:browser anonid="initialBrowser" type="content-primary" message="true" disablehistory="true"
|
||||
<xul:browser anonid="initialBrowser" type="content-primary" message="true"
|
||||
xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup,selectpopup"/>
|
||||
</xul:stack>
|
||||
</xul:vbox>
|
||||
|
|
|
@ -1479,7 +1479,7 @@ let SessionStoreInternal = {
|
|||
|
||||
TabStateCache.delete(aTab);
|
||||
this._setWindowStateBusy(window);
|
||||
this.restoreHistoryPrecursor(window, [aTab], [tabState], 0, 0, 0);
|
||||
this.restoreHistoryPrecursor(window, [aTab], [tabState], 0);
|
||||
},
|
||||
|
||||
duplicateTab: function ssi_duplicateTab(aWindow, aTab, aDelta = 0) {
|
||||
|
@ -1499,7 +1499,7 @@ let SessionStoreInternal = {
|
|||
aWindow.gBrowser.addTab(null, {relatedToCurrent: true, ownerTab: aTab}) :
|
||||
aWindow.gBrowser.addTab();
|
||||
|
||||
this.restoreHistoryPrecursor(aWindow, [newTab], [tabState], 0, 0, 0,
|
||||
this.restoreHistoryPrecursor(aWindow, [newTab], [tabState], 0,
|
||||
true /* Load this tab right away. */);
|
||||
|
||||
return newTab;
|
||||
|
@ -1579,7 +1579,7 @@ let SessionStoreInternal = {
|
|||
let tab = tabbrowser.addTab();
|
||||
|
||||
// restore tab content
|
||||
this.restoreHistoryPrecursor(aWindow, [tab], [closedTabState], 1, 0, 0);
|
||||
this.restoreHistoryPrecursor(aWindow, [tab], [closedTabState], 1);
|
||||
|
||||
// restore the tab's position
|
||||
tabbrowser.moveTabTo(tab, closedTab.pos);
|
||||
|
@ -2352,7 +2352,7 @@ let SessionStoreInternal = {
|
|||
}
|
||||
|
||||
this.restoreHistoryPrecursor(aWindow, tabs, winData.tabs,
|
||||
(overwriteTabs ? (parseInt(winData.selected) || 1) : 0), 0, 0);
|
||||
(overwriteTabs ? (parseInt(winData.selected) || 1) : 0));
|
||||
|
||||
if (aState.scratchpads) {
|
||||
ScratchpadManager.restoreSession(aState.scratchpads);
|
||||
|
@ -2456,40 +2456,17 @@ let SessionStoreInternal = {
|
|||
* Array of tab data
|
||||
* @param aSelectTab
|
||||
* Index of selected tab
|
||||
* @param aIx
|
||||
* Index of the next tab to check readyness for
|
||||
* @param aCount
|
||||
* Counter for number of times delaying b/c browser or history aren't ready
|
||||
* @param aRestoreImmediately
|
||||
* Flag to indicate whether the given set of tabs aTabs should be
|
||||
* restored/loaded immediately even if restore_on_demand = true
|
||||
*/
|
||||
restoreHistoryPrecursor:
|
||||
function ssi_restoreHistoryPrecursor(aWindow, aTabs, aTabData, aSelectTab,
|
||||
aIx, aCount, aRestoreImmediately = false) {
|
||||
aRestoreImmediately = false)
|
||||
{
|
||||
|
||||
var tabbrowser = aWindow.gBrowser;
|
||||
|
||||
// make sure that all browsers and their histories are available
|
||||
// - if one's not, resume this check in 100ms (repeat at most 10 times)
|
||||
for (var t = aIx; t < aTabs.length; t++) {
|
||||
try {
|
||||
if (!tabbrowser.getBrowserForTab(aTabs[t]).webNavigation.sessionHistory) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
catch (ex) { // in case browser or history aren't ready yet
|
||||
if (aCount < 10) {
|
||||
var restoreHistoryFunc = function(self) {
|
||||
self.restoreHistoryPrecursor(aWindow, aTabs, aTabData, aSelectTab,
|
||||
aIx, aCount + 1, aRestoreImmediately);
|
||||
};
|
||||
aWindow.setTimeout(restoreHistoryFunc, 100, this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this._isWindowLoaded(aWindow)) {
|
||||
// from now on, the data will come from the actual window
|
||||
delete this._statesToRestore[aWindow.__SS_restoreID];
|
||||
|
@ -2515,7 +2492,7 @@ let SessionStoreInternal = {
|
|||
return;
|
||||
}
|
||||
|
||||
// Sets the tabs restoring order.
|
||||
// Sets the tabs restoring order.
|
||||
[aTabs, aTabData] =
|
||||
this._setTabsRestoringOrder(tabbrowser, aTabs, aTabData, aSelectTab);
|
||||
|
||||
|
@ -2523,7 +2500,7 @@ let SessionStoreInternal = {
|
|||
// and show/hide tabs as necessary. We'll also set the labels, user typed
|
||||
// value, and attach a copy of the tab's data in case we close it before
|
||||
// it's been restored.
|
||||
for (t = 0; t < aTabs.length; t++) {
|
||||
for (let t = 0; t < aTabs.length; t++) {
|
||||
let tab = aTabs[t];
|
||||
let browser = tabbrowser.getBrowserForTab(tab);
|
||||
let tabData = aTabData[t];
|
||||
|
@ -2595,14 +2572,14 @@ let SessionStoreInternal = {
|
|||
|
||||
// helper hashes for ensuring unique frame IDs and unique document
|
||||
// identifiers.
|
||||
var idMap = { used: {} };
|
||||
var docIdentMap = {};
|
||||
let idMap = { used: {} };
|
||||
let docIdentMap = {};
|
||||
this.restoreHistory(aWindow, aTabs, aTabData, idMap, docIdentMap,
|
||||
aRestoreImmediately);
|
||||
},
|
||||
|
||||
/**
|
||||
* Restore history for a window
|
||||
* Restore history for a list of tabs.
|
||||
* @param aWindow
|
||||
* Window reference
|
||||
* @param aTabs
|
||||
|
|
|
@ -449,7 +449,7 @@ pref("app.update.silent", true);
|
|||
pref("app.update.staging.enabled", true);
|
||||
|
||||
// Update service URL:
|
||||
#ifdef NIGHTLY_BUILD
|
||||
#ifndef RELEASE_BUILD
|
||||
pref("app.update.url", "https://aus4.mozilla.org/update/3/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");
|
||||
#else
|
||||
pref("app.update.url", "https://aus3.mozilla.org/update/3/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");
|
||||
|
@ -522,8 +522,9 @@ pref("app.update.cert.maxErrors", 5);
|
|||
// the |app.update.url.override| preference should ONLY be used for testing.
|
||||
// IMPORTANT! firefox.js should also be updated for updates to certs.X.issuerName
|
||||
|
||||
// Nightly builds have switched over to aus4.mozilla.org, but we don't want anything else to yet.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
// Non-release builds (Nightly, Aurora, etc.) have been switched over to aus4.mozilla.org.
|
||||
// This condition protects us against accidentally using it for release builds.
|
||||
#ifndef RELEASE_BUILD
|
||||
pref("app.update.certs.1.issuerName", "CN=DigiCert Secure Server CA,O=DigiCert Inc,C=US");
|
||||
pref("app.update.certs.1.commonName", "aus4.mozilla.org");
|
||||
pref("app.update.certs.2.issuerName", "CN=Thawte SSL CA,O=\"Thawte, Inc.\",C=US");
|
||||
|
|
|
@ -30,9 +30,8 @@ this.webappsUI = {
|
|||
Services.obs.addObserver(this, "webapps-launch", false);
|
||||
Services.obs.addObserver(this, "webapps-uninstall", false);
|
||||
cpmm.addMessageListener("Webapps:Install:Return:OK", this);
|
||||
cpmm.addMessageListener("Webapps:OfflineCache", this);
|
||||
cpmm.addMessageListener("Webapps:Install:Return:KO", this);
|
||||
cpmm.addMessageListener("Webapps:PackageEvent", this);
|
||||
cpmm.addMessageListener("Webapps:UpdateState", this);
|
||||
},
|
||||
|
||||
uninit: function webappsUI_uninit() {
|
||||
|
@ -40,9 +39,8 @@ this.webappsUI = {
|
|||
Services.obs.removeObserver(this, "webapps-launch");
|
||||
Services.obs.removeObserver(this, "webapps-uninstall");
|
||||
cpmm.removeMessageListener("Webapps:Install:Return:OK", this);
|
||||
cpmm.removeMessageListener("Webapps:OfflineCache", this);
|
||||
cpmm.removeMessageListener("Webapps:Install:Return:KO", this);
|
||||
cpmm.removeMessageListener("Webapps:PackageEvent", this);
|
||||
cpmm.removeMessageListener("Webapps:UpdateState", this);
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
|
@ -56,10 +54,10 @@ this.webappsUI = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (aMessage.name == "Webapps:OfflineCache") {
|
||||
if (aMessage.name == "Webapps:UpdateState") {
|
||||
if (data.error) {
|
||||
this.installations[manifestURL].reject(data.error);
|
||||
} else if (data.installState == "installed") {
|
||||
} else if (data.app.installState == "installed") {
|
||||
this.installations[manifestURL].resolve();
|
||||
}
|
||||
} else if (aMessage.name == "Webapps:Install:Return:OK" &&
|
||||
|
@ -70,12 +68,6 @@ this.webappsUI = {
|
|||
}
|
||||
} else if (aMessage.name == "Webapps:Install:Return:KO") {
|
||||
this.installations[manifestURL].reject(data.error);
|
||||
} else if (aMessage.name == "Webapps:PackageEvent") {
|
||||
if (data.type == "installed") {
|
||||
this.installations[manifestURL].resolve();
|
||||
} else if (data.type == "error") {
|
||||
this.installations[manifestURL].reject(data.error);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -29,9 +29,9 @@ toolkit/library
|
|||
editor
|
||||
parser
|
||||
js/src
|
||||
js/xpconnect
|
||||
js/xpconnect/loader
|
||||
mfbt
|
||||
js/xpconnect
|
||||
js/xpconnect/loader
|
||||
view
|
||||
caps
|
||||
xpfe/appshell
|
||||
|
|
62
configure.in
62
configure.in
|
@ -86,27 +86,41 @@ dnl ========================================================
|
|||
MOZ_USE_PTHREADS=
|
||||
_PTHREAD_LDFLAGS=""
|
||||
|
||||
dnl Do not allow a separate objdir build if a srcdir build exists.
|
||||
dnl Do not allow objdir == srcdir builds.
|
||||
dnl ==============================================================
|
||||
_topsrcdir=`cd \`dirname $0\`; pwd`
|
||||
_objdir=`pwd`
|
||||
|
||||
if test "$_topsrcdir" != "$_objdir"
|
||||
then
|
||||
# Check for a couple representative files in the source tree
|
||||
_conflict_files=
|
||||
for file in $_topsrcdir/Makefile $_topsrcdir/config/autoconf.mk; do
|
||||
if test -f $file; then
|
||||
_conflict_files="$_conflict_files $file"
|
||||
fi
|
||||
|
||||
|
||||
dnl TODO Don't exempt L10N builds once bug 842760 is resolved.
|
||||
if test "$_topsrcdir" = "$_objdir" -a "${with_l10n_base+set}" != set; then
|
||||
echo " ***"
|
||||
echo " * Building directly in the main source directory is not allowed."
|
||||
echo " *"
|
||||
echo " * To build, you must run configure from a separate directory"
|
||||
echo " * (referred to as an object directory)."
|
||||
echo " *"
|
||||
echo " * If you are building with a mozconfig, you will need to change your"
|
||||
echo " * mozconfig to point to a different object directory."
|
||||
echo " ***"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for a couple representative files in the source tree
|
||||
_conflict_files=
|
||||
for file in $_topsrcdir/Makefile $_topsrcdir/config/autoconf.mk; do
|
||||
if test -f $file; then
|
||||
_conflict_files="$_conflict_files $file"
|
||||
fi
|
||||
done
|
||||
if test "$_conflict_files"; then
|
||||
echo "***"
|
||||
echo "* Your source tree contains these files:"
|
||||
for file in $_conflict_files; do
|
||||
echo "* $file"
|
||||
done
|
||||
if test "$_conflict_files"; then
|
||||
echo "***"
|
||||
echo "* Your source tree contains these files:"
|
||||
for file in $_conflict_files; do
|
||||
echo "* $file"
|
||||
done
|
||||
cat 1>&2 <<-EOF
|
||||
cat 1>&2 <<-EOF
|
||||
* This indicates that you previously built in the source tree.
|
||||
* A source tree build can confuse the separate objdir build.
|
||||
*
|
||||
|
@ -115,9 +129,8 @@ then
|
|||
* 2. gmake distclean
|
||||
***
|
||||
EOF
|
||||
exit 1
|
||||
break
|
||||
fi
|
||||
exit 1
|
||||
break
|
||||
fi
|
||||
MOZ_BUILD_ROOT=`pwd`
|
||||
|
||||
|
@ -209,6 +222,7 @@ if test -n "$gonkdir" ; then
|
|||
15)
|
||||
GONK_INCLUDES="-I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/frameworks/base/include -I$gonkdir/frameworks/base/services/camera -I$gonkdir/frameworks/base/include/media/stagefright -I$gonkdir/frameworks/base/include/media/stagefright/openmax -I$gonkdir/frameworks/base/media/libstagefright/rtsp -I$gonkdir/frameworks/base/media/libstagefright/include -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib -I$gonkdir/dalvik/libnativehelper/include/nativehelper"
|
||||
MOZ_B2G_BT=1
|
||||
MOZ_B2G_BT_BLUEZ=1
|
||||
MOZ_B2G_CAMERA=1
|
||||
MOZ_OMX_DECODER=1
|
||||
AC_SUBST(MOZ_OMX_DECODER)
|
||||
|
@ -217,9 +231,15 @@ if test -n "$gonkdir" ; then
|
|||
18)
|
||||
GONK_INCLUDES="-I$gonkdir/frameworks/native/include -I$gonkdir/frameworks/av/include -I$gonkdir/frameworks/av/include/media -I$gonkdir/frameworks/av/include/camera -I$gonkdir/frameworks/native/include/media/openmax -I$gonkdir/frameworks/av/media/libstagefright/include"
|
||||
if test -d "$gonkdir/external/bluetooth/bluez"; then
|
||||
GONK_INCLUDES+=" -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib"
|
||||
GONK_INCLUDES="$GONK_INCLUDES -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib"
|
||||
MOZ_B2G_BT=1
|
||||
MOZ_B2G_BT_BLUEZ=1
|
||||
fi
|
||||
if test -d "$gonkdir/external/bluetooth/bluedroid"; then
|
||||
MOZ_B2G_BT=1
|
||||
MOZ_B2G_BT_BLUEDROID=1
|
||||
fi
|
||||
|
||||
MOZ_B2G_CAMERA=1
|
||||
MOZ_OMX_DECODER=1
|
||||
AC_SUBST(MOZ_OMX_DECODER)
|
||||
|
@ -7275,6 +7295,8 @@ if test -n "$MOZ_B2G_BT"; then
|
|||
AC_DEFINE(MOZ_B2G_BT)
|
||||
fi
|
||||
AC_SUBST(MOZ_B2G_BT)
|
||||
AC_SUBST(MOZ_B2G_BT_BLUEZ)
|
||||
AC_SUBST(MOZ_B2G_BT_BLUEDROID)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable Pico Speech Synthesis (Gonk usually)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#endif
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "js/Value.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
|
@ -1637,7 +1638,7 @@ public:
|
|||
|
||||
static nsresult WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
|
||||
nsISupports *native, const nsIID* aIID,
|
||||
JS::Value *vp,
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
// If non-null aHolder will keep the Value alive
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nullptr,
|
||||
|
@ -1649,7 +1650,7 @@ public:
|
|||
|
||||
// Same as the WrapNative above, but use this one if aIID is nsISupports' IID.
|
||||
static nsresult WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
|
||||
nsISupports *native, JS::Value *vp,
|
||||
nsISupports *native, JS::MutableHandle<JS::Value> vp,
|
||||
// If non-null aHolder will keep the Value alive
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nullptr,
|
||||
|
@ -1660,7 +1661,7 @@ public:
|
|||
}
|
||||
static nsresult WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
|
||||
nsISupports *native, nsWrapperCache *cache,
|
||||
JS::Value *vp,
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
// If non-null aHolder will keep the Value alive
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nullptr,
|
||||
|
@ -2091,7 +2092,7 @@ private:
|
|||
|
||||
static nsresult WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
|
||||
nsISupports *native, nsWrapperCache *cache,
|
||||
const nsIID* aIID, JS::Value *vp,
|
||||
const nsIID* aIID, JS::MutableHandle<JS::Value> vp,
|
||||
nsIXPConnectJSObjectHolder** aHolder,
|
||||
bool aAllowWrapping);
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ CSPService::CSPService()
|
|||
|
||||
CSPService::~CSPService()
|
||||
{
|
||||
mAppStatusCache.Clear();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(CSPService, nsIContentPolicy, nsIChannelEventSink)
|
||||
|
@ -105,6 +106,55 @@ CSPService::ShouldLoad(uint32_t aContentType,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// ----- THIS IS A TEMPORARY FAST PATH FOR CERTIFIED APPS. -----
|
||||
// ----- PLEASE REMOVE ONCE bug 925004 LANDS. -----
|
||||
|
||||
// Cache the app status for this origin.
|
||||
uint16_t status = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
nsAutoCString contentOrigin;
|
||||
aContentLocation->GetPrePath(contentOrigin);
|
||||
if (aRequestPrincipal && !mAppStatusCache.Get(contentOrigin, &status)) {
|
||||
aRequestPrincipal->GetAppStatus(&status);
|
||||
mAppStatusCache.Put(contentOrigin, status);
|
||||
}
|
||||
|
||||
if (status == nsIPrincipal::APP_STATUS_CERTIFIED) {
|
||||
// The CSP for certified apps is :
|
||||
// "default-src *; script-src 'self'; object-src 'none'; style-src 'self'"
|
||||
// That means we can optimize for this case by:
|
||||
// - loading only same origin scripts and stylesheets.
|
||||
// - never loading objects.
|
||||
// - accepting everything else.
|
||||
|
||||
switch (aContentType) {
|
||||
case nsIContentPolicy::TYPE_SCRIPT:
|
||||
case nsIContentPolicy::TYPE_STYLESHEET:
|
||||
{
|
||||
nsAutoCString sourceOrigin;
|
||||
aRequestOrigin->GetPrePath(sourceOrigin);
|
||||
if (!sourceOrigin.Equals(contentOrigin)) {
|
||||
*aDecision = nsIContentPolicy::REJECT_SERVER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIContentPolicy::TYPE_OBJECT:
|
||||
*aDecision = nsIContentPolicy::REJECT_SERVER;
|
||||
break;
|
||||
|
||||
default:
|
||||
*aDecision = nsIContentPolicy::ACCEPT;
|
||||
}
|
||||
|
||||
// Only cache and return if we are successful. If not, we want the error
|
||||
// to be reported, and thus fallback to the slow path.
|
||||
if (*aDecision == nsIContentPolicy::ACCEPT) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// ----- END OF TEMPORARY FAST PATH FOR CERTIFIED APPS. -----
|
||||
|
||||
// find the principal of the document that initiated this request and see
|
||||
// if it has a CSP policy object
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(aRequestContext));
|
||||
|
|
|
@ -23,4 +23,7 @@ public:
|
|||
CSPService();
|
||||
virtual ~CSPService();
|
||||
static bool sCSPEnabled;
|
||||
private:
|
||||
// Maps origins to app status.
|
||||
nsDataHashtable<nsCStringHashKey, uint16_t> mAppStatusCache;
|
||||
};
|
||||
|
|
|
@ -5659,14 +5659,14 @@ nsContentUtils::DispatchXULCommand(nsIContent* aTarget,
|
|||
nsresult
|
||||
nsContentUtils::WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
|
||||
nsISupports *native, nsWrapperCache *cache,
|
||||
const nsIID* aIID, JS::Value *vp,
|
||||
const nsIID* aIID, JS::MutableHandleValue vp,
|
||||
nsIXPConnectJSObjectHolder **aHolder,
|
||||
bool aAllowWrapping)
|
||||
{
|
||||
if (!native) {
|
||||
NS_ASSERTION(!aHolder || !*aHolder, "*aHolder should be null!");
|
||||
|
||||
*vp = JSVAL_NULL;
|
||||
vp.setNull();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -5685,7 +5685,7 @@ nsContentUtils::WrapNative(JSContext *cx, JS::Handle<JSObject*> scope,
|
|||
nsresult rv = NS_OK;
|
||||
AutoPushJSContext context(cx);
|
||||
rv = sXPConnect->WrapNativeToJSVal(context, scope, native, cache, aIID,
|
||||
aAllowWrapping, vp, aHolder);
|
||||
aAllowWrapping, vp.address(), aHolder);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -5728,8 +5728,7 @@ nsContentUtils::CreateBlobBuffer(JSContext* aCx,
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
return nsContentUtils::WrapNative(aCx, scope, blob, aBlob.address(), nullptr,
|
||||
true);
|
||||
return nsContentUtils::WrapNative(aCx, scope, blob, aBlob, nullptr, true);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -206,9 +206,11 @@ nsDOMFileReader::GetResult(JSContext* aCx, JS::Value* aResult)
|
|||
}
|
||||
|
||||
nsString tmpResult = mResult;
|
||||
if (!xpc::StringToJsval(aCx, tmpResult, aResult)) {
|
||||
JS::Rooted<JS::Value> result(aCx);
|
||||
if (!xpc::StringToJsval(aCx, tmpResult, &result)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
*aResult = result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -5167,7 +5167,7 @@ CustomElementConstructor(JSContext *aCx, unsigned aArgc, JS::Value* aVp)
|
|||
nsresult rv = document->CreateElem(elemName, nullptr, kNameSpaceID_XHTML,
|
||||
getter_AddRefs(newElement));
|
||||
rv = nsContentUtils::WrapNative(aCx, global, newElement, newElement,
|
||||
args.rval().address());
|
||||
args.rval());
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
return true;
|
||||
|
@ -6732,7 +6732,7 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
|
|||
JS::Rooted<JSObject*> global(cx, GetScopeObject()->GetGlobalJSObject());
|
||||
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
rv = nsContentUtils::WrapNative(cx, global, this, this, v.address(),
|
||||
rv = nsContentUtils::WrapNative(cx, global, this, this, &v,
|
||||
nullptr, /* aAllowWrapping = */ false);
|
||||
if (rv.Failed())
|
||||
return nullptr;
|
||||
|
@ -11345,7 +11345,7 @@ nsIDocument::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aScope)
|
|||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
nsresult rv = nsContentUtils::WrapNative(aCx, obj, win,
|
||||
&NS_GET_IID(nsIDOMWindow),
|
||||
winVal.address(),
|
||||
&winVal,
|
||||
getter_AddRefs(holder),
|
||||
false);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
|
@ -832,7 +832,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
|
||||
JS::Rooted<JS::Value> targetv(ctx);
|
||||
JS::Rooted<JSObject*> global(ctx, JS_GetGlobalForObject(ctx, object));
|
||||
nsContentUtils::WrapNative(ctx, global, aTarget, targetv.address(),
|
||||
nsContentUtils::WrapNative(ctx, global, aTarget, &targetv,
|
||||
nullptr, true);
|
||||
|
||||
JS::RootedObject cpows(ctx);
|
||||
|
@ -888,7 +888,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
}
|
||||
JS::Rooted<JSObject*> global(ctx, JS_GetGlobalForObject(ctx, object));
|
||||
nsContentUtils::WrapNative(ctx, global, defaultThisValue,
|
||||
thisValue.address(), nullptr, true);
|
||||
&thisValue, nullptr, true);
|
||||
} else {
|
||||
// If the listener is a JS object which has receiveMessage function:
|
||||
if (!JS_GetProperty(ctx, object, "receiveMessage", &funval) ||
|
||||
|
|
|
@ -49,7 +49,15 @@ void
|
|||
nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri)
|
||||
{
|
||||
if (gDataTable) {
|
||||
gDataTable->Remove(aUri);
|
||||
nsCString uriIgnoringRef;
|
||||
int32_t hashPos = aUri.FindChar('#');
|
||||
if (hashPos < 0) {
|
||||
uriIgnoringRef = aUri;
|
||||
}
|
||||
else {
|
||||
uriIgnoringRef = StringHead(aUri, hashPos);
|
||||
}
|
||||
gDataTable->Remove(uriIgnoringRef);
|
||||
if (gDataTable->Count() == 0) {
|
||||
delete gDataTable;
|
||||
gDataTable = nullptr;
|
||||
|
@ -80,6 +88,27 @@ nsHostObjectProtocolHandler::GenerateURIString(const nsACString &aScheme,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static DataInfo*
|
||||
GetDataInfo(const nsACString& aUri)
|
||||
{
|
||||
if (!gDataTable) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DataInfo* res;
|
||||
nsCString uriIgnoringRef;
|
||||
int32_t hashPos = aUri.FindChar('#');
|
||||
if (hashPos < 0) {
|
||||
uriIgnoringRef = aUri;
|
||||
}
|
||||
else {
|
||||
uriIgnoringRef = StringHead(aUri, hashPos);
|
||||
}
|
||||
gDataTable->Get(uriIgnoringRef, &res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
nsHostObjectProtocolHandler::GetDataEntryPrincipal(const nsACString& aUri)
|
||||
{
|
||||
|
@ -87,8 +116,8 @@ nsHostObjectProtocolHandler::GetDataEntryPrincipal(const nsACString& aUri)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
DataInfo* res;
|
||||
gDataTable->Get(aUri, &res);
|
||||
DataInfo* res = GetDataInfo(aUri);
|
||||
|
||||
if (!res) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -114,18 +143,6 @@ nsHostObjectProtocolHandler::Traverse(const nsACString& aUri,
|
|||
aCallback.NoteXPCOMChild(res->mObject);
|
||||
}
|
||||
|
||||
static DataInfo*
|
||||
GetDataInfo(const nsACString& aUri)
|
||||
{
|
||||
if (!gDataTable) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DataInfo* res;
|
||||
gDataTable->Get(aUri, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static nsISupports*
|
||||
GetDataObject(nsIURI* aURI)
|
||||
{
|
||||
|
|
|
@ -966,7 +966,7 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
|
|||
if (aRv.Failed()) {
|
||||
return JSVAL_NULL;
|
||||
}
|
||||
JS::Value result;
|
||||
JS::Rooted<JS::Value> result(aCx);
|
||||
if (!xpc::StringToJsval(aCx, str, &result)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return JSVAL_NULL;
|
||||
|
@ -1014,7 +1014,7 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
|
|||
|
||||
JS::Rooted<JS::Value> result(aCx, JSVAL_NULL);
|
||||
JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
aRv = nsContentUtils::WrapNative(aCx, scope, mResponseBlob, result.address(),
|
||||
aRv = nsContentUtils::WrapNative(aCx, scope, mResponseBlob, &result,
|
||||
nullptr, true);
|
||||
return result;
|
||||
}
|
||||
|
@ -1026,7 +1026,7 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
|
|||
|
||||
JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
JS::Rooted<JS::Value> result(aCx, JSVAL_NULL);
|
||||
aRv = nsContentUtils::WrapNative(aCx, scope, mResponseXML, result.address(),
|
||||
aRv = nsContentUtils::WrapNative(aCx, scope, mResponseXML, &result,
|
||||
nullptr, true);
|
||||
return result;
|
||||
}
|
||||
|
@ -3659,7 +3659,7 @@ nsXMLHttpRequest::GetInterface(JSContext* aCx, nsIJSID* aIID, ErrorResult& aRv)
|
|||
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
|
||||
JSAutoCompartment ac(aCx, wrapper);
|
||||
JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, wrapper));
|
||||
aRv = nsContentUtils::WrapNative(aCx, global, result, iid, v.address());
|
||||
aRv = nsContentUtils::WrapNative(aCx, global, result, iid, &v);
|
||||
return aRv.Failed() ? JSVAL_NULL : v;
|
||||
}
|
||||
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 17 KiB |
|
@ -0,0 +1 @@
|
|||
== test_bug920877.html test_bug920877-ref.html
|
|
@ -0,0 +1,20 @@
|
|||
<html>
|
||||
<body>
|
||||
<script>
|
||||
var img = document.createElement("img");
|
||||
img.id = "img-ori";
|
||||
img.src = "mixed-bmp-png.ico";
|
||||
document.body.appendChild(img);
|
||||
|
||||
img = document.createElement("img");
|
||||
img.id = "img-res32";
|
||||
img.src = "mixed-bmp-png.ico#-moz-resolution=32,32";
|
||||
document.body.appendChild(img);
|
||||
|
||||
img = document.createElement("img");
|
||||
img.id = "img-res48";
|
||||
img.src = "mixed-bmp-png.ico#-moz-resolution=48,48";
|
||||
document.body.appendChild(img);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -114,7 +114,7 @@ HTMLAudioElement::MozSetup(uint32_t aChannels, uint32_t aRate, ErrorResult& aRv)
|
|||
#endif
|
||||
|
||||
mAudioStream = AudioStream::AllocateStream();
|
||||
aRv = mAudioStream->Init(aChannels, aRate, mAudioChannelType);
|
||||
aRv = mAudioStream->Init(aChannels, aRate, mAudioChannelType, AudioStream::HighLatency);
|
||||
if (aRv.Failed()) {
|
||||
mAudioStream->Shutdown();
|
||||
mAudioStream = nullptr;
|
||||
|
|
|
@ -3155,7 +3155,7 @@ nsGenericHTMLElement::GetItemValue(JSContext* aCx, JSObject* aScope,
|
|||
|
||||
nsString string;
|
||||
GetItemValueText(string);
|
||||
JS::Value v;
|
||||
JS::Rooted<JS::Value> v(aCx);
|
||||
if (!xpc::NonVoidStringToJsval(aCx, string, &v)) {
|
||||
aError.Throw(NS_ERROR_FAILURE);
|
||||
return JS::UndefinedValue();
|
||||
|
|
|
@ -41,6 +41,11 @@ PRLogModuleInfo* gAudioStreamLog = nullptr;
|
|||
static Mutex* gAudioPrefsLock = nullptr;
|
||||
static double gVolumeScale;
|
||||
static uint32_t gCubebLatency;
|
||||
static bool gCubebLatencyPrefSet;
|
||||
static const uint32_t CUBEB_NORMAL_LATENCY_MS = 100;
|
||||
|
||||
StaticMutex AudioStream::mMutex;
|
||||
uint32_t AudioStream::mPreferredSampleRate = 0;
|
||||
|
||||
/**
|
||||
* When MOZ_DUMP_AUDIO is set in the environment (to anything),
|
||||
|
@ -65,9 +70,10 @@ static int PrefChanged(const char* aPref, void* aClosure)
|
|||
// Arbitrary default stream latency of 100ms. The higher this
|
||||
// value, the longer stream volume changes will take to become
|
||||
// audible.
|
||||
uint32_t value = Preferences::GetUint(aPref, 100);
|
||||
gCubebLatencyPrefSet = Preferences::HasUserValue(aPref);
|
||||
uint32_t value = Preferences::GetUint(aPref, CUBEB_NORMAL_LATENCY_MS);
|
||||
MutexAutoLock lock(*gAudioPrefsLock);
|
||||
gCubebLatency = std::min<uint32_t>(std::max<uint32_t>(value, 20), 1000);
|
||||
gCubebLatency = std::min<uint32_t>(std::max<uint32_t>(value, 1), 1000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -97,6 +103,12 @@ static uint32_t GetCubebLatency()
|
|||
MutexAutoLock lock(*gAudioPrefsLock);
|
||||
return gCubebLatency;
|
||||
}
|
||||
|
||||
static bool CubebLatencyPrefSet()
|
||||
{
|
||||
MutexAutoLock lock(*gAudioPrefsLock);
|
||||
return gCubebLatencyPrefSet;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_CUBEB) && defined(__ANDROID__) && defined(MOZ_B2G)
|
||||
|
@ -311,7 +323,8 @@ class BufferedAudioStream : public AudioStream
|
|||
~BufferedAudioStream();
|
||||
|
||||
nsresult Init(int32_t aNumChannels, int32_t aRate,
|
||||
const dom::AudioChannelType aAudioChannelType);
|
||||
const dom::AudioChannelType aAudioChannelType,
|
||||
AudioStream::LatencyRequest aLatencyRequest);
|
||||
void Shutdown();
|
||||
nsresult Write(const AudioDataValue* aBuf, uint32_t aFrames);
|
||||
uint32_t Available();
|
||||
|
@ -431,6 +444,23 @@ int AudioStream::MaxNumberOfChannels()
|
|||
return static_cast<int>(maxNumberOfChannels);
|
||||
}
|
||||
|
||||
int AudioStream::PreferredSampleRate()
|
||||
{
|
||||
StaticMutexAutoLock lock(AudioStream::mMutex);
|
||||
// Get the preferred samplerate for this platform, or fallback to something
|
||||
// sensible if we fail. We cache the value, because this might be accessed
|
||||
// often, and the complexity of the function call below depends on the
|
||||
// backend used.
|
||||
const int fallbackSampleRate = 44100;
|
||||
if (mPreferredSampleRate == 0) {
|
||||
if (cubeb_get_preferred_sample_rate(GetCubebContext(), &mPreferredSampleRate) != CUBEB_OK) {
|
||||
mPreferredSampleRate = fallbackSampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
return mPreferredSampleRate;
|
||||
}
|
||||
|
||||
static void SetUint16LE(uint8_t* aDest, uint16_t aValue)
|
||||
{
|
||||
aDest[0] = aValue & 0xFF;
|
||||
|
@ -526,7 +556,8 @@ BufferedAudioStream::EnsureTimeStretcherInitialized()
|
|||
|
||||
nsresult
|
||||
BufferedAudioStream::Init(int32_t aNumChannels, int32_t aRate,
|
||||
const dom::AudioChannelType aAudioChannelType)
|
||||
const dom::AudioChannelType aAudioChannelType,
|
||||
AudioStream::LatencyRequest aLatencyRequest)
|
||||
{
|
||||
cubeb* cubebContext = GetCubebContext();
|
||||
|
||||
|
@ -562,10 +593,22 @@ BufferedAudioStream::Init(int32_t aNumChannels, int32_t aRate,
|
|||
|
||||
mAudioClock.Init();
|
||||
|
||||
// If the latency pref is set, use it. Otherwise, if this stream is intended
|
||||
// for low latency playback, try to get the lowest latency possible.
|
||||
// Otherwise, for normal streams, use 100ms.
|
||||
uint32_t latency;
|
||||
if (aLatencyRequest == AudioStream::LowLatency && !CubebLatencyPrefSet()) {
|
||||
if (cubeb_get_min_latency(cubebContext, params, &latency) != CUBEB_OK) {
|
||||
latency = GetCubebLatency();
|
||||
}
|
||||
} else {
|
||||
latency = GetCubebLatency();
|
||||
}
|
||||
|
||||
{
|
||||
cubeb_stream* stream;
|
||||
if (cubeb_stream_init(cubebContext, &stream, "BufferedAudioStream", params,
|
||||
GetCubebLatency(), DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
|
||||
latency, DataCallback_S, StateCallback_S, this) == CUBEB_OK) {
|
||||
mCubebStream.own(stream);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "Latency.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
|
||||
namespace soundtouch {
|
||||
class SoundTouch;
|
||||
|
@ -92,6 +93,10 @@ class AudioClock
|
|||
class AudioStream
|
||||
{
|
||||
public:
|
||||
enum LatencyRequest {
|
||||
HighLatency,
|
||||
LowLatency
|
||||
};
|
||||
AudioStream();
|
||||
|
||||
virtual ~AudioStream();
|
||||
|
@ -112,11 +117,16 @@ public:
|
|||
// Returns the maximum number of channels supported by the audio hardware.
|
||||
static int MaxNumberOfChannels();
|
||||
|
||||
// Returns the samplerate the systems prefer, because it is the
|
||||
// samplerate the hardware/mixer supports.
|
||||
static int PreferredSampleRate();
|
||||
|
||||
// Initialize the audio stream. aNumChannels is the number of audio
|
||||
// channels (1 for mono, 2 for stereo, etc) and aRate is the sample rate
|
||||
// (22050Hz, 44100Hz, etc).
|
||||
virtual nsresult Init(int32_t aNumChannels, int32_t aRate,
|
||||
const dom::AudioChannelType aAudioStreamType) = 0;
|
||||
const dom::AudioChannelType aAudioStreamType,
|
||||
LatencyRequest aLatencyRequest) = 0;
|
||||
|
||||
// Closes the stream. All future use of the stream is an error.
|
||||
virtual void Shutdown() = 0;
|
||||
|
@ -178,6 +188,11 @@ public:
|
|||
virtual nsresult SetPreservesPitch(bool aPreservesPitch);
|
||||
|
||||
protected:
|
||||
// This mutex protects the mPreferedSamplerate member below.
|
||||
static StaticMutex mMutex;
|
||||
// Prefered samplerate, in Hz (characteristic of the
|
||||
// hardware/mixer/platform/API used).
|
||||
static uint32_t mPreferredSampleRate;
|
||||
// Input rate in Hz (characteristic of the media being played)
|
||||
int mInRate;
|
||||
// Output rate in Hz (characteristic of the playback rate)
|
||||
|
|
|
@ -1059,7 +1059,7 @@ void MediaDecoderStateMachine::AudioLoop()
|
|||
// circumstances, so we take care to drop the decoder monitor while
|
||||
// initializing.
|
||||
nsAutoPtr<AudioStream> audioStream(AudioStream::AllocateStream());
|
||||
audioStream->Init(channels, rate, audioChannelType);
|
||||
audioStream->Init(channels, rate, audioChannelType, AudioStream::HighLatency);
|
||||
audioStream->SetVolume(volume);
|
||||
if (audioStream->SetPreservesPitch(preservesPitch) != NS_OK) {
|
||||
NS_WARNING("Setting the pitch preservation failed at AudioLoop start.");
|
||||
|
|
|
@ -768,7 +768,7 @@ MediaStreamGraphImpl::CreateOrDestroyAudioStreams(GraphTime aAudioOutputStartTim
|
|||
audioOutputStream->mStream = AudioStream::AllocateStream();
|
||||
// XXX for now, allocate stereo output. But we need to fix this to
|
||||
// match the system's ideal channel configuration.
|
||||
audioOutputStream->mStream->Init(2, tracks->GetRate(), AUDIO_CHANNEL_NORMAL);
|
||||
audioOutputStream->mStream->Init(2, tracks->GetRate(), AUDIO_CHANNEL_NORMAL, AudioStream::LowLatency);
|
||||
audioOutputStream->mTrackID = tracks->GetID();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -960,7 +960,7 @@ protected:
|
|||
};
|
||||
|
||||
// Returns ideal audio rate for processing
|
||||
inline TrackRate IdealAudioRate() { return 48000; }
|
||||
inline TrackRate IdealAudioRate() { return AudioStream::PreferredSampleRate(); }
|
||||
|
||||
/**
|
||||
* Initially, at least, we will have a singleton MediaStreamGraph per
|
||||
|
|
|
@ -85,7 +85,7 @@ void VideoFrameContainer::ClearCurrentFrame(bool aResetSize)
|
|||
kungFuDeathGrip = mImageContainer->LockCurrentImage();
|
||||
mImageContainer->UnlockCurrentImage();
|
||||
|
||||
mImageContainer->SetCurrentImage(nullptr);
|
||||
mImageContainer->ClearAllImages();
|
||||
mImageSizeChanged = aResetSize;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ OpusTrackEncoder::OpusTrackEncoder()
|
|||
, mEncoder(nullptr)
|
||||
, mSourceSegment(new AudioSegment())
|
||||
, mLookahead(0)
|
||||
, mResampler(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -147,16 +148,24 @@ OpusTrackEncoder::Init(int aChannels, int aSamplingRate)
|
|||
// The granule position is required to be incremented at a rate of 48KHz, and
|
||||
// it is simply calculated as |granulepos = samples * (48000/source_rate)|,
|
||||
// that is, the source sampling rate must divide 48000 evenly.
|
||||
// If this constraint is not satisfied, we resample the input to 48kHz.
|
||||
if (!((aSamplingRate >= 8000) && (kOpusSamplingRate / aSamplingRate) *
|
||||
aSamplingRate == kOpusSamplingRate)) {
|
||||
LOG("[Opus] Error! The source sample rate should be greater than 8000 and"
|
||||
" divides 48000 evenly.");
|
||||
return NS_ERROR_FAILURE;
|
||||
int error;
|
||||
mResampler = speex_resampler_init(mChannels,
|
||||
aSamplingRate,
|
||||
kOpusSamplingRate,
|
||||
SPEEX_RESAMPLER_QUALITY_DEFAULT,
|
||||
&error);
|
||||
|
||||
if (error != RESAMPLER_ERR_SUCCESS) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
mSamplingRate = aSamplingRate;
|
||||
|
||||
int error = 0;
|
||||
mEncoder = opus_encoder_create(mSamplingRate, mChannels,
|
||||
mEncoder = opus_encoder_create(GetOutputSampleRate(), mChannels,
|
||||
OPUS_APPLICATION_AUDIO, &error);
|
||||
|
||||
mInitialized = (error == OPUS_OK);
|
||||
|
@ -166,10 +175,16 @@ OpusTrackEncoder::Init(int aChannels, int aSamplingRate)
|
|||
return error == OPUS_OK ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int
|
||||
OpusTrackEncoder::GetOutputSampleRate()
|
||||
{
|
||||
return mResampler ? kOpusSamplingRate : mSamplingRate;
|
||||
}
|
||||
|
||||
int
|
||||
OpusTrackEncoder::GetPacketDuration()
|
||||
{
|
||||
return mSamplingRate * kFrameDurationMs / 1000;
|
||||
return GetOutputSampleRate() * kFrameDurationMs / 1000;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -282,8 +297,35 @@ OpusTrackEncoder::GetEncodedTrack(nsTArray<uint8_t>* aOutput,
|
|||
iter.Next();
|
||||
}
|
||||
|
||||
// The ogg time stamping and pre-skip is always timed at 48000.
|
||||
aOutputDuration = frameCopied * (kOpusSamplingRate / mSamplingRate);
|
||||
if (mResampler) {
|
||||
nsAutoTArray<AudioDataValue, 9600> resamplingDest;
|
||||
// We want to consume all the input data, so we slightly oversize the
|
||||
// resampled data buffer so we can fit the output data in. We cannot really
|
||||
// predict the output frame count at each call.
|
||||
uint32_t outframes = frameCopied * kOpusSamplingRate / mSamplingRate + 1;
|
||||
uint32_t inframes = frameCopied;
|
||||
|
||||
resamplingDest.SetLength(outframes * mChannels);
|
||||
|
||||
#if MOZ_SAMPLE_TYPE_S16
|
||||
short* in = reinterpret_cast<short*>(pcm.Elements());
|
||||
short* out = reinterpret_cast<short*>(resamplingDest.Elements());
|
||||
speex_resampler_process_interleaved_int(mResampler, in, &inframes,
|
||||
out, &outframes);
|
||||
#else
|
||||
float* in = reinterpret_cast<float*>(pcm.Elements());
|
||||
float* out = reinterpret_cast<float*>(resamplingDest.Elements());
|
||||
speex_resampler_process_interleaved_float(mResampler, in, &inframes,
|
||||
out, &outframes);
|
||||
#endif
|
||||
|
||||
pcm = resamplingDest;
|
||||
// This is always at 48000Hz.
|
||||
aOutputDuration = outframes;
|
||||
} else {
|
||||
// The ogg time stamping and pre-skip is always timed at 48000.
|
||||
aOutputDuration = frameCopied * (kOpusSamplingRate / mSamplingRate);
|
||||
}
|
||||
|
||||
// Remove the raw data which has been pulled to pcm buffer.
|
||||
// The value of frameCopied should equal to (or smaller than, if eos)
|
||||
|
@ -294,6 +336,9 @@ OpusTrackEncoder::GetEncodedTrack(nsTArray<uint8_t>* aOutput,
|
|||
// encoding.
|
||||
if (mSourceSegment->GetDuration() == 0 && mEndOfStream) {
|
||||
mDoneEncoding = true;
|
||||
if (mResampler) {
|
||||
speex_resampler_destroy(mResampler);
|
||||
}
|
||||
LOG("[Opus] Done encoding.");
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#ifndef OpusTrackEncoder_h_
|
||||
#define OpusTrackEncoder_h_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <speex/speex_resampler.h>
|
||||
#include "TrackEncoder.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
|
@ -35,6 +37,12 @@ private:
|
|||
DATA
|
||||
} mEncoderState;
|
||||
|
||||
/**
|
||||
* Get the samplerate of the data to be fed to the Opus encoder. This might be
|
||||
* different from the intput samplerate if resampling occurs.
|
||||
*/
|
||||
int GetOutputSampleRate();
|
||||
|
||||
/**
|
||||
* The Opus encoder from libopus.
|
||||
*/
|
||||
|
@ -54,6 +62,12 @@ private:
|
|||
* in order to align the time of input and output.
|
||||
*/
|
||||
int mLookahead;
|
||||
|
||||
/**
|
||||
* If the input sample rate does not divide 48kHz evenly, the input data are
|
||||
* resampled.
|
||||
*/
|
||||
SpeexResamplerState* mResampler;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -345,6 +345,10 @@ nsresult MediaOmxReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndT
|
|||
{
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
|
||||
VideoFrameContainer* container = mDecoder->GetVideoFrameContainer();
|
||||
if (container && container->GetImageContainer()) {
|
||||
container->GetImageContainer()->ClearAllImagesExceptFront();
|
||||
}
|
||||
mVideoQueue.Reset();
|
||||
mAudioQueue.Reset();
|
||||
|
||||
|
|
|
@ -231,6 +231,7 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED_1(AudioDestinationNode, AudioNode,
|
|||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AudioDestinationNode)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgentCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_END_INHERITING(AudioNode)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(AudioDestinationNode, AudioNode)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIAudioChannelAgent.h"
|
||||
#include "AudioChannelCommon.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -21,6 +22,7 @@ class AudioContext;
|
|||
class AudioDestinationNode : public AudioNode
|
||||
, public nsIDOMEventListener
|
||||
, public nsIAudioChannelAgentCallback
|
||||
, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
// This node type knows what MediaStreamGraph to use based on
|
||||
|
|
|
@ -50,13 +50,13 @@ DelayProcessor::Process(const double *aPerFrameDelays,
|
|||
MOZ_ASSERT(readPosition >= 0.0, "Why are we reading before the beginning of the buffer?");
|
||||
|
||||
// Here is a the reason why readIndex1 and readIndex will never be out
|
||||
// of bounds. The maximum value for bufferLength is 180 * 48000 (see
|
||||
// AudioContext::CreateDelay). The maximum value for mCurrentDelay is
|
||||
// 180.0, so initially readPosition cannot be more than bufferLength +
|
||||
// a fraction less than 1. Then we take care of that case by
|
||||
// subtracting bufferLength from it if needed. So, if
|
||||
// |bufferLength-readPosition<1.0|, readIndex1 will end up being zero.
|
||||
// If |1.0<=bufferLength-readPosition<2.0|, readIndex1 will be
|
||||
// of bounds. The maximum value for bufferLength is
|
||||
// 180 * AudioContext.samplerate (see AudioContext::CreateDelay). The
|
||||
// maximum value for mCurrentDelay is 180.0, so initially readPosition
|
||||
// cannot be more than bufferLength + a fraction less than 1. Then we
|
||||
// take care of that case by subtracting bufferLength from it if needed.
|
||||
// So, if |bufferLength-readPosition<1.0|, readIndex1 will end up being
|
||||
// zero. If |1.0<=bufferLength-readPosition<2.0|, readIndex1 will be
|
||||
// bufferLength-1 and readIndex2 will be 0.
|
||||
int readIndex1 = int(readPosition);
|
||||
int readIndex2 = (readIndex1 + 1) % bufferLength;
|
||||
|
|
Двоичные данные
content/media/webaudio/test/audio-expected.wav
Двоичные данные
content/media/webaudio/test/audio-expected.wav
Двоичный файл не отображается.
|
@ -12,15 +12,14 @@ support-files =
|
|||
small-shot-expected.wav
|
||||
small-shot-mono-expected.wav
|
||||
small-shot.ogg
|
||||
ting-dualchannel44.1-expected.wav
|
||||
ting-dualchannel44.1.ogg
|
||||
ting-dualchannel48-expected.wav
|
||||
ting-dualchannel48.ogg
|
||||
ting-expected.wav
|
||||
ting-mono-dualchannel44.1-expected.wav
|
||||
ting-mono-dualchannel48-expected.wav
|
||||
ting-mono-expected.wav
|
||||
ting.ogg
|
||||
ting-44.1k-1ch.ogg
|
||||
ting-44.1k-2ch.ogg
|
||||
ting-48k-1ch.ogg
|
||||
ting-48k-2ch.ogg
|
||||
ting-44.1k-1ch.wav
|
||||
ting-44.1k-2ch.wav
|
||||
ting-48k-1ch.wav
|
||||
ting-48k-2ch.wav
|
||||
webaudio.js
|
||||
|
||||
[test_AudioBuffer.html]
|
||||
|
|
|
@ -13,7 +13,6 @@ SimpleTest.waitForExplicitFinish();
|
|||
addLoadEvent(function() {
|
||||
var ac = new AudioContext();
|
||||
ok(ac, "Create a AudioContext object");
|
||||
is(ac.sampleRate, 48000, "Correct sample rate");
|
||||
ok(ac instanceof EventTarget, "AudioContexts must be EventTargets");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
|
|
@ -105,63 +105,91 @@ function createWaveFileData(audioBuffer) {
|
|||
</script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var cx = new AudioContext();
|
||||
|
||||
// fuzzTolerance and fuzzToleranceMobile are used to determine fuzziness
|
||||
// thresholds. They're needed to make sure that we can deal with neglibible
|
||||
// differences in the binary buffer caused as a result of resampling the
|
||||
// audio. fuzzToleranceMobile is typically larger on mobile platforms since
|
||||
// we do fixed-point resampling as opposed to floating-point resampling on
|
||||
// those platforms.
|
||||
var tests = [
|
||||
// A normal ogg file, 44.1khz
|
||||
var files = [
|
||||
// An ogg file, 44.1khz, mono
|
||||
{
|
||||
url: "ting.ogg",
|
||||
url: "ting-44.1k-1ch.ogg",
|
||||
valid: true,
|
||||
expected: "ting-expected.wav",
|
||||
expectedMono: "ting-mono-expected.wav",
|
||||
numberOfChannels: 2,
|
||||
duration: 0.6936,
|
||||
length: 33294,
|
||||
fuzzTolerance: 38,
|
||||
fuzzToleranceMobile: 15906
|
||||
expected: "ting-44.1k-1ch.wav",
|
||||
numberOfChannels: 1,
|
||||
frames: 30592,
|
||||
sampleRate: 44100,
|
||||
duration: 0.693,
|
||||
fuzzTolerance: 5,
|
||||
fuzzToleranceMobile: 1284
|
||||
},
|
||||
// An ogg file with two different channels, 44.1khz
|
||||
// An ogg file, 44.1khz, stereo
|
||||
{
|
||||
url: "ting-dualchannel44.1.ogg",
|
||||
url: "ting-44.1k-2ch.ogg",
|
||||
valid: true,
|
||||
expected: "ting-dualchannel44.1-expected.wav",
|
||||
expectedMono: "ting-mono-dualchannel44.1-expected.wav",
|
||||
expected: "ting-44.1k-2ch.wav",
|
||||
numberOfChannels: 2,
|
||||
duration: 0.6932,
|
||||
length: 33274,
|
||||
fuzzTolerance: 39,
|
||||
fuzzToleranceMobile: 16798
|
||||
frames: 30592,
|
||||
sampleRate: 44100,
|
||||
duration: 0.693,
|
||||
fuzzTolerance: 6,
|
||||
fuzzToleranceMobile: 2544
|
||||
},
|
||||
// An ogg file with two different channels, 48khz
|
||||
// An ogg file, 48khz, mono
|
||||
{
|
||||
url: "ting-dualchannel48.ogg",
|
||||
url: "ting-48k-1ch.ogg",
|
||||
valid: true,
|
||||
expected: "ting-dualchannel48-expected.wav",
|
||||
expectedMono: "ting-mono-dualchannel48-expected.wav",
|
||||
numberOfChannels: 2,
|
||||
duration: 0.6373,
|
||||
length: 30592,
|
||||
fuzzTolerance: 9,
|
||||
fuzzToleranceMobile: 8000
|
||||
expected: "ting-48k-1ch.wav",
|
||||
numberOfChannels: 1,
|
||||
frames: 33297,
|
||||
sampleRate: 48000,
|
||||
duration: 0.693,
|
||||
fuzzTolerance: 7,
|
||||
fuzzToleranceMobile: 7070
|
||||
},
|
||||
// An ogg file which needs to be resampled
|
||||
// An ogg file, 48khz, stereo
|
||||
{
|
||||
url: "small-shot.ogg",
|
||||
url: "ting-48k-2ch.ogg",
|
||||
valid: true,
|
||||
expected: "small-shot-expected.wav",
|
||||
expectedMono: "small-shot-mono-expected.wav",
|
||||
expected: "ting-48k-2ch.wav",
|
||||
numberOfChannels: 2,
|
||||
duration: 0.2760,
|
||||
length: 13248,
|
||||
fuzzTolerance: 76,
|
||||
fuzzToleranceMobile: 14844
|
||||
frames: 33297,
|
||||
sampleRate: 48000,
|
||||
duration: 0.693,
|
||||
fuzzTolerance: 12,
|
||||
fuzzToleranceMobile: 13982
|
||||
},
|
||||
// A wave file
|
||||
//{ url: "24bit-44khz.wav", valid: true, expected: "24bit-44khz-expected.wav" },
|
||||
// Make sure decoding a wave file results in the same buffer (for both the
|
||||
// resampling and non-resampling cases)
|
||||
{
|
||||
url: "ting-44.1k-1ch.wav",
|
||||
valid: true,
|
||||
expected: "ting-44.1k-1ch.wav",
|
||||
numberOfChannels: 1,
|
||||
frames: 30592,
|
||||
sampleRate: 44100,
|
||||
duration: 0.693,
|
||||
fuzzTolerance: 0,
|
||||
fuzzToleranceMobile: 0
|
||||
},
|
||||
{
|
||||
url: "ting-48k-1ch.wav",
|
||||
valid: true,
|
||||
expected: "ting-48k-1ch.wav",
|
||||
numberOfChannels: 1,
|
||||
frames: 33297,
|
||||
sampleRate: 48000,
|
||||
duration: 0.693,
|
||||
fuzzTolerance: 0,
|
||||
fuzzToleranceMobile: 0
|
||||
},
|
||||
// // A wave file
|
||||
// //{ url: "24bit-44khz.wav", valid: true, expected: "24bit-44khz-expected.wav" },
|
||||
// A non-audio file
|
||||
{ url: "invalid.txt", valid: false },
|
||||
// A webm file with no audio
|
||||
|
@ -171,24 +199,12 @@ var tests = [
|
|||
url: "audio.ogv",
|
||||
valid: true,
|
||||
expected: "audio-expected.wav",
|
||||
expectedMono: "audio-mono-expected.wav",
|
||||
numberOfChannels: 2,
|
||||
sampleRate: 44100,
|
||||
frames: 47680,
|
||||
duration: 1.0807,
|
||||
length: 51872,
|
||||
fuzzTolerance: 91427,
|
||||
fuzzToleranceMobile: 119684
|
||||
},
|
||||
// Make sure decoding a wave file results in the same buffer
|
||||
{
|
||||
url: "audio-expected.wav",
|
||||
valid: true,
|
||||
expected: "audio-expected.wav",
|
||||
expectedMono: "audio-mono-expected-2.wav",
|
||||
numberOfChannels: 2,
|
||||
duration: 1.0807,
|
||||
length: 51872,
|
||||
fuzzTolerance: 0,
|
||||
fuzzToleranceMobile: 0
|
||||
fuzzTolerance: 106,
|
||||
fuzzToleranceMobile: 3482
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -198,7 +214,7 @@ function fuzzyMemcmp(buf1, buf2, fuzz) {
|
|||
var difference = 0;
|
||||
is(buf1.length, buf2.length, "same length");
|
||||
for (var i = 0; i < buf1.length; ++i) {
|
||||
if (buf1[i] != buf2[i]) {
|
||||
if (Math.abs(buf1[i] - buf2[i])) {
|
||||
++difference;
|
||||
}
|
||||
}
|
||||
|
@ -216,17 +232,20 @@ function getFuzzTolerance(test) {
|
|||
}
|
||||
|
||||
function checkAudioBuffer(buffer, test, callback, monoTest) {
|
||||
is(buffer.numberOfChannels, monoTest ? 1 : test.numberOfChannels, "Correct number of channels");
|
||||
ok(Math.abs(buffer.duration - test.duration) < 1e-4, "Correct duration");
|
||||
if (Math.abs(buffer.duration - test.duration) >= 1e-4) {
|
||||
is(buffer.numberOfChannels, test.numberOfChannels, "Correct number of channels");
|
||||
ok(Math.abs(buffer.duration - test.duration) < 1e-3, "Correct duration");
|
||||
if (Math.abs(buffer.duration - test.duration) >= 1e-3) {
|
||||
ok(false, "got: " + buffer.duration + ", expected: " + test.duration);
|
||||
}
|
||||
is(buffer.sampleRate, cx.sampleRate, "Correct sample rate");
|
||||
is(buffer.length, test.length, "Correct length");
|
||||
// Take into account the resampling when checking the size
|
||||
var SRCRate = test.sampleRate / cx.sampleRate;
|
||||
ok(Math.abs(buffer.length * SRCRate - test.frames) < test.frames * 0.01, "Correct length");
|
||||
|
||||
var wave = createWaveFileData(buffer);
|
||||
|
||||
var getExpected = new XMLHttpRequest();
|
||||
getExpected.open("GET", monoTest ? test.expectedMono : test.expected, true);
|
||||
getExpected.open("GET", test.expected, true);
|
||||
getExpected.responseType = "arraybuffer";
|
||||
getExpected.onload = function() {
|
||||
ok(fuzzyMemcmp(wave, new Uint8Array(getExpected.response), getFuzzTolerance(test)), "Received expected decoded data");
|
||||
|
@ -248,12 +267,7 @@ function runTest(test, callback) {
|
|||
checkAudioBuffer(result, test, function() {
|
||||
result = cx.createBuffer(xhr.response, false);
|
||||
checkAudioBuffer(result, test, function() {
|
||||
if ("expectedMono" in test) {
|
||||
result = cx.createBuffer(xhr.response, true);
|
||||
checkAudioBuffer(result, test, callback, true);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}, false);
|
||||
}, false);
|
||||
}, function onFailure() {
|
||||
|
@ -267,17 +281,13 @@ function runTest(test, callback) {
|
|||
}
|
||||
|
||||
function runNextTest() {
|
||||
if (tests.length) {
|
||||
runTest(tests.shift(), runNextTest);
|
||||
if (files.length) {
|
||||
runTest(files.shift(), runNextTest);
|
||||
} else {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var cx = new AudioContext();
|
||||
|
||||
// Run some simple tests first
|
||||
function callbackShouldNeverRun() {
|
||||
ok(false, "callback should not fire");
|
||||
|
@ -298,7 +308,7 @@ expectTypeError(function() {
|
|||
cx.decodeAudioData(new Uint8Array(100), callbackShouldNeverRun, callbackShouldNeverRun);
|
||||
});
|
||||
|
||||
if (cx.sampleRate == 48000) {
|
||||
if (cx.sampleRate >= 44100) {
|
||||
// Now, let's get real!
|
||||
runNextTest();
|
||||
} else {
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
content/media/webaudio/test/ting-dualchannel44.1-expected.wav
Двоичные данные
content/media/webaudio/test/ting-dualchannel44.1-expected.wav
Двоичный файл не отображается.
Двоичные данные
content/media/webaudio/test/ting-dualchannel44.1.ogg
Двоичные данные
content/media/webaudio/test/ting-dualchannel44.1.ogg
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
content/media/webaudio/test/ting-dualchannel48-expected.wav
Двоичные данные
content/media/webaudio/test/ting-dualchannel48-expected.wav
Двоичный файл не отображается.
Двоичные данные
content/media/webaudio/test/ting-dualchannel48.ogg
Двоичные данные
content/media/webaudio/test/ting-dualchannel48.ogg
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
content/media/webaudio/test/ting-expected.wav
Двоичные данные
content/media/webaudio/test/ting-expected.wav
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
content/media/webaudio/test/ting-mono-dualchannel48-expected.wav
Двоичные данные
content/media/webaudio/test/ting-mono-dualchannel48-expected.wav
Двоичный файл не отображается.
Двоичные данные
content/media/webaudio/test/ting-mono-expected.wav
Двоичные данные
content/media/webaudio/test/ting-mono-expected.wav
Двоичный файл не отображается.
Двоичные данные
content/media/webaudio/test/ting.ogg
Двоичные данные
content/media/webaudio/test/ting.ogg
Двоичный файл не отображается.
|
@ -3,6 +3,8 @@
|
|||
# To: /content/canvas/test/reftest
|
||||
skip-if(xulFennec) include ../../canvas/test/reftest/reftest.list
|
||||
|
||||
include ../../base/test/reftest/reftest.list # bug 920877
|
||||
|
||||
== bug453105.html bug453105-ref.html
|
||||
== optiontext.html optiontext-ref.html
|
||||
== bug456008.xhtml bug456008-ref.html
|
||||
|
|
|
@ -166,7 +166,7 @@ nsXBLProtoImpl::InitTargetObjects(nsXBLPrototypeBinding* aBinding,
|
|||
dom::XULElementBinding::GetConstructorObject(cx, global, defineOnGlobal);
|
||||
}
|
||||
|
||||
rv = nsContentUtils::WrapNative(cx, global, aBoundElement, v.address(),
|
||||
rv = nsContentUtils::WrapNative(cx, global, aBoundElement, &v,
|
||||
getter_AddRefs(wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -309,7 +309,7 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement)
|
|||
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
nsresult rv =
|
||||
nsContentUtils::WrapNative(cx, globalObject, aBoundElement, v.address(),
|
||||
nsContentUtils::WrapNative(cx, globalObject, aBoundElement, &v,
|
||||
getter_AddRefs(wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
|
|||
// scope if one doesn't already exist, and potentially wraps it cross-
|
||||
// compartment into our scope (via aAllowWrapping=true).
|
||||
JS::Rooted<JS::Value> targetV(cx, JS::UndefinedValue());
|
||||
rv = nsContentUtils::WrapNative(cx, scopeObject, scriptTarget, targetV.address(), nullptr,
|
||||
rv = nsContentUtils::WrapNative(cx, scopeObject, scriptTarget, &targetV, nullptr,
|
||||
/* aAllowWrapping = */ true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -1385,7 +1385,7 @@ nsXULTemplateBuilder::InitHTMLTemplateRoot()
|
|||
JS::Rooted<JSObject*> scope(jscontext, global->GetGlobalJSObject());
|
||||
JS::Rooted<JS::Value> v(jscontext);
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
|
||||
rv = nsContentUtils::WrapNative(jscontext, scope, mRoot, mRoot, v.address(),
|
||||
rv = nsContentUtils::WrapNative(jscontext, scope, mRoot, mRoot, &v,
|
||||
getter_AddRefs(wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -1396,7 +1396,7 @@ nsXULTemplateBuilder::InitHTMLTemplateRoot()
|
|||
JS::Rooted<JS::Value> jsdatabase(jscontext);
|
||||
rv = nsContentUtils::WrapNative(jscontext, scope, mDB,
|
||||
&NS_GET_IID(nsIRDFCompositeDataSource),
|
||||
jsdatabase.address(), getter_AddRefs(wrapper));
|
||||
&jsdatabase, getter_AddRefs(wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool ok;
|
||||
|
@ -1413,7 +1413,7 @@ nsXULTemplateBuilder::InitHTMLTemplateRoot()
|
|||
rv = nsContentUtils::WrapNative(jscontext, jselement,
|
||||
static_cast<nsIXULTemplateBuilder*>(this),
|
||||
&NS_GET_IID(nsIXULTemplateBuilder),
|
||||
jsbuilder.address(), getter_AddRefs(wrapper));
|
||||
&jsbuilder, getter_AddRefs(wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool ok;
|
||||
|
|
|
@ -347,27 +347,24 @@ WebappsApplication.prototype = {
|
|||
this._downloadError = null;
|
||||
|
||||
this.initDOMRequestHelper(aWindow, [
|
||||
"Webapps:OfflineCache",
|
||||
"Webapps:CheckForUpdate:Return:OK",
|
||||
"Webapps:CheckForUpdate:Return:KO",
|
||||
"Webapps:PackageEvent",
|
||||
"Webapps:Connect:Return:OK",
|
||||
"Webapps:Connect:Return:KO",
|
||||
"Webapps:GetConnections:Return:OK"
|
||||
"Webapps:FireEvent",
|
||||
"Webapps:GetConnections:Return:OK",
|
||||
"Webapps:UpdateState"
|
||||
]);
|
||||
|
||||
cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
|
||||
{
|
||||
messages: ["Webapps:OfflineCache",
|
||||
"Webapps:PackageEvent",
|
||||
"Webapps:CheckForUpdate:Return:OK"],
|
||||
app: {
|
||||
id: this.id,
|
||||
manifestURL: this.manifestURL,
|
||||
installState: this.installState,
|
||||
downloading: this.downloading
|
||||
}
|
||||
});
|
||||
cpmm.sendAsyncMessage("Webapps:RegisterForMessages", {
|
||||
messages: ["Webapps:FireEvent",
|
||||
"Webapps:UpdateState"],
|
||||
app: {
|
||||
id: this.id,
|
||||
manifestURL: this.manifestURL,
|
||||
installState: this.installState,
|
||||
downloading: this.downloading
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
get manifest() {
|
||||
|
@ -378,8 +375,10 @@ WebappsApplication.prototype = {
|
|||
},
|
||||
|
||||
get updateManifest() {
|
||||
return this.updateManifest = this._updateManifest ? ObjectWrapper.wrap(this._updateManifest, this._window)
|
||||
: null;
|
||||
return this.updateManifest =
|
||||
this._updateManifest ? ObjectWrapper.wrap(this._updateManifest,
|
||||
this._window)
|
||||
: null;
|
||||
},
|
||||
|
||||
set onprogress(aCallback) {
|
||||
|
@ -512,18 +511,42 @@ WebappsApplication.prototype = {
|
|||
|
||||
uninit: function() {
|
||||
this._onprogress = null;
|
||||
cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
|
||||
["Webapps:OfflineCache",
|
||||
"Webapps:PackageEvent",
|
||||
"Webapps:CheckForUpdate:Return:OK"]);
|
||||
cpmm.sendAsyncMessage("Webapps:UnregisterForMessages", [
|
||||
"Webapps:FireEvent",
|
||||
"Webapps:PackageEvent"
|
||||
]);
|
||||
|
||||
manifestCache.evict(this.manifestURL, this.innerWindowID);
|
||||
},
|
||||
|
||||
_fireEvent: function(aName, aHandler) {
|
||||
if (aHandler) {
|
||||
let event = new this._window.MozApplicationEvent(aName, { application: this });
|
||||
aHandler.handleEvent(event);
|
||||
_fireEvent: function(aName) {
|
||||
let handler = this["_on" + aName];
|
||||
if (handler) {
|
||||
let event = new this._window.MozApplicationEvent(aName, {
|
||||
application: this
|
||||
});
|
||||
try {
|
||||
handler.handleEvent(event);
|
||||
} catch (ex) {
|
||||
dump("Event handler expection " + ex + "\n");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_updateState: function(aMsg) {
|
||||
if (aMsg.app) {
|
||||
for (let prop in aMsg.app) {
|
||||
this[prop] = aMsg.app[prop];
|
||||
}
|
||||
}
|
||||
|
||||
if (aMsg.error) {
|
||||
this._downloadError = aMsg.error;
|
||||
}
|
||||
|
||||
if (aMsg.manifest) {
|
||||
this._manifest = aMsg.manifest;
|
||||
manifestCache.evict(this.manifestURL, this.innerWindowID);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -540,10 +563,11 @@ WebappsApplication.prototype = {
|
|||
|
||||
// ondownload* callbacks should be triggered on all app instances
|
||||
if ((msg.oid != this._id || !req) &&
|
||||
aMessage.name !== "Webapps:OfflineCache" &&
|
||||
aMessage.name !== "Webapps:PackageEvent" &&
|
||||
aMessage.name !== "Webapps:CheckForUpdate:Return:OK")
|
||||
aMessage.name !== "Webapps:FireEvent" &&
|
||||
aMessage.name !== "Webapps:UpdateState") {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Launch:Return:KO":
|
||||
this.removeMessageListeners(["Webapps:Launch:Return:OK",
|
||||
|
@ -558,108 +582,36 @@ WebappsApplication.prototype = {
|
|||
case "Webapps:CheckForUpdate:Return:KO":
|
||||
Services.DOMRequest.fireError(req, msg.error);
|
||||
break;
|
||||
case "Webapps:CheckForUpdate:Return:OK":
|
||||
if (msg.manifestURL != this.manifestURL)
|
||||
return;
|
||||
|
||||
manifestCache.evict(this.manifestURL, this.innerWindowID);
|
||||
|
||||
let hiddenProps = ["manifest", "updateManifest"];
|
||||
let updatableProps = ["installOrigin", "installTime", "installState",
|
||||
"lastUpdateCheck", "updateTime", "progress", "downloadAvailable",
|
||||
"downloading", "readyToApplyDownload", "downloadSize"];
|
||||
// Props that we don't update: origin, receipts, manifestURL, removable.
|
||||
|
||||
updatableProps.forEach(function(prop) {
|
||||
if (msg.app[prop]) {
|
||||
this[prop] = msg.app[prop];
|
||||
}
|
||||
}, this);
|
||||
|
||||
hiddenProps.forEach(function(prop) {
|
||||
if (msg.app[prop]) {
|
||||
this["_" + prop] = msg.app[prop];
|
||||
}
|
||||
}, this);
|
||||
|
||||
if (msg.event == "downloadapplied") {
|
||||
this._fireEvent("downloadapplied", this._ondownloadapplied);
|
||||
} else if (msg.event == "downloadavailable") {
|
||||
this._fireEvent("downloadavailable", this._ondownloadavailable);
|
||||
case "Webapps:FireEvent":
|
||||
if (msg.manifestURL != this.manifestURL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The parent might ask childs to trigger more than one event in one
|
||||
// shot, so in order to avoid needless IPC we allow an array for the
|
||||
// 'eventType' IPC message field.
|
||||
if (!Array.isArray(msg.eventType)) {
|
||||
msg.eventType = [msg.eventType];
|
||||
}
|
||||
|
||||
msg.eventType.forEach((aEventType) => {
|
||||
if ("_on" + aEventType in this) {
|
||||
this._fireEvent(aEventType);
|
||||
} else {
|
||||
dump("Unsupported event type " + aEventType + "\n");
|
||||
}
|
||||
});
|
||||
|
||||
if (req) {
|
||||
Services.DOMRequest.fireSuccess(req, this.manifestURL);
|
||||
}
|
||||
break;
|
||||
case "Webapps:OfflineCache":
|
||||
if (msg.manifest != this.manifestURL)
|
||||
case "Webapps:UpdateState":
|
||||
if (msg.manifestURL != this.manifestURL) {
|
||||
return;
|
||||
|
||||
if ("installState" in msg) {
|
||||
this.installState = msg.installState;
|
||||
this.progress = msg.progress;
|
||||
if (this.installState == "installed") {
|
||||
this._downloadError = null;
|
||||
this.downloading = false;
|
||||
this.downloadAvailable = false;
|
||||
this._fireEvent("downloadsuccess", this._ondownloadsuccess);
|
||||
this._fireEvent("downloadapplied", this._ondownloadapplied);
|
||||
} else {
|
||||
this.downloading = true;
|
||||
this._fireEvent("downloadprogress", this._onprogress);
|
||||
}
|
||||
} else if (msg.error) {
|
||||
this._downloadError = msg.error;
|
||||
this.downloading = false;
|
||||
this._fireEvent("downloaderror", this._ondownloaderror);
|
||||
}
|
||||
break;
|
||||
case "Webapps:PackageEvent":
|
||||
if (msg.manifestURL != this.manifestURL)
|
||||
return;
|
||||
|
||||
// Set app values according to parent process results.
|
||||
let app = msg.app;
|
||||
this.downloading = app.downloading;
|
||||
this.downloadAvailable = app.downloadAvailable;
|
||||
this.downloadSize = app.downloadSize || 0;
|
||||
this.installState = app.installState;
|
||||
this.progress = app.progress || msg.progress || 0;
|
||||
this.readyToApplyDownload = app.readyToApplyDownload;
|
||||
this.updateTime = app.updateTime;
|
||||
this.origin = app.origin;
|
||||
|
||||
switch(msg.type) {
|
||||
case "error":
|
||||
case "canceled":
|
||||
this._downloadError = msg.error;
|
||||
this._fireEvent("downloaderror", this._ondownloaderror);
|
||||
break;
|
||||
case "progress":
|
||||
this._fireEvent("downloadprogress", this._onprogress);
|
||||
break;
|
||||
case "installed":
|
||||
manifestCache.evict(this.manifestURL, this.innerWindowID);
|
||||
this._manifest = msg.manifest;
|
||||
this._fireEvent("downloadsuccess", this._ondownloadsuccess);
|
||||
this._fireEvent("downloadapplied", this._ondownloadapplied);
|
||||
break;
|
||||
case "downloaded":
|
||||
// We don't update the packaged apps manifests until they
|
||||
// are installed or until the update is unstaged.
|
||||
if (msg.manifest) {
|
||||
manifestCache.evict(this.manifestURL, this.innerWindowID);
|
||||
this._manifest = msg.manifest;
|
||||
}
|
||||
this._fireEvent("downloadsuccess", this._ondownloadsuccess);
|
||||
break;
|
||||
case "applied":
|
||||
manifestCache.evict(this.manifestURL, this.innerWindowID);
|
||||
this._manifest = msg.manifest;
|
||||
this._fireEvent("downloadapplied", this._ondownloadapplied);
|
||||
break;
|
||||
}
|
||||
this._updateState(msg);
|
||||
break;
|
||||
case "Webapps:ClearBrowserData:Return":
|
||||
this.removeMessageListeners(aMessage.name);
|
||||
|
@ -667,10 +619,10 @@ WebappsApplication.prototype = {
|
|||
break;
|
||||
case "Webapps:Connect:Return:OK":
|
||||
let messagePorts = [];
|
||||
msg.messagePortIDs.forEach(function(aPortID) {
|
||||
msg.messagePortIDs.forEach((aPortID) => {
|
||||
let port = new this._window.MozInterAppMessagePort(aPortID);
|
||||
messagePorts.push(port);
|
||||
}, this);
|
||||
});
|
||||
req.resolve(messagePorts);
|
||||
break;
|
||||
case "Webapps:Connect:Return:KO":
|
||||
|
@ -678,13 +630,13 @@ WebappsApplication.prototype = {
|
|||
break;
|
||||
case "Webapps:GetConnections:Return:OK":
|
||||
let connections = [];
|
||||
msg.connections.forEach(function(aConnection) {
|
||||
msg.connections.forEach((aConnection) => {
|
||||
let connection =
|
||||
new this._window.MozInterAppConnection(aConnection.keyword,
|
||||
aConnection.pubAppManifestURL,
|
||||
aConnection.subAppManifestURL);
|
||||
connections.push(connection);
|
||||
}, this);
|
||||
});
|
||||
req.resolve(connections);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ function supportSystemMessages() {
|
|||
}
|
||||
|
||||
// Minimum delay between two progress events while downloading, in ms.
|
||||
const MIN_PROGRESS_EVENT_DELAY = 1000;
|
||||
const MIN_PROGRESS_EVENT_DELAY = 1500;
|
||||
|
||||
const WEBAPP_RUNTIME = Services.appinfo.ID == "webapprt@mozilla.org";
|
||||
|
||||
|
@ -945,8 +945,6 @@ this.DOMApplicationRegistry = {
|
|||
addMessageListener: function(aMsgNames, aApp, aMm) {
|
||||
aMsgNames.forEach(function (aMsgName) {
|
||||
let man = aApp && aApp.manifestURL;
|
||||
debug("Adding messageListener for: " + aMsgName + "App: " +
|
||||
man);
|
||||
if (!(aMsgName in this.children)) {
|
||||
this.children[aMsgName] = [];
|
||||
}
|
||||
|
@ -966,8 +964,8 @@ this.DOMApplicationRegistry = {
|
|||
});
|
||||
|
||||
// If it wasn't registered before, let's update its state
|
||||
if ((aMsgName === 'Webapps:PackageEvent') ||
|
||||
(aMsgName === 'Webapps:OfflineCache')) {
|
||||
if ((aMsgName === 'Webapps:FireEvent') ||
|
||||
(aMsgName === 'Webapps:UpdateState')) {
|
||||
if (man) {
|
||||
let app = this.getAppByManifestURL(aApp.manifestURL);
|
||||
if (app && ((aApp.installState !== app.installState) ||
|
||||
|
@ -1124,9 +1122,9 @@ this.DOMApplicationRegistry = {
|
|||
// Webapps:Install:Return:OK
|
||||
// Webapps:Uninstall:Return:OK
|
||||
// Webapps:Uninstall:Broadcast:Return:OK
|
||||
// Webapps:OfflineCache
|
||||
// Webapps:FireEvent
|
||||
// Webapps:checkForUpdate:Return:OK
|
||||
// Webapps:PackageEvent
|
||||
// Webapps:UpdateState
|
||||
broadcastMessage: function broadcastMessage(aMsgName, aContent) {
|
||||
if (!(aMsgName in this.children)) {
|
||||
return;
|
||||
|
@ -1140,7 +1138,7 @@ this.DOMApplicationRegistry = {
|
|||
return FileUtils.getDir(DIRECTORY_NAME, ["webapps", aId], true, true);
|
||||
},
|
||||
|
||||
_writeFile: function ss_writeFile(aFile, aData, aCallbak) {
|
||||
_writeFile: function _writeFile(aFile, aData, aCallback) {
|
||||
debug("Saving " + aFile.path);
|
||||
// Initialize the file output stream.
|
||||
let ostream = FileUtils.openSafeFileOutputStream(aFile);
|
||||
|
@ -1153,8 +1151,9 @@ this.DOMApplicationRegistry = {
|
|||
// Asynchronously copy the data to the file.
|
||||
let istream = converter.convertToInputStream(aData);
|
||||
NetUtil.asyncCopy(istream, ostream, function(rc) {
|
||||
if (aCallbak)
|
||||
aCallbak();
|
||||
if (aCallback) {
|
||||
aCallback();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1216,22 +1215,15 @@ this.DOMApplicationRegistry = {
|
|||
let app = this.webapps[download.appId];
|
||||
|
||||
if (download.cacheUpdate) {
|
||||
// Cancel hosted app download.
|
||||
app.isCanceling = true;
|
||||
try {
|
||||
download.cacheUpdate.cancel();
|
||||
} catch (e) {
|
||||
delete app.isCanceling;
|
||||
debug (e);
|
||||
}
|
||||
} else if (download.channel) {
|
||||
// Cancel packaged app download.
|
||||
app.isCanceling = true;
|
||||
try {
|
||||
download.channel.cancel(Cr.NS_BINDING_ABORTED);
|
||||
} catch(e) {
|
||||
delete app.isCanceling;
|
||||
}
|
||||
} catch(e) { }
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -1241,11 +1233,19 @@ this.DOMApplicationRegistry = {
|
|||
app.installState = download.previousState;
|
||||
app.downloading = false;
|
||||
this._saveApps((function() {
|
||||
this.broadcastMessage("Webapps:PackageEvent",
|
||||
{ type: "canceled",
|
||||
manifestURL: app.manifestURL,
|
||||
app: app,
|
||||
error: error });
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
app: {
|
||||
progress: 0,
|
||||
installState: download.previousState,
|
||||
downloading: false
|
||||
},
|
||||
error: error,
|
||||
manifestURL: app.manifestURL,
|
||||
})
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloaderror",
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
}).bind(this));
|
||||
AppDownloadManager.remove(aManifestURL);
|
||||
},
|
||||
|
@ -1267,11 +1267,14 @@ this.DOMApplicationRegistry = {
|
|||
// If the caller is trying to start a download but we have nothing to
|
||||
// download, send an error.
|
||||
if (!app.downloadAvailable) {
|
||||
this.broadcastMessage("Webapps:PackageEvent",
|
||||
{ type: "canceled",
|
||||
manifestURL: app.manifestURL,
|
||||
app: app,
|
||||
error: "NO_DOWNLOAD_AVAILABLE" });
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
error: "NO_DOWNLOAD_AVAILABLE",
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloaderror",
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1303,16 +1306,21 @@ this.DOMApplicationRegistry = {
|
|||
debug("appcache found");
|
||||
this.startOfflineCacheDownload(manifest, app, null, isUpdate);
|
||||
} else {
|
||||
// hosted app with no appcache, nothing to do, but we fire a
|
||||
// downloaded event
|
||||
// Hosted app with no appcache, nothing to do, but we fire a
|
||||
// downloaded event.
|
||||
debug("No appcache found, sending 'downloaded' for " + aManifestURL);
|
||||
app.downloadAvailable = false;
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:PackageEvent",
|
||||
{ type: "downloaded",
|
||||
manifestURL: aManifestURL,
|
||||
app: app,
|
||||
manifest: jsonManifest });
|
||||
DOMApplicationRegistry._saveApps();
|
||||
DOMApplicationRegistry._saveApps(function() {
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifest: jsonManifest,
|
||||
manifestURL: aManifestURL
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadsuccess",
|
||||
manifestURL: aManifestURL
|
||||
});
|
||||
});
|
||||
}
|
||||
}).bind(this));
|
||||
|
||||
|
@ -1321,7 +1329,8 @@ this.DOMApplicationRegistry = {
|
|||
|
||||
this._loadJSONAsync(file, (function(aJSON) {
|
||||
if (!aJSON) {
|
||||
debug("startDownload: No update manifest found at " + file.path + " " + aManifestURL);
|
||||
debug("startDownload: No update manifest found at " + file.path + " " +
|
||||
aManifestURL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1350,11 +1359,14 @@ this.DOMApplicationRegistry = {
|
|||
app.readyToApplyDownload = true;
|
||||
app.updateTime = Date.now();
|
||||
DOMApplicationRegistry._saveApps(function() {
|
||||
debug("About to fire Webapps:PackageEvent");
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:PackageEvent",
|
||||
{ type: "downloaded",
|
||||
manifestURL: aManifestURL,
|
||||
app: app });
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: aManifestURL
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadsuccess",
|
||||
manifestURL: aManifestURL
|
||||
});
|
||||
if (app.installState == "pending") {
|
||||
// We restarted a failed download, apply it automatically.
|
||||
DOMApplicationRegistry.applyDownload(aManifestURL);
|
||||
|
@ -1442,11 +1454,15 @@ this.DOMApplicationRegistry = {
|
|||
}
|
||||
this.updateDataStore(this.webapps[id].localId, app.origin,
|
||||
app.manifestURL, aData);
|
||||
this.broadcastMessage("Webapps:PackageEvent",
|
||||
{ type: "applied",
|
||||
manifestURL: app.manifestURL,
|
||||
app: app,
|
||||
manifest: aData });
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifest: aData,
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadapplied",
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
}).bind(this));
|
||||
}).bind(this));
|
||||
}).bind(this));
|
||||
|
@ -1475,6 +1491,14 @@ this.DOMApplicationRegistry = {
|
|||
aApp.downloading = true;
|
||||
aApp.progress = 0;
|
||||
DOMApplicationRegistry._saveApps((function() {
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: {
|
||||
downloading: true,
|
||||
installState: aApp.installState,
|
||||
progress: 0
|
||||
},
|
||||
manifestURL: aApp.manifestURL
|
||||
});
|
||||
let cacheUpdate = aProfileDir
|
||||
? updateSvc.scheduleCustomProfileUpdate(appcacheURI, docURI, aProfileDir)
|
||||
: updateSvc.scheduleAppUpdate(appcacheURI, docURI, aApp.localId, false);
|
||||
|
@ -1598,16 +1622,17 @@ this.DOMApplicationRegistry = {
|
|||
// event.
|
||||
app.downloadAvailable = true;
|
||||
app.downloadSize = manifest.size;
|
||||
aData.event = "downloadavailable";
|
||||
aData.app = {
|
||||
downloadAvailable: true,
|
||||
downloadSize: manifest.size,
|
||||
updateManifest: aManifest
|
||||
}
|
||||
app.updateManifest = aManifest;
|
||||
DOMApplicationRegistry._saveApps(function() {
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:CheckForUpdate:Return:OK",
|
||||
aData);
|
||||
delete aData.app.updateManifest;
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadavailable",
|
||||
manifestURL: app.manifestURL,
|
||||
requestID: aData.requestID
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1662,10 +1687,17 @@ this.DOMApplicationRegistry = {
|
|||
this.webapps[id] = app;
|
||||
this._saveApps(function() {
|
||||
let reg = DOMApplicationRegistry;
|
||||
aData.app = app;
|
||||
if (!manifest.appcache_path) {
|
||||
aData.event = "downloadapplied";
|
||||
reg.broadcastMessage("Webapps:CheckForUpdate:Return:OK", aData);
|
||||
reg.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifest: app.manifest,
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
reg.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadapplied",
|
||||
manifestURL: app.manifestURL,
|
||||
requestID: aData.requestID
|
||||
});
|
||||
} else {
|
||||
// Check if the appcache is updatable, and send "downloadavailable" or
|
||||
// "downloadapplied".
|
||||
|
@ -1673,14 +1705,24 @@ this.DOMApplicationRegistry = {
|
|||
observe: function(aSubject, aTopic, aObsData) {
|
||||
debug("updateHostedApp: updateSvc.checkForUpdate return for " +
|
||||
app.manifestURL + " - event is " + aTopic);
|
||||
aData.event =
|
||||
let eventType =
|
||||
aTopic == "offline-cache-update-available" ? "downloadavailable"
|
||||
: "downloadapplied";
|
||||
aData.app.downloadAvailable = (aData.event == "downloadavailable");
|
||||
reg._saveApps();
|
||||
reg.broadcastMessage("Webapps:CheckForUpdate:Return:OK", aData);
|
||||
app.downloadAvailable = (eventType == "downloadavailable");
|
||||
reg._saveApps(function() {
|
||||
reg.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifest: app.manifest,
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
reg.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: eventType,
|
||||
manifestURL: app.manifestURL,
|
||||
requestID: aData.requestID
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
debug("updateHostedApp: updateSvc.checkForUpdate for " +
|
||||
manifest.fullAppcachePath());
|
||||
updateSvc.checkForUpdate(Services.io.newURI(manifest.fullAppcachePath(), null, null),
|
||||
|
@ -1715,8 +1757,8 @@ this.DOMApplicationRegistry = {
|
|||
let onlyCheckAppCache = false;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
let appDir = FileUtils.getDir("coreAppsDir", ["webapps"], false);
|
||||
onlyCheckAppCache = (app.basePath == appDir.path);
|
||||
let appDir = FileUtils.getDir("coreAppsDir", ["webapps"], false);
|
||||
onlyCheckAppCache = (app.basePath == appDir.path);
|
||||
#endif
|
||||
|
||||
if (onlyCheckAppCache) {
|
||||
|
@ -1744,19 +1786,24 @@ this.DOMApplicationRegistry = {
|
|||
debug("onlyCheckAppCache updateSvc.checkForUpdate return for " +
|
||||
app.manifestURL + " - event is " + aTopic);
|
||||
if (aTopic == "offline-cache-update-available") {
|
||||
aData.event = "downloadavailable";
|
||||
app.downloadAvailable = true;
|
||||
aData.app = app;
|
||||
this._saveApps(function() {
|
||||
DOMApplicationRegistry.broadcastMessage(
|
||||
"Webapps:CheckForUpdate:Return:OK", aData);
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloadavailable",
|
||||
manifestURL: app.manifestURL,
|
||||
requestID: aData.requestID
|
||||
});
|
||||
});
|
||||
} else {
|
||||
aData.error = "NOT_UPDATABLE";
|
||||
aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:KO", aData);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let helper = new ManifestHelper(manifest);
|
||||
debug("onlyCheckAppCache - launch updateSvc.checkForUpdate for " +
|
||||
helper.fullAppcachePath());
|
||||
|
@ -1806,15 +1853,21 @@ this.DOMApplicationRegistry = {
|
|||
if (oldHash != hash) {
|
||||
updatePackagedApp.call(this, manifest);
|
||||
} else {
|
||||
// Like if we got a 304, just send a 'downloadapplied'
|
||||
// or downloadavailable event.
|
||||
aData.event = app.downloadAvailable ? "downloadavailable"
|
||||
: "downloadapplied";
|
||||
aData.app = {
|
||||
lastCheckedUpdate: app.lastCheckedUpdate
|
||||
}
|
||||
aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:OK", aData);
|
||||
this._saveApps();
|
||||
this._saveApps(function() {
|
||||
// Like if we got a 304, just send a 'downloadapplied'
|
||||
// or downloadavailable event.
|
||||
let eventType = app.downloadAvailable ? "downloadavailable"
|
||||
: "downloadapplied";
|
||||
aMm.sendAsyncMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
aMm.sendAsyncMessage("Webapps:FireEvent", {
|
||||
eventType: eventType,
|
||||
manifestURL: app.manifestURL,
|
||||
requestID: aData.requestID
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Update only the appcache if the manifest has not changed
|
||||
|
@ -1826,16 +1879,22 @@ this.DOMApplicationRegistry = {
|
|||
} else if (xhr.status == 304) {
|
||||
// The manifest has not changed.
|
||||
if (isPackage) {
|
||||
// If the app is a packaged app, we just send a 'downloadapplied'
|
||||
// or downloadavailable event.
|
||||
app.lastCheckedUpdate = Date.now();
|
||||
aData.event = app.downloadAvailable ? "downloadavailable"
|
||||
: "downloadapplied";
|
||||
aData.app = {
|
||||
lastCheckedUpdate: app.lastCheckedUpdate
|
||||
}
|
||||
aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:OK", aData);
|
||||
this._saveApps();
|
||||
this._saveApps(function() {
|
||||
// If the app is a packaged app, we just send a 'downloadapplied'
|
||||
// or downloadavailable event.
|
||||
let eventType = app.downloadAvailable ? "downloadavailable"
|
||||
: "downloadapplied";
|
||||
aMm.sendAsyncMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
aMm.sendAsyncMessage("Webapps:FireEvent", {
|
||||
eventType: eventType,
|
||||
manifestURL: app.manifestURL,
|
||||
requestID: aData.requestID
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// For hosted apps, even if the manifest has not changed, we check
|
||||
// for offline cache updates.
|
||||
|
@ -2146,21 +2205,25 @@ this.DOMApplicationRegistry = {
|
|||
|
||||
if (supportUseCurrentProfile()) {
|
||||
// Update the permissions for this app.
|
||||
PermissionsInstaller.installPermissions({ manifest: aManifest,
|
||||
origin: appObject.origin,
|
||||
manifestURL: appObject.manifestURL },
|
||||
true);
|
||||
PermissionsInstaller.installPermissions({
|
||||
manifest: aManifest,
|
||||
origin: appObject.origin,
|
||||
manifestURL: appObject.manifestURL
|
||||
}, true);
|
||||
}
|
||||
|
||||
this.updateDataStore(this.webapps[aId].localId, appObject.origin,
|
||||
appObject.manifestURL, aManifest);
|
||||
|
||||
debug("About to fire Webapps:PackageEvent 'installed'");
|
||||
this.broadcastMessage("Webapps:PackageEvent",
|
||||
{ type: "installed",
|
||||
manifestURL: appObject.manifestURL,
|
||||
app: app,
|
||||
manifest: aManifest });
|
||||
this.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifest: aManifest,
|
||||
manifestURL: appObject.manifestURL
|
||||
});
|
||||
this.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: ["downloadsuccess", "downloadapplied"],
|
||||
manifestURL: appObject.manifestURL
|
||||
});
|
||||
if (installSuccessCallback) {
|
||||
installSuccessCallback(aManifest, zipFile.path);
|
||||
}
|
||||
|
@ -2426,14 +2489,6 @@ this.DOMApplicationRegistry = {
|
|||
dir.remove(true);
|
||||
} catch (e) { }
|
||||
|
||||
// We avoid notifying the error to the DOM side if the app download
|
||||
// was cancelled via cancelDownload, which already sends its own
|
||||
// notification.
|
||||
if (app.isCanceling) {
|
||||
delete app.isCanceling;
|
||||
return;
|
||||
}
|
||||
|
||||
let download = AppDownloadManager.get(aApp.manifestURL);
|
||||
app.downloading = false;
|
||||
|
||||
|
@ -2449,20 +2504,31 @@ this.DOMApplicationRegistry = {
|
|||
delete app.staged;
|
||||
}
|
||||
|
||||
self.broadcastMessage("Webapps:PackageEvent",
|
||||
{ type: "error",
|
||||
manifestURL: aApp.manifestURL,
|
||||
error: aError,
|
||||
app: app });
|
||||
self._saveApps();
|
||||
self._saveApps(function() {
|
||||
self.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
error: aError,
|
||||
manifestURL: aApp.manifestURL
|
||||
});
|
||||
self.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "downloaderror",
|
||||
manifestURL: aApp.manifestURL
|
||||
});
|
||||
});
|
||||
AppDownloadManager.remove(aApp.manifestURL);
|
||||
}
|
||||
|
||||
function sendProgressEvent() {
|
||||
self.broadcastMessage("Webapps:PackageEvent",
|
||||
{ type: "progress",
|
||||
manifestURL: aApp.manifestURL,
|
||||
app: app });
|
||||
function sendProgressEvent(aProgress) {
|
||||
self.broadcastMessage("Webapps:UpdateState", {
|
||||
app: {
|
||||
progress: aProgress
|
||||
},
|
||||
manifestURL: aApp.manifestURL
|
||||
});
|
||||
self.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "progress",
|
||||
manifestURL: aApp.manifestURL
|
||||
});
|
||||
}
|
||||
|
||||
// aStoreId must be a string of the form
|
||||
|
@ -2548,7 +2614,7 @@ this.DOMApplicationRegistry = {
|
|||
let now = Date.now();
|
||||
if (now - lastProgressTime > MIN_PROGRESS_EVENT_DELAY) {
|
||||
debug("onProgress: " + aProgress + "/" + aProgressMax);
|
||||
sendProgressEvent();
|
||||
sendProgressEvent(aProgress);
|
||||
lastProgressTime = now;
|
||||
self._saveApps();
|
||||
}
|
||||
|
@ -2646,16 +2712,17 @@ this.DOMApplicationRegistry = {
|
|||
OS.Path.join(dirPath, "update.webapp"));
|
||||
}
|
||||
|
||||
self.broadcastMessage("Webapps:PackageEvent", {
|
||||
type: "downloaded",
|
||||
manifestURL: aApp.manifestURL,
|
||||
app: app });
|
||||
self.broadcastMessage("Webapps:PackageEvent", {
|
||||
type: "applied",
|
||||
manifestURL: aApp.manifestURL,
|
||||
app: app });
|
||||
// Save the updated registry, and cleanup the tmp directory.
|
||||
self._saveApps();
|
||||
self._saveApps(function() {
|
||||
self.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: aApp.manifestURL
|
||||
});
|
||||
self.broadcastMessage("Webapps:FireEvent", {
|
||||
manifestURL: aApp.manifestURL,
|
||||
eventType: ["downloadsuccess", "downloadapplied"]
|
||||
});
|
||||
});
|
||||
let file = FileUtils.getFile("TmpD", ["webapps", id], false);
|
||||
if (file && file.exists()) {
|
||||
file.remove(true);
|
||||
|
@ -2907,7 +2974,7 @@ this.DOMApplicationRegistry = {
|
|||
requestChannel.asyncOpen(listener, null);
|
||||
|
||||
// send a first progress event to correctly set the DOM object's properties
|
||||
sendProgressEvent();
|
||||
sendProgressEvent(0);
|
||||
};
|
||||
|
||||
let checkDownloadSize = function (freeBytes) {
|
||||
|
@ -3305,7 +3372,7 @@ let AppcacheObserver = function(aApp) {
|
|||
this.app = aApp;
|
||||
this.startStatus = aApp.installState;
|
||||
this.lastProgressTime = 0;
|
||||
// send a first progress event to correctly set the DOM object's properties
|
||||
// Send a first progress event to correctly set the DOM object's properties.
|
||||
this._sendProgressEvent();
|
||||
};
|
||||
|
||||
|
@ -3313,10 +3380,14 @@ AppcacheObserver.prototype = {
|
|||
// nsIOfflineCacheUpdateObserver implementation
|
||||
_sendProgressEvent: function() {
|
||||
let app = this.app;
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:OfflineCache",
|
||||
{ manifest: app.manifestURL,
|
||||
installState: app.installState,
|
||||
progress: app.progress });
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: "progress",
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
},
|
||||
|
||||
updateStateChanged: function appObs_Update(aUpdate, aState) {
|
||||
|
@ -3328,31 +3399,41 @@ AppcacheObserver.prototype = {
|
|||
var self = this;
|
||||
let setStatus = function appObs_setStatus(aStatus, aProgress) {
|
||||
debug("Offlinecache setStatus to " + aStatus + " with progress " +
|
||||
aProgress + " for " + app.origin);
|
||||
aProgress + " for " + app.origin);
|
||||
mustSave = (app.installState != aStatus);
|
||||
|
||||
app.installState = aStatus;
|
||||
app.progress = aProgress;
|
||||
if (aStatus == "installed") {
|
||||
app.updateTime = Date.now();
|
||||
app.downloading = false;
|
||||
app.downloadAvailable = false;
|
||||
if (aStatus != "installed") {
|
||||
self._sendProgressEvent();
|
||||
return;
|
||||
}
|
||||
self._sendProgressEvent();
|
||||
|
||||
app.updateTime = Date.now();
|
||||
app.downloading = false;
|
||||
app.downloadAvailable = false;
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
eventType: ["downloadsuccess", "downloadapplied"],
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
}
|
||||
|
||||
let setError = function appObs_setError(aError) {
|
||||
debug("Offlinecache setError to " + aError);
|
||||
// If we are canceling the download, we already send a DOWNLOAD_CANCELED
|
||||
// error.
|
||||
if (!app.isCanceling) {
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:OfflineCache",
|
||||
{ manifest: app.manifestURL,
|
||||
error: aError });
|
||||
} else {
|
||||
delete app.isCanceling;
|
||||
}
|
||||
|
||||
app.downloading = false;
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:UpdateState", {
|
||||
app: app,
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
DOMApplicationRegistry.broadcastMessage("Webapps:FireEvent", {
|
||||
error: aError,
|
||||
eventType: "downloaderror",
|
||||
manifestURL: app.manifestURL
|
||||
});
|
||||
mustSave = true;
|
||||
}
|
||||
|
||||
|
@ -3369,9 +3450,9 @@ AppcacheObserver.prototype = {
|
|||
setStatus("installed", aUpdate.byteProgress);
|
||||
break;
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_DOWNLOADING:
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMSTARTED:
|
||||
setStatus(this.startStatus, aUpdate.byteProgress);
|
||||
break;
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMSTARTED:
|
||||
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMPROGRESS:
|
||||
let now = Date.now();
|
||||
if (now - this.lastProgressTime > MIN_PROGRESS_EVENT_DELAY) {
|
||||
|
|
|
@ -159,7 +159,7 @@ var steps = [
|
|||
},
|
||||
function() {
|
||||
ok(true, "== TEST == Update packaged app - same package");
|
||||
updateApp(false, 3, 4);
|
||||
updateApp(false, 3, 3);
|
||||
},
|
||||
function() {
|
||||
ok(true, "== TEST == Check for Update after getting the same package");
|
||||
|
|
|
@ -123,7 +123,7 @@ PostMessageReadStructuredClone(JSContext* cx,
|
|||
JS::Rooted<JS::Value> val(cx);
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
|
||||
if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, global, supports,
|
||||
val.address(),
|
||||
&val,
|
||||
getter_AddRefs(wrapper)))) {
|
||||
return JSVAL_TO_OBJECT(val);
|
||||
}
|
||||
|
|
|
@ -1589,7 +1589,7 @@ Navigator::DoNewResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
|
|||
|
||||
if (JSVAL_IS_PRIMITIVE(prop_val) && !JSVAL_IS_NULL(prop_val)) {
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
rv = nsContentUtils::WrapNative(aCx, aObject, native, prop_val.address(),
|
||||
rv = nsContentUtils::WrapNative(aCx, aObject, native, &prop_val,
|
||||
getter_AddRefs(holder), true);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -1716,8 +1716,13 @@ Navigator::HasCameraSupport(JSContext* /* unused */, JSObject* aGlobal)
|
|||
bool
|
||||
Navigator::HasTelephonySupport(JSContext* /* unused */, JSObject* aGlobal)
|
||||
{
|
||||
// First of all, the general pref has to be turned on.
|
||||
bool enabled = false;
|
||||
Preferences::GetBool("dom.telephony.enabled", &enabled);
|
||||
NS_ENSURE_TRUE(enabled, false);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
||||
return win && Telephony::CheckPermission(win);
|
||||
return win && CheckPermission(win, "telephony");
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -1725,6 +1730,11 @@ bool
|
|||
Navigator::HasMobileConnectionSupport(JSContext* /* unused */,
|
||||
JSObject* aGlobal)
|
||||
{
|
||||
// First of all, the general pref has to be turned on.
|
||||
bool enabled = false;
|
||||
Preferences::GetBool("dom.mobileconnection.enabled", &enabled);
|
||||
NS_ENSURE_TRUE(enabled, false);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
||||
return win && (CheckPermission(win, "mobileconnection") ||
|
||||
CheckPermission(win, "mobilenetwork"));
|
||||
|
@ -1735,6 +1745,11 @@ bool
|
|||
Navigator::HasCellBroadcastSupport(JSContext* /* unused */,
|
||||
JSObject* aGlobal)
|
||||
{
|
||||
// First of all, the general pref has to be turned on.
|
||||
bool enabled = false;
|
||||
Preferences::GetBool("dom.cellbroadcast.enabled", &enabled);
|
||||
NS_ENSURE_TRUE(enabled, false);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
||||
return win && CheckPermission(win, "cellbroadcast");
|
||||
}
|
||||
|
@ -1744,6 +1759,11 @@ bool
|
|||
Navigator::HasVoicemailSupport(JSContext* /* unused */,
|
||||
JSObject* aGlobal)
|
||||
{
|
||||
// First of all, the general pref has to be turned on.
|
||||
bool enabled = false;
|
||||
Preferences::GetBool("dom.voicemail.enabled", &enabled);
|
||||
NS_ENSURE_TRUE(enabled, false);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
||||
return win && CheckPermission(win, "voicemail");
|
||||
}
|
||||
|
@ -1753,6 +1773,11 @@ bool
|
|||
Navigator::HasIccManagerSupport(JSContext* /* unused */,
|
||||
JSObject* aGlobal)
|
||||
{
|
||||
// First of all, the general pref has to be turned on.
|
||||
bool enabled = false;
|
||||
Preferences::GetBool("dom.icc.enabled", &enabled);
|
||||
NS_ENSURE_TRUE(enabled, false);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetWindowFromGlobal(aGlobal);
|
||||
return win && CheckPermission(win, "mobileconnection");
|
||||
}
|
||||
|
|
|
@ -643,13 +643,13 @@ IdToString(JSContext *cx, jsid id)
|
|||
|
||||
static inline nsresult
|
||||
WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
||||
nsWrapperCache *cache, const nsIID* aIID, jsval *vp,
|
||||
nsWrapperCache *cache, const nsIID* aIID, JS::MutableHandle<JS::Value> vp,
|
||||
nsIXPConnectJSObjectHolder** aHolder, bool aAllowWrapping)
|
||||
{
|
||||
if (!native) {
|
||||
NS_ASSERTION(!aHolder || !*aHolder, "*aHolder should be null!");
|
||||
|
||||
*vp = JSVAL_NULL;
|
||||
vp.setNull();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -661,13 +661,13 @@ WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
|||
|
||||
return nsDOMClassInfo::XPConnect()->WrapNativeToJSVal(cx, scope, native,
|
||||
cache, aIID,
|
||||
aAllowWrapping, vp,
|
||||
aAllowWrapping, vp.address(),
|
||||
aHolder);
|
||||
}
|
||||
|
||||
static inline nsresult
|
||||
WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
||||
const nsIID* aIID, bool aAllowWrapping, jsval *vp,
|
||||
const nsIID* aIID, bool aAllowWrapping, JS::MutableHandle<JS::Value> vp,
|
||||
// If non-null aHolder will keep the jsval alive
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nullptr)
|
||||
|
@ -679,7 +679,7 @@ WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
|||
// Same as the WrapNative above, but use these if aIID is nsISupports' IID.
|
||||
static inline nsresult
|
||||
WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
||||
bool aAllowWrapping, jsval *vp,
|
||||
bool aAllowWrapping, JS::MutableHandle<JS::Value> vp,
|
||||
// If non-null aHolder will keep the jsval alive
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nullptr)
|
||||
|
@ -690,7 +690,8 @@ WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
|||
|
||||
static inline nsresult
|
||||
WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
||||
nsWrapperCache *cache, bool aAllowWrapping, jsval *vp,
|
||||
nsWrapperCache *cache, bool aAllowWrapping,
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
// If non-null aHolder will keep the jsval alive
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nullptr)
|
||||
|
@ -2221,26 +2222,25 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner,
|
|||
// wrap parameters in the target compartment
|
||||
// we also pass in the calling window as the first argument
|
||||
unsigned argc = args.length() + 1;
|
||||
nsAutoArrayPtr<JS::Value> argv(new JS::Value[argc]);
|
||||
JS::AutoArrayRooter rooter(cx, 0, argv);
|
||||
JS::AutoValueVector argv(cx);
|
||||
argv.resize(argc);
|
||||
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
nsCOMPtr<nsIDOMWindow> currentWin(do_GetInterface(currentInner));
|
||||
rv = WrapNative(cx, obj, currentWin, &NS_GET_IID(nsIDOMWindow),
|
||||
true, &argv[0], getter_AddRefs(holder));
|
||||
true, argv.handleAt(0), getter_AddRefs(holder));
|
||||
if (!JS_WrapValue(cx, &argv[0]))
|
||||
return NS_ERROR_FAILURE;
|
||||
rooter.changeLength(1);
|
||||
|
||||
for (size_t i = 1; i < argc; ++i) {
|
||||
argv[i] = args[i - 1];
|
||||
if (!JS_WrapValue(cx, &argv[i]))
|
||||
return NS_ERROR_FAILURE;
|
||||
rooter.changeLength(i + 1);
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> frval(cx);
|
||||
bool ret = JS_CallFunctionValue(cx, thisObject, funval, argc, argv,
|
||||
bool ret = JS_CallFunctionValue(cx, thisObject, funval,
|
||||
argc, argv.begin(),
|
||||
frval.address());
|
||||
|
||||
if (!ret) {
|
||||
|
@ -2250,7 +2250,7 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner,
|
|||
}
|
||||
}
|
||||
|
||||
return WrapNative(cx, obj, native, true, args.rval().address());
|
||||
return WrapNative(cx, obj, native, true, args.rval());
|
||||
}
|
||||
|
||||
static nsresult
|
||||
|
@ -2818,7 +2818,7 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
|
|||
JS::Rooted<JS::Value> v(cx);
|
||||
|
||||
rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor),
|
||||
false, v.address(), getter_AddRefs(holder));
|
||||
false, &v, getter_AddRefs(holder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (install) {
|
||||
|
@ -3100,7 +3100,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
|||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor),
|
||||
false, v.address(), getter_AddRefs(holder));
|
||||
false, &v, getter_AddRefs(holder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = constructor->Install(cx, obj, v);
|
||||
|
@ -3202,7 +3202,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
|||
JS::Rooted<JS::Value> val(cx);
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor),
|
||||
false, val.address(), getter_AddRefs(holder));
|
||||
false, &val, getter_AddRefs(holder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = constructor->Install(cx, obj, val);
|
||||
|
@ -3251,7 +3251,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
|
|||
scope = aWin->GetGlobalJSObject();
|
||||
}
|
||||
|
||||
rv = WrapNative(cx, scope, native, true, prop_val.address(),
|
||||
rv = WrapNative(cx, scope, native, true, &prop_val,
|
||||
getter_AddRefs(holder));
|
||||
}
|
||||
|
||||
|
@ -3303,7 +3303,7 @@ ContentWindowGetter(JSContext *cx, unsigned argc, jsval *vp)
|
|||
|
||||
template<class Interface>
|
||||
static nsresult
|
||||
LocationSetterGuts(JSContext *cx, JSObject *obj, jsval *vp)
|
||||
LocationSetterGuts(JSContext *cx, JSObject *obj, JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
// This function duplicates some of the logic in XPC_WN_HelperSetProperty
|
||||
obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
|
||||
|
@ -3322,7 +3322,7 @@ LocationSetterGuts(JSContext *cx, JSObject *obj, jsval *vp)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Grab the value we're being set to before we stomp on |vp|
|
||||
JS::Rooted<JSString*> val(cx, ::JS_ValueToString(cx, *vp));
|
||||
JS::Rooted<JSString*> val(cx, ::JS_ValueToString(cx, vp));
|
||||
NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Make sure |val| stays alive below
|
||||
|
@ -3352,7 +3352,7 @@ static bool
|
|||
LocationSetter(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool strict,
|
||||
JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
nsresult rv = LocationSetterGuts<Interface>(cx, obj, vp.address());
|
||||
nsresult rv = LocationSetterGuts<Interface>(cx, obj, vp);
|
||||
if (NS_FAILED(rv)) {
|
||||
xpc::Throw(cx, rv);
|
||||
return false;
|
||||
|
@ -3365,7 +3365,7 @@ static bool
|
|||
LocationSetterUnwrapper(JSContext *cx, JS::Handle<JSObject*> obj_, JS::Handle<jsid> id,
|
||||
bool strict, JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
JS::RootedObject obj(cx, obj_);
|
||||
JS::Rooted<JSObject*> obj(cx, obj_);
|
||||
|
||||
JSObject *wrapped = XPCWrapper::UnsafeUnwrapSecurityWrapper(obj);
|
||||
if (wrapped) {
|
||||
|
@ -3410,7 +3410,7 @@ const InterfaceShimEntry kInterfaceShimMap[] =
|
|||
{ "nsIDOMXPathResult", "XPathResult" } };
|
||||
|
||||
static nsresult
|
||||
DefineComponentsShim(JSContext *cx, JS::HandleObject global, nsPIDOMWindow *win)
|
||||
DefineComponentsShim(JSContext *cx, JS::Handle<JSObject*> global, nsPIDOMWindow *win)
|
||||
{
|
||||
// Keep track of how often this happens.
|
||||
Telemetry::Accumulate(Telemetry::COMPONENTS_SHIM_ACCESSED_BY_CONTENT, true);
|
||||
|
@ -3468,7 +3468,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
JSObject *obj_, jsid id_, uint32_t flags,
|
||||
JSObject **objp, bool *_retval)
|
||||
{
|
||||
JS::RootedObject obj(cx, obj_);
|
||||
JS::Rooted<JSObject*> obj(cx, obj_);
|
||||
JS::RootedId id(cx, id_);
|
||||
|
||||
if (!JSID_IS_STRING(id)) {
|
||||
|
@ -3565,7 +3565,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
rv = WrapNative(cx, scope, location, &NS_GET_IID(nsIDOMLocation), true,
|
||||
v.address(), getter_AddRefs(holder));
|
||||
&v, getter_AddRefs(holder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool ok = JS_WrapValue(cx, v.address()) &&
|
||||
|
@ -3590,7 +3590,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
JS::Rooted<JS::Value> v(cx);
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
rv = WrapNative(cx, obj, top, &NS_GET_IID(nsIDOMWindow), true,
|
||||
v.address(), getter_AddRefs(holder));
|
||||
&v, getter_AddRefs(holder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Hold on to the top window object as a global property so we
|
||||
|
@ -3606,7 +3606,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
}
|
||||
|
||||
// Handle resolving if id refers to a name resolved by DOM worker code.
|
||||
JS::RootedObject tmp(cx, NULL);
|
||||
JS::Rooted<JSObject*> tmp(cx, NULL);
|
||||
if (!ResolveWorkerClasses(cx, obj, id, flags, &tmp)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -3679,7 +3679,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
JS::Rooted<JS::Value> v(cx);
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
rv = WrapNative(cx, JS::CurrentGlobalOrNull(cx), document, document,
|
||||
&NS_GET_IID(nsIDOMDocument), v.address(), getter_AddRefs(holder),
|
||||
&NS_GET_IID(nsIDOMDocument), &v, getter_AddRefs(holder),
|
||||
false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -3986,9 +3986,11 @@ nsArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (array_item) {
|
||||
JS::Rooted<JS::Value> rval(cx);
|
||||
rv = WrapNative(cx, JS::CurrentGlobalOrNull(cx), array_item, cache,
|
||||
true, vp);
|
||||
true, &rval);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
*vp = rval;
|
||||
|
||||
rv = NS_SUCCESS_I_DID_SOMETHING;
|
||||
}
|
||||
|
@ -4085,7 +4087,7 @@ nsHTMLDocumentSH::GetDocumentAllNodeList(JSContext *cx,
|
|||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
nsresult tmp = WrapNative(cx, JS::CurrentGlobalOrNull(cx),
|
||||
static_cast<nsINodeList*>(list), list, false,
|
||||
collection.address(), getter_AddRefs(holder));
|
||||
&collection, getter_AddRefs(holder));
|
||||
if (NS_FAILED(tmp)) {
|
||||
rv = tmp;
|
||||
}
|
||||
|
@ -4189,7 +4191,7 @@ nsHTMLDocumentSH::DocumentAllGetProperty(JSContext *cx, JS::Handle<JSObject*> ob
|
|||
}
|
||||
|
||||
if (result) {
|
||||
rv = WrapNative(cx, JS::CurrentGlobalOrNull(cx), result, cache, true, vp.address());
|
||||
rv = WrapNative(cx, JS::CurrentGlobalOrNull(cx), result, cache, true, vp);
|
||||
if (NS_FAILED(rv)) {
|
||||
xpc::Throw(cx, rv);
|
||||
|
||||
|
@ -4207,7 +4209,7 @@ nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JS::Handle<JSObject*> obj
|
|||
JS::Handle<jsid> id, unsigned flags,
|
||||
JS::MutableHandle<JSObject*> objp)
|
||||
{
|
||||
JS::RootedValue v(cx);
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
|
||||
if (nsDOMClassInfo::sItem_id == id || nsDOMClassInfo::sNamedItem_id == id) {
|
||||
// Define the item() or namedItem() method.
|
||||
|
@ -4326,8 +4328,10 @@ nsStringArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
|
|||
return NS_SUCCESS_I_DID_SOMETHING;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(xpc::NonVoidStringToJsval(cx, val, vp),
|
||||
JS::Rooted<JS::Value> rval(cx);
|
||||
NS_ENSURE_TRUE(xpc::NonVoidStringToJsval(cx, val, &rval),
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
*vp = rval;
|
||||
return NS_SUCCESS_I_DID_SOMETHING;
|
||||
}
|
||||
|
||||
|
|
|
@ -2385,8 +2385,9 @@ nsDOMWindowUtils::GetIsTestControllingRefreshes(bool *aResult)
|
|||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
nsPresContext* pc = GetPresContext();
|
||||
*aResult =
|
||||
GetPresContext()->RefreshDriver()->IsTestControllingRefreshesEnabled();
|
||||
pc ? pc->RefreshDriver()->IsTestControllingRefreshesEnabled() : false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -3632,8 +3632,11 @@ nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::Value* aVal)
|
|||
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
if (content && global) {
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
|
||||
return nsContentUtils::WrapNative(aCx, global, content, aVal,
|
||||
getter_AddRefs(wrapper));
|
||||
JS::Rooted<JS::Value> rval(aCx);
|
||||
nsresult rv = nsContentUtils::WrapNative(aCx, global, content, &rval,
|
||||
getter_AddRefs(wrapper));
|
||||
*aVal = rval;
|
||||
return rv;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -6806,9 +6809,9 @@ PostMessageReadStructuredClone(JSContext* cx,
|
|||
JS::Rooted<JS::Value> val(cx);
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
|
||||
if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, global, supports,
|
||||
val.address(),
|
||||
&val,
|
||||
getter_AddRefs(wrapper)))) {
|
||||
return JSVAL_TO_OBJECT(val);
|
||||
return val.toObjectOrNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1035,23 +1035,21 @@ nsJSContext::JSObjectFromInterface(nsISupports* aTarget,
|
|||
// We don't wrap here because we trust the JS engine to wrap the target
|
||||
// later.
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
nsresult rv = nsContentUtils::WrapNative(cx, aScope, aTarget,
|
||||
v.address());
|
||||
nsresult rv = nsContentUtils::WrapNative(cx, aScope, aTarget, &v);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsISupports> targetSupp = do_QueryInterface(aTarget);
|
||||
nsCOMPtr<nsISupports> native =
|
||||
nsContentUtils::XPConnect()->GetNativeOfWrapper(cx,
|
||||
JSVAL_TO_OBJECT(v));
|
||||
NS_ASSERTION(native == targetSupp, "Native should be the target!");
|
||||
#endif
|
||||
|
||||
JSObject* obj = v.toObjectOrNull();
|
||||
if (obj) {
|
||||
JS::ExposeObjectToActiveJS(obj);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsISupports> targetSupp = do_QueryInterface(aTarget);
|
||||
nsCOMPtr<nsISupports> native =
|
||||
nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, obj);
|
||||
NS_ASSERTION(native == targetSupp, "Native should be the target!");
|
||||
#endif
|
||||
|
||||
*aRet = obj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1298,7 +1296,7 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports *aArgs,
|
|||
#endif
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
rv = nsContentUtils::WrapNative(cx, aScope, arg, v.address(),
|
||||
rv = nsContentUtils::WrapNative(cx, aScope, arg, &v,
|
||||
getter_AddRefs(wrapper));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*thisval = v;
|
||||
|
@ -1500,7 +1498,7 @@ nsJSContext::AddSupportsPrimitiveTojsvals(nsISupports *aArg, JS::Value *aArgv)
|
|||
JS::Rooted<JSObject*> global(cx, GetWindowProxy());
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
nsresult rv = nsContentUtils::WrapNative(cx, global,
|
||||
data, iid, v.address(),
|
||||
data, iid, &v,
|
||||
getter_AddRefs(wrapper));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -320,13 +320,13 @@ enum {
|
|||
TOSTRING_NAME_RESERVED_SLOT = 1
|
||||
};
|
||||
|
||||
bool
|
||||
static bool
|
||||
InterfaceObjectToString(JSContext* cx, unsigned argc, JS::Value *vp)
|
||||
{
|
||||
JS::Rooted<JSObject*> callee(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
JS::Rooted<JSObject*> callee(cx, &args.callee());
|
||||
|
||||
JS::Rooted<JSObject*> obj(cx, JS_THIS_OBJECT(cx, vp));
|
||||
if (!obj) {
|
||||
if (!args.computeThis(cx).isObject()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,
|
||||
"null", "object");
|
||||
return false;
|
||||
|
@ -334,14 +334,14 @@ InterfaceObjectToString(JSContext* cx, unsigned argc, JS::Value *vp)
|
|||
|
||||
JS::Value v = js::GetFunctionNativeReserved(callee,
|
||||
TOSTRING_CLASS_RESERVED_SLOT);
|
||||
const JSClass* clasp = static_cast<const JSClass*>(JSVAL_TO_PRIVATE(v));
|
||||
const JSClass* clasp = static_cast<const JSClass*>(v.toPrivate());
|
||||
|
||||
v = js::GetFunctionNativeReserved(callee, TOSTRING_NAME_RESERVED_SLOT);
|
||||
JSString* jsname = static_cast<JSString*>(JSVAL_TO_STRING(v));
|
||||
size_t length;
|
||||
const jschar* name = JS_GetInternedStringCharsAndLength(jsname, &length);
|
||||
|
||||
if (js::GetObjectJSClass(obj) != clasp) {
|
||||
if (js::GetObjectJSClass(&args.computeThis(cx).toObject()) != clasp) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
|
||||
NS_ConvertUTF16toUTF8(name).get(), "toString",
|
||||
"object");
|
||||
|
@ -357,7 +357,7 @@ InterfaceObjectToString(JSContext* cx, unsigned argc, JS::Value *vp)
|
|||
str.Append('\n');
|
||||
str.AppendLiteral("}");
|
||||
|
||||
return xpc::NonVoidStringToJsval(cx, str, vp);
|
||||
return xpc::NonVoidStringToJsval(cx, str, args.rval());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -673,7 +673,7 @@ CreateInterfaceObjects(JSContext* cx, JS::Handle<JSObject*> global,
|
|||
bool
|
||||
NativeInterface2JSObjectAndThrowIfFailed(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aScope,
|
||||
JS::Value* aRetval,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
xpcObjectHelper& aHelper,
|
||||
const nsIID* aIID,
|
||||
bool aAllowNativeWrapper)
|
||||
|
@ -684,7 +684,7 @@ NativeInterface2JSObjectAndThrowIfFailed(JSContext* aCx,
|
|||
nsWrapperCache *cache = aHelper.GetWrapperCache();
|
||||
|
||||
if (cache && cache->IsDOMBinding()) {
|
||||
JS::RootedObject obj(aCx, cache->GetWrapper());
|
||||
JS::Rooted<JSObject*> obj(aCx, cache->GetWrapper());
|
||||
if (!obj) {
|
||||
obj = cache->WrapObject(aCx, aScope);
|
||||
}
|
||||
|
@ -694,7 +694,7 @@ NativeInterface2JSObjectAndThrowIfFailed(JSContext* aCx,
|
|||
}
|
||||
|
||||
if (obj) {
|
||||
*aRetval = JS::ObjectValue(*obj);
|
||||
aRetval.setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -751,7 +751,7 @@ InstanceClassHasProtoAtDepth(JS::Handle<JSObject*> protoObject, uint32_t protoID
|
|||
bool
|
||||
XPCOMObjectToJsval(JSContext* cx, JS::Handle<JSObject*> scope,
|
||||
xpcObjectHelper& helper, const nsIID* iid,
|
||||
bool allowNativeWrapper, JS::Value* rval)
|
||||
bool allowNativeWrapper, JS::MutableHandle<JS::Value> rval)
|
||||
{
|
||||
if (!NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval, helper, iid,
|
||||
allowNativeWrapper)) {
|
||||
|
@ -759,7 +759,7 @@ XPCOMObjectToJsval(JSContext* cx, JS::Handle<JSObject*> scope,
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
JSObject* jsobj = JSVAL_TO_OBJECT(*rval);
|
||||
JSObject* jsobj = rval.toObjectOrNull();
|
||||
if (jsobj && !js::GetObjectParent(jsobj))
|
||||
NS_ASSERTION(js::GetObjectClass(jsobj)->flags & JSCLASS_IS_GLOBAL,
|
||||
"Why did we recreate this wrapper?");
|
||||
|
@ -770,7 +770,7 @@ XPCOMObjectToJsval(JSContext* cx, JS::Handle<JSObject*> scope,
|
|||
|
||||
bool
|
||||
VariantToJsval(JSContext* aCx, JS::Handle<JSObject*> aScope,
|
||||
nsIVariant* aVariant, JS::Value* aRetval)
|
||||
nsIVariant* aVariant, JS::MutableHandle<JS::Value> aRetval)
|
||||
{
|
||||
nsresult rv;
|
||||
if (!XPCVariant::VariantDataToJS(aVariant, &rv, aRetval)) {
|
||||
|
@ -810,15 +810,14 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
return Throw(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
|
||||
}
|
||||
|
||||
JS::Value* argv = JS_ARGV(cx, vp);
|
||||
if (!argv[0].isObject()) {
|
||||
if (!args[0].isObject()) {
|
||||
return Throw(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
|
||||
}
|
||||
|
||||
nsIJSID* iid;
|
||||
SelfRef iidRef;
|
||||
if (NS_FAILED(xpc_qsUnwrapArg<nsIJSID>(cx, argv[0], &iid, &iidRef.ptr,
|
||||
&argv[0]))) {
|
||||
if (NS_FAILED(xpc_qsUnwrapArg<nsIJSID>(cx, args[0], &iid, &iidRef.ptr,
|
||||
args[0]))) {
|
||||
return Throw(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
|
||||
}
|
||||
MOZ_ASSERT(iid);
|
||||
|
@ -1475,7 +1474,7 @@ AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
|
|||
{
|
||||
for (uint32_t i = 0; i < names.Length(); ++i) {
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
if (!xpc::NonVoidStringToJsval(cx, names[i], v.address())) {
|
||||
if (!xpc::NonVoidStringToJsval(cx, names[i], &v)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1649,10 +1648,10 @@ private:
|
|||
};
|
||||
|
||||
nsresult
|
||||
ReparentWrapper(JSContext* aCx, JS::HandleObject aObjArg)
|
||||
ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
|
||||
{
|
||||
// aObj is assigned to below, so needs to be re-rooted.
|
||||
JS::RootedObject aObj(aCx, aObjArg);
|
||||
JS::Rooted<JSObject*> aObj(aCx, aObjArg);
|
||||
const DOMClass* domClass = GetDOMClass(aObj);
|
||||
|
||||
JS::Rooted<JSObject*> oldParent(aCx, JS_GetParent(aObj));
|
||||
|
@ -1756,20 +1755,9 @@ ReparentWrapper(JSContext* aCx, JS::HandleObject aObjArg)
|
|||
if (ww != aObj) {
|
||||
MOZ_ASSERT(cache->HasSystemOnlyWrapper());
|
||||
|
||||
JS::RootedObject newwrapper(aCx,
|
||||
xpc::WrapperFactory::WrapSOWObject(aCx, newobj));
|
||||
if (!newwrapper) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
// Oops. We don't support transplanting objects with SOWs anymore.
|
||||
MOZ_CRASH();
|
||||
|
||||
// Ok, now we do the special object-plus-wrapper transplant.
|
||||
ww = xpc::TransplantObjectWithWrapper(aCx, aObj, ww, newobj, newwrapper);
|
||||
if (!ww) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
aObj = newobj;
|
||||
SetSystemOnlyWrapperSlot(aObj, JS::ObjectValue(*ww));
|
||||
} else {
|
||||
aObj = xpc::TransplantObject(aCx, aObj, newobj);
|
||||
if (!aObj) {
|
||||
|
@ -1863,7 +1851,7 @@ GlobalObject::GetAsSupports() const
|
|||
// using new bindings.
|
||||
nsresult rv = xpc_qsUnwrapArg<nsISupports>(mCx, val, &mGlobalObject,
|
||||
static_cast<nsISupports**>(getter_AddRefs(mGlobalObjectRef)),
|
||||
val.address());
|
||||
&val);
|
||||
if (NS_FAILED(rv)) {
|
||||
mGlobalObject = nullptr;
|
||||
Throw(mCx, NS_ERROR_XPC_BAD_CONVERT_JS);
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
class nsPIDOMWindow;
|
||||
|
||||
extern nsresult
|
||||
xpc_qsUnwrapArgImpl(JSContext* cx, jsval v, const nsIID& iid, void** ppArg,
|
||||
nsISupports** ppArgRef, jsval* vp);
|
||||
xpc_qsUnwrapArgImpl(JSContext* cx, JS::Handle<JS::Value> v, const nsIID& iid, void** ppArg,
|
||||
nsISupports** ppArgRef, JS::MutableHandle<JS::Value> vp);
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -53,8 +53,8 @@ struct SelfRef
|
|||
/** Convert a jsval to an XPCOM pointer. */
|
||||
template <class Interface, class StrongRefType>
|
||||
inline nsresult
|
||||
UnwrapArg(JSContext* cx, jsval v, Interface** ppArg,
|
||||
StrongRefType** ppArgRef, jsval* vp)
|
||||
UnwrapArg(JSContext* cx, JS::Handle<JS::Value> v, Interface** ppArg,
|
||||
StrongRefType** ppArgRef, JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
nsISupports* argRef = *ppArgRef;
|
||||
nsresult rv = xpc_qsUnwrapArgImpl(cx, v, NS_GET_TEMPLATE_IID(Interface),
|
||||
|
@ -792,7 +792,7 @@ WrapNewBindingNonWrapperCachedObject(JSContext* cx, JS::Handle<JSObject*> scope,
|
|||
bool
|
||||
NativeInterface2JSObjectAndThrowIfFailed(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aScope,
|
||||
JS::Value* aRetval,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
xpcObjectHelper& aHelper,
|
||||
const nsIID* aIID,
|
||||
bool aAllowNativeWrapper);
|
||||
|
@ -811,7 +811,7 @@ HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
|
|||
}
|
||||
|
||||
qsObjectHelper helper(value, GetWrapperCache(value));
|
||||
return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval.address(),
|
||||
return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval,
|
||||
helper, nullptr, true);
|
||||
}
|
||||
|
||||
|
@ -977,12 +977,12 @@ InstanceClassHasProtoAtDepth(JS::Handle<JSObject*> protoObject, uint32_t protoID
|
|||
bool
|
||||
XPCOMObjectToJsval(JSContext* cx, JS::Handle<JSObject*> scope,
|
||||
xpcObjectHelper& helper, const nsIID* iid,
|
||||
bool allowNativeWrapper, JS::Value* rval);
|
||||
bool allowNativeWrapper, JS::MutableHandle<JS::Value> rval);
|
||||
|
||||
// Special-cased wrapping for variants
|
||||
bool
|
||||
VariantToJsval(JSContext* aCx, JS::Handle<JSObject*> aScope,
|
||||
nsIVariant* aVariant, JS::Value* aRetval);
|
||||
nsIVariant* aVariant, JS::MutableHandle<JS::Value> aRetval);
|
||||
|
||||
// Wrap an object "p" which is not using WebIDL bindings yet. This _will_
|
||||
// actually work on WebIDL binding objects that are wrappercached, but will be
|
||||
|
@ -994,10 +994,10 @@ WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
|
|||
nsWrapperCache* cache, const nsIID* iid,
|
||||
JS::MutableHandle<JS::Value> rval)
|
||||
{
|
||||
if (xpc_FastGetCachedWrapper(cache, scope, rval.address()))
|
||||
if (xpc_FastGetCachedWrapper(cache, scope, rval))
|
||||
return true;
|
||||
qsObjectHelper helper(p, cache);
|
||||
return XPCOMObjectToJsval(cx, scope, helper, iid, true, rval.address());
|
||||
return XPCOMObjectToJsval(cx, scope, helper, iid, true, rval);
|
||||
}
|
||||
|
||||
// A specialization of the above for nsIVariant, because that needs to
|
||||
|
@ -1010,7 +1010,7 @@ WrapObject<nsIVariant>(JSContext* cx, JS::Handle<JSObject*> scope, nsIVariant* p
|
|||
{
|
||||
MOZ_ASSERT(iid);
|
||||
MOZ_ASSERT(iid->Equals(NS_GET_IID(nsIVariant)));
|
||||
return VariantToJsval(cx, scope, p, rval.address());
|
||||
return VariantToJsval(cx, scope, p, rval);
|
||||
}
|
||||
|
||||
// Wrap an object "p" which is not using WebIDL bindings yet. Just like the
|
||||
|
@ -1100,8 +1100,8 @@ WrapNativeISupportsParent(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
|
|||
{
|
||||
qsObjectHelper helper(ToSupports(p), cache);
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
return XPCOMObjectToJsval(cx, scope, helper, nullptr, false, v.address()) ?
|
||||
JSVAL_TO_OBJECT(v) :
|
||||
return XPCOMObjectToJsval(cx, scope, helper, nullptr, false, &v) ?
|
||||
v.toObjectOrNull() :
|
||||
nullptr;
|
||||
}
|
||||
|
||||
|
@ -2005,7 +2005,7 @@ const T& NonNullHelper(const OwningNonNull<T>& aArg)
|
|||
// Reparent the wrapper of aObj to whatever its native now thinks its
|
||||
// parent should be.
|
||||
nsresult
|
||||
ReparentWrapper(JSContext* aCx, JS::HandleObject aObj);
|
||||
ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObj);
|
||||
|
||||
/**
|
||||
* Used to implement the hasInstance hook of an interface object.
|
||||
|
|
|
@ -1516,7 +1516,7 @@ class MethodDefiner(PropertyDefiner):
|
|||
if any(m.isGetter() and m.isIndexed() for m in methods):
|
||||
self.regular.append({"name": "@@iterator",
|
||||
"methodInfo": False,
|
||||
"selfHostedName": "ArrayIterator",
|
||||
"selfHostedName": "ArrayValues",
|
||||
"length": 0,
|
||||
"flags": "JSPROP_ENUMERATE",
|
||||
"condition": MemberCondition(None, None) })
|
||||
|
@ -2409,7 +2409,7 @@ class CastableObjectUnwrapper():
|
|||
"${type} *objPtr;\n"
|
||||
"SelfRef objRef;\n"
|
||||
"JS::Rooted<JS::Value> val(cx, JS::ObjectValue(*${source}));\n"
|
||||
"nsresult rv = UnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, val.address());\n"
|
||||
"nsresult rv = UnwrapArg<${type}>(cx, val, &objPtr, &objRef.ptr, &val);\n"
|
||||
"if (NS_FAILED(rv)) {\n"
|
||||
"${codeOnFailure}\n"
|
||||
"}\n"
|
||||
|
@ -3230,7 +3230,7 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||
templateBody += (
|
||||
"JS::Rooted<JS::Value> tmpVal(cx, ${val});\n" +
|
||||
typePtr + " tmp;\n"
|
||||
"if (NS_FAILED(UnwrapArg<" + typeName + ">(cx, ${val}, &tmp, static_cast<" + typeName + "**>(getter_AddRefs(${holderName})), tmpVal.address()))) {\n")
|
||||
"if (NS_FAILED(UnwrapArg<" + typeName + ">(cx, ${val}, &tmp, static_cast<" + typeName + "**>(getter_AddRefs(${holderName})), &tmpVal))) {\n")
|
||||
templateBody += CGIndenter(onFailureBadType(failureCode,
|
||||
descriptor.interface.identifier.name)).define()
|
||||
templateBody += ("}\n"
|
||||
|
@ -4121,9 +4121,9 @@ if (!returnArray) {
|
|||
|
||||
if type.isDOMString():
|
||||
if type.nullable():
|
||||
return (wrapAndSetPtr("xpc::StringToJsval(cx, %s, ${jsvalRef}.address())" % result), False)
|
||||
return (wrapAndSetPtr("xpc::StringToJsval(cx, %s, ${jsvalHandle})" % result), False)
|
||||
else:
|
||||
return (wrapAndSetPtr("xpc::NonVoidStringToJsval(cx, %s, ${jsvalRef}.address())" % result), False)
|
||||
return (wrapAndSetPtr("xpc::NonVoidStringToJsval(cx, %s, ${jsvalHandle})" % result), False)
|
||||
|
||||
if type.isByteString():
|
||||
if type.nullable():
|
||||
|
|
|
@ -67,9 +67,9 @@ public:
|
|||
MOZ_ASSERT(aReq && aAdapterPtr);
|
||||
}
|
||||
|
||||
virtual bool ParseSuccessfulReply(JS::Value* aValue)
|
||||
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
|
||||
{
|
||||
*aValue = JSVAL_VOID;
|
||||
aValue.setUndefined();
|
||||
|
||||
const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
|
||||
if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
|
||||
|
@ -113,7 +113,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
aValue->setObject(*JsDevices);
|
||||
aValue.setObject(*JsDevices);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -136,9 +136,9 @@ public:
|
|||
MOZ_ASSERT(aReq);
|
||||
}
|
||||
|
||||
virtual bool ParseSuccessfulReply(JS::Value* aValue)
|
||||
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
|
||||
{
|
||||
*aValue = JSVAL_VOID;
|
||||
aValue.setUndefined();
|
||||
|
||||
const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
|
||||
if (v.type() != BluetoothValue::Tbool) {
|
||||
|
@ -147,7 +147,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
aValue->setBoolean(v.get_bool());
|
||||
aValue.setBoolean(v.get_bool());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -878,6 +878,75 @@ BluetoothAdapter::IsScoConnected(ErrorResult& aRv)
|
|||
return request.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
BluetoothAdapter::AnswerWaitingCall(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
||||
if (!win) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
||||
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
||||
new BluetoothVoidReplyRunnable(request);
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
bs->AnswerWaitingCall(results);
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
BluetoothAdapter::IgnoreWaitingCall(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
||||
if (!win) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
||||
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
||||
new BluetoothVoidReplyRunnable(request);
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
bs->IgnoreWaitingCall(results);
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
BluetoothAdapter::ToggleCalls(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
||||
if (!win) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
||||
nsRefPtr<BluetoothVoidReplyRunnable> results =
|
||||
new BluetoothVoidReplyRunnable(request);
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
if (!bs) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
bs->ToggleCalls(results);
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
BluetoothAdapter::SendMediaMetaData(const MediaMetaData& aMediaMetaData, ErrorResult& aRv)
|
||||
{
|
||||
|
|
|
@ -137,6 +137,10 @@ public:
|
|||
already_AddRefed<DOMRequest> DisconnectSco(ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest> IsScoConnected(ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<DOMRequest> AnswerWaitingCall(ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest> IgnoreWaitingCall(ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest> ToggleCalls(ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
SendMediaMetaData(const MediaMetaData& aMediaMetaData, ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest>
|
||||
|
|
|
@ -142,22 +142,6 @@ static CINDItem sCINDItems[] = {
|
|||
{"roam", "0,1", 0, true}
|
||||
};
|
||||
|
||||
class mozilla::dom::bluetooth::Call {
|
||||
public:
|
||||
Call(uint16_t aState = nsITelephonyProvider::CALL_STATE_DISCONNECTED,
|
||||
bool aDirection = false,
|
||||
const nsAString& aNumber = EmptyString(),
|
||||
int aType = TOA_UNKNOWN)
|
||||
: mState(aState), mDirection(aDirection), mNumber(aNumber), mType(aType)
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t mState;
|
||||
bool mDirection; // true: incoming call; false: outgoing call
|
||||
nsString mNumber;
|
||||
int mType;
|
||||
};
|
||||
|
||||
class BluetoothHfpManager::GetVolumeTask : public nsISettingsServiceCallback
|
||||
{
|
||||
public:
|
||||
|
@ -313,6 +297,32 @@ IsMandatoryIndicator(const CINDType aType) {
|
|||
(aType == CINDType::CALLSETUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*/
|
||||
Call::Call()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void
|
||||
Call::Reset()
|
||||
{
|
||||
mState = nsITelephonyProvider::CALL_STATE_DISCONNECTED;
|
||||
mDirection = false;
|
||||
mNumber.Truncate();
|
||||
mType = TOA_UNKNOWN;
|
||||
}
|
||||
|
||||
bool
|
||||
Call::IsActive()
|
||||
{
|
||||
return (mState == nsITelephonyProvider::CALL_STATE_CONNECTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* BluetoothHfpManager
|
||||
*/
|
||||
BluetoothHfpManager::BluetoothHfpManager()
|
||||
{
|
||||
Reset();
|
||||
|
@ -326,6 +336,10 @@ BluetoothHfpManager::ResetCallArray()
|
|||
// index from RIL starts at 1.
|
||||
Call call;
|
||||
mCurrentCallArray.AppendElement(call);
|
||||
|
||||
if (mPhoneType == PhoneType::CDMA) {
|
||||
mCdmaSecondCall.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -550,6 +564,10 @@ BluetoothHfpManager::HandleVoiceConnectionChanged()
|
|||
connection->GetVoiceConnectionInfo(getter_AddRefs(voiceInfo));
|
||||
NS_ENSURE_TRUE_VOID(voiceInfo);
|
||||
|
||||
nsString type;
|
||||
voiceInfo->GetType(type);
|
||||
mPhoneType = GetPhoneType(type);
|
||||
|
||||
bool roaming;
|
||||
voiceInfo->GetRoaming(&roaming);
|
||||
UpdateCIND(CINDType::ROAM, roaming);
|
||||
|
@ -647,10 +665,15 @@ BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
|||
// For more information, please refer to 4.34.1 "Bluetooth Defined AT
|
||||
// Capabilities" in Bluetooth hands-free profile 1.6
|
||||
if (msg.Find("AT+BRSF=") != -1) {
|
||||
uint32_t brsf = BRSF_BIT_THREE_WAY_CALLING |
|
||||
BRSF_BIT_ABILITY_TO_REJECT_CALL |
|
||||
uint32_t brsf = BRSF_BIT_ABILITY_TO_REJECT_CALL |
|
||||
BRSF_BIT_ENHANCED_CALL_STATUS;
|
||||
|
||||
// No support for three way calling in CDMA since
|
||||
// CDMA disallows to hang existing call for CHLD=1
|
||||
if (mPhoneType != PhoneType::CDMA) {
|
||||
brsf |= BRSF_BIT_THREE_WAY_CALLING;
|
||||
}
|
||||
|
||||
if (mBSIR) {
|
||||
brsf |= BRSF_BIT_IN_BAND_RING_TONE;
|
||||
}
|
||||
|
@ -1076,6 +1099,68 @@ BluetoothHfpManager::Disconnect(BluetoothProfileController* aController)
|
|||
mSocket = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::SendCCWA(const nsAString& aNumber, int aType)
|
||||
{
|
||||
if (mCCWA) {
|
||||
nsAutoCString ccwaMsg("+CCWA: \"");
|
||||
ccwaMsg.Append(NS_ConvertUTF16toUTF8(aNumber));
|
||||
ccwaMsg.AppendLiteral("\",");
|
||||
ccwaMsg.AppendInt(aType);
|
||||
SendLine(ccwaMsg.get());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothHfpManager::SendCLCC(const Call& aCall, int aIndex)
|
||||
{
|
||||
if (aCall.mState == nsITelephonyProvider::CALL_STATE_DISCONNECTED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsAutoCString message("+CLCC: ");
|
||||
message.AppendInt(aIndex);
|
||||
message.AppendLiteral(",");
|
||||
message.AppendInt(aCall.mDirection);
|
||||
message.AppendLiteral(",");
|
||||
|
||||
int status = 0;
|
||||
switch (aCall.mState) {
|
||||
case nsITelephonyProvider::CALL_STATE_CONNECTED:
|
||||
if (mPhoneType == PhoneType::CDMA && aIndex == 1) {
|
||||
status = (mCdmaSecondCall.IsActive()) ? 1 : 0;
|
||||
}
|
||||
message.AppendInt(status);
|
||||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_HELD:
|
||||
message.AppendInt(1);
|
||||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_DIALING:
|
||||
message.AppendInt(2);
|
||||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_ALERTING:
|
||||
message.AppendInt(3);
|
||||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_INCOMING:
|
||||
if (!FindFirstCall(nsITelephonyProvider::CALL_STATE_CONNECTED)) {
|
||||
message.AppendInt(4);
|
||||
} else {
|
||||
message.AppendInt(5);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BT_WARNING("Not handling call status for CLCC");
|
||||
break;
|
||||
}
|
||||
|
||||
message.AppendLiteral(",0,0,\"");
|
||||
message.Append(NS_ConvertUTF16toUTF8(aCall.mNumber));
|
||||
message.AppendLiteral("\",");
|
||||
message.AppendInt(aCall.mType);
|
||||
|
||||
return SendLine(message.get());
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothHfpManager::SendLine(const char* aMessage)
|
||||
{
|
||||
|
@ -1143,49 +1228,18 @@ BluetoothHfpManager::SendCommand(const char* aCommand, uint32_t aValue)
|
|||
} else if (!strcmp(aCommand, "+CLCC: ")) {
|
||||
bool rv = true;
|
||||
uint32_t callNumbers = mCurrentCallArray.Length();
|
||||
for (uint32_t i = 1; i < callNumbers; i++) {
|
||||
Call& call = mCurrentCallArray[i];
|
||||
if (call.mState == nsITelephonyProvider::CALL_STATE_DISCONNECTED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
message.AssignLiteral("+CLCC: ");
|
||||
message.AppendInt(i);
|
||||
message.AppendLiteral(",");
|
||||
message.AppendInt(call.mDirection);
|
||||
message.AppendLiteral(",");
|
||||
|
||||
switch (call.mState) {
|
||||
case nsITelephonyProvider::CALL_STATE_CONNECTED:
|
||||
message.AppendInt(0);
|
||||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_HELD:
|
||||
message.AppendInt(1);
|
||||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_DIALING:
|
||||
message.AppendInt(2);
|
||||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_ALERTING:
|
||||
message.AppendInt(3);
|
||||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_INCOMING:
|
||||
if (!FindFirstCall(nsITelephonyProvider::CALL_STATE_CONNECTED)) {
|
||||
message.AppendInt(4);
|
||||
} else {
|
||||
message.AppendInt(5);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BT_WARNING("Not handling call status for CLCC");
|
||||
break;
|
||||
}
|
||||
message.AppendLiteral(",0,0,\"");
|
||||
message.Append(NS_ConvertUTF16toUTF8(call.mNumber));
|
||||
message.AppendLiteral("\",");
|
||||
message.AppendInt(call.mType);
|
||||
|
||||
rv &= SendLine(message.get());
|
||||
uint32_t i;
|
||||
for (i = 1; i < callNumbers; i++) {
|
||||
rv &= SendCLCC(mCurrentCallArray[i], i);
|
||||
}
|
||||
|
||||
if (!mCdmaSecondCall.mNumber.IsEmpty()) {
|
||||
MOZ_ASSERT(mPhoneType == PhoneType::CDMA);
|
||||
MOZ_ASSERT(i == 2);
|
||||
|
||||
rv &= SendCLCC(mCdmaSecondCall, 2);
|
||||
}
|
||||
|
||||
return rv;
|
||||
} else {
|
||||
message.AppendInt(aValue);
|
||||
|
@ -1276,13 +1330,7 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
|||
break;
|
||||
case nsITelephonyProvider::CALL_STATE_INCOMING:
|
||||
if (FindFirstCall(nsITelephonyProvider::CALL_STATE_CONNECTED)) {
|
||||
if (mCCWA) {
|
||||
nsAutoCString ccwaMsg("+CCWA: \"");
|
||||
ccwaMsg.Append(NS_ConvertUTF16toUTF8(aNumber));
|
||||
ccwaMsg.AppendLiteral("\",");
|
||||
ccwaMsg.AppendInt(mCurrentCallArray[aCallIndex].mType);
|
||||
SendLine(ccwaMsg.get());
|
||||
}
|
||||
SendCCWA(aNumber, mCurrentCallArray[aCallIndex].mType);
|
||||
UpdateCIND(CINDType::CALLSETUP, CallSetupState::INCOMING, aSend);
|
||||
} else {
|
||||
// Start sending RING indicator to HF
|
||||
|
@ -1410,6 +1458,77 @@ BluetoothHfpManager::HandleCallStateChanged(uint32_t aCallIndex,
|
|||
}
|
||||
}
|
||||
|
||||
PhoneType
|
||||
BluetoothHfpManager::GetPhoneType(const nsAString& aType)
|
||||
{
|
||||
// FIXME: Query phone type from RIL after RIL implements new API (bug 912019)
|
||||
if (aType.EqualsLiteral("gsm") || aType.EqualsLiteral("gprs") ||
|
||||
aType.EqualsLiteral("edge") || aType.EqualsLiteral("umts") ||
|
||||
aType.EqualsLiteral("hspa") || aType.EqualsLiteral("hsdpa") ||
|
||||
aType.EqualsLiteral("hsupa") || aType.EqualsLiteral("hspa+")) {
|
||||
return PhoneType::GSM;
|
||||
} else if (aType.EqualsLiteral("is95a") || aType.EqualsLiteral("is95b") ||
|
||||
aType.EqualsLiteral("1xrtt") || aType.EqualsLiteral("evdo0") ||
|
||||
aType.EqualsLiteral("evdoa") || aType.EqualsLiteral("evdob")) {
|
||||
return PhoneType::CDMA;
|
||||
}
|
||||
|
||||
return PhoneType::NONE;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::UpdateSecondNumber(const nsAString& aNumber)
|
||||
{
|
||||
MOZ_ASSERT(mPhoneType == PhoneType::CDMA);
|
||||
|
||||
// Always regard second call as incoming call since v1.2 RIL
|
||||
// doesn't support outgoing second call in CDMA.
|
||||
mCdmaSecondCall.mDirection = true;
|
||||
|
||||
mCdmaSecondCall.mNumber = aNumber;
|
||||
mCdmaSecondCall.mType = (aNumber[0] == '+') ? TOA_INTERNATIONAL :
|
||||
TOA_UNKNOWN;
|
||||
|
||||
SendCCWA(aNumber, mCdmaSecondCall.mType);
|
||||
UpdateCIND(CINDType::CALLSETUP, CallSetupState::INCOMING, true);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::AnswerWaitingCall()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mPhoneType == PhoneType::CDMA);
|
||||
|
||||
// Pick up second call. First call is held now.
|
||||
mCdmaSecondCall.mState = nsITelephonyProvider::CALL_STATE_CONNECTED;
|
||||
UpdateCIND(CINDType::CALLSETUP, CallSetupState::NO_CALLSETUP, true);
|
||||
|
||||
sCINDItems[CINDType::CALLHELD].value = CallHeldState::ONHOLD_ACTIVE;
|
||||
SendCommand("+CIEV: ", CINDType::CALLHELD);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::IgnoreWaitingCall()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mPhoneType == PhoneType::CDMA);
|
||||
|
||||
mCdmaSecondCall.Reset();
|
||||
UpdateCIND(CINDType::CALLSETUP, CallSetupState::NO_CALLSETUP, true);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::ToggleCalls()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mPhoneType == PhoneType::CDMA);
|
||||
|
||||
// Toggle acitve and held calls
|
||||
mCdmaSecondCall.mState = (mCdmaSecondCall.IsActive()) ?
|
||||
nsITelephonyProvider::CALL_STATE_HELD :
|
||||
nsITelephonyProvider::CALL_STATE_CONNECTED;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
|
||||
{
|
||||
|
|
|
@ -50,6 +50,24 @@ enum BluetoothCmeError {
|
|||
NETWORK_NOT_ALLOWED = 32
|
||||
};
|
||||
|
||||
enum PhoneType {
|
||||
NONE, // no connection
|
||||
GSM,
|
||||
CDMA
|
||||
};
|
||||
|
||||
class Call {
|
||||
public:
|
||||
Call();
|
||||
void Reset();
|
||||
bool IsActive();
|
||||
|
||||
uint16_t mState;
|
||||
bool mDirection; // true: incoming call; false: outgoing call
|
||||
nsString mNumber;
|
||||
int mType;
|
||||
};
|
||||
|
||||
class BluetoothHfpManager : public BluetoothSocketObserver
|
||||
, public BluetoothProfileManagerBase
|
||||
, public BatteryObserver
|
||||
|
@ -103,6 +121,12 @@ public:
|
|||
bool IsConnected();
|
||||
bool IsScoConnected();
|
||||
|
||||
// CDMA-specific functions
|
||||
void UpdateSecondNumber(const nsAString& aNumber);
|
||||
void AnswerWaitingCall();
|
||||
void IgnoreWaitingCall();
|
||||
void ToggleCalls();
|
||||
|
||||
private:
|
||||
class CloseScoTask;
|
||||
class GetVolumeTask;
|
||||
|
@ -125,10 +149,13 @@ private:
|
|||
void ResetCallArray();
|
||||
uint32_t FindFirstCall(uint16_t aState);
|
||||
uint32_t GetNumberOfCalls(uint16_t aState);
|
||||
PhoneType GetPhoneType(const nsAString& aType);
|
||||
|
||||
void NotifyConnectionStatusChanged(const nsAString& aType);
|
||||
void NotifyDialer(const nsAString& aCommand);
|
||||
|
||||
void SendCCWA(const nsAString& aNumber, int aType);
|
||||
bool SendCLCC(const Call& aCall, int aIndex);
|
||||
bool SendCommand(const char* aCommand, uint32_t aValue = 0);
|
||||
bool SendLine(const char* aMessage);
|
||||
void UpdateCIND(uint8_t aType, uint8_t aValue, bool aSend = true);
|
||||
|
@ -145,6 +172,7 @@ private:
|
|||
bool mCMER;
|
||||
bool mFirstCKPD;
|
||||
int mNetworkSelectionMode;
|
||||
PhoneType mPhoneType;
|
||||
bool mReceiveVgsFlag;
|
||||
bool mDialingRequestProcessed;
|
||||
nsString mDeviceAddress;
|
||||
|
@ -170,6 +198,9 @@ private:
|
|||
nsRefPtr<BluetoothSocket> mHeadsetSocket;
|
||||
nsRefPtr<BluetoothSocket> mScoSocket;
|
||||
SocketConnectionStatus mScoSocketStatus;
|
||||
|
||||
// CDMA-specific variable
|
||||
Call mCdmaSecondCall;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
|
|
@ -42,9 +42,9 @@ public:
|
|||
}
|
||||
|
||||
bool
|
||||
ParseSuccessfulReply(JS::Value* aValue)
|
||||
ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue)
|
||||
{
|
||||
*aValue = JSVAL_VOID;
|
||||
aValue.setUndefined();
|
||||
|
||||
const BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
|
||||
if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
|
||||
|
|
|
@ -32,7 +32,7 @@ BluetoothReplyRunnable::~BluetoothReplyRunnable()
|
|||
{}
|
||||
|
||||
nsresult
|
||||
BluetoothReplyRunnable::FireReply(const JS::Value& aVal)
|
||||
BluetoothReplyRunnable::FireReply(JS::Handle<JS::Value> aVal)
|
||||
{
|
||||
nsCOMPtr<nsIDOMRequestService> rs =
|
||||
do_GetService(DOMREQUEST_SERVICE_CONTRACTID);
|
||||
|
@ -62,10 +62,12 @@ BluetoothReplyRunnable::Run()
|
|||
|
||||
nsresult rv;
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
JS::Rooted<JS::Value> v(cx, JSVAL_VOID);
|
||||
|
||||
if (mReply->type() != BluetoothReply::TBluetoothReplySuccess) {
|
||||
rv = FireReply(JSVAL_VOID);
|
||||
rv = FireReply(v);
|
||||
} else {
|
||||
JS::Value v;
|
||||
if (!ParseSuccessfulReply(&v)) {
|
||||
rv = FireErrorString();
|
||||
} else {
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
protected:
|
||||
virtual ~BluetoothReplyRunnable();
|
||||
|
||||
virtual bool ParseSuccessfulReply(JS::Value* aValue) = 0;
|
||||
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) = 0;
|
||||
|
||||
// This is an autoptr so we don't have to bring the ipdl include into the
|
||||
// header. We assume we'll only be running this once and it should die on
|
||||
|
@ -45,7 +45,7 @@ protected:
|
|||
nsAutoPtr<BluetoothReply> mReply;
|
||||
|
||||
private:
|
||||
nsresult FireReply(const JS::Value& aVal);
|
||||
nsresult FireReply(JS::Handle<JS::Value> aVal);
|
||||
nsresult FireErrorString();
|
||||
|
||||
nsCOMPtr<nsIDOMDOMRequest> mDOMRequest;
|
||||
|
@ -59,9 +59,9 @@ public:
|
|||
~BluetoothVoidReplyRunnable();
|
||||
|
||||
protected:
|
||||
virtual bool ParseSuccessfulReply(JS::Value* aValue) MOZ_OVERRIDE
|
||||
virtual bool ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) MOZ_OVERRIDE
|
||||
{
|
||||
*aValue = JSVAL_VOID;
|
||||
aValue.setUndefined();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -214,6 +214,9 @@ TelephonyListener::SupplementaryServiceNotification(int32_t aCallIndex,
|
|||
NS_IMETHODIMP
|
||||
TelephonyListener::NotifyCdmaCallWaiting(const nsAString& aNumber)
|
||||
{
|
||||
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
|
||||
hfp->UpdateSecondNumber(aNumber);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,9 @@
|
|||
|
||||
#if defined(MOZ_B2G_BT)
|
||||
# if defined(MOZ_BLUETOOTH_GONK)
|
||||
# include "BluetoothGonkService.h"
|
||||
#ifndef MOZ_B2G_BT_BLUEDROID
|
||||
#include "BluetoothGonkService.h"
|
||||
#endif
|
||||
# elif defined(MOZ_BLUETOOTH_DBUS)
|
||||
# include "BluetoothDBusService.h"
|
||||
# else
|
||||
|
@ -304,9 +306,13 @@ BluetoothService::Create()
|
|||
#endif
|
||||
|
||||
#if defined(MOZ_BLUETOOTH_GONK)
|
||||
#ifndef MOZ_B2G_BT_BLUEDROID
|
||||
return new BluetoothGonkService();
|
||||
#endif
|
||||
#elif defined(MOZ_BLUETOOTH_DBUS)
|
||||
#ifdef MOZ_B2G_BT_BLUEZ
|
||||
return new BluetoothDBusService();
|
||||
#endif
|
||||
#endif
|
||||
BT_WARNING("No platform support for bluetooth!");
|
||||
return nullptr;
|
||||
|
|
|
@ -266,6 +266,15 @@ public:
|
|||
virtual void
|
||||
IsScoConnected(BluetoothReplyRunnable* aRunnable) = 0;
|
||||
|
||||
virtual void
|
||||
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) = 0;
|
||||
|
||||
virtual void
|
||||
IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable) = 0;
|
||||
|
||||
virtual void
|
||||
ToggleCalls(BluetoothReplyRunnable* aRunnable) = 0;
|
||||
|
||||
virtual void
|
||||
SendMetaData(const nsAString& aTitle,
|
||||
const nsAString& aArtist,
|
||||
|
|
|
@ -27,11 +27,12 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#ifdef MOZ_B2G_BT_BLUEZ
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/l2cap.h>
|
||||
#include <bluetooth/rfcomm.h>
|
||||
#include <bluetooth/sco.h>
|
||||
|
||||
#endif
|
||||
#include "BluetoothUnixSocketConnector.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
|
@ -43,6 +44,7 @@ static const int L2CAP_SO_SNDBUF = 400 * 1024; // 400 KB send buffer
|
|||
static const int L2CAP_SO_RCVBUF = 400 * 1024; // 400 KB receive buffer
|
||||
static const int L2CAP_MAX_MTU = 65000;
|
||||
|
||||
#ifdef MOZ_B2G_BT_BLUEZ
|
||||
static
|
||||
int get_bdaddr(const char *str, bdaddr_t *ba)
|
||||
{
|
||||
|
@ -62,6 +64,8 @@ void get_bdaddr_as_string(const bdaddr_t *ba, char *str) {
|
|||
b[5], b[4], b[3], b[2], b[1], b[0]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
BluetoothUnixSocketConnector::BluetoothUnixSocketConnector(
|
||||
BluetoothSocketType aType,
|
||||
int aChannel,
|
||||
|
@ -76,6 +80,7 @@ BluetoothUnixSocketConnector::BluetoothUnixSocketConnector(
|
|||
bool
|
||||
BluetoothUnixSocketConnector::SetUp(int aFd)
|
||||
{
|
||||
#ifdef MOZ_B2G_BT_BLUEZ
|
||||
int lm = 0;
|
||||
int sndbuf, rcvbuf;
|
||||
|
||||
|
@ -157,7 +162,7 @@ BluetoothUnixSocketConnector::SetUp(int aFd)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -167,6 +172,7 @@ BluetoothUnixSocketConnector::Create()
|
|||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
int fd = -1;
|
||||
|
||||
#ifdef MOZ_B2G_BT_BLUEZ
|
||||
switch (mType) {
|
||||
case BluetoothSocketType::RFCOMM:
|
||||
fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
|
||||
|
@ -193,7 +199,7 @@ BluetoothUnixSocketConnector::Create()
|
|||
BT_WARNING("Could not set up socket!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
@ -203,6 +209,7 @@ BluetoothUnixSocketConnector::CreateAddr(bool aIsServer,
|
|||
sockaddr_any& aAddr,
|
||||
const char* aAddress)
|
||||
{
|
||||
#ifdef MOZ_B2G_BT_BLUEZ
|
||||
// Set to BDADDR_ANY, if it's not a server, we'll reset.
|
||||
bdaddr_t bd_address_obj = {{0, 0, 0, 0, 0, 0}};
|
||||
|
||||
|
@ -242,6 +249,7 @@ BluetoothUnixSocketConnector::CreateAddr(bool aIsServer,
|
|||
BT_WARNING("Socket type unknown!");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -249,6 +257,7 @@ void
|
|||
BluetoothUnixSocketConnector::GetSocketAddr(const sockaddr_any& aAddr,
|
||||
nsAString& aAddrStr)
|
||||
{
|
||||
#ifdef MOZ_B2G_BT_BLUEZ
|
||||
char addr[18];
|
||||
switch (mType) {
|
||||
case BluetoothSocketType::RFCOMM:
|
||||
|
@ -265,4 +274,5 @@ BluetoothUnixSocketConnector::GetSocketAddr(const sockaddr_any& aAddr,
|
|||
MOZ_CRASH("Socket should be either RFCOMM or SCO!");
|
||||
}
|
||||
aAddrStr.AssignASCII(addr);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -36,6 +36,14 @@ DEFINES += -DMOZ_BLUETOOTH_DBUS
|
|||
endif
|
||||
endif
|
||||
|
||||
ifdef MOZ_B2G_BT_BLUEZ
|
||||
DEFINES += -DMOZ_B2G_BT_BLUEZ
|
||||
endif
|
||||
|
||||
ifdef MOZ_B2G_BT_BLUEDROID
|
||||
DEFINES += -DMOZ_B2G_BT_BLUEDROID
|
||||
endif
|
||||
|
||||
# Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
|
||||
# subdirectory.
|
||||
LOCAL_INCLUDES += $(VPATH:%=-I%)
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
}
|
||||
|
||||
virtual bool
|
||||
ParseSuccessfulReply(JS::Value* aValue) MOZ_OVERRIDE
|
||||
ParseSuccessfulReply(JS::MutableHandle<JS::Value> aValue) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_CRASH("This should never be called!");
|
||||
}
|
||||
|
@ -226,6 +226,12 @@ BluetoothParent::RecvPBluetoothRequestConstructor(
|
|||
return actor->DoRequest(aRequest.get_DisconnectScoRequest());
|
||||
case Request::TIsScoConnectedRequest:
|
||||
return actor->DoRequest(aRequest.get_IsScoConnectedRequest());
|
||||
case Request::TAnswerWaitingCallRequest:
|
||||
return actor->DoRequest(aRequest.get_AnswerWaitingCallRequest());
|
||||
case Request::TIgnoreWaitingCallRequest:
|
||||
return actor->DoRequest(aRequest.get_IgnoreWaitingCallRequest());
|
||||
case Request::TToggleCallsRequest:
|
||||
return actor->DoRequest(aRequest.get_ToggleCallsRequest());
|
||||
case Request::TSendMetaDataRequest:
|
||||
return actor->DoRequest(aRequest.get_SendMetaDataRequest());
|
||||
case Request::TSendPlayStatusRequest:
|
||||
|
@ -575,6 +581,39 @@ BluetoothRequestParent::DoRequest(const IsScoConnectedRequest& aRequest)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothRequestParent::DoRequest(const AnswerWaitingCallRequest& aRequest)
|
||||
{
|
||||
MOZ_ASSERT(mService);
|
||||
MOZ_ASSERT(mRequestType == Request::TAnswerWaitingCallRequest);
|
||||
|
||||
mService->AnswerWaitingCall(mReplyRunnable.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothRequestParent::DoRequest(const IgnoreWaitingCallRequest& aRequest)
|
||||
{
|
||||
MOZ_ASSERT(mService);
|
||||
MOZ_ASSERT(mRequestType == Request::TAnswerWaitingCallRequest);
|
||||
|
||||
mService->IgnoreWaitingCall(mReplyRunnable.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothRequestParent::DoRequest(const ToggleCallsRequest& aRequest)
|
||||
{
|
||||
MOZ_ASSERT(mService);
|
||||
MOZ_ASSERT(mRequestType == Request::TAnswerWaitingCallRequest);
|
||||
|
||||
mService->ToggleCalls(mReplyRunnable.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BluetoothRequestParent::DoRequest(const SendMetaDataRequest& aRequest)
|
||||
{
|
||||
|
|
|
@ -190,6 +190,15 @@ protected:
|
|||
bool
|
||||
DoRequest(const IsScoConnectedRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const AnswerWaitingCallRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const IgnoreWaitingCallRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const ToggleCallsRequest& aRequest);
|
||||
|
||||
bool
|
||||
DoRequest(const SendMetaDataRequest& aRequest);
|
||||
|
||||
|
|
|
@ -328,6 +328,27 @@ BluetoothServiceChildProcess::IsScoConnected(BluetoothReplyRunnable* aRunnable)
|
|||
SendRequest(aRunnable, IsScoConnectedRequest());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceChildProcess::AnswerWaitingCall(
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
SendRequest(aRunnable, AnswerWaitingCallRequest());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceChildProcess::IgnoreWaitingCall(
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
SendRequest(aRunnable, IgnoreWaitingCallRequest());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceChildProcess::ToggleCalls(
|
||||
BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
SendRequest(aRunnable, ToggleCallsRequest());
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothServiceChildProcess::SendMetaData(const nsAString& aTitle,
|
||||
const nsAString& aArtist,
|
||||
|
|
|
@ -149,6 +149,15 @@ public:
|
|||
virtual void
|
||||
IsScoConnected(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
ToggleCalls(BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
SendMetaData(const nsAString& aTitle,
|
||||
const nsAString& aArtist,
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче