mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge latest green fx-team changeset and mozilla-central
This commit is contained in:
commit
a308a05b5c
@ -4,7 +4,7 @@
|
||||
|
||||
#filter substitution
|
||||
|
||||
pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.xul");
|
||||
pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.html");
|
||||
pref("browser.chromeURL", "chrome://browser/content/");
|
||||
|
||||
// Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
|
||||
|
@ -11,7 +11,7 @@ window.addEventListener('ContentStart', function() {
|
||||
let shell = document.getElementById('shell');
|
||||
|
||||
// The <browser> element inside it
|
||||
let browser = document.getElementById('homescreen');
|
||||
let browser = document.getElementById('systemapp');
|
||||
|
||||
// Figure out the native resolution of the screen
|
||||
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
|
33
b2g/chrome/content/shell.html
Normal file
33
b2g/chrome/content/shell.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
- You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
id="shell"
|
||||
windowtype="navigator:browser"
|
||||
#ifdef ANDROID
|
||||
sizemode="fullscreen"
|
||||
#endif
|
||||
style="background: black; overflow: hidden; width:100%; height:100%; padding: 0px !important"
|
||||
onunload="shell.stop();">
|
||||
|
||||
<head>
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://browser/content/settings.js"> </script>
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://browser/content/shell.js"> </script>
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
<!-- this script handles the screen argument for desktop builds -->
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://browser/content/screen.js"> </script>
|
||||
<!-- this script handles the "runapp" argument for desktop builds -->
|
||||
<script type="application/javascript;version=1.8"
|
||||
src="chrome://browser/content/runapp.js"> </script>
|
||||
#endif
|
||||
</head>
|
||||
<body id="container" style="margin: 0px; width:100%; height:100%;">
|
||||
<!-- The html:iframe containing the UI is created here. -->
|
||||
</body>
|
||||
</html>
|
@ -186,7 +186,7 @@ var shell = {
|
||||
|
||||
get contentBrowser() {
|
||||
delete this.contentBrowser;
|
||||
return this.contentBrowser = document.getElementById('homescreen');
|
||||
return this.contentBrowser = document.getElementById('systemapp');
|
||||
},
|
||||
|
||||
get homeURL() {
|
||||
@ -269,25 +269,25 @@ var shell = {
|
||||
}
|
||||
|
||||
let manifestURL = this.manifestURL;
|
||||
// <html:iframe id="homescreen"
|
||||
// <html:iframe id="systemapp"
|
||||
// mozbrowser="true" allowfullscreen="true"
|
||||
// style="overflow: hidden; -moz-box-flex: 1; border: none;"
|
||||
// style="overflow: hidden; height: 100%; width: 100%; border: none;"
|
||||
// src="data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;'>"/>
|
||||
let browserFrame =
|
||||
let systemAppFrame =
|
||||
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:iframe');
|
||||
browserFrame.setAttribute('id', 'homescreen');
|
||||
browserFrame.setAttribute('mozbrowser', 'true');
|
||||
browserFrame.setAttribute('mozapp', manifestURL);
|
||||
browserFrame.setAttribute('allowfullscreen', 'true');
|
||||
browserFrame.setAttribute('style', "overflow: hidden; -moz-box-flex: 1; border: none;");
|
||||
browserFrame.setAttribute('src', "data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;");
|
||||
document.getElementById('shell').appendChild(browserFrame);
|
||||
systemAppFrame.setAttribute('id', 'systemapp');
|
||||
systemAppFrame.setAttribute('mozbrowser', 'true');
|
||||
systemAppFrame.setAttribute('mozapp', manifestURL);
|
||||
systemAppFrame.setAttribute('allowfullscreen', 'true');
|
||||
systemAppFrame.setAttribute('style', "overflow: hidden; height: 100%; width: 100%; border: none;");
|
||||
systemAppFrame.setAttribute('src', "data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;");
|
||||
document.getElementById('container').appendChild(systemAppFrame);
|
||||
|
||||
browserFrame.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
|
||||
.createInstance(Ci.nsISHistory);
|
||||
systemAppFrame.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
|
||||
.createInstance(Ci.nsISHistory);
|
||||
|
||||
// Capture all key events so we can filter out hardware buttons
|
||||
// And send them to Gaia via mozChromeEvents.
|
||||
@ -1239,3 +1239,50 @@ Services.obs.addObserver(function(aSubject, aTopic, aData) {
|
||||
Services.prefs.setIntPref("browser.cache.disk.capacity", size);
|
||||
}) ()
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
let SensorsListener = {
|
||||
sensorsListenerDevices: ['crespo'],
|
||||
device: libcutils.property_get("ro.product.device"),
|
||||
|
||||
deviceNeedsWorkaround: function SensorsListener_deviceNeedsWorkaround() {
|
||||
return (this.sensorsListenerDevices.indexOf(this.device) != -1);
|
||||
},
|
||||
|
||||
handleEvent: function SensorsListener_handleEvent(evt) {
|
||||
switch(evt.type) {
|
||||
case 'devicemotion':
|
||||
// Listener that does nothing, we need this to have the sensor being
|
||||
// able to report correct values, as explained in bug 753245, comment 6
|
||||
// and in bug 871916
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
observe: function SensorsListener_observe(subject, topic, data) {
|
||||
// We remove the listener when the screen is off, otherwise sensor will
|
||||
// continue to bother us with data and we won't be able to get the
|
||||
// system into suspend state, thus draining battery.
|
||||
if (data === 'on') {
|
||||
window.addEventListener('devicemotion', this);
|
||||
} else {
|
||||
window.removeEventListener('devicemotion', this);
|
||||
}
|
||||
},
|
||||
|
||||
init: function SensorsListener_init() {
|
||||
if (this.deviceNeedsWorkaround()) {
|
||||
// On boot, enable the listener, screen will be on.
|
||||
window.addEventListener('devicemotion', this);
|
||||
|
||||
// Then listen for further screen state changes
|
||||
Services.obs.addObserver(this, 'screen-state-changed', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SensorsListener.init();
|
||||
#endif
|
||||
|
@ -1,26 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
- You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="shell"
|
||||
windowtype="navigator:browser"
|
||||
#ifdef ANDROID
|
||||
sizemode="fullscreen"
|
||||
#endif
|
||||
style="background: black; overflow: hidden; width:320px; height:480px"
|
||||
onunload="shell.stop();">
|
||||
|
||||
<script type="application/javascript" src="chrome://browser/content/settings.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/shell.js"/>
|
||||
|
||||
#ifndef MOZ_WIDGET_GONK
|
||||
<!-- this script handles the screen argument for desktop builds -->
|
||||
<script type="application/javascript" src="chrome://browser/content/screen.js"/>
|
||||
<!-- this script handles the "runapp" argument for desktop builds -->
|
||||
<script type="application/javascript" src="chrome://browser/content/runapp.js"/>
|
||||
#endif
|
||||
<!-- The html:iframe containing the UI is created here. -->
|
||||
</window>
|
@ -12,7 +12,7 @@ chrome.jar:
|
||||
* content/dbg-browser-actors.js (content/dbg-browser-actors.js)
|
||||
content/forms.js (content/forms.js)
|
||||
* content/settings.js (content/settings.js)
|
||||
* content/shell.xul (content/shell.xul)
|
||||
* content/shell.html (content/shell.html)
|
||||
* content/shell.js (content/shell.js)
|
||||
#ifndef ANDROID
|
||||
content/screen.js (content/screen.js)
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"revision": "f400eac8b28353050ea9ff87dcb7e780e3537a89",
|
||||
"revision": "7db3c28d7056b880b3be261f7784b5cc3e96702b",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ Cu.import("resource://gre/modules/OfflineCacheInstaller.jsm");
|
||||
Cu.import("resource://gre/modules/SystemMessagePermissionsChecker.jsm");
|
||||
Cu.import("resource://gre/modules/AppDownloadManager.jsm");
|
||||
Cu.import("resource://gre/modules/WebappOSUtils.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
XPCOMUtils.defineLazyGetter(this, "libcutils", function() {
|
||||
@ -1327,7 +1328,6 @@ this.DOMApplicationRegistry = {
|
||||
|
||||
// Returns the MD5 hash of a file, doing async IO off the main thread.
|
||||
computeFileHash: function computeFileHash(aFile, aCallback) {
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
const CHUNK_SIZE = 16384;
|
||||
|
||||
// Return the two-digit hexadecimal code for a byte.
|
||||
|
@ -452,8 +452,7 @@ Navigator::GetMimeTypes(ErrorResult& aRv)
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
nsWeakPtr win = do_GetWeakReference(mWindow);
|
||||
mMimeTypes = new nsMimeTypeArray(win);
|
||||
mMimeTypes = new nsMimeTypeArray(mWindow);
|
||||
}
|
||||
|
||||
return mMimeTypes;
|
||||
@ -467,8 +466,7 @@ Navigator::GetPlugins(ErrorResult& aRv)
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
nsWeakPtr win = do_GetWeakReference(mWindow);
|
||||
mPlugins = new nsPluginArray(win);
|
||||
mPlugins = new nsPluginArray(mWindow);
|
||||
mPlugins->Init();
|
||||
}
|
||||
|
||||
@ -582,8 +580,7 @@ Navigator::JavaEnabled(ErrorResult& aRv)
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return false;
|
||||
}
|
||||
nsWeakPtr win = do_GetWeakReference(mWindow);
|
||||
mMimeTypes = new nsMimeTypeArray(win);
|
||||
mMimeTypes = new nsMimeTypeArray(mWindow);
|
||||
}
|
||||
|
||||
RefreshMIMEArray();
|
||||
|
@ -9,7 +9,6 @@ TEST_DIRS += ['test']
|
||||
XPIDL_SOURCES += [
|
||||
'nsIDOMDOMCursor.idl',
|
||||
'nsIDOMDOMRequest.idl',
|
||||
'nsIDOMDOMWindowResizeEventDetail.idl',
|
||||
'nsIEntropyCollector.idl',
|
||||
'nsIScriptChannel.idl',
|
||||
'nsISiteSpecificUserAgent.idl',
|
||||
@ -74,7 +73,6 @@ CPP_SOURCES += [
|
||||
'nsDOMNavigationTiming.cpp',
|
||||
'nsDOMScriptObjectFactory.cpp',
|
||||
'nsDOMWindowList.cpp',
|
||||
'nsDOMWindowResizeEventDetail.cpp',
|
||||
'nsDOMWindowUtils.cpp',
|
||||
'nsFocusManager.cpp',
|
||||
'nsGlobalWindow.cpp',
|
||||
|
@ -184,7 +184,6 @@
|
||||
#endif
|
||||
|
||||
#include "nsIDOMCameraManager.h"
|
||||
#include "nsIDOMDOMWindowResizeEventDetail.h"
|
||||
#include "nsIDOMGlobalObjectConstructor.h"
|
||||
#include "nsIDOMLockedFile.h"
|
||||
#include "nsDebug.h"
|
||||
@ -554,9 +553,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
NS_DEFINE_CLASSINFO_DATA(CameraCapabilities, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(DOMWindowResizeEventDetail, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(LockedFile, nsEventTargetSH,
|
||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(CSSFontFeatureValuesRule, nsDOMGenericSH,
|
||||
@ -1429,10 +1425,6 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsICameraCapabilities)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(DOMWindowResizeEventDetail, nsIDOMDOMWindowResizeEventDetail)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMWindowResizeEventDetail)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(LockedFile, nsIDOMLockedFile)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMLockedFile)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
@ -141,8 +141,6 @@ DOMCI_CLASS(BluetoothDevice)
|
||||
|
||||
DOMCI_CLASS(CameraCapabilities)
|
||||
|
||||
DOMCI_CLASS(DOMWindowResizeEventDetail)
|
||||
|
||||
DOMCI_CLASS(LockedFile)
|
||||
|
||||
DOMCI_CLASS(CSSFontFeatureValuesRule)
|
||||
|
@ -1,31 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsDOMWindowResizeEventDetail.h"
|
||||
#include "nsDOMClassInfoID.h" // DOMCI_DATA
|
||||
|
||||
DOMCI_DATA(DOMWindowResizeEventDetail, nsDOMWindowResizeEventDetail)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMWindowResizeEventDetail)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDOMWindowResizeEventDetail)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMWindowResizeEventDetail)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ADDREF(nsDOMWindowResizeEventDetail)
|
||||
NS_IMPL_RELEASE(nsDOMWindowResizeEventDetail)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowResizeEventDetail::GetWidth(int32_t* aOut)
|
||||
{
|
||||
*aOut = mSize.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowResizeEventDetail::GetHeight(int32_t* aOut)
|
||||
{
|
||||
*aOut = mSize.height;
|
||||
return NS_OK;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsIDOMDOMWindowResizeEventDetail.h"
|
||||
#include "nsSize.h"
|
||||
|
||||
class nsDOMWindowResizeEventDetail : public nsIDOMDOMWindowResizeEventDetail
|
||||
{
|
||||
public:
|
||||
nsDOMWindowResizeEventDetail(const nsIntSize& aSize)
|
||||
: mSize(aSize)
|
||||
{}
|
||||
|
||||
virtual ~nsDOMWindowResizeEventDetail() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMDOMWINDOWRESIZEEVENTDETAIL
|
||||
|
||||
private:
|
||||
const nsIntSize mSize;
|
||||
};
|
@ -34,7 +34,6 @@
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptTimeoutHandler.h"
|
||||
#include "nsDOMWindowResizeEventDetail.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Thanks so much, Microsoft! :(
|
||||
@ -179,6 +178,7 @@
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
#include "GeneratedEvents.h"
|
||||
#include "GeneratedEventClasses.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
@ -209,6 +209,7 @@
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "TimeChangeObserver.h"
|
||||
#include "mozilla/dom/AudioContext.h"
|
||||
#include "mozilla/dom/BrowserElementDictionariesBinding.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
|
||||
@ -4956,31 +4957,40 @@ nsGlobalWindow::DispatchCustomEvent(const char *aEventName)
|
||||
bool
|
||||
nsGlobalWindow::DispatchResizeEvent(const nsIntSize& aSize)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDoc);
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsresult rv = domDoc->CreateEvent(NS_LITERAL_STRING("CustomEvent"),
|
||||
getter_AddRefs(event));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
ErrorResult res;
|
||||
nsRefPtr<nsDOMEvent> domEvent =
|
||||
mDoc->CreateEvent(NS_LITERAL_STRING("CustomEvent"), res);
|
||||
if (res.Failed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWritableVariant> detailVariant = new nsVariant();
|
||||
nsCOMPtr<nsIDOMDOMWindowResizeEventDetail> detail =
|
||||
new nsDOMWindowResizeEventDetail(aSize);
|
||||
rv = detailVariant->SetAsISupports(detail);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoCompartment ac(cx, mJSObject);
|
||||
DOMWindowResizeEventDetailInitializer detail;
|
||||
detail.mWidth = aSize.width;
|
||||
detail.mHeight = aSize.height;
|
||||
JS::Rooted<JS::Value> detailValue(cx);
|
||||
detail.ToObject(cx, JS::NullPtr(), &detailValue);
|
||||
|
||||
nsCOMPtr<nsIDOMCustomEvent> customEvent = do_QueryInterface(event);
|
||||
customEvent->InitCustomEvent(NS_LITERAL_STRING("DOMWindowResize"),
|
||||
CustomEvent* customEvent = static_cast<CustomEvent*>(domEvent.get());
|
||||
customEvent->InitCustomEvent(cx,
|
||||
NS_LITERAL_STRING("DOMWindowResize"),
|
||||
/* bubbles = */ true,
|
||||
/* cancelable = */ true,
|
||||
detailVariant);
|
||||
customEvent->SetTrusted(true);
|
||||
customEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
|
||||
detailValue,
|
||||
res);
|
||||
if (res.Failed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
domEvent->SetTrusted(true);
|
||||
domEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
|
||||
|
||||
nsCOMPtr<EventTarget> target = do_QueryInterface(GetOuterWindow());
|
||||
customEvent->SetTarget(target);
|
||||
domEvent->SetTarget(target);
|
||||
|
||||
bool defaultActionEnabled = true;
|
||||
target->DispatchEvent(event, &defaultActionEnabled);
|
||||
target->DispatchEvent(domEvent, &defaultActionEnabled);
|
||||
|
||||
return defaultActionEnabled;
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(166fa8f4-ff40-4150-ab31-272e8246e362)]
|
||||
interface nsIDOMDOMWindowResizeEventDetail : nsISupports
|
||||
{
|
||||
readonly attribute long width;
|
||||
readonly attribute long height;
|
||||
};
|
@ -29,7 +29,6 @@
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -329,23 +328,102 @@ NS_HandleScriptError(nsIScriptGlobalObject *aScriptGlobal,
|
||||
return called;
|
||||
}
|
||||
|
||||
class ScriptErrorEvent : public nsRunnable
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
AsyncErrorReporter::AsyncErrorReporter(JSRuntime* aRuntime,
|
||||
JSErrorReport* aErrorReport,
|
||||
const char* aFallbackMessage,
|
||||
nsIPrincipal* aGlobalPrincipal,
|
||||
nsPIDOMWindow* aWindow)
|
||||
: mSourceLine(static_cast<const PRUnichar*>(aErrorReport->uclinebuf))
|
||||
, mLineNumber(aErrorReport->lineno)
|
||||
, mColumn(aErrorReport->uctokenptr - aErrorReport->uclinebuf)
|
||||
, mFlags(aErrorReport->flags)
|
||||
{
|
||||
if (!aErrorReport->filename) {
|
||||
mFileName.SetIsVoid(true);
|
||||
} else {
|
||||
mFileName.AssignWithConversion(aErrorReport->filename);
|
||||
}
|
||||
|
||||
const PRUnichar* m = static_cast<const PRUnichar*>(aErrorReport->ucmessage);
|
||||
if (m) {
|
||||
const PRUnichar* n = static_cast<const PRUnichar*>
|
||||
(js::GetErrorTypeName(aRuntime, aErrorReport->exnType));
|
||||
if (n) {
|
||||
mErrorMsg.Assign(n);
|
||||
mErrorMsg.AppendLiteral(": ");
|
||||
}
|
||||
mErrorMsg.Append(m);
|
||||
}
|
||||
|
||||
if (mErrorMsg.IsEmpty() && aFallbackMessage) {
|
||||
mErrorMsg.AssignWithConversion(aFallbackMessage);
|
||||
}
|
||||
|
||||
mCategory = nsContentUtils::IsSystemPrincipal(aGlobalPrincipal) ?
|
||||
NS_LITERAL_CSTRING("chrome javascript") :
|
||||
NS_LITERAL_CSTRING("content javascript");
|
||||
|
||||
mInnerWindowID = 0;
|
||||
if (aWindow && aWindow->IsOuterWindow()) {
|
||||
aWindow = aWindow->GetCurrentInnerWindow();
|
||||
}
|
||||
if (aWindow) {
|
||||
mInnerWindowID = aWindow->WindowID();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AsyncErrorReporter::ReportError()
|
||||
{
|
||||
nsCOMPtr<nsIScriptError> errorObject =
|
||||
do_CreateInstance("@mozilla.org/scripterror;1");
|
||||
if (!errorObject) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv = errorObject->InitWithWindowID(mErrorMsg, mFileName,
|
||||
mSourceLine, mLineNumber,
|
||||
mColumn, mFlags, mCategory,
|
||||
mInnerWindowID);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIConsoleService> consoleService =
|
||||
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
|
||||
if (!consoleService) {
|
||||
return;
|
||||
}
|
||||
|
||||
consoleService->LogMessage(errorObject);
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
class ScriptErrorEvent : public AsyncErrorReporter
|
||||
{
|
||||
public:
|
||||
ScriptErrorEvent(nsIScriptGlobalObject* aScriptGlobal,
|
||||
JSRuntime* aRuntime,
|
||||
JSErrorReport* aErrorReport,
|
||||
const char* aFallbackMessage,
|
||||
nsIPrincipal* aScriptOriginPrincipal,
|
||||
uint32_t aLineNr, uint32_t aColumn, uint32_t aFlags,
|
||||
const nsAString& aErrorMsg,
|
||||
const nsAString& aFileName,
|
||||
const nsAString& aSourceLine,
|
||||
bool aDispatchEvent,
|
||||
uint64_t aInnerWindowID)
|
||||
: mScriptGlobal(aScriptGlobal), mOriginPrincipal(aScriptOriginPrincipal),
|
||||
mLineNr(aLineNr), mColumn(aColumn),
|
||||
mFlags(aFlags), mErrorMsg(aErrorMsg), mFileName(aFileName),
|
||||
mSourceLine(aSourceLine), mDispatchEvent(aDispatchEvent),
|
||||
mInnerWindowID(aInnerWindowID)
|
||||
{}
|
||||
nsIPrincipal* aGlobalPrincipal,
|
||||
nsPIDOMWindow* aWindow,
|
||||
bool aDispatchEvent)
|
||||
// Pass an empty category, then compute ours
|
||||
: AsyncErrorReporter(aRuntime, aErrorReport, aFallbackMessage,
|
||||
aGlobalPrincipal, aWindow)
|
||||
, mScriptGlobal(aScriptGlobal)
|
||||
, mOriginPrincipal(aScriptOriginPrincipal)
|
||||
, mDispatchEvent(aDispatchEvent)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
@ -383,7 +461,7 @@ public:
|
||||
NS_NAMED_LITERAL_STRING(xoriginMsg, "Script error.");
|
||||
if (sameOrigin) {
|
||||
errorevent.errorMsg = mErrorMsg.get();
|
||||
errorevent.lineNr = mLineNr;
|
||||
errorevent.lineNr = mLineNumber;
|
||||
} else {
|
||||
NS_WARNING("Not same origin error!");
|
||||
errorevent.errorMsg = xoriginMsg.get();
|
||||
@ -399,54 +477,16 @@ public:
|
||||
}
|
||||
|
||||
if (status != nsEventStatus_eConsumeNoDefault) {
|
||||
// Make an nsIScriptError and populate it with information from
|
||||
// this error.
|
||||
nsCOMPtr<nsIScriptError> errorObject =
|
||||
do_CreateInstance("@mozilla.org/scripterror;1");
|
||||
|
||||
if (errorObject != nullptr) {
|
||||
nsresult rv = NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// Set category to chrome or content
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
|
||||
do_QueryInterface(mScriptGlobal);
|
||||
NS_ASSERTION(scriptPrincipal, "Global objects must implement "
|
||||
"nsIScriptObjectPrincipal");
|
||||
nsCOMPtr<nsIPrincipal> systemPrincipal;
|
||||
sSecurityManager->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
|
||||
const nsACString& category =
|
||||
scriptPrincipal->GetPrincipal() == systemPrincipal
|
||||
? NS_LITERAL_CSTRING("chrome javascript")
|
||||
: NS_LITERAL_CSTRING("content javascript");
|
||||
|
||||
rv = errorObject->InitWithWindowID(mErrorMsg, mFileName,
|
||||
mSourceLine,
|
||||
mLineNr, mColumn, mFlags,
|
||||
category, mInnerWindowID);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIConsoleService> consoleService =
|
||||
do_GetService(NS_CONSOLESERVICE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
consoleService->LogMessage(errorObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
AsyncErrorReporter::ReportError();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIScriptGlobalObject> mScriptGlobal;
|
||||
nsCOMPtr<nsIPrincipal> mOriginPrincipal;
|
||||
uint32_t mLineNr;
|
||||
uint32_t mColumn;
|
||||
uint32_t mFlags;
|
||||
nsString mErrorMsg;
|
||||
nsString mFileName;
|
||||
nsString mSourceLine;
|
||||
bool mDispatchEvent;
|
||||
uint64_t mInnerWindowID;
|
||||
|
||||
static bool sHandlingScriptError;
|
||||
};
|
||||
@ -499,53 +539,28 @@ NS_ScriptErrorReporter(JSContext *cx,
|
||||
nsIScriptGlobalObject *globalObject = context->GetGlobalObject();
|
||||
|
||||
if (globalObject) {
|
||||
nsAutoString fileName, msg;
|
||||
if (!report->filename) {
|
||||
fileName.SetIsVoid(true);
|
||||
} else {
|
||||
fileName.AssignWithConversion(report->filename);
|
||||
}
|
||||
|
||||
const PRUnichar* m = static_cast<const PRUnichar*>(report->ucmessage);
|
||||
if (m) {
|
||||
const PRUnichar* n = static_cast<const PRUnichar*>
|
||||
(js::GetErrorTypeName(cx, report->exnType));
|
||||
if (n) {
|
||||
msg.Assign(n);
|
||||
msg.AppendLiteral(": ");
|
||||
}
|
||||
msg.Append(m);
|
||||
}
|
||||
|
||||
if (msg.IsEmpty() && message) {
|
||||
msg.AssignWithConversion(message);
|
||||
}
|
||||
|
||||
|
||||
/* We do not try to report Out Of Memory via a dom
|
||||
* event because the dom event handler would encounter
|
||||
* an OOM exception trying to process the event, and
|
||||
* then we'd need to generate a new OOM event for that
|
||||
* new OOM instance -- this isn't pretty.
|
||||
*/
|
||||
nsAutoString sourceLine;
|
||||
sourceLine.Assign(reinterpret_cast<const PRUnichar*>(report->uclinebuf));
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(globalObject);
|
||||
uint64_t innerWindowID = 0;
|
||||
if (win) {
|
||||
nsCOMPtr<nsPIDOMWindow> innerWin = win->GetCurrentInnerWindow();
|
||||
if (innerWin) {
|
||||
innerWindowID = innerWin->WindowID();
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal =
|
||||
do_QueryInterface(globalObject);
|
||||
NS_ASSERTION(scriptPrincipal, "Global objects must implement "
|
||||
"nsIScriptObjectPrincipal");
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new ScriptErrorEvent(globalObject,
|
||||
JS_GetRuntime(cx),
|
||||
report,
|
||||
message,
|
||||
nsJSPrincipals::get(report->originPrincipals),
|
||||
report->lineno,
|
||||
report->uctokenptr - report->uclinebuf,
|
||||
report->flags, msg, fileName, sourceLine,
|
||||
report->errorNumber != JSMSG_OUT_OF_MEMORY,
|
||||
innerWindowID));
|
||||
scriptPrincipal->GetPrincipal(),
|
||||
win,
|
||||
/* We do not try to report Out Of Memory via a dom
|
||||
* event because the dom event handler would
|
||||
* encounter an OOM exception trying to process the
|
||||
* event, and then we'd need to generate a new OOM
|
||||
* event for that new OOM instance -- this isn't
|
||||
* pretty.
|
||||
*/
|
||||
report->errorNumber != JSMSG_OUT_OF_MEMORY));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsIArray.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class nsICycleCollectorListener;
|
||||
class nsIXPConnectJSObjectHolder;
|
||||
@ -181,6 +182,8 @@ private:
|
||||
};
|
||||
|
||||
class nsIJSRuntimeService;
|
||||
class nsIPrincipal;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -191,6 +194,37 @@ void ShutdownJSEnvironment();
|
||||
// Get the NameSpaceManager, creating if necessary
|
||||
nsScriptNameSpaceManager* GetNameSpaceManager();
|
||||
|
||||
// Runnable that's used to do async error reporting
|
||||
class AsyncErrorReporter : public nsRunnable
|
||||
{
|
||||
public:
|
||||
// aWindow may be null if this error report is not associated with a window
|
||||
AsyncErrorReporter(JSRuntime* aRuntime,
|
||||
JSErrorReport* aErrorReport,
|
||||
const char* aFallbackMessage,
|
||||
nsIPrincipal* aGlobalPrincipal, // To determine category
|
||||
nsPIDOMWindow* aWindow);
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
ReportError();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Do the actual error reporting
|
||||
void ReportError();
|
||||
|
||||
nsString mErrorMsg;
|
||||
nsString mFileName;
|
||||
nsString mSourceLine;
|
||||
nsCString mCategory;
|
||||
uint32_t mLineNumber;
|
||||
uint32_t mColumn;
|
||||
uint32_t mFlags;
|
||||
uint64_t mInnerWindowID;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -24,10 +24,11 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsMimeTypeArray)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsMimeTypeArray,
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(nsMimeTypeArray,
|
||||
mWindow,
|
||||
mMimeTypes)
|
||||
|
||||
nsMimeTypeArray::nsMimeTypeArray(nsWeakPtr aWindow)
|
||||
nsMimeTypeArray::nsMimeTypeArray(nsPIDOMWindow* aWindow)
|
||||
: mWindow(aWindow),
|
||||
mPluginMimeTypeCount(0)
|
||||
{
|
||||
@ -51,12 +52,11 @@ nsMimeTypeArray::Refresh()
|
||||
mPluginMimeTypeCount = 0;
|
||||
}
|
||||
|
||||
nsPIDOMWindow *
|
||||
nsPIDOMWindow*
|
||||
nsMimeTypeArray::GetParentObject() const
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
|
||||
MOZ_ASSERT(win);
|
||||
return win;
|
||||
MOZ_ASSERT(mWindow);
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
nsMimeType*
|
||||
@ -184,14 +184,12 @@ nsMimeTypeArray::GetSupportedNames(nsTArray< nsString >& aRetval)
|
||||
void
|
||||
nsMimeTypeArray::EnsureMimeTypes()
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
|
||||
|
||||
if (!mMimeTypes.IsEmpty() || !win) {
|
||||
if (!mMimeTypes.IsEmpty() || !mWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNavigator> navigator;
|
||||
win->GetNavigator(getter_AddRefs(navigator));
|
||||
mWindow->GetNavigator(getter_AddRefs(navigator));
|
||||
|
||||
if (!navigator) {
|
||||
return;
|
||||
@ -219,9 +217,9 @@ nsMimeTypeArray::EnsureMimeTypes()
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsMimeType, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsMimeType, Release)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsMimeType, mPluginElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(nsMimeType, mWindow, mPluginElement)
|
||||
|
||||
nsMimeType::nsMimeType(nsWeakPtr aWindow, nsPluginElement* aPluginElement,
|
||||
nsMimeType::nsMimeType(nsPIDOMWindow* aWindow, nsPluginElement* aPluginElement,
|
||||
uint32_t aPluginTagMimeIndex, const nsAString& aType)
|
||||
: mWindow(aWindow),
|
||||
mPluginElement(aPluginElement),
|
||||
@ -231,7 +229,7 @@ nsMimeType::nsMimeType(nsWeakPtr aWindow, nsPluginElement* aPluginElement,
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
nsMimeType::nsMimeType(nsWeakPtr aWindow, const nsAString& aType)
|
||||
nsMimeType::nsMimeType(nsPIDOMWindow* aWindow, const nsAString& aType)
|
||||
: mWindow(aWindow),
|
||||
mPluginElement(nullptr),
|
||||
mPluginTagMimeIndex(0),
|
||||
@ -244,12 +242,11 @@ nsMimeType::~nsMimeType()
|
||||
{
|
||||
}
|
||||
|
||||
nsPIDOMWindow *
|
||||
nsPIDOMWindow*
|
||||
nsMimeType::GetParentObject() const
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
|
||||
MOZ_ASSERT(win);
|
||||
return win;
|
||||
MOZ_ASSERT(mWindow);
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
@ -21,7 +20,7 @@ class nsMimeTypeArray MOZ_FINAL : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
nsMimeTypeArray(nsWeakPtr aWindow);
|
||||
nsMimeTypeArray(nsPIDOMWindow* aWindow);
|
||||
virtual ~nsMimeTypeArray();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
@ -45,7 +44,7 @@ protected:
|
||||
void EnsureMimeTypes();
|
||||
void Clear();
|
||||
|
||||
nsWeakPtr mWindow;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
|
||||
// mMimeTypes contains all mime types handled by plugins followed by
|
||||
// any other mime types that we handle internally and have been
|
||||
@ -64,9 +63,9 @@ public:
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsMimeType)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsMimeType)
|
||||
|
||||
nsMimeType(nsWeakPtr aWindow, nsPluginElement* aPluginElement,
|
||||
nsMimeType(nsPIDOMWindow* aWindow, nsPluginElement* aPluginElement,
|
||||
uint32_t aPluginTagMimeIndex, const nsAString& aMimeType);
|
||||
nsMimeType(nsWeakPtr aWindow, const nsAString& aMimeType);
|
||||
nsMimeType(nsPIDOMWindow* aWindow, const nsAString& aMimeType);
|
||||
virtual ~nsMimeType();
|
||||
|
||||
nsPIDOMWindow* GetParentObject() const;
|
||||
@ -85,7 +84,7 @@ public:
|
||||
void GetType(nsString& retval) const;
|
||||
|
||||
protected:
|
||||
nsWeakPtr mWindow;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
|
||||
// Strong reference to the active plugin, if any. Note that this
|
||||
// creates an explicit reference cycle through the plugin element's
|
||||
|
@ -21,7 +21,7 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
nsPluginArray::nsPluginArray(nsWeakPtr aWindow)
|
||||
nsPluginArray::nsPluginArray(nsPIDOMWindow* aWindow)
|
||||
: mWindow(aWindow)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
@ -44,9 +44,8 @@ nsPluginArray::~nsPluginArray()
|
||||
nsPIDOMWindow*
|
||||
nsPluginArray::GetParentObject() const
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
|
||||
MOZ_ASSERT(win);
|
||||
return win;
|
||||
MOZ_ASSERT(mWindow);
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
@ -64,7 +63,8 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginArray)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsPluginArray,
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(nsPluginArray,
|
||||
mWindow,
|
||||
mPlugins)
|
||||
|
||||
void
|
||||
@ -127,10 +127,8 @@ nsPluginArray::Refresh(bool aReloadDocuments)
|
||||
|
||||
mPlugins.Clear();
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
|
||||
|
||||
nsCOMPtr<nsIDOMNavigator> navigator;
|
||||
win->GetNavigator(getter_AddRefs(navigator));
|
||||
mWindow->GetNavigator(getter_AddRefs(navigator));
|
||||
|
||||
if (!navigator) {
|
||||
return;
|
||||
@ -138,7 +136,7 @@ nsPluginArray::Refresh(bool aReloadDocuments)
|
||||
|
||||
static_cast<mozilla::dom::Navigator*>(navigator.get())->RefreshMIMEArray();
|
||||
|
||||
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(win);
|
||||
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(mWindow);
|
||||
if (aReloadDocuments && webNav) {
|
||||
webNav->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
|
||||
}
|
||||
@ -244,8 +242,7 @@ nsPluginArray::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
bool
|
||||
nsPluginArray::AllowPlugins() const
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
|
||||
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(win);
|
||||
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mWindow);
|
||||
|
||||
return docShell && docShell->PluginsAllowedInCurrentDoc();
|
||||
}
|
||||
@ -280,9 +277,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginElement)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsPluginElement, mMimeTypes)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(nsPluginElement, mWindow, mMimeTypes)
|
||||
|
||||
nsPluginElement::nsPluginElement(nsWeakPtr aWindow,
|
||||
nsPluginElement::nsPluginElement(nsPIDOMWindow* aWindow,
|
||||
nsPluginTag* aPluginTag)
|
||||
: mWindow(aWindow),
|
||||
mPluginTag(aPluginTag)
|
||||
@ -293,9 +290,8 @@ nsPluginElement::nsPluginElement(nsWeakPtr aWindow,
|
||||
nsPIDOMWindow*
|
||||
nsPluginElement::GetParentObject() const
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mWindow));
|
||||
MOZ_ASSERT(win);
|
||||
return win;
|
||||
MOZ_ASSERT(mWindow);
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
// nsIObserver
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
nsPluginArray(nsWeakPtr aWindow);
|
||||
nsPluginArray(nsPIDOMWindow* aWindow);
|
||||
virtual ~nsPluginArray();
|
||||
|
||||
nsPIDOMWindow* GetParentObject() const;
|
||||
@ -59,7 +59,7 @@ private:
|
||||
bool AllowPlugins() const;
|
||||
void EnsurePlugins();
|
||||
|
||||
nsWeakPtr mWindow;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
nsTArray<nsRefPtr<nsPluginElement> > mPlugins;
|
||||
};
|
||||
|
||||
@ -70,7 +70,7 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsPluginElement)
|
||||
|
||||
nsPluginElement(nsWeakPtr aWindow, nsPluginTag* aPluginTag);
|
||||
nsPluginElement(nsPIDOMWindow* aWindow, nsPluginTag* aPluginTag);
|
||||
|
||||
nsPIDOMWindow* GetParentObject() const;
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
@ -99,7 +99,7 @@ public:
|
||||
protected:
|
||||
void EnsureMimeTypes();
|
||||
|
||||
nsWeakPtr mWindow;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
nsRefPtr<nsPluginTag> mPluginTag;
|
||||
nsTArray<nsRefPtr<nsMimeType> > mMimeTypes;
|
||||
};
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "nsStringGlue.h"
|
||||
#include "js/Value.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDOMString.h"
|
||||
|
@ -1624,6 +1624,12 @@ public:
|
||||
new (storage.addr()) T();
|
||||
return *storage.addr();
|
||||
}
|
||||
template <typename T1>
|
||||
T& SetValue(const T1 &t1)
|
||||
{
|
||||
new (storage.addr()) T(t1);
|
||||
return *storage.addr();
|
||||
}
|
||||
template <typename T1, typename T2>
|
||||
T& SetValue(const T1 &t1, const T2 &t2)
|
||||
{
|
||||
|
@ -2514,7 +2514,7 @@ class JSToNativeConversionInfo():
|
||||
|
||||
holderType: A CGThing representing the type of a "holder" which will
|
||||
hold a possible reference to the C++ thing whose type we
|
||||
returned in #1, or None if no such holder is needed.
|
||||
returned in declType, or None if no such holder is needed.
|
||||
|
||||
dealWithOptional: A boolean indicating whether the caller has to do
|
||||
optional-argument handling. This should only be set
|
||||
@ -2868,6 +2868,9 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
# to get traced
|
||||
if not isMember and typeNeedsRooting(elementType, descriptorProvider):
|
||||
holderType = CGTemplatedType("SequenceRooter", elementInfo.declType)
|
||||
# If our sequence is nullable, this will set the Nullable to be
|
||||
# not-null, but that's ok because we make an explicit SetNull() call
|
||||
# on it as needed if our JS value is actually null.
|
||||
holderArgs = "cx, &%s" % arrayRef
|
||||
else:
|
||||
holderType = None
|
||||
@ -3266,7 +3269,8 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
if type.isSpiderMonkeyInterface():
|
||||
assert not isEnforceRange and not isClamp
|
||||
name = type.name
|
||||
declType = CGGeneric(name)
|
||||
arrayType = CGGeneric(name)
|
||||
declType = arrayType
|
||||
if type.nullable():
|
||||
declType = CGTemplatedType("Nullable", declType)
|
||||
objRef = "${declName}.SetValue()"
|
||||
@ -3281,9 +3285,37 @@ for (uint32_t i = 0; i < length; ++i) {
|
||||
CGIndenter(onFailureBadType(failureCode, type.name)).define()))
|
||||
template = wrapObjectTemplate(template, type, "${declName}.SetNull()",
|
||||
failureCode)
|
||||
if not isMember:
|
||||
# This is a bit annoying. In a union we don't want to have a
|
||||
# holder, since unions don't support that. But if we're optional we
|
||||
# want to have a holder, so that the callee doesn't see
|
||||
# Optional<RootedTypedArray<ArrayType> >. So do a holder if we're
|
||||
# optional and use a RootedTypedArray otherwise.
|
||||
if isOptional:
|
||||
holderType = CGTemplatedType("TypedArrayRooter", arrayType)
|
||||
# If our typed array is nullable, this will set the Nullable to
|
||||
# be not-null, but that's ok because we make an explicit
|
||||
# SetNull() call on it as needed if our JS value is actually
|
||||
# null. XXXbz Because "Maybe" takes const refs for constructor
|
||||
# arguments, we can't pass a reference here; have to pass a
|
||||
# pointer.
|
||||
holderArgs = "cx, &%s" % objRef
|
||||
declArgs = None
|
||||
else:
|
||||
holderType = None
|
||||
holderArgs = None
|
||||
declType = CGTemplatedType("RootedTypedArray", declType)
|
||||
declArgs = "cx"
|
||||
else:
|
||||
holderType = None
|
||||
holderArgs = None
|
||||
declArgs = None
|
||||
return JSToNativeConversionInfo(template,
|
||||
declType=declType,
|
||||
dealWithOptional=isOptional)
|
||||
holderType=holderType,
|
||||
dealWithOptional=isOptional,
|
||||
declArgs=declArgs,
|
||||
holderArgs=holderArgs)
|
||||
|
||||
if type.isDOMString():
|
||||
assert not isEnforceRange and not isClamp
|
||||
@ -5769,7 +5801,8 @@ class CGMemberJITInfo(CGThing):
|
||||
# while we have the right type.
|
||||
getter = ("(JSJitGetterOp)get_%s" % self.member.identifier.name)
|
||||
getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
|
||||
getterconst = self.member.getExtendedAttribute("Constant")
|
||||
getterconst = (self.member.getExtendedAttribute("SameObject") or
|
||||
self.member.getExtendedAttribute("Constant"))
|
||||
getterpure = getterconst or self.member.getExtendedAttribute("Pure")
|
||||
assert (getterinfal or (not getterconst and not getterpure))
|
||||
|
||||
@ -6053,6 +6086,8 @@ def getUnionTypeTemplateVars(unionType, type, descriptorProvider, isReturnValue=
|
||||
else:
|
||||
name = type.name
|
||||
|
||||
ctorArgs = "cx" if type.isSpiderMonkeyInterface() else ""
|
||||
|
||||
tryNextCode = ("tryNext = true;\n"
|
||||
"return true;")
|
||||
if type.isGeckoInterface():
|
||||
@ -6085,7 +6120,7 @@ def getUnionTypeTemplateVars(unionType, type, descriptorProvider, isReturnValue=
|
||||
{
|
||||
"val": "value",
|
||||
"mutableVal": "pvalue",
|
||||
"declName": "SetAs" + name + "()",
|
||||
"declName": "SetAs" + name + "(%s)" % ctorArgs,
|
||||
"holderName": "m" + name + "Holder",
|
||||
}
|
||||
)
|
||||
@ -6106,7 +6141,9 @@ def getUnionTypeTemplateVars(unionType, type, descriptorProvider, isReturnValue=
|
||||
"structType": structType,
|
||||
"externalType": externalType,
|
||||
"setter": setter,
|
||||
"holderType": conversionInfo.holderType.define() if conversionInfo.holderType else None
|
||||
"holderType": conversionInfo.holderType.define() if conversionInfo.holderType else None,
|
||||
"ctorArgs": ctorArgs,
|
||||
"ctorArgList": [Argument("JSContext*", "cx")] if type.isSpiderMonkeyInterface() else []
|
||||
}
|
||||
|
||||
def mapTemplate(template, templateVarArray):
|
||||
@ -6157,13 +6194,13 @@ class CGUnionStruct(CGThing):
|
||||
isReturnValue=self.isReturnValue)
|
||||
if vars["name"] != "Object":
|
||||
body=string.Template("mType = e${name};\n"
|
||||
"return mValue.m${name}.SetValue();").substitute(vars)
|
||||
"return mValue.m${name}.SetValue(${ctorArgs});").substitute(vars)
|
||||
# bodyInHeader must be false for return values because they own
|
||||
# their union members and we don't want include headers in
|
||||
# UnionTypes.h just to call Addref/Release
|
||||
methods.append(ClassMethod("SetAs" + vars["name"],
|
||||
vars["structType"] + "&",
|
||||
[],
|
||||
vars["ctorArgList"],
|
||||
bodyInHeader=not self.isReturnValue,
|
||||
body=body))
|
||||
body = string.Template('MOZ_ASSERT(Is${name}(), "Wrong type!");\n'
|
||||
@ -6267,10 +6304,10 @@ class CGUnionConversionStruct(CGThing):
|
||||
methods.append(vars["setter"])
|
||||
if vars["name"] != "Object":
|
||||
body=string.Template("mUnion.mType = mUnion.e${name};\n"
|
||||
"return mUnion.mValue.m${name}.SetValue();").substitute(vars)
|
||||
"return mUnion.mValue.m${name}.SetValue(${ctorArgs});").substitute(vars)
|
||||
methods.append(ClassMethod("SetAs" + vars["name"],
|
||||
vars["structType"] + "&",
|
||||
[],
|
||||
vars["ctorArgList"],
|
||||
bodyInHeader=True,
|
||||
body=body,
|
||||
visibility="private"))
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Likely.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsproxy.h"
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
|
@ -9,12 +9,34 @@
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/*
|
||||
* Class that just handles the JSObject storage and tracing for typed arrays
|
||||
*/
|
||||
struct TypedArrayObjectStorage : AllTypedArraysBase {
|
||||
protected:
|
||||
JSObject* mObj;
|
||||
|
||||
TypedArrayObjectStorage()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
inline void TraceSelf(JSTracer* trc)
|
||||
{
|
||||
JS_CallObjectTracer(trc, &mObj, "TypedArray.mObj");
|
||||
}
|
||||
|
||||
private:
|
||||
TypedArrayObjectStorage(const TypedArrayObjectStorage&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
/*
|
||||
* Various typed array classes for argument conversion. We have a base class
|
||||
* that has a way of initializing a TypedArray from an existing typed array, and
|
||||
@ -23,21 +45,20 @@ namespace dom {
|
||||
*/
|
||||
template<typename T,
|
||||
JSObject* UnboxArray(JSObject*, uint32_t*, T**)>
|
||||
struct TypedArray_base : AllTypedArraysBase {
|
||||
struct TypedArray_base : public TypedArrayObjectStorage {
|
||||
TypedArray_base(JSObject* obj)
|
||||
{
|
||||
DoInit(obj);
|
||||
}
|
||||
|
||||
TypedArray_base() :
|
||||
mObj(nullptr)
|
||||
TypedArray_base()
|
||||
{
|
||||
mObj = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
T* mData;
|
||||
uint32_t mLength;
|
||||
JSObject* mObj;
|
||||
|
||||
public:
|
||||
inline bool Init(JSObject* obj)
|
||||
@ -71,16 +92,14 @@ public:
|
||||
return JS_WrapObject(cx, &mObj);
|
||||
}
|
||||
|
||||
inline void TraceSelf(JSTracer* trc)
|
||||
{
|
||||
JS_CallObjectTracer(trc, &mObj, "TypedArray.mObj");
|
||||
}
|
||||
|
||||
protected:
|
||||
inline void DoInit(JSObject* obj)
|
||||
{
|
||||
mObj = UnboxArray(obj, &mLength, &mData);
|
||||
}
|
||||
|
||||
private:
|
||||
TypedArray_base(const TypedArray_base&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
|
||||
@ -134,6 +153,8 @@ private:
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
TypedArray(const TypedArray&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
typedef TypedArray<int8_t, JS_GetInt8ArrayData, JS_GetObjectAsInt8Array,
|
||||
@ -169,6 +190,75 @@ typedef TypedArray<uint8_t, JS_GetArrayBufferData,
|
||||
JS_GetObjectAsArrayBuffer, JS_NewArrayBuffer>
|
||||
ArrayBuffer;
|
||||
|
||||
// A class for rooting an existing TypedArray struct
|
||||
template<typename ArrayType>
|
||||
class MOZ_STACK_CLASS TypedArrayRooter : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
TypedArrayRooter(JSContext* cx,
|
||||
ArrayType* aArray MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
|
||||
JS::CustomAutoRooter(cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
|
||||
mArray(aArray)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void trace(JSTracer* trc) MOZ_OVERRIDE
|
||||
{
|
||||
mArray->TraceSelf(trc);
|
||||
}
|
||||
|
||||
private:
|
||||
TypedArrayObjectStorage* const mArray;
|
||||
};
|
||||
|
||||
// And a specialization for dealing with nullable typed arrays
|
||||
template<typename Inner> struct Nullable;
|
||||
template<typename ArrayType>
|
||||
class MOZ_STACK_CLASS TypedArrayRooter<Nullable<ArrayType> > :
|
||||
private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
TypedArrayRooter(JSContext* cx,
|
||||
Nullable<ArrayType>* aArray MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
|
||||
JS::CustomAutoRooter(cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
|
||||
mArray(aArray)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void trace(JSTracer* trc) MOZ_OVERRIDE
|
||||
{
|
||||
if (!mArray->IsNull()) {
|
||||
mArray->Value().TraceSelf(trc);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Nullable<ArrayType>* const mArray;
|
||||
};
|
||||
|
||||
// Class for easily setting up a rooted typed array object on the stack
|
||||
template<typename ArrayType>
|
||||
class MOZ_STACK_CLASS RootedTypedArray : public ArrayType,
|
||||
private TypedArrayRooter<ArrayType>
|
||||
{
|
||||
public:
|
||||
RootedTypedArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
|
||||
ArrayType(),
|
||||
TypedArrayRooter<ArrayType>(cx,
|
||||
MOZ_THIS_IN_INITIALIZER_LIST()
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
|
||||
{
|
||||
}
|
||||
|
||||
RootedTypedArray(JSContext* cx, JSObject* obj MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
|
||||
ArrayType(obj),
|
||||
TypedArrayRooter<ArrayType>(cx,
|
||||
MOZ_THIS_IN_INITIALIZER_LIST()
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -243,7 +243,7 @@ class IDLScope(IDLObject):
|
||||
return
|
||||
|
||||
# ensureUnique twice with the same object is not allowed
|
||||
assert object != self._dict[identifier.name]
|
||||
assert id(object) != id(self._dict[identifier.name])
|
||||
|
||||
replacement = self.resolveIdentifierConflict(self, identifier,
|
||||
self._dict[identifier.name],
|
||||
@ -2601,6 +2601,10 @@ class IDLAttribute(IDLInterfaceMember):
|
||||
raise WebIDLError("An attribute with [PutForwards] must have an "
|
||||
"interface type as its type", [self.location])
|
||||
|
||||
if not self.type.isInterface() and self.getExtendedAttribute("SameObject"):
|
||||
raise WebIDLError("An attribute with [SameObject] must have an "
|
||||
"interface type as its type", [self.location])
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
@ -2615,12 +2619,14 @@ class IDLAttribute(IDLInterfaceMember):
|
||||
[self.location])
|
||||
elif (((identifier == "Throws" or identifier == "GetterThrows") and
|
||||
(self.getExtendedAttribute("Pure") or
|
||||
self.getExtendedAttribute("SameObject") or
|
||||
self.getExtendedAttribute("Constant"))) or
|
||||
((identifier == "Pure" or identifier == "Constant") and
|
||||
((identifier == "Pure" or identifier == "SameObject" or
|
||||
identifier == "Constant") and
|
||||
(self.getExtendedAttribute("Throws") or
|
||||
self.getExtendedAttribute("GetterThrows")))):
|
||||
raise WebIDLError("Throwing things can't be [Pure] or [Constant]",
|
||||
[attr.location])
|
||||
raise WebIDLError("Throwing things can't be [Pure] or [Constant] "
|
||||
"or [SameObject]", [attr.location])
|
||||
elif identifier == "LenientThis":
|
||||
if not attr.noArguments():
|
||||
raise WebIDLError("[LenientThis] must take no arguments",
|
||||
@ -2637,6 +2643,9 @@ class IDLAttribute(IDLInterfaceMember):
|
||||
raise WebIDLError("[Unforgeable] is only allowed on non-static "
|
||||
"attributes", [attr.location, self.location])
|
||||
self._unforgeable = True
|
||||
elif identifier == "SameObject" and not self.readonly:
|
||||
raise WebIDLError("[SameObject] only allowed on readonly attributes",
|
||||
[attr.location, self.location])
|
||||
elif identifier == "Constant" and not self.readonly:
|
||||
raise WebIDLError("[Constant] only allowed on readonly attributes",
|
||||
[attr.location, self.location])
|
||||
@ -2673,6 +2682,7 @@ class IDLAttribute(IDLInterfaceMember):
|
||||
identifier == "Throws" or
|
||||
identifier == "GetterThrows" or
|
||||
identifier == "ChromeOnly" or
|
||||
identifier == "SameObject" or
|
||||
identifier == "Constant" or
|
||||
identifier == "Func" or
|
||||
identifier == "Creator"):
|
||||
@ -3196,6 +3206,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
||||
raise WebIDLError("Methods must not be flagged as "
|
||||
"[Unforgeable]",
|
||||
[attr.location, self.location])
|
||||
elif identifier == "SameObject":
|
||||
raise WebIDLError("Methods must not be flagged as [SameObject]",
|
||||
[attr.location, self.location]);
|
||||
elif identifier == "Constant":
|
||||
raise WebIDLError("Methods must not be flagged as [Constant]",
|
||||
[attr.location, self.location]);
|
||||
|
@ -313,3 +313,29 @@ def WebIDLTest(parser, harness):
|
||||
except Exception, x:
|
||||
threw = True
|
||||
harness.ok(threw, "Should spell [Throws] correctly")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {
|
||||
[SameObject] readonly attribute boolean foo;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except Exception, x:
|
||||
threw = True
|
||||
harness.ok(threw, "Should not allow [SameObject] on attributes not of interface type")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
interface A {
|
||||
[SameObject] readonly attribute A foo;
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except Exception, x:
|
||||
threw = True
|
||||
harness.ok(not threw, "Should allow [SameObject] on attributes of interface type")
|
||||
|
@ -480,6 +480,7 @@ public:
|
||||
void PassOptionalNullableObjectWithDefaultValue(JSContext*, JS::Handle<JSObject*>);
|
||||
void PassSequenceOfObject(JSContext*, const Sequence<JSObject*>&);
|
||||
void PassSequenceOfNullableObject(JSContext*, const Sequence<JSObject*>&);
|
||||
void PassNullableSequenceOfObject(JSContext*, const Nullable<Sequence<JSObject*> >&);
|
||||
void PassOptionalNullableSequenceOfNullableSequenceOfObject(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*> > > > >&);
|
||||
void PassOptionalNullableSequenceOfNullableSequenceOfNullableObject(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*> > > > >&);
|
||||
JSObject* ReceiveObject(JSContext*);
|
||||
|
@ -432,6 +432,7 @@ interface TestInterface {
|
||||
void passOptionalNullableObjectWithDefaultValue(optional object? arg = null);
|
||||
void passSequenceOfObject(sequence<object> arg);
|
||||
void passSequenceOfNullableObject(sequence<object?> arg);
|
||||
void passNullableSequenceOfObject(sequence<object>? arg);
|
||||
void passOptionalNullableSequenceOfNullableSequenceOfObject(optional sequence<sequence<object>?>? arg);
|
||||
void passOptionalNullableSequenceOfNullableSequenceOfNullableObject(optional sequence<sequence<object?>?>? arg);
|
||||
object receiveObject();
|
||||
|
@ -328,6 +328,7 @@ interface TestExampleInterface {
|
||||
void passOptionalNullableObjectWithDefaultValue(optional object? arg = null);
|
||||
void passSequenceOfObject(sequence<object> arg);
|
||||
void passSequenceOfNullableObject(sequence<object?> arg);
|
||||
void passNullableSequenceOfObject(sequence<object>? arg);
|
||||
void passOptionalNullableSequenceOfNullableSequenceOfObject(optional sequence<sequence<object>?>? arg);
|
||||
void passOptionalNullableSequenceOfNullableSequenceOfNullableObject(optional sequence<sequence<object?>?>? arg);
|
||||
object receiveObject();
|
||||
|
@ -350,6 +350,7 @@ interface TestJSImplInterface {
|
||||
void passOptionalNullableObjectWithDefaultValue(optional object? arg = null);
|
||||
void passSequenceOfObject(sequence<object> arg);
|
||||
void passSequenceOfNullableObject(sequence<object?> arg);
|
||||
void passNullableSequenceOfObject(sequence<object>? arg);
|
||||
void passOptionalNullableSequenceOfNullableSequenceOfObject(optional sequence<sequence<object>?>? arg);
|
||||
void passOptionalNullableSequenceOfNullableSequenceOfNullableObject(optional sequence<sequence<object?>?>? arg);
|
||||
object receiveObject();
|
||||
|
@ -245,7 +245,7 @@ interface XMLDocument : Document {};
|
||||
|
||||
interface DOMImplementation {
|
||||
DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId);
|
||||
XMLDocument createDocument(DOMString? namespace, [TreatNullAs=EmptyString] DOMString qualifiedName, DocumentType? doctype);
|
||||
XMLDocument createDocument(DOMString? namespace, [TreatNullAs=EmptyString] DOMString qualifiedName, optional DocumentType? doctype = null);
|
||||
Document createHTMLDocument(optional DOMString title);
|
||||
|
||||
boolean hasFeature(DOMString feature, [TreatNullAs=EmptyString] DOMString version);
|
||||
|
@ -5,6 +5,8 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/Promise.h"
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/dom/PromiseBinding.h"
|
||||
#include "mozilla/dom/PromiseResolver.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
@ -13,7 +15,9 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "WorkerPrivate.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsJSEnvironment.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -52,11 +56,12 @@ private:
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(Promise)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Promise)
|
||||
tmp->MaybeReportRejected();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mResolver)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mResolveCallbacks);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRejectCallbacks);
|
||||
tmp->mResult = JSVAL_VOID;
|
||||
tmp->mResult = JS::UndefinedValue();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
@ -86,6 +91,7 @@ Promise::Promise(nsPIDOMWindow* aWindow)
|
||||
, mResult(JS::UndefinedValue())
|
||||
, mState(Pending)
|
||||
, mTaskPending(false)
|
||||
, mHadRejectCallback(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(Promise);
|
||||
NS_HOLD_JS_OBJECTS(this, Promise);
|
||||
@ -96,7 +102,8 @@ Promise::Promise(nsPIDOMWindow* aWindow)
|
||||
|
||||
Promise::~Promise()
|
||||
{
|
||||
mResult = JSVAL_VOID;
|
||||
MaybeReportRejected();
|
||||
mResult = JS::UndefinedValue();
|
||||
NS_DROP_JS_OBJECTS(this, Promise);
|
||||
MOZ_COUNT_DTOR(Promise);
|
||||
}
|
||||
@ -248,6 +255,7 @@ Promise::AppendCallbacks(PromiseCallback* aResolveCallback,
|
||||
}
|
||||
|
||||
if (aRejectCallback) {
|
||||
mHadRejectCallback = true;
|
||||
mRejectCallbacks.AppendElement(aRejectCallback);
|
||||
}
|
||||
|
||||
@ -280,5 +288,31 @@ Promise::RunTask()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Promise::MaybeReportRejected()
|
||||
{
|
||||
if (mState != Rejected || mHadRejectCallback || mResult.isUndefined()) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSErrorReport* report = js::ErrorFromException(mResult);
|
||||
if (!report) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mResult.isObject(), "How did we get a JSErrorReport?");
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win =
|
||||
do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(&mResult.toObject()));
|
||||
|
||||
// Now post an event to do the real reporting async
|
||||
NS_DispatchToCurrentThread(
|
||||
new AsyncErrorReporter(JS_GetObjectRuntime(&mResult.toObject()),
|
||||
report,
|
||||
nullptr,
|
||||
nsContentUtils::GetObjectPrincipal(&mResult.toObject()),
|
||||
win));
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -101,6 +101,10 @@ private:
|
||||
void AppendCallbacks(PromiseCallback* aResolveCallback,
|
||||
PromiseCallback* aRejectCallback);
|
||||
|
||||
// If we have been rejected and our mResult is a JS exception,
|
||||
// report it to the error console.
|
||||
void MaybeReportRejected();
|
||||
|
||||
nsRefPtr<nsPIDOMWindow> mWindow;
|
||||
|
||||
nsRefPtr<PromiseResolver> mResolver;
|
||||
@ -111,6 +115,7 @@ private:
|
||||
JS::Heap<JS::Value> mResult;
|
||||
PromiseState mState;
|
||||
bool mTaskPending;
|
||||
bool mHadRejectCallback;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -172,7 +172,6 @@ var interfaceNamesInGlobalScope =
|
||||
"DOMStringMap",
|
||||
"DOMTokenList",
|
||||
"DOMTransactionEvent",
|
||||
"DOMWindowResizeEventDetail",
|
||||
"DragEvent",
|
||||
"DynamicsCompressorNode",
|
||||
"Element",
|
||||
|
@ -22,3 +22,8 @@ dictionary OpenWindowEventDetail {
|
||||
DOMString features = "";
|
||||
Node? frameElement = null;
|
||||
};
|
||||
|
||||
dictionary DOMWindowResizeEventDetail {
|
||||
long width = 0;
|
||||
long height = 0;
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ interface DOMImplementation {
|
||||
[Throws]
|
||||
Document createDocument(DOMString? namespace,
|
||||
[TreatNullAs=EmptyString] DOMString qualifiedName,
|
||||
DocumentType? doctype);
|
||||
optional DocumentType? doctype = null);
|
||||
[Throws]
|
||||
Document createHTMLDocument(optional DOMString title);
|
||||
};
|
||||
|
@ -23,6 +23,7 @@ interface DummyInterface {
|
||||
void MmsAttachment(optional MmsAttachment arg);
|
||||
void AsyncScrollEventDetail(optional AsyncScrollEventDetail arg);
|
||||
void OpenWindowEventDetail(optional OpenWindowEventDetail arg);
|
||||
void DOMWindowResizeEventDetail(optional DOMWindowResizeEventDetail arg);
|
||||
void WifiOptions(optional WifiCommandOptions arg1,
|
||||
optional WifiResultOptions arg2);
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ interface Element : Node {
|
||||
[Constant]
|
||||
readonly attribute DOMTokenList? classList;
|
||||
|
||||
[Constant]
|
||||
[SameObject]
|
||||
readonly attribute MozNamedAttrMap attributes;
|
||||
DOMString? getAttribute(DOMString name);
|
||||
DOMString? getAttributeNS(DOMString? namespace, DOMString localName);
|
||||
|
@ -42,7 +42,7 @@ interface Node : EventTarget {
|
||||
[Pure]
|
||||
readonly attribute Element? parentElement;
|
||||
boolean hasChildNodes();
|
||||
[Constant]
|
||||
[SameObject]
|
||||
readonly attribute NodeList childNodes;
|
||||
[Pure]
|
||||
readonly attribute Node? firstChild;
|
||||
|
@ -120,7 +120,7 @@ class ControlRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ControlRunnable(CommandOptions aOptions) : mOptions(aOptions) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
|
@ -880,7 +880,7 @@ struct Coverage
|
||||
switch (format) {
|
||||
case 1: return u.format1.more ();
|
||||
case 2: return u.format2.more ();
|
||||
default:return true;
|
||||
default:return false;
|
||||
}
|
||||
}
|
||||
inline void next (void) {
|
||||
|
@ -253,7 +253,7 @@ class HashMap
|
||||
void rekey(const Lookup &old_key, const Key &new_key) {
|
||||
if (old_key != new_key) {
|
||||
if (Ptr p = lookup(old_key))
|
||||
impl.rekey(p, new_key, new_key);
|
||||
impl.rekeyAndMaybeRehash(p, new_key, new_key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -452,7 +452,7 @@ class HashSet
|
||||
void rekey(const Lookup &old_key, const T &new_key) {
|
||||
if (old_key != new_key) {
|
||||
if (Ptr p = lookup(old_key))
|
||||
impl.rekey(p, new_key, new_key);
|
||||
impl.rekeyAndMaybeRehash(p, new_key, new_key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -814,7 +814,7 @@ class HashTable : private AllocPolicy
|
||||
// a new key at the new Lookup position. |front()| is invalid after
|
||||
// this operation until the next call to |popFront()|.
|
||||
void rekeyFront(const Lookup &l, const Key &k) {
|
||||
table.rekey(*this->cur, l, k);
|
||||
table.rekeyWithoutRehash(*this->cur, l, k);
|
||||
rekeyed = true;
|
||||
this->validEntry = false;
|
||||
}
|
||||
@ -1462,7 +1462,7 @@ class HashTable : private AllocPolicy
|
||||
checkUnderloaded();
|
||||
}
|
||||
|
||||
void rekey(Ptr p, const Lookup &l, const Key &k)
|
||||
void rekeyWithoutRehash(Ptr p, const Lookup &l, const Key &k)
|
||||
{
|
||||
JS_ASSERT(table);
|
||||
mozilla::ReentrancyGuard g(*this);
|
||||
@ -1473,6 +1473,12 @@ class HashTable : private AllocPolicy
|
||||
putNewInfallible(l, mozilla::Move(t));
|
||||
}
|
||||
|
||||
void rekeyAndMaybeRehash(Ptr p, const Lookup &l, const Key &k)
|
||||
{
|
||||
rekeyWithoutRehash(p, l, k);
|
||||
checkOverRemoved();
|
||||
}
|
||||
|
||||
#undef METER
|
||||
};
|
||||
|
||||
|
@ -1112,11 +1112,69 @@ IonBuilder::traverseBytecode()
|
||||
return maybeAddOsrTypeBarriers();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// In debug builds, after compiling this op, check that all values
|
||||
// popped by this opcode either:
|
||||
//
|
||||
// (1) Have the Folded flag set on them.
|
||||
// (2) Have more uses than before compiling this op (the value is
|
||||
// used as operand of a new MIR instruction).
|
||||
//
|
||||
// This is used to catch problems where IonBuilder pops a value without
|
||||
// adding any SSA uses and doesn't call setFoldedUnchecked on it.
|
||||
Vector<MDefinition *> popped(cx);
|
||||
Vector<size_t> poppedUses(cx);
|
||||
unsigned nuses = GetUseCount(script_, pc - script_->code);
|
||||
|
||||
for (unsigned i = 0; i < nuses; i++) {
|
||||
MDefinition *def = current->peek(-int32_t(i + 1));
|
||||
if (!popped.append(def) || !poppedUses.append(def->defUseCount()))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Nothing in inspectOpcode() is allowed to advance the pc.
|
||||
JSOp op = JSOp(*pc);
|
||||
if (!inspectOpcode(op))
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG
|
||||
for (size_t i = 0; i < popped.length(); i++) {
|
||||
// Call instructions can discard PassArg instructions. Ignore them.
|
||||
if (popped[i]->isPassArg() && popped[i]->useCount() == 0)
|
||||
continue;
|
||||
|
||||
switch (op) {
|
||||
case JSOP_POP:
|
||||
case JSOP_POPN:
|
||||
case JSOP_DUP:
|
||||
case JSOP_DUP2:
|
||||
case JSOP_PICK:
|
||||
case JSOP_SWAP:
|
||||
case JSOP_SETARG:
|
||||
case JSOP_SETLOCAL:
|
||||
case JSOP_VOID:
|
||||
// Don't require SSA uses for values popped by these ops.
|
||||
break;
|
||||
|
||||
case JSOP_POS:
|
||||
case JSOP_TOID:
|
||||
// These ops may leave their input on the stack without setting
|
||||
// the Folded flag. If this value will be popped immediately,
|
||||
// we may replace it with |undefined|, but the difference is
|
||||
// not observable.
|
||||
JS_ASSERT(i == 0);
|
||||
if (current->peek(-1) == popped[0])
|
||||
break;
|
||||
// FALL THROUGH
|
||||
|
||||
default:
|
||||
JS_ASSERT(popped[i]->isFolded() || popped[i]->defUseCount() > poppedUses[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
pc += js_CodeSpec[op].length;
|
||||
current->updateTrackedPc(pc);
|
||||
}
|
||||
@ -5220,6 +5278,8 @@ IonBuilder::jsop_eval(uint32_t argc)
|
||||
return false;
|
||||
callInfo.unwrapArgs();
|
||||
|
||||
callInfo.fun()->setFoldedUnchecked();
|
||||
|
||||
MDefinition *scopeChain = current->scopeChain();
|
||||
MDefinition *string = callInfo.getArg(0);
|
||||
|
||||
@ -6526,6 +6586,7 @@ IonBuilder::getElemTryTypedStatic(bool *emitted, MDefinition *obj, MDefinition *
|
||||
// Emit LoadTypedArrayElementStatic.
|
||||
|
||||
obj->setFoldedUnchecked();
|
||||
index->setFoldedUnchecked();
|
||||
|
||||
MLoadTypedArrayElementStatic *load = MLoadTypedArrayElementStatic::New(tarr, ptr);
|
||||
current->add(load);
|
||||
@ -6651,6 +6712,7 @@ IonBuilder::getElemTryArgumentsInlined(bool *emitted, MDefinition *obj, MDefinit
|
||||
return true;
|
||||
|
||||
// Emit inlined arguments.
|
||||
obj->setFoldedUnchecked();
|
||||
|
||||
JS_ASSERT(!info().argsObjAliasesFormals());
|
||||
|
||||
@ -7066,6 +7128,7 @@ IonBuilder::setElemTryTypedStatic(bool *emitted, MDefinition *object,
|
||||
|
||||
// Emit StoreTypedArrayElementStatic.
|
||||
object->setFoldedUnchecked();
|
||||
index->setFoldedUnchecked();
|
||||
|
||||
// Clamp value to [0, 255] for Uint8ClampedArray.
|
||||
MDefinition *toWrite = value;
|
||||
|
@ -193,14 +193,26 @@ TypeName(JSType type, JSContext *cx)
|
||||
}
|
||||
|
||||
inline Handle<PropertyName*>
|
||||
ClassName(JSProtoKey key, ExclusiveContext *cx)
|
||||
ClassName(JSProtoKey key, JSAtomState &atomState)
|
||||
{
|
||||
JS_ASSERT(key < JSProto_LIMIT);
|
||||
JS_STATIC_ASSERT(offsetof(JSAtomState, Null) +
|
||||
JSProto_LIMIT * sizeof(FixedHeapPtr<PropertyName>) <=
|
||||
sizeof(JSAtomState));
|
||||
JS_STATIC_ASSERT(JSProto_Null == 0);
|
||||
return (&cx->names().Null)[key];
|
||||
return (&atomState.Null)[key];
|
||||
}
|
||||
|
||||
inline Handle<PropertyName*>
|
||||
ClassName(JSProtoKey key, JSRuntime *rt)
|
||||
{
|
||||
return ClassName(key, rt->atomState);
|
||||
}
|
||||
|
||||
inline Handle<PropertyName*>
|
||||
ClassName(JSProtoKey key, ExclusiveContext *cx)
|
||||
{
|
||||
return ClassName(key, cx->names());
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
@ -872,7 +872,7 @@ js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale,
|
||||
}
|
||||
|
||||
JS_FRIEND_API(const jschar*)
|
||||
js::GetErrorTypeName(JSContext* cx, int16_t exnType)
|
||||
js::GetErrorTypeName(JSRuntime* rt, int16_t exnType)
|
||||
{
|
||||
/*
|
||||
* JSEXN_INTERNALERR returns null to prevent that "InternalError: "
|
||||
@ -884,7 +884,7 @@ js::GetErrorTypeName(JSContext* cx, int16_t exnType)
|
||||
return NULL;
|
||||
}
|
||||
JSProtoKey key = GetExceptionProtoKey(exnType);
|
||||
return ClassName(key, cx)->chars();
|
||||
return ClassName(key, rt)->chars();
|
||||
}
|
||||
|
||||
#if defined ( DEBUG_mccabe ) && defined ( PRINTNAMES )
|
||||
|
@ -555,6 +555,12 @@ js::SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback)
|
||||
rt->preserveWrapperCallback = callback;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSErrorReport*)
|
||||
js::ErrorFromException(Value val)
|
||||
{
|
||||
return js_ErrorFromException(val);
|
||||
}
|
||||
|
||||
/*
|
||||
* The below code is for temporary telemetry use. It can be removed when
|
||||
* sufficient data has been harvested.
|
||||
|
@ -35,6 +35,7 @@ class JSAtom;
|
||||
struct JSErrorFormatString;
|
||||
class JSLinearString;
|
||||
struct JSJitInfo;
|
||||
class JSErrorReport;
|
||||
|
||||
namespace JS {
|
||||
template <class T>
|
||||
@ -576,6 +577,14 @@ SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback);
|
||||
JS_FRIEND_API(bool)
|
||||
IsObjectInContextCompartment(JSObject *obj, const JSContext *cx);
|
||||
|
||||
/*
|
||||
* ErrorFromException takes a raw Value so that it's possible to call it during
|
||||
* GC/CC/whatever, when it may not be possible to get a JSContext to create a
|
||||
* Rooted. It promises to never ever GC.
|
||||
*/
|
||||
JS_FRIEND_API(JSErrorReport*)
|
||||
ErrorFromException(JS::Value val);
|
||||
|
||||
/*
|
||||
* NB: these flag bits are encoded into the bytecode stream in the immediate
|
||||
* operand of JSOP_ITER, so don't change them without advancing vm/Xdr.h's
|
||||
@ -713,7 +722,7 @@ CastToJSFreeOp(FreeOp *fop)
|
||||
* Returns NULL for invalid arguments and JSEXN_INTERNALERR
|
||||
*/
|
||||
extern JS_FRIEND_API(const jschar*)
|
||||
GetErrorTypeName(JSContext* cx, int16_t exnType);
|
||||
GetErrorTypeName(JSRuntime* rt, int16_t exnType);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern JS_FRIEND_API(unsigned)
|
||||
|
@ -464,6 +464,25 @@ js::math_imul(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::math_fround(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (args.length() == 0) {
|
||||
args.rval().setDouble(js_NaN);
|
||||
return true;
|
||||
}
|
||||
|
||||
double x;
|
||||
if (!ToNumber(cx, args[0], &x))
|
||||
return false;
|
||||
|
||||
float f = x;
|
||||
args.rval().setDouble(static_cast<double>(f));
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(SOLARIS) && defined(__GNUC__)
|
||||
#define LOG_IF_OUT_OF_RANGE(x) if (x < 0) return js_NaN;
|
||||
#else
|
||||
@ -1425,6 +1444,7 @@ static const JSFunctionSpec math_static_methods[] = {
|
||||
JS_FN("exp", math_exp, 1, 0),
|
||||
JS_FN("floor", js_math_floor, 1, 0),
|
||||
JS_FN("imul", math_imul, 2, 0),
|
||||
JS_FN("fround", math_fround, 1, 0),
|
||||
JS_FN("log", math_log, 1, 0),
|
||||
JS_FN("max", js_math_max, 2, 0),
|
||||
JS_FN("min", js_math_min, 2, 0),
|
||||
|
@ -99,6 +99,9 @@ namespace js {
|
||||
extern bool
|
||||
math_imul(JSContext *cx, unsigned argc, js::Value *vp);
|
||||
|
||||
extern bool
|
||||
math_fround(JSContext *cx, unsigned argc, js::Value *vp);
|
||||
|
||||
extern bool
|
||||
math_log(JSContext *cx, unsigned argc, js::Value *vp);
|
||||
|
||||
|
@ -26,8 +26,11 @@ using namespace js::gc;
|
||||
using mozilla::ArrayLength;
|
||||
|
||||
void
|
||||
js::AutoEnterPolicy::reportError(JSContext *cx, jsid id)
|
||||
js::AutoEnterPolicy::reportErrorIfExceptionIsNotPending(JSContext *cx, jsid id)
|
||||
{
|
||||
if (JS_IsExceptionPending(cx))
|
||||
return;
|
||||
|
||||
if (JSID_IS_VOID(id)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_OBJECT_ACCESS_DENIED);
|
||||
|
@ -9,13 +9,26 @@
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
#include "js/CallNonGenericMethod.h"
|
||||
#include "js/Class.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
using JS::AutoIdVector;
|
||||
using JS::CallArgs;
|
||||
using JS::HandleId;
|
||||
using JS::HandleObject;
|
||||
using JS::HandleValue;
|
||||
using JS::IsAcceptableThis;
|
||||
using JS::MutableHandle;
|
||||
using JS::MutableHandleObject;
|
||||
using JS::MutableHandleValue;
|
||||
using JS::NativeImpl;
|
||||
using JS::PrivateValue;
|
||||
using JS::Value;
|
||||
|
||||
class RegExpGuard;
|
||||
class JS_FRIEND_API(Wrapper);
|
||||
|
||||
@ -275,12 +288,12 @@ extern JS_FRIEND_DATA(js::Class* const) OuterWindowProxyClassPtr;
|
||||
|
||||
inline bool IsObjectProxyClass(const Class *clasp)
|
||||
{
|
||||
return clasp == js::ObjectProxyClassPtr || clasp == js::OuterWindowProxyClassPtr;
|
||||
return clasp == ObjectProxyClassPtr || clasp == OuterWindowProxyClassPtr;
|
||||
}
|
||||
|
||||
inline bool IsFunctionProxyClass(const Class *clasp)
|
||||
{
|
||||
return clasp == js::FunctionProxyClassPtr;
|
||||
return clasp == FunctionProxyClassPtr;
|
||||
}
|
||||
|
||||
inline bool IsProxyClass(const Class *clasp)
|
||||
@ -388,8 +401,8 @@ class JS_FRIEND_API(AutoEnterPolicy)
|
||||
// * The policy set rv to false, indicating that we should throw.
|
||||
// * The caller did not instruct us to ignore exceptions.
|
||||
// * The policy did not throw itself.
|
||||
if (!allow && !rv && mayThrow && !JS_IsExceptionPending(cx))
|
||||
reportError(cx, id);
|
||||
if (!allow && !rv && mayThrow)
|
||||
reportErrorIfExceptionIsNotPending(cx, id);
|
||||
}
|
||||
|
||||
virtual ~AutoEnterPolicy() { recordLeave(); }
|
||||
@ -403,7 +416,7 @@ class JS_FRIEND_API(AutoEnterPolicy)
|
||||
: context(NULL)
|
||||
#endif
|
||||
{};
|
||||
void reportError(JSContext *cx, jsid id);
|
||||
void reportErrorIfExceptionIsNotPending(JSContext *cx, jsid id);
|
||||
bool allow;
|
||||
bool rv;
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsproxy.h"
|
||||
|
||||
namespace js {
|
||||
|
81
js/src/tests/ecma_6/Math/fround.js
Normal file
81
js/src/tests/ecma_6/Math/fround.js
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
// Some tests regarding conversion to Float32
|
||||
assertEq(Math.fround(), NaN);
|
||||
|
||||
// Special values
|
||||
assertEq(Math.fround(NaN), NaN);
|
||||
assertEq(Math.fround(-Infinity), -Infinity);
|
||||
assertEq(Math.fround(Infinity), Infinity);
|
||||
assertEq(Math.fround(-0), -0);
|
||||
assertEq(Math.fround(+0), +0);
|
||||
|
||||
// Polyfill function for Float32 conversion
|
||||
var toFloat32 = (function() {
|
||||
var f32 = new Float32Array(1);
|
||||
function f(x) {
|
||||
f32[0] = x;
|
||||
return f32[0];
|
||||
}
|
||||
return f;
|
||||
})();
|
||||
|
||||
// A test on a certain range of numbers, including big numbers, so that
|
||||
// we get a loss in precision for some of them.
|
||||
for (var i = 0; i < 64; ++i) {
|
||||
var p = Math.pow(2, i) + 1;
|
||||
assertEq(Math.fround(p), toFloat32(p));
|
||||
assertEq(Math.fround(-p), toFloat32(-p));
|
||||
}
|
||||
|
||||
/********************************************
|
||||
/* Tests on maximal Float32 / Double values *
|
||||
/*******************************************/
|
||||
function maxValue(exponentWidth, significandWidth) {
|
||||
var n = 0;
|
||||
var maxExp = Math.pow(2, exponentWidth - 1) - 1;
|
||||
for (var i = significandWidth; i >= 0; i--)
|
||||
n += Math.pow(2, maxExp - i);
|
||||
return n;
|
||||
}
|
||||
|
||||
var DBL_MAX = maxValue(11, 52);
|
||||
assertEq(DBL_MAX, Number.MAX_VALUE); // sanity check
|
||||
|
||||
// Finite as a double, too big for a float
|
||||
assertEq(Math.fround(DBL_MAX), Infinity);
|
||||
|
||||
var FLT_MAX = maxValue(8, 23);
|
||||
assertEq(Math.fround(FLT_MAX), FLT_MAX);
|
||||
assertEq(Math.fround(FLT_MAX + Math.pow(2, Math.pow(2, 8 - 1) - 1 - 23 - 2)), FLT_MAX); // round-nearest rounds down to FLT_MAX
|
||||
assertEq(Math.fround(FLT_MAX + Math.pow(2, Math.pow(2, 8 - 1) - 1 - 23 - 1)), Infinity); // no longer rounds down to FLT_MAX
|
||||
|
||||
/*********************************************************
|
||||
/******* Tests on denormalizations and roundings *********
|
||||
/********************************************************/
|
||||
|
||||
function minValue(exponentWidth, significandWidth) {
|
||||
return Math.pow(2, -(Math.pow(2, exponentWidth - 1) - 2) - significandWidth);
|
||||
}
|
||||
|
||||
var DBL_MIN = Math.pow(2, -1074);
|
||||
assertEq(DBL_MIN, Number.MIN_VALUE); // sanity check
|
||||
|
||||
// Too small for a float
|
||||
assertEq(Math.fround(DBL_MIN), 0);
|
||||
|
||||
var FLT_MIN = minValue(8, 23);
|
||||
assertEq(Math.fround(FLT_MIN), FLT_MIN);
|
||||
|
||||
assertEq(Math.fround(FLT_MIN / 2), 0); // halfway, round-nearest rounds down to 0 (even)
|
||||
assertEq(Math.fround(FLT_MIN / 2 + Math.pow(2, -202)), FLT_MIN); // first double > FLT_MIN / 2, rounds up to FLT_MIN
|
||||
|
||||
assertEq(Math.fround(-FLT_MIN), -FLT_MIN);
|
||||
|
||||
assertEq(Math.fround(-FLT_MIN / 2), -0); // halfway, round-nearest rounds up to -0 (even)
|
||||
assertEq(Math.fround(-FLT_MIN / 2 - Math.pow(2, -202)), -FLT_MIN); // first double < -FLT_MIN / 2, rounds down to -FLT_MIN
|
||||
|
||||
reportCompare(0, 0, "ok");
|
@ -8,6 +8,7 @@
|
||||
#ifndef xpcpublic_h
|
||||
#define xpcpublic_h
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsproxy.h"
|
||||
#include "js/HeapAPI.h"
|
||||
#include "js/GCAPI.h"
|
||||
|
@ -8,6 +8,7 @@
|
||||
#ifndef __AccessCheck_h__
|
||||
#define __AccessCheck_h__
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
class nsIPrincipal;
|
||||
|
@ -1906,14 +1906,15 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
|
||||
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
|
||||
bool usingDisplayPort = false;
|
||||
nsRect displayport;
|
||||
if (rootScrollFrame) {
|
||||
if (rootScrollFrame && !aFrame->GetParent()) {
|
||||
nsIContent* content = rootScrollFrame->GetContent();
|
||||
if (content) {
|
||||
usingDisplayPort = nsLayoutUtils::GetDisplayPort(content, &displayport);
|
||||
}
|
||||
}
|
||||
|
||||
bool ignoreViewportScrolling = presShell->IgnoringViewportScrolling();
|
||||
bool ignoreViewportScrolling =
|
||||
aFrame->GetParent() ? false : presShell->IgnoringViewportScrolling();
|
||||
nsRegion visibleRegion;
|
||||
if (aFlags & PAINT_WIDGET_LAYERS) {
|
||||
// This layer tree will be reused, so we'll need to calculate it
|
||||
@ -1975,30 +1976,27 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ignoreViewportScrolling && !aFrame->GetParent()) {
|
||||
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
|
||||
if (rootScrollFrame) {
|
||||
nsIScrollableFrame* rootScrollableFrame =
|
||||
presShell->GetRootScrollFrameAsScrollable();
|
||||
if (aFlags & PAINT_DOCUMENT_RELATIVE) {
|
||||
// Make visibleRegion and aRenderingContext relative to the
|
||||
// scrolled frame instead of the root frame.
|
||||
nsPoint pos = rootScrollableFrame->GetScrollPosition();
|
||||
visibleRegion.MoveBy(-pos);
|
||||
if (aRenderingContext) {
|
||||
aRenderingContext->Translate(pos);
|
||||
}
|
||||
if (ignoreViewportScrolling && rootScrollFrame) {
|
||||
nsIScrollableFrame* rootScrollableFrame =
|
||||
presShell->GetRootScrollFrameAsScrollable();
|
||||
if (aFlags & PAINT_DOCUMENT_RELATIVE) {
|
||||
// Make visibleRegion and aRenderingContext relative to the
|
||||
// scrolled frame instead of the root frame.
|
||||
nsPoint pos = rootScrollableFrame->GetScrollPosition();
|
||||
visibleRegion.MoveBy(-pos);
|
||||
if (aRenderingContext) {
|
||||
aRenderingContext->Translate(pos);
|
||||
}
|
||||
builder.SetIgnoreScrollFrame(rootScrollFrame);
|
||||
}
|
||||
builder.SetIgnoreScrollFrame(rootScrollFrame);
|
||||
|
||||
nsCanvasFrame* canvasFrame =
|
||||
do_QueryFrame(rootScrollableFrame->GetScrolledFrame());
|
||||
if (canvasFrame) {
|
||||
// Use UnionRect here to ensure that areas where the scrollbars
|
||||
// were are still filled with the background color.
|
||||
canvasArea.UnionRect(canvasArea,
|
||||
canvasFrame->CanvasArea() + builder.ToReferenceFrame(canvasFrame));
|
||||
}
|
||||
nsCanvasFrame* canvasFrame =
|
||||
do_QueryFrame(rootScrollableFrame->GetScrolledFrame());
|
||||
if (canvasFrame) {
|
||||
// Use UnionRect here to ensure that areas where the scrollbars
|
||||
// were are still filled with the background color.
|
||||
canvasArea.UnionRect(canvasArea,
|
||||
canvasFrame->CanvasArea() + builder.ToReferenceFrame(canvasFrame));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ this.OnRefTestLoad = function OnRefTestLoad(win)
|
||||
|
||||
#if BOOTSTRAP
|
||||
#if REFTEST_B2G
|
||||
var doc = gContainingWindow.document.getElementsByTagName("window")[0];
|
||||
var doc = gContainingWindow.document.getElementsByTagName("html")[0];
|
||||
#else
|
||||
var doc = gContainingWindow.document.getElementById('main-window');
|
||||
#endif
|
||||
|
@ -23,6 +23,8 @@ namespace {
|
||||
struct NetworkInterface {
|
||||
struct sockaddr_in addr;
|
||||
std::string name;
|
||||
// See NR_INTERFACE_TYPE_* in nICEr/src/net/local_addrs.h
|
||||
int type;
|
||||
};
|
||||
|
||||
nsresult
|
||||
@ -74,6 +76,19 @@ GetInterfaces(std::vector<NetworkInterface>* aInterfaces)
|
||||
}
|
||||
interface.name = NS_ConvertUTF16toUTF8(ifaceName).get();
|
||||
|
||||
int32_t type;
|
||||
if (NS_FAILED(iface->GetType(&type))) {
|
||||
continue;
|
||||
}
|
||||
switch (type) {
|
||||
case nsINetworkInterface::NETWORK_TYPE_WIFI:
|
||||
interface.type = NR_INTERFACE_TYPE_WIFI;
|
||||
break;
|
||||
case nsINetworkInterface::NETWORK_TYPE_MOBILE:
|
||||
interface.type = NR_INTERFACE_TYPE_MOBILE;
|
||||
break;
|
||||
}
|
||||
|
||||
aInterfaces->push_back(interface);
|
||||
}
|
||||
return NS_OK;
|
||||
@ -81,7 +96,7 @@ GetInterfaces(std::vector<NetworkInterface>* aInterfaces)
|
||||
} // anonymous namespace
|
||||
|
||||
int
|
||||
nr_stun_get_addrs(nr_transport_addr aAddrs[], int aMaxAddrs,
|
||||
nr_stun_get_addrs(nr_local_addr aAddrs[], int aMaxAddrs,
|
||||
int aDropLoopback, int* aCount)
|
||||
{
|
||||
nsresult rv;
|
||||
@ -106,11 +121,14 @@ nr_stun_get_addrs(nr_transport_addr aAddrs[], int aMaxAddrs,
|
||||
NetworkInterface &interface = interfaces[i];
|
||||
if (nr_sockaddr_to_transport_addr((sockaddr*)&(interface.addr),
|
||||
sizeof(struct sockaddr_in),
|
||||
IPPROTO_UDP, 0, &(aAddrs[n]))) {
|
||||
IPPROTO_UDP, 0, &(aAddrs[n].addr))) {
|
||||
r_log(NR_LOG_STUN, LOG_WARNING, "Problem transforming address");
|
||||
return R_FAILED;
|
||||
}
|
||||
strlcpy(aAddrs[n].ifname, interface.name.c_str(), sizeof(aAddrs[n].ifname));
|
||||
strlcpy(aAddrs[n].addr.ifname, interface.name.c_str(),
|
||||
sizeof(aAddrs[n].addr.ifname));
|
||||
aAddrs[n].interface.type = interface.type;
|
||||
aAddrs[n].interface.estimated_speed = 0;
|
||||
n++;
|
||||
}
|
||||
|
||||
@ -121,8 +139,10 @@ nr_stun_get_addrs(nr_transport_addr aAddrs[], int aMaxAddrs,
|
||||
}
|
||||
|
||||
for (int i = 0; i < *aCount; ++i) {
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Address %d: %s on %s", i,
|
||||
aAddrs[i].as_string, aAddrs[i].ifname);
|
||||
char typestr[100];
|
||||
nr_local_addr_fmt_info_string(aAddrs + i, typestr, sizeof(typestr));
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Address %d: %s on %s, type: %s\n",
|
||||
i, aAddrs[i].addr.as_string, aAddrs[i].addr.ifname, typestr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -82,6 +82,7 @@ extern "C" {
|
||||
#include "nricectx.h"
|
||||
#include "nricemediastream.h"
|
||||
#include "nr_socket_prsock.h"
|
||||
#include "nrinterfaceprioritizer.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -368,6 +369,20 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef USE_INTERFACE_PRIORITIZER
|
||||
nr_interface_prioritizer *prioritizer = CreateInterfacePrioritizer();
|
||||
if (!prioritizer) {
|
||||
MOZ_MTLOG(PR_LOG_ERROR, "Couldn't create interface prioritizer.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
r = nr_ice_ctx_set_interface_prioritizer(ctx->ctx_, prioritizer);
|
||||
if (r) {
|
||||
MOZ_MTLOG(PR_LOG_ERROR, "Couldn't set interface prioritizer.");
|
||||
return nullptr;
|
||||
}
|
||||
#endif // USE_INTERFACE_PRIORITIZER
|
||||
|
||||
// Create the handler objects
|
||||
ctx->ice_handler_vtbl_ = new nr_ice_handler_vtbl();
|
||||
ctx->ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair;
|
||||
|
189
media/mtransport/nrinterfaceprioritizer.cpp
Normal file
189
media/mtransport/nrinterfaceprioritizer.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "logging.h"
|
||||
#include "nrinterfaceprioritizer.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
MOZ_MTLOG_MODULE("mtransport")
|
||||
|
||||
namespace {
|
||||
|
||||
class LocalAddress {
|
||||
public:
|
||||
LocalAddress()
|
||||
: key_(),
|
||||
is_vpn_(-1),
|
||||
estimated_speed_(-1),
|
||||
type_preference_(-1) {}
|
||||
|
||||
bool Init(const nr_local_addr& local_addr) {
|
||||
char buf[MAXIFNAME + 41];
|
||||
int r = nr_transport_addr_fmt_ifname_addr_string(&local_addr.addr, buf, sizeof(buf));
|
||||
if (r) {
|
||||
MOZ_MTLOG(PR_LOG_ERROR, "Error formatting interface address string.");
|
||||
return false;
|
||||
}
|
||||
key_ = buf;
|
||||
is_vpn_ = (local_addr.interface.type & NR_INTERFACE_TYPE_VPN) != 0 ? 1 : 0;
|
||||
estimated_speed_ = local_addr.interface.estimated_speed;
|
||||
type_preference_ = GetNetworkTypePreference(local_addr.interface.type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator<(const LocalAddress& rhs) const {
|
||||
// Interface that is "less" here is preferred.
|
||||
// If type preferences are different, we should simply sort by
|
||||
// |type_preference_|.
|
||||
if (type_preference_ != rhs.type_preference_) {
|
||||
return type_preference_ < rhs.type_preference_;
|
||||
}
|
||||
|
||||
// If type preferences are the same, the next thing we use to sort is vpn.
|
||||
// If two LocalAddress are different in |is_vpn_|, the LocalAddress that is
|
||||
// not in vpn gets priority.
|
||||
if (is_vpn_ != rhs.is_vpn_) {
|
||||
return is_vpn_ < rhs.is_vpn_;
|
||||
}
|
||||
|
||||
// Compare estimated speed.
|
||||
if (estimated_speed_ != rhs.estimated_speed_) {
|
||||
return estimated_speed_ > rhs.estimated_speed_;
|
||||
}
|
||||
|
||||
// All things above are the same, we can at least sort with key.
|
||||
return key_ < rhs.key_;
|
||||
}
|
||||
|
||||
const std::string& GetKey() const {
|
||||
return key_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Getting the preference corresponding to a type. Getting lower number here
|
||||
// means the type of network is preferred.
|
||||
static inline int GetNetworkTypePreference(int type) {
|
||||
if (type & NR_INTERFACE_TYPE_WIRED) {
|
||||
return 1;
|
||||
}
|
||||
if (type & NR_INTERFACE_TYPE_WIFI) {
|
||||
return 2;
|
||||
}
|
||||
if (type & NR_INTERFACE_TYPE_MOBILE) {
|
||||
return 3;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
std::string key_;
|
||||
int is_vpn_;
|
||||
int estimated_speed_;
|
||||
int type_preference_;
|
||||
};
|
||||
|
||||
class InterfacePrioritizer {
|
||||
public:
|
||||
InterfacePrioritizer()
|
||||
: local_addrs_(),
|
||||
preference_map_(),
|
||||
sorted_(false) {}
|
||||
|
||||
int add(const nr_local_addr *iface) {
|
||||
LocalAddress addr;
|
||||
if (!addr.Init(*iface)) {
|
||||
return R_FAILED;
|
||||
}
|
||||
std::pair<std::set<LocalAddress>::iterator, bool> r =
|
||||
local_addrs_.insert(addr);
|
||||
if (!r.second) {
|
||||
return R_ALREADY; // This address is already in the set.
|
||||
}
|
||||
sorted_ = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sort() {
|
||||
UCHAR tmp_pref = 127;
|
||||
preference_map_.clear();
|
||||
for (std::set<LocalAddress>::iterator i = local_addrs_.begin();
|
||||
i != local_addrs_.end(); ++i) {
|
||||
if (tmp_pref == 0) {
|
||||
return R_FAILED;
|
||||
}
|
||||
preference_map_.insert(make_pair(i->GetKey(), tmp_pref--));
|
||||
}
|
||||
sorted_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getPreference(const char *key, UCHAR *pref) {
|
||||
if (!sorted_) {
|
||||
return R_FAILED;
|
||||
}
|
||||
std::map<std::string, UCHAR>::iterator i = preference_map_.find(key);
|
||||
if (i == preference_map_.end()) {
|
||||
return R_NOT_FOUND;
|
||||
}
|
||||
*pref = i->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<LocalAddress> local_addrs_;
|
||||
std::map<std::string, UCHAR> preference_map_;
|
||||
bool sorted_;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
static int add_interface(void *obj, nr_local_addr *iface) {
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(obj);
|
||||
return ip->add(iface);
|
||||
}
|
||||
|
||||
static int get_priority(void *obj, const char *key, UCHAR *pref) {
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(obj);
|
||||
return ip->getPreference(key, pref);
|
||||
}
|
||||
|
||||
static int sort_preference(void *obj) {
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(obj);
|
||||
return ip->sort();
|
||||
}
|
||||
|
||||
static int destroy(void **objp) {
|
||||
if (!objp || !*objp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(*objp);
|
||||
*objp = 0;
|
||||
delete ip;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nr_interface_prioritizer_vtbl priorizer_vtbl = {
|
||||
add_interface,
|
||||
get_priority,
|
||||
sort_preference,
|
||||
destroy
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
nr_interface_prioritizer* CreateInterfacePrioritizer() {
|
||||
nr_interface_prioritizer *ip;
|
||||
int r = nr_interface_prioritizer_create_int(new InterfacePrioritizer(),
|
||||
&priorizer_vtbl,
|
||||
&ip);
|
||||
if (r != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
18
media/mtransport/nrinterfaceprioritizer.h
Normal file
18
media/mtransport/nrinterfaceprioritizer.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef nrinterfacepriority_h__
|
||||
#define nrinterfacepriority_h__
|
||||
|
||||
extern "C" {
|
||||
#include "nr_api.h"
|
||||
#include "nr_interface_prioritizer.h"
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
nr_interface_prioritizer* CreateInterfacePrioritizer();
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -40,7 +40,7 @@ LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/media/mtransport/third_party/nrappkit/src/port/linux/include \
|
||||
-I$(topsrcdir)/media/mtransport/third_party/nrappkit/src/port/generic/include \
|
||||
$(NULL)
|
||||
DEFINES += -DLINUX
|
||||
DEFINES += -DLINUX -DUSE_INTERFACE_PRIORITIZER
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET), Android)
|
||||
@ -71,6 +71,7 @@ MTRANSPORT_LCPPSRCS = \
|
||||
nricemediastream.cpp \
|
||||
nriceresolverfake.cpp \
|
||||
nriceresolver.cpp \
|
||||
nrinterfaceprioritizer.cpp \
|
||||
nr_socket_prsock.cpp \
|
||||
nr_timer.cpp \
|
||||
transportflow.cpp \
|
||||
@ -86,6 +87,7 @@ ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
|
||||
MTRANSPORT_LCPPSRCS += \
|
||||
gonk_addrs.cpp \
|
||||
$(NULL)
|
||||
DEFINES += -DUSE_INTERFACE_PRIORITIZER
|
||||
endif
|
||||
|
||||
MTRANSPORT_CPPSRCS = $(addprefix $(topsrcdir)/media/mtransport/, $(MTRANSPORT_LCPPSRCS))
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nricemediastream.h"
|
||||
#include "nriceresolverfake.h"
|
||||
#include "nriceresolver.h"
|
||||
#include "nrinterfaceprioritizer.h"
|
||||
#include "mtransport_test_utils.h"
|
||||
#include "runnable_utils.h"
|
||||
|
||||
@ -485,6 +486,54 @@ class IceConnectTest : public ::testing::Test {
|
||||
mozilla::ScopedDeletePtr<IceTestPeer> p2_;
|
||||
};
|
||||
|
||||
class PrioritizerTest : public ::testing::Test {
|
||||
public:
|
||||
PrioritizerTest():
|
||||
prioritizer_(nullptr) {}
|
||||
|
||||
~PrioritizerTest() {
|
||||
if (prioritizer_) {
|
||||
nr_interface_prioritizer_destroy(&prioritizer_);
|
||||
}
|
||||
}
|
||||
|
||||
void SetPriorizer(nr_interface_prioritizer *prioritizer) {
|
||||
prioritizer_ = prioritizer;
|
||||
}
|
||||
|
||||
void AddInterface(const std::string& num, int type, int estimated_speed) {
|
||||
std::string str_addr = "10.0.0." + num;
|
||||
std::string ifname = "eth" + num;
|
||||
nr_local_addr local_addr;
|
||||
local_addr.interface.type = type;
|
||||
local_addr.interface.estimated_speed = estimated_speed;
|
||||
|
||||
int r = nr_ip4_str_port_to_transport_addr(str_addr.c_str(), 0,
|
||||
IPPROTO_UDP, &(local_addr.addr));
|
||||
ASSERT_EQ(0, r);
|
||||
strncpy(local_addr.addr.ifname, ifname.c_str(), MAXIFNAME);
|
||||
|
||||
r = nr_interface_prioritizer_add_interface(prioritizer_, &local_addr);
|
||||
ASSERT_EQ(0, r);
|
||||
r = nr_interface_prioritizer_sort_preference(prioritizer_);
|
||||
ASSERT_EQ(0, r);
|
||||
}
|
||||
|
||||
void HasLowerPreference(const std::string& num1, const std::string& num2) {
|
||||
std::string key1 = "eth" + num1 + ":10.0.0." + num1;
|
||||
std::string key2 = "eth" + num2 + ":10.0.0." + num2;
|
||||
UCHAR pref1, pref2;
|
||||
int r = nr_interface_prioritizer_get_priority(prioritizer_, key1.c_str(), &pref1);
|
||||
ASSERT_EQ(0, r);
|
||||
r = nr_interface_prioritizer_get_priority(prioritizer_, key2.c_str(), &pref2);
|
||||
ASSERT_EQ(0, r);
|
||||
ASSERT_LE(pref1, pref2);
|
||||
}
|
||||
|
||||
private:
|
||||
nr_interface_prioritizer *prioritizer_;
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherFakeStunServerHostnameNoResolver) {
|
||||
@ -673,6 +722,37 @@ TEST_F(IceConnectTest, TestConnectShutdownOneSide) {
|
||||
ConnectThenDelete();
|
||||
}
|
||||
|
||||
TEST_F(PrioritizerTest, TestPrioritizer) {
|
||||
SetPriorizer(::mozilla::CreateInterfacePrioritizer());
|
||||
|
||||
AddInterface("0", NR_INTERFACE_TYPE_VPN, 100); // unknown vpn
|
||||
AddInterface("1", NR_INTERFACE_TYPE_VPN | NR_INTERFACE_TYPE_WIRED, 100); // wired vpn
|
||||
AddInterface("2", NR_INTERFACE_TYPE_VPN | NR_INTERFACE_TYPE_WIFI, 100); // wifi vpn
|
||||
AddInterface("3", NR_INTERFACE_TYPE_VPN | NR_INTERFACE_TYPE_MOBILE, 100); // wifi vpn
|
||||
AddInterface("4", NR_INTERFACE_TYPE_WIRED, 1000); // wired, high speed
|
||||
AddInterface("5", NR_INTERFACE_TYPE_WIRED, 10); // wired, low speed
|
||||
AddInterface("6", NR_INTERFACE_TYPE_WIFI, 10); // wifi, low speed
|
||||
AddInterface("7", NR_INTERFACE_TYPE_WIFI, 1000); // wifi, high speed
|
||||
AddInterface("8", NR_INTERFACE_TYPE_MOBILE, 10); // mobile, low speed
|
||||
AddInterface("9", NR_INTERFACE_TYPE_MOBILE, 1000); // mobile, high speed
|
||||
AddInterface("10", NR_INTERFACE_TYPE_UNKNOWN, 10); // unknown, low speed
|
||||
AddInterface("11", NR_INTERFACE_TYPE_UNKNOWN, 1000); // unknown, high speed
|
||||
|
||||
// expected preference "4" > "5" > "1" > "7" > "6" > "2" > "9" > "8" > "3" > "11" > "10" > "0"
|
||||
|
||||
HasLowerPreference("0", "10");
|
||||
HasLowerPreference("10", "11");
|
||||
HasLowerPreference("11", "3");
|
||||
HasLowerPreference("3", "8");
|
||||
HasLowerPreference("8", "9");
|
||||
HasLowerPreference("9", "2");
|
||||
HasLowerPreference("2", "6");
|
||||
HasLowerPreference("6", "7");
|
||||
HasLowerPreference("7", "1");
|
||||
HasLowerPreference("1", "5");
|
||||
HasLowerPreference("5", "4");
|
||||
}
|
||||
|
||||
static std::string get_environment(const char *name) {
|
||||
char *value = getenv(name);
|
||||
|
||||
|
4
media/mtransport/third_party/nICEr/nicer.gyp
vendored
4
media/mtransport/third_party/nICEr/nicer.gyp
vendored
@ -76,6 +76,10 @@
|
||||
"./src/net/transport_addr.h",
|
||||
"./src/net/transport_addr_reg.c",
|
||||
"./src/net/transport_addr_reg.h",
|
||||
"./src/net/local_addr.c",
|
||||
"./src/net/local_addr.h",
|
||||
"./src/net/nr_interface_prioritizer.c",
|
||||
"./src/net/nr_interface_prioritizer.h",
|
||||
|
||||
# STUN
|
||||
"./src/stun/addrs.c",
|
||||
|
@ -358,23 +358,37 @@ int nr_ice_candidate_compute_priority(nr_ice_candidate *cand)
|
||||
if(type_preference > 126)
|
||||
r_log(LOG_ICE,LOG_ERR,"Illegal type preference %d",type_preference);
|
||||
|
||||
|
||||
if(r=NR_reg_get2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,
|
||||
&interface_preference)) {
|
||||
if (r==R_NOT_FOUND) {
|
||||
if (next_automatic_preference == 1) {
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Out of preference values. Can't assign one for interface %s",cand->base.ifname);
|
||||
ABORT(R_NOT_FOUND);
|
||||
if(!cand->ctx->interface_prioritizer) {
|
||||
/* Prioritizer is not set, read from registry */
|
||||
if(r=NR_reg_get2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,
|
||||
&interface_preference)) {
|
||||
if (r==R_NOT_FOUND) {
|
||||
if (next_automatic_preference == 1) {
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Out of preference values. Can't assign one for interface %s",cand->base.ifname);
|
||||
ABORT(R_NOT_FOUND);
|
||||
}
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Automatically assigning preference for interface %s->%d",cand->base.ifname,
|
||||
next_automatic_preference);
|
||||
if (r=NR_reg_set2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,next_automatic_preference)){
|
||||
ABORT(r);
|
||||
}
|
||||
interface_preference=next_automatic_preference;
|
||||
next_automatic_preference--;
|
||||
}
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Automatically assigning preference for interface %s->%d",cand->base.ifname,
|
||||
next_automatic_preference);
|
||||
if (r=NR_reg_set2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,next_automatic_preference)){
|
||||
else {
|
||||
ABORT(r);
|
||||
}
|
||||
interface_preference=next_automatic_preference;
|
||||
next_automatic_preference--;
|
||||
}
|
||||
else {
|
||||
}
|
||||
else {
|
||||
char key_of_interface[MAXIFNAME + 41];
|
||||
|
||||
if(r=nr_transport_addr_fmt_ifname_addr_string(&cand->base,key_of_interface,
|
||||
sizeof(key_of_interface))) {
|
||||
ABORT(r);
|
||||
}
|
||||
if(r=nr_interface_prioritizer_get_priority(cand->ctx->interface_prioritizer,
|
||||
key_of_interface,&interface_preference)) {
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
@ -170,31 +170,24 @@ int nr_ice_component_destroy(nr_ice_component **componentp)
|
||||
return(0);
|
||||
}
|
||||
|
||||
#define MAXADDRS 100 // Ridiculously high
|
||||
/* Make all the candidates we can make at the beginning */
|
||||
int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *component)
|
||||
{
|
||||
int r,_status;
|
||||
nr_transport_addr addrs[MAXADDRS];
|
||||
nr_local_addr *addrs=ctx->local_addrs;
|
||||
nr_socket *sock;
|
||||
nr_ice_socket *isock=0;
|
||||
nr_ice_candidate *cand=0;
|
||||
char *lufrag;
|
||||
char *lpwd;
|
||||
Data pwd;
|
||||
int addr_ct;
|
||||
int addr_ct=ctx->local_addr_ct;
|
||||
int i;
|
||||
int j;
|
||||
char label[256];
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): initializing component with id %d",ctx->label,component->component_id);
|
||||
|
||||
/* First, gather all the local addresses we have */
|
||||
if(r=nr_stun_find_local_addresses(addrs,MAXADDRS,&addr_ct)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to find local addresses",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
if(addr_ct==0){
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): no local addresses available",ctx->label);
|
||||
ABORT(R_NOT_FOUND);
|
||||
@ -204,7 +197,7 @@ int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *compon
|
||||
for(i=0;i<addr_ct;i++){
|
||||
char suppress;
|
||||
|
||||
if(r=NR_reg_get2_char(NR_ICE_REG_SUPPRESS_INTERFACE_PRFX,addrs[i].ifname,&suppress)){
|
||||
if(r=NR_reg_get2_char(NR_ICE_REG_SUPPRESS_INTERFACE_PRFX,addrs[i].addr.ifname,&suppress)){
|
||||
if(r!=R_NOT_FOUND)
|
||||
ABORT(r);
|
||||
}
|
||||
@ -214,9 +207,9 @@ int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *compon
|
||||
}
|
||||
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): host address %s",ctx->label,addrs[i].as_string);
|
||||
if(r=nr_socket_local_create(&addrs[i],&sock)){
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): couldn't create socket for address %s",ctx->label,addrs[i].as_string);
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): host address %s",ctx->label,addrs[i].addr.as_string);
|
||||
if(r=nr_socket_local_create(&addrs[i].addr,&sock)){
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): couldn't create socket for address %s",ctx->label,addrs[i].addr.as_string);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -279,7 +272,7 @@ int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *compon
|
||||
#endif /* USE_TURN */
|
||||
|
||||
/* Create a STUN server context for this socket */
|
||||
snprintf(label, sizeof(label), "server(%s)", addrs[i].as_string);
|
||||
snprintf(label, sizeof(label), "server(%s)", addrs[i].addr.as_string);
|
||||
if(r=nr_stun_server_ctx_create(label,sock,&isock->stun_server))
|
||||
ABORT(r);
|
||||
if(r=nr_ice_socket_register_stun_server(isock,isock->stun_server,&isock->stun_server_handle))
|
||||
|
@ -156,6 +156,33 @@ int nr_ice_ctx_set_turn_servers(nr_ice_ctx *ctx,nr_ice_turn_server *servers,int
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_set_local_addrs(nr_ice_ctx *ctx,nr_local_addr *addrs,int ct)
|
||||
{
|
||||
int _status,i,r;
|
||||
|
||||
if(ctx->local_addrs) {
|
||||
RFREE(ctx->local_addrs);
|
||||
ctx->local_addr_ct=0;
|
||||
ctx->local_addrs=0;
|
||||
}
|
||||
|
||||
if (ct) {
|
||||
if(!(ctx->local_addrs=RCALLOC(sizeof(nr_local_addr)*ct)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
for (i=0;i<ct;++i) {
|
||||
if (r=nr_local_addr_copy(ctx->local_addrs+i,addrs+i)) {
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
ctx->local_addr_ct = ct;
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver)
|
||||
{
|
||||
int _status;
|
||||
@ -171,6 +198,20 @@ int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver)
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritizer *ip)
|
||||
{
|
||||
int _status;
|
||||
|
||||
if (ctx->interface_prioritizer) {
|
||||
ABORT(R_ALREADY);
|
||||
}
|
||||
|
||||
ctx->interface_prioritizer = ip;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
#ifdef USE_TURN
|
||||
int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out)
|
||||
@ -301,6 +342,9 @@ int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp)
|
||||
ctx->turn_server_ct=0;
|
||||
#endif /* USE_TURN */
|
||||
|
||||
ctx->local_addrs=0;
|
||||
ctx->local_addr_ct=0;
|
||||
|
||||
/* 255 is the max for our priority algorithm */
|
||||
if((ctx->stun_server_ct+ctx->turn_server_ct)>255){
|
||||
r_log(LOG_ICE,LOG_WARNING,"Too many STUN/TURN servers specified: max=255");
|
||||
@ -348,6 +392,8 @@ static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
|
||||
|
||||
RFREE(ctx->stun_servers);
|
||||
|
||||
RFREE(ctx->local_addrs);
|
||||
|
||||
for (i = 0; i < ctx->turn_server_ct; i++) {
|
||||
RFREE(ctx->turn_servers[i].username);
|
||||
r_data_destroy(&ctx->turn_servers[i].password);
|
||||
@ -374,6 +420,7 @@ static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
|
||||
}
|
||||
|
||||
nr_resolver_destroy(&ctx->resolver);
|
||||
nr_interface_prioritizer_destroy(&ctx->interface_prioritizer);
|
||||
|
||||
RFREE(ctx);
|
||||
}
|
||||
@ -416,10 +463,13 @@ void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg)
|
||||
}
|
||||
}
|
||||
|
||||
#define MAXADDRS 100 // Ridiculously high
|
||||
int nr_ice_initialize(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg)
|
||||
{
|
||||
int r,_status;
|
||||
nr_ice_media_stream *stream;
|
||||
nr_local_addr addrs[MAXADDRS];
|
||||
int i,addr_ct;
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Initializing candidates",ctx->label);
|
||||
ctx->state=NR_ICE_STATE_INITIALIZING;
|
||||
@ -431,6 +481,30 @@ int nr_ice_initialize(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg)
|
||||
ABORT(R_BAD_ARGS);
|
||||
}
|
||||
|
||||
/* First, gather all the local addresses we have */
|
||||
if(r=nr_stun_find_local_addresses(addrs,MAXADDRS,&addr_ct)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to find local addresses",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
/* Sort interfaces by preference */
|
||||
if(ctx->interface_prioritizer) {
|
||||
for(i=0;i<addr_ct;i++){
|
||||
if(r=nr_interface_prioritizer_add_interface(ctx->interface_prioritizer,addrs+i)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to add interface ",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
if(r=nr_interface_prioritizer_sort_preference(ctx->interface_prioritizer)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to sort interface by preference",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
||||
if (r=nr_ice_ctx_set_local_addrs(ctx,addrs,addr_ct)) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
/* Initialize all the media stream/component pairs */
|
||||
stream=STAILQ_FIRST(&ctx->streams);
|
||||
while(stream){
|
||||
|
@ -43,6 +43,7 @@ extern "C" {
|
||||
#include "transport_addr.h"
|
||||
#include "nr_socket.h"
|
||||
#include "nr_resolver.h"
|
||||
#include "nr_interface_prioritizer.h"
|
||||
#include "stun_client_ctx.h"
|
||||
#include "stun_server_ctx.h"
|
||||
#include "turn_client_ctx.h"
|
||||
@ -122,8 +123,11 @@ struct nr_ice_ctx_ {
|
||||
int stun_server_ct;
|
||||
nr_ice_turn_server *turn_servers; /* The list of turn servers */
|
||||
int turn_server_ct;
|
||||
nr_local_addr *local_addrs; /* The list of available local addresses and corresponding interface information */
|
||||
int local_addr_ct;
|
||||
|
||||
nr_resolver *resolver; /* The resolver to use */
|
||||
nr_interface_prioritizer *interface_prioritizer; /* Priority decision logic */
|
||||
|
||||
nr_ice_foundation_head foundations;
|
||||
|
||||
@ -161,6 +165,7 @@ int nr_ice_ctx_finalize(nr_ice_ctx *ctx, nr_ice_peer_ctx *pctx);
|
||||
int nr_ice_ctx_set_stun_servers(nr_ice_ctx *ctx,nr_ice_stun_server *servers, int ct);
|
||||
int nr_ice_ctx_set_turn_servers(nr_ice_ctx *ctx,nr_ice_turn_server *servers, int ct);
|
||||
int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver);
|
||||
int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritizer *prioritizer);
|
||||
|
||||
extern int LOG_ICE;
|
||||
|
||||
|
60
media/mtransport/third_party/nICEr/src/net/local_addr.c
vendored
Normal file
60
media/mtransport/third_party/nICEr/src/net/local_addr.c
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <nr_api.h>
|
||||
#include <string.h>
|
||||
#include "local_addr.h"
|
||||
|
||||
int nr_local_addr_copy(nr_local_addr *to, nr_local_addr *from)
|
||||
{
|
||||
nr_transport_addr_copy(&(to->addr), &(from->addr));
|
||||
to->interface = from->interface;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_local_addr_fmt_info_string(nr_local_addr *addr, char *buf, int len)
|
||||
{
|
||||
int addr_type = addr->interface.type;
|
||||
const char *vpn = (addr_type & NR_INTERFACE_TYPE_VPN) ? "VPN on " : "";
|
||||
|
||||
const char *type = (addr_type & NR_INTERFACE_TYPE_WIRED) ? "wired" :
|
||||
(addr_type & NR_INTERFACE_TYPE_WIFI) ? "wifi" :
|
||||
(addr_type & NR_INTERFACE_TYPE_MOBILE) ? "mobile" :
|
||||
"unknown";
|
||||
|
||||
snprintf(buf, len, "%s%s, estimated speed: %d kbps",
|
||||
vpn, type, addr->interface.estimated_speed);
|
||||
return (0);
|
||||
}
|
59
media/mtransport/third_party/nICEr/src/net/local_addr.h
vendored
Normal file
59
media/mtransport/third_party/nICEr/src/net/local_addr.h
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _local_addr_h
|
||||
#define _local_addr_h
|
||||
|
||||
#include "transport_addr.h"
|
||||
|
||||
typedef struct nr_interface_ {
|
||||
int type;
|
||||
#define NR_INTERFACE_TYPE_UNKNOWN 0x0
|
||||
#define NR_INTERFACE_TYPE_WIRED 0x1
|
||||
#define NR_INTERFACE_TYPE_WIFI 0x2
|
||||
#define NR_INTERFACE_TYPE_MOBILE 0x4
|
||||
#define NR_INTERFACE_TYPE_VPN 0x8
|
||||
int estimated_speed; /* Speed in kbps */
|
||||
} nr_interface;
|
||||
|
||||
typedef struct nr_local_addr_ {
|
||||
nr_transport_addr addr;
|
||||
nr_interface interface;
|
||||
} nr_local_addr;
|
||||
|
||||
int nr_local_addr_copy(nr_local_addr *to, nr_local_addr *from);
|
||||
int nr_local_addr_fmt_info_string(nr_local_addr *addr, char *buf, int len);
|
||||
|
||||
#endif
|
88
media/mtransport/third_party/nICEr/src/net/nr_interface_prioritizer.c
vendored
Normal file
88
media/mtransport/third_party/nICEr/src/net/nr_interface_prioritizer.c
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "nr_api.h"
|
||||
#include "nr_interface_prioritizer.h"
|
||||
#include "transport_addr.h"
|
||||
|
||||
int nr_interface_prioritizer_create_int(void *obj,
|
||||
nr_interface_prioritizer_vtbl *vtbl,nr_interface_prioritizer **ifpp)
|
||||
{
|
||||
int _status;
|
||||
nr_interface_prioritizer *ifp=0;
|
||||
|
||||
if(!(ifp=RCALLOC(sizeof(nr_interface_prioritizer))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
ifp->obj = obj;
|
||||
ifp->vtbl = vtbl;
|
||||
|
||||
*ifpp = ifp;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_destroy(nr_interface_prioritizer **ifpp)
|
||||
{
|
||||
nr_interface_prioritizer *ifp;
|
||||
|
||||
if (!ifpp || !*ifpp)
|
||||
return(0);
|
||||
|
||||
ifp = *ifpp;
|
||||
*ifpp = 0;
|
||||
ifp->vtbl->destroy(&ifp->obj);
|
||||
RFREE(ifp);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_add_interface(nr_interface_prioritizer *ifp,
|
||||
nr_local_addr *addr)
|
||||
{
|
||||
return ifp->vtbl->add_interface(ifp->obj, addr);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_get_priority(nr_interface_prioritizer *ifp,
|
||||
const char *key, UCHAR *interface_preference)
|
||||
{
|
||||
return ifp->vtbl->get_priority(ifp->obj,key,interface_preference);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_sort_preference(nr_interface_prioritizer *ifp)
|
||||
{
|
||||
return ifp->vtbl->sort_preference(ifp->obj);
|
||||
}
|
66
media/mtransport/third_party/nICEr/src/net/nr_interface_prioritizer.h
vendored
Normal file
66
media/mtransport/third_party/nICEr/src/net/nr_interface_prioritizer.h
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _nr_interface_prioritizer
|
||||
#define _nr_interface_prioritizer
|
||||
|
||||
#include "transport_addr.h"
|
||||
#include "local_addr.h"
|
||||
|
||||
typedef struct nr_interface_prioritizer_vtbl_ {
|
||||
int (*add_interface)(void *obj, nr_local_addr *iface);
|
||||
int (*get_priority)(void *obj, const char *key, UCHAR *pref);
|
||||
int (*sort_preference)(void *obj);
|
||||
int (*destroy)(void **obj);
|
||||
} nr_interface_prioritizer_vtbl;
|
||||
|
||||
typedef struct nr_interface_prioritizer_ {
|
||||
void *obj;
|
||||
nr_interface_prioritizer_vtbl *vtbl;
|
||||
} nr_interface_prioritizer;
|
||||
|
||||
int nr_interface_prioritizer_create_int(void *obj, nr_interface_prioritizer_vtbl *vtbl,
|
||||
nr_interface_prioritizer **prioritizer);
|
||||
|
||||
int nr_interface_prioritizer_destroy(nr_interface_prioritizer **prioritizer);
|
||||
|
||||
int nr_interface_prioritizer_add_interface(nr_interface_prioritizer *prioritizer,
|
||||
nr_local_addr *addr);
|
||||
|
||||
int nr_interface_prioritizer_get_priority(nr_interface_prioritizer *prioritizer,
|
||||
const char *key, UCHAR *interface_preference);
|
||||
|
||||
int nr_interface_prioritizer_sort_preference(nr_interface_prioritizer *prioritizer);
|
||||
#endif
|
@ -37,6 +37,7 @@ static char *RCSSTRING __UNUSED__="$Id: nr_socket.c,v 1.2 2008/04/28 17:59:02 ek
|
||||
#include <assert.h>
|
||||
#include <nr_api.h>
|
||||
#include "nr_socket.h"
|
||||
#include "local_addr.h"
|
||||
|
||||
int nr_socket_create_int(void *obj, nr_socket_vtbl *vtbl, nr_socket **sockp)
|
||||
{
|
||||
|
@ -78,6 +78,27 @@ int nr_transport_addr_fmt_addr_string(nr_transport_addr *addr)
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_transport_addr_fmt_ifname_addr_string(const nr_transport_addr *addr, char *buf, int len)
|
||||
{
|
||||
int _status;
|
||||
char buffer[40];
|
||||
|
||||
switch(addr->ip_version){
|
||||
case NR_IPV4:
|
||||
if (!inet_ntop(AF_INET, &addr->u.addr4.sin_addr,buffer,sizeof(buffer))) {
|
||||
strncpy(buffer, "[error]", len);
|
||||
}
|
||||
snprintf(buf,len,"%s:%s",addr->ifname,buffer);
|
||||
break;
|
||||
default:
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_sockaddr_to_transport_addr(struct sockaddr *saddr, int saddr_len, int protocol, int keep, nr_transport_addr *addr)
|
||||
{
|
||||
int r,_status;
|
||||
|
@ -91,6 +91,7 @@ int nr_transport_addr_is_loopback(nr_transport_addr *addr);
|
||||
int nr_transport_addr_copy(nr_transport_addr *to, nr_transport_addr *from);
|
||||
int nr_transport_addr_copy_keep_ifname(nr_transport_addr *to, nr_transport_addr *from);
|
||||
int nr_transport_addr_fmt_addr_string(nr_transport_addr *addr);
|
||||
int nr_transport_addr_fmt_ifname_addr_string(const nr_transport_addr *addr, char *buf, int len);
|
||||
int nr_transport_addr_set_port(nr_transport_addr *addr, int port);
|
||||
|
||||
#endif
|
||||
|
127
media/mtransport/third_party/nICEr/src/stun/addrs.c
vendored
127
media/mtransport/third_party/nICEr/src/stun/addrs.c
vendored
@ -62,7 +62,13 @@ static char *RCSSTRING __UNUSED__="$Id: addrs.c,v 1.2 2008/04/28 18:21:30 ekr Ex
|
||||
#include <net/if_types.h>
|
||||
#include <sys/sockio.h>
|
||||
#else
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/wireless.h>
|
||||
#ifndef ANDROID
|
||||
#include <linux/ethtool.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <net/route.h>
|
||||
|
||||
@ -120,9 +126,9 @@ static char *RCSSTRING __UNUSED__="$Id: addrs.c,v 1.2 2008/04/28 18:21:30 ekr Ex
|
||||
static void stun_rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
|
||||
static int stun_grab_addrs(char *name, int addrcount,
|
||||
struct ifa_msghdr *ifam,
|
||||
nr_transport_addr addrs[], int maxaddrs, int *count);
|
||||
nr_local_addr addrs[], int maxaddrs, int *count);
|
||||
static int
|
||||
nr_stun_is_duplicate_addr(nr_transport_addr addrs[], int count, nr_transport_addr *addr);
|
||||
nr_stun_is_duplicate_addr(nr_local_addr addrs[], int count, nr_local_addr *addr);
|
||||
|
||||
|
||||
/*
|
||||
@ -151,7 +157,7 @@ stun_rt_xaddrs(cp, cplim, rtinfo)
|
||||
}
|
||||
|
||||
static int
|
||||
stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int r,_status;
|
||||
int s = -1;
|
||||
@ -172,15 +178,18 @@ stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_transport
|
||||
|
||||
/* Expand the compacted addresses */
|
||||
stun_rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, &info);
|
||||
addrs[*count].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[*count].interface.estimated_speed = 0;
|
||||
/* TODO (Bug 895790) Get interface properties for Darwin */
|
||||
|
||||
switch (info.rti_info[RTAX_IFA]->sa_family) {
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)info.rti_info[RTAX_IFA];
|
||||
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sin, sizeof(*sin), IPPROTO_UDP, 0, &(addrs[*count]))))
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sin, sizeof(*sin), IPPROTO_UDP, 0, &(addrs[*count].addr))))
|
||||
ABORT(r);
|
||||
|
||||
strlcpy(addrs[*count].ifname, name, sizeof(addrs[*count].ifname));
|
||||
strlcpy(addrs[*count].addr.ifname, name, sizeof(addrs[*count].addr.ifname));
|
||||
|
||||
++*count;
|
||||
break;
|
||||
@ -206,7 +215,7 @@ stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_transport
|
||||
}
|
||||
|
||||
static int
|
||||
stun_get_mib_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_get_mib_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int _status;
|
||||
char name[32];
|
||||
@ -353,7 +362,7 @@ abort:
|
||||
|
||||
|
||||
static int
|
||||
stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int r,_status;
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
@ -424,24 +433,30 @@ stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
|
||||
for (pAddrString = &(pAdapter->IpAddressList); pAddrString != NULL; pAddrString = pAddrString->Next) {
|
||||
unsigned long this_addr = inet_addr(pAddrString->IpAddress.String);
|
||||
nr_transport_addr *addr = &(addrs[n].addr);
|
||||
|
||||
if (this_addr == 0)
|
||||
continue;
|
||||
|
||||
r_log(NR_LOG_STUN, LOG_INFO, "Adapter %s address: %s", munged_ifname, pAddrString->IpAddress.String);
|
||||
|
||||
addrs[n].ip_version=NR_IPV4;
|
||||
addrs[n].protocol = IPPROTO_UDP;
|
||||
addr->ip_version=NR_IPV4;
|
||||
addr->protocol = IPPROTO_UDP;
|
||||
|
||||
addrs[n].u.addr4.sin_family=PF_INET;
|
||||
addrs[n].u.addr4.sin_port=0;
|
||||
addrs[n].u.addr4.sin_addr.s_addr=this_addr;
|
||||
addrs[n].addr=(struct sockaddr *)&(addrs[n].u.addr4);
|
||||
addrs[n].addr_len=sizeof(struct sockaddr_in);
|
||||
addr->u.addr4.sin_family=PF_INET;
|
||||
addr->u.addr4.sin_port=0;
|
||||
addr->u.addr4.sin_addr.s_addr=this_addr;
|
||||
addr->addr=(struct sockaddr *)&(addr->u.addr4);
|
||||
addr->addr_len=sizeof(struct sockaddr_in);
|
||||
|
||||
strlcpy(addrs[n].ifname, munged_ifname, sizeof(addrs[n].ifname));
|
||||
snprintf(addrs[n].as_string,40,"IP4:%s:%d",inet_ntoa(addrs[n].u.addr4.sin_addr),
|
||||
ntohs(addrs[n].u.addr4.sin_port));
|
||||
strlcpy(addr->ifname, munged_ifname, sizeof(addr->ifname));
|
||||
snprintf(addr->as_string,40,"IP4:%s:%d",
|
||||
inet_ntoa(addr->u.addr4.sin_addr),
|
||||
ntohs(addr->u.addr4.sin_port));
|
||||
|
||||
/* TODO: (Bug 895793) Getting interface properties for Windows */
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[n].interface.estimated_speed = 0;
|
||||
|
||||
if (++n >= maxaddrs)
|
||||
goto done;
|
||||
@ -465,7 +480,7 @@ stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
* isn't supported on Win2000.
|
||||
*/
|
||||
static int
|
||||
stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int r,_status;
|
||||
PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL, tmpAddress = NULL;
|
||||
@ -531,7 +546,7 @@ stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
|
||||
if ((sa_addr->lpSockaddr->sa_family == AF_INET) ||
|
||||
(sa_addr->lpSockaddr->sa_family == AF_INET6)) {
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sa_addr->lpSockaddr, sizeof(*sa_addr->lpSockaddr), IPPROTO_UDP, 0, &(addrs[n]))))
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sa_addr->lpSockaddr, sizeof(*sa_addr->lpSockaddr), IPPROTO_UDP, 0, &(addrs[n].addr))))
|
||||
ABORT(r);
|
||||
}
|
||||
else {
|
||||
@ -539,7 +554,10 @@ stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
continue;
|
||||
}
|
||||
|
||||
strlcpy(addrs[n].ifname, munged_ifname, sizeof(addrs[n].ifname));
|
||||
strlcpy(addrs[n].addr.ifname, munged_ifname, sizeof(addrs[n].addr.ifname));
|
||||
/* TODO: (Bug 895793) Getting interface properties for Windows */
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[n].interface.estimated_speed = 0;
|
||||
if (++n >= maxaddrs)
|
||||
goto done;
|
||||
}
|
||||
@ -559,7 +577,7 @@ stun_get_win32_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
#elif defined(__sparc__)
|
||||
|
||||
static int
|
||||
stun_get_sparc_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_get_sparc_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
*count = 0;
|
||||
UNIMPLEMENTED; /*TODO !nn! - sparc */
|
||||
@ -569,7 +587,7 @@ stun_get_sparc_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
#else
|
||||
|
||||
static int
|
||||
stun_get_siocgifconf_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
stun_get_siocgifconf_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
struct ifconf ifc;
|
||||
int _status;
|
||||
@ -598,6 +616,10 @@ stun_get_siocgifconf_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
|
||||
#ifdef LINUX
|
||||
int si = sizeof(struct ifreq);
|
||||
#ifndef ANDROID
|
||||
struct ethtool_cmd ecmd;
|
||||
struct iwreq wrq;
|
||||
#endif
|
||||
#else
|
||||
int si = sizeof(ifr->ifr_name) + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr));
|
||||
#endif
|
||||
@ -614,11 +636,46 @@ stun_get_siocgifconf_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
|
||||
//r_log(NR_LOG_STUN, LOG_ERR, "ioctl addr e = %d",e);
|
||||
|
||||
if ((r=nr_sockaddr_to_transport_addr(&ifr2.ifr_addr, sizeof(ifr2.ifr_addr), IPPROTO_UDP, 0, &(addrs[n])))) {
|
||||
if ((r=nr_sockaddr_to_transport_addr(&ifr2.ifr_addr, sizeof(ifr2.ifr_addr), IPPROTO_UDP, 0, &(addrs[n].addr)))) {
|
||||
r_log(NR_LOG_STUN, LOG_WARNING, "Problem transforming address");
|
||||
}
|
||||
else {
|
||||
strlcpy(addrs[n].ifname, ifr->ifr_name, sizeof(addrs[n].ifname));
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[n].interface.estimated_speed = 0;
|
||||
#if defined(LINUX) && !defined(ANDROID)
|
||||
/* TODO (Bug 896851): interface property for Android */
|
||||
/* Getting ethtool for ethernet information. */
|
||||
ecmd.cmd = ETHTOOL_GSET;
|
||||
ifr2.ifr_data = (void*)&ecmd;
|
||||
e = ioctl(s, SIOCETHTOOL, &ifr2);
|
||||
if (e == 0)
|
||||
{
|
||||
/* For wireless network, we won't get ethtool, it's a wired
|
||||
connection */
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_WIRED;
|
||||
addrs[n].interface.estimated_speed = ((ecmd.speed_hi << 16) | ecmd.speed) * 1000;
|
||||
}
|
||||
|
||||
strncpy(wrq.ifr_name, ifr->ifr_name, sizeof(wrq.ifr_name));
|
||||
e = ioctl(s, SIOCGIWRATE, &wrq);
|
||||
if (e == 0)
|
||||
{
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_WIFI;
|
||||
addrs[n].interface.estimated_speed = wrq.u.bitrate.value / 1000;
|
||||
}
|
||||
|
||||
ifr2 = *ifr;
|
||||
e = ioctl(s, SIOCGIFFLAGS, &ifr2);
|
||||
if (e == 0)
|
||||
{
|
||||
if (ifr2.ifr_flags & IFF_POINTOPOINT)
|
||||
{
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN | NR_INTERFACE_TYPE_VPN;
|
||||
/* TODO (Bug 896913): find backend network type of this VPN */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
strlcpy(addrs[n].addr.ifname, ifr->ifr_name, sizeof(addrs[n].addr.ifname));
|
||||
++n;
|
||||
}
|
||||
}
|
||||
@ -633,13 +690,14 @@ stun_get_siocgifconf_addrs(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
#endif
|
||||
|
||||
static int
|
||||
nr_stun_is_duplicate_addr(nr_transport_addr addrs[], int count, nr_transport_addr *addr)
|
||||
nr_stun_is_duplicate_addr(nr_local_addr addrs[], int count, nr_local_addr *addr)
|
||||
{
|
||||
int i;
|
||||
int different;
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
different = nr_transport_addr_cmp(&addrs[i], addr, NR_TRANSPORT_ADDR_CMP_MODE_ALL);
|
||||
different = nr_transport_addr_cmp(&addrs[i].addr, &(addr->addr),
|
||||
NR_TRANSPORT_ADDR_CMP_MODE_ALL);
|
||||
if (!different)
|
||||
return 1; /* duplicate */
|
||||
}
|
||||
@ -648,10 +706,10 @@ nr_stun_is_duplicate_addr(nr_transport_addr addrs[], int count, nr_transport_add
|
||||
}
|
||||
|
||||
int
|
||||
nr_stun_remove_duplicate_addrs(nr_transport_addr addrs[], int remove_loopback, int *count)
|
||||
nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback, int *count)
|
||||
{
|
||||
int r, _status;
|
||||
nr_transport_addr *tmp = 0;
|
||||
nr_local_addr *tmp = 0;
|
||||
int i;
|
||||
int n;
|
||||
|
||||
@ -664,12 +722,12 @@ nr_stun_remove_duplicate_addrs(nr_transport_addr addrs[], int remove_loopback, i
|
||||
if (nr_stun_is_duplicate_addr(tmp, n, &addrs[i])) {
|
||||
/* skip addrs[i], it's a duplicate */
|
||||
}
|
||||
else if (remove_loopback && nr_transport_addr_is_loopback(&addrs[i])) {
|
||||
else if (remove_loopback && nr_transport_addr_is_loopback(&addrs[i].addr)) {
|
||||
/* skip addrs[i], it's a loopback */
|
||||
}
|
||||
else {
|
||||
/* otherwise, copy it to the temporary array */
|
||||
if ((r=nr_transport_addr_copy(&tmp[n], &addrs[i])))
|
||||
if ((r=nr_local_addr_copy(&tmp[n], &addrs[i])))
|
||||
ABORT(r);
|
||||
++n;
|
||||
}
|
||||
@ -679,7 +737,7 @@ nr_stun_remove_duplicate_addrs(nr_transport_addr addrs[], int remove_loopback, i
|
||||
|
||||
/* copy temporary array into passed in/out array */
|
||||
for (i = 0; i < *count; ++i) {
|
||||
if ((r=nr_transport_addr_copy(&addrs[i], &tmp[i])))
|
||||
if ((r=nr_local_addr_copy(&addrs[i], &tmp[i])))
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
@ -692,10 +750,11 @@ nr_stun_remove_duplicate_addrs(nr_transport_addr addrs[], int remove_loopback, i
|
||||
#ifndef USE_PLATFORM_NR_STUN_GET_ADDRS
|
||||
|
||||
int
|
||||
nr_stun_get_addrs(nr_transport_addr addrs[], int maxaddrs, int drop_loopback, int *count)
|
||||
nr_stun_get_addrs(nr_local_addr addrs[], int maxaddrs, int drop_loopback, int *count)
|
||||
{
|
||||
int _status=0;
|
||||
int i;
|
||||
char typestr[100];
|
||||
|
||||
#if defined(BSD) || defined(DARWIN)
|
||||
_status = stun_get_mib_addrs(addrs, maxaddrs, count);
|
||||
@ -710,7 +769,9 @@ nr_stun_get_addrs(nr_transport_addr addrs[], int maxaddrs, int drop_loopback, in
|
||||
nr_stun_remove_duplicate_addrs(addrs, drop_loopback, count);
|
||||
|
||||
for (i = 0; i < *count; ++i) {
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Address %d: %s on %s", i, addrs[i].as_string, addrs[i].ifname);
|
||||
nr_local_addr_fmt_info_string(addrs+i,typestr,sizeof(typestr));
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Address %d: %s on %s, type: %s\n",
|
||||
i,addrs[i].addr.as_string,addrs[i].addr.ifname,typestr);
|
||||
}
|
||||
|
||||
return _status;
|
||||
|
@ -35,8 +35,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#define _addrs_h_
|
||||
|
||||
#include "transport_addr.h"
|
||||
#include "local_addr.h"
|
||||
|
||||
int nr_stun_get_addrs(nr_transport_addr addrs[], int maxaddrs, int remove_loopback, int *count);
|
||||
int nr_stun_remove_duplicate_addrs(nr_transport_addr addrs[], int remove_loopback,int *count);
|
||||
int nr_stun_get_addrs(nr_local_addr addrs[], int maxaddrs, int remove_loopback, int *count);
|
||||
int nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback,int *count);
|
||||
|
||||
#endif
|
||||
|
@ -98,7 +98,7 @@ nr_stun_xor_mapped_address(UINT4 magicCookie, nr_transport_addr *from, nr_transp
|
||||
}
|
||||
|
||||
int
|
||||
nr_stun_find_local_addresses(nr_transport_addr addrs[], int maxaddrs, int *count)
|
||||
nr_stun_find_local_addresses(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int r,_status;
|
||||
NR_registry *children = 0;
|
||||
@ -137,7 +137,7 @@ nr_stun_find_local_addresses(nr_transport_addr addrs[], int maxaddrs, int *count
|
||||
ABORT(r);
|
||||
|
||||
for (i = 0; i < *count; ++i) {
|
||||
if ((r=nr_reg_get_transport_addr(children[i], 0, &addrs[i])))
|
||||
if ((r=nr_reg_get_transport_addr(children[i], 0, &addrs[i].addr)))
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#define _stun_util_h
|
||||
|
||||
#include "stun.h"
|
||||
#include "local_addr.h"
|
||||
|
||||
extern int NR_LOG_STUN;
|
||||
|
||||
@ -43,7 +44,7 @@ int nr_stun_startup(void);
|
||||
|
||||
int nr_stun_xor_mapped_address(UINT4 magicCookie, nr_transport_addr *from, nr_transport_addr *to);
|
||||
|
||||
int nr_stun_find_local_addresses(nr_transport_addr addrs[], int maxaddrs, int *count);
|
||||
int nr_stun_find_local_addresses(nr_local_addr addrs[], int maxaddrs, int *count);
|
||||
|
||||
int nr_stun_different_transaction(UCHAR *msg, int len, nr_stun_message *req);
|
||||
|
||||
|
@ -395,9 +395,6 @@ pref("app.geo.reportdata", 0);
|
||||
//pref("content.sink.perf_deflect_count", 1000000);
|
||||
//pref("content.sink.perf_parse_time", 50000000);
|
||||
|
||||
// Disable methodjit in chrome to save memory
|
||||
pref("javascript.options.methodjit.chrome", false);
|
||||
|
||||
// Disable the JS engine's gc on memory pressure, since we do one in the mobile
|
||||
// browser (bug 669346).
|
||||
pref("javascript.options.gc_on_memory_pressure", false);
|
||||
|
@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES">
|
||||
<attributes>
|
||||
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="geckoview_library/libs/armeabi-v7a"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>GeckoView</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -1,17 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mozilla.geckoview"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="8"
|
||||
android:targetSdkVersion="17" />
|
||||
|
||||
</manifest>
|
@ -1,45 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
INSTALL_TARGETS += GECKOVIEW_LIBRARY
|
||||
GECKOVIEW_LIBRARY_DEST = $(CURDIR)
|
||||
GECKOVIEW_LIBRARY_FILES := \
|
||||
.classpath \
|
||||
.project \
|
||||
AndroidManifest.xml \
|
||||
project.properties \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
package:
|
||||
# Make directory for the zips
|
||||
$(MKDIR) -p $(DIST)/geckoview_library
|
||||
|
||||
# Zip the assets
|
||||
cd $(DIST)/fennec; \
|
||||
$(ZIP) -r ../geckoview_library/geckoview_assets.zip assets
|
||||
|
||||
# Make empty directories to fit an Android project structure
|
||||
$(MKDIR) -p bin gen libs/$(ABI_DIR) src
|
||||
|
||||
# Copy the JARs
|
||||
cp ../base/jars/* libs/
|
||||
|
||||
# Copy the SOs
|
||||
cp $(DIST)/bin/libmozglue.so $(DIST)/bin/lib/libplugin-container.so libs/$(ABI_DIR)/
|
||||
|
||||
# Copy the resources
|
||||
cp -R ../base/res .
|
||||
|
||||
# Zip the directory
|
||||
cd ..; \
|
||||
$(ZIP) -r ../../dist/geckoview_library/geckoview_library.zip geckoview_library --exclude geckoview_library/backend.mk geckoview_library/Makefile
|
@ -1,5 +0,0 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
@ -1,15 +0,0 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-17
|
||||
android.library=true
|
@ -16,7 +16,6 @@ DIRS += [
|
||||
'themes/core',
|
||||
'app',
|
||||
'fonts',
|
||||
'geckoview_library',
|
||||
]
|
||||
|
||||
if not CONFIG['LIBXUL_SDK']:
|
||||
|
@ -13,7 +13,8 @@ class testElementTouch(MarionetteTestCase):
|
||||
button.tap()
|
||||
expected = "button1-touchstart-touchend-mousemove-mousedown-mouseup-click"
|
||||
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
|
||||
button.tap(0, 300)
|
||||
button = self.marionette.find_element("id", "button2")
|
||||
button.tap()
|
||||
expected = "button2-touchstart-touchend-mousemove-mousedown-mouseup-click"
|
||||
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button2').innerHTML;") == expected)
|
||||
|
||||
|
@ -9,7 +9,7 @@ const CHILD_SCRIPT = "chrome://specialpowers/content/specialpowers.js";
|
||||
const CHILD_SCRIPT_API = "chrome://specialpowers/content/specialpowersAPI.js";
|
||||
const CHILD_LOGGER_SCRIPT = "chrome://specialpowers/content/MozillaLogger.js";
|
||||
|
||||
let homescreen = document.getElementById('homescreen');
|
||||
let homescreen = document.getElementById('systemapp');
|
||||
let container = homescreen.contentWindow.document.getElementById('test-container');
|
||||
|
||||
function openWindow(aEvent) {
|
||||
|
@ -409,7 +409,7 @@ toolbar#nav-bar {
|
||||
if options.browserChrome or options.chrome or options.a11y or options.webapprtChrome:
|
||||
chrome += """
|
||||
overlay chrome://browser/content/browser.xul chrome://mochikit/content/browser-test-overlay.xul
|
||||
overlay chrome://browser/content/shell.xul chrome://mochikit/content/browser-test-overlay.xul
|
||||
overlay chrome://browser/content/shell.xhtml chrome://mochikit/content/browser-test-overlay.xul
|
||||
overlay chrome://navigator/content/navigator.xul chrome://mochikit/content/browser-test-overlay.xul
|
||||
overlay chrome://webapprt/content/webapp.xul chrome://mochikit/content/browser-test-overlay.xul
|
||||
"""
|
||||
|
@ -8,6 +8,7 @@ let Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import("resource://gre/modules/RemoteAddonsChild.jsm");
|
||||
|
||||
let WebProgressListener = {
|
||||
init: function() {
|
||||
@ -223,4 +224,6 @@ addEventListener("ImageContentLoaded", function (aEvent) {
|
||||
sendAsyncMessage("ImageDocumentLoaded", { width: req.image.width,
|
||||
height: req.image.height });
|
||||
}
|
||||
}, false)
|
||||
}, false);
|
||||
|
||||
RemoteAddonsChild.init(this);
|
||||
|
@ -113,6 +113,10 @@
|
||||
let RemoteController = Components.utils.import(jsm, {}).RemoteController;
|
||||
this._controller = new RemoteController(this);
|
||||
this.controllers.appendController(this._controller);
|
||||
|
||||
jsm = "resource://gre/modules/RemoteAddonsParent.jsm";
|
||||
let RemoteAddonsParent = Components.utils.import(jsm, {}).RemoteAddonsParent;
|
||||
RemoteAddonsParent.init();
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
|
108
toolkit/modules/RemoteAddonsChild.jsm
Normal file
108
toolkit/modules/RemoteAddonsChild.jsm
Normal file
@ -0,0 +1,108 @@
|
||||
// -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["RemoteAddonsChild"];
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
/**
|
||||
* This code registers an nsIContentPolicy in the child process. When
|
||||
* it runs, it notifies the parent that it needs to run its own
|
||||
* nsIContentPolicy list. If any policy in the parent rejects the load,
|
||||
* that answer is returned to the child.
|
||||
*/
|
||||
let ContentPolicyChild = {
|
||||
_classDescription: "Addon shim content policy",
|
||||
_classID: Components.ID("6e869130-635c-11e2-bcfd-0800200c9a66"),
|
||||
_contractID: "@mozilla.org/addon-child/policy;1",
|
||||
|
||||
/**
|
||||
* We only notify the parent of the load if it has any
|
||||
* non-builtin policies registered.
|
||||
*/
|
||||
_childNeedsHook: false,
|
||||
|
||||
init: function(aContentGlobal) {
|
||||
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.registerFactory(this._classID, this._classDescription, this._contractID, this);
|
||||
|
||||
var catMan = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
|
||||
catMan.addCategoryEntry("content-policy", this._contractID, this._contractID, false, true);
|
||||
|
||||
let policiesToIgnore = [];
|
||||
let services = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager)
|
||||
.enumerateCategory("content-policy");
|
||||
while (services.hasMoreElements()) {
|
||||
let item = services.getNext();
|
||||
let name = item.QueryInterface(Components.interfaces.nsISupportsCString).toString();
|
||||
policiesToIgnore.push(name);
|
||||
}
|
||||
|
||||
let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(Ci.nsISyncMessageSender);
|
||||
cpmm.addMessageListener("Addons:ContentPolicy:NeedHook", this);
|
||||
cpmm.sendAsyncMessage("Addons:ContentPolicy:IgnorePolicies", { "policies": policiesToIgnore });
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
switch (aMessage.name) {
|
||||
case "Addons:ContentPolicy:NeedHook":
|
||||
this._childNeedsHook = aMessage.data.needed;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIObserver,
|
||||
Ci.nsIChannelEventSink, Ci.nsIFactory,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
shouldLoad: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra) {
|
||||
if (!this._childNeedsHook)
|
||||
return Ci.nsIContentPolicy.ACCEPT;
|
||||
|
||||
let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(Ci.nsISyncMessageSender);
|
||||
var rval = cpmm.sendSyncMessage("Addons:ContentPolicy:Run", {
|
||||
contentType: contentType,
|
||||
mimeTypeGuess: mimeTypeGuess
|
||||
}, {
|
||||
contentLocation: contentLocation,
|
||||
requestOrigin: requestOrigin,
|
||||
node: node
|
||||
});
|
||||
if (rval.length != 1)
|
||||
return Ci.nsIContentPolicy.ACCEPT;
|
||||
|
||||
return rval[0];
|
||||
},
|
||||
|
||||
shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra) {
|
||||
return Ci.nsIContentPolicy.ACCEPT;
|
||||
},
|
||||
|
||||
createInstance: function(outer, iid) {
|
||||
if (outer)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return this.QueryInterface(iid);
|
||||
},
|
||||
};
|
||||
|
||||
let RemoteAddonsChild = {
|
||||
initialized: false,
|
||||
|
||||
init: function(aContentGlobal) {
|
||||
if (this.initialized)
|
||||
return;
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
ContentPolicyChild.init(aContentGlobal);
|
||||
},
|
||||
};
|
129
toolkit/modules/RemoteAddonsParent.jsm
Normal file
129
toolkit/modules/RemoteAddonsParent.jsm
Normal file
@ -0,0 +1,129 @@
|
||||
// -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["RemoteAddonsParent"];
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
/**
|
||||
* This code listens for nsIContentPolicy hooks firing in child
|
||||
* processes. It then fires all hooks in the parent process and
|
||||
* returns the result to the child.
|
||||
*/
|
||||
let ContentPolicyParent = {
|
||||
/**
|
||||
* Some builtin policies will have already run in the child, and
|
||||
* there's no reason to run them in the parent. This is a list of
|
||||
* those policies. We assume that all child processes have the same
|
||||
* set of built-in policies.
|
||||
*/
|
||||
_policiesToIgnore: [],
|
||||
|
||||
init: function() {
|
||||
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageBroadcaster);
|
||||
ppmm.addMessageListener("Addons:ContentPolicy:IgnorePolicies", this);
|
||||
ppmm.addMessageListener("Addons:ContentPolicy:Run", this);
|
||||
|
||||
Services.obs.addObserver(this, "xpcom-category-entry-added", true);
|
||||
Services.obs.addObserver(this, "xpcom-category-entry-removed", true);
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "xpcom-category-entry-added":
|
||||
case "xpcom-category-entry-removed":
|
||||
if (aData == "content-policy")
|
||||
this.updatePolicies();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* There's no need for the child process to inform us about the
|
||||
* shouldLoad hook if we don't have any policies in the parent to
|
||||
* run. This code iterates over the parent's policies, looking for
|
||||
* ones that should not be ignored. Based on that, it tells the
|
||||
* children whether it needs to be informed about the shouldLoad
|
||||
* hook.
|
||||
*/
|
||||
updatePolicies: function() {
|
||||
let needHook = false;
|
||||
|
||||
let services = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager)
|
||||
.enumerateCategory("content-policy");
|
||||
while (services.hasMoreElements()) {
|
||||
let item = services.getNext();
|
||||
let name = item.QueryInterface(Components.interfaces.nsISupportsCString).toString();
|
||||
|
||||
if (this._policiesToIgnore.indexOf(name) == -1) {
|
||||
needHook = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageBroadcaster);
|
||||
ppmm.broadcastAsyncMessage("Addons:ContentPolicy:NeedHook", { needed: needHook });
|
||||
},
|
||||
|
||||
receiveMessage: function (aMessage) {
|
||||
switch (aMessage.name) {
|
||||
case "Addons:ContentPolicy:IgnorePolicies":
|
||||
this._policiesToIgnore = aMessage.data.policies;
|
||||
this.updatePolicies();
|
||||
break;
|
||||
|
||||
case "Addons:ContentPolicy:Run":
|
||||
return this.shouldLoad(aMessage.data, aMessage.objects);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
shouldLoad: function(aData, aObjects) {
|
||||
let services = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager)
|
||||
.enumerateCategory("content-policy");
|
||||
while (services.hasMoreElements()) {
|
||||
let item = services.getNext();
|
||||
let name = item.QueryInterface(Components.interfaces.nsISupportsCString).toString();
|
||||
if (this._policiesToIgnore.indexOf(name) != -1)
|
||||
continue;
|
||||
|
||||
let policy = Cc[name].getService(Ci.nsIContentPolicy);
|
||||
try {
|
||||
let result = policy.shouldLoad(aData.contentType,
|
||||
aObjects.contentLocation,
|
||||
aObjects.requestOrigin,
|
||||
aObjects.node,
|
||||
aData.mimeTypeGuess,
|
||||
null);
|
||||
if (result != Ci.nsIContentPolicy.ACCEPT && result != 0)
|
||||
return result;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
return Ci.nsIContentPolicy.ACCEPT;
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
||||
};
|
||||
|
||||
let RemoteAddonsParent = {
|
||||
initialized: false,
|
||||
|
||||
init: function() {
|
||||
if (this.initialized)
|
||||
return;
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
ContentPolicyParent.init();
|
||||
},
|
||||
};
|
@ -21,6 +21,8 @@ EXTRA_JS_MODULES += [
|
||||
'PrivateBrowsingUtils.jsm',
|
||||
'Promise.jsm',
|
||||
'PropertyListUtils.jsm',
|
||||
'RemoteAddonsChild.jsm',
|
||||
'RemoteAddonsParent.jsm',
|
||||
'RemoteController.jsm',
|
||||
'RemoteSecurityUI.jsm',
|
||||
'RemoteWebNavigation.jsm',
|
||||
|
@ -344,10 +344,6 @@ else
|
||||
INNER_ROBOCOP_PACKAGE=echo 'Testing is disabled - No Robocop for you'
|
||||
endif
|
||||
|
||||
# Create geckoview_library/geckoview_{assets,library}.zip for third-party GeckoView consumers.
|
||||
INNER_MAKE_GECKOVIEW_LIBRARY= \
|
||||
$(MAKE) -C ../mobile/android/geckoview_library package ABI_DIR=$(ABI_DIR)
|
||||
|
||||
ifdef MOZ_OMX_PLUGIN
|
||||
DIST_FILES += libomxplugin.so libomxplugingb.so libomxplugingb235.so libomxpluginhc.so libomxpluginsony.so libomxpluginfroyo.so libomxpluginjb-htc.so
|
||||
endif
|
||||
@ -398,8 +394,7 @@ INNER_MAKE_PACKAGE = \
|
||||
cp $(_ABS_DIST)/gecko.apk $(_ABS_DIST)/gecko-unsigned-unaligned.apk && \
|
||||
$(RELEASE_JARSIGNER) $(_ABS_DIST)/gecko.apk && \
|
||||
$(ZIPALIGN) -f -v 4 $(_ABS_DIST)/gecko.apk $(PACKAGE) && \
|
||||
$(INNER_ROBOCOP_PACKAGE) && \
|
||||
$(INNER_MAKE_GECKOVIEW_LIBRARY)
|
||||
$(INNER_ROBOCOP_PACKAGE)
|
||||
|
||||
# Language repacks root the resources contained in assets/omni.ja
|
||||
# under assets/, but the repacks expect them to be rooted at /.
|
||||
|
@ -1211,14 +1211,14 @@ protected:
|
||||
* GetModifierKeyForNativeKeyCode() returns the stored ModifierKey for
|
||||
* the key.
|
||||
*/
|
||||
ModifierKey*
|
||||
const ModifierKey*
|
||||
GetModifierKeyForNativeKeyCode(unsigned short aKeyCode) const;
|
||||
|
||||
/**
|
||||
* GetModifierKeyForDeviceDependentFlags() returns the stored ModifierKey for
|
||||
* the device dependent flags.
|
||||
*/
|
||||
ModifierKey*
|
||||
const ModifierKey*
|
||||
GetModifierKeyForDeviceDependentFlags(NSUInteger aFlags) const;
|
||||
|
||||
/**
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user