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