Merge m-c to fx-team.

This commit is contained in:
Ryan VanderMeulen 2013-08-27 20:38:23 -04:00
commit 1f9cf546ef
370 changed files with 4426 additions and 2044 deletions

View File

@ -30,7 +30,6 @@ MOCHITEST_A11Y_FILES =\
test_dragndrop.html \
test_flush.html \
test_focus_aria_activedescendant.html \
test_focus_autocomplete.xul \
test_focus_browserui.xul \
test_focus_canvas.html \
test_focus_contextmenu.xul \
@ -62,4 +61,11 @@ MOCHITEST_A11Y_FILES =\
test_valuechange.html \
$(NULL)
# Disabled on Linux and Windows due to frequent failures - bug 695019, bug 890795
ifeq (,$(filter Linux WINNT,$(OS_ARCH)))
MOCHITEST_A11Y_FILES += \
test_focus_autocomplete.xul \
$(NULL)
endif
include $(topsrcdir)/config/rules.mk

View File

@ -757,6 +757,9 @@ var AlertsHelper = {
return helper.resolveFromOrigin(message["notification"]);
}
}
// No message found...
return null;
}
listener.target = getNotificationURLFor(manifest.messages);
@ -833,7 +836,7 @@ var AlertsHelper = {
if (!aMessage.target.assertAppHasPermission("desktop-notification")) {
Cu.reportError("Desktop-notification message " + aMessage.name +
" from a content process with no desktop-notification privileges.");
return null;
return;
}
let data = aMessage.data;

View File

@ -1,4 +1,4 @@
{
"revision": "e8f63cae5aff3b61c0a49a9209ae971092ddee22",
"revision": "a183b055417d036b01e177750ab2ec6162d6fcd7",
"repo_path": "/integration/gaia-central"
}

View File

@ -329,7 +329,10 @@ static int Launch()
return RETRY;
}
Log(L"Activation succeeded. processid=%d", processID);
Log(L"Activation succeeded.");
// automation.py picks up on this, don't mess with it.
Log(L"METRO_BROWSER_PROCESS=%d", processID);
HANDLE child = OpenProcess(SYNCHRONIZE, FALSE, processID);
if (!child) {

View File

@ -542,31 +542,39 @@ class Automation(object):
GetLastError = ctypes.windll.kernel32.GetLastError
def readWithTimeout(self, f, timeout):
"""Try to read a line of output from the file object |f|.
|f| must be a pipe, like the |stdout| member of a subprocess.Popen
object created with stdout=PIPE. If no output
is received within |timeout| seconds, return a blank line.
Returns a tuple (line, did_timeout), where |did_timeout| is True
if the read timed out, and False otherwise."""
"""
Try to read a line of output from the file object |f|. |f| must be a
pipe, like the |stdout| member of a subprocess.Popen object created
with stdout=PIPE. Returns a tuple (line, did_timeout), where |did_timeout|
is True if the read timed out, and False otherwise. If no output is
received within |timeout| seconds, returns a blank line.
"""
if timeout is None:
# shortcut to allow callers to pass in "None" for no timeout.
return (f.readline(), False)
timeout = 0
x = msvcrt.get_osfhandle(f.fileno())
l = ctypes.c_long()
done = time.time() + timeout
while time.time() < done:
buffer = ""
while timeout == 0 or time.time() < done:
if self.PeekNamedPipe(x, None, 0, None, ctypes.byref(l), None) == 0:
err = self.GetLastError()
if err == 38 or err == 109: # ERROR_HANDLE_EOF || ERROR_BROKEN_PIPE
return ('', False)
else:
self.log.error("readWithTimeout got error: %d", err)
if l.value > 0:
# we're assuming that the output is line-buffered,
# which is not unreasonable
return (f.readline(), False)
# read a character at a time, checking for eol. Return once we get there.
index = 0
while index < l.value:
char = f.read(1)
buffer += char
if char == '\n':
return (buffer, False)
index = index + 1
time.sleep(0.01)
return ('', True)
return (buffer, True)
def isPidAlive(self, pid):
STILL_ACTIVE = 259
@ -725,6 +733,11 @@ class Automation(object):
stdout=subprocess.PIPE)
logsource = stackFixerProcess.stdout
# With metro browser runs this script launches the metro test harness which launches the browser.
# The metro test harness hands back the real browser process id via log output which we need to
# pick up on and parse out. This variable tracks the real browser process id if we find it.
browserProcessId = -1
(line, didTimeout) = self.readWithTimeout(logsource, timeout)
while line != "" and not didTimeout:
if stackFixerFunction:
@ -736,14 +749,25 @@ class Automation(object):
self.dumpScreen(utilityPath)
(line, didTimeout) = self.readWithTimeout(logsource, timeout)
if "METRO_BROWSER_PROCESS" in line:
index = line.find("=")
if index:
browserProcessId = line[index+1:].rstrip()
self.log.info("INFO | automation.py | metro browser sub process id detected: %s", browserProcessId)
if not hitMaxTime and maxTime and datetime.now() - startTime > timedelta(seconds = maxTime):
# Kill the application, but continue reading from stack fixer so as not to deadlock on stackFixerProcess.wait().
hitMaxTime = True
self.log.info("TEST-UNEXPECTED-FAIL | %s | application ran for longer than allowed maximum time of %d seconds", self.lastTestSeen, int(maxTime))
self.killAndGetStack(proc.pid, utilityPath, debuggerInfo)
if didTimeout:
if line:
self.log.info(line.rstrip().decode("UTF-8", "ignore"))
self.log.info("TEST-UNEXPECTED-FAIL | %s | application timed out after %d seconds with no output", self.lastTestSeen, int(timeout))
self.killAndGetStack(proc.pid, utilityPath, debuggerInfo)
if browserProcessId == -1:
browserProcessId = proc.pid
self.killAndGetStack(browserProcessId, utilityPath, debuggerInfo)
status = proc.wait()
if status == 0:

View File

@ -356,7 +356,7 @@ Element::GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult)
JSObject*
Element::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aScope)
{
JSObject* obj = nsINode::WrapObject(aCx, aScope);
JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx, aScope));
if (!obj) {
return nullptr;
}

View File

@ -753,6 +753,7 @@ GK_ATOM(onobsolete, "onobsolete")
GK_ATOM(ononline, "ononline")
GK_ATOM(onoffline, "onoffline")
GK_ATOM(onopen, "onopen")
GK_ATOM(onotastatuschange, "onotastatuschange")
GK_ATOM(onoverflow, "onoverflow")
GK_ATOM(onoverflowchanged, "onoverflowchanged")
GK_ATOM(onpagehide, "onpagehide")

View File

@ -872,6 +872,7 @@ private:
void VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr);
bool ValidateBufferFetching(const char *info);
bool BindArrayAttribToLocation0(WebGLProgram *program);
// -----------------------------------------------------------------------------
// PROTECTED

View File

@ -1966,6 +1966,36 @@ WebGLContext::IsTexture(WebGLTexture *tex)
tex->HasEverBeenBound();
}
// Try to bind an attribute that is an array to location 0:
bool WebGLContext::BindArrayAttribToLocation0(WebGLProgram *program)
{
if (mBoundVertexArray->mAttribBuffers[0].enabled) {
return false;
}
GLint leastArrayLocation = -1;
std::map<GLint, nsCString>::iterator itr;
for (itr = program->mActiveAttribMap.begin();
itr != program->mActiveAttribMap.end();
itr++) {
int32_t index = itr->first;
if (mBoundVertexArray->mAttribBuffers[index].enabled &&
index < leastArrayLocation)
{
leastArrayLocation = index;
}
}
if (leastArrayLocation > 0) {
nsCString& attrName = program->mActiveAttribMap.find(leastArrayLocation)->second;
const char* attrNameCStr = attrName.get();
gl->fBindAttribLocation(program->GLName(), 0, attrNameCStr);
return true;
}
return false;
}
void
WebGLContext::LinkProgram(WebGLProgram *program)
{
@ -2003,7 +2033,8 @@ WebGLContext::LinkProgram(WebGLProgram *program)
return;
}
GLint ok;
bool updateInfoSucceeded = false;
GLint ok = 0;
if (gl->WorkAroundDriverBugs() &&
program->HasBadShaderAttached())
{
@ -2015,12 +2046,25 @@ WebGLContext::LinkProgram(WebGLProgram *program)
MakeContextCurrent();
gl->fLinkProgram(progname);
gl->fGetProgramiv(progname, LOCAL_GL_LINK_STATUS, &ok);
if (ok) {
updateInfoSucceeded = program->UpdateInfo();
program->SetLinkStatus(updateInfoSucceeded);
if (BindArrayAttribToLocation0(program)) {
GenerateWarning("linkProgram: relinking program to make attrib0 an "
"array.");
gl->fLinkProgram(progname);
gl->fGetProgramiv(progname, LOCAL_GL_LINK_STATUS, &ok);
if (ok) {
updateInfoSucceeded = program->UpdateInfo();
program->SetLinkStatus(updateInfoSucceeded);
}
}
}
}
if (ok) {
bool updateInfoSucceeded = program->UpdateInfo();
program->SetLinkStatus(updateInfoSucceeded);
// Bug 750527
if (gl->WorkAroundDriverBugs() &&
updateInfoSucceeded &&

View File

@ -86,6 +86,25 @@ WebGLProgram::UpdateInfo()
}
}
mActiveAttribMap.clear();
GLint numActiveAttrs = 0;
mContext->gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, &numActiveAttrs);
// Spec says the maximum attrib name length is 256 chars, so this is
// sufficient to hold any attrib name.
char attrName[257];
GLint dummySize;
GLenum dummyType;
for (GLint i = 0; i < numActiveAttrs; i++) {
mContext->gl->fGetActiveAttrib(mGLName, i, 257, nullptr, &dummySize,
&dummyType, attrName);
GLint attrLoc = mContext->gl->fGetAttribLocation(mGLName, attrName);
MOZ_ASSERT(attrLoc >= 0);
mActiveAttribMap.insert(std::make_pair(attrLoc, nsCString(attrName)));
}
return true;
}

View File

@ -110,6 +110,9 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLProgram)
// public post-link data
std::map<GLint, nsCString> mActiveAttribMap;
protected:
WebGLuint mGLName;

View File

@ -0,0 +1,3 @@
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<window id="win" removeelement="true"/>
</overlay>

View File

@ -0,0 +1,3 @@
<?xul-overlay href="509719-1-overlay.xul"?>
<window id="win" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
</window>

View File

@ -0,0 +1,8 @@
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script>
if (document.getElementById("testnode")) {
document.loadOverlay(window.location.href.substr(0,window.location.href.lastIndexOf('/')+1)+'509719-2-overlay.xul', null);
}
</script>
<box xmlns="http://www.w3.org/1999/xhtml" id="testnode" removeelement="true"/>
</overlay>

View File

@ -0,0 +1,7 @@
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
<window id="win" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<box id="testnode" onDOMAttrModified="this.parentNode.removeChild(this)"/>
<script>
document.loadOverlay(window.location.href.substr(0,window.location.href.lastIndexOf('/')+1)+'509719-2-overlay.xul', null);
</script>
</window>

View File

@ -20,3 +20,5 @@ load 429085-1.xhtml
load 431906-1.html
load 451311-1.xul
load 461917-1.xhtml
load 509719-1.xul
asserts(3) load 509719-2.xul # bug 909819

View File

