mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 912015 - Support multiple wap_supplicant connections. r=mrbkap
This commit is contained in:
parent
11e739f7c6
commit
4b2cee8645
@ -15,7 +15,7 @@ Cu.import("resource://gre/modules/systemlibs.js");
|
||||
const SUPP_PROP = "init.svc.wpa_supplicant";
|
||||
const WPA_SUPPLICANT = "wpa_supplicant";
|
||||
|
||||
this.WifiCommand = function(controlMessage) {
|
||||
this.WifiCommand = function(aControlMessage, aInterface) {
|
||||
var command = {};
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -337,16 +337,17 @@ this.WifiCommand = function(controlMessage) {
|
||||
//--------------------------------------------------
|
||||
|
||||
function voidControlMessage(cmd, callback) {
|
||||
controlMessage({ cmd: cmd }, function (data) {
|
||||
aControlMessage({ cmd: cmd, iface: aInterface }, function (data) {
|
||||
callback(data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function doCommand(request, callback) {
|
||||
var msg = { cmd: "command",
|
||||
request: request };
|
||||
request: request,
|
||||
iface: aInterface };
|
||||
|
||||
controlMessage(msg, callback);
|
||||
aControlMessage(msg, callback);
|
||||
}
|
||||
|
||||
function doIntCommand(request, callback) {
|
||||
|
@ -19,7 +19,7 @@ using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
|
||||
// The singleton Wifi service, to be used on the main thread.
|
||||
StaticRefPtr<WifiProxyService> gWifiProxyService;
|
||||
static StaticRefPtr<WifiProxyService> gWifiProxyService;
|
||||
|
||||
// The singleton supplicant class, that can be used on any thread.
|
||||
static nsAutoPtr<WpaSupplicant> gWpaSupplicant;
|
||||
@ -28,7 +28,9 @@ static nsAutoPtr<WpaSupplicant> gWpaSupplicant;
|
||||
class WifiEventDispatcher : public nsRunnable
|
||||
{
|
||||
public:
|
||||
WifiEventDispatcher(nsAString& aEvent): mEvent(aEvent)
|
||||
WifiEventDispatcher(const nsAString& aEvent, const nsACString& aInterface)
|
||||
: mEvent(aEvent)
|
||||
, mInterface(aInterface)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
}
|
||||
@ -36,19 +38,21 @@ public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gWifiProxyService->DispatchWifiEvent(mEvent);
|
||||
gWifiProxyService->DispatchWifiEvent(mEvent, mInterface);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsString mEvent;
|
||||
nsCString mInterface;
|
||||
};
|
||||
|
||||
// Runnable used to call WaitForEvent on the event thread.
|
||||
class EventRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
EventRunnable()
|
||||
EventRunnable(const nsACString& aInterface)
|
||||
: mInterface(aInterface)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
@ -57,20 +61,24 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
nsAutoString event;
|
||||
gWpaSupplicant->WaitForEvent(event);
|
||||
gWpaSupplicant->WaitForEvent(event, mInterface);
|
||||
if (!event.IsEmpty()) {
|
||||
nsCOMPtr<nsIRunnable> runnable = new WifiEventDispatcher(event);
|
||||
nsCOMPtr<nsIRunnable> runnable = new WifiEventDispatcher(event, mInterface);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCString mInterface;
|
||||
};
|
||||
|
||||
// Runnable used dispatch the Command result on the main thread.
|
||||
class WifiResultDispatcher : public nsRunnable
|
||||
{
|
||||
public:
|
||||
WifiResultDispatcher(WifiResultOptions& aResult)
|
||||
WifiResultDispatcher(WifiResultOptions& aResult, const nsACString& aInterface)
|
||||
: mInterface(aInterface)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
@ -106,33 +114,38 @@ public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gWifiProxyService->DispatchWifiResult(mResult);
|
||||
gWifiProxyService->DispatchWifiResult(mResult, mInterface);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
WifiResultOptions mResult;
|
||||
nsCString mInterface;
|
||||
};
|
||||
|
||||
// Runnable used to call SendCommand on the control thread.
|
||||
class ControlRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ControlRunnable(CommandOptions aOptions) : mOptions(aOptions) {
|
||||
ControlRunnable(CommandOptions aOptions, const nsACString& aInterface)
|
||||
: mOptions(aOptions)
|
||||
, mInterface(aInterface)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
WifiResultOptions result;
|
||||
if (gWpaSupplicant->ExecuteCommand(mOptions, result)) {
|
||||
nsCOMPtr<nsIRunnable> runnable = new WifiResultDispatcher(result);
|
||||
if (gWpaSupplicant->ExecuteCommand(mOptions, result, mInterface)) {
|
||||
nsCOMPtr<nsIRunnable> runnable = new WifiResultDispatcher(result, mInterface);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
CommandOptions mOptions;
|
||||
nsCString mInterface;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(WifiProxyService, nsIWifiProxyService)
|
||||
@ -170,23 +183,33 @@ WifiProxyService::FactoryCreate()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WifiProxyService::Start(nsIWifiEventListener* aListener)
|
||||
WifiProxyService::Start(nsIWifiEventListener* aListener,
|
||||
const char ** aInterfaces,
|
||||
uint32_t aNumOfInterfaces)
|
||||
{
|
||||
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;
|
||||
nsresult rv;
|
||||
|
||||
// Since EventRunnable runs in the manner of blocking, we have to
|
||||
// spin a thread for each interface.
|
||||
// (See the WpaSupplicant::WaitForEvent)
|
||||
mEventThreadList.SetLength(aNumOfInterfaces);
|
||||
for (uint32_t i = 0; i < aNumOfInterfaces; i++) {
|
||||
mEventThreadList[i].mInterface = aInterfaces[i];
|
||||
rv = NS_NewThread(getter_AddRefs(mEventThreadList[i].mThread));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Can't create wifi event thread");
|
||||
Shutdown();
|
||||
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;
|
||||
Shutdown();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -199,15 +222,23 @@ NS_IMETHODIMP
|
||||
WifiProxyService::Shutdown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mEventThread->Shutdown();
|
||||
mEventThread = nullptr;
|
||||
mControlThread->Shutdown();
|
||||
mControlThread = nullptr;
|
||||
for (size_t i = 0; i < mEventThreadList.Length(); i++) {
|
||||
if (mEventThreadList[i].mThread) {
|
||||
mEventThreadList[i].mThread->Shutdown();
|
||||
mEventThreadList[i].mThread = nullptr;
|
||||
}
|
||||
}
|
||||
mEventThreadList.Clear();
|
||||
if (mControlThread) {
|
||||
mControlThread->Shutdown();
|
||||
mControlThread = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WifiProxyService::SendCommand(const JS::Value& aOptions, JSContext* aCx)
|
||||
WifiProxyService::SendCommand(const JS::Value& aOptions, const nsACString& aInterface,
|
||||
JSContext* aCx)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
WifiCommandOptions options;
|
||||
@ -220,22 +251,30 @@ WifiProxyService::SendCommand(const JS::Value& aOptions, JSContext* aCx)
|
||||
|
||||
// Dispatch the command to the control thread.
|
||||
CommandOptions commandOptions(options);
|
||||
nsCOMPtr<nsIRunnable> runnable = new ControlRunnable(commandOptions);
|
||||
nsCOMPtr<nsIRunnable> runnable = new ControlRunnable(commandOptions, aInterface);
|
||||
mControlThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WifiProxyService::WaitForEvent()
|
||||
WifiProxyService::WaitForEvent(const nsACString& aInterface)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsCOMPtr<nsIRunnable> runnable = new EventRunnable();
|
||||
mEventThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
|
||||
// Dispatch to the event thread which has the given interface name
|
||||
for (size_t i = 0; i < mEventThreadList.Length(); i++) {
|
||||
if (mEventThreadList[i].mInterface.Equals(aInterface)) {
|
||||
nsCOMPtr<nsIRunnable> runnable = new EventRunnable(aInterface);
|
||||
mEventThreadList[i].mThread->Dispatch(runnable, nsIEventTarget::DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void
|
||||
WifiProxyService::DispatchWifiResult(const WifiResultOptions& aOptions)
|
||||
WifiProxyService::DispatchWifiResult(const WifiResultOptions& aOptions, const nsACString& aInterface)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -247,15 +286,15 @@ WifiProxyService::DispatchWifiResult(const WifiResultOptions& aOptions)
|
||||
}
|
||||
|
||||
// Call the listener with a JS value.
|
||||
mListener->OnCommand(val);
|
||||
mListener->OnCommand(val, aInterface);
|
||||
}
|
||||
|
||||
void
|
||||
WifiProxyService::DispatchWifiEvent(const nsAString& aEvent)
|
||||
WifiProxyService::DispatchWifiEvent(const nsAString& aEvent, const nsACString& aInterface)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// Call the listener.
|
||||
mListener->OnWaitEvent(aEvent);
|
||||
mListener->OnWaitEvent(aEvent, aInterface);
|
||||
}
|
||||
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WifiProxyService,
|
||||
|
@ -9,11 +9,19 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsThread.h"
|
||||
#include "mozilla/dom/WifiOptionsBinding.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WifiProxyService MOZ_FINAL : public nsIWifiProxyService
|
||||
{
|
||||
private:
|
||||
struct EventThreadListEntry
|
||||
{
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
nsCString mInterface;
|
||||
};
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWIFIPROXYSERVICE
|
||||
@ -21,14 +29,15 @@ public:
|
||||
static already_AddRefed<WifiProxyService>
|
||||
FactoryCreate();
|
||||
|
||||
void DispatchWifiEvent(const nsAString& aEvent);
|
||||
void DispatchWifiResult(const mozilla::dom::WifiResultOptions& aOptions);
|
||||
void DispatchWifiEvent(const nsAString& aEvent, const nsACString& aInterface);
|
||||
void DispatchWifiResult(const mozilla::dom::WifiResultOptions& aOptions,
|
||||
const nsACString& aInterface);
|
||||
|
||||
private:
|
||||
WifiProxyService();
|
||||
~WifiProxyService();
|
||||
|
||||
nsCOMPtr<nsIThread> mEventThread;
|
||||
nsTArray<EventThreadListEntry> mEventThreadList;
|
||||
nsCOMPtr<nsIThread> mControlThread;
|
||||
nsCOMPtr<nsIWifiEventListener> mListener;
|
||||
};
|
||||
|
@ -221,12 +221,12 @@ WpaSupplicant::WpaSupplicant()
|
||||
mNetUtils = new NetUtils();
|
||||
};
|
||||
|
||||
void WpaSupplicant::WaitForEvent(nsAString& aEvent)
|
||||
void WpaSupplicant::WaitForEvent(nsAString& aEvent, const nsCString& aInterface)
|
||||
{
|
||||
CHECK_HWLIB()
|
||||
|
||||
char buffer[BUFFER_SIZE];
|
||||
int32_t ret = mImpl->do_wifi_wait_for_event("wlan0", buffer, BUFFER_SIZE);
|
||||
int32_t ret = mImpl->do_wifi_wait_for_event(aInterface.get(), buffer, BUFFER_SIZE);
|
||||
CheckBuffer(buffer, ret, aEvent);
|
||||
}
|
||||
|
||||
@ -244,7 +244,8 @@ uint32_t WpaSupplicant::MakeMask(uint32_t len) {
|
||||
}
|
||||
|
||||
bool WpaSupplicant::ExecuteCommand(CommandOptions aOptions,
|
||||
WifiResultOptions& aResult)
|
||||
WifiResultOptions& aResult,
|
||||
const nsCString& aInterface)
|
||||
{
|
||||
CHECK_HWLIB(false)
|
||||
if (!mNetUtils->GetSharedLibrary()) {
|
||||
@ -258,7 +259,7 @@ bool WpaSupplicant::ExecuteCommand(CommandOptions aOptions,
|
||||
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);
|
||||
aResult.mStatus = mImpl->do_wifi_command(aInterface.get(), request.get(), buffer, &len);
|
||||
nsString value;
|
||||
if (aResult.mStatus == 0) {
|
||||
if (buffer[len - 1] == '\n') { // remove trailing new lines.
|
||||
@ -269,7 +270,7 @@ bool WpaSupplicant::ExecuteCommand(CommandOptions aOptions,
|
||||
}
|
||||
aResult.mReply = value;
|
||||
} else if (aOptions.mCmd.EqualsLiteral("close_supplicant_connection")) {
|
||||
mImpl->do_wifi_close_supplicant_connection("wlan0");
|
||||
mImpl->do_wifi_close_supplicant_connection(aInterface.get());
|
||||
} else if (aOptions.mCmd.EqualsLiteral("load_driver")) {
|
||||
aResult.mStatus = mImpl->do_wifi_load_driver();
|
||||
} else if (aOptions.mCmd.EqualsLiteral("unload_driver")) {
|
||||
@ -279,7 +280,7 @@ bool WpaSupplicant::ExecuteCommand(CommandOptions aOptions,
|
||||
} 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");
|
||||
aResult.mStatus = mImpl->do_wifi_connect_to_supplicant(aInterface.get());
|
||||
} else if (aOptions.mCmd.EqualsLiteral("ifc_enable")) {
|
||||
aResult.mStatus = mNetUtils->do_ifc_enable(GET_CHAR(mIfname));
|
||||
} else if (aOptions.mCmd.EqualsLiteral("ifc_disable")) {
|
||||
|
@ -86,6 +86,9 @@ public:
|
||||
class WpaSupplicantImpl
|
||||
{
|
||||
public:
|
||||
// Suppress warning from nsAutoPtr
|
||||
virtual ~WpaSupplicantImpl() {}
|
||||
|
||||
virtual int32_t
|
||||
do_wifi_wait_for_event(const char *iface, char *buf, size_t len) = 0; // ICS != JB
|
||||
|
||||
@ -117,9 +120,13 @@ class WpaSupplicant MOZ_FINAL
|
||||
public:
|
||||
WpaSupplicant();
|
||||
|
||||
void WaitForEvent(nsAString& aEvent);
|
||||
// Use nsCString as the type of aInterface to guarantee it's
|
||||
// null-terminated so that we can pass it to c API without
|
||||
// conversion
|
||||
void WaitForEvent(nsAString& aEvent, const nsCString& aInterface);
|
||||
bool ExecuteCommand(CommandOptions aOptions,
|
||||
mozilla::dom::WifiResultOptions& result);
|
||||
mozilla::dom::WifiResultOptions& result,
|
||||
const nsCString& aInterface);
|
||||
|
||||
private:
|
||||
nsAutoPtr<WpaSupplicantImpl> mImpl;
|
||||
|
@ -96,6 +96,8 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
|
||||
// command always succeeds and we do a string/boolean check for the
|
||||
// expected results).
|
||||
var WifiManager = (function() {
|
||||
var manager = {};
|
||||
|
||||
function getStartupPrefs() {
|
||||
return {
|
||||
sdkVersion: parseInt(libcutils.property_get("ro.build.version.sdk"), 10),
|
||||
@ -109,26 +111,17 @@ var WifiManager = (function() {
|
||||
let {sdkVersion, unloadDriverEnabled, schedScanRecovery, driverDelay, ifname} = getStartupPrefs();
|
||||
|
||||
let wifiListener = {
|
||||
onWaitEvent: function(event) {
|
||||
if (handleEvent(event)) {
|
||||
waitForEvent();
|
||||
onWaitEvent: function(event, iface) {
|
||||
if (manager.ifname === iface && handleEvent(event)) {
|
||||
waitForEvent(iface);
|
||||
}
|
||||
},
|
||||
|
||||
onCommand: function(event) {
|
||||
onmessageresult(event);
|
||||
onCommand: function(event, iface) {
|
||||
onmessageresult(event, iface);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
// Emulator build runs to here.
|
||||
// The debug() should only be used after WifiManager.
|
||||
@ -138,7 +131,16 @@ var WifiManager = (function() {
|
||||
manager.schedScanRecovery = schedScanRecovery;
|
||||
manager.driverDelay = driverDelay ? parseInt(driverDelay, 10) : DRIVER_READY_WAIT;
|
||||
|
||||
var wifiCommand = WifiCommand(controlMessage);
|
||||
let wifiService = Cc["@mozilla.org/wifi/service;1"];
|
||||
if (wifiService) {
|
||||
wifiService = wifiService.getService(Ci.nsIWifiProxyService);
|
||||
let interfaces = [manager.ifname];
|
||||
wifiService.start(wifiListener, interfaces, interfaces.length);
|
||||
} else {
|
||||
debug("No wifi service component available!");
|
||||
}
|
||||
|
||||
var wifiCommand = WifiCommand(controlMessage, manager.ifname);
|
||||
var netUtil = WifiNetUtil(controlMessage);
|
||||
|
||||
// Callbacks to invoke when a reply arrives from the wifi service.
|
||||
@ -148,12 +150,13 @@ var WifiManager = (function() {
|
||||
function controlMessage(obj, callback) {
|
||||
var id = idgen++;
|
||||
obj.id = id;
|
||||
if (callback)
|
||||
if (callback) {
|
||||
controlCallbacks[id] = callback;
|
||||
wifiService.sendCommand(obj);
|
||||
}
|
||||
wifiService.sendCommand(obj, obj.iface);
|
||||
}
|
||||
|
||||
let onmessageresult = function(data) {
|
||||
let onmessageresult = function(data, iface) {
|
||||
var id = data.id;
|
||||
var callback = controlCallbacks[id];
|
||||
if (callback) {
|
||||
@ -165,8 +168,8 @@ var WifiManager = (function() {
|
||||
// Polling the status worker
|
||||
var recvErrors = 0;
|
||||
|
||||
function waitForEvent() {
|
||||
wifiService.waitForEvent();
|
||||
function waitForEvent(iface) {
|
||||
wifiService.waitForEvent(iface);
|
||||
}
|
||||
|
||||
// Commands to the control worker.
|
||||
@ -755,7 +758,7 @@ var WifiManager = (function() {
|
||||
}
|
||||
|
||||
function didConnectSupplicant(callback) {
|
||||
waitForEvent();
|
||||
waitForEvent(manager.ifname);
|
||||
|
||||
// Load up the supplicant state.
|
||||
getDebugEnabled(function(ok) {
|
||||
|
@ -4,17 +4,19 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(e3d54c8d-b1c7-4ed5-b760-e26d3075e3e5)]
|
||||
[scriptable, uuid(4d4389e0-1547-11e3-8ffd-0800200c9a66)]
|
||||
interface nsIWifiEventListener : nsISupports {
|
||||
void onWaitEvent(in AString event);
|
||||
void onCommand(in jsval result);
|
||||
void onWaitEvent(in AString event, in ACString aInterface);
|
||||
void onCommand(in jsval result, in ACString aInterface);
|
||||
};
|
||||
|
||||
[scriptable, uuid(ac5ebae6-ec72-4212-89cb-cd25ed5a1b46)]
|
||||
[scriptable, uuid(5e2bd8c0-1547-11e3-8ffd-0800200c9a66)]
|
||||
interface nsIWifiProxyService : nsISupports {
|
||||
void start(in nsIWifiEventListener listener);
|
||||
void start(in nsIWifiEventListener listener,
|
||||
[array, size_is(aNumOfInterface)] in string aInterfaces,
|
||||
in unsigned long aNumOfInterface);
|
||||
void shutdown();
|
||||
[implicit_jscontext]
|
||||
void sendCommand(in jsval parameters);
|
||||
void waitForEvent();
|
||||
void sendCommand(in jsval parameters, in ACString aInterface);
|
||||
void waitForEvent(in ACString aInterface);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user