1 /* 2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef WIFI_NAPI_EVENT_H_ 17 #define WIFI_NAPI_EVENT_H_ 18 19 #include <string> 20 #include <set> 21 #include <map> 22 #include "napi/native_api.h" 23 #include "wifi_errcode.h" 24 #include <shared_mutex> 25 #include "wifi_p2p.h" 26 #include "wifi_hotspot.h" 27 #include "wifi_logger.h" 28 #include "wifi_sa_event.h" 29 30 DEFINE_WIFILOG_LABEL("WifiNapiEvent"); 31 32 namespace OHOS { 33 namespace Wifi { 34 class RegObj { 35 public: RegObj()36 RegObj() : m_regEnv(0), m_regHanderRef(nullptr) { 37 } RegObj(const napi_env & env,const napi_ref & ref)38 explicit RegObj(const napi_env& env, const napi_ref& ref) { 39 m_regEnv = env; 40 m_regHanderRef = ref; 41 } 42 ~RegObj()43 ~RegObj() { 44 } 45 46 bool operator == (const RegObj& other) const { 47 return m_regEnv == other.m_regEnv && m_regHanderRef == other.m_regHanderRef; 48 } 49 50 bool operator != (const RegObj& other) const { 51 return !(*this == other); 52 } 53 54 bool operator < (const RegObj& other) const { 55 return m_regEnv < other.m_regEnv || (m_regEnv == other.m_regEnv && m_regHanderRef < other.m_regHanderRef); 56 } 57 58 napi_env m_regEnv; 59 napi_ref m_regHanderRef; 60 }; 61 62 class AsyncEventData { 63 public: 64 napi_env env; 65 napi_ref callbackRef; 66 std::function<napi_value ()> packResult; 67 std::string eventType; 68 AsyncEventData(napi_env e,napi_ref r,std::function<napi_value ()> p,const std::string & type)69 explicit AsyncEventData(napi_env e, napi_ref r, std::function<napi_value ()> p, const std::string& type) 70 { 71 env = e; 72 callbackRef = r; 73 packResult = p; 74 eventType = type; 75 } 76 77 AsyncEventData() = delete; 78 ~AsyncEventData()79 virtual ~AsyncEventData() { 80 } 81 }; 82 83 static std::shared_mutex g_regInfoMutex; 84 static std::map<std::string, std::vector<RegObj>> g_eventRegisterInfo; 85 86 class NapiEvent { 87 public: 88 napi_value CreateResult(const napi_env& env, int value); 89 napi_value CreateResult(const napi_env& env, const StationInfo& info); 90 napi_value CreateResult(const napi_env& env, napi_value placehoders); 91 napi_value CreateResult(const napi_env& env, const WifiP2pDevice& device); 92 napi_value CreateResult(const napi_env& env, const std::vector<WifiP2pDevice>& devices); 93 napi_value CreateResult(const napi_env& env, const WifiP2pLinkedInfo& info); 94 void EventNotify(AsyncEventData *asyncEvent); 95 96 template<typename T> CheckAndNotify(const std::string & type,const T & obj)97 void CheckAndNotify(const std::string& type, const T& obj) { 98 std::shared_lock<std::shared_mutex> guard(g_regInfoMutex); 99 auto it = g_eventRegisterInfo.find(type); 100 if (it == g_eventRegisterInfo.end()) { 101 WIFI_LOGW("not find register info."); 102 return; 103 } 104 for (auto& each : it->second) { 105 auto func = [this, env = each.m_regEnv, obj] () -> napi_value { return CreateResult(env, obj); }; 106 AsyncEventData *asyncEvent = new (std::nothrow)AsyncEventData(each.m_regEnv, each.m_regHanderRef, 107 func, type); 108 if (asyncEvent == nullptr) { 109 return; 110 } 111 EventNotify(asyncEvent); 112 } 113 } 114 }; 115 116 class WifiNapiAbilityStatusChange : public WifiAbilityStatusChange { 117 public: 118 void OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; 119 }; 120 121 class EventRegister { 122 public: EventRegister()123 EventRegister() 124 { 125 int32_t ret; 126 auto samgrProxy = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 127 if (samgrProxy == nullptr) { 128 WIFI_LOGI("samgrProxy is nullptr!"); 129 return; 130 } 131 mSaStatusListener = new OHOS::Wifi::WifiNapiAbilityStatusChange(); 132 if (mSaStatusListener == nullptr) { 133 WIFI_LOGI("mSaStatusListener is nullptr!"); 134 return; 135 } 136 ret = samgrProxy->SubscribeSystemAbility((int32_t)WIFI_DEVICE_ABILITY_ID, mSaStatusListener); 137 samgrProxy->SubscribeSystemAbility((int32_t)WIFI_SCAN_ABILITY_ID, mSaStatusListener); 138 samgrProxy->SubscribeSystemAbility((int32_t)WIFI_HOTSPOT_ABILITY_ID, mSaStatusListener); 139 samgrProxy->SubscribeSystemAbility((int32_t)WIFI_P2P_ABILITY_ID, mSaStatusListener); 140 WIFI_LOGI("EventRegister, SubscribeSystemAbility return ret:%{public}d!", ret); 141 } ~EventRegister()142 ~EventRegister() { 143 } 144 145 static EventRegister& GetInstance(); 146 static void CleanUp(void *data); 147 148 void Register(const napi_env& env, const std::string& type, napi_value handler); 149 void Unregister(const napi_env& env, const std::string& type, napi_value handler); 150 ErrCode RegisterDeviceEvents(const std::vector<std::string> &event); 151 ErrCode RegisterScanEvents(const std::vector<std::string> &event); 152 ErrCode RegisterHotspotEvents(const std::vector<std::string> &event); 153 ErrCode RegisterP2PEvents(const std::vector<std::string> &event); 154 155 private: 156 ErrCode RegisterWifiEvents(int32_t sysCap, const std::string& type); 157 bool IsEventSupport(const std::string& type); 158 void DeleteRegisterObj(const napi_env& env, std::vector<RegObj>& vecRegObjs, napi_value& handler); 159 void DeleteAllRegisterObj(const napi_env& env, std::vector<RegObj>& vecRegObjs); 160 OHOS::sptr<OHOS::ISystemAbilityStatusChange> mSaStatusListener = nullptr; 161 }; 162 163 napi_value On(napi_env env, napi_callback_info cbinfo); 164 napi_value Off(napi_env env, napi_callback_info cbinfo); 165 } // namespace Wifi 166 } // namespace OHOS 167 168 #endif 169