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