Merge latest green fx-team changeset and mozilla-central

This commit is contained in:
Ed Morley 2013-08-29 15:01:41 +01:00
commit a308a05b5c
101 changed files with 1948 additions and 595 deletions

View File

@ -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.

View File

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

View 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>

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
{
"revision": "f400eac8b28353050ea9ff87dcb7e780e3537a89",
"revision": "7db3c28d7056b880b3be261f7784b5cc3e96702b",
"repo_path": "/integration/gaia-central"
}

View File

@ -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.

View File

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

View File

@ -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',

View File

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

View File

@ -141,8 +141,6 @@ DOMCI_CLASS(BluetoothDevice)
DOMCI_CLASS(CameraCapabilities)
DOMCI_CLASS(DOMWindowResizeEventDetail)
DOMCI_CLASS(LockedFile)
DOMCI_CLASS(CSSFontFeatureValuesRule)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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*

View File

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

View File

@ -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*

View File

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

View File

@ -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"

View File

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

View File

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

View File

@ -9,6 +9,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/Likely.h"
#include "jsapi.h"
#include "jsproxy.h"
#include "nsStringGlue.h"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -172,7 +172,6 @@ var interfaceNamesInGlobalScope =
"DOMStringMap",
"DOMTokenList",
"DOMTransactionEvent",
"DOMWindowResizeEventDetail",
"DragEvent",
"DynamicsCompressorNode",
"Element",

View File

@ -22,3 +22,8 @@ dictionary OpenWindowEventDetail {
DOMString features = "";
Node? frameElement = null;
};
dictionary DOMWindowResizeEventDetail {
long width = 0;
long height = 0;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,6 @@
#include "mozilla/Attributes.h"
#include "jsapi.h"
#include "jsproxy.h"
namespace js {

View 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");

View File

@ -8,6 +8,7 @@
#ifndef xpcpublic_h
#define xpcpublic_h
#include "jsapi.h"
#include "jsproxy.h"
#include "js/HeapAPI.h"
#include "js/GCAPI.h"

View File

@ -8,6 +8,7 @@
#ifndef __AccessCheck_h__
#define __AccessCheck_h__
#include "jsapi.h"
#include "jswrapper.h"
class nsIPrincipal;

View File

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

View File

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

View File

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

View File

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

View 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

View 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

View File

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

View File

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

View File

@ -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",

View File

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

View File

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

View File

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

View File

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

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

View 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

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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/.

View File

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

View File

@ -16,7 +16,6 @@ DIRS += [
'themes/core',
'app',
'fonts',
'geckoview_library',
]
if not CONFIG['LIBXUL_SDK']:

View File

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

View File

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

View File

@ -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
"""

View File

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

View File

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

View 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);
},
};

View 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();
},
};

View File

@ -21,6 +21,8 @@ EXTRA_JS_MODULES += [
'PrivateBrowsingUtils.jsm',
'Promise.jsm',
'PropertyListUtils.jsm',
'RemoteAddonsChild.jsm',
'RemoteAddonsParent.jsm',
'RemoteController.jsm',
'RemoteSecurityUI.jsm',
'RemoteWebNavigation.jsm',

View File

@ -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 /.

View File

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