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