Bug 712629 - Make Wifi work under gonk. There are large parts of this that are still sketches, but this gets us limping along. r=gal

--HG--
extra : rebase_source : 7fb2de1e4eb22250dbe0958a46e551012ff54ac3
This commit is contained in:
Blake Kaplan 2011-12-06 22:14:55 +08:00
Родитель 4e7545ab62
Коммит 3d440a920c
17 изменённых файлов: 1266 добавлений и 35 удалений

Просмотреть файл

@ -147,6 +147,7 @@
@BINPATH@/components/dom_base.xpt
#ifdef MOZ_B2G_RIL
@BINPATH@/components/dom_telephony.xpt
@BINPATH@/components/dom_wifi.xpt
@BINPATH@/components/dom_system_b2g.xpt
#endif
@BINPATH@/components/dom_battery.xpt
@ -396,6 +397,8 @@
@BINPATH@/components/nsTelephonyWorker.js
@BINPATH@/components/Telephony.manifest
@BINPATH@/components/Telephony.js
@BINPATH@/components/nsWifiWorker.js
@BINPATH@/components/nsWifiWorker.manifest
#endif
#ifdef XP_MACOSX
@BINPATH@/components/libalerts_s.dylib

Просмотреть файл

@ -138,6 +138,7 @@
@BINPATH@/components/dom_base.xpt
#ifdef MOZ_B2G_RIL
@BINPATH@/components/dom_telephony.xpt
@BINPATH@/components/dom_wifi.xpt
@BINPATH@/components/dom_system_b2g.xpt
#endif
@BINPATH@/components/dom_battery.xpt
@ -366,6 +367,8 @@
@BINPATH@/components/nsTelephonyWorker.js
@BINPATH@/components/Telephony.manifest
@BINPATH@/components/Telephony.js
@BINPATH@/components/nsWifiWorker.js
@BINPATH@/components/nsWifiWorker.manifest
#endif
@BINPATH@/components/BrowserProfileMigrators.manifest
@BINPATH@/components/ChromeProfileMigrator.js

Просмотреть файл

@ -70,6 +70,7 @@ components/pluginGlue.js
components/sidebar.xpt
#ifdef MOZ_B2G_RIL
components/dom_telephony.xpt
components/dom_wifi.xpt
components/dom_system_b2g.xpt
#endif
components/uconvd.dll
@ -922,6 +923,8 @@ xpicleanup@BIN_SUFFIX@
components/nsTelephonyWorker.js
components/Telephony.manifest
components/Telephony.js
components/nsWifiWorker.js
components/nsWifiWorker.manifest
#endif
components/txEXSLTRegExFunctions.js
components/Weave.js
@ -1143,6 +1146,7 @@ xpicleanup@BIN_SUFFIX@
components/dom_base.xpt
#ifdef MOZ_B2G_RIL
components/dom_telephony.xpt
components/dom_wifi.xpt
components/dom_system_b2g.xpt
#endif
components/dom_canvas.xpt

Просмотреть файл

@ -84,7 +84,10 @@ DIRS += \
$(NULL)
ifdef MOZ_B2G_RIL #{
DIRS += telephony
DIRS += \
telephony \
wifi \
$(NULL)
endif #}
ifdef ENABLE_TESTS

Просмотреть файл

@ -66,6 +66,7 @@ XPIDLSRCS = \
LOCAL_INCLUDES = \
-I$(topsrcdir)/dom/base \
-I$(topsrcdir)/dom/telephony \
-I$(topsrcdir)/dom/wifi \
-I$(topsrcdir)/content/events/src \
$(NULL)

Просмотреть файл

