mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Merge m-c to fx-team.
This commit is contained in:
commit
1f9cf546ef
@ -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
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"revision": "e8f63cae5aff3b61c0a49a9209ae971092ddee22",
|
||||
"revision": "a183b055417d036b01e177750ab2ec6162d6fcd7",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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 &&
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
3
content/xul/content/crashtests/509719-1-overlay.xul
Normal file
3
content/xul/content/crashtests/509719-1-overlay.xul
Normal file
@ -0,0 +1,3 @@
|
||||
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<window id="win" removeelement="true"/>
|
||||
</overlay>
|
3
content/xul/content/crashtests/509719-1.xul
Normal file
3
content/xul/content/crashtests/509719-1.xul
Normal 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>
|
8
content/xul/content/crashtests/509719-2-overlay.xul
Normal file
8
content/xul/content/crashtests/509719-2-overlay.xul
Normal 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>
|
7
content/xul/content/crashtests/509719-2.xul
Normal file
7
content/xul/content/crashtests/509719-2.xul
Normal 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>
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -1243,7 +1243,7 @@ DOMInterfaces = {
|
||||
|
||||
'WebGLActiveInfo': {
|
||||
'nativeType': 'mozilla::WebGLActiveInfo',
|
||||
'headerFile': 'WebGLContext.h',
|
||||
'headerFile': 'WebGLActiveInfo.h',
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
||||
|
@ -22,6 +22,7 @@ if CONFIG['MOZ_B2G_RIL']:
|
||||
'nsIDOMCFStateChangeEvent.idl',
|
||||
'nsIDOMMobileConnection.idl',
|
||||
'nsIDOMMozEmergencyCbModeEvent.idl',
|
||||
'nsIDOMMozOtaStatusEvent.idl',
|
||||
'nsIDOMNetworkStats.idl',
|
||||
'nsIDOMNetworkStatsManager.idl',
|
||||
'nsIMobileConnectionProvider.idl',
|
||||
|
@ -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)]
|
||||
|
21
dom/network/interfaces/nsIDOMMozOtaStatusEvent.idl
Normal file
21
dom/network/interfaces/nsIDOMMozOtaStatusEvent.idl
Normal 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;
|
||||
};
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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();
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
87
dom/system/gonk/tests/test_ril_worker_barring_password.js
Normal file
87
dom/system/gonk/tests/test_ril_worker_barring_password.js
Normal 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();
|
||||
});
|
@ -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]
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
33
dom/webidl/MozOtaStatusEvent.webidl
Normal file
33
dom/webidl/MozOtaStatusEvent.webidl
Normal 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 = "";
|
||||
};
|
@ -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 \
|
||||
|
59
dom/webidl/WifiOptions.webidl
Normal file
59
dom/webidl/WifiOptions.webidl
Normal 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;
|
||||
};
|
@ -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
139
dom/wifi/NetUtils.cpp
Normal 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
60
dom/wifi/NetUtils.h
Normal 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
|
286
dom/wifi/WifiProxyService.cpp
Normal file
286
dom/wifi/WifiProxyService.cpp
Normal 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;
|
38
dom/wifi/WifiProxyService.h
Normal file
38
dom/wifi/WifiProxyService.h
Normal 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
382
dom/wifi/WifiUtils.cpp
Normal 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
133
dom/wifi/WifiUtils.h
Normal 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
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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;
|
||||
})();
|
@ -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
|
||||
|
||||
|
20
dom/wifi/nsIWifiService.idl
Normal file
20
dom/wifi/nsIWifiService.idl
Normal 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();
|
||||
};
|
@ -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;
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
65
ipc/chromium/src/third_party/libevent-avoid-empty-sighandler.patch
vendored
Normal file
65
ipc/chromium/src/third_party/libevent-avoid-empty-sighandler.patch
vendored
Normal 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;
|
||||
|
19
ipc/chromium/src/third_party/libevent/kqueue.c
vendored
19
ipc/chromium/src/third_party/libevent/kqueue.c
vendored
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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:
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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()) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
9
js/src/jit-test/tests/generators/bug908920.js
Normal file
9
js/src/jit-test/tests/generators/bug908920.js
Normal file
@ -0,0 +1,9 @@
|
||||
if (typeof schedulegc != 'undefined') {
|
||||
Function("\
|
||||
x = (function() { yield })();\
|
||||
Set(x);\
|
||||
schedulegc(1);\
|
||||
print( /x/ );\
|
||||
for (p in x) {}\
|
||||
")();
|
||||
}
|
5
js/src/jit-test/tests/ion/bug909505.js
Normal file
5
js/src/jit-test/tests/ion/bug909505.js
Normal file
@ -0,0 +1,5 @@
|
||||
function f(type) {
|
||||
for (var i = 0; i < 3; i++) {}
|
||||
assertEq((new String) instanceof type, true);
|
||||
}
|
||||
f(String);
|
82
js/src/jit-test/tests/parallel/math-fcns.js
Normal file
82
js/src/jit-test/tests/parallel/math-fcns.js
Normal 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();
|
@ -15,7 +15,7 @@
|
||||
#include "jit/MIRGraph.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
using namespace js::jit;
|
||||
|
||||
using mozilla::Array;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user