• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2024 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 #include "event_listener_handler.h"
17 
18 #include <cinttypes>
19 
20 #include "event_listener_manager.h"
21 #include "inner_event.h"
22 #include "napi_parameter_util.h"
23 #include "napi_radio_types.h"
24 #include "napi_state_registry.h"
25 #include "napi_telephony_observer.h"
26 #include "napi_util.h"
27 #include "singleton.h"
28 #include "telephony_errors.h"
29 #include "telephony_log_wrapper.h"
30 #include "telephony_state_manager.h"
31 #include "update_contexts.h"
32 
33 namespace OHOS {
34 namespace Telephony {
35 namespace {
WrapRegState(int32_t nativeState)36 int32_t WrapRegState(int32_t nativeState)
37 {
38     RegServiceState state = static_cast<RegServiceState>(nativeState);
39     switch (state) {
40         case RegServiceState::REG_STATE_NO_SERVICE:
41         case RegServiceState::REG_STATE_SEARCH: {
42             return RegStatus::REGISTRATION_STATE_NO_SERVICE;
43         }
44         case RegServiceState::REG_STATE_IN_SERVICE: {
45             return RegStatus::REGISTRATION_STATE_IN_SERVICE;
46         }
47         case RegServiceState::REG_STATE_EMERGENCY_ONLY: {
48             return RegStatus::REGISTRATION_STATE_EMERGENCY_CALL_ONLY;
49         }
50         case RegServiceState::REG_STATE_UNKNOWN: {
51             return RegStatus::REGISTRATION_STATE_POWER_OFF;
52         }
53         default:
54             return RegStatus::REGISTRATION_STATE_POWER_OFF;
55     }
56 }
57 
WrapCallState(int32_t callState)58 int32_t WrapCallState(int32_t callState)
59 {
60     switch (callState) {
61         case (int32_t)Telephony::CallStatus::CALL_STATUS_ACTIVE:
62         case (int32_t)Telephony::CallStatus::CALL_STATUS_HOLDING:
63         case (int32_t)Telephony::CallStatus::CALL_STATUS_DIALING:
64         case (int32_t)Telephony::CallStatus::CALL_STATUS_ALERTING:
65             return static_cast<int32_t>(CallState::CALL_STATE_OFFHOOK);
66         case (int32_t)Telephony::CallStatus::CALL_STATUS_WAITING:
67         case (int32_t)Telephony::CallStatus::CALL_STATUS_INCOMING:
68             return static_cast<int32_t>(CallState::CALL_STATE_RINGING);
69         case (int32_t)Telephony::CallStatus::CALL_STATUS_DISCONNECTING:
70         case (int32_t)Telephony::CallStatus::CALL_STATUS_DISCONNECTED:
71         case (int32_t)Telephony::CallStatus::CALL_STATUS_IDLE:
72             return static_cast<int32_t>(CallState::CALL_STATE_IDLE);
73         case (int32_t)Telephony::CallStatus::CALL_STATUS_ANSWERED:
74             return static_cast<int32_t>(CallState::CALL_STATE_ANSWERED);
75         default:
76             return static_cast<int32_t>(CallState::CALL_STATE_UNKNOWN);
77     }
78 }
79 
WrapNetworkType(SignalInformation::NetworkType nativeNetworkType)80 int32_t WrapNetworkType(SignalInformation::NetworkType nativeNetworkType)
81 {
82     NetworkType jsNetworkType = NetworkType::NETWORK_TYPE_UNKNOWN;
83     switch (nativeNetworkType) {
84         case SignalInformation::NetworkType::GSM: {
85             jsNetworkType = NetworkType::NETWORK_TYPE_GSM;
86             break;
87         }
88         case SignalInformation::NetworkType::CDMA: {
89             jsNetworkType = NetworkType::NETWORK_TYPE_CDMA;
90             break;
91         }
92         case SignalInformation::NetworkType::LTE: {
93             jsNetworkType = NetworkType::NETWORK_TYPE_LTE;
94             break;
95         }
96         case SignalInformation::NetworkType::TDSCDMA: {
97             jsNetworkType = NetworkType::NETWORK_TYPE_TDSCDMA;
98             break;
99         }
100         case SignalInformation::NetworkType::WCDMA: {
101             jsNetworkType = NetworkType::NETWORK_TYPE_WCDMA;
102             break;
103         }
104         default: {
105             jsNetworkType = NetworkType::NETWORK_TYPE_UNKNOWN;
106         }
107     }
108     return static_cast<int32_t>(jsNetworkType);
109 }
110 
WrapRadioTech(int32_t radioTechType)111 int32_t WrapRadioTech(int32_t radioTechType)
112 {
113     RadioTech techType = static_cast<RadioTech>(radioTechType);
114     switch (techType) {
115         case RadioTech::RADIO_TECHNOLOGY_GSM:
116             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_GSM);
117         case RadioTech::RADIO_TECHNOLOGY_LTE:
118             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_LTE);
119         case RadioTech::RADIO_TECHNOLOGY_WCDMA:
120             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_WCDMA);
121         case RadioTech::RADIO_TECHNOLOGY_1XRTT:
122             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_1XRTT);
123         case RadioTech::RADIO_TECHNOLOGY_HSPA:
124             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_HSPA);
125         case RadioTech::RADIO_TECHNOLOGY_HSPAP:
126             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_HSPAP);
127         case RadioTech::RADIO_TECHNOLOGY_TD_SCDMA:
128             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_TD_SCDMA);
129         case RadioTech::RADIO_TECHNOLOGY_EVDO:
130             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_EVDO);
131         case RadioTech::RADIO_TECHNOLOGY_EHRPD:
132             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_EHRPD);
133         case RadioTech::RADIO_TECHNOLOGY_LTE_CA:
134             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_LTE_CA);
135         case RadioTech::RADIO_TECHNOLOGY_IWLAN:
136             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_IWLAN);
137         case RadioTech::RADIO_TECHNOLOGY_NR:
138             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_NR);
139         default:
140             return static_cast<int32_t>(RatType::RADIO_TECHNOLOGY_UNKNOWN);
141     }
142 }
143 
NapiReturnToJS(napi_env env,napi_ref callbackRef,napi_value callbackVal,std::unique_lock<std::mutex> & lock)144 napi_status NapiReturnToJS(
145     napi_env env, napi_ref callbackRef, napi_value callbackVal, std::unique_lock<std::mutex> &lock)
146 {
147     if (callbackRef == nullptr) {
148         TELEPHONY_LOGE("NapiReturnToJS callbackRef is nullptr");
149         return napi_ok;
150     }
151     napi_value callbackFunc = nullptr;
152     napi_get_reference_value(env, callbackRef, &callbackFunc);
153     lock.unlock();
154     napi_value callbackValues[] = { callbackVal };
155     napi_value recv = nullptr;
156     napi_get_undefined(env, &recv);
157     napi_value callbackResult = nullptr;
158     napi_status status =
159         napi_call_function(env, recv, callbackFunc, std::size(callbackValues), callbackValues, &callbackResult);
160     if (status != napi_ok) {
161         TELEPHONY_LOGE("NapiReturnToJS napi_call_function return error : %{public}d", status);
162     }
163     return status;
164 }
165 
SignalInfoConversion(napi_env env,int32_t type,int32_t level,int32_t signalIntensity)166 napi_value SignalInfoConversion(napi_env env, int32_t type, int32_t level, int32_t signalIntensity)
167 {
168     napi_value val = nullptr;
169     napi_create_object(env, &val);
170     SetPropertyToNapiObject(env, val, "signalType", type);
171     SetPropertyToNapiObject(env, val, "signalLevel", level);
172     SetPropertyToNapiObject(env, val, "dBm", signalIntensity);
173     return val;
174 }
175 
DataOfNetworkConversion(napi_env env,const GsmCellInformation & info)176 napi_value DataOfNetworkConversion(napi_env env, const GsmCellInformation &info)
177 {
178     napi_value val = nullptr;
179     napi_create_object(env, &val);
180     SetPropertyToNapiObject(env, val, "lac", info.GetLac());
181     SetPropertyToNapiObject(env, val, "cellId", info.GetCellId());
182     SetPropertyToNapiObject(env, val, "arfcn", info.GetArfcn());
183     SetPropertyToNapiObject(env, val, "basic", info.GetBsic());
184     SetPropertyToNapiObject(env, val, "mcc", info.GetMcc());
185     SetPropertyToNapiObject(env, val, "mnc", info.GetMnc());
186     return val;
187 }
188 
DataOfNetworkConversion(napi_env env,const LteCellInformation & info)189 napi_value DataOfNetworkConversion(napi_env env, const LteCellInformation &info)
190 {
191     napi_value val = nullptr;
192     napi_create_object(env, &val);
193     SetPropertyToNapiObject(env, val, "cgi", info.GetCellId());
194     SetPropertyToNapiObject(env, val, "pci", info.GetPci());
195     SetPropertyToNapiObject(env, val, "tac", info.GetTac());
196     SetPropertyToNapiObject(env, val, "earfcn", info.GetArfcn());
197     SetPropertyToNapiObject(env, val, "bandwith", 0);
198     SetPropertyToNapiObject(env, val, "mcc", info.GetMcc());
199     SetPropertyToNapiObject(env, val, "mnc", info.GetMnc());
200     SetPropertyToNapiObject(env, val, "isSupportEndc", false);
201     return val;
202 }
203 
DataOfNetworkConversion(napi_env env,const WcdmaCellInformation & info)204 napi_value DataOfNetworkConversion(napi_env env, const WcdmaCellInformation &info)
205 {
206     napi_value val = nullptr;
207     napi_create_object(env, &val);
208     SetPropertyToNapiObject(env, val, "lac", info.GetLac());
209     SetPropertyToNapiObject(env, val, "cellId", info.GetCellId());
210     SetPropertyToNapiObject(env, val, "psc", info.GetPsc());
211     SetPropertyToNapiObject(env, val, "uarfcn", info.GetArfcn());
212     SetPropertyToNapiObject(env, val, "mcc", info.GetMcc());
213     SetPropertyToNapiObject(env, val, "mnc", info.GetMnc());
214     return val;
215 }
216 
DataOfNetworkConversion(napi_env env,const NrCellInformation & info)217 napi_value DataOfNetworkConversion(napi_env env, const NrCellInformation &info)
218 {
219     napi_value val = nullptr;
220     napi_create_object(env, &val);
221     SetPropertyToNapiObject(env, val, "nrArfcn", info.GetArfcn());
222     SetPropertyToNapiObject(env, val, "pci", info.GetPci());
223     SetPropertyToNapiObject(env, val, "tac", info.GetTac());
224     SetPropertyToNapiObject(env, val, "nci", info.GetNci());
225     SetPropertyToNapiObject(env, val, "mcc", info.GetMcc());
226     SetPropertyToNapiObject(env, val, "mnc", info.GetMnc());
227     return val;
228 }
229 
CellInfoConversion(napi_env env,const CellInformation & info)230 napi_value CellInfoConversion(napi_env env, const CellInformation &info)
231 {
232     napi_value val = nullptr;
233     napi_create_object(env, &val);
234     CellInformation::CellType networkType = info.GetNetworkType();
235     SetPropertyToNapiObject(env, val, "networkType", static_cast<int32_t>(networkType));
236     SetPropertyToNapiObject(env, val, "isCamped", info.GetIsCamped());
237     SetPropertyToNapiObject(env, val, "timeStamp", static_cast<int64_t>(info.GetTimeStamp()));
238     SetPropertyToNapiObject(env, val, "signalInformation",
239         SignalInfoConversion(env, static_cast<int32_t>(networkType), info.GetSignalLevel(), info.GetSignalIntensity()));
240 
241     switch (networkType) {
242         case CellInformation::CellType::CELL_TYPE_GSM:
243             napi_set_named_property(
244                 env, val, "data", DataOfNetworkConversion(env, static_cast<const GsmCellInformation &>(info)));
245             break;
246         case CellInformation::CellType::CELL_TYPE_LTE:
247             napi_set_named_property(
248                 env, val, "data", DataOfNetworkConversion(env, static_cast<const LteCellInformation &>(info)));
249             break;
250         case CellInformation::CellType::CELL_TYPE_WCDMA:
251             napi_set_named_property(
252                 env, val, "data", DataOfNetworkConversion(env, static_cast<const WcdmaCellInformation &>(info)));
253             break;
254         case CellInformation::CellType::CELL_TYPE_NR:
255             napi_set_named_property(
256                 env, val, "data", DataOfNetworkConversion(env, static_cast<const NrCellInformation &>(info)));
257             break;
258         default:
259             break;
260     }
261     return val;
262 }
263 
InitLoop(napi_env env,uv_loop_s ** loop)264 bool InitLoop(napi_env env, uv_loop_s **loop)
265 {
266 #if NAPI_VERSION >= 2
267     napi_status status = napi_get_uv_event_loop(env, loop);
268     if (status != napi_ok) {
269         TELEPHONY_LOGE("napi_get_uv_event_loop napi_status = %{public}d", status);
270         return false;
271     }
272 #endif // NAPI_VERSION >= 2
273     return *loop != nullptr;
274 }
275 } // namespace
276 
277 std::map<TelephonyUpdateEventType,
278     void (*)(uv_work_t *work, std::unique_lock<std::mutex> &lock)> EventListenerHandler::workFuncMap_;
279 std::mutex EventListenerHandler::operatorMutex_;
280 
EventListenerHandler()281 EventListenerHandler::EventListenerHandler() : AppExecFwk::EventHandler(AppExecFwk::EventRunner::Create())
282 {
283     AddBasicHandlerToMap();
284     AddNetworkHandlerToMap();
285     AddWorkFuncToMap();
286 }
287 
~EventListenerHandler()288 EventListenerHandler::~EventListenerHandler()
289 {
290     handleFuncMap_.clear();
291     workFuncMap_.clear();
292     listenerList_.clear();
293 }
294 
AddBasicHandlerToMap()295 void EventListenerHandler::AddBasicHandlerToMap()
296 {
297     handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_CALL_STATE_UPDATE] =
298         [this](const AppExecFwk::InnerEvent::Pointer &event) {
299             HandleCallbackInfoUpdate<CallStateContext, CallStateUpdateInfo,
300                 TelephonyUpdateEventType::EVENT_CALL_STATE_UPDATE>(event);
301         };
302     handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_SIM_STATE_UPDATE] =
303         [this](const AppExecFwk::InnerEvent::Pointer &event) {
304             HandleCallbackInfoUpdate<SimStateContext, SimStateUpdateInfo,
305                 TelephonyUpdateEventType::EVENT_SIM_STATE_UPDATE>(event);
306         };
307     handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_CELLULAR_DATA_CONNECTION_UPDATE] =
308         [this](const AppExecFwk::InnerEvent::Pointer &event) {
309             HandleCallbackInfoUpdate<CellularDataConnectStateContext, CellularDataConnectState,
310                 TelephonyUpdateEventType::EVENT_DATA_CONNECTION_UPDATE>(event);
311         };
312     handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_CELLULAR_DATA_FLOW_UPDATE] =
313         [this](const AppExecFwk::InnerEvent::Pointer &event) {
314             HandleCallbackInfoUpdate<CellularDataFlowContext, CellularDataFlowUpdate,
315                 TelephonyUpdateEventType::EVENT_CELLULAR_DATA_FLOW_UPDATE>(event);
316         };
317     handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_CFU_INDICATOR_UPDATE] =
318         [this](const AppExecFwk::InnerEvent::Pointer &event) {
319             HandleCallbackInfoUpdate<CfuIndicatorContext, CfuIndicatorUpdate,
320                 TelephonyUpdateEventType::EVENT_CFU_INDICATOR_UPDATE>(event);
321         };
322     handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_VOICE_MAIL_MSG_INDICATOR_UPDATE] =
323         [this](const AppExecFwk::InnerEvent::Pointer &event) {
324             HandleCallbackInfoUpdate<VoiceMailMsgIndicatorContext, VoiceMailMsgIndicatorUpdate,
325                 TelephonyUpdateEventType::EVENT_VOICE_MAIL_MSG_INDICATOR_UPDATE>(event);
326         };
327     handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_ICC_ACCOUNT_UPDATE] =
328         [this](const AppExecFwk::InnerEvent::Pointer &event) {
329             HandleCallbackVoidUpdate<TelephonyUpdateEventType::EVENT_ICC_ACCOUNT_CHANGE>(event);
330         };
331 }
332 
AddNetworkHandlerToMap()333 void EventListenerHandler::AddNetworkHandlerToMap()
334 {
335     handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_SIGNAL_INFO_UPDATE] =
336         [this](const AppExecFwk::InnerEvent::Pointer &event) {
337             HandleCallbackInfoUpdate<SignalListContext, SignalUpdateInfo,
338                 TelephonyUpdateEventType::EVENT_SIGNAL_STRENGTHS_UPDATE>(event);
339         };
340     handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_NETWORK_STATE_UPDATE] =
341         [this](const AppExecFwk::InnerEvent::Pointer &event) {
342             HandleCallbackInfoUpdate<NetworkStateContext, NetworkStateUpdateInfo,
343                 TelephonyUpdateEventType::EVENT_NETWORK_STATE_UPDATE>(event);
344         };
345     handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_CELL_INFOMATION_UPDATE] =
346         [this](const AppExecFwk::InnerEvent::Pointer &event) {
347             HandleCallbackInfoUpdate<CellInfomationContext, CellInfomationUpdate,
348                 TelephonyUpdateEventType::EVENT_CELL_INFO_UPDATE>(event);
349         };
350 }
351 
AddWorkFuncToMap()352 void EventListenerHandler::AddWorkFuncToMap()
353 {
354     workFuncMap_[TelephonyUpdateEventType::EVENT_CALL_STATE_UPDATE] = &EventListenerHandler::WorkCallStateUpdated;
355     workFuncMap_[TelephonyUpdateEventType::EVENT_SIGNAL_STRENGTHS_UPDATE] = &EventListenerHandler::WorkSignalUpdated;
356     workFuncMap_[TelephonyUpdateEventType::EVENT_NETWORK_STATE_UPDATE] = &EventListenerHandler::WorkNetworkStateUpdated;
357     workFuncMap_[TelephonyUpdateEventType::EVENT_SIM_STATE_UPDATE] = &EventListenerHandler::WorkSimStateUpdated;
358     workFuncMap_[TelephonyUpdateEventType::EVENT_CELL_INFO_UPDATE] = &EventListenerHandler::WorkCellInfomationUpdated;
359     workFuncMap_[TelephonyUpdateEventType::EVENT_DATA_CONNECTION_UPDATE] =
360         &EventListenerHandler::WorkCellularDataConnectStateUpdated;
361     workFuncMap_[TelephonyUpdateEventType::EVENT_CELLULAR_DATA_FLOW_UPDATE] =
362         &EventListenerHandler::WorkCellularDataFlowUpdated;
363     workFuncMap_[TelephonyUpdateEventType::EVENT_CFU_INDICATOR_UPDATE] = &EventListenerHandler::WorkCfuIndicatorUpdated;
364     workFuncMap_[TelephonyUpdateEventType::EVENT_VOICE_MAIL_MSG_INDICATOR_UPDATE] =
365         &EventListenerHandler::WorkVoiceMailMsgIndicatorUpdated;
366     workFuncMap_[TelephonyUpdateEventType::EVENT_ICC_ACCOUNT_CHANGE] = &EventListenerHandler::WorkIccAccountUpdated;
367 }
368 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)369 void EventListenerHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
370 {
371     if (event == nullptr) {
372         TELEPHONY_LOGE("EventListenerHandler::ProcessEvent event is nullptr");
373         return;
374     }
375     auto itor = handleFuncMap_.find(static_cast<TelephonyCallbackEventId>(event->GetInnerEventId()));
376     if (itor != handleFuncMap_.end()) {
377         itor->second(event);
378     }
379 }
380 
CheckEventListenerRegister(EventListener & eventListener)381 int32_t EventListenerHandler::CheckEventListenerRegister(EventListener &eventListener)
382 {
383     int32_t flag = EVENT_LISTENER_DIFF;
384     for (auto &listen : listenerList_) {
385         if (eventListener.env == listen.env && eventListener.slotId == listen.slotId &&
386             eventListener.eventType == listen.eventType &&
387             IsCallBackRegister(eventListener.env, eventListener.callbackRef, listen.callbackRef)) {
388             flag = EVENT_LISTENER_SAME;
389             return flag;
390         }
391         if (eventListener.slotId == listen.slotId && eventListener.eventType == listen.eventType) {
392             flag = EVENT_LISTENER_SLOTID_AND_EVENTTYPE_SAME;
393         }
394     }
395     return flag;
396 }
397 
RegisterEventListener(EventListener & eventListener)398 int32_t EventListenerHandler::RegisterEventListener(EventListener &eventListener)
399 {
400     std::unique_lock<std::mutex> lock(operatorMutex_);
401     int32_t registerStatus = CheckEventListenerRegister(eventListener);
402     if (registerStatus == EVENT_LISTENER_SAME) {
403         return TELEPHONY_ERR_CALLBACK_ALREADY_REGISTERED;
404     }
405     if (registerStatus != EVENT_LISTENER_SLOTID_AND_EVENTTYPE_SAME) {
406         NapiTelephonyObserver *telephonyObserver = std::make_unique<NapiTelephonyObserver>().release();
407         if (telephonyObserver == nullptr) {
408             TELEPHONY_LOGE("error by telephonyObserver nullptr");
409             return TELEPHONY_ERR_LOCAL_PTR_NULL;
410         }
411         sptr<TelephonyObserverBroker> observer(telephonyObserver);
412         if (observer == nullptr) {
413             TELEPHONY_LOGE("error by observer nullptr");
414             return TELEPHONY_ERR_LOCAL_PTR_NULL;
415         }
416         int32_t addResult = TelephonyStateManager::AddStateObserver(
417             observer, eventListener.slotId, ToUint32t(eventListener.eventType),
418             eventListener.eventType == TelephonyUpdateEventType::EVENT_CALL_STATE_UPDATE);
419         if (addResult != TELEPHONY_SUCCESS) {
420             TELEPHONY_LOGE("AddStateObserver failed, ret=%{public}d!", addResult);
421             return addResult;
422         }
423     }
424     listenerList_.push_back(eventListener);
425     TELEPHONY_LOGI("EventListenerHandler::RegisterEventListener listenerList_ size=%{public}d",
426         static_cast<int32_t>(listenerList_.size()));
427     return TELEPHONY_SUCCESS;
428 }
429 
SetEventListenerDeleting(std::shared_ptr<bool> isDeleting)430 void EventListenerHandler::SetEventListenerDeleting(std::shared_ptr<bool> isDeleting)
431 {
432     if (isDeleting == nullptr) {
433         TELEPHONY_LOGE("isDeleting is nullptr");
434         return;
435     }
436     *isDeleting = true;
437 }
438 
CheckEventTypeExist(int32_t slotId,TelephonyUpdateEventType eventType)439 bool EventListenerHandler::CheckEventTypeExist(int32_t slotId, TelephonyUpdateEventType eventType)
440 {
441     for (auto &listen : listenerList_) {
442         if (slotId == listen.slotId && eventType == listen.eventType) {
443             return true;
444         }
445     }
446     return false;
447 }
448 
RemoveEventListenerRegister(napi_env env,TelephonyUpdateEventType eventType,napi_ref ref,std::list<EventListener> & removeListenerList,std::set<int32_t> & soltIdSet)449 void EventListenerHandler::RemoveEventListenerRegister(napi_env env, TelephonyUpdateEventType eventType, napi_ref ref,
450     std::list<EventListener> &removeListenerList, std::set<int32_t> &soltIdSet)
451 {
452     std::list<EventListener>::iterator it = listenerList_.begin();
453     while (it != listenerList_.end()) {
454         if (env == it->env && eventType == it->eventType && IsCallBackRegister(env, ref, it->callbackRef)) {
455             SetEventListenerDeleting(it->isDeleting);
456             soltIdSet.insert(it->slotId);
457             removeListenerList.push_back(*it);
458             it = listenerList_.erase(it);
459         } else {
460             ++it;
461         }
462     }
463 }
464 
RemoveEventListenerRegister(napi_env env,TelephonyUpdateEventType eventType,std::list<EventListener> & removeListenerList,std::set<int32_t> & soltIdSet)465 void EventListenerHandler::RemoveEventListenerRegister(napi_env env, TelephonyUpdateEventType eventType,
466     std::list<EventListener> &removeListenerList, std::set<int32_t> &soltIdSet)
467 {
468     std::list<EventListener>::iterator it = listenerList_.begin();
469     while (it != listenerList_.end()) {
470         if (env == it->env && eventType == it->eventType) {
471             SetEventListenerDeleting(it->isDeleting);
472             soltIdSet.insert(it->slotId);
473             removeListenerList.push_back(*it);
474             it = listenerList_.erase(it);
475         } else {
476             ++it;
477         }
478     }
479 }
480 
CheckRemoveStateObserver(TelephonyUpdateEventType eventType,int32_t slotId,int32_t & result)481 void EventListenerHandler::CheckRemoveStateObserver(TelephonyUpdateEventType eventType, int32_t slotId, int32_t &result)
482 {
483     if (!CheckEventTypeExist(slotId, eventType)) {
484         int32_t removeRet = TelephonyStateManager::RemoveStateObserver(slotId, ToUint32t(eventType));
485         if (removeRet != TELEPHONY_SUCCESS) {
486             TELEPHONY_LOGE("EventListenerHandler::RemoveStateObserver slotId %{public}d, eventType %{public}d fail!",
487                 slotId, static_cast<int32_t>(eventType));
488             result = removeRet;
489         }
490     }
491 }
492 
UnregisterEventListener(napi_env env,TelephonyUpdateEventType eventType,napi_ref ref,std::list<EventListener> & removeListenerList)493 int32_t EventListenerHandler::UnregisterEventListener(
494     napi_env env, TelephonyUpdateEventType eventType, napi_ref ref, std::list<EventListener> &removeListenerList)
495 {
496     std::unique_lock<std::mutex> lock(operatorMutex_);
497     if (listenerList_.empty()) {
498         TELEPHONY_LOGI("UnregisterEventListener listener list is empty.");
499         return TELEPHONY_SUCCESS;
500     }
501 
502     std::set<int32_t> soltIdSet;
503     RemoveEventListenerRegister(env, eventType, ref, removeListenerList, soltIdSet);
504     int32_t result = TELEPHONY_SUCCESS;
505     for (int32_t slotId : soltIdSet) {
506         CheckRemoveStateObserver(eventType, slotId, result);
507     }
508     TELEPHONY_LOGI("EventListenerHandler::UnregisterEventListener listenerList_ size=%{public}d",
509         static_cast<int32_t>(listenerList_.size()));
510     return result;
511 }
512 
UnregisterEventListener(napi_env env,TelephonyUpdateEventType eventType,std::list<EventListener> & removeListenerList)513 int32_t EventListenerHandler::UnregisterEventListener(
514     napi_env env, TelephonyUpdateEventType eventType, std::list<EventListener> &removeListenerList)
515 {
516     std::unique_lock<std::mutex> lock(operatorMutex_);
517     if (listenerList_.empty()) {
518         TELEPHONY_LOGI("UnregisterEventListener listener list is empty.");
519         return TELEPHONY_SUCCESS;
520     }
521 
522     std::set<int32_t> soltIdSet;
523     RemoveEventListenerRegister(env, eventType, removeListenerList, soltIdSet);
524     int32_t result = TELEPHONY_SUCCESS;
525     for (int32_t slotId : soltIdSet) {
526         CheckRemoveStateObserver(eventType, slotId, result);
527     }
528     TELEPHONY_LOGI("EventListenerHandler::UnregisterEventListener listenerList_ size=%{public}d",
529         static_cast<int32_t>(listenerList_.size()));
530     return result;
531 }
532 
UnRegisterAllListener(napi_env env)533 void EventListenerHandler::UnRegisterAllListener(napi_env env)
534 {
535     std::unique_lock<std::mutex> lock(operatorMutex_);
536     if (listenerList_.empty()) {
537         TELEPHONY_LOGI("UnRegisterAllListener listener list is empty.");
538         return;
539     }
540     std::map<int32_t, std::set<TelephonyUpdateEventType>> removeTypeMap;
541     listenerList_.remove_if([&](EventListener listener) -> bool {
542         bool matched = listener.env == env;
543         if (matched) {
544             SetEventListenerDeleting(listener.isDeleting);
545             if (!removeTypeMap.count(listener.slotId)) {
546                 std::set<TelephonyUpdateEventType> eventTypeSet;
547                 eventTypeSet.insert(listener.eventType);
548                 removeTypeMap.insert(std::make_pair(listener.slotId, eventTypeSet));
549             } else {
550                 removeTypeMap[listener.slotId].insert(listener.eventType);
551             }
552             if (listener.env != nullptr && listener.callbackRef != nullptr) {
553                 napi_delete_reference(listener.env, listener.callbackRef);
554             }
555         }
556 
557         return matched;
558     });
559 
560     int32_t result = TELEPHONY_SUCCESS;
561     for (auto &elem : removeTypeMap) {
562         for (auto &innerElem : elem.second) {
563             CheckRemoveStateObserver(innerElem, elem.first, result);
564         }
565     }
566     TELEPHONY_LOGI(
567         "UnRegisterAllListener listener list size finish: %{public}d", static_cast<int32_t>(listenerList_.size()));
568 }
569 
IsCallBackRegister(napi_env env,napi_ref ref,napi_ref registeredRef) const570 bool EventListenerHandler::IsCallBackRegister(napi_env env, napi_ref ref, napi_ref registeredRef) const
571 {
572     napi_value callback = nullptr;
573     napi_get_reference_value(env, ref, &callback);
574     napi_value existCallBack = nullptr;
575     napi_get_reference_value(env, registeredRef, &existCallBack);
576     bool result = false;
577     napi_strict_equals(env, callback, existCallBack, &result);
578     return result;
579 }
580 
581 template<typename T, typename D, TelephonyUpdateEventType eventType>
HandleCallbackInfoUpdate(const AppExecFwk::InnerEvent::Pointer & event)582 void EventListenerHandler::HandleCallbackInfoUpdate(const AppExecFwk::InnerEvent::Pointer &event)
583 {
584     if (event == nullptr) {
585         TELEPHONY_LOGE("event nullptr");
586         return;
587     }
588 
589     std::unique_ptr<D> info = event->GetUniqueObject<D>();
590     if (info == nullptr) {
591         TELEPHONY_LOGE("update info nullptr");
592         return;
593     }
594 
595     std::unique_lock<std::mutex> lock(operatorMutex_);
596     for (const EventListener &listen : listenerList_) {
597         if ((listen.eventType == eventType) && (listen.slotId == info->slotId_)) {
598             uv_loop_s *loop = nullptr;
599             if (!InitLoop(listen.env, &loop)) {
600                 TELEPHONY_LOGE("loop is null");
601                 break;
602             }
603             T *context = std::make_unique<T>().release();
604             if (context == nullptr) {
605                 TELEPHONY_LOGE("make context failed");
606                 break;
607             }
608             *(static_cast<EventListener *>(context)) = listen;
609             *context = *info;
610             uv_work_t *work = std::make_unique<uv_work_t>().release();
611             if (work == nullptr) {
612                 TELEPHONY_LOGE("make work failed");
613                 break;
614             }
615             work->data = static_cast<void *>(context);
616             int32_t resultCode =
617                 uv_queue_work_with_qos(loop, work, [](uv_work_t *) {}, WorkUpdated, uv_qos_default);
618             if (resultCode != 0) {
619                 delete context;
620                 context = nullptr;
621                 TELEPHONY_LOGE("HandleCallbackInfoUpdate failed, result: %{public}d", resultCode);
622                 delete work;
623                 work = nullptr;
624                 return;
625             }
626         }
627     }
628 }
629 
630 template<TelephonyUpdateEventType eventType>
HandleCallbackVoidUpdate(const AppExecFwk::InnerEvent::Pointer & event)631 void EventListenerHandler::HandleCallbackVoidUpdate(const AppExecFwk::InnerEvent::Pointer &event)
632 {
633     if (event == nullptr) {
634         TELEPHONY_LOGE("event nullptr");
635         return;
636     }
637 
638     std::unique_lock<std::mutex> lock(operatorMutex_);
639     for (const EventListener &listen : listenerList_) {
640         if ((listen.eventType == eventType)) {
641             uv_loop_s *loop = nullptr;
642             if (!InitLoop(listen.env, &loop)) {
643                 TELEPHONY_LOGE("loop is null");
644                 break;
645             }
646             uv_work_t *work = std::make_unique<uv_work_t>().release();
647             if (work == nullptr) {
648                 TELEPHONY_LOGE("make work failed");
649                 break;
650             }
651             EventListener *listener = new EventListener();
652             listener->env = listen.env;
653             listener->eventType = listen.eventType;
654             listener->slotId = listen.slotId;
655             listener->callbackRef = listen.callbackRef;
656             listener->isDeleting = listen.isDeleting;
657             work->data = static_cast<void *>(listener);
658             int32_t retVal =
659                 uv_queue_work_with_qos(loop, work, [](uv_work_t *) {}, WorkUpdated, uv_qos_default);
660             if (retVal != 0) {
661                 delete listener;
662                 listener = nullptr;
663                 TELEPHONY_LOGE("HandleCallbackVoidUpdate failed, result: %{public}d", retVal);
664                 delete work;
665                 work = nullptr;
666                 return;
667             }
668         }
669     }
670 }
671 
WorkUpdated(uv_work_t * work,int status)672 void EventListenerHandler::WorkUpdated(uv_work_t *work, int status)
673 {
674     std::unique_lock<std::mutex> lock(operatorMutex_);
675     EventListener *listener = static_cast<EventListener *>(work->data);
676     TELEPHONY_LOGD("WorkUpdated eventType is %{public}d", listener->eventType);
677     if (listener->isDeleting == nullptr || *(listener->isDeleting)) {
678         TELEPHONY_LOGI("listener is deleting");
679         delete listener;
680         listener = nullptr;
681         return;
682     }
683     if (workFuncMap_.find(listener->eventType) == workFuncMap_.end() ||
684         workFuncMap_.find(listener->eventType)->second == nullptr) {
685         TELEPHONY_LOGE("listener state update is nullptr");
686         delete listener;
687         listener = nullptr;
688         return;
689     }
690     workFuncMap_.find(listener->eventType)->second(work, lock);
691 }
692 
WorkCallStateUpdated(uv_work_t * work,std::unique_lock<std::mutex> & lock)693 void EventListenerHandler::WorkCallStateUpdated(uv_work_t *work, std::unique_lock<std::mutex> &lock)
694 {
695     std::unique_ptr<CallStateContext> callStateInfo(static_cast<CallStateContext *>(work->data));
696     napi_value callbackValue = nullptr;
697     napi_create_object(callStateInfo->env, &callbackValue);
698     int32_t wrappedCallState = WrapCallState(callStateInfo->callState);
699     std::string number = NapiUtil::ToUtf8(callStateInfo->phoneNumber);
700     SetPropertyToNapiObject(callStateInfo->env, callbackValue, "state", wrappedCallState);
701     SetPropertyToNapiObject(callStateInfo->env, callbackValue, "number", number);
702     NapiReturnToJS(callStateInfo->env, callStateInfo->callbackRef, callbackValue, lock);
703 }
704 
WorkSignalUpdated(uv_work_t * work,std::unique_lock<std::mutex> & lock)705 void EventListenerHandler::WorkSignalUpdated(uv_work_t *work, std::unique_lock<std::mutex> &lock)
706 {
707     std::unique_ptr<SignalListContext> infoListUpdateInfo(static_cast<SignalListContext *>(work->data));
708     napi_value callbackValue = nullptr;
709     const napi_env &env = infoListUpdateInfo->env;
710     napi_create_array(env, &callbackValue);
711     size_t infoSize = infoListUpdateInfo->signalInfoList.size();
712     for (size_t i = 0; i < infoSize; ++i) {
713         sptr<SignalInformation> infoItem = infoListUpdateInfo->signalInfoList[i];
714         napi_value info = nullptr;
715         napi_create_object(env, &info);
716         SetPropertyToNapiObject(env, info, "signalType", WrapNetworkType(infoItem->GetNetworkType()));
717         SetPropertyToNapiObject(env, info, "signalLevel", infoItem->GetSignalLevel());
718         SetPropertyToNapiObject(env, info, "dBm", infoItem->GetSignalIntensity());
719         napi_set_element(env, callbackValue, i, info);
720     }
721     NapiReturnToJS(env, infoListUpdateInfo->callbackRef, callbackValue, lock);
722 }
723 
WorkNetworkStateUpdated(uv_work_t * work,std::unique_lock<std::mutex> & lock)724 void EventListenerHandler::WorkNetworkStateUpdated(uv_work_t *work, std::unique_lock<std::mutex> &lock)
725 {
726     std::unique_ptr<NetworkStateContext> networkStateUpdateInfo(static_cast<NetworkStateContext *>(work->data));
727     napi_value callbackValue = nullptr;
728     const napi_env &env = networkStateUpdateInfo->env;
729     const sptr<NetworkState> &networkState = networkStateUpdateInfo->networkState;
730     napi_create_object(env, &callbackValue);
731     std::string longOperatorName = networkState->GetLongOperatorName();
732     std::string shortOperatorName = networkState->GetShortOperatorName();
733     std::string plmnNumeric = networkState->GetPlmnNumeric();
734     bool isRoaming = networkState->IsRoaming();
735     int32_t regStatus = static_cast<int32_t>(networkState->GetRegStatus());
736     bool isEmergency = networkState->IsEmergency();
737     int32_t cfgTech = static_cast<int32_t>(networkState->GetCfgTech());
738     int32_t nsaState = static_cast<int32_t>(networkState->GetNrState());
739     SetPropertyToNapiObject(env, callbackValue, "longOperatorName", longOperatorName);
740     SetPropertyToNapiObject(env, callbackValue, "shortOperatorName", shortOperatorName);
741     SetPropertyToNapiObject(env, callbackValue, "plmnNumeric", plmnNumeric);
742     SetPropertyToNapiObject(env, callbackValue, "isRoaming", isRoaming);
743     SetPropertyToNapiObject(env, callbackValue, "regState", WrapRegState(regStatus));
744     SetPropertyToNapiObject(env, callbackValue, "isEmergency", isEmergency);
745     SetPropertyToNapiObject(env, callbackValue, "cfgTech", WrapRadioTech(cfgTech));
746     SetPropertyToNapiObject(env, callbackValue, "nsaState", nsaState);
747     SetPropertyToNapiObject(env, callbackValue, "isCaActive", false);
748     NapiReturnToJS(env, networkStateUpdateInfo->callbackRef, callbackValue, lock);
749 }
750 
WorkSimStateUpdated(uv_work_t * work,std::unique_lock<std::mutex> & lock)751 void EventListenerHandler::WorkSimStateUpdated(uv_work_t *work, std::unique_lock<std::mutex> &lock)
752 {
753     std::unique_ptr<SimStateContext> simStateUpdateInfo(static_cast<SimStateContext *>(work->data));
754     napi_value callbackValue = nullptr;
755     int32_t cardType = static_cast<int32_t>(simStateUpdateInfo->cardType);
756     int32_t simState = static_cast<int32_t>(simStateUpdateInfo->simState);
757     int32_t lockReason = static_cast<int32_t>(simStateUpdateInfo->reason);
758     napi_create_object(simStateUpdateInfo->env, &callbackValue);
759     SetPropertyToNapiObject(simStateUpdateInfo->env, callbackValue, "type", cardType);
760     SetPropertyToNapiObject(simStateUpdateInfo->env, callbackValue, "state", simState);
761     SetPropertyToNapiObject(simStateUpdateInfo->env, callbackValue, "reason", lockReason);
762     NapiReturnToJS(simStateUpdateInfo->env, simStateUpdateInfo->callbackRef, callbackValue, lock);
763 }
764 
WorkCellInfomationUpdated(uv_work_t * work,std::unique_lock<std::mutex> & lock)765 void EventListenerHandler::WorkCellInfomationUpdated(uv_work_t *work, std::unique_lock<std::mutex> &lock)
766 {
767     std::unique_ptr<CellInfomationContext> cellInfo(static_cast<CellInfomationContext *>(work->data));
768     napi_value callbackValue = nullptr;
769     napi_create_array(cellInfo->env, &callbackValue);
770     for (size_t i = 0; i < cellInfo->cellInfoVec.size(); i++) {
771         napi_value val = CellInfoConversion(cellInfo->env, *(cellInfo->cellInfoVec[i]));
772         napi_set_element(cellInfo->env, callbackValue, i, val);
773     }
774     NapiReturnToJS(cellInfo->env, cellInfo->callbackRef, callbackValue, lock);
775 }
776 
WorkCellularDataConnectStateUpdated(uv_work_t * work,std::unique_lock<std::mutex> & lock)777 void EventListenerHandler::WorkCellularDataConnectStateUpdated(uv_work_t *work, std::unique_lock<std::mutex> &lock)
778 {
779     std::unique_ptr<CellularDataConnectStateContext> context(
780         static_cast<CellularDataConnectStateContext *>(work->data));
781     napi_value callbackValue = nullptr;
782     napi_create_object(context->env, &callbackValue);
783     SetPropertyToNapiObject(context->env, callbackValue, "state", context->dataState);
784     SetPropertyToNapiObject(context->env, callbackValue, "network", context->networkType);
785     NapiReturnToJS(context->env, context->callbackRef, callbackValue, lock);
786 }
787 
WorkCellularDataFlowUpdated(uv_work_t * work,std::unique_lock<std::mutex> & lock)788 void EventListenerHandler::WorkCellularDataFlowUpdated(uv_work_t *work, std::unique_lock<std::mutex> &lock)
789 {
790     std::unique_ptr<CellularDataFlowContext> dataFlowInfo(static_cast<CellularDataFlowContext *>(work->data));
791     napi_value callbackValue = GetNapiValue(dataFlowInfo->env, dataFlowInfo->flowType_);
792     NapiReturnToJS(dataFlowInfo->env, dataFlowInfo->callbackRef, callbackValue, lock);
793 }
794 
WorkCfuIndicatorUpdated(uv_work_t * work,std::unique_lock<std::mutex> & lock)795 void EventListenerHandler::WorkCfuIndicatorUpdated(uv_work_t *work, std::unique_lock<std::mutex> &lock)
796 {
797     if (work == nullptr) {
798         TELEPHONY_LOGE("work is null");
799         return;
800     }
801     std::unique_ptr<CfuIndicatorContext> cfuIndicatorInfo(static_cast<CfuIndicatorContext *>(work->data));
802     napi_value callbackValue = GetNapiValue(cfuIndicatorInfo->env, cfuIndicatorInfo->cfuResult_);
803     NapiReturnToJS(cfuIndicatorInfo->env, cfuIndicatorInfo->callbackRef, callbackValue, lock);
804 }
805 
WorkVoiceMailMsgIndicatorUpdated(uv_work_t * work,std::unique_lock<std::mutex> & lock)806 void EventListenerHandler::WorkVoiceMailMsgIndicatorUpdated(uv_work_t *work, std::unique_lock<std::mutex> &lock)
807 {
808     if (work == nullptr) {
809         TELEPHONY_LOGE("work is null");
810         return;
811     }
812     std::unique_ptr<VoiceMailMsgIndicatorContext> voiceMailMsgIndicatorInfo(
813         static_cast<VoiceMailMsgIndicatorContext *>(work->data));
814     napi_value callbackValue =
815         GetNapiValue(voiceMailMsgIndicatorInfo->env, voiceMailMsgIndicatorInfo->voiceMailMsgResult_);
816     NapiReturnToJS(voiceMailMsgIndicatorInfo->env, voiceMailMsgIndicatorInfo->callbackRef, callbackValue, lock);
817 }
818 
WorkIccAccountUpdated(uv_work_t * work,std::unique_lock<std::mutex> & lock)819 void EventListenerHandler::WorkIccAccountUpdated(uv_work_t *work, std::unique_lock<std::mutex> &lock)
820 {
821     if (work == nullptr) {
822         TELEPHONY_LOGE("work is null");
823         return;
824     }
825     std::unique_ptr<EventListener> UpdateIccAccount(static_cast<EventListener *>(work->data));
826     napi_value callbackValue = nullptr;
827     napi_create_object(UpdateIccAccount->env, &callbackValue);
828     NapiReturnToJS(UpdateIccAccount->env, UpdateIccAccount->callbackRef, callbackValue, lock);
829 }
830 } // namespace Telephony
831 } // namespace OHOS
832