@ -3543,6 +3543,11 @@ XULDocument::OnStreamComplete(nsIStreamLoader* aLoader,
NS_IMETHODIMP
XULDocument::OnScriptCompileComplete(JSScript* aScript, nsresult aStatus)
{
// When compiling off thread the script will not have been attached to the
// script proto yet.
if (aScript && !mCurrentScriptProto->GetScriptObject())
mCurrentScriptProto->Set(aScript);
// Allow load events to be fired once off thread compilation finishes.
if (mOffThreadCompiling) {
mOffThreadCompiling = false;
@ -3552,11 +3557,6 @@ XULDocument::OnScriptCompileComplete(JSScript* aScript, nsresult aStatus)
// After compilation finishes the script's characters are no longer needed.
mOffThreadCompileString.Truncate();
// When compiling off thread the script will not have been attached to the
// script proto yet.
if (aScript && !mCurrentScriptProto->GetScriptObject())
mCurrentScriptProto->Set(aScript);
// Clear mCurrentScriptProto now, but save it first for use below in
// the execute code, and in the while loop that resumes walks of other
// documents that raced to load this script.
@ -3664,7 +3664,7 @@ XULDocument::ExecuteScript(nsIScriptContext * aContext,
nsAutoMicroTask mt;
JSContext *cx = aContext->GetNativeContext();
AutoCxPusher pusher(cx);
JSObject* global = mScriptGlobalObject->GetGlobalJSObject();
JS::Rooted<JSObject*> global(cx, mScriptGlobalObject->GetGlobalJSObject());
xpc_UnmarkGrayObject(global);
xpc_UnmarkGrayScript(aScriptObject);
JSAutoCompartment ac(cx, global);
@ -4067,7 +4067,8 @@ XULDocument::OverlayForwardReference::Merge(nsIContent* aTargetNode,
if (attr == nsGkAtoms::removeelement &&
value.EqualsLiteral("true")) {
nsCOMPtr<nsIContent> parent = aTargetNode->GetParent();
nsCOMPtr<nsINode> parent = aTargetNode->GetParentNode();
if (!parent) return NS_ERROR_FAILURE;
rv = RemoveElement(parent, aTargetNode);
if (NS_FAILED(rv)) return rv;
@ -4449,7 +4450,7 @@ XULDocument::CheckBroadcasterHookup(Element* aElement,
}
nsresult
XULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild,
XULDocument::InsertElement(nsINode* aParent, nsIContent* aChild,
bool aNotify)
{
// Insert aChild appropriately into aParent, accounting for a
@ -4530,7 +4531,7 @@ XULDocument::InsertElement(nsIContent* aParent, nsIContent* aChild,
}
nsresult
XULDocument::RemoveElement(nsIContent* aParent, nsIContent* aChild)
XULDocument::RemoveElement(nsINode* aParent, nsINode* aChild)
{
int32_t nodeOffset = aParent->IndexOf(aChild);

View File

@ -591,11 +591,11 @@ protected:
static
nsresult
InsertElement(nsIContent* aParent, nsIContent* aChild, bool aNotify);
InsertElement(nsINode* aParent, nsIContent* aChild, bool aNotify);
static
nsresult
RemoveElement(nsIContent* aParent, nsIContent* aChild);
RemoveElement(nsINode* aParent, nsINode* aChild);
/**
* The current prototype that we are walking to construct the

View File

@ -1243,7 +1243,7 @@ DOMInterfaces = {
'WebGLActiveInfo': {
'nativeType': 'mozilla::WebGLActiveInfo',
'headerFile': 'WebGLContext.h',
'headerFile': 'WebGLActiveInfo.h',
'wrapperCache': False
},

View File

@ -22,6 +22,7 @@ if CONFIG['MOZ_B2G_RIL']:
'nsIDOMCFStateChangeEvent.idl',
'nsIDOMMobileConnection.idl',
'nsIDOMMozEmergencyCbModeEvent.idl',
'nsIDOMMozOtaStatusEvent.idl',
'nsIDOMNetworkStats.idl',
'nsIDOMNetworkStatsManager.idl',
'nsIMobileConnectionProvider.idl',

View File

@ -11,7 +11,7 @@ interface nsIDOMMozMobileNetworkInfo;
interface nsIDOMMozMobileCellInfo;
interface nsIDOMMozMobileCFInfo;
[scriptable, builtinclass, uuid(8284af62-c39d-4a59-b258-107040040418)]
[scriptable, builtinclass, uuid(095b3720-058c-11e3-8ffd-0800200c9a66)]
interface nsIDOMMozMobileConnection : nsIDOMEventTarget
{
const long ICC_SERVICE_CLASS_VOICE = (1 << 0);
@ -263,6 +263,21 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
*/
nsIDOMDOMRequest getCallBarringOption(in jsval option);
/**
* Change call barring facility password.
*
* @param info
* An object containing information about pin and newPin, and,
* this object must have both "pin" and "newPin" attributes
* to change the call barring facility password.
*
* Example:
*
* changeCallBarringPassword({pin: "...",
* newPin: "..."});
*/
nsIDOMDOMRequest changeCallBarringPassword(in jsval info);
/**
* Configures call waiting options.
*
@ -362,6 +377,12 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
* callback mode changes.
*/
[implicit_jscontext] attribute jsval onemergencycbmodechange;
/**
* The 'onotastatuschange' event is notified whenever the ota provision status
* changes.
*/
[implicit_jscontext] attribute jsval onotastatuschange;
};
[scriptable, uuid(49706beb-a160-40b7-b745-50f62e389a2c)]

View File

@ -0,0 +1,21 @@
/* 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 "nsIDOMEvent.idl"
[scriptable, builtinclass, uuid(d3592cdc-c5cf-4c24-a27c-6f789ac94959)]
interface nsIDOMMozOtaStatusEvent : nsIDOMEvent
{
readonly attribute DOMString status;
[noscript] void initMozOtaStatusEvent(in DOMString aType,
in boolean aCanBubble,
in boolean aCancelable,
in DOMString aStatus);
};
dictionary MozOtaStatusEventInit : EventInit
{
DOMString status;
};

View File

@ -10,7 +10,7 @@ interface nsIDOMMozMobileConnectionInfo;
interface nsIDOMMozMobileNetworkInfo;
interface nsIDOMWindow;
[scriptable, uuid(7da2d9f6-eba1-4339-bde1-dc6732d42cdf)]
[scriptable, uuid(f1878629-4151-4e02-a22a-8cec3d7eddee)]
interface nsIMobileConnectionListener : nsISupports
{
void notifyVoiceChanged();
@ -26,13 +26,14 @@ interface nsIMobileConnectionListener : nsISupports
in unsigned short serviceClass);
void notifyEmergencyCbModeChanged(in boolean active,
in unsigned long timeoutMs);
void notifyOtaStatusChanged(in DOMString status);
};
/**
* XPCOM component (in the content process) that provides the mobile
* network information.
*/
[scriptable, uuid(576c7c00-7319-4309-aa9e-1dab102e0874)]
[scriptable, uuid(c66652e0-0628-11e3-8ffd-0800200c9a66)]
interface nsIMobileConnectionProvider : nsISupports
{
/**
@ -71,6 +72,8 @@ interface nsIMobileConnectionProvider : nsISupports
in jsval option);
nsIDOMDOMRequest setCallBarringOption(in nsIDOMWindow window,
in jsval option);
nsIDOMDOMRequest changeCallBarringPassword(in nsIDOMWindow window,
in jsval info);
nsIDOMDOMRequest setCallWaitingOption(in nsIDOMWindow window,
in bool enabled);

View File

@ -3,7 +3,6 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MobileConnection.h"
#include "GeneratedEvents.h"
#include "mozilla/Preferences.h"
#include "nsDOMEvent.h"
@ -12,6 +11,7 @@
#include "nsIDOMDOMRequest.h"
#include "nsIDOMDataErrorEvent.h"
#include "nsIDOMMozEmergencyCbModeEvent.h"
#include "nsIDOMMozOtaStatusEvent.h"
#include "nsIDOMUSSDReceivedEvent.h"
#include "nsIPermissionManager.h"
@ -76,6 +76,7 @@ NS_IMPL_EVENT_HANDLER(MobileConnection, ussdreceived)
NS_IMPL_EVENT_HANDLER(MobileConnection, dataerror)
NS_IMPL_EVENT_HANDLER(MobileConnection, cfstatechange)
NS_IMPL_EVENT_HANDLER(MobileConnection, emergencycbmodechange)
NS_IMPL_EVENT_HANDLER(MobileConnection, otastatuschange)
MobileConnection::MobileConnection()
{
@ -406,6 +407,23 @@ MobileConnection::SetCallBarringOption(const JS::Value& aOption,
return mProvider->SetCallBarringOption(GetOwner(), aOption, aRequest);
}
NS_IMETHODIMP
MobileConnection::ChangeCallBarringPassword(const JS::Value& aInfo,
nsIDOMDOMRequest** aRequest)
{
*aRequest = nullptr;
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
if (!mProvider) {
return NS_ERROR_FAILURE;
}
return mProvider->ChangeCallBarringPassword(GetOwner(), aInfo, aRequest);
}
NS_IMETHODIMP
MobileConnection::GetCallWaitingOption(nsIDOMDOMRequest** aRequest)
{
@ -594,3 +612,22 @@ MobileConnection::NotifyEmergencyCbModeChanged(bool aActive,
return DispatchTrustedEvent(ce);
}
NS_IMETHODIMP
MobileConnection::NotifyOtaStatusChanged(const nsAString& aStatus)
{
if (!CheckPermission("mobileconnection")) {
return NS_OK;
}
nsCOMPtr<nsIDOMEvent> event;
NS_NewDOMMozOtaStatusEvent(getter_AddRefs(event), this, nullptr, nullptr);
MOZ_ASSERT(event);
nsCOMPtr<nsIDOMMozOtaStatusEvent> ce = do_QueryInterface(event);
nsresult rv = ce->InitMozOtaStatusEvent(NS_LITERAL_STRING("otastatuschange"),
false, false, aStatus);
NS_ENSURE_SUCCESS(rv, rv);
return DispatchTrustedEvent(ce);
}

View File

@ -16,3 +16,4 @@ disabled = Bug 808783
[test_mobile_roaming_preference.js]
[test_call_barring_get_option.js]
[test_call_barring_set_error.js]
[test_call_barring_change_password.js]

View File

@ -0,0 +1,63 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
SpecialPowers.addPermission("mobileconnection", true, document);
// Permission changes can't change existing Navigator.prototype
// objects, so grab our objects from a new Navigator
let ifr = document.createElement("iframe");
let connection;
ifr.onload = function() {
connection = ifr.contentWindow.navigator.mozMobileConnection;
ok(connection instanceof ifr.contentWindow.MozMobileConnection,
"connection is instanceof " + connection.constructor);
setTimeout(testChangeCallBarringPasswordWithFailure, 0);
};
document.body.appendChild(ifr);
function testChangeCallBarringPasswordWithFailure() {
// Incorrect parameters, expect onerror callback.
let options = [
{pin: null, newPin: '0000'},
{pin: '0000', newPin: null},
{pin: null, newPin: null},
{pin: '000', newPin: '0000'},
{pin: '00000', newPin: '1111'},
{pin: 'abcd', newPin: 'efgh'},
];
function do_test() {
for (let i = 0; i < options.length; i++) {
let request = connection.changeCallBarringPassword(options[i]);
request.onsuccess = function() {
ok(false, 'Unexpected result.');
setTimeout(cleanUp , 0);
};
request.onerror = function() {
ok(request.error.name === 'InvalidPassword', 'InvalidPassword');
if (i >= options.length) {
setTimeout(testChangeCallBarringPasswordWithSuccess, 0);
}
};
}
}
do_test();
}
function testChangeCallBarringPasswordWithSuccess() {
// TODO: Bug 906603 - B2G RIL: Support Change Call Barring Password on
// Emulator.
setTimeout(cleanUp , 0);
}
function cleanUp() {
SpecialPowers.removePermission("mobileconnection", document);
finish();
}

View File

@ -4,7 +4,7 @@ random-if(!haveTestPlugin) != plugin-asyncbitmap-sanity.html about:blank
fails-if(!haveTestPlugin) == plugin-sanity.html div-sanity.html
fails-if(!haveTestPlugin) == plugin-asyncbitmap-sanity.html div-sanity.html
fails-if(!haveTestPlugin) == plugin-asyncdxgi-sanity.html div-sanity.html
skip-if(!haveTestPlugin) == plugin-asyncbitmap-update.html plugin-async-update-ref.html
random-if(OSX==10.6||OSX==10.7) skip-if(!haveTestPlugin) == plugin-asyncbitmap-update.html plugin-async-update-ref.html
random-if(OSX==10.6||OSX==10.7) skip-if(!haveTestPlugin) == plugin-asyncdxgi-update.html plugin-async-update-ref.html
fails-if(!haveTestPlugin) == plugin-alpha-zindex.html div-alpha-zindex.html
fails-if(!haveTestPlugin) == plugin-alpha-opacity.html div-alpha-opacity.html

View File

@ -92,6 +92,7 @@ const RIL_IPC_MSG_NAMES = [
"RIL:GetCallForwardingOption",
"RIL:SetCallBarringOption",
"RIL:GetCallBarringOption",
"RIL:ChangeCallBarringPassword",
"RIL:SetCallWaitingOption",
"RIL:GetCallWaitingOption",
"RIL:SetCallingLineIdRestriction",
@ -109,7 +110,8 @@ const RIL_IPC_MSG_NAMES = [
"RIL:ExitEmergencyCbMode",
"RIL:SetVoicePrivacyMode",
"RIL:GetVoicePrivacyMode",
"RIL:ConferenceCallStateChanged"
"RIL:ConferenceCallStateChanged",
"RIL:OtaStatusChanged"
];
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
@ -1102,6 +1104,31 @@ RILContentHelper.prototype = {
return request;
},
changeCallBarringPassword: function changeCallBarringPassword(window, info) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
// Checking valid PIN for supplementary services. See TS.22.004 clause 5.2.
if (info.pin == null || !info.pin.match(/^\d{4}$/) ||
info.newPin == null || !info.newPin.match(/^\d{4}$/)) {
this.dispatchFireRequestError(requestId, "InvalidPassword");
return request;
}
if (DEBUG) debug("changeCallBarringPassword: " + JSON.stringify(info));
info.requestId = requestId;
cpmm.sendAsyncMessage("RIL:ChangeCallBarringPassword", {
clientId: 0,
data: info
});
return request;
},
getCallWaitingOption: function getCallWaitingOption(window) {
if (window == null) {
throw Components.Exception("Can't get window object",
@ -1531,6 +1558,11 @@ RILContentHelper.prototype = {
"notifyDataChanged",
null);
break;
case "RIL:OtaStatusChanged":
this._deliverEvent("_mobileConnectionListeners",
"notifyOtaStatusChanged",
[msg.json.data]);
break;
case "RIL:EnumerateCalls":
this.handleEnumerateCalls(msg.json.calls);
break;
@ -1658,6 +1690,9 @@ RILContentHelper.prototype = {
case "RIL:SetCallBarringOption":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
break;
case "RIL:ChangeCallBarringPassword":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg, null);
break;
case "RIL:GetCallWaitingOption":
this.handleSimpleRequest(msg.json.requestId, msg.json.errorMsg,
msg.json.enabled);

View File

@ -109,6 +109,7 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [
"RIL:GetCallForwardingOption",
"RIL:SetCallBarringOption",
"RIL:GetCallBarringOption",
"RIL:ChangeCallBarringPassword",
"RIL:SetCallWaitingOption",
"RIL:GetCallWaitingOption",
"RIL:SetCallingLineIdRestriction",
@ -1017,6 +1018,9 @@ RadioInterface.prototype = {
case "RIL:GetCallBarringOption":
this.workerMessenger.sendWithIPCMessage(msg, "queryCallBarringStatus");
break;
case "RIL:ChangeCallBarringPassword":
this.workerMessenger.sendWithIPCMessage(msg, "changeCallBarringPassword");
break;
case "RIL:SetCallWaitingOption":
this.workerMessenger.sendWithIPCMessage(msg, "setCallWaiting");
break;
@ -1100,6 +1104,9 @@ RadioInterface.prototype = {
case "operatorchange":
this.handleOperatorChange(message);
break;
case "otastatuschange":
this.handleOtaStatus(message);
break;
case "radiostatechange":
this.handleRadioStateChange(message);
break;
@ -1457,6 +1464,18 @@ RadioInterface.prototype = {
}
},
handleOtaStatus: function handleOtaStatus(message) {
if (message.status < 0 ||
RIL.CDMA_OTA_PROVISION_STATUS_TO_GECKO.length <= message.status) {
return;
}
let status = RIL.CDMA_OTA_PROVISION_STATUS_TO_GECKO[message.status];
gMessageManager.sendMobileConnectionMessage("RIL:OtaStatusChanged",
this.clientId, status);
},
handleRadioStateChange: function handleRadioStateChange(message) {
this._changingRadioPower = false;

View File

@ -2814,5 +2814,38 @@ this.GECKO_SUPP_SVC_NOTIFICATION_FROM_CODE2 = {};
GECKO_SUPP_SVC_NOTIFICATION_FROM_CODE2[SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD] = GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD;
GECKO_SUPP_SVC_NOTIFICATION_FROM_CODE2[SUPP_SVC_NOTIFICATION_CODE2_RETRIEVED] = GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED;
/**
* The status for an Over-the-Air Service Provisioning / Over-the-Air
* Parameter Administration (OTASP/OTAPA) session.
*
* @see 3GPP2 C.S0016
*/
this.GECKO_OTA_STATUS_SPL_UNLOCKED = "spl_unlocked";
this.GECKO_OTA_STATUS_SPC_RETRIES_EXCEEDED = "spc_retries_exceeded";
this.GECKO_OTA_STATUS_A_KEY_EXCHANGED = "a_key_exchanged";
this.GECKO_OTA_STATUS_SSD_UPDATED = "ssd_updated";
this.GECKO_OTA_STATUS_NAM_DOWNLOADED = "nam_downloaded";
this.GECKO_OTA_STATUS_MDN_DOWNLOADED = "mdn_downloaded";
this.GECKO_OTA_STATUS_IMSI_DOWNLOADED = "imsi_downloaded";
this.GECKO_OTA_STATUS_PRL_DOWNLOADED = "prl_downloaded";
this.GECKO_OTA_STATUS_COMMITTED = "committed";
this.GECKO_OTA_STATUS_OTAPA_STARTED = "otapa_started";
this.GECKO_OTA_STATUS_OTAPA_STOPPED = "otapa_stopped";
this.GECKO_OTA_STATUS_OTAPA_ABORTED = "otapa_aborted";
this.CDMA_OTA_PROVISION_STATUS_TO_GECKO = [
GECKO_OTA_STATUS_SPL_UNLOCKED,
GECKO_OTA_STATUS_SPC_RETRIES_EXCEEDED,
GECKO_OTA_STATUS_A_KEY_EXCHANGED,
GECKO_OTA_STATUS_SSD_UPDATED,
GECKO_OTA_STATUS_NAM_DOWNLOADED,
GECKO_OTA_STATUS_MDN_DOWNLOADED,
GECKO_OTA_STATUS_IMSI_DOWNLOADED,
GECKO_OTA_STATUS_PRL_DOWNLOADED,
GECKO_OTA_STATUS_COMMITTED,
GECKO_OTA_STATUS_OTAPA_STARTED,
GECKO_OTA_STATUS_OTAPA_STOPPED,
GECKO_OTA_STATUS_OTAPA_ABORTED
];
// Allow this file to be imported via Components.utils.import().
this.EXPORTED_SYMBOLS = Object.keys(this);

View File

@ -2327,6 +2327,25 @@ let RIL = {
this.setICCFacilityLock(options);
},
/**
* Change call barring facility password.
*
* @param pin
* Old password.
* @param newPin
* New password.
*/
changeCallBarringPassword: function changeCallBarringPassword(options) {
Buf.newParcel(REQUEST_CHANGE_BARRING_PASSWORD, options);
Buf.writeUint32(3);
// Set facility to ICC_CB_FACILITY_BA_ALL by following TS.22.030 clause
// 6.5.4 and Table B.1.
Buf.writeString(ICC_CB_FACILITY_BA_ALL);
Buf.writeString(options.pin);
Buf.writeString(options.newPin);
Buf.sendParcel();
},
/**
* Handle STK CALL_SET_UP request.
*
@ -5318,7 +5337,13 @@ RIL[REQUEST_SET_FACILITY_LOCK] = function REQUEST_SET_FACILITY_LOCK(length, opti
}
this.sendChromeMessage(options);
};
RIL[REQUEST_CHANGE_BARRING_PASSWORD] = null;
RIL[REQUEST_CHANGE_BARRING_PASSWORD] =
function REQUEST_CHANGE_BARRING_PASSWORD(length, options) {
if (options.rilRequestError) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
}
this.sendChromeMessage(options);
};
RIL[REQUEST_SIM_OPEN_CHANNEL] = function REQUEST_SIM_OPEN_CHANNEL(length, options) {
if (options.rilRequestError) {
options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
@ -6000,7 +6025,11 @@ RIL[UNSOLICITED_CDMA_CALL_WAITING] = function UNSOLICITED_CDMA_CALL_WAITING(leng
this.sendChromeMessage({rilMessageType: "cdmaCallWaiting",
number: call.number});
};
RIL[UNSOLICITED_CDMA_OTA_PROVISION_STATUS] = null;
RIL[UNSOLICITED_CDMA_OTA_PROVISION_STATUS] = function UNSOLICITED_CDMA_OTA_PROVISION_STATUS() {
let status = Buf.readUint32List()[0];
this.sendChromeMessage({rilMessageType: "otastatuschange",
status: status});
};
RIL[UNSOLICITED_CDMA_INFO_REC] = null;
RIL[UNSOLICITED_OEM_HOOK_RAW] = null;
RIL[UNSOLICITED_RINGBACK_TONE] = null;

View File

@ -209,7 +209,7 @@ this.libnetutils = (function () {
let c_dhcp_do_request_renew;
// also changed for 16 and 18
if (sdkVersion >= 18) {
if (sdkVersion >= 18) { // 18 == JB 4.3
dnslistbuf[0] = dns1buf;
dnslistbuf[1] = dns2buf;
c_dhcp_do_request =
@ -236,7 +236,7 @@ this.libnetutils = (function () {
ctypes.int.ptr, // lease
ctypes.char.ptr, // vendorinfo
ctypes.char.ptr); // domain
} else if (sdkVersion >= 16) {
} else if (sdkVersion >= 16) { // 16 == JB 4.1
c_dhcp_do_request =
library.declare("dhcp_do_request", ctypes.default_abi,
ctypes.int, // return value
@ -249,7 +249,7 @@ this.libnetutils = (function () {
ctypes.char.ptr, // server
ctypes.int.ptr, // lease
ctypes.char.ptr); // vendorinfo
} else {
} else { // ICS
c_dhcp_do_request =
library.declare("dhcp_do_request", ctypes.default_abi,
ctypes.int, // return value
@ -337,7 +337,7 @@ this.libnetutils = (function () {
iface.ifc_reset_connections = function(ifname, reset_mask) {
return c_ifc_reset_connections(ifname, reset_mask) | 0;
}
} else {
} else { // version < 15 - we don't care anymore.
let ints = ctypes.int.array(8)();
let c_dhcp_do_request =
library.declare("dhcp_do_request", ctypes.default_abi,

View File

@ -0,0 +1,87 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
function run_test() {
run_next_test();
}
const PIN = "0000";
const NEW_PIN = "1234";
/**
* Helper function.
*/
function newUint8Worker() {
let worker = newWorker();
let index = 0; // index for read
let buf = [];
worker.Buf.writeUint8 = function (value) {
buf.push(value);
};
worker.Buf.readUint8 = function () {
return buf[index++];
};
worker.Buf.seekIncoming = function (offset) {
index += offset;
};
worker.debug = do_print;
return worker;
}
add_test(function test_change_call_barring_password() {
let worker = newUint8Worker();
let buf = worker.Buf;
function do_test(facility, pin, newPin) {
buf.sendParcel = function fakeSendParcel () {
// Request Type.
do_check_eq(this.readUint32(), REQUEST_CHANGE_BARRING_PASSWORD);
// Token : we don't care.
this.readUint32();
let parcel = this.readStringList();
do_check_eq(parcel.length, 3);
do_check_eq(parcel[0], facility);
do_check_eq(parcel[1], pin);
do_check_eq(parcel[2], newPin);
};
let options = {facility: facility, pin: pin, newPin: newPin};
worker.RIL.changeCallBarringPassword(options);
}
do_test(ICC_CB_FACILITY_BA_ALL, PIN, NEW_PIN);
run_next_test();
});
add_test(function test_check_change_call_barring_password_result() {
let barringPasswordOptions;
let worker = newWorker({
postMessage: function fakePostMessage(message) {
do_check_eq(barringPasswordOptions.pin, PIN);
do_check_eq(barringPasswordOptions.newPin, NEW_PIN);
do_check_eq(message.errorMsg, GECKO_ERROR_SUCCESS);
}
});
worker.RIL.changeCallBarringPassword =
function fakeChangeCallBarringPassword(options) {
barringPasswordOptions = options;
worker.RIL[REQUEST_CHANGE_BARRING_PASSWORD](0, {
rilRequestError: ERROR_SUCCESS
});
}
worker.RIL.changeCallBarringPassword({pin: PIN, newPin: NEW_PIN});
run_next_test();
});

View File

@ -17,3 +17,4 @@ tail =
[test_ril_worker_voiceprivacy.js]
[test_ril_worker_ecm.js]
[test_ril_worker_stk.js]
[test_ril_worker_barring_password.js]

View File

@ -5,70 +5,50 @@ function sleep(delay)
while (Date.now() < start + delay);
}
function force_prompt(allow) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
prefs.setBoolPref("geo.prompt.testing", true);
prefs.setBoolPref("geo.prompt.testing.allow", allow);
function force_prompt(allow, callback) {
SpecialPowers.pushPrefEnv({"set": [["geo.prompt.testing", true], ["geo.prompt.testing.allow", allow]]}, callback);
}
function reset_prompt() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
prefs.setBoolPref("geo.prompt.testing", false);
prefs.setBoolPref("geo.prompt.testing.allow", false);
}
function start_sending_garbage()
function start_sending_garbage(callback)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=respond-garbage");
// we need to be sure that all location data has been purged/set.
sleep(1000);
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=respond-garbage"]]}, function() {
// we need to be sure that all location data has been purged/set.
sleep(1000);
callback.call();
});
}
function stop_sending_garbage()
function stop_sending_garbage(callback)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs");
// we need to be sure that all location data has been purged/set.
sleep(1000);
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs"]]}, function() {
// we need to be sure that all location data has been purged/set.
sleep(1000);
callback.call();
});
}
function stop_geolocationProvider()
function stop_geolocationProvider(callback)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=stop-responding");
// we need to be sure that all location data has been purged/set.
sleep(1000);
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=stop-responding"]]}, function() {
// we need to be sure that all location data has been purged/set.
sleep(1000);
callback.call();
});
}
function worse_geolocationProvider()
function worse_geolocationProvider(callback)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=worse-accuracy");
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=worse-accuracy"]]}, callback);
}
function resume_geolocationProvider()
function resume_geolocationProvider(callback)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs");
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs"]]}, callback);
}
function delay_geolocationProvider(delay)
function delay_geolocationProvider(delay, callback)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
prefs.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?delay=" + delay);
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?delay=" + delay]]}, callback);
}
function check_geolocation(location) {

View File

@ -20,17 +20,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478911
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
function successCallback(position) {
check_geolocation(position);
reset_prompt();
SimpleTest.finish();
}
navigator.geolocation.getCurrentPosition(successCallback);
function test1() {
navigator.geolocation.getCurrentPosition(successCallback);
}
</script>
</pre>
</body>

View File

@ -20,20 +20,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478911
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
var watchID;
function successCallback(position) {
check_geolocation(position);
navigator.geolocation.clearWatch(watchID);
reset_prompt();
SimpleTest.finish();
}
watchID = navigator.geolocation.watchPosition(successCallback, null, null);
function test1() {
watchID = navigator.geolocation.watchPosition(successCallback, null, null);
}
</script>
</pre>
</body>

View File

@ -21,13 +21,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=850442
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
function done() {
reset_prompt();
resume_geolocationProvider();
SimpleTest.finish();
resume_geolocationProvider(function() {
SimpleTest.finish();
});
}
function errorCallback(err) {
@ -45,13 +46,13 @@ function testCachedPosition() {
// force use of cached position, make sure
// it's equal to what we have
is(pos, cached, "position should be equal to cached position");
resume_geolocationProvider();
navigator.geolocation.getCurrentPosition(function(pos) {
// force new position, can't be the one we have
isnot(pos, cached, "new position should be different from the cached");
done();
}, errorCallback, {maximumAge: 0});
resume_geolocationProvider(function() {
navigator.geolocation.getCurrentPosition(function(pos) {
// force new position, can't be the one we have
isnot(pos, cached, "new position should be different from the cached");
done();
}, errorCallback, {maximumAge: 0});
});
}, errorCallback, {maximumAge: 21600000});
}, errorCallback, {maximumAge: 21600000});
}
@ -60,20 +61,21 @@ function testCachedPosition() {
// and stop receiving new positions once we do so the
// cache doesn't change
var watchID;
watchID = navigator.geolocation.watchPosition(
function(pos) {
info("Stopping geolocation provider");
stop_geolocationProvider();
}, function(err) {
is(err.code, err.TIMEOUT, "got TIMEOUT for watchPosition");
// no new positions in a while,
// the cache should be stable now.
navigator.geolocation.clearWatch(watchID);
testCachedPosition();
}, {maximumAge: 0, timeout: 1000}
);
function test1() {
watchID = navigator.geolocation.watchPosition(
function(pos) {
info("Stopping geolocation provider");
stop_geolocationProvider(function() {});
}, function(err) {
is(err.code, err.TIMEOUT, "got TIMEOUT for watchPosition");
// no new positions in a while,
// the cache should be stable now.
navigator.geolocation.clearWatch(watchID);
testCachedPosition();
}, {maximumAge: 0, timeout: 1000}
);
}
</script>
</pre>
</body>

View File

@ -20,23 +20,24 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478911
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(false);
resume_geolocationProvider(function() {
force_prompt(false, test1);
});
function failureCallback(error) {
ok(error.code == error.PERMISSION_DENIED, "Ensure that the error was PERMISSION_DENIED");
reset_prompt();
SimpleTest.finish();
}
function successCallback(position){
ok(0, "Success was called when it shouldn't have been. major problem");
reset_prompt();
SimpleTest.finish();
}
navigator.geolocation.getCurrentPosition(successCallback, failureCallback, null);
function test1() {
navigator.geolocation.getCurrentPosition(successCallback, failureCallback, null);
}
</script>
</pre>
</body>

View File

@ -20,25 +20,26 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478911
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(false);
resume_geolocationProvider(function() {
force_prompt(false, test1);
});
var watchID;
function failureCallback(error) {
ok(error.code == error.PERMISSION_DENIED, "Ensure that the error was PERMISSION_DENIED");
reset_prompt();
SimpleTest.finish();
}
function successCallback(position){
ok(0, "Success was called when it shouldn't have been. major problem");
reset_prompt();
SimpleTest.finish();
}
watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null);
function test1() {
watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null);
}
</script>
</pre>
</body>

View File

@ -20,8 +20,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478911
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true)
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
var hasBeenCleared = false;
var successWasCalledAfterClear = false;
@ -56,15 +58,14 @@ function testAccepted() {
ok(true, "testAccepted was called, hasBeenCleared=" + hasBeenCleared +
", successWasCalledAfterClear=" + successWasCalledAfterClear);
ok(!successWasCalledAfterClear, "The successCallback should not be called after clear");
reset_prompt();
SimpleTest.finish();
}
ok(true, "Getting the watchPosition");
watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null);
ok(true, "Waiting");
function test1() {
ok(true, "Getting the watchPosition");
watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null);
ok(true, "Waiting");
}
</script>
</pre>
</body>

View File

@ -18,20 +18,27 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=463039
<pre id="test">
<script class="testbody" type="text/javascript">
resume_geolocationProvider();
force_prompt(true);
navigator.geolocation.watchPosition(function(){});
SimpleTest.waitForExplicitFinish();
// there are no watches, so this should always throw
for (x=-10; x<10; x++) {
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
function test1() {
navigator.geolocation.watchPosition(function(){});
// there are no watches, so this should always throw
for (x=-10; x<10; x++) {
navigator.geolocation.clearWatch(x);
ok(1, "clearWatch should not throw");
}
}
// lets try something huge
navigator.geolocation.clearWatch(Number.MAX_VALUE);
ok(1, "clearWatch should not throw");
reset_prompt();
// lets try something huge
navigator.geolocation.clearWatch(Number.MAX_VALUE);
ok(1, "clearWatch should not throw");
SimpleTest.finish();
}
</script>
</pre>

View File

@ -21,35 +21,35 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=482260
/** Test for Bug **/
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
start_sending_garbage();
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
function test1() {
start_sending_garbage(test2);
}
function successCallback(pos){
ok(false, "success should have never been called.");
stop_sending_garbage();
reset_prompt();
SimpleTest.finish();
stop_sending_garbage(function() {SimpleTest.finish();});
}
function errorCallback(err) {
ok(err.code == err.TIMEOUT, "ensure error is a timeout.");
stop_sending_garbage();
reset_prompt();
SimpleTest.finish();
stop_sending_garbage(function() { SimpleTest.finish(); });
}
var options = {
maximumAge: 0,
timeout: 1000,
};
navigator.geolocation.watchPosition(successCallback,
errorCallback,
options);
function test2() {
navigator.geolocation.watchPosition(successCallback,
errorCallback,
options);
}
</script>
</pre>
</body>

View File

@ -20,8 +20,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=482260
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
var successCallbackCalled = 0;
var failureCallbackCalled = 0;
@ -37,14 +39,15 @@ function failureCallback(code) {
testPassed();
}
for (var x = 0; x < totalResults; x++)
navigator.geolocation.getCurrentPosition(successCallback, failureCallback);
function test1() {
for (var x = 0; x < totalResults; x++)
navigator.geolocation.getCurrentPosition(successCallback, failureCallback);
}
function testPassed() {
if (successCallbackCalled + failureCallbackCalled != totalResults)
return;
is(failureCallbackCalled, 0, "no failure callbacks should have been received");
reset_prompt();
SimpleTest.finish();
}

View File

@ -21,8 +21,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=482260
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true)
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
var keepGoing = 10;
@ -33,12 +34,12 @@ function successCallback(position) {
}
ok(1, "100 successful calls");
reset_prompt();
SimpleTest.finish();
}
navigator.geolocation.getCurrentPosition(successCallback);
function test1() {
navigator.geolocation.getCurrentPosition(successCallback);
}
</script>
</pre>
</body>

View File

@ -20,8 +20,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=482260
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
var successCallbackCalled = 0;
var failureCallbackCalled = 0;
@ -37,14 +39,15 @@ function failureCallback(code) {
testPassed();
}
for (var x = 0; x < totalResults; x++)
navigator.geolocation.watchPosition(successCallback, failureCallback);
function test1() {
for (var x = 0; x < totalResults; x++)
navigator.geolocation.watchPosition(successCallback, failureCallback);
}
function testPassed() {
if (successCallbackCalled + failureCallbackCalled != totalResults)
return;
is(failureCallbackCalled, 0, "no failure callbacks should have been received");
reset_prompt();
SimpleTest.finish();
}

View File

@ -20,8 +20,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=482260
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
var watchID = 0;
var completeCount = 10;
@ -35,7 +37,6 @@ function successCallback(position) {
if (completeCount==0) {
ok(1, "all watchPosition successCallbacks called");
reset_prompt();
SimpleTest.finish();
return;
}
@ -43,8 +44,9 @@ function successCallback(position) {
watchID = navigator.geolocation.watchPosition(successCallback);
}
watchID = navigator.geolocation.watchPosition(successCallback);
function test1() {
watchID = navigator.geolocation.watchPosition(successCallback);
}
</script>
</pre>
</body>

View File

@ -21,8 +21,9 @@ href="https://bugzilla.mozilla.org/show_bug.cgi?id=478911">Crash in Multiple Win
<script class="testbody" type="text/javascript">
// ensure we are using the right testing provider
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
/** Test for Bug **/
@ -38,8 +39,10 @@ addEventListener("message", function() {
}
}, false);
for(var i = 0; i < numberOfWindows; i++) {
windows[i] = window.open("geolocation.html", "_blank", "width=700,height=400");
function test1() {
for(var i = 0; i < numberOfWindows; i++) {
windows[i] = window.open("geolocation.html", "_blank", "width=700,height=400");
}
}
function closeWindows()
@ -55,7 +58,6 @@ SimpleTest.waitForExplicitFinish();
function done()
{
ok(navigator.geolocation, "Opened a bunch of windows and didn't crash.");
reset_prompt();
SimpleTest.finish();
}

View File

@ -20,25 +20,31 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478911
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
if (SpecialPowers.isMainProcess()) {
SpecialPowers.Cu.import("resource://gre/modules/SettingsChangeNotifier.jsm");
}
SpecialPowers.addPermission("settings-read", true, document);
SpecialPowers.addPermission("settings-write", true, document);
function test1() {
//This pushPermissions call is after pushPrefEnv call and pushPrefEnv calls follow after this
SpecialPowers.pushPermissions([{'type': 'settings-read', 'allow': true, 'context': document}, {'type': 'settings-write', 'allow': true, 'context': document}], test2);
}
ok(navigator.geolocation, "get geolocation object");
function test2() {
ok(navigator.geolocation, "get geolocation object");
toggleGeolocationSetting(false, function() {
ok(true, "turned off geolocation via mozSettings");
setTimeout(function() {
navigator.geolocation.getCurrentPosition(successCallbackAfterMozsettingOff,
failureCallbackAfterMozsettingOff);
}, 500); // need to wait a bit for all of these async callbacks to finish
toggleGeolocationSetting(false, function() {
ok(true, "turned off geolocation via mozSettings");
setTimeout(function() {
navigator.geolocation.getCurrentPosition(successCallbackAfterMozsettingOff,
failureCallbackAfterMozsettingOff);
}, 500); // need to wait a bit for all of these async callbacks to finish
});
}
function successCallbackAfterMozsettingOff(position) {
ok(false, "Success callback should not have been called after setting geolocation.enabled to false.");
@ -66,15 +72,11 @@ function failureCallbackAfterMozsettingOff(error) {
function successCallbackAfterMozsettingOn(position) {
ok(true, "Geolocation worked after setting geolocation.enabled to true.");
reset_prompt();
SimpleTest.finish();
}
function failureCallbackAfterMozsettingOn(error) {
ok(false, "Geolocation didn't work after setting geolocation.enabled to true.");
reset_prompt();
SimpleTest.finish();
}

View File

@ -20,26 +20,32 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=478911
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
if (SpecialPowers.isMainProcess()) {
SpecialPowers.Cu.import("resource://gre/modules/SettingsChangeNotifier.jsm");
}
SpecialPowers.addPermission("settings-read", true, document);
SpecialPowers.addPermission("settings-write", true, document);
ok(navigator.geolocation, "get geolocation object");
function test1() {
//This pushPermissions call is after pushPrefEnv call and pushPrefEnv calls follow after this
SpecialPowers.pushPermissions([{'type': 'settings-read', 'allow': true, 'context': document}, {'type': 'settings-write', 'allow': true, 'context': document}], test2);
}
var watchId;
toggleGeolocationSetting(false, function() {
ok(true, "turned off geolocation via mozSettings");
setTimeout(function() {
watchId = navigator.geolocation.watchPosition(successCallbackAfterMozsettingOff,
failureCallbackAfterMozsettingOff);
function test2() {
ok(navigator.geolocation, "get geolocation object");
toggleGeolocationSetting(false, function() {
ok(true, "turned off geolocation via mozSettings");
setTimeout(function() {
watchId = navigator.geolocation.watchPosition(successCallbackAfterMozsettingOff,
failureCallbackAfterMozsettingOff);
}, 500); // need to wait a bit for all of these async callbacks to finish
});
}
function successCallbackAfterMozsettingOff(position) {
ok(false, "Success callback should not have been called after setting geolocation.enabled to false.");
@ -71,7 +77,6 @@ function successCallbackAfterMozsettingOn(position) {
ok(true, "Geolocation worked after setting geolocation.enabled to true.");
navigator.geolocation.clearWatch(watchId);
reset_prompt();
SimpleTest.finish();
}
@ -79,7 +84,6 @@ function failureCallbackAfterMozsettingOn(error) {
ok(false, "Geolocation didn't work after setting geolocation.enabled to true.");
navigator.geolocation.clearWatch(watchId);
reset_prompt();
SimpleTest.finish();
}

View File

@ -18,80 +18,83 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452566
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
// ensure we are using the right testing provider
resume_geolocationProvider();
force_prompt(true)
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
/** Test for Bug 452566 **/
function test1() {
ok(navigator.geolocation, "Should have geolocation");
ok(navigator.geolocation, "Should have geolocation");
var exception = null;
try {
navigator.geolocation.getCurrentPosition();
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(exception, "Should have got an exception");
var exception = null;
try {
navigator.geolocation.getCurrentPosition();
} catch(ex if ex instanceof TypeError) {
exception = ex;
exception = null;
try {
navigator.geolocation.getCurrentPosition(function() {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
exception = null;
try {
navigator.geolocation.getCurrentPosition(function() {}, function() {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
exception = null;
try {
navigator.geolocation.getCurrentPosition(function() {}, function() {}, {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
exception = null;
try {
navigator.geolocation.watchPosition();
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(exception, "Should have got an exception");
exception = null;
try {
navigator.geolocation.watchPosition(function() {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
exception = null;
try {
navigator.geolocation.watchPosition(function() {}, function() {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
exception = null;
try {
navigator.geolocation.watchPosition(function() {}, function() {}, {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
SimpleTest.finish();
}
ok(exception, "Should have got an exception");
exception = null;
try {
navigator.geolocation.getCurrentPosition(function() {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
exception = null;
try {
navigator.geolocation.getCurrentPosition(function() {}, function() {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
exception = null;
try {
navigator.geolocation.getCurrentPosition(function() {}, function() {}, {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
exception = null;
try {
navigator.geolocation.watchPosition();
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(exception, "Should have got an exception");
exception = null;
try {
navigator.geolocation.watchPosition(function() {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
exception = null;
try {
navigator.geolocation.watchPosition(function() {}, function() {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
exception = null;
try {
navigator.geolocation.watchPosition(function() {}, function() {}, {});
} catch(ex if ex instanceof TypeError) {
exception = ex;
}
ok(!exception, exception);
// so clean up ready for the next test.
reset_prompt();
</script>
</pre>

View File

@ -21,16 +21,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=716127
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
function successCallback(position) {
check_geolocation(position);
SpecialPowers.pushPrefEnv({'set': [['geo.timeout', 100]]}, function() {
delay_geolocationProvider(1000);
force_prompt(true);
navigator.geolocation.getCurrentPosition(success2, handle_error, {maximumAge: 0});
delay_geolocationProvider(1000, function() {
force_prompt(true, function() {
navigator.geolocation.getCurrentPosition(success2, handle_error, {maximumAge: 0});
});
});
});
}
@ -39,11 +43,12 @@ function errorCallback() {
SimpleTest.finish();
}
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
function test1() {
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
}
function success2(position) {
check_geolocation(position);
reset_prompt();
SimpleTest.finish();
}

View File

@ -21,18 +21,21 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=455327
/** Test for Bug **/
// ensure we are using the right testing provider
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
SimpleTest.waitForExplicitFinish();
stop_geolocationProvider();
function test1() {
stop_geolocationProvider(test2);
}
function successCallback(pos){
ok(false, "success should have never been called.");
resume_geolocationProvider();
reset_prompt()
SimpleTest.finish();
resume_geolocationProvider(function() {
SimpleTest.finish();
});
}
function errorCallback(err) {
@ -40,9 +43,9 @@ function errorCallback(err) {
ok(false, "nothing is hooked up to test against.");
else
ok(err.code == err.TIMEOUT, "ensure error is a timeout.");
resume_geolocationProvider();
reset_prompt()
SimpleTest.finish();
resume_geolocationProvider(function() {
SimpleTest.finish();
});
}
@ -51,9 +54,11 @@ var options = {
timeout: 10
};
navigator.geolocation.watchPosition(successCallback,
errorCallback,
options);
function test2() {
navigator.geolocation.watchPosition(successCallback,
errorCallback,
options);
}
</script>
</pre>
</body>

View File

@ -22,8 +22,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=526326
SimpleTest.waitForExplicitFinish();
// ensure we are using the right testing provider
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
var watchID;
var times = 0;
@ -35,16 +36,16 @@ function errorCallback(err) {
// make sure we got at least 3 times errorCallback
if (times >= 3) {
navigator.geolocation.clearWatch(watchID);
resume_geolocationProvider();
reset_prompt();
SimpleTest.finish();
resume_geolocationProvider(function() {
SimpleTest.finish();
});
}
}
function successCallback(position) {
// Now that we got a success callback, lets try to ensure
// that we get a timeout error.
stop_geolocationProvider();
stop_geolocationProvider(function() {});
}
var options = {
@ -52,8 +53,9 @@ var options = {
timeout: 1000
};
watchID = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
function test1() {
watchID = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
}
</script>
</pre>
</body>

View File

@ -22,13 +22,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=493615
function done() {
ok(1, "no crash, so pass.");
SimpleTest.finish();
reset_prompt();
}
SimpleTest.waitForExplicitFinish();
force_prompt(true);
window.open("windowTest.html");
force_prompt(true, function() {
window.open("windowTest.html");
});
</script>
</pre>

View File

@ -20,23 +20,26 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=494924
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
resume_geolocationProvider();
force_prompt(true);
resume_geolocationProvider(function() {
force_prompt(true, test1);
});
function successCallback2(position) {
check_geolocation(position);
reset_prompt();
SimpleTest.finish();
}
function successCallback1(position) {
check_geolocation(position);
worse_geolocationProvider();
navigator.geolocation.getCurrentPosition(successCallback2, null, { maximumAge: 0 });
worse_geolocationProvider(function() {
navigator.geolocation.getCurrentPosition(successCallback2, null, { maximumAge: 0 });
});
}
navigator.geolocation.getCurrentPosition(successCallback1, null, { maximumAge: 0 });
function test1() {
navigator.geolocation.getCurrentPosition(successCallback1, null, { maximumAge: 0 });
}
</script>
</pre>
</body>

View File

@ -23,6 +23,8 @@ interface DummyInterface {
void MmsAttachment(optional MmsAttachment arg);
void AsyncScrollEventDetail(optional AsyncScrollEventDetail arg);
void OpenWindowEventDetail(optional OpenWindowEventDetail arg);
void WifiOptions(optional WifiCommandOptions arg1,
optional WifiResultOptions arg2);
};
interface DummyInterfaceWorkers {

View File

@ -58,31 +58,26 @@ interface MozInputMethodManager {
[JSImplementation="@mozilla.org/b2g-inputcontext;1"]
interface MozInputContext: EventTarget {
// The tag name of input field, which is enum of "input", "textarea", or "contenteditable"
readonly attribute DOMString type;
readonly attribute DOMString? type;
// The type of the input field, which is enum of text, number, password, url, search, email, and so on.
// See http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#states-of-the-type-attribute
readonly attribute DOMString inputType;
readonly attribute DOMString? inputType;
/*
* The inputmode string, representing the input mode.
* See http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#input-modalities:-the-inputmode-attribute
*/
readonly attribute DOMString inputMode;
readonly attribute DOMString? inputMode;
/*
* The primary language for the input field.
* It is the value of HTMLElement.lang.
* See http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#htmlelement
*/
readonly attribute DOMString lang;
readonly attribute DOMString? lang;
/*
* Get the whole text content of the input field.
* @return DOMString
*/
Promise getText(optional long offset, optional long length);
// The start and stop position of the selection.
readonly attribute long selectionStart;
readonly attribute long selectionEnd;

View File

@ -0,0 +1,33 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[Constructor(DOMString type, optional MozOtaStatusEventInit eventInitDict),
HeaderFile="GeneratedEventClasses.h"]
interface MozOtaStatusEvent : Event
{
/**
* One of the following values:
*
* spl_unlocked
* spc_retries_exceeded
* a_key_exchanged
* ssd_updated
* nam_downloaded
* mdn_downloaded
* imsi_downloaded
* prl_downloaded
* committed
* otapa_started
* otapa_stopped
* otapa_aborted
*/
readonly attribute DOMString status;
};
dictionary MozOtaStatusEventInit : EventInit
{
DOMString status = "";
};

View File

@ -384,6 +384,7 @@ webidl_files = \
WebComponents.webidl \
WebSocket.webidl \
WheelEvent.webidl \
WifiOptions.webidl \
Window.webidl \
WorkerLocation.webidl \
WorkerNavigator.webidl \
@ -498,6 +499,7 @@ webidl_files += \
MozCellBroadcast.webidl \
MozCellBroadcastEvent.webidl \
MozEmergencyCbModeEvent.webidl \
MozOtaStatusEvent.webidl \
MozVoicemailEvent.webidl \
MozWifiConnectionInfoEvent.webidl \
MozWifiStatusChangeEvent.webidl \

View File

@ -0,0 +1,59 @@
/* 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 dictionnary holds the parameters sent to the wifi service.
*/
dictionary WifiCommandOptions
{
long id = 0; // opaque id.
DOMString cmd = ""; // the command name.
DOMString request; // for "command"
DOMString ifname; // for "ifc_reset_connections", "ifc_enable",
// "ifc_disable", "ifc_remove_host_routes",
// "ifc_remove_default_route", "dhcp_stop",
// "dhcp_release_lease", "ifc_get_default_route",
// "ifc_add_host_route", "ifc_set_default_route",
// "ifc_configure", "dhcp_do_request",
// "dhcp_do_request_renew".
long route; // for "ifc_add_host_route", "ifc_set_default_route".
long ipaddr; // for "ifc_configure".
long mask; // for "ifc_configure".
long gateway; // for "ifc_configure".
long dns1; // for "ifc_configure".
long dns2; // for "ifc_configure".
DOMString key; // for "property_get", "property_set".
DOMString value; // for "property_set".
DOMString defaultValue; // for "property_get".
};
/**
* This dictionnary holds the parameters sent back to WifiWorker.js
*/
dictionary WifiResultOptions
{
long id = 0; // opaque id.
long status = 0; // the return status of the command.
// Used by most commands.
DOMString reply = ""; // for "command".
DOMString route = ""; // for "ifc_get_default_route".
DOMString error = ""; // for "dhcp_get_errmsg".
DOMString value = ""; // for "property_get".
DOMString ipaddr_str = ""; // The following are for the result of
// dhcp_do_request.
DOMString gateway_str = "";
DOMString broadcast_str = "";
DOMString dns1_str = "";
DOMString dns2_str = "";
DOMString mask_str = "";
DOMString server_str = "";
DOMString vendor_str = "";
long lease = 0;
long mask = 0;
long ipaddr = 0;
long gateway = 0;
long dns1 = 0;
long dns2 = 0;
long server = 0;
};

View File

@ -10,6 +10,8 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = domwifi_s
EXPORT_LIBRARY = 1
include $(topsrcdir)/dom/dom-config.mk
include $(topsrcdir)/config/rules.mk

139
dom/wifi/NetUtils.cpp Normal file
View File

@ -0,0 +1,139 @@
/* 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 "NetUtils.h"
#include <dlfcn.h>
#include <errno.h>
#include <cutils/properties.h>
#include "prinit.h"
#include "mozilla/Assertions.h"
#include "nsDebug.h"
static void* sNetUtilsLib;
static PRCallOnceType sInitNetUtilsLib;
static PRStatus
InitNetUtilsLib()
{
sNetUtilsLib = dlopen("/system/lib/libnetutils.so", RTLD_LAZY);
// We might fail to open the hardware lib. That's OK.
return PR_SUCCESS;
}
static void*
GetNetUtilsLibHandle()
{
PR_CallOnce(&sInitNetUtilsLib, InitNetUtilsLib);
return sNetUtilsLib;
}
// static
void*
NetUtils::GetSharedLibrary()
{
void* netLib = GetNetUtilsLibHandle();
if (!netLib) {
NS_WARNING("No /system/lib/libnetutils.so");
}
return netLib;
}
// static
int32_t
NetUtils::SdkVersion()
{
char propVersion[PROPERTY_VALUE_MAX];
property_get("ro.build.version.sdk", propVersion, "0");
int32_t version = strtol(propVersion, nullptr, 10);
return version;
}
DEFINE_DLFUNC(ifc_enable, int32_t, const char*)
DEFINE_DLFUNC(ifc_disable, int32_t, const char*)
DEFINE_DLFUNC(ifc_configure, int32_t, const char*, in_addr_t, uint32_t,
in_addr_t, in_addr_t, in_addr_t)
DEFINE_DLFUNC(ifc_reset_connections, int32_t, const char*, const int32_t)
DEFINE_DLFUNC(dhcp_stop, int32_t, const char*)
int32_t NetUtils::do_ifc_enable(const char *ifname)
{
USE_DLFUNC(ifc_enable)
return ifc_enable(ifname);
}
int32_t NetUtils::do_ifc_disable(const char *ifname)
{
USE_DLFUNC(ifc_disable)
return ifc_disable(ifname);
}
int32_t NetUtils::do_ifc_configure(const char *ifname,
in_addr_t address,
uint32_t prefixLength,
in_addr_t gateway,
in_addr_t dns1,
in_addr_t dns2)
{
USE_DLFUNC(ifc_configure)
int32_t ret = ifc_configure(ifname, address, prefixLength, gateway, dns1, dns2);
return ret;
}
int32_t NetUtils::do_ifc_reset_connections(const char *ifname,
const int32_t resetMask)
{
USE_DLFUNC(ifc_reset_connections)
return ifc_reset_connections(ifname, resetMask);
}
int32_t NetUtils::do_dhcp_stop(const char *ifname)
{
USE_DLFUNC(dhcp_stop)
return dhcp_stop(ifname);
}
int32_t NetUtils::do_dhcp_do_request(const char *ifname,
char *ipaddr,
char *gateway,
uint32_t *prefixLength,
char *dns1,
char *dns2,
char *server,
uint32_t *lease,
char* vendorinfo)
{
int32_t ret = -1;
uint32_t sdkVersion = SdkVersion();
if (sdkVersion == 15) {
// ICS
// http://androidxref.com/4.0.4/xref/system/core/libnetutils/dhcp_utils.c#149
DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char*, char*, char*, uint32_t*)
USE_DLFUNC(dhcp_do_request)
vendorinfo[0] = '\0';
ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns1, dns2,
server, lease);
} else if (sdkVersion == 16 || sdkVersion == 17) {
// JB 4.1 and 4.2
// http://androidxref.com/4.1.2/xref/system/core/libnetutils/dhcp_utils.c#175
// http://androidxref.com/4.2.2_r1/xref/system/core/include/netutils/dhcp.h#26
DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char*, char*, char*, uint32_t*, char*)
USE_DLFUNC(dhcp_do_request)
ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns1, dns2,
server, lease, vendorinfo);
} else if (sdkVersion == 18) {
// JB 4.3
// http://androidxref.com/4.3_r2.1/xref/system/core/libnetutils/dhcp_utils.c#181
DEFINE_DLFUNC(dhcp_do_request, int32_t, const char*, char*, char*, uint32_t*, char**, char*, uint32_t*, char*, char*)
USE_DLFUNC(dhcp_do_request)
char *dns[3] = {dns1, dns2, NULL};
char domains[PROPERTY_VALUE_MAX];
ret = dhcp_do_request(ifname, ipaddr, gateway, prefixLength, dns,
server, lease, vendorinfo, domains);
} else {
NS_WARNING("Unable to perform do_dhcp_request: unsupported sdk version!");
}
return ret;
}

60
dom/wifi/NetUtils.h Normal file
View File

@ -0,0 +1,60 @@
/* 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/. */
/**
* Abstraction on top of the network support from libnetutils that we
* use to set up network connections.
*/
#ifndef NetUtils_h
#define NetUtils_h
#include "arpa/inet.h"
// Copied from ifc.h
#define RESET_IPV4_ADDRESSES 0x01
#define RESET_IPV6_ADDRESSES 0x02
#define RESET_ALL_ADDRESSES (RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES)
// Implements netutils functions. No need for an abstract class here since we
// only have a one sdk specific method (dhcp_do_request)
class NetUtils
{
public:
static void* GetSharedLibrary();
int32_t do_ifc_enable(const char *ifname);
int32_t do_ifc_disable(const char *ifname);
int32_t do_ifc_configure(const char *ifname,
in_addr_t address,
uint32_t prefixLength,
in_addr_t gateway,
in_addr_t dns1,
in_addr_t dns2);
int32_t do_ifc_reset_connections(const char *ifname, const int32_t resetMask);
int32_t do_dhcp_stop(const char *ifname);
int32_t do_dhcp_do_request(const char *ifname,
char *ipaddr,
char *gateway,
uint32_t *prefixLength,
char *dns1,
char *dns2,
char *server,
uint32_t *lease,
char* vendorinfo);
static int32_t SdkVersion();
};
// Defines a function type with the right arguments and return type.
#define DEFINE_DLFUNC(name, ret, args...) typedef ret (*FUNC##name)(args);
// Set up a dlsymed function ready to use.
#define USE_DLFUNC(name) \
FUNC##name name = (FUNC##name) dlsym(GetSharedLibrary(), #name); \
if (!name) { \
MOZ_ASSERT("Symbol not found in shared library : " #name); \
}
#endif // NetUtils_h

View File

@ -0,0 +1,286 @@
/* 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 "WifiProxyService.h"
#include "nsServiceManagerUtils.h"
#include "mozilla/ModuleUtils.h"
#include "mozilla/ClearOnShutdown.h"
#include "nsXULAppAPI.h"
#include "WifiUtils.h"
#include "jsapi.h"
#include "nsCxPusher.h"
#define NS_WIFIPROXYSERVICE_CID \
{ 0xc6c9be7e, 0x744f, 0x4222, {0xb2, 0x03, 0xcd, 0x55, 0xdf, 0xc8, 0xbc, 0x12} }
using namespace mozilla;
using namespace mozilla::dom;
namespace mozilla {
// The singleton Wifi service, to be used on the main thread.
StaticRefPtr<WifiProxyService> gWifiProxyService;
// The singleton supplicant class, that can be used on any thread.
static nsAutoPtr<WpaSupplicant> gWpaSupplicant;
// Runnable used dispatch the WaitForEvent result on the main thread.
class WifiEventDispatcher : public nsRunnable
{
public:
WifiEventDispatcher(nsAString& aEvent): mEvent(aEvent)
{
MOZ_ASSERT(!NS_IsMainThread());
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
gWifiProxyService->DispatchWifiEvent(mEvent);
return NS_OK;
}
private:
nsString mEvent;
};
// Runnable used to call WaitForEvent on the event thread.
class EventRunnable : public nsRunnable
{
public:
EventRunnable()
{
MOZ_ASSERT(NS_IsMainThread());
}
NS_IMETHOD Run()
{
MOZ_ASSERT(!NS_IsMainThread());
nsAutoString event;
gWpaSupplicant->WaitForEvent(event);
if (!event.IsEmpty()) {
nsCOMPtr<nsIRunnable> runnable = new WifiEventDispatcher(event);
NS_DispatchToMainThread(runnable);
}
return NS_OK;
}
};
// Runnable used dispatch the Command result on the main thread.
class WifiResultDispatcher : public nsRunnable
{
public:
WifiResultDispatcher(WifiResultOptions& aResult)
{
MOZ_ASSERT(!NS_IsMainThread());
// XXX: is there a better way to copy webidl dictionnaries?
// the copy constructor is private.
#define COPY_FIELD(prop) mResult.prop = aResult.prop;
COPY_FIELD(mId)
COPY_FIELD(mStatus)
COPY_FIELD(mReply)
COPY_FIELD(mRoute)
COPY_FIELD(mError)
COPY_FIELD(mValue)
COPY_FIELD(mIpaddr_str)
COPY_FIELD(mGateway_str)
COPY_FIELD(mBroadcast_str)
COPY_FIELD(mDns1_str)
COPY_FIELD(mDns2_str)
COPY_FIELD(mMask_str)
COPY_FIELD(mServer_str)
COPY_FIELD(mVendor_str)
COPY_FIELD(mLease)
COPY_FIELD(mMask)
COPY_FIELD(mIpaddr)
COPY_FIELD(mGateway)
COPY_FIELD(mDns1)
COPY_FIELD(mDns2)
COPY_FIELD(mServer)
#undef COPY_FIELD
}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
gWifiProxyService->DispatchWifiResult(mResult);
return NS_OK;
}
private:
WifiResultOptions mResult;
};
// Runnable used to call SendCommand on the control thread.
class ControlRunnable : public nsRunnable
{
public:
ControlRunnable(CommandOptions aOptions) : mOptions(aOptions) {
MOZ_ASSERT(!NS_IsMainThread());
}
NS_IMETHOD Run()
{
WifiResultOptions result;
if (gWpaSupplicant->ExecuteCommand(mOptions, result)) {
nsCOMPtr<nsIRunnable> runnable = new WifiResultDispatcher(result);
NS_DispatchToMainThread(runnable);
}
return NS_OK;
}
private:
CommandOptions mOptions;
};
NS_IMPL_ISUPPORTS1(WifiProxyService, nsIWifiProxyService)
WifiProxyService::WifiProxyService()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!gWifiProxyService);
}
WifiProxyService::~WifiProxyService()
{
MOZ_ASSERT(!gWifiProxyService);
}
already_AddRefed<WifiProxyService>
WifiProxyService::FactoryCreate()
{
if (XRE_GetProcessType() != GeckoProcessType_Default) {
return nullptr;
}
MOZ_ASSERT(NS_IsMainThread());
if (!gWifiProxyService) {
gWifiProxyService = new WifiProxyService();
ClearOnShutdown(&gWifiProxyService);
gWpaSupplicant = new WpaSupplicant();
ClearOnShutdown(&gWpaSupplicant);
}
nsRefPtr<WifiProxyService> service = gWifiProxyService.get();
return service.forget();
}
NS_IMETHODIMP
WifiProxyService::Start(nsIWifiEventListener* aListener)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aListener);
nsresult rv = NS_NewThread(getter_AddRefs(mEventThread));
if (NS_FAILED(rv)) {
NS_WARNING("Can't create wifi event thread");
return NS_ERROR_FAILURE;
}
rv = NS_NewThread(getter_AddRefs(mControlThread));
if (NS_FAILED(rv)) {
NS_WARNING("Can't create wifi control thread");
// Shutdown the event thread.
mEventThread->Shutdown();
mEventThread = nullptr;
return NS_ERROR_FAILURE;
}
mListener = aListener;
return NS_OK;
}
NS_IMETHODIMP
WifiProxyService::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
mEventThread->Shutdown();
mEventThread = nullptr;
mControlThread->Shutdown();
mControlThread = nullptr;
return NS_OK;
}
NS_IMETHODIMP
WifiProxyService::SendCommand(const JS::Value& aOptions, JSContext* aCx)
{
MOZ_ASSERT(NS_IsMainThread());
WifiCommandOptions options;
if (!options.Init(aCx,
JS::Handle<JS::Value>::fromMarkedLocation(&aOptions))) {
NS_WARNING("Bad dictionary passed to WifiProxyService::SendCommand");
return NS_ERROR_FAILURE;
}
// Dispatch the command to the control thread.
CommandOptions commandOptions(options);
nsCOMPtr<nsIRunnable> runnable = new ControlRunnable(commandOptions);
mControlThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
return NS_OK;
}
NS_IMETHODIMP
WifiProxyService::WaitForEvent()
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIRunnable> runnable = new EventRunnable();
mEventThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
return NS_OK;
}
void
WifiProxyService::DispatchWifiResult(const WifiResultOptions& aOptions)
{
MOZ_ASSERT(NS_IsMainThread());
mozilla::AutoSafeJSContext cx;
JS::RootedValue val(cx);
if (!aOptions.ToObject(cx, JS::NullPtr(), &val)) {
return;
}
// Call the listener with a JS value.
mListener->OnCommand(val);
}
void
WifiProxyService::DispatchWifiEvent(const nsAString& aEvent)
{
MOZ_ASSERT(NS_IsMainThread());
// Call the listener.
mListener->OnWaitEvent(aEvent);
}
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WifiProxyService,
WifiProxyService::FactoryCreate)
NS_DEFINE_NAMED_CID(NS_WIFIPROXYSERVICE_CID);
static const mozilla::Module::CIDEntry kWifiProxyServiceCIDs[] = {
{ &kNS_WIFIPROXYSERVICE_CID, false, nullptr, WifiProxyServiceConstructor },
{ nullptr }
};
static const mozilla::Module::ContractIDEntry kWifiProxyServiceContracts[] = {
{ "@mozilla.org/wifi/service;1", &kNS_WIFIPROXYSERVICE_CID },
{ nullptr }
};
static const mozilla::Module kWifiProxyServiceModule = {
mozilla::Module::kVersion,
kWifiProxyServiceCIDs,
kWifiProxyServiceContracts,
nullptr
};
} // namespace mozilla
NSMODULE_DEFN(WifiProxyServiceModule) = &kWifiProxyServiceModule;

View File

@ -0,0 +1,38 @@
/* 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 WifiProxyService_h
#define WifiProxyService_h
#include "nsIWifiService.h"
#include "nsCOMPtr.h"
#include "nsThread.h"
#include "mozilla/dom/WifiOptionsBinding.h"
namespace mozilla {
class WifiProxyService MOZ_FINAL : public nsIWifiProxyService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIWIFIPROXYSERVICE
static already_AddRefed<WifiProxyService>
FactoryCreate();
void DispatchWifiEvent(const nsAString& aEvent);
void DispatchWifiResult(const mozilla::dom::WifiResultOptions& aOptions);
private:
WifiProxyService();
~WifiProxyService();
nsCOMPtr<nsIThread> mEventThread;
nsCOMPtr<nsIThread> mControlThread;
nsCOMPtr<nsIWifiEventListener> mListener;
};
} // namespace mozilla
#endif // WifiProxyService_h

382
dom/wifi/WifiUtils.cpp Normal file
View File

@ -0,0 +1,382 @@
/* 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 "WifiUtils.h"
#include <dlfcn.h>
#include <errno.h>
#include "prinit.h"
#include "js/CharacterEncoding.h"
#include "NetUtils.h"
using namespace mozilla::dom;
#define BUFFER_SIZE 4096
#define PROPERTY_VALUE_MAX 80
// Intentionally not trying to dlclose() this handle. That's playing
// Russian roulette with security bugs.
static void* sWifiLib;
static PRCallOnceType sInitWifiLib;
static PRStatus
InitWifiLib()
{
sWifiLib = dlopen("/system/lib/libhardware_legacy.so", RTLD_LAZY);
// We might fail to open the hardware lib. That's OK.
return PR_SUCCESS;
}
static void*
GetSharedLibrary()
{
PR_CallOnce(&sInitWifiLib, InitWifiLib);
return sWifiLib;
}
// This is the same algorithm as in InflateUTF8StringToBuffer with Copy and
// while ignoring invalids.
// https://mxr.mozilla.org/mozilla-central/source/js/src/vm/CharacterEncoding.cpp#231
static const uint32_t REPLACE_UTF8 = 0xFFFD;
void LossyConvertUTF8toUTF16(const char* aInput, uint32_t aLength, nsAString& aOut)
{
JS::UTF8Chars src(aInput, aLength);
PRUnichar dst[aLength]; // Allocating for worst case.
// First, count how many jschars need to be in the inflated string.
// |i| is the index into |src|, and |j| is the the index into |dst|.
size_t srclen = src.length();
uint32_t j = 0;
for (uint32_t i = 0; i < srclen; i++, j++) {
uint32_t v = uint32_t(src[i]);
if (!(v & 0x80)) {
// ASCII code unit. Simple copy.
dst[j] = PRUnichar(v);
} else {
// Non-ASCII code unit. Determine its length in bytes (n).
uint32_t n = 1;
while (v & (0x80 >> n))
n++;
#define INVALID(report, arg, n2) \
do { \
n = n2; \
goto invalidMultiByteCodeUnit; \
} while (0)
// Check the leading byte.
if (n < 2 || n > 4)
INVALID(ReportInvalidCharacter, i, 1);
// Check that |src| is large enough to hold an n-byte code unit.
if (i + n > srclen)
INVALID(ReportBufferTooSmall, /* dummy = */ 0, 1);
// Check the second byte. From Unicode Standard v6.2, Table 3-7
// Well-Formed UTF-8 Byte Sequences.
if ((v == 0xE0 && ((uint8_t)src[i + 1] & 0xE0) != 0xA0) || // E0 A0~BF
(v == 0xED && ((uint8_t)src[i + 1] & 0xE0) != 0x80) || // ED 80~9F
(v == 0xF0 && ((uint8_t)src[i + 1] & 0xF0) == 0x80) || // F0 90~BF
(v == 0xF4 && ((uint8_t)src[i + 1] & 0xF0) != 0x80)) // F4 80~8F
{
INVALID(ReportInvalidCharacter, i, 1);
}
// Check the continuation bytes.
for (uint32_t m = 1; m < n; m++)
if ((src[i + m] & 0xC0) != 0x80)
INVALID(ReportInvalidCharacter, i, m);
// Determine the code unit's length in jschars and act accordingly.
v = JS::Utf8ToOneUcs4Char((uint8_t *)&src[i], n);
if (v < 0x10000) {
// The n-byte UTF8 code unit will fit in a single jschar.
dst[j] = jschar(v);
} else {
v -= 0x10000;
if (v <= 0xFFFFF) {
// The n-byte UTF8 code unit will fit in two jschars.
dst[j] = jschar((v >> 10) + 0xD800);
j++;
dst[j] = jschar((v & 0x3FF) + 0xDC00);
} else {
// The n-byte UTF8 code unit won't fit in two jschars.
INVALID(ReportTooBigCharacter, v, 1);
}
}
invalidMultiByteCodeUnit:
// Move i to the last byte of the multi-byte code unit; the loop
// header will do the final i++ to move to the start of the next
// code unit.
i += n - 1;
}
}
dst[j] = 0;
aOut = dst;
}
// Helper to check we have loaded the hardware shared library.
#define CHECK_HWLIB(ret) \
void* hwLib = GetSharedLibrary(); \
if (!hwLib) { \
NS_WARNING("No /system/lib/libhardware_legacy.so"); \
return ret; \
}
#define DEFAULT_IMPL(name, ret, args...) \
DEFINE_DLFUNC(name, ret, args...) \
ret do_##name(args) { \
USE_DLFUNC(name) \
return name(args); \
}
// ICS implementation.
class ICSWpaSupplicantImpl : public WpaSupplicantImpl
{
public:
DEFAULT_IMPL(wifi_load_driver, int32_t, )
DEFAULT_IMPL(wifi_unload_driver, int32_t, )
DEFAULT_IMPL(wifi_stop_supplicant, int32_t, )
DEFINE_DLFUNC(wifi_wait_for_event, int32_t, char*, size_t)
int32_t do_wifi_wait_for_event(const char *iface, char *buf, size_t len) {
USE_DLFUNC(wifi_wait_for_event)
return wifi_wait_for_event(buf, len);
}
DEFINE_DLFUNC(wifi_command, int32_t, const char*, char*, size_t*)
int32_t do_wifi_command(const char* iface, const char* cmd, char* buf, size_t* len) {
USE_DLFUNC(wifi_command)
return wifi_command(cmd, buf, len);
}
DEFINE_DLFUNC(wifi_start_supplicant, int32_t, )
int32_t do_wifi_start_supplicant(int32_t) {
USE_DLFUNC(wifi_start_supplicant)
return wifi_start_supplicant();
}
DEFINE_DLFUNC(wifi_connect_to_supplicant, int32_t, )
int32_t do_wifi_connect_to_supplicant(const char* iface) {
USE_DLFUNC(wifi_connect_to_supplicant)
return wifi_connect_to_supplicant();
}
DEFINE_DLFUNC(wifi_close_supplicant_connection, void, )
void do_wifi_close_supplicant_connection(const char* iface) {
USE_DLFUNC(wifi_close_supplicant_connection)
return wifi_close_supplicant_connection();
}
};
// JB implementation.
// We only redefine the methods that have a different signature than on ICS.
class JBWpaSupplicantImpl : public ICSWpaSupplicantImpl
{
public:
DEFINE_DLFUNC(wifi_wait_for_event, int32_t, const char*, char*, size_t)
int32_t do_wifi_wait_for_event(const char* iface, char* buf, size_t len) {
USE_DLFUNC(wifi_wait_for_event)
return wifi_wait_for_event(iface, buf, len);
}
DEFINE_DLFUNC(wifi_command, int32_t, const char*, const char*, char*, size_t*)
int32_t do_wifi_command(const char* iface, const char* cmd, char* buf, size_t* len) {
USE_DLFUNC(wifi_command)
return wifi_command(iface, cmd, buf, len);
}
DEFINE_DLFUNC(wifi_start_supplicant, int32_t, int32_t)
int32_t do_wifi_start_supplicant(int32_t arg) {
USE_DLFUNC(wifi_start_supplicant)
return wifi_start_supplicant(arg);
}
DEFINE_DLFUNC(wifi_connect_to_supplicant, int32_t, const char*)
int32_t do_wifi_connect_to_supplicant(const char* iface) {
USE_DLFUNC(wifi_connect_to_supplicant)
return wifi_connect_to_supplicant(iface);
}
DEFINE_DLFUNC(wifi_close_supplicant_connection, void, const char*)
void do_wifi_close_supplicant_connection(const char* iface) {
USE_DLFUNC(wifi_close_supplicant_connection)
wifi_close_supplicant_connection(iface);
}
};
// Concrete class to use to access the wpa supplicant.
WpaSupplicant::WpaSupplicant()
{
if (NetUtils::SdkVersion() < 16) {
mImpl = new ICSWpaSupplicantImpl();
} else {
mImpl = new JBWpaSupplicantImpl();
}
mNetUtils = new NetUtils();
};
void WpaSupplicant::WaitForEvent(nsAString& aEvent)
{
CHECK_HWLIB()
char buffer[BUFFER_SIZE];
int32_t ret = mImpl->do_wifi_wait_for_event("wlan0", buffer, BUFFER_SIZE);
CheckBuffer(buffer, ret, aEvent);
}
#define GET_CHAR(prop) NS_ConvertUTF16toUTF8(aOptions.prop).get()
/**
* Make a subnet mask.
*/
uint32_t WpaSupplicant::MakeMask(uint32_t len) {
uint32_t mask = 0;
for (uint32_t i = 0; i < len; ++i) {
mask |= (0x80000000 >> i);
}
return ntohl(mask);
}
bool WpaSupplicant::ExecuteCommand(CommandOptions aOptions,
WifiResultOptions& aResult)
{
CHECK_HWLIB(false)
if (!mNetUtils->GetSharedLibrary()) {
return false;
}
// Always correlate the opaque ids.
aResult.mId = aOptions.mId;
if (aOptions.mCmd.EqualsLiteral("command")) {
size_t len = BUFFER_SIZE - 1;
char buffer[BUFFER_SIZE];
NS_ConvertUTF16toUTF8 request(aOptions.mRequest);
aResult.mStatus = mImpl->do_wifi_command("wlan0", request.get(), buffer, &len);
nsString value;
if (aResult.mStatus == 0) {
if (buffer[len - 1] == '\n') { // remove trailing new lines.
len--;
}
buffer[len] = '\0';
CheckBuffer(buffer, len, value);
}
aResult.mReply = value;
} else if (aOptions.mCmd.EqualsLiteral("close_supplicant_connection")) {
mImpl->do_wifi_close_supplicant_connection("wlan0");
} else if (aOptions.mCmd.EqualsLiteral("load_driver")) {
aResult.mStatus = mImpl->do_wifi_load_driver();
} else if (aOptions.mCmd.EqualsLiteral("unload_driver")) {
aResult.mStatus = mImpl->do_wifi_unload_driver();
} else if (aOptions.mCmd.EqualsLiteral("start_supplicant")) {
aResult.mStatus = mImpl->do_wifi_start_supplicant(0);
} else if (aOptions.mCmd.EqualsLiteral("stop_supplicant")) {
aResult.mStatus = mImpl->do_wifi_stop_supplicant();
} else if (aOptions.mCmd.EqualsLiteral("connect_to_supplicant")) {
aResult.mStatus = mImpl->do_wifi_connect_to_supplicant("wlan0");
} else if (aOptions.mCmd.EqualsLiteral("ifc_enable")) {
aResult.mStatus = mNetUtils->do_ifc_enable(GET_CHAR(mIfname));
} else if (aOptions.mCmd.EqualsLiteral("ifc_disable")) {
aResult.mStatus = mNetUtils->do_ifc_disable(GET_CHAR(mIfname));
} else if (aOptions.mCmd.EqualsLiteral("ifc_configure")) {
aResult.mStatus = mNetUtils->do_ifc_configure(
GET_CHAR(mIfname), aOptions.mIpaddr, aOptions.mMask,
aOptions.mGateway, aOptions.mDns1, aOptions.mDns2
);
} else if (aOptions.mCmd.EqualsLiteral("ifc_reset_connections")) {
aResult.mStatus = mNetUtils->do_ifc_reset_connections(
GET_CHAR(mIfname), RESET_ALL_ADDRESSES
);
} else if (aOptions.mCmd.EqualsLiteral("dhcp_stop")) {
aResult.mStatus = mNetUtils->do_dhcp_stop(GET_CHAR(mIfname));
} else if (aOptions.mCmd.EqualsLiteral("dhcp_do_request")) {
char ipaddr[PROPERTY_VALUE_MAX];
char gateway[PROPERTY_VALUE_MAX];
uint32_t prefixLength;
char dns1[PROPERTY_VALUE_MAX];
char dns2[PROPERTY_VALUE_MAX];
char server[PROPERTY_VALUE_MAX];
uint32_t lease;
char vendorinfo[PROPERTY_VALUE_MAX];
aResult.mStatus =
mNetUtils->do_dhcp_do_request(GET_CHAR(mIfname),
ipaddr,
gateway,
&prefixLength,
dns1,
dns2,
server,
&lease,
vendorinfo);
if (aResult.mStatus == -1) {
// Early return since we failed.
return true;
}
aResult.mIpaddr_str = NS_ConvertUTF8toUTF16(ipaddr);
aResult.mGateway_str = NS_ConvertUTF8toUTF16(gateway);
aResult.mDns1_str = NS_ConvertUTF8toUTF16(dns1);
aResult.mDns2_str = NS_ConvertUTF8toUTF16(dns2);
aResult.mServer_str = NS_ConvertUTF8toUTF16(server);
aResult.mVendor_str = NS_ConvertUTF8toUTF16(vendorinfo);
aResult.mLease = lease;
aResult.mMask = MakeMask(prefixLength);
uint32_t inet4; // only support IPv4 for now.
#define INET_PTON(var, field) \
PR_BEGIN_MACRO \
inet_pton(AF_INET, var, &inet4); \
aResult.field = inet4; \
PR_END_MACRO
INET_PTON(ipaddr, mIpaddr);
INET_PTON(gateway, mGateway);
if (dns1[0] != '\0') {
INET_PTON(dns1, mDns1);
}
if (dns2[0] != '\0') {
INET_PTON(dns2, mDns2);
}
INET_PTON(server, mServer);
//aResult.mask_str = netHelpers.ipToString(obj.mask);
char inet_str[64];
if (inet_ntop(AF_INET, &aResult.mMask, inet_str, sizeof(inet_str))) {
aResult.mMask_str = NS_ConvertUTF8toUTF16(inet_str);
}
uint32_t broadcast = (aResult.mIpaddr & aResult.mMask) + ~aResult.mMask;
if (inet_ntop(AF_INET, &broadcast, inet_str, sizeof(inet_str))) {
aResult.mBroadcast_str = NS_ConvertUTF8toUTF16(inet_str);
}
} else {
NS_WARNING("WpaSupplicant::ExecuteCommand : Unknown command");
printf_stderr("WpaSupplicant::ExecuteCommand : Unknown command: %s",
NS_ConvertUTF16toUTF8(aOptions.mCmd).get());
return false;
}
return true;
}
// Checks the buffer and do the utf processing.
void
WpaSupplicant::CheckBuffer(char* buffer, int32_t length,
nsAString& aEvent)
{
if (length > 0 && length < BUFFER_SIZE) {
buffer[length] = 0;
LossyConvertUTF8toUTF16(buffer, length, aEvent);
}
}

133
dom/wifi/WifiUtils.h Normal file
View File

@ -0,0 +1,133 @@
/* 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/. */
/**
* Abstraction on top of the wifi support from libhardware_legacy that we
* use to talk to the wpa_supplicant.
*/
#ifndef WifiUtils_h
#define WifiUtils_h
#include "nsString.h"
#include "nsAutoPtr.h"
#include "mozilla/dom/WifiOptionsBinding.h"
#include "NetUtils.h"
#include "nsCxPusher.h"
// Needed to add a copy constructor to WifiCommandOptions.
struct CommandOptions
{
public:
CommandOptions(const CommandOptions& aOther) {
mId = aOther.mId;
mCmd = aOther.mCmd;
mRequest = aOther.mRequest;
mIfname = aOther.mIfname;
mRoute = aOther.mRoute;
mIpaddr = aOther.mIpaddr;
mMask = aOther.mMask;
mGateway = aOther.mGateway;
mDns1 = aOther.mDns1;
mDns2 = aOther.mDns2;
mKey = aOther.mKey;
mValue = aOther.mValue;
mDefaultValue = aOther.mDefaultValue;
}
CommandOptions(const mozilla::dom::WifiCommandOptions& aOther) {
#define COPY_OPT_FIELD(prop, defaultValue) \
if (aOther.prop.WasPassed()) { \
prop = aOther.prop.Value(); \
} else { \
prop = defaultValue; \
}
#define COPY_FIELD(prop) prop = aOther.prop;
COPY_FIELD(mId)
COPY_FIELD(mCmd)
COPY_OPT_FIELD(mRequest, EmptyString())
COPY_OPT_FIELD(mIfname, EmptyString())
COPY_OPT_FIELD(mIpaddr, 0)
COPY_OPT_FIELD(mRoute, 0)
COPY_OPT_FIELD(mMask, 0)
COPY_OPT_FIELD(mGateway, 0)
COPY_OPT_FIELD(mDns1, 0)
COPY_OPT_FIELD(mDns2, 0)
COPY_OPT_FIELD(mKey, EmptyString())
COPY_OPT_FIELD(mValue, EmptyString())
COPY_OPT_FIELD(mDefaultValue, EmptyString())
#undef COPY_OPT_FIELD
#undef COPY_FIELD
}
// All the fields, not Optional<> anymore to get copy constructors.
nsString mCmd;
nsString mDefaultValue;
int32_t mDns1;
int32_t mDns2;
int32_t mGateway;
int32_t mId;
nsString mIfname;
int32_t mIpaddr;
nsString mKey;
int32_t mMask;
nsString mRequest;
int32_t mRoute;
nsString mValue;
};
// Abstract class that exposes libhardware_legacy functions we need for
// wifi management.
// We use the ICS signatures here since they are likely more future-proof.
class WpaSupplicantImpl
{
public:
virtual int32_t
do_wifi_wait_for_event(const char *iface, char *buf, size_t len) = 0; // ICS != JB
virtual int32_t
do_wifi_command(const char* iface, const char* cmd, char* buff, size_t* len) = 0; // ICS != JB
virtual int32_t
do_wifi_load_driver() = 0;
virtual int32_t
do_wifi_unload_driver() = 0;
virtual int32_t
do_wifi_start_supplicant(int32_t) = 0; // ICS != JB
virtual int32_t
do_wifi_stop_supplicant() = 0;
virtual int32_t
do_wifi_connect_to_supplicant(const char* iface) = 0; // ICS != JB
virtual void
do_wifi_close_supplicant_connection(const char* iface) = 0; // ICS != JB
};
// Concrete class to use to access the wpa supplicant.
class WpaSupplicant MOZ_FINAL
{
public:
WpaSupplicant();
void WaitForEvent(nsAString& aEvent);
bool ExecuteCommand(CommandOptions aOptions,
mozilla::dom::WifiResultOptions& result);
private:
nsAutoPtr<WpaSupplicantImpl> mImpl;
nsAutoPtr<NetUtils> mNetUtils;
protected:
void CheckBuffer(char* buffer, int32_t length, nsAString& aEvent);
uint32_t MakeMask(uint32_t len);
};
#endif // WifiUtils_h

View File

@ -105,8 +105,25 @@ var WifiManager = (function() {
let {sdkVersion, unloadDriverEnabled, schedScanRecovery, driverDelay, ifname} = getStartupPrefs();
var controlWorker = new ChromeWorker(WIFIWORKER_WORKER);
var eventWorker = new ChromeWorker(WIFIWORKER_WORKER);
let wifiListener = {
onWaitEvent: function(event) {
if (handleEvent(event)) {
waitForEvent();
}
},
onCommand: function(event) {
onmessageresult(event);
}
}
let wifiService = Cc["@mozilla.org/wifi/service;1"];
if (wifiService) {
wifiService = wifiService.getService(Ci.nsIWifiProxyService);
wifiService.start(wifiListener);
} else {
debug("No wifi service component available!");
}
var manager = {};
manager.ifname = ifname;
@ -118,7 +135,7 @@ var WifiManager = (function() {
manager.schedScanRecovery = schedScanRecovery;
manager.driverDelay = driverDelay ? parseInt(driverDelay, 10) : DRIVER_READY_WAIT;
// Callbacks to invoke when a reply arrives from the controlWorker.
// Callbacks to invoke when a reply arrives from the wifi service.
var controlCallbacks = Object.create(null);
var idgen = 0;
@ -127,49 +144,23 @@ var WifiManager = (function() {
obj.id = id;
if (callback)
controlCallbacks[id] = callback;
controlWorker.postMessage(obj);
wifiService.sendCommand(obj);
}
function onerror(e) {
// It is very important to call preventDefault on the event here.
// If an exception is thrown on the worker, it bubbles out to the
// component that created it. If that component doesn't have an
// onerror handler, the worker will try to call the error reporter
// on the context it was created on. However, That doesn't work
// for component contexts and can result in crashes. This onerror
// handler has to make sure that it calls preventDefault on the
// incoming event.
e.preventDefault();
var worker = (this === controlWorker) ? "control" : "event";
debug("Got an error from the " + worker + " worker: " + e.filename +
":" + e.lineno + ": " + e.message + "\n");
}
controlWorker.onerror = onerror;
eventWorker.onerror = onerror;
controlWorker.onmessage = function(e) {
var data = e.data;
let onmessageresult = function(data) {
var id = data.id;
var callback = controlCallbacks[id];
if (callback) {
callback(data);
delete controlCallbacks[id];
}
};
}
// Polling the status worker
var recvErrors = 0;
eventWorker.onmessage = function(e) {
// Process the event and tell the event worker to listen for more events.
if (handleEvent(e.data.event))
waitForEvent();
};
function waitForEvent() {
eventWorker.postMessage({ cmd: "wait_for_event" });
wifiService.waitForEvent();
}
// Commands to the control worker.
@ -595,16 +586,17 @@ var WifiManager = (function() {
doBooleanCommand("DRIVER SETSUSPENDOPT " + (enabled ? 0 : 1), "OK", callback);
}
function getProperty(key, defaultValue, callback) {
controlMessage({ cmd: "property_get", key: key, defaultValue: defaultValue }, function(data) {
callback(data.status < 0 ? null : data.value);
});
}
// Wrapper around libcutils.property_set that returns true if setting the
// value was successful.
// Note that the callback is not called asynchronously.
function setProperty(key, value, callback) {
controlMessage({ cmd: "property_set", key: key, value: value }, function(data) {
callback(!data.status);
});
let ok = true;
try {
libcutils.property_set(key, value);
} catch(e) {
ok = false;
}
callback(ok);
}
function enableInterface(ifname, callback) {
@ -778,9 +770,10 @@ var WifiManager = (function() {
}
function configureInterface(ifname, ipaddr, mask, gateway, dns1, dns2, callback) {
controlMessage({ cmd: "ifc_configure", ifname: ifname,
let message = { cmd: "ifc_configure", ifname: ifname,
ipaddr: ipaddr, mask: mask, gateway: gateway,
dns1: dns1, dns2: dns2}, function(data) {
dns1: dns1, dns2: dns2};
controlMessage(message, function(data) {
callback(!data.status);
});
}

View File

@ -1,96 +0,0 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
"use strict";
let libhardware_legacy = (function () {
let library = ctypes.open("libhardware_legacy.so");
let sdkVersion = libcutils.property_get("ro.build.version.sdk", "0");
sdkVersion = parseInt(sdkVersion, 10);
let iface = {
// Load wifi driver, 0 on success, < 0 on failure.
load_driver: library.declare("wifi_load_driver", ctypes.default_abi, ctypes.int),
// Unload wifi driver, 0 on success, < 0 on failure.
unload_driver: library.declare("wifi_unload_driver", ctypes.default_abi, ctypes.int),
// Start supplicant, 0 on success, < 0 on failure.
start_supplicant: library.declare("wifi_start_supplicant", ctypes.default_abi, ctypes.int),
// Stop supplicant, 0 on success, < 0 on failure.
stop_supplicant: library.declare("wifi_stop_supplicant", ctypes.default_abi, ctypes.int),
// Open a connection to the supplicant, 0 on success, < 0 on failure.
connect_to_supplicant: library.declare("wifi_connect_to_supplicant", ctypes.default_abi, ctypes.int),
// Close connection to connection to the supplicant, 0 on success, < 0 on failure.
close_supplicant_connection: library.declare("wifi_close_supplicant_connection", ctypes.default_abi, ctypes.void_t),
// Block until a wifi event is returned, buf is the buffer, len is the max length of the buffer.
// Return value is number of bytes in buffer, or 0 if no event (no connection for instance), and < 0 on failure.
wait_for_event: library.declare("wifi_wait_for_event", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.size_t),
// Issue a command to the wifi driver. command is the command string, reply will hold the reply, reply_len contains
// the maximum reply length initially and is updated with the actual length. 0 is returned on success, < 0 on failure.
command: library.declare("wifi_command", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr, ctypes.size_t.ptr),
};
if (sdkVersion >= 16) {
let c_start_supplicant =
library.declare("wifi_start_supplicant",
ctypes.default_abi,
ctypes.int,
ctypes.int);
iface.start_supplicant = function () {
return c_start_supplicant(0);
};
let c_connect_to_supplicant =
library.declare("wifi_connect_to_supplicant",
ctypes.default_abi,
ctypes.int,
ctypes.char.ptr);
iface.connect_to_supplicant = function () {
return c_connect_to_supplicant("wlan0");
};
let c_close_supplicant_connection =
library.declare("wifi_close_supplicant_connection",
ctypes.default_abi,
ctypes.void_t,
ctypes.char.ptr);
iface.close_supplicant_connection = function () {
c_close_supplicant_connection("wlan0");
};
let c_wait_for_event =
library.declare("wifi_wait_for_event",
ctypes.default_abi,
ctypes.int,
ctypes.char.ptr,
ctypes.char.ptr,
ctypes.size_t);
iface.wait_for_event = function (cbuf, len) {
return c_wait_for_event("wlan0", cbuf, len);
};
let c_command =
library.declare("wifi_command",
ctypes.default_abi,
ctypes.int,
ctypes.char.ptr,
ctypes.char.ptr,
ctypes.char.ptr,
ctypes.size_t.ptr);
iface.command = function (message, cbuf, len) {
return c_command("wlan0", message, cbuf, len);
};
}
return iface;
})();

View File

@ -8,6 +8,7 @@ XPIDL_SOURCES += [
'nsIDOMMozWifiConnectionInfoEvent.idl',
'nsIDOMMozWifiStatusChangeEvent.idl',
'nsIWifi.idl',
'nsIWifiService.idl',
]
XPIDL_MODULE = 'dom_wifi'
@ -21,10 +22,12 @@ EXTRA_COMPONENTS += [
'WifiWorker.manifest',
]
EXTRA_JS_MODULES += [
'libhardware_legacy.js',
'wifi_worker.js',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
CPP_SOURCES = [
'NetUtils.cpp',
'WifiProxyService.cpp',
'WifiUtils.cpp',
]
LIBXUL_LIBRARY = True

View File

@ -0,0 +1,20 @@
/* 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(e3d54c8d-b1c7-4ed5-b760-e26d3075e3e5)]
interface nsIWifiEventListener : nsISupports {
void onWaitEvent(in AString event);
void onCommand(in jsval result);
};
[scriptable, uuid(ac5ebae6-ec72-4212-89cb-cd25ed5a1b46)]
interface nsIWifiProxyService : nsISupports {
void start(in nsIWifiEventListener listener);
void shutdown();
[implicit_jscontext]
void sendCommand(in jsval parameters);
void waitForEvent();
};

View File

@ -1,138 +0,0 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* 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/. */
"use strict";
importScripts("systemlibs.js", "libhardware_legacy.js");
var cbuf = ctypes.char.array(4096)();
var hwaddr = ctypes.uint8_t.array(6)();
var len = ctypes.size_t();
var ints = ctypes.int.array(8)();
let DEBUG = false;
let debug;
if (DEBUG) {
debug = function (s) {
dump("-*- WifiWorker component: " + s + "\n");
};
} else {
debug = function (s) {};
}
// TODO: consolidate with implementation in systemlibs.js
let libcutils = (function () {
let library = ctypes.open("libcutils.so");
return {
property_get: library.declare("property_get", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr, ctypes.char.ptr),
property_set: library.declare("property_set", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.char.ptr)
};
})();
self.onmessage = function(e) {
var data = e.data;
var id = data.id;
var cmd = data.cmd;
switch (cmd) {
case "command":
len.value = 4096;
var ret = libhardware_legacy.command(data.request, cbuf, len.address());
var reply = "";
if (!ret) {
// The return value from libhardware_legacy.command is not guaranteed to
// be null-terminated. At the same time we want to make sure that we
// don't return a response with a trailing newline, so handle both cases
// here. Note that if we wrote 4096 characters to cbuf, we don't have to
// null-terminate the buffer, as ctypes has the maximum size already.
// Note also that len.value is an object. We can ignore the high 32 bits
// because we know that the maximum that it can be is 4096.
var reply_len = ctypes.UInt64.lo(len.value);
if (reply_len !== 0) {
if (cbuf[reply_len - 1] === 10)
cbuf[--reply_len] = 0;
else if (reply_len !== 4096)
cbuf[reply_len] = 0;
reply = cbuf.readStringReplaceMalformed();
}
// Else if reply_len was 0, use the empty reply, set above.
}
postMessage({ id: id, status: ret, reply: reply });
break;
case "wait_for_event":
var ret = libhardware_legacy.wait_for_event(cbuf, 4096);
// Check the array index.
if (ret > 0 && ret < 4096) {
// Make sure the string buffer is null terminated.
cbuf[ret] = 0;
// Use readStringReplaceMalformed() to handle non-UTF8-encoded string.
var event = cbuf.readStringReplaceMalformed();
postMessage({ id: id, event: event });
}
break;
case "ifc_reset_connections":
var ret = libnetutils.ifc_reset_connections(data.ifname,
libnetutils.RESET_ALL_ADDRESSES);
postMessage({ id: id, status: ret });
break;
case "ifc_enable":
case "ifc_disable":
case "ifc_remove_host_routes":
case "ifc_remove_default_route":
case "dhcp_stop":
case "dhcp_release_lease":
var ret = libnetutils[cmd](data.ifname);
postMessage({ id: id, status: ret });
break;
case "ifc_get_default_route":
var route = libnetutils.ifc_get_default_route(data.ifname);
postMessage({ id: id, route: route });
break;
case "ifc_add_host_route":
case "ifc_set_default_route":
var ret = libnetutils[cmd](data.ifname, data.route);
postMessage({ id: id, status: ret });
break;
case "ifc_configure":
debug("WIFI: data: " + uneval(data) + "\n");
var ret = libnetutils.ifc_configure(data.ifname, data.ipaddr, data.mask, data.gateway, data.dns1, data.dns2);
postMessage({ id: id, status: ret });
break;
case "dhcp_get_errmsg":
var error = libnetutils.get_dhcp_get_errmsg();
postMessage({ id: id, error: error.readString() });
break;
case "dhcp_do_request":
case "dhcp_do_request_renew":
var out = libnetutils[cmd](data.ifname);
out.id = id;
out.status = out.ret;
postMessage(out);
break;
case "property_get":
var ret = libcutils.property_get(data.key, cbuf, data.defaultValue);
postMessage({ id: id, status: ret, value: cbuf.readString() });
break;
case "property_set":
var ret = libcutils.property_set(data.key, data.value);
postMessage({ id: id, status: ret });
break;
case "close_supplicant_connection":
libhardware_legacy.close_supplicant_connection();
postMessage({ id: id, status: ret });
break;
default:
var f = libhardware_legacy[cmd] || libnetutils[cmd];
var ret = f();
debug("WIFI: " + cmd + " returned: " + ret);
postMessage({ id: id, status: ret });
break;
}
}

View File

@ -32,6 +32,18 @@ static const char *sExtensionNames[] = {
static PRLibrary* LoadApitraceLibrary()
{
static bool sUseApitraceInitialized = false;
static bool sUseApitrace = false;
if (!sUseApitraceInitialized) {
sUseApitrace = Preferences::GetBool("gfx.apitrace.enabled", false);
sUseApitraceInitialized = true;
}
if (!sUseApitrace) {
return nullptr;
}
static PRLibrary* sApitraceLibrary = nullptr;
if (sApitraceLibrary)

View File

@ -66,7 +66,7 @@ class SurfaceDescriptor;
* where we have a different way of interfacing with the textures - in terms of
* drawing into the compositable and/or passing its contents to the compostior.
*/
class CompositableClient : public RefCounted<CompositableClient>
class CompositableClient : public AtomicRefCounted<CompositableClient>
{
public:
CompositableClient(CompositableForwarder* aForwarder);

View File

@ -93,7 +93,7 @@ public:
* In order to send several different buffers to the compositor side, use
* several TextureClients.
*/
class TextureClient : public RefCounted<TextureClient>
class TextureClient : public AtomicRefCounted<TextureClient>
{
public:
TextureClient(TextureFlags aFlags = TEXTURE_FLAGS_DEFAULT);

View File

@ -120,24 +120,22 @@ FPSState::DrawFPS(TimeStamp aNow,
context->fTexParameteri(LOCAL_GL_TEXTURE_2D,LOCAL_GL_TEXTURE_MIN_FILTER,LOCAL_GL_NEAREST);
context->fTexParameteri(LOCAL_GL_TEXTURE_2D,LOCAL_GL_TEXTURE_MAG_FILTER,LOCAL_GL_NEAREST);
uint32_t text[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 255, 255, 255, 0, 255, 255, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 0, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
0, 255, 0, 255, 0, 0, 255, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
0, 255, 0, 255, 0, 0, 255, 0, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0,
0, 255, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0, 255, 0, 255, 0, 0, 0, 255, 0,
0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0, 255, 255, 255, 0, 0, 0, 255, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const char *text =
" "
" XXX XX XXX XXX X X XXX XXX XXX XXX XXX "
" X X X X X X X X X X X X X X "
" X X X XXX XXX XXX XXX XXX X XXX XXX "
" X X X X X X X X X X X X X "
" XXX XXX XXX XXX X XXX XXX X XXX X "
" ";
// convert from 8 bit to 32 bit so that don't have to write the text above out in 32 bit format
// we rely on int being 32 bits
unsigned int* buf = (unsigned int*)malloc(64 * 8 * 4);
// Convert the text encoding above to RGBA.
uint32_t* buf = (uint32_t *) malloc(64 * 8 * sizeof(uint32_t));
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 41; j++) {
unsigned int purple = 0xfff000ff;
unsigned int white = 0xffffffff;
buf[i * 64 + j] = (text[i * 41 + j] == 0) ? purple : white;
uint32_t purple = 0xfff000ff;
uint32_t white = 0xffffffff;
buf[i * 64 + j] = (text[i * 41 + j] == ' ') ? purple : white;
}
}
context->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, 64, 8, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, buf);

View File

@ -0,0 +1,65 @@
diff --git a/ipc/chromium/src/third_party/libevent/kqueue.c b/ipc/chromium/src/third_party/libevent/kqueue.c
--- a/ipc/chromium/src/third_party/libevent/kqueue.c
+++ b/ipc/chromium/src/third_party/libevent/kqueue.c
@@ -158,26 +158,20 @@ kq_init(struct event_base *base)
base->evsigsel = &kqsigops;
return (kqueueop);
err:
if (kqueueop)
kqop_free(kqueueop);
return (NULL);
}
-static void
-kq_sighandler(int sig)
-{
- /* Do nothing here */
-}
-
#define ADD_UDATA 0x30303
static void
kq_setup_kevent(struct kevent *out, evutil_socket_t fd, int filter, short change)
{
memset(out, 0, sizeof(struct kevent));
out->ident = fd;
out->filter = filter;
if (change & EV_CHANGE_ADD) {
@@ -431,24 +425,31 @@ kq_sig_add(struct event_base *base, int
kev.ident = nsignal;
kev.filter = EVFILT_SIGNAL;
kev.flags = EV_ADD;
/* Be ready for the signal if it is sent any
* time between now and the next call to
* kq_dispatch. */
if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1)
return (-1);
- /* XXXX The manpage suggest we could use SIG_IGN instead of a
- * do-nothing handler */
- if (_evsig_set_handler(base, nsignal, kq_sighandler) == -1)
+ /* Backported from
+ * https://github.com/nmathewson/Libevent/commit/148458e0a1fd25e167aa2ef229d1c9a70b27c3e9 */
+ /* We can set the handler for most signals to SIG_IGN and
+ * still have them reported to us in the queue. However,
+ * if the handler for SIGCHLD is SIG_IGN, the system reaps
+ * zombie processes for us, and we don't get any notification.
+ * This appears to be the only signal with this quirk. */
+ if (_evsig_set_handler(base, nsignal,
+ nsignal == SIGCHLD ? SIG_DFL : SIG_IGN) == -1) {
return (-1);
+ }
return (0);
}
static int
kq_sig_del(struct event_base *base, int nsignal, short old, short events, void *p)
{
struct kqop *kqop = base->evbase;
struct kevent kev;

View File

@ -165,12 +165,6 @@ err:
return (NULL);
}
static void
kq_sighandler(int sig)
{
/* Do nothing here */
}
#define ADD_UDATA 0x30303
static void
@ -438,10 +432,17 @@ kq_sig_add(struct event_base *base, int nsignal, short old, short events, void *
if (kevent(kqop->kq, &kev, 1, NULL, 0, &timeout) == -1)
return (-1);
/* XXXX The manpage suggest we could use SIG_IGN instead of a
* do-nothing handler */
if (_evsig_set_handler(base, nsignal, kq_sighandler) == -1)
/* Backported from
* https://github.com/nmathewson/Libevent/commit/148458e0a1fd25e167aa2ef229d1c9a70b27c3e9 */
/* We can set the handler for most signals to SIG_IGN and
* still have them reported to us in the queue. However,
* if the handler for SIGCHLD is SIG_IGN, the system reaps
* zombie processes for us, and we don't get any notification.
* This appears to be the only signal with this quirk. */
if (_evsig_set_handler(base, nsignal,
nsignal == SIGCHLD ? SIG_DFL : SIG_IGN) == -1) {
return (-1);
}
return (0);
}

View File

@ -44,7 +44,7 @@
// TODO: We don't print the condition code in our spew lines. Doing this
// is awkward whilst maintaining a consistent field width.
namespace js {
namespace ion {
namespace jit {
class Assembler;
}
}
@ -260,7 +260,7 @@ namespace JSC {
class JmpSrc {
friend class ARMAssembler;
friend class js::ion::Assembler;
friend class js::jit::Assembler;
public:
JmpSrc()
: m_offset(-1)
@ -283,7 +283,7 @@ namespace JSC {
class JmpDst {
friend class ARMAssembler;
friend class js::ion::Assembler;
friend class js::jit::Assembler;
public:
JmpDst()
: m_offset(-1)

View File

@ -273,7 +273,7 @@ namespace JSC {
{
if (printer
#ifdef JS_ION
|| js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen)
|| js::jit::IonSpewEnabled(js::jit::IonSpew_Codegen)
#endif
)
{
@ -291,7 +291,7 @@ namespace JSC {
printer->printf("%s\n", buf);
#ifdef JS_ION
js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
js::jit::IonSpew(js::jit::IonSpew_Codegen, "%s", buf);
#endif
}
}
@ -303,7 +303,7 @@ namespace JSC {
#endif
{
#ifdef JS_ION
if (js::ion::IonSpewEnabled(js::ion::IonSpew_Codegen)) {
if (js::jit::IonSpewEnabled(js::jit::IonSpew_Codegen)) {
char buf[200];
va_list va;
@ -312,7 +312,7 @@ namespace JSC {
va_end(va);
if (i > -1)
js::ion::IonSpew(js::ion::IonSpew_Codegen, "%s", buf);
js::jit::IonSpew(js::jit::IonSpew_Codegen, "%s", buf);
}
#endif
}

View File

@ -896,7 +896,7 @@ static bool
EnableOsiPointRegisterChecks(JSContext *, unsigned, jsval *vp)
{
#ifdef CHECK_OSIPOINT_REGISTERS
ion::js_IonOptions.checkOsiPointRegisters = true;
jit::js_IonOptions.checkOsiPointRegisters = true;
#endif
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;

View File

@ -156,7 +156,7 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco
const jschar *chars, size_t length,
JSString *source_ /* = NULL */,
unsigned staticLevel /* = 0 */,
SourceCompressionToken *extraSct /* = NULL */)
SourceCompressionTask *extraSct /* = NULL */)
{
RootedString source(cx, source_);
SkipRoot skip(cx, &chars);
@ -192,20 +192,12 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco
if (!sourceObject)
return NULL;
// Saving source is not yet supported when parsing off thread.
JS_ASSERT_IF(!cx->isJSContext(),
!extraSct && options.sourcePolicy != CompileOptions::SAVE_SOURCE);
SourceCompressionToken *sct = extraSct;
Maybe<SourceCompressionToken> mysct;
if (cx->isJSContext() && !sct) {
mysct.construct(cx->asJSContext());
sct = mysct.addr();
}
SourceCompressionTask mysct(cx);
SourceCompressionTask *sct = extraSct ? extraSct : &mysct;
switch (options.sourcePolicy) {
case CompileOptions::SAVE_SOURCE:
if (!ss->setSourceCopy(cx->asJSContext(), chars, length, false, sct))
if (!ss->setSourceCopy(cx, chars, length, false, sct))
return NULL;
break;
case CompileOptions::LAZY_SOURCE:
@ -479,7 +471,7 @@ CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileOptions opt
JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss));
if (!sourceObject)
return false;
SourceCompressionToken sct(cx);
SourceCompressionTask sct(cx);
JS_ASSERT(options.sourcePolicy != CompileOptions::LAZY_SOURCE);
if (options.sourcePolicy == CompileOptions::SAVE_SOURCE) {
if (!ss->setSourceCopy(cx, chars, length, true, &sct))

View File

@ -16,7 +16,7 @@ namespace js {
class AutoNameVector;
class LazyScript;
class LifoAlloc;
struct SourceCompressionToken;
struct SourceCompressionTask;
namespace frontend {
@ -25,7 +25,7 @@ CompileScript(ExclusiveContext *cx, LifoAlloc *alloc,
HandleObject scopeChain, HandleScript evalCaller,
const CompileOptions &options, const jschar *chars, size_t length,
JSString *source_ = NULL, unsigned staticLevel = 0,
SourceCompressionToken *extraSct = NULL);
SourceCompressionTask *extraSct = NULL);
bool
CompileLazyFunction(JSContext *cx, LazyScript *lazy, const jschar *chars, size_t length);

View File

@ -322,7 +322,9 @@ class Parser : private AutoGCRooter, public StrictModeGetter
/* innermost parse context (stack-allocated) */
ParseContext<ParseHandler> *pc;
SourceCompressionToken *sct; /* compression token for aborting */
/* Compression token for aborting. */
SourceCompressionTask *sct;
ScriptSource *ss;
/* Root atoms and objects allocated for the parsed tree. */

View File

@ -86,7 +86,7 @@ static void MarkChildren(JSTracer *trc, LazyScript *lazy);
static void MarkChildren(JSTracer *trc, Shape *shape);
static void MarkChildren(JSTracer *trc, BaseShape *base);
static void MarkChildren(JSTracer *trc, types::TypeObject *type);
static void MarkChildren(JSTracer *trc, ion::IonCode *code);
static void MarkChildren(JSTracer *trc, jit::IonCode *code);
} /* namespace gc */
} /* namespace js */
@ -363,7 +363,7 @@ Is##base##AboutToBeFinalized(EncapsulatedPtr<type> *thingp)
DeclMarkerImpl(BaseShape, BaseShape)
DeclMarkerImpl(BaseShape, UnownedBaseShape)
DeclMarkerImpl(IonCode, ion::IonCode)
DeclMarkerImpl(IonCode, jit::IonCode)
DeclMarkerImpl(Object, ArgumentsObject)
DeclMarkerImpl(Object, ArrayBufferObject)
DeclMarkerImpl(Object, ArrayBufferViewObject)
@ -417,7 +417,7 @@ gc::MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind)
MarkInternal(trc, reinterpret_cast<types::TypeObject **>(thingp));
break;
case JSTRACE_IONCODE:
MarkInternal(trc, reinterpret_cast<ion::IonCode **>(thingp));
MarkInternal(trc, reinterpret_cast<jit::IonCode **>(thingp));
break;
}
}
@ -839,7 +839,7 @@ PushMarkStack(GCMarker *gcmarker, Shape *thing)
}
static void
PushMarkStack(GCMarker *gcmarker, ion::IonCode *thing)
PushMarkStack(GCMarker *gcmarker, jit::IonCode *thing)
{
JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing);
JS_ASSERT(!IsInsideNursery(gcmarker->runtime, thing));
@ -1163,7 +1163,7 @@ gc::MarkChildren(JSTracer *trc, types::TypeObject *type)
}
static void
gc::MarkChildren(JSTracer *trc, ion::IonCode *code)
gc::MarkChildren(JSTracer *trc, jit::IonCode *code)
{
#ifdef JS_ION
code->trace(trc);
@ -1211,7 +1211,7 @@ gc::PushArena(GCMarker *gcmarker, ArenaHeader *aheader)
break;
case JSTRACE_IONCODE:
PushArenaTyped<js::ion::IonCode>(gcmarker, aheader);
PushArenaTyped<js::jit::IonCode>(gcmarker, aheader);
break;
}
}
@ -1337,7 +1337,7 @@ GCMarker::processMarkStackOther(SliceBudget &budget, uintptr_t tag, uintptr_t ad
else
pushObject(obj);
} else if (tag == IonCodeTag) {
MarkChildren(this, reinterpret_cast<ion::IonCode *>(addr));
MarkChildren(this, reinterpret_cast<jit::IonCode *>(addr));
} else if (tag == ArenaTag) {
ArenaHeader *aheader = reinterpret_cast<ArenaHeader *>(addr);
AllocKind thingKind = aheader->getAllocKind();
@ -1554,7 +1554,7 @@ js::TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind)
break;
case JSTRACE_IONCODE:
MarkChildren(trc, (js::ion::IonCode *)thing);
MarkChildren(trc, (js::jit::IonCode *)thing);
break;
case JSTRACE_BASE_SHAPE:

View File

@ -91,7 +91,7 @@ bool Is##base##AboutToBeFinalized(EncapsulatedPtr<type> *thingp);
DeclMarker(BaseShape, BaseShape)
DeclMarker(BaseShape, UnownedBaseShape)
DeclMarker(IonCode, ion::IonCode)
DeclMarker(IonCode, jit::IonCode)
DeclMarker(Object, ArgumentsObject)
DeclMarker(Object, ArrayBufferObject)
DeclMarker(Object, ArrayBufferViewObject)
@ -277,7 +277,7 @@ Mark(JSTracer *trc, EncapsulatedPtrScript *o, const char *name)
}
inline void
Mark(JSTracer *trc, HeapPtr<ion::IonCode> *code, const char *name)
Mark(JSTracer *trc, HeapPtr<jit::IonCode> *code, const char *name)
{
MarkIonCode(trc, code, name);
}
@ -346,7 +346,7 @@ IsAboutToBeFinalized(EncapsulatedPtrScript *scriptp)
/* Nonsense to get WeakCache to work with new Marking semantics. */
inline bool
IsAboutToBeFinalized(const js::ion::VMFunction **vmfunc)
IsAboutToBeFinalized(const js::jit::VMFunction **vmfunc)
{
/*
* Preserves entries in the WeakCache<VMFunction, IonCode>
@ -356,7 +356,7 @@ IsAboutToBeFinalized(const js::ion::VMFunction **vmfunc)
}
inline bool
IsAboutToBeFinalized(ReadBarriered<js::ion::IonCode> code)
IsAboutToBeFinalized(ReadBarriered<js::jit::IonCode> code)
{
return IsIonCodeAboutToBeFinalized(code.unsafeGet());
}

View File

@ -24,7 +24,7 @@ namespace gc {
class MinorCollectionTracer;
} /* namespace gc */
namespace ion {
namespace jit {
class CodeGenerator;
class MacroAssembler;
class ICStubCompiler;
@ -235,10 +235,10 @@ class Nursery
static void MinorGCCallback(JSTracer *trc, void **thingp, JSGCTraceKind kind);
friend class gc::MinorCollectionTracer;
friend class ion::CodeGenerator;
friend class ion::MacroAssembler;
friend class ion::ICStubCompiler;
friend class ion::BaselineCompiler;
friend class jit::CodeGenerator;
friend class jit::MacroAssembler;
friend class jit::ICStubCompiler;
friend class jit::BaselineCompiler;
};
} /* namespace js */

View File

@ -60,7 +60,7 @@ MarkExactStackRoot(JSTracer *trc, Rooted<void*> *rooter, ThingRootKind kind)
case THING_ROOT_BASE_SHAPE: MarkBaseShapeRoot(trc, (BaseShape **)addr, "exact-baseshape"); break;
case THING_ROOT_TYPE: MarkTypeRoot(trc, (types::Type *)addr, "exact-type"); break;
case THING_ROOT_TYPE_OBJECT: MarkTypeObjectRoot(trc, (types::TypeObject **)addr, "exact-typeobject"); break;
case THING_ROOT_ION_CODE: MarkIonCodeRoot(trc, (ion::IonCode **)addr, "exact-ioncode"); break;
case THING_ROOT_ION_CODE: MarkIonCodeRoot(trc, (jit::IonCode **)addr, "exact-ioncode"); break;
case THING_ROOT_VALUE: MarkValueRoot(trc, (Value *)addr, "exact-value"); break;
case THING_ROOT_ID: MarkIdRoot(trc, (jsid *)addr, "exact-id"); break;
case THING_ROOT_PROPERTY_ID: MarkIdRoot(trc, &((js::PropertyId *)addr)->asId(), "exact-propertyid"); break;
@ -276,7 +276,7 @@ MarkRangeConservativelyAndSkipIon(JSTracer *trc, JSRuntime *rt, const uintptr_t
// Walk only regions in between JIT activations. Note that non-volatile
// registers are spilled to the stack before the entry frame, ensuring
// that the conservative scanner will still see them.
for (ion::JitActivationIterator iter(rt); !iter.done(); ++iter) {
for (jit::JitActivationIterator iter(rt); !iter.done(); ++iter) {
uintptr_t *jitMin, *jitEnd;
iter.jitStackRange(jitMin, jitEnd);
@ -518,14 +518,14 @@ AutoGCRooter::trace(JSTracer *trc)
case IONMASM: {
#ifdef JS_ION
static_cast<js::ion::MacroAssembler::AutoRooter *>(this)->masm()->trace(trc);
static_cast<js::jit::MacroAssembler::AutoRooter *>(this)->masm()->trace(trc);
#endif
return;
}
case IONALLOC: {
#ifdef JS_ION
static_cast<js::ion::AutoTempAllocatorRooter *>(this)->trace(trc);
static_cast<js::jit::AutoTempAllocatorRooter *>(this)->trace(trc);
#endif
return;
}
@ -696,7 +696,7 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
MarkAtoms(trc);
rt->staticStrings.trace(trc);
#ifdef JS_ION
ion::IonRuntime::Mark(trc);
jit::IonRuntime::Mark(trc);
#endif
}
@ -746,7 +746,7 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
MarkInterpreterActivations(rt, trc);
#ifdef JS_ION
ion::MarkJitActivations(rt, trc);
jit::MarkJitActivations(rt, trc);
#endif
if (!rt->isHeapMinorCollecting()) {

View File

@ -68,7 +68,7 @@ StoreBuffer::WholeCellEdges::mark(JSTracer *trc)
}
#ifdef JS_ION
JS_ASSERT(kind == JSTRACE_IONCODE);
static_cast<ion::IonCode *>(tenured)->trace(trc);
static_cast<jit::IonCode *>(tenured)->trace(trc);
#else
MOZ_ASSUME_UNREACHABLE("Only objects can be in the wholeCellBuffer if IonMonkey is disabled.");
#endif

View File

@ -125,7 +125,7 @@ CheckStackRootsRangeAndSkipJit(JSRuntime *rt, uintptr_t *begin, uintptr_t *end,
uintptr_t *i = begin;
#if defined(JS_ION)
for (ion::JitActivationIterator iter(rt); !iter.done(); ++iter) {
for (jit::JitActivationIterator iter(rt); !iter.done(); ++iter) {
uintptr_t *jitMin, *jitEnd;
iter.jitStackRange(jitMin, jitEnd);

View File

@ -68,7 +68,7 @@ Zone::setNeedsBarrier(bool needs, ShouldUpdateIon updateIon)
{
#ifdef JS_ION
if (updateIon == UpdateIon && needs != ionUsingBarriers_) {
ion::ToggleBarriers(this, needs);
jit::ToggleBarriers(this, needs);
ionUsingBarriers_ = needs;
}
#endif
@ -201,20 +201,20 @@ Zone::discardJitCode(FreeOp *fop, bool discardConstraints)
# endif
/* Mark baseline scripts on the stack as active. */
ion::MarkActiveBaselineScripts(this);
jit::MarkActiveBaselineScripts(this);
/* Only mark OSI points if code is being discarded. */
ion::InvalidateAll(fop, this);
jit::InvalidateAll(fop, this);
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
ion::FinishInvalidation(fop, script);
jit::FinishInvalidation(fop, script);
/*
* Discard baseline script if it's not marked as active. Note that
* this also resets the active flag.
*/
ion::FinishDiscardBaselineScript(fop, script);
jit::FinishDiscardBaselineScript(fop, script);
/*
* Use counts for scripts are reset on GC. After discarding code we

View File

@ -82,6 +82,9 @@ def main(argv):
op.add_option('--devicePort', action='store',
type=int, dest='device_port', default=20701,
help='port of remote device to test')
op.add_option('--deviceSerial', action='store',
type='string', dest='device_serial', default=None,
help='ADB device serial number of remote device to test')
op.add_option('--deviceTransport', action='store',
type='string', dest='device_transport', default='sut',
help='The transport to use to communicate with device: [adb|sut]; default=sut')

View File

@ -0,0 +1,9 @@
if (typeof schedulegc != 'undefined') {
Function("\
x = (function() { yield })();\
Set(x);\
schedulegc(1);\
print( /x/ );\
for (p in x) {}\
")();
}

View File

@ -0,0 +1,5 @@
function f(type) {
for (var i = 0; i < 3; i++) {}
assertEq((new String) instanceof type, true);
}
f(String);

View File

@ -0,0 +1,82 @@
// |jit-test| slow;
load(libdir + "parallelarray-helpers.js");
// The MathCache has 4096 entries, so ensure we overwrite at least one
// entry by using > 4096 distinct inputs.
var len = 5000;
var iters = 100;
// The problem we are trying to expose (Bugzilla 901000) is
// a data-race on the MathCache; such a bug is inherently
// non-deterministic. On a 4 core Mac laptop:
//
// len == 10000 iters==1 replicates the problem on 2/10 runs,
// len == 10000 iters==2 replicates the problem on 3/10 runs,
// len == 10000 iters==5 replicates the problem on 6/10 runs,
// len == 10000 iters==10 replicates the problem on 9/10 runs.
//
// len == 5000 iters==1 replicates the problem on 1/10 runs,
// len == 5000 iters==2 replicates the problem on 4/10 runs,
// len == 5000 iters==5 replicates the problem on 5/10 runs,
// len == 5000 iters==10 replicates the problem on 9/10 runs.
//
// len == 2000 iters==1 replicates the problem on 0/10 runs,
// len == 2000 iters==2 replicates the problem on 0/10 runs,
// len == 2000 iters==5 replicates the problem on 0/10 runs,
// len == 2000 iters==10 replicates the problem on 3/10 runs
function check(fill) {
var seq = Array.build(len, fill);
for (var i = 0; i < iters; i++) {
var par = Array.buildPar(len, fill);
assertStructuralEq(par, seq);
}
}
function checkAbs(a) { check(function (i) { return Math.abs(a[i]); }); }
function checkAcos(a) { check(function (i) { return Math.acos(a[i]); }); }
function checkAsin(a) { check(function (i) { return Math.asin(a[i]); }); }
function checkAtan(a) { check(function (i) { return Math.atan(a[i]); }); }
function checkAtan2(a) { check(function (i) { return Math.atan2(a[i]); }); }
function checkCeil(a) { check(function (i) { return Math.ceil(a[i]); }); }
function checkCos(a) { check(function (i) { return Math.cos(a[i]); }); }
function checkExp(a) { check(function (i) { return Math.exp(a[i]); }); }
function checkFloor(a) { check(function (i) { return Math.floor(a[i]); }); }
function checkLog(a) { check(function (i) { return Math.log(a[i]); }); }
function checkRound(a) { check(function (i) { return Math.round(a[i]); }); }
function checkSin(a) { check(function (i) { return Math.sin(a[i]); }); }
function checkSqrt(a) { check(function (i) { return Math.sqrt(a[i]); }); }
function checkTan(a) { check(function (i) { return Math.tan(a[i]); }); }
function callVariousUnaryMathFunctions() {
// We might want to consider making this test adopt seedrandom.js
// and call Math.seedrandom("seed") here ...
// function fill(i) { return (2*Math.random())-1; }
// function fill(i) { return (20*Math.random())-10; }
//
// ... but its easiest to just drop the pseudo-random input entirely.
function fill(i) { return 10/i; }
var input = Array.build(len, fill);
checkAbs(input); //print("abs");
checkAcos(input); //print("acos");
checkAsin(input); //print("asin");
checkAtan(input); //print("atan");
checkAtan2(input); //print("atan2");
checkCeil(input); //print("ceil");
checkCos(input); //print("cos");
checkExp(input); //print("exp");
checkFloor(input); //print("floor");
checkLog(input); //print("log");
checkRound(input); //print("round");
checkSin(input); //print("sin");
checkSqrt(input); //print("sqrt");
checkTan(input); //print("tan");
}
if (getBuildConfiguration().parallelJS)
callVariousUnaryMathFunctions();

View File

@ -15,7 +15,7 @@
#include "jit/MIRGraph.h"
using namespace js;
using namespace js::ion;
using namespace js::jit;
using mozilla::Array;

View File

@ -11,7 +11,7 @@
#include "jit/MIRGraph.h"
namespace js {
namespace ion {
namespace jit {
class MIRGraph;
@ -57,6 +57,6 @@ class AliasAnalysis
};
} // namespace js
} // namespace ion
} // namespace jit
#endif /* jit_AliasAnalysis_h */

View File

@ -35,7 +35,7 @@
using namespace js;
using namespace js::frontend;
using namespace js::ion;
using namespace js::jit;
using mozilla::AddToHash;
using mozilla::ArrayLength;
@ -4702,14 +4702,14 @@ GenerateCode(ModuleCompiler &m, ModuleCompiler::Func &func, MIRGenerator &mir, L
m.masm().bind(func.code());
ScopedJSDeletePtr<CodeGenerator> codegen(ion::GenerateCode(&mir, &lir, &m.masm()));
ScopedJSDeletePtr<CodeGenerator> codegen(jit::GenerateCode(&mir, &lir, &m.masm()));
if (!codegen)
return m.fail(NULL, "internal codegen failure (probably out of memory)");
if (!m.collectAccesses(mir))
return false;
ion::IonScriptCounts *counts = codegen->extractUnassociatedScriptCounts();
jit::IonScriptCounts *counts = codegen->extractUnassociatedScriptCounts();
if (counts && !m.addFunctionCounts(counts)) {
js_delete(counts);
return false;
@ -5378,7 +5378,7 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
masm.reserveStack(stackDec);
//JS_ASSERT(masm.framePushed() % 8 == 0);
if(getenv("GDB_BREAK")) {
masm.breakpoint(js::ion::Assembler::Always);
masm.breakpoint(js::jit::Assembler::Always);
}
// Copy parameters out of argv into the registers/stack-slots specified by
// the system ABI.

View File

@ -26,7 +26,7 @@
#include "jsscriptinlines.h"
using namespace js;
using namespace js::ion;
using namespace js::jit;
using mozilla::IsNaN;
@ -350,7 +350,7 @@ CallAsmJS(JSContext *cx, unsigned argc, Value *vp)
{
AsmJSActivation activation(cx, module);
ion::IonContext ictx(cx, NULL);
jit::IonContext ictx(cx, NULL);
JitActivation jitActivation(cx, /* firstFrameIsConstructing = */ false, /* active */ false);
// Call into generated code.

Some files were not shown because too many files have changed in this diff Show More