fix(*): Js module multi thread problem fix

Signed-off-by: zhangfeng <hw.zhangfeng@huawei.com>
This commit is contained in:
zhangfeng 2022-01-26 07:12:53 +00:00
parent a6562c600d
commit d18332c1c0
11 changed files with 570 additions and 501 deletions

View File

@ -157,14 +157,19 @@ import wf from '@ohos.wifi'; // Import the @ohos.wifi class.
```js
// Start a scan.
var isScanSuccess = wf.scan(); // true
// Wait for some time.
// Obtain the scan result.
wf.getScanInfos(result => {
var num = Object.keys(result).length;
console.info("wifi scan result mum: " + num);
for (var i = 0; i < num; ++i) {
wf.getScanInfos((err, result) => {
if (err) {
console.error("get scan info error");
return;
}
var len = Object.keys(result).length;
console.log("get scan info number: " + len);
for (var i = 0; i < len; ++i) {
console.info("ssid: " + result[i].ssid);
console.info("bssid: " + result[i].bssid);
console.info("securityType: " + result[i].securityType);
@ -173,7 +178,7 @@ import wf from '@ohos.wifi'; // Import the @ohos.wifi class.
console.info("frequency: " + result[i].frequency);
console.info("timestamp: " + result[i].timestamp);
}
})
});
```
@ -190,13 +195,19 @@ Set up a WLAN connection.
"isHiddenSsid":false,
"securityType":3,
}
Method 1:
// Add a hotspot configuration.
wf.addDeviceConfig(config, (result) => {
wf.addDeviceConfig(config, (err, result) => {
if (err) {
console.error("add device config error");
return;
}
console.info("config id: " + result);
// Set up a WLAN based on the hotspot configuration ID.
wf.connectToNetwork(result);
});
Method 2:
// Set up a WLAN by calling connectToDevice with the hotspot configuration passed.
wf.connectToDevice(config);

View File

@ -157,14 +157,19 @@ import wf from '@ohos.wifi'; // 导入js接口类
```js
// 调用WLAN扫描接口
var isScanSuccess = wf.scan(); // true
// 延迟一定时间
// 获取扫描结果
wf.getScanInfos(result => {
var num = Object.keys(result).length;
console.info("wifi scan result mum: " + num);
for (var i = 0; i < num; ++i) {
wf.getScanInfos((err, result) => {
if (err) {
console.error("get scan info error");
return;
}
var len = Object.keys(result).length;
console.log("get scan info number: " + len);
for (var i = 0; i < len; ++i) {
console.info("ssid: " + result[i].ssid);
console.info("bssid: " + result[i].bssid);
console.info("securityType: " + result[i].securityType);
@ -173,7 +178,7 @@ import wf from '@ohos.wifi'; // 导入js接口类
console.info("frequency: " + result[i].frequency);
console.info("timestamp: " + result[i].timestamp);
}
})
});
```
@ -190,14 +195,18 @@ import wf from '@ohos.wifi'; // 导入js接口类
"isHiddenSsid":false,
"securityType":3,
}
方式一
方式一:
// 添加配置
wf.addDeviceConfig(config, (result) => {
wf.addDeviceConfig(config, (err, result) => {
if (err) {
console.error("add device config error");
return;
}
console.info("config id: " + result);
// 通过配置id连接WLAN
wf.connectToNetwork(result);
});
方式二
方式二:
// 通过配置信息直接连接WLAN
wf.connectToDevice(config);
```

View File

@ -96,7 +96,7 @@ static SecTypeJs SecurityTypeNativeToJs(const WifiSecurity& cppSecurityType)
return jsSecurityType;
}
static bool NativeScanInfosToJsObj(const napi_env& env,
static ErrCode NativeScanInfosToJsObj(const napi_env& env,
const std::vector<WifiScanInfo>& vecScnIanfos, napi_value& arrayResult)
{
uint32_t idx = 0;
@ -115,10 +115,10 @@ static bool NativeScanInfosToJsObj(const napi_env& env,
napi_status status = napi_set_element(env, arrayResult, idx++, eachObj);
if (status != napi_ok) {
WIFI_LOGE("Wifi napi set element error: %{public}d, idx: %{public}d", status, idx - 1);
return false;
return WIFI_OPT_FAILED;
}
}
return true;
return WIFI_OPT_SUCCESS;
}
napi_value GetScanInfos(napi_env env, napi_callback_info info)
@ -138,14 +138,14 @@ napi_value GetScanInfos(napi_env env, napi_callback_info info)
asyncContext->executeFunc = [&](void* data) -> void {
ScanInfoAsyncContext *context = static_cast<ScanInfoAsyncContext *>(data);
TRACE_FUNC_CALL_NAME("wifiScanPtr->GetScanInfoList");
context->isSuccess = (wifiScanPtr->GetScanInfoList(context->vecScanInfos) == WIFI_OPT_SUCCESS);
context->errorCode = wifiScanPtr->GetScanInfoList(context->vecScanInfos);
WIFI_LOGI("GetScanInfoList, size: %{public}zu", context->vecScanInfos.size());
};
asyncContext->completeFunc = [&](void* data) -> void {
ScanInfoAsyncContext *context = static_cast<ScanInfoAsyncContext *>(data);
napi_create_array_with_length(context->env, context->vecScanInfos.size(), &context->result);
context->isSuccess = NativeScanInfosToJsObj(context->env, context->vecScanInfos, context->result);
context->errorCode = NativeScanInfosToJsObj(context->env, context->vecScanInfos, context->result);
WIFI_LOGI("Push scan info list to client");
};
@ -223,7 +223,7 @@ napi_value AddDeviceConfig(napi_env env, napi_callback_info info)
if (context->addResult < 0 || ret != WIFI_OPT_SUCCESS) {
context->addResult = -1;
}
context->isSuccess = (ret == WIFI_OPT_SUCCESS);
context->errorCode = ret;
};
asyncContext->completeFunc = [&](void* data) -> void {
@ -425,7 +425,7 @@ napi_value GetLinkedInfo(napi_env env, napi_callback_info info)
asyncContext->executeFunc = [&](void* data) -> void {
LinkedInfoAsyncContext *context = static_cast<LinkedInfoAsyncContext *>(data);
TRACE_FUNC_CALL_NAME("wifiDevicePtr->GetLinkedInfo");
context->isSuccess = (wifiDevicePtr->GetLinkedInfo(context->linkedInfo) == WIFI_OPT_SUCCESS);
context->errorCode = wifiDevicePtr->GetLinkedInfo(context->linkedInfo);
};
asyncContext->completeFunc = [&](void* data) -> void {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -22,26 +22,6 @@
namespace OHOS {
namespace Wifi {
#ifndef ENABLE_NAPI_COMPATIBLE
DEFINE_WIFILOG_LABEL("WifiNAPIEntry");
/*
* Event class initialization function
*/
static void InitEventClass(napi_env& env, napi_value& exports) {
const char className[] = "EventListener";
napi_property_descriptor properties[] = {
DECLARE_NAPI_FUNCTION("on", On),
DECLARE_NAPI_FUNCTION("off", Off),
};
napi_value eventListenerClass = nullptr;
napi_define_class(env, className, sizeof(className), EventListenerConstructor, nullptr,
sizeof(properties) / sizeof(napi_property_descriptor), properties, &eventListenerClass);
napi_status status = napi_set_named_property(env, exports, "EventListener", eventListenerClass);
if (status != napi_ok) {
WIFI_LOGE("Init event class set property error.");
}
}
/*
* Module initialization function
*/
@ -91,11 +71,12 @@ static napi_value Init(napi_env env, napi_value exports) {
DECLARE_NAPI_FUNCTION("startP2pListen", StartP2pListen),
DECLARE_NAPI_FUNCTION("stopP2pListen", StopP2pListen),
DECLARE_NAPI_FUNCTION("deletePersistentGroup", DeletePersistentGroup),
DECLARE_NAPI_FUNCTION("setP2pDeviceName", SetP2pDeviceName)
DECLARE_NAPI_FUNCTION("setP2pDeviceName", SetP2pDeviceName),
DECLARE_NAPI_FUNCTION("on", On),
DECLARE_NAPI_FUNCTION("off", Off),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc));
InitEventClass(env, exports);
return exports;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -14,347 +14,296 @@
*/
#include "wifi_napi_event.h"
#include <shared_mutex>
#include <uv.h>
#include "wifi_napi_utils.h"
#include "wifi_device.h"
#include "wifi_scan.h"
#include "wifi_p2p.h"
#include "wifi_logger.h"
using namespace OHOS::EventFwk;
namespace OHOS {
namespace Wifi {
DEFINE_WIFILOG_LABEL("WifiNAPIEvent");
const std::string WIFI_EVENT_TYPE_POWER_STATE = "wifiStateChange";
const std::string WIFI_EVENT_TYPE_CONN_STATE = "wifiConnectionChange";
const std::string WIFI_EVENT_TYPE_SCAN_STATE = "wifiScanStateChange";
const std::string WIFI_EVENT_TYPE_RSSI_STATE = "wifiRssiChange";
const std::string WIFI_EVENT_TYPE_HOTSPOT_STATE = "hotspotStateChange";
const std::string WIFI_EVENT_TYPE_AP_STA_JOIN = "hotspotStaJoin";
const std::string WIFI_EVENT_TYPE_AP_STA_LEAVE = "hotspotStaLeave";
const std::string WIFI_EVENT_TYPE_P2P_DEVICES_STATE = "p2pDevicesChange";
const std::string WIFI_EVENT_TYPE_P2P_STATE = "p2pStateChange";
const std::string WIFI_EVENT_TYPE_P2P_CONN_STATE = "p2pConnStateChange";
const std::string WIFI_EVENT_TYPE_P2P_PEER_DISCOVERY_STATE = "p2pPeerDiscoveryStateChange";
const std::string WIFI_EVENT_TYPE_P2P_CURRENT_DEVICE_STATE = "p2pCurrentDeviceChange";
const std::string WIFI_EVENT_TYPE_P2P_GROUP_STATE = "p2pGroupStateChange";
const std::string EVENT_STA_POWER_STATE_CHANGE = "wifiStateChange";
const std::string EVENT_STA_CONN_STATE_CHANGE = "wifiConnectionChange";
const std::string EVENT_STA_SCAN_STATE_CHANGE = "wifiScanStateChange";
const std::string EVENT_STA_RSSI_STATE_CHANGE = "wifiRssiChange";
const std::string EVENT_HOTSPOT_STATE_CHANGE = "hotspotStateChange";
const std::string EVENT_HOTSPOT_STA_JOIN = "hotspotStaJoin";
const std::string EVENT_HOTSPOT_STA_LEAVE = "hotspotStaLeave";
const std::string EVENT_P2P_STATE_CHANGE = "p2pStateChange";
const std::string EVENT_P2P_CONN_STATE_CHANGE = "p2pConnectionChange";
const std::string EVENT_P2P_DEVICE_STATE_CHANGE = "p2pDeviceChange";
const std::string EVENT_P2P_PERSISTENT_GROUP_CHANGE = "p2pPersistentGroupChange";
const std::string EVENT_P2P_PEER_DEVICE_CHANGE = "p2pPeerDeviceChange";
const std::string EVENT_P2P_DISCOVERY_CHANGE = "p2pPeerDeviceChange";
const std::string WIFI_USUAL_EVENT_POWER_STATE = "usual.event.wifi.POWER_STATE";
const std::string WIFI_USUAL_EVENT_CONN_STATE = "usual.event.wifi.CONN_STATE";
const std::string WIFI_USUAL_EVENT_SCAN_STATE = "usual.event.wifi.SCAN_STATE";
const std::string WIFI_USUAL_EVENT_RSSI_STATE = "usual.event.wifi.RSSI_VALUE";
const std::string WIFI_USUAL_EVENT_HOTSPOT_STATE = "usual.event.wifi.HOTSPOT_STATE";
const std::string WIFI_USUAL_EVENT_AP_STA_JOIN = "usual.event.wifi.WIFI_HS_STA_JOIN";
const std::string WIFI_USUAL_EVENT_AP_STA_LEAVE = "usual.event.wifi.WIFI_HS_STA_LEAVE";
const std::string WIFI_USUAL_EVENT_P2P_DEVICES_CHANGE = "usual.event.wifi.p2p.DEVICES_CHANGE";
const std::string WIFI_USUAL_EVENT_P2P_STATE_CHANGE = "usual.event.wifi.p2p.STATE_CHANGE";
const std::string WIFI_USUAL_EVENT_P2P_CONN_STATE_CHANGE = "usual.event.wifi.p2p.CONN_STATE_CHANGE";
const std::string WIFI_USUAL_EVENT_P2P_PEER_DISCOVERY_STATE_CHANG = "usual.event.wifi.p2p.PEER_DISCOVERY_STATE_CHANGE";
const std::string WIFI_USUAL_EVENT_P2P_CURRENT_DEVICE_STATE_CHANGE = "usual.event.wifi.p2p.CURRENT_DEVICE_CHANGE";
const std::string WIFI_USUAL_EVENT_P2P_GROUP_STATE_CHANGE = "usual.event.wifi.p2p.GROUP_STATE_CHANGED";
std::shared_mutex g_regInfoMutex;
static std::map<std::string, EventRegisterInfo> g_eventRegisterInfo;
static std::map<std::string, std::string> g_mapEventTypeToUsualEvent = {
{ WIFI_EVENT_TYPE_POWER_STATE, WIFI_USUAL_EVENT_POWER_STATE },
{ WIFI_EVENT_TYPE_CONN_STATE, WIFI_USUAL_EVENT_CONN_STATE },
{ WIFI_EVENT_TYPE_SCAN_STATE, WIFI_USUAL_EVENT_SCAN_STATE },
{ WIFI_EVENT_TYPE_RSSI_STATE, WIFI_USUAL_EVENT_RSSI_STATE },
{ WIFI_EVENT_TYPE_HOTSPOT_STATE, WIFI_USUAL_EVENT_HOTSPOT_STATE },
{ WIFI_EVENT_TYPE_P2P_DEVICES_STATE, WIFI_USUAL_EVENT_P2P_DEVICES_CHANGE },
{ WIFI_EVENT_TYPE_P2P_STATE, WIFI_USUAL_EVENT_P2P_STATE_CHANGE },
{ WIFI_EVENT_TYPE_P2P_CONN_STATE, WIFI_USUAL_EVENT_P2P_CONN_STATE_CHANGE },
{ WIFI_EVENT_TYPE_P2P_PEER_DISCOVERY_STATE, WIFI_USUAL_EVENT_P2P_PEER_DISCOVERY_STATE_CHANG },
{ WIFI_EVENT_TYPE_P2P_CURRENT_DEVICE_STATE, WIFI_USUAL_EVENT_P2P_CURRENT_DEVICE_STATE_CHANGE },
{ WIFI_EVENT_TYPE_P2P_GROUP_STATE, WIFI_USUAL_EVENT_P2P_GROUP_STATE_CHANGE }
static std::set<std::string> g_supportEventList = {
EVENT_STA_POWER_STATE_CHANGE,
EVENT_STA_CONN_STATE_CHANGE,
EVENT_STA_SCAN_STATE_CHANGE,
EVENT_STA_RSSI_STATE_CHANGE,
EVENT_HOTSPOT_STATE_CHANGE,
EVENT_HOTSPOT_STA_JOIN,
EVENT_HOTSPOT_STA_LEAVE,
EVENT_P2P_STATE_CHANGE,
EVENT_P2P_CONN_STATE_CHANGE,
EVENT_P2P_DEVICE_STATE_CHANGE,
EVENT_P2P_PERSISTENT_GROUP_CHANGE,
EVENT_P2P_PEER_DEVICE_CHANGE,
EVENT_P2P_DISCOVERY_CHANGE,
};
static std::map<std::string, UserDefinedEventProcessFunc> g_mapUserDefinedEventProcessFunc = {};
void NapiEvent::EventNotify(AsyncEventData *asyncEvent)
{
WIFI_LOGI("Enter wifi event notify");
uv_loop_s* loop = nullptr;
napi_get_uv_event_loop(asyncEvent->env, &loop);
class EventRegisterInfo {
public:
explicit EventRegisterInfo(EventManager* context) : m_context(context) {
}
EventRegisterInfo() {
}
virtual ~EventRegisterInfo() {
}
std::set<napi_ref>& GetHandlersCb() {
return m_handlersCb;
}
void SetSubscriber(std::shared_ptr<WifiEventSubscriber>& subscriber) {
m_subscriber = subscriber;
}
std::shared_ptr<WifiEventSubscriber> GetSubscriber() {
return m_subscriber;
}
void SetContext(EventManager* context) {
m_context = context;
}
EventManager* GetContext() {
return m_context;
}
private:
std::set<napi_ref> m_handlersCb;
std::shared_ptr<WifiEventSubscriber> m_subscriber;
EventManager *m_context;
};
void Event::SetName(std::string& name) {
m_name = name;
}
std::string Event::GetName() {
return m_name;
}
napi_env Event::GetEnv() {
return m_env;
}
napi_value WifiCommonEvent::PackResult() {
napi_value result;
napi_create_int32(GetEnv(), m_value, &result);
return result;
}
static bool GetUsualEventByEventType(const std::string& type, std::string& usual) {
std::map<std::string, std::string>::const_iterator it = g_mapEventTypeToUsualEvent.find(type);
if (it == g_mapEventTypeToUsualEvent.end()) {
return false;
}
usual = it->second;
return true;
}
static bool GetEventTypeByUsualEvent(const std::string& usual, std::string& type) {
for (auto& each : g_mapEventTypeToUsualEvent) {
if (each.second == usual) {
type = each.first;
return true;
}
}
return false;
}
static bool IsEventTypeExist(const std::string& type) {
return g_mapEventTypeToUsualEvent.find(type) != g_mapEventTypeToUsualEvent.end();
}
void WifiEventSubscriber::OnReceiveEvent(const CommonEventData& data) {
std::string event = data.GetWant().GetAction();
int code = data.GetCode();
WIFI_LOGI("Received event: %{public}s, value: %{public}d", event.c_str(), code);
std::string type;
if (!GetEventTypeByUsualEvent(event, type)) {
WIFI_LOGI("Received event: %{public}s is ignored", event.c_str());
uv_work_t* work = new uv_work_t;
if (work == nullptr) {
WIFI_LOGE("uv_work_t work is null.");
delete asyncEvent;
asyncEvent = nullptr;
return;
}
EventManager *manager = nullptr;
{
std::shared_lock<std::shared_mutex> guard(g_regInfoMutex);
std::map<std::string, EventRegisterInfo>::iterator it = g_eventRegisterInfo.find(type);
if (it == g_eventRegisterInfo.end()) {
WIFI_LOGE("No register info for event: %{public}s", type.c_str());
return;
}
manager = it->second.GetContext();
if (manager == nullptr) {
WIFI_LOGE("Context is null");
return;
}
}
WIFI_LOGI("Get the event loop, napi_env: %{public}p", asyncEvent->env);
work->data = asyncEvent;
uv_queue_work(
loop,
work,
[](uv_work_t* work) {},
[](uv_work_t* work, int status) {
AsyncEventData *asyncData = static_cast<AsyncEventData*>(work->data);
if (asyncData == nullptr) {
WIFI_LOGE("asyncData is null.");
return;
}
WIFI_LOGI("Napi event uv_queue_work, env: %{public}p, status: %{public}d", asyncData->env, status);
napi_handle_scope scope = nullptr;
napi_open_handle_scope(asyncData->env, &scope);
if (scope == nullptr) {
WIFI_LOGE("scope is nullptr");
napi_close_handle_scope(asyncData->env, scope);
return;
}
napi_value undefine;
napi_get_undefined(asyncData->env, &undefine);
napi_value handler = nullptr;
napi_get_reference_value(asyncData->env, asyncData->callbackRef, &handler);
std::map<std::string, UserDefinedEventProcessFunc>::iterator iter = g_mapUserDefinedEventProcessFunc.find(type);
if (iter != g_mapUserDefinedEventProcessFunc.end()) {
WIFI_LOGI("Has user-defined func for event: %{public}s", type.c_str());
iter->second(manager->GetEnv(), type, data);
} else {
WIFI_LOGI("Use default policy to process event: %{public}s", type.c_str());
WifiCommonEvent commonEvent(manager->GetEnv(), type, code);
if (!manager->Send(commonEvent)) {
WIFI_LOGE("Send event error");
WIFI_LOGI("Push event to js, env: %{public}p, ref : %{public}p", asyncData->env, &asyncData->callbackRef);
if (napi_call_function(asyncData->env, nullptr, handler, 1, &asyncData->jsEvent, &undefine) != napi_ok) {
WIFI_LOGE("Report event to Js failed");
}
napi_close_handle_scope(asyncData->env, scope);
if (asyncData != nullptr) {
delete asyncData;
asyncData = nullptr;
}
if (work != nullptr) {
delete work;
work = nullptr;
}
}
}
);
}
EventManager::EventManager(napi_env env, napi_value thisVar) : m_env(env) {
m_thisVarRef = nullptr;
napi_create_reference(env, thisVar, 1, &m_thisVarRef);
bool NapiEvent::CheckIsRegister(const std::string& type)
{
return g_eventRegisterInfo.find(type) != g_eventRegisterInfo.end();
}
EventManager::~EventManager() {}
bool EventManager::Send(Event& event) {
WIFI_LOGI("Report event: %{public}s", event.GetName().c_str());
napi_handle_scope scope = nullptr;
napi_open_handle_scope(m_env, &scope);
std::shared_lock<std::shared_mutex> guard(g_regInfoMutex);
std::map<std::string, EventRegisterInfo>::iterator it = g_eventRegisterInfo.find(event.GetName());
if (it == g_eventRegisterInfo.end()) {
WIFI_LOGE("Event receive owner not exits: %{public}s", event.GetName().c_str());
return false;
}
bool result = true;
napi_value thisVar = nullptr;
napi_get_reference_value(m_env, m_thisVarRef, &thisVar);
for (auto& each : it->second.GetHandlersCb()) {
napi_value undefine;
napi_value handler = nullptr;
napi_get_undefined(m_env, &undefine);
napi_get_reference_value(m_env, each, &handler);
napi_value jsEvent = event.PackResult();
if (napi_call_function(m_env, thisVar, handler, 1, &jsEvent, &undefine) != napi_ok) {
WIFI_LOGE("Report event failed");
result = false;
}
}
napi_close_handle_scope(m_env, scope);
napi_value NapiEvent::CreateResult(const napi_env& env, int value) {
napi_value result;
napi_create_int32(env, value, &result);
return result;
}
bool EventManager::SubscribeServiceEvent(const std::string& event) {
MatchingSkills matchingSkills;
matchingSkills.AddEvent(event);
CommonEventSubscribeInfo subscriberInfo(matchingSkills);
std::shared_ptr<WifiEventSubscriber> subscriber = std::make_shared<WifiEventSubscriber>(subscriberInfo);
if (subscriber == nullptr) {
WIFI_LOGE("subscriber is null.");
return false;
}
WIFI_LOGI("Subscribe event -> %{public}s", event.c_str());
bool result = CommonEventManager::SubscribeCommonEvent(subscriber);
if (result) {
g_eventRegisterInfo[m_eventType].SetSubscriber(subscriber);
} else {
WIFI_LOGE("Subscribe service event error: %{public}s", event.c_str());
}
napi_value NapiEvent::CreateResult(const napi_env& env, const StationInfo& info)
{
napi_value result;
napi_create_object(env, &result);
SetValueUtf8String(env, "name", info.deviceName.c_str(), result);
SetValueUtf8String(env, "macAddress", info.bssid.c_str(), result);
SetValueUtf8String(env, "ipAddress", info.ipAddr.c_str(), result);
return result;
}
bool EventManager::UnsubscribeServiceEvent(const std::string& event) {
bool result = CommonEventManager::UnSubscribeCommonEvent(g_eventRegisterInfo[m_eventType].GetSubscriber());
if (!result) {
WIFI_LOGE("Unsubscribe service event error: %{public}s", event.c_str());
}
napi_value NapiEvent::CreateResult(const napi_env& env, const WifiP2pDevice& device)
{
napi_value result;
napi_create_object(env, &result);
SetValueUtf8String(env, "deviceName", device.GetDeviceName().c_str(), result);
SetValueUtf8String(env, "deviceAddress", device.GetDeviceAddress().c_str(), result);
SetValueUtf8String(env, "primaryDeviceType", device.GetPrimaryDeviceType().c_str(), result);
SetValueInt32(env, "devStatus", static_cast<int>(device.GetP2pDeviceStatus()), result);
SetValueInt32(env, "groupCapability", device.GetGroupCapabilitys(), result);
return result;
}
bool EventManager::SubscribeEvent(const std::string& name, napi_value handler) {
WIFI_LOGI("Subscribe event: %{public}s", name.c_str());
if (!IsEventTypeExist(name)) {
WIFI_LOGE("Subscribe event is not a valid event: %{public}s", name.c_str());
return false;
}
SetEventType(name);
std::unique_lock<std::shared_mutex> guard(g_regInfoMutex);
std::map<std::string, EventRegisterInfo>::iterator it = g_eventRegisterInfo.find(name);
if (it == g_eventRegisterInfo.end()) {
std::string usualEvent;
GetUsualEventByEventType(name, usualEvent);
bool result = SubscribeServiceEvent(usualEvent);
if (!result) {
WIFI_LOGE("Service register event failed: %{public}s", name.c_str());
return false;
}
EventRegisterInfo regInfo(this);
g_eventRegisterInfo[name] = regInfo;
}
if (g_eventRegisterInfo[name].GetContext() != this) {
WIFI_LOGW("Subscribe event context changed!");
g_eventRegisterInfo[name].SetContext(this);
}
napi_ref handlerRef = nullptr;
napi_create_reference(m_env, handler, 1, &handlerRef);
g_eventRegisterInfo[name].GetHandlersCb().insert(handlerRef);
return true;
}
void EventManager::DeleteHanderRef(std::set<napi_ref>& setRefs, napi_value handler) {
for (auto& each : setRefs) {
napi_value handlerTemp = nullptr;
napi_get_reference_value(m_env, each, &handlerTemp);
bool isEqual = false;
napi_strict_equals(m_env, handlerTemp, handler, &isEqual);
if (isEqual) {
napi_delete_reference(m_env, each);
setRefs.erase(each);
return;
napi_value NapiEvent::CreateResult(const napi_env& env, const std::vector<WifiP2pDevice>& devices)
{
uint32_t idx = 0;
napi_value arrayResult;
napi_create_array_with_length(env, devices.size(), &arrayResult);
for (auto& each : devices) {
if (napi_set_element(env, arrayResult, idx++, CreateResult(env, each)) != napi_ok) {
WIFI_LOGE("Array result set element error, idx: %{public}d", idx - 1);
}
}
return arrayResult;
}
void EventManager::DeleteAllHanderRef(std::set<napi_ref>& setRefs) {
for (auto& each : setRefs) {
napi_delete_reference(m_env, each);
}
setRefs.clear();
napi_value NapiEvent::CreateResult(const napi_env& env, const WifiP2pLinkedInfo& info)
{
napi_value result;
napi_create_object(env, &result);
SetValueInt32(env, "connectState", static_cast<int>(info.GetConnectState()), result);
SetValueBool(env, "isGroupOwner", info.IsGroupOwner(), result);
SetValueUtf8String(env, "groupOwnerAddr", info.GetGroupOwnerAddress().c_str(), result);
return result;
}
bool EventManager::UnsubscribeEvent(const std::string& name, napi_value handler) {
WIFI_LOGI("Unsubscribe event: %{public}s", name.c_str());
if (!IsEventTypeExist(name)) {
WIFI_LOGE("Unsubscribe event is not a valid event: %{public}s", name.c_str());
return false;
}
bool isNeedUnsubscribe = false;
std::unique_lock<std::shared_mutex> guard(g_regInfoMutex);
std::map<std::string, EventRegisterInfo>::iterator it = g_eventRegisterInfo.find(name);
if (it == g_eventRegisterInfo.end()) {
WIFI_LOGE("Unsubscribe event is not subscribe: %{public}s", name.c_str());
return false;
}
if (handler != nullptr) {
DeleteHanderRef(it->second.GetHandlersCb(), handler);
} else {
WIFI_LOGW("All callback is unsubscribe for event: %{public}s", name.c_str());
DeleteAllHanderRef(it->second.GetHandlersCb());
}
/* No one subscribes event now */
if (it->second.GetHandlersCb().empty()) {
isNeedUnsubscribe = true;
}
SetEventType(name);
if (isNeedUnsubscribe) {
std::string usualEvent;
GetUsualEventByEventType(name, usualEvent);
bool result = UnsubscribeServiceEvent(usualEvent);
g_eventRegisterInfo.erase(name);
if (!result) {
WIFI_LOGE("Service unregister event failed: %{public}s", name.c_str());
return false;
}
}
return true;
napi_value NapiEvent::NapiEvent::CreateResult(const napi_env& env, napi_value placehoders)
{
return placehoders == nullptr ? UndefinedNapiValue(env) : placehoders;
}
void EventManager::SetEventType(const std::string& type) {
m_eventType = type;
}
class WifiNapiDeviceEventCallback : public IWifiDeviceCallBack, public NapiEvent {
public:
WifiNapiDeviceEventCallback() {
}
napi_env EventManager::GetEnv() {
return m_env;
}
virtual ~WifiNapiDeviceEventCallback() {
}
public:
void OnWifiStateChanged(int state) override {
WIFI_LOGI("sta received state changed event: %{public}d", state);
CheckAndNotify(EVENT_STA_POWER_STATE_CHANGE, state);
}
void OnWifiConnectionChanged(int state, const WifiLinkedInfo &info) override {
WIFI_LOGI("sta received connection changed event: %{public}d", state);
CheckAndNotify(EVENT_STA_CONN_STATE_CHANGE, state);
}
void OnWifiRssiChanged(int rssi) override {
WIFI_LOGI("sta received rssi changed event: %{public}d", rssi);
CheckAndNotify(EVENT_STA_RSSI_STATE_CHANGE, rssi);
}
void OnWifiWpsStateChanged(int state, const std::string &pinCode) override {
}
void OnStreamChanged(int direction) override {
}
OHOS::sptr<OHOS::IRemoteObject> AsObject() override {
return nullptr;
}
};
class WifiNapiScanEventCallback : public IWifiScanCallback, public NapiEvent {
public:
WifiNapiScanEventCallback() {
}
virtual ~WifiNapiScanEventCallback() {
}
public:
void OnWifiScanStateChanged(int state) override {
WIFI_LOGI("scan received state changed event: %{public}d", state);
CheckAndNotify(EVENT_STA_SCAN_STATE_CHANGE, state);
}
OHOS::sptr<OHOS::IRemoteObject> AsObject() override {
return nullptr;
}
};
class WifiNapiHotspotEventCallback : public IWifiHotspotCallback, public NapiEvent {
public:
WifiNapiHotspotEventCallback() {
}
virtual ~WifiNapiHotspotEventCallback() {
}
public:
void OnHotspotStateChanged(int state) override {
WIFI_LOGI("Hotspot received state changed event: %{public}d", state);
CheckAndNotify(EVENT_HOTSPOT_STATE_CHANGE, state);
}
void OnHotspotStaJoin(const StationInfo &info) override {
WIFI_LOGI("Hotspot received sta join event");
CheckAndNotify(EVENT_HOTSPOT_STA_JOIN, info);
}
void OnHotspotStaLeave(const StationInfo &info) override {
WIFI_LOGI("Hotspot received sta leave event");
CheckAndNotify(EVENT_HOTSPOT_STA_LEAVE, info);
}
OHOS::sptr<OHOS::IRemoteObject> AsObject() override {
return nullptr;
}
};
class WifiNapiP2pEventCallback : public IWifiP2pCallback, public NapiEvent {
public:
WifiNapiP2pEventCallback() {
}
virtual ~WifiNapiP2pEventCallback() {
}
public:
void OnP2pStateChanged(int state) override {
WIFI_LOGI("received p2p state changed event: %{public}d", state);
CheckAndNotify(EVENT_P2P_STATE_CHANGE, state);
}
void OnP2pPersistentGroupsChanged(void) override {
WIFI_LOGI("received persistent group changed event");
CheckAndNotify(EVENT_P2P_PERSISTENT_GROUP_CHANGE, nullptr);
}
void OnP2pThisDeviceChanged(const WifiP2pDevice& device) override {
WIFI_LOGI("received this device changed event");
CheckAndNotify(EVENT_P2P_DEVICE_STATE_CHANGE, device);
}
void OnP2pPeersChanged(const std::vector<WifiP2pDevice>& devices) override {
WIFI_LOGI("received peers changed event: %{public}d", (int)devices.size());
CheckAndNotify(EVENT_P2P_PEER_DEVICE_CHANGE, devices);
}
void OnP2pServicesChanged(const std::vector<WifiP2pServiceInfo>& srvInfo) override {
}
void OnP2pConnectionChanged(const WifiP2pLinkedInfo& info) override {
WIFI_LOGI("received connection changed event");
CheckAndNotify(EVENT_P2P_CONN_STATE_CHANGE, info);
}
void OnP2pDiscoveryChanged(bool isChange) override {
WIFI_LOGI("received discovery state changed event");
CheckAndNotify(EVENT_P2P_DISCOVERY_CHANGE, (int)isChange);
}
void OnP2pActionResult(P2pActionCallback action, ErrCode code) override {
}
OHOS::sptr<OHOS::IRemoteObject> AsObject() override {
return nullptr;
}
};
napi_value On(napi_env env, napi_callback_info cbinfo) {
TRACE_FUNC_CALL;
@ -373,16 +322,10 @@ napi_value On(napi_env env, napi_callback_info cbinfo) {
napi_typeof(env, argv[1], &handler);
NAPI_ASSERT(env, handler == napi_function, "type mismatch for parameter 2");
EventManager *manager = nullptr;
napi_status status = napi_unwrap(env, thisVar, (void**)&manager);
if (status == napi_ok && manager != nullptr) {
char type[64] = {0};
size_t typeLen = 0;
napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &typeLen);
manager->SubscribeEvent(type, argv[1]);
} else {
WIFI_LOGE("On unwrap class failed");
}
char type[64] = {0};
size_t typeLen = 0;
napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &typeLen);
EventRegister::GetInstance().Register(env, type, argv[1]);
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
@ -408,42 +351,164 @@ napi_value Off(napi_env env, napi_callback_info cbinfo) {
NAPI_ASSERT(env, handler == napi_function, "type mismatch for parameter 2");
}
EventManager *manager = nullptr;
napi_status status = napi_unwrap(env, thisVar, (void**)&manager);
if (status == napi_ok && manager != nullptr) {
char type[64] = {0};
size_t typeLen = 0;
napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &typeLen);
manager->UnsubscribeEvent(type, argc >= requireArgcWithCb ? argv[1] : nullptr);
} else {
WIFI_LOGE("Off unwrap class failed");
}
char type[64] = {0};
size_t typeLen = 0;
napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &typeLen);
EventRegister::GetInstance().Unregister(env, type, argc >= requireArgcWithCb ? argv[1] : nullptr);
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
napi_value EventListenerConstructor(napi_env env, napi_callback_info cbinfo) {
WIFI_LOGI("Event listener constructor");
napi_value thisVar = nullptr;
void* data = nullptr;
napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, &data);
sptr<WifiNapiDeviceEventCallback> wifiDeviceCallback =
sptr<WifiNapiDeviceEventCallback>(new (std::nothrow) WifiNapiDeviceEventCallback());
EventManager *eventManager = new EventManager(env, thisVar);
if (eventManager == nullptr) {
WIFI_LOGE("Init listener constructor failed");
return nullptr;
sptr<WifiNapiScanEventCallback> wifiScanCallback =
sptr<WifiNapiScanEventCallback>(new (std::nothrow) WifiNapiScanEventCallback());
sptr<WifiNapiHotspotEventCallback> wifiHotspotCallback =
sptr<WifiNapiHotspotEventCallback>(new (std::nothrow) WifiNapiHotspotEventCallback());
sptr<WifiNapiP2pEventCallback> wifiP2pCallback =
sptr<WifiNapiP2pEventCallback>(new (std::nothrow) WifiNapiP2pEventCallback());
bool EventRegister::isEventRegistered = false;
ErrCode EventRegister::RegisterWifiEvents()
{
std::unique_ptr<WifiDevice> wifiStaPtr = WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID);
if (wifiStaPtr == nullptr) {
WIFI_LOGE("Register sta event get instance failed!");
return WIFI_OPT_FAILED;
}
ErrCode ret = wifiStaPtr->RegisterCallBack(wifiDeviceCallback);
if (ret != WIFI_OPT_SUCCESS) {
WIFI_LOGE("Register sta event failed!");
return ret;
}
std::unique_ptr<WifiScan> wifiScanPtr = WifiScan::GetInstance(WIFI_SCAN_ABILITY_ID);
if (wifiScanPtr == nullptr) {
WIFI_LOGE("Register scan event get instance failed!");
return WIFI_OPT_FAILED;
}
ret = wifiScanPtr->RegisterCallBack(wifiScanCallback);
if (ret != WIFI_OPT_SUCCESS) {
WIFI_LOGE("Register scan event failed!");
return ret;
}
std::unique_ptr<WifiHotspot> wifiHotspotPtr = WifiHotspot::GetInstance(WIFI_HOTSPOT_ABILITY_ID);
if (wifiHotspotPtr == nullptr) {
WIFI_LOGE("Register hotspot event get instance failed!");
return WIFI_OPT_FAILED;
}
ret = wifiHotspotPtr->RegisterCallBack(wifiHotspotCallback);
if (ret != WIFI_OPT_SUCCESS) {
WIFI_LOGE("Register hotspot event failed!");
return ret;
}
std::unique_ptr<WifiP2p> wifiP2pPtr = WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID);
if (wifiP2pPtr == nullptr) {
WIFI_LOGE("Register p2p event get instance failed!");
return WIFI_OPT_FAILED;
}
ret = wifiP2pPtr->RegisterCallBack(wifiP2pCallback);
if (ret != WIFI_OPT_SUCCESS) {
WIFI_LOGE("Register p2p event failed!");
return ret;
}
return ret;
}
EventRegister& EventRegister::GetInstance()
{
static EventRegister inst;
return inst;
}
bool EventRegister::IsEventSupport(const std::string& type)
{
return g_supportEventList.find(type) != g_supportEventList.end();
}
void EventRegister::Register(const napi_env& env, const std::string& type, napi_value handler)
{
WIFI_LOGI("Register event: %{public}s, env: %{public}p", type.c_str(), env);
if (!IsEventSupport(type)) {
WIFI_LOGE("Register type error or not support!");
return;
}
std::unique_lock<std::shared_mutex> guard(g_regInfoMutex);
if (!isEventRegistered) {
if (RegisterWifiEvents() != WIFI_OPT_SUCCESS) {
return;
}
isEventRegistered = true;
}
napi_ref handlerRef = nullptr;
napi_create_reference(env, handler, 1, &handlerRef);
RegObj regObj(env, handlerRef);
auto iter = g_eventRegisterInfo.find(type);
if (iter == g_eventRegisterInfo.end()) {
g_eventRegisterInfo[type] = std::vector<RegObj>{regObj};
} else {
iter->second.emplace_back(regObj);
}
}
void EventRegister::DeleteRegisterObj(std::vector<RegObj>& vecRegObjs, napi_value& handler)
{
auto iter = vecRegObjs.begin();
for (; iter != vecRegObjs.end();) {
napi_value handlerTemp = nullptr;
napi_get_reference_value(iter->m_regEnv, iter->m_regHanderRef, &handlerTemp);
bool isEqual = false;
napi_strict_equals(iter->m_regEnv, handlerTemp, handler, &isEqual);
if (isEqual) {
napi_delete_reference(iter->m_regEnv, iter->m_regHanderRef);
WIFI_LOGI("Delete register object ref.");
iter = vecRegObjs.erase(iter);
} else {
++iter;
}
}
}
void EventRegister::DeleteAllRegisterObj(std::vector<RegObj>& vecRegObjs)
{
for (auto& each : vecRegObjs) {
napi_delete_reference(each.m_regEnv, each.m_regHanderRef);
}
vecRegObjs.clear();
}
void EventRegister::Unregister(const napi_env& env, const std::string& type, napi_value handler)
{
WIFI_LOGI("Unregister event: %{public}s, env: %{public}p", type.c_str(), env);
if (!IsEventSupport(type)) {
WIFI_LOGE("Unregister type error or not support!");
return;
}
std::unique_lock<std::shared_mutex> guard(g_regInfoMutex);
auto iter = g_eventRegisterInfo.find(type);
if (iter == g_eventRegisterInfo.end()) {
WIFI_LOGE("Unregister type not registered!");
return;
}
if (handler != nullptr) {
DeleteRegisterObj(iter->second, handler);
} else {
WIFI_LOGW("All callback is unsubscribe for event: %{public}s", type.c_str());
DeleteAllRegisterObj(iter->second);
}
if (iter->second.empty()) {
g_eventRegisterInfo.erase(iter);
}
napi_wrap(
env, thisVar, eventManager,
[](napi_env env, void* data, void* hint) {
WIFI_LOGI("Event listener destructor");
EventManager *eventManager = (EventManager *)data;
delete eventManager;
eventManager = nullptr;
},
nullptr, nullptr);
return thisVar;
}
} // namespace Wifi
} // namespace OHOS

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -20,85 +20,102 @@
#include <set>
#include <map>
#include "napi/native_api.h"
#include "common_event_manager.h"
#include "wifi_errcode.h"
#include <shared_mutex>
#include "wifi_hotspot.h"
namespace OHOS {
namespace Wifi {
typedef void (*UserDefinedEventProcessFunc)(const napi_env& env, const std::string& type,
const OHOS::EventFwk::CommonEventData& data);
class Event {
class AsyncEventData {
public:
Event(napi_env env, std::string& name) : m_env(env), m_name(name) {
napi_env env;
napi_ref callbackRef;
napi_value jsEvent;
explicit AsyncEventData(napi_env e, napi_ref r, napi_value v) {
env = e;
callbackRef = r;
jsEvent = v;
}
virtual ~Event() {
AsyncEventData() = delete;
virtual ~AsyncEventData() {
}
virtual napi_value PackResult() = 0;
void SetName(std::string& name);
std::string GetName();
napi_env GetEnv();
private:
napi_env m_env;
std::string m_name;
};
class WifiCommonEvent: public Event {
class RegObj {
public:
WifiCommonEvent(napi_env env, std::string& name, int value) : Event(env, name), m_value(value) {
RegObj() : m_regEnv(0), m_regHanderRef(nullptr) {
}
explicit RegObj(const napi_env& env, const napi_ref& ref) {
m_regEnv = env;
m_regHanderRef = ref;
}
virtual napi_value PackResult();
~RegObj() {
}
private:
int m_value;
napi_env m_regEnv;
napi_ref m_regHanderRef;
};
class WifiEventSubscriber : public OHOS::EventFwk::CommonEventSubscriber {
static std::shared_mutex g_regInfoMutex;
static std::map<std::string, std::vector<RegObj>> g_eventRegisterInfo;
class NapiEvent {
public:
explicit WifiEventSubscriber(const OHOS::EventFwk::CommonEventSubscribeInfo &subscribeInfo) :
CommonEventSubscriber(subscribeInfo) {
}
bool CheckIsRegister(const std::string& type);
napi_value CreateResult(const napi_env& env, int value);
napi_value CreateResult(const napi_env& env, const StationInfo& info);
napi_value CreateResult(const napi_env& env, napi_value placehoders);
napi_value CreateResult(const napi_env& env, const WifiP2pDevice& device);
napi_value CreateResult(const napi_env& env, const std::vector<WifiP2pDevice>& devices);
napi_value CreateResult(const napi_env& env, const WifiP2pLinkedInfo& info);
void EventNotify(AsyncEventData *asyncEvent);
virtual ~WifiEventSubscriber() {
}
template<typename T>
void CheckAndNotify(const std::string& type, const T& obj) {
std::shared_lock<std::shared_mutex> guard(g_regInfoMutex);
if (!CheckIsRegister(type)) {
return;
}
virtual void OnReceiveEvent(const OHOS::EventFwk::CommonEventData &data) override;
std::vector<RegObj>& vecObj = g_eventRegisterInfo[type];
for (auto& each : vecObj) {
napi_value result = CreateResult(each.m_regEnv, obj);
AsyncEventData *asyncEvent = new AsyncEventData(each.m_regEnv, each.m_regHanderRef, result);
if (asyncEvent == nullptr) {
return;
}
EventNotify(asyncEvent);
}
}
};
class EventRegisterInfo;
class EventManager {
class EventRegister {
public:
EventManager(napi_env env, napi_value thisVar);
virtual ~EventManager();
EventRegister() {
}
~EventRegister() {
}
bool Send(Event& event);
bool SubscribeEvent(const std::string& name, napi_value handler);
bool UnsubscribeEvent(const std::string& name, napi_value handler);
napi_env GetEnv();
static EventRegister& GetInstance();
void Register(const napi_env& env, const std::string& type, napi_value handler);
void Unregister(const napi_env& env, const std::string& type, napi_value handler);
private:
bool SubscribeServiceEvent(const std::string& event);
bool UnsubscribeServiceEvent(const std::string& event);
void DeleteHanderRef(std::set<napi_ref>& setRefs, napi_value handler);
void DeleteAllHanderRef(std::set<napi_ref>& setRefs);
void SetEventType(const std::string& type);
ErrCode RegisterWifiEvents();
bool IsEventSupport(const std::string& type);
void DeleteRegisterObj(std::vector<RegObj>& vecRegObjs, napi_value& handler);
void DeleteAllRegisterObj(std::vector<RegObj>& vecRegObjs);
private:
napi_env m_env;
napi_ref m_thisVarRef;
std::string m_eventType;
static bool isEventRegistered;
};
napi_value On(napi_env env, napi_callback_info cbinfo);
napi_value Off(napi_env env, napi_callback_info cbinfo);
napi_value EventListenerConstructor(napi_env env, napi_callback_info cbinfo);
} // namespace Wifi
} // namespace OHOS

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -25,7 +25,7 @@ std::unique_ptr<WifiP2p> wifiP2pPtr = WifiP2p::GetInstance(WIFI_P2P_ABILITY_ID);
napi_value EnableP2p(napi_env env, napi_callback_info info)
{
TRACE_FUNC_CALL;
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
ErrCode ret = wifiP2pPtr->EnableP2p();
napi_value result;
@ -36,7 +36,7 @@ napi_value EnableP2p(napi_env env, napi_callback_info info)
napi_value DisableP2p(napi_env env, napi_callback_info info)
{
TRACE_FUNC_CALL;
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
ErrCode ret = wifiP2pPtr->DisableP2p();
napi_value result;
@ -64,7 +64,7 @@ static void WfdInfoToJs(const napi_env& env, const WifiP2pWfdInfo& wfdInfo, napi
SetValueInt32(env, "maxThroughput", wfdInfo.GetMaxThroughput(), result);
}
static bool DeviceInfosToJs(const napi_env& env,
static ErrCode DeviceInfosToJs(const napi_env& env,
const std::vector<WifiP2pDevice>& vecDevices, napi_value& arrayResult)
{
uint32_t idx = 0;
@ -80,13 +80,13 @@ static bool DeviceInfosToJs(const napi_env& env,
napi_status status = napi_set_element(env, arrayResult, idx++, eachObj);
if (status != napi_ok) {
WIFI_LOGE("wifi napi set element error: %{public}d, idx: %{public}d", status, idx - 1);
return false;
return WIFI_OPT_FAILED;
}
}
return true;
return WIFI_OPT_SUCCESS;
}
static bool GroupInfosToJs(const napi_env& env, WifiP2pGroupInfo& groupInfo, napi_value& result)
static ErrCode GroupInfosToJs(const napi_env& env, WifiP2pGroupInfo& groupInfo, napi_value& result)
{
SetValueBool(env, "isP2pGroupOwner", groupInfo.IsGroupOwner(), result);
SetValueUtf8String(env, "passphrase", groupInfo.GetPassphrase().c_str(), result);
@ -105,22 +105,22 @@ static bool GroupInfosToJs(const napi_env& env, WifiP2pGroupInfo& groupInfo, nap
napi_status status = napi_set_named_property(env, result, "owner", owner);
if (status != napi_ok) {
WIFI_LOGE("napi_set_named_property owner fail");
return false;
return WIFI_OPT_FAILED;
}
if (!groupInfo.IsClientDevicesEmpty()) {
const std::vector<OHOS::Wifi::WifiP2pDevice>& vecDevices = groupInfo.GetClientDevices();
napi_value devices;
napi_create_array_with_length(env, vecDevices.size(), &devices);
if (!DeviceInfosToJs(env, vecDevices, devices)) {
return false;
if (DeviceInfosToJs(env, vecDevices, devices) != WIFI_OPT_SUCCESS) {
return WIFI_OPT_FAILED;
}
status = napi_set_named_property(env, result, "clientDevices", devices);
if (status != napi_ok) {
WIFI_LOGE("napi_set_named_property clientDevices fail");
return false;
return WIFI_OPT_FAILED;
}
}
return true;
return WIFI_OPT_SUCCESS;
}
napi_value GetCurrentGroup(napi_env env, napi_callback_info info)
@ -139,13 +139,13 @@ napi_value GetCurrentGroup(napi_env env, napi_callback_info info)
asyncContext->executeFunc = [&](void* data) -> void {
P2pGroupInfoAsyncContext *context = static_cast<P2pGroupInfoAsyncContext *>(data);
TRACE_FUNC_CALL_NAME("wifiP2pPtr->GetCurrentGroup");
context->isSuccess = (wifiP2pPtr->GetCurrentGroup(context->groupInfo) == WIFI_OPT_SUCCESS);
context->errorCode = wifiP2pPtr->GetCurrentGroup(context->groupInfo);
};
asyncContext->completeFunc = [&](void* data) -> void {
P2pGroupInfoAsyncContext *context = static_cast<P2pGroupInfoAsyncContext *>(data);
napi_create_object(context->env, &context->result);
context->isSuccess = GroupInfosToJs(context->env, context->groupInfo, context->result);
context->errorCode = GroupInfosToJs(context->env, context->groupInfo, context->result);
WIFI_LOGI("Push get current group result to client");
};
@ -168,7 +168,7 @@ napi_value StartP2pListen(napi_env env, napi_callback_info info)
NAPI_ASSERT(env, valueType == napi_number, "Wrong argument 1 type. napi_number expected.");
NAPI_ASSERT(env, value2Type == napi_object, "Wrong argument 2 type. napi_number expected.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
int period;
int interval;
napi_get_value_int32(env, argv[0], &period);
@ -182,7 +182,7 @@ napi_value StartP2pListen(napi_env env, napi_callback_info info)
napi_value StopP2pListen(napi_env env, napi_callback_info info)
{
TRACE_FUNC_CALL;
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
ErrCode ret = wifiP2pPtr->StopP2pListen();
napi_value result;
@ -202,7 +202,7 @@ napi_value DeletePersistentGroup(napi_env env, napi_callback_info info)
napi_typeof(env, argv[0], &valueType);
NAPI_ASSERT(env, valueType == napi_number, "Wrong argument type. napi_number expected.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
WifiP2pGroupInfo groupInfo;
int netId = -999;
napi_get_value_int32(env, argv[0], &netId);
@ -216,7 +216,7 @@ napi_value DeletePersistentGroup(napi_env env, napi_callback_info info)
napi_value StartDiscoverDevices(napi_env env, napi_callback_info info)
{
TRACE_FUNC_CALL;
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
ErrCode ret = wifiP2pPtr->DiscoverDevices();
napi_value result;
@ -227,7 +227,7 @@ napi_value StartDiscoverDevices(napi_env env, napi_callback_info info)
napi_value StopDiscoverDevices(napi_env env, napi_callback_info info)
{
TRACE_FUNC_CALL;
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
ErrCode ret = wifiP2pPtr->StopDiscoverDevices();
napi_value result;
@ -250,14 +250,14 @@ napi_value GetP2pDevices(napi_env env, napi_callback_info info)
asyncContext->executeFunc = [&](void* data) -> void {
QueryP2pDeviceAsyncContext *context = static_cast<QueryP2pDeviceAsyncContext *>(data);
context->isSuccess = (wifiP2pPtr->QueryP2pDevices(context->vecP2pDevices) == WIFI_OPT_SUCCESS);
context->errorCode = wifiP2pPtr->QueryP2pDevices(context->vecP2pDevices);
WIFI_LOGI("GetP2pDeviceList, size: %{public}zu", context->vecP2pDevices.size());
};
asyncContext->completeFunc = [&](void* data) -> void {
QueryP2pDeviceAsyncContext *context = static_cast<QueryP2pDeviceAsyncContext *>(data);
napi_create_array_with_length(context->env, context->vecP2pDevices.size(), &context->result);
context->isSuccess = DeviceInfosToJs(context->env, context->vecP2pDevices, context->result);
context->errorCode = DeviceInfosToJs(context->env, context->vecP2pDevices, context->result);
WIFI_LOGI("Push P2p Device List to client");
};
@ -323,7 +323,7 @@ napi_value P2pConnect(napi_env env, napi_callback_info info)
napi_typeof(env, argv[0], &valueType);
NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type. Object expected.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
WifiP2pConfig config;
JsObjToP2pConfig(env, argv[0], config);
ErrCode ret = wifiP2pPtr->P2pConnect(config);
@ -338,7 +338,7 @@ napi_value P2pConnect(napi_env env, napi_callback_info info)
napi_value P2pDisConnect(napi_env env, napi_callback_info info)
{
TRACE_FUNC_CALL;
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
ErrCode ret = wifiP2pPtr->P2pDisConnect();
napi_value result;
@ -358,7 +358,7 @@ napi_value CreateGroup(napi_env env, napi_callback_info info)
napi_typeof(env, argv[0], &valueType);
NAPI_ASSERT(env, valueType == napi_object, "Wrong argument type. Object expected.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
WifiP2pConfig config;
JsObjToP2pConfig(env, argv[0], config);
@ -371,7 +371,7 @@ napi_value CreateGroup(napi_env env, napi_callback_info info)
napi_value RemoveGroup(napi_env env, napi_callback_info info)
{
TRACE_FUNC_CALL;
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "[NAPI] Wifi p2p instance is null.");
NAPI_ASSERT(env, wifiP2pPtr != nullptr, "Wifi p2p instance is null.");
ErrCode ret = wifiP2pPtr->RemoveGroup();
napi_value result;
@ -403,7 +403,7 @@ napi_value GetP2pLinkedInfo(napi_env env, napi_callback_info info)
asyncContext->executeFunc = [&](void* data) -> void {
P2pLinkedInfoAsyncContext *context = static_cast<P2pLinkedInfoAsyncContext *>(data);
TRACE_FUNC_CALL_NAME("wifiP2pPtr->QueryP2pLinkedInfo");
context->isSuccess = (wifiP2pPtr->QueryP2pLinkedInfo(context->linkedInfo) == WIFI_OPT_SUCCESS);
context->errorCode = wifiP2pPtr->QueryP2pLinkedInfo(context->linkedInfo);
};
asyncContext->completeFunc = [&](void* data) -> void {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -236,15 +236,19 @@ static napi_value DoCallBackAsyncWork(const napi_env& env, AsyncContext *asyncCo
napi_get_undefined(env, &undefine);
napi_value callback;
context->completeFunc(data);
if (context->isSuccess) {
constexpr int ARGS_TWO = 2;
napi_value result[ARGS_TWO] = {nullptr};
napi_create_uint32(env, context->errorCode, &result[0]);
result[1] = context->result;
if (context->errorCode == ERR_CODE_SUCCESS) {
napi_get_reference_value(env, context->callback[0], &callback);
napi_call_function(env, nullptr, callback, 1, &context->result, &undefine);
napi_call_function(env, nullptr, callback, ARGS_TWO, result, &undefine);
} else {
if (context->callback[1]) {
napi_get_reference_value(env, context->callback[1], &callback);
napi_call_function(env, nullptr, callback, 1, &context->result, &undefine);
napi_call_function(env, nullptr, callback, ARGS_TWO, result, &undefine);
} else {
WIFI_LOGE("Get scan info callback func is null");
WIFI_LOGE("Get callback func[1] is null");
}
}
if (context->callback[0] != nullptr) {
@ -283,7 +287,7 @@ static napi_value DoPromiseAsyncWork(const napi_env& env, AsyncContext *asyncCon
}
AsyncContext *context = (AsyncContext *)data;
context->completeFunc(data);
if (context->isSuccess) {
if (context->errorCode == ERR_CODE_SUCCESS) {
napi_resolve_deferred(context->env, context->deferred, context->result);
} else {
napi_reject_deferred(context->env, context->deferred, context->result);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -40,6 +40,8 @@ private:
#define TRACE_FUNC_CALL TraceFuncCall func(__func__)
#define TRACE_FUNC_CALL_NAME(name) TraceFuncCall funcName(name)
constexpr int ERR_CODE_SUCCESS = 0;
class AsyncContext {
public:
napi_env env;
@ -50,7 +52,7 @@ public:
std::function<void(void*)> completeFunc;
napi_value resourceName;
napi_value result;
bool isSuccess;
int errorCode;
AsyncContext(napi_env e, napi_async_work w = nullptr, napi_deferred d = nullptr)
{
@ -60,7 +62,7 @@ public:
executeFunc = nullptr;
completeFunc = nullptr;
result = nullptr;
isSuccess = false;
errorCode = ERR_CODE_SUCCESS;
}
AsyncContext() = delete;

View File

@ -393,12 +393,12 @@ declare namespace wifi {
function p2pConnect(config: WifiP2PConfig): boolean;
/**
* Disconnects a P2P connection.
* Canceling a P2P connection.
*
* @return Returns {@code true} if the scanning is successful; returns {@code false} otherwise.
* @since 8
*/
function p2pDisconnect(): boolean;
function p2pCancelConnect(): boolean;
/**
* Discovers Wi-Fi P2P devices.
@ -416,26 +416,6 @@ declare namespace wifi {
*/
function stopDiscoveryDevices(): boolean;
/**
* Enables P2P listening.
*
* <p>After P2P listening is enabled, your application can listen for and respond to requests from other devices.
*
* @return Returns {@code true} if the scanning is successful; returns {@code false} otherwise.
* @since 8
*/
function startListen(): boolean;
/**
* Disables P2P listening.
*
* <p>After P2P listening is disabled, your application cannot listen for requests from other devices.
*
* @return Returns {@code true} if the scanning is successful; returns {@code false} otherwise.
* @since 8
*/
function stopListen(): boolean;
/**
* Deletes the persistent P2P group with the specified network ID.
*
@ -950,7 +930,7 @@ declare namespace wifi {
deviceAddress: string;
/** Primary device type */
primaryDeviceType: number;
primaryDeviceType: string;
/** Device status */
devStatus: P2pDeviceStatus;