@ -45,7 +45,11 @@
#include "nsIObserverService.h"
#include "mozilla/dom/workers/Workers.h"
#include "jstypedarray.h"
#include "nsTelephonyWorker.h"
#include "nsITelephone.h"
#include "nsWifiWorker.h"
#include "nsIWifi.h"
#include "nsThreadUtils.h"
@ -60,6 +64,7 @@ USING_WORKERS_NAMESPACE
using namespace mozilla::ipc;
static NS_DEFINE_CID(kTelephonyWorkerCID, NS_TELEPHONYWORKER_CID);
static NS_DEFINE_CID(kWifiWorkerCID, NS_WIFIWORKER_CID);
// Topic we listen to for shutdown.
#define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change"
@ -225,16 +230,6 @@ RadioManager::Init()
nsresult rv = obs->AddObserver(this, PROFILE_BEFORE_CHANGE_TOPIC, false);
NS_ENSURE_SUCCESS(rv, rv);
// The telephony worker component is a hack that gives us a global object for
// our own functions and makes creating the worker possible.
nsCOMPtr<nsIRadioWorker> worker(do_CreateInstance(kTelephonyWorkerCID));
NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
jsval workerval;
rv = worker->GetWorker(&workerval);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(!JSVAL_IS_PRIMITIVE(workerval), "bad worker value");
JSContext *cx;
rv = nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&cx);
NS_ENSURE_SUCCESS(rv, rv);
@ -243,30 +238,11 @@ RadioManager::Init()
return NS_ERROR_FAILURE;
}
JSObject *workerobj = JSVAL_TO_OBJECT(workerval);
rv = InitTelephone(cx);
NS_ENSURE_SUCCESS(rv, rv);
JSAutoRequest ar(cx);
JSAutoEnterCompartment ac;
if (!ac.enter(cx, workerobj)) {
return NS_ERROR_OUT_OF_MEMORY;
}
WorkerCrossThreadDispatcher *wctd = GetWorkerCrossThreadDispatcher(cx, workerval);
if (!wctd) {
return NS_ERROR_FAILURE;
}
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
if (!wctd->PostTask(connection)) {
return NS_ERROR_UNEXPECTED;
}
// Now that we're set up, connect ourselves to the RIL thread.
mozilla::RefPtr<RILReceiver> receiver = new RILReceiver(wctd);
StartRil(receiver);
mTelephone = do_QueryInterface(worker);
NS_ENSURE_TRUE(mTelephone, NS_ERROR_FAILURE);
rv = InitWifi(cx);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
@ -278,6 +254,7 @@ RadioManager::Shutdown()
StopRil();
mTelephone = nsnull;
mWifi = nsnull;
mShutdown = true;
}
@ -316,6 +293,59 @@ RadioManager::GetTelephone()
return nsnull;
}
nsresult
RadioManager::InitTelephone(JSContext *cx)
{
// The telephony worker component is a hack that gives us a global object for
// our own functions and makes creating the worker possible.
nsCOMPtr<nsIRadioWorker> worker(do_CreateInstance(kTelephonyWorkerCID));
NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
jsval workerval;
nsresult rv = worker->GetWorker(&workerval);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(!JSVAL_IS_PRIMITIVE(workerval), "bad worker value");
JSObject *workerobj = JSVAL_TO_OBJECT(workerval);
JSAutoRequest ar(cx);
JSAutoEnterCompartment ac;
if (!ac.enter(cx, workerobj)) {
return NS_ERROR_OUT_OF_MEMORY;
}
WorkerCrossThreadDispatcher *wctd = GetWorkerCrossThreadDispatcher(cx, workerval);
if (!wctd) {
return NS_ERROR_FAILURE;
}
nsRefPtr<ConnectWorkerToRIL> connection = new ConnectWorkerToRIL();
if (!wctd->PostTask(connection)) {
return NS_ERROR_UNEXPECTED;
}
// Now that we're set up, connect ourselves to the RIL thread.
mozilla::RefPtr<RILReceiver> receiver = new RILReceiver(wctd);
StartRil(receiver);
mTelephone = do_QueryInterface(worker);
NS_ENSURE_TRUE(mTelephone, NS_ERROR_FAILURE);
return NS_OK;
}
nsresult
RadioManager::InitWifi(JSContext *cx)
{
nsCOMPtr<nsIRadioWorker> worker(do_CreateInstance(kWifiWorkerCID));
NS_ENSURE_TRUE(worker, NS_ERROR_FAILURE);
mWifi = do_QueryInterface(worker);
NS_ENSURE_TRUE(mWifi, NS_ERROR_FAILURE);
return NS_OK;
}
NS_IMPL_ISUPPORTS1(RadioManager, nsIObserver)

Просмотреть файл

@ -48,7 +48,6 @@
#include "nsIObserver.h"
#include "mozilla/ipc/Ril.h"
#include "nsITelephone.h"
#define TELEPHONYRADIO_CONTRACTID "@mozilla.org/telephony/radio;1"
#define TELEPHONYRADIOINTERFACE_CONTRACTID "@mozilla.org/telephony/radio-interface;1"
@ -70,6 +69,8 @@
class nsIXPConnectJSObjectHolder;
class nsITelephone;
class nsIWifi;
BEGIN_TELEPHONY_NAMESPACE
@ -92,7 +93,11 @@ protected:
RadioManager();
~RadioManager();
nsresult InitTelephone(JSContext *cx);
nsresult InitWifi(JSContext *cx);
nsCOMPtr<nsITelephone> mTelephone;
nsCOMPtr<nsIWifi> mWifi;
bool mShutdown;
};

70
dom/wifi/Makefile.in Normal file
Просмотреть файл

@ -0,0 +1,70 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Telephony.
#
# The Initial Developer of the Original Code is
# The Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Ben Turner <bent.mozilla@gmail.com> (Original Author)
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = dom
LIBRARY_NAME = domwifi_s
XPIDL_MODULE = dom_wifi
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
include $(topsrcdir)/dom/dom-config.mk
XPIDLSRCS = \
nsIWifi.idl \
$(NULL)
EXTRA_COMPONENTS = \
nsWifiWorker.js \
nsWifiWorker.manifest \
$(NULL)
EXTRA_JS_MODULES = \
libcutils.js \
libhardware_legacy.js \
libnetutils.js \
network_worker.js \
$(NULL)
include $(topsrcdir)/config/rules.mk

13
dom/wifi/libcutils.js Normal file
Просмотреть файл

@ -0,0 +1,13 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
"use strict";
let libcutils = (function () {
let library = ctypes.open("/system/lib/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)
};
})();

Просмотреть файл

@ -0,0 +1,36 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
"use strict";
let libhardware_legacy = (function () {
let library = ctypes.open("/system/lib/libhardware_legacy.so");
return {
// 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.int),
// 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),
};
})();

30
dom/wifi/libnetutils.js Normal file
Просмотреть файл

@ -0,0 +1,30 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
"use strict";
let libnetutils = (function () {
let library = ctypes.open("/system/lib/libnetutils.so");
return {
ifc_enable: library.declare("ifc_enable", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
ifc_disable: library.declare("ifc_disable", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
ifc_add_host_route: library.declare("ifc_add_host_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.int),
ifc_remove_host_routes: library.declare("ifc_remove_host_routes", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
ifc_set_default_route: library.declare("ifc_set_default_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr, ctypes.int),
ifc_get_default_route: library.declare("ifc_get_default_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
ifc_remove_default_route: library.declare("ifc_remove_default_route", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
ifc_reset_connections: library.declare("ifc_reset_connections", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
ifc_configure: library.declare("ifc_configure", ctypes.default_abi, ctypes.int, ctypes.char.ptr,
ctypes.int, ctypes.int, ctypes.int, ctypes.int, ctypes.int),
dhcp_do_request: library.declare("dhcp_do_request", ctypes.default_abi, ctypes.int,
ctypes.char.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr,
ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr),
dhcp_stop: library.declare("dhcp_stop", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
dhcp_release_lease: library.declare("dhcp_release_lease", ctypes.default_abi, ctypes.int, ctypes.char.ptr),
dhcp_get_errmsg: library.declare("dhcp_get_errmsg", ctypes.default_abi, ctypes.char.ptr),
dhcp_do_request_renew: library.declare("dhcp_do_request_renew", ctypes.default_abi, ctypes.int,
ctypes.char.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr,
ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr, ctypes.int.ptr)
};
})();

Просмотреть файл

@ -0,0 +1,94 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
"use strict";
importScripts("libhardware_legacy.js", "libnetutils.js", "libcutils.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)();
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());
dump("For command " + data.request + " ret is " + ret + "\n");
var reply = "";
if (!ret) {
var reply_len = len.value;
var str = cbuf.readString();
if (str[reply_len-1] == "\n")
--reply_len;
reply = str.substr(0, reply_len);
}
postMessage({ id: id, status: ret, reply: reply });
break;
case "wait_for_event":
var ret = libhardware_legacy.wait_for_event(cbuf, 4096);
var event = cbuf.readString().substr(0, ret.value);
postMessage({ id: id, event: event });
break;
case "ifc_enable":
case "ifc_disable":
case "ifc_remove_host_routes":
case "ifc_remove_default_route":
case "ifc_reset_connections":
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":
dump("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 ret = libnetutils[cmd](data.ifname,
ints.addressOfElement(0),
ints.addressOfElement(1),
ints.addressOfElement(2),
ints.addressOfElement(3),
ints.addressOfElement(4),
ints.addressOfElement(5),
ints.addressOfElement(6));
postMessage({ id: id, status: ret, ipaddr: ints[0], gateway: ints[1], mask: ints[2],
dns1: ints[3], dns2: ints[4], server: ints[5], lease: ints[6]});
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;
default:
var f = libhardware_legacy[cmd] || libnetutils[cmd];
var ret = f();
dump("WIFI: " + cmd + " returned: " + ret);
postMessage({ id: id, status: ret });
break;
}
}

42
dom/wifi/nsIWifi.idl Normal file
Просмотреть файл

@ -0,0 +1,42 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Telephony.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Philipp von Weitershausen <philipp@weitershausen.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
[scriptable, uuid(9DCE05BF-659C-4427-A050-0EAC3BB6C1C0)]
interface nsIWifi : nsISupports {
};

40
dom/wifi/nsWifiWorker.h Normal file
Просмотреть файл

@ -0,0 +1,40 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Telephony.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Turner <bent.mozilla@gmail.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#define NS_WIFIWORKER_CID \
{ 0xA14E8977, 0xD259, 0x433A, \
{ 0xA8, 0x8D, 0x58, 0xDD, 0x44, 0x65, 0x7E, 0x5B } }

853
dom/wifi/nsWifiWorker.js Normal file
Просмотреть файл

@ -0,0 +1,853 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Telephony.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Andreas Gal <gal@mozilla.com>
* Blake Kaplan <mrbkap@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const DEBUG = true; // set to false to suppress debug messages
const WIFIWORKER_CONTRACTID = "@mozilla.org/wifi/worker;1";
const WIFIWORKER_CID = Components.ID("{a14e8977-d259-433a-a88d-58dd44657e5b}");
const WIFIWORKER_WORKER = "resource://gre/modules/network_worker.js";
var WifiManager = (function() {
var controlWorker = new ChromeWorker(WIFIWORKER_WORKER);
var eventWorker = new ChromeWorker(WIFIWORKER_WORKER);
// Callbacks to invoke when a reply arrives from the controlWorker.
var controlCallbacks = Object.create(null);
var idgen = 0;
function controlMessage(obj, callback) {
var id = idgen++;
obj.id = id;
if (callback)
controlCallbacks[id] = callback;
controlWorker.postMessage(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;
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" });
}
// Commands to the control worker
function voidControlMessage(cmd, callback) {
controlMessage({ cmd: cmd }, function (data) {
callback(data.status);
});
}
function loadDriver(callback) {
voidControlMessage("load_driver", callback);
}
function unloadDriver(callback) {
voidControlMessage("unload_driver", callback);
}
function startSupplicant(callback) {
voidControlMessage("start_supplicant", callback);
}
function stopSupplicant(callback) {
voidControlMessage("stop_supplicant", callback);
}
function connectToSupplicant(callback) {
voidControlMessage("connect_to_supplicant", callback);
}
function closeSupplicantConnection(callback) {
voidControlMessage("close_supplicant_connection", callback);
}
function doCommand(request, callback) {
controlMessage({ cmd: "command", request: request }, callback);
}
function doIntCommand(request, callback) {
doCommand(request, function(data) {
callback(data.status ? -1 : (data.reply|0));
});
}
function doBooleanCommand(request, expected, callback) {
doCommand(request, function(data) {
callback(data.status ? false : (data.reply == expected));
});
}
function doStringCommand(request, callback) {
doCommand(request, function(data) {
callback(data.status ? null : data.reply);
});
}
function listNetworksCommand(callback) {
doStringCommand("LIST_NETWORKS", callback);
}
function addNetworkCommand(callback) {
doIntCommand("ADD_NETWORK", callback);
}
function setNetworkVariableCommand(netId, name, value, callback) {
doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value, "OK", callback);
}
function getNetworkVariableCommand(netId, name, callback) {
doStringCommand("GET_NETWORK " + netId + " " + name, callback);
}
function removeNetworkCommand(netId, callback) {
doBooleanCommand("REMOVE_NETWORK " + netId, callback);
}
function enableNetworkCommand(netId, disableOthers, callback) {
doBooleanCommand((disableOthers ? "SELECT_NETWORK " : "ENABLE_NETWORK ") + netId, "OK", callback);
}
function disableNetworkCommand(netId, callback) {
doBooleanCommand("DISABLE_NETWORK " + netId, "OK", callback);
}
function statusCommand(callback) {
doStringCommand("STATUS", callback);
}
function pingCommand(callback) {
doBooleanCommand("PING", "PONG", callback);
}
function scanResultsCommand(callback) {
doStringCommand("SCAN_RESULTS", callback);
}
function disconnectCommand(callback) {
doBooleanCommand("DISCONNECT", "OK", callback);
}
function reconnectCommand(callback) {
doBooleanCommand("RECONNECT", "OK", callback);
}
function reassociateCommand(callback) {
doBooleanCommand("REASSOCIATE", "OK", callback);
}
var scanModeActive = false;
function doSetScanModeCommand(setActive, callback) {
doBooleanCommand(setActive ? "DRIVER SCAN-ACTIVE" : "DRIVER SCAN-PASSIVE", "OK", callback);
}
function scanCommand(forceActive, callback) {
if (forceActive && !scanModeActive) {
doSetScanModeCommand(true, function(ok) {
ok && doBooleanCommand("SCAN", "OK", function(ok) {
ok && doSetScanModeCommand(false, callback);
});
});
return;
}
doBooleanCommand("SCAN", "OK", callback);
}
function setScanModeCommand(setActive, callback) {
sScanModeActive = setActive;
doSetScanModeCommand(setActive, callback);
}
function startDriverCommand(callback) {
doBooleanCommand("DRIVER START", "OK");
}
function stopDriverCommand(callback) {
doBooleanCommand("DRIVER STOP", "OK");
}
function startPacketFiltering(callback) {
doBooleanCommand("DRIVER RXFILTER-ADD 0", "OK", function(ok) {
ok && doBooleanCommand("DRIVER RXFILTER-ADD 1", "OK", function(ok) {
ok && doBooleanCommand("DRIVER RXFILTER-ADD 3", "OK", function(ok) {
ok && doBooleanCommand("DRIVER RXFILTER-START", "OK", callback)
});
});
});
}
function stopPacketFiltering(callback) {
doBooleanCommand("DRIVER RXFILTER-STOP", "OK", function(ok) {
ok && doBooleanCommand("DRIVER RXFILTER-REMOVE 3", "OK", function(ok) {
ok && doBooleanCommand("DRIVER RXFILTER-REMOVE 1", "OK", function(ok) {
ok && doBooleanCommand("DRIVER RXFILTER-REMOVE 0", "OK", callback)
});
});
});
}
function doGetRssiCommand(cmd, callback) {
doCommand(cmd, function(data) {
var rssi = -200;
if (!data.status) {
// If we are associating, the reply is "OK".
var reply = data.reply;
if (reply != "OK") {
// Format is: <SSID> rssi XX". SSID can contain spaces.
var offset = reply.lastIndexOf("rssi ");
if (offset != -1)
rssi = reply.substr(offset + 5) | 0;
}
}
callback(rssi);
});
}
function getRssiCommand(callback) {
doGetRssiCommand("DRIVER RSSI", callback);
}
function getRssiApproxCommand(callback) {
doGetRssiCommand("DRIVER RSSI-APPROX", callback);
}
function getLinkSpeedCommand(callback) {
doStringCommand("DRIVER LINKSPEED", function(reply) {
if (reply)
reply = reply.split()[1] | 0; // Format: LinkSpeed XX
callback(reply);
});
}
function getMacAddressCommand(callback) {
doStringCommand("DRIVER MACADDR", function(reply) {
if (reply)
reply = reply.split(" ")[2]; // Format: Macaddr = XX.XX.XX.XX.XX.XX
callback(reply);
});
}
function setPowerModeCommand(mode, callback) {
doBooleanCommand("DRIVER POWERMODE " + mode, "OK", callback);
}
function getPowerModeCommand(callback) {
doStringCommand("DRIVER GETPOWER", function(reply) {
if (reply)
reply = (reply.split()[2]|0); // Format: powermode = XX
callback(reply);
});
}
function setNumAllowedChannelsCommand(numChannels, callback) {
doBooleanCommand("DRIVER SCAN-CHANNELS " + numChannels, "OK", callback);
}
function getNumAllowedChannelsCommand(callback) {
doStringCommand("DRIVER SCAN-CHANNELS", function(reply) {
if (reply)
reply = (reply.split()[2]|0); // Format: Scan-Channels = X
callback(reply);
});
}
function setBluetoothCoexistenceModeCommand(mode, callback) {
doBooleanCommand("DRIVER BTCOEXMODE " + mode, "OK", callback);
}
function setBluetoothCoexistenceScanModeCommand(mode, callback) {
doBooleanCommand("DRIVER BTCOEXSCAN-" + (mode ? "START" : "STOP"), "OK", callback);
}
function saveConfigCommand(callback) {
// Make sure we never write out a value for AP_SCAN other than 1
doBooleanCommand("AP_SCAN 1", "OK", function(ok) {
doBooleanCommand("SAVE_CONFIG", "OK", callback);
});
}
function reloadConfigCommand(callback) {
doBooleanCommand("RECONFIGURE", "OK", callback);
}
function setScanResultHandlingCommand(mode, callback) {
doBooleanCommand("AP_SCAN " + mode, "OK", callback);
}
function addToBlacklistCommand(bssid, callback) {
doBooleanCommand("BLACKLIST " + bssid, "OK", callback);
}
function clearBlacklistCommand(callback) {
doBooleanCommand("BLACKLIST clear", "OK", callback);
}
function setSuspendOptimizationsCommand(enabled, callback) {
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);
});
}
function setProperty(key, value, callback) {
controlMessage({ cmd: "property_set", key: key, value: value }, function(data) {
callback(!data.status);
});
}
function enableInterface(ifname, callback) {
controlMessage({ cmd: "ifc_enable", ifname: ifname }, function(data) {
callback(!data.status);
});
}
function disableInterface(ifname, callback) {
controlMessage({ cmd: "ifc_disable", ifname: ifname }, function(data) {
callback(!data.status);
});
}
function addHostRoute(ifname, route, callback) {
controlMessage({ cmd: "ifc_add_host_route", ifname: ifname, route: route }, function(data) {
callback(!data.status);
});
}
function removeHostRoutes(ifname, callback) {
controlMessage({ cmd: "ifc_remove_host_routes", ifname: ifname }, function(data) {
callback(!data.status);
});
}
function setDefaultRoute(ifname, route, callback) {
controlMessage({ cmd: "ifc_set_default_route", ifname: ifname, route: route }, function(data) {
callback(!data.status);
});
}
function getDefaultRoute(ifname, callback) {
controlMessage({ cmd: "ifc_get_default_route", ifname: ifname }, function(data) {
callback(!data.route);
});
}
function removeDefaultRoute(ifname, callback) {
controlMessage({ cmd: "ifc_remove_default_route", ifname: ifname }, function(data) {
callback(!data.status);
});
}
function resetConnections(ifname, callback) {
controlMessage({ cmd: "ifc_reset_connections", ifname: ifname }, function(data) {
callback(!data.status);
});
}
function runDhcp(ifname, callback) {
controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
callback(data.status ? null : data);
});
}
function stopDhcp(ifname, callback) {
controlMessage({ cmd: "dhcp_stop", ifname: ifname }, function(data) {
callback(!data.status);
});
}
function releaseDhcpLease(ifname, callback) {
controlMessage({ cmd: "dhcp_release_lease", ifname: ifname }, function(data) {
callback(!data.status);
});
}
function getDhcpError(callback) {
controlMessage({ cmd: "dhcp_get_errmsg" }, function(data) {
callback(data.error);
});
}
function configureInterface(ifname, ipaddr, mask, gateway, dns1, dns2, callback) {
controlMessage({ cmd: "ifc_configure", ifname: ifname,
ipaddr: ipaddr, mask: mask, gateway: gateway,
dns1: dns1, dns2: dns2}, function(data) {
callback(!data.status);
});
}
function runDhcpRenew(ifname, callback) {
controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
callback(data.status ? null : data);
});
}
var manager = {};
function notify(eventName, eventObject) {
var handler = manager["on" + eventName];
if (handler) {
if (!eventObject)
eventObject = ({});
handler.call(eventObject);
}
}
// try to connect to the supplicant
var connectTries = 0;
var retryTimer = null;
function connectCallback(ok) {
if (ok === 0) {
// tell the event worker to start waiting for events
retryTimer = null;
waitForEvent();
notify("supplicantconnection");
return;
}
if (connectTries++ < 3) {
// try again in 5 seconds
if (!retryTimer)
retryTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
retryTimer.initWithCallback(function(timer) {
connectToSupplicant(connectCallback);
}, 5000, Ci.nsITimer.TYPE_ONE_SHOT);
return;
}
retryTimer = null;
notify("supplicantlost");
}
manager.start = function() {
connectToSupplicant(connectCallback);
}
var supplicantStatesMap = ["DISCONNECTED", "INACTIVE", "SCANNING", "ASSOCIATING",
"FOUR_WAY_HANDSHAKE", "GROUP_HANDSHAKE", "COMPLETED",
"DORMANT", "UNINITIALIZED"];
var driverEventMap = { STOPPED: "driverstopped", STARTED: "driverstarted", HANGED: "driverhung" };
// handle events sent to us by the event worker
function handleEvent(event) {
debug("Event coming in: " + event);
if (event.indexOf("CTRL-EVENT-") !== 0) {
debug("Got weird event, possibly not doing anything.");
if (event.indexOf("WPA:") == 0 &&
event.indexOf("pre-shared key may be incorrect") != -1) {
notify("passwordmaybeincorrect");
}
return true;
}
var eventData = event.substr(0, event.indexOf(" ") + 1);
if (eventData.indexOf("CTRL-EVENT-STATE-CHANGE") === 0) {
// Parse the event data
var fields = {};
var tokens = eventData.split(" ");
for (var n = 0; n < tokens.length; ++n) {
var kv = tokens[n].split("=");
if (kv.length === 2)
fields[kv[0]] = kv[1];
}
if (!("state" in fields))
return true;
fields.state = supplicantStatesMap[fields.state];
notify("statechange", fields);
return true;
}
if (eventData.indexOf("CTRL-EVENT-DRIVER-STATE") === 0) {
var handlerName = driverEventMap[eventData];
if (handlerName)
notify(handlerName);
return true;
}
if (eventData.indexOf("CTRL-EVENT-TERMINATING") === 0) {
// If the monitor socket is closed, we have already stopped the
// supplicant and we can stop waiting for more events and
// simply exit here (we don't have to notify).
if (eventData.indexOf("connection closed") !== -1)
return false;
// As long we haven't seen too many recv errors yet, we
// will keep going for a bit longer
if (eventData.indexOf("recv error") !== -1 && ++recvErrors < 10)
return true;
notify("supplicantlost");
return false;
}
if (eventData.indexOf("CTRL-EVENT-DISCONNECTED") === 0) {
notify("statechange", { state: "DISCONNECTED" });
return true;
}
if (eventData.indexOf("CTRL-EVENT-CONNECTED") === 0) {
// Format: CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=]
var bssid = eventData.split(" ")[4];
var id = eventData.substr(eventData.indexOf("id=")).split(" ")[0];
notify("statechange", { state: "CONNECTED", BSSID: bssid, id: id });
return true;
}
if (eventData.indexOf("CTRL-EVENT-SCAN-RESULTS") === 0) {
debug("Notifying of scn results available");
notify("scanresultsavailable");
return true;
}
// unknown event
return true;
}
// Initial state
var airplaneMode = false;
// Public interface of the wifi service
manager.setWifiEnabled = function(enable, callback) {
var targetState = enable ? "ENABLED" : "DISABLED";
if (enable == targetState)
return true;
if (enable && airplaneMode)
return false;
if (enable) {
loadDriver(function (ok) {
(ok === 0) ? startSupplicant(callback) : callback(-1);
});
} else {
stopSupplicant(function (ok) {
(ok === 0) ? unloadDriver(callback) : callback(-1);
});
}
}
manager.disconnect = disconnectCommand;
manager.reconnect = reconnectCommand;
manager.reassociate = reassociateCommand;
var networkConfigurationFields = ["ssid", "bssid", "psk", "wep_key0", "wep_key1", "wep_key2", "wep_key3",
"wep_tx_keyidx", "priority", "key_mgmt", "scan_ssid"];
manager.getNetworkConfiguration = function(config, callback) {
var netId = config.netId;
var done = 0;
for (var n = 0; n < networkConfigurationFields; ++n) {
var fieldName = networkConfigurationFields[n];
getNetworkVariableCommand(netId, fieldName, function(value) {
config[fieldName] = value;
if (++done == networkConfigurationFields.length)
callback(config);
});
}
}
manager.setNetworkConfiguration = function(config, callback) {
var netId = config.netId;
var done = 0;
var errors = 0;
for (var n = 0; n < networkConfigurationFields.length; ++n) {
var fieldName = networkConfigurationFields[n];
if (!(fieldName in config)) {
++done;
} else {
setNetworkVariableCommand(netId, fieldName, config[fieldName], function(ok) {
if (!ok)
++errors;
if (++done == networkConfigurationFields.length)
callback(errors == 0);
});
}
}
// If config didn't contain any of the fields we want, don't lose the error callback
if (done == networkConfigurationFields.length)
callback(false);
}
manager.getConfiguredNetworks = function(callback) {
listNetworksCommand(function (reply) {
var networks = {};
var done = 0;
var errors = 0;
var lines = reply.split("\n");
for (var n = 1; n < lines.length; ++n) {
var result = lines[n].split("\t");
var netId = result[0];
var config = networks[netId] = { netId: netId };
switch (result[3]) {
case "[CURRENT]":
config.status = "CURRENT";
break;
case "[DISABLED]":
config.status = "DISABLED";
break;
default:
config.status = "ENABLED";
break;
}
manager.getNetworkConfiguration(config, function (ok) {
if (!ok)
++errors;
if (++done == lines.length - 1) {
if (errors) {
// If an error occured, delete the new netId
removeNetworkCommand(netId, function() {
callback(null);
});
} else {
callback(networks);
}
}
});
}
});
}
manager.addNetwork = function(config, callback) {
addNetworkCommand(function (netId) {
config.netId = netId;
manager.setNetworkConfiguration(config, callback);
});
}
manager.updateNetwork = function(config, callback) {
manager.setNetworkConfiguration(config, callback);
}
manager.removeNetwork = function(netId, callback) {
removeNetworkCommand(netId, callback);
}
function ipToString(n) {
return String((n & (0xff << 24)) >> 24) + "." +
((n & (0xff << 16)) >> 16) + "." +
((n & (0xff << 8)) >> 8) + "." +
((n & (0xff << 0)) >> 0);
}
manager.enableNetwork = function(netId, disableOthers, callback) {
getProperty("wifi.interface", "tiwlan0", function (ifname) {
if (!ifname) {
callback(false);
return;
}
enableInterface(ifname, function (ok) {
if (!ok) {
callback(false);
return;
}
enableNetworkCommand(netId, disableOthers, function (ok) {
if (!ok) {
disableInterface(ifname, function () {
callback(false);
});
return;
}
runDhcp(ifname, function (data) {
debug("After running dhcp, got data: " + uneval(data));
if (!data) {
disableInterface(ifname, function() {
callback(false);
});
return;
}
setProperty("net.dns1", ipToString(data.dns1), function(ok) {
if (!ok) {
callback(false);
return;
}
getProperty("net.dnschange", "0", function(value) {
if (value === null) {
callback(false);
return;
}
setProperty("net.dnschange", String(Number(value) + 1), function(ok) {
callback(ok);
});
});
});
});
});
});
});
}
manager.disableNetwork = function(netId, callback) {
disableNetworkCommand(netId, callback);
}
manager.getMacAddress = getMacAddressCommand;
manager.getScanResults = scanResultsCommand;
return manager;
})();
function nsWifiWorker() {
WifiManager.onsupplicantconnection = function() {
debug("Connected to supplicant");
WifiManager.getMacAddress(function (mac) {
debug("Got mac: " + mac);
});
}
WifiManager.onsupplicantlost = function() {
debug("Couldn't connect to supplicant");
}
var networks = Object.create(null);
WifiManager.onscanresultsavailable = function() {
debug("Scan results are available! Asking for them.");
if (networks["Mozilla Guest"])
return;
WifiManager.getScanResults(function(r) {
let lines = r.split("\n");
// NB: Skip the header line.
let added = !("Mozilla Guest" in networks);
for (let i = 1; i < lines.length; ++i) {
// bssid / frequency / signal level / flags / ssid
var match = /([\S]+)\s+([\S]+)\s+([\S]+)\s+(\[[\S]+\])?\s+(.*)/.exec(lines[i])
if (match)
networks[match[5]] = match[1];
else
debug("Match didn't find anything for: " + lines[i]);
}
if (("Mozilla Guest" in networks) && added) {
debug("Mozilla Guest exists in networks, trying to connect!");
var config = Object.create(null);
config["ssid"] = '"Mozilla Guest"';
//config["bssid"] = '"' + networks["Mozilla Guest"] + '"';
config["key_mgmt"] = "NONE";
config["scan_ssid"] = 1;
WifiManager.addNetwork(config, function (ok) {
if (ok) {
WifiManager.enableNetwork(config.netId, false, function (ok) {
if (ok)
debug("Enabled the network!");
else
debug("Failed to enable the network :(");
});
} else {
debug("Failed to add the network :(");
}
});
}
});
}
WifiManager.setWifiEnabled(true, function (ok) {
if (ok === 0)
WifiManager.start();
else
debug("Couldn't start Wifi");
});
debug("Wifi starting");
}
nsWifiWorker.prototype = {
classID: WIFIWORKER_CID,
classInfo: XPCOMUtils.generateCI({classID: WIFIWORKER_CID,
contractID: WIFIWORKER_CONTRACTID,
classDescription: "WifiWorker",
interfaces: [Ci.nsIRadioWorker,
Ci.nsIWifi]}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRadioWorker,
Ci.nsIWifi]),
setWifiEnabled: function(enable) {
WifiManager.setWifiEnabled(enable, function (ok) {
debug(ok);
});
},
// This is a bit ugly, but works. In particular, this depends on the fact
// that RadioManager never actually tries to get the worker from us.
get worker() { throw "Not implemented"; },
shutdown: function() {
this.setWifiEnabled(false);
}
};
const NSGetFactory = XPCOMUtils.generateNSGetFactory([nsWifiWorker]);
let debug;
if (DEBUG) {
debug = function (s) {
dump("-*- nsWifiWorker component: " + s + "\n");
};
} else {
debug = function (s) {};
}

Просмотреть файл

@ -0,0 +1 @@
component {a14e8977-d259-433a-a88d-58dd44657e5b} nsWifiWorker.js

Просмотреть файл

@ -154,6 +154,7 @@
@BINPATH@/components/dom_base.xpt
#ifdef MOZ_B2G_RIL
@BINPATH@/components/dom_telephony.xpt
@BINPATH@/components/dom_wifi.xpt
@BINPATH@/components/dom_system_b2g.xpt
#endif
@BINPATH@/components/dom_battery.xpt
@ -398,6 +399,8 @@
@BINPATH@/components/nsTelephonyWorker.js
@BINPATH@/components/Telephony.manifest
@BINPATH@/components/Telephony.js
@BINPATH@/components/nsWifiWorker.js
@BINPATH@/components/nsWifiWorker.manifest
#endif
#ifdef XP_MACOSX
@BINPATH@/components/libalerts_s.dylib