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 "call_manager_inner_type.h"
21 #include "event_listener_manager.h"
22 #include "inner_event.h"
23 #include "napi_parameter_util.h"
24 #include "napi_radio_types.h"
25 #include "napi_sim_type.h"
26 #include "napi_state_registry.h"
27 #include "napi_telephony_observer.h"
28 #include "napi_util.h"
29 #include "singleton.h"
30 #include "telephony_errors.h"
31 #include "telephony_log_wrapper.h"
32 #include "telephony_state_manager.h"
33 #include "update_contexts.h"
34
35 namespace OHOS {
36 namespace Telephony {
37 namespace {
WrapRegState(int32_t nativeState)38 int32_t WrapRegState(int32_t nativeState)
39 {
40 RegServiceState state = static_cast<RegServiceState>(nativeState);
41 switch (state) {
42 case RegServiceState::REG_STATE_NO_SERVICE:
43 case RegServiceState::REG_STATE_SEARCH: {
44 return RegStatus::REGISTRATION_STATE_NO_SERVICE;
45 }
46 case RegServiceState::REG_STATE_IN_SERVICE: {
47 return RegStatus::REGISTRATION_STATE_IN_SERVICE;
48 }
49 case RegServiceState::REG_STATE_EMERGENCY_ONLY: {
50 return RegStatus::REGISTRATION_STATE_EMERGENCY_CALL_ONLY;
51 }
52 case RegServiceState::REG_STATE_UNKNOWN: {
53 return RegStatus::REGISTRATION_STATE_POWER_OFF;
54 }
55 default:
56 return RegStatus::REGISTRATION_STATE_POWER_OFF;
57 }
58 }
59
WrapCallState(int32_t callState)60 int32_t WrapCallState(int32_t callState)
61 {
62 switch (callState) {
63 case (int32_t)Telephony::TelCallState::CALL_STATUS_ACTIVE:
64 case (int32_t)Telephony::TelCallState::CALL_STATUS_HOLDING:
65 case (int32_t)Telephony::TelCallState::CALL_STATUS_DIALING:
66 case (int32_t)Telephony::TelCallState::CALL_STATUS_ALERTING:
67 case (int32_t)Telephony::TelCallState::CALL_STATUS_DISCONNECTING:
68 return static_cast<int32_t>(CallState::CALL_STATE_OFFHOOK);
69 case (int32_t)Telephony::TelCallState::CALL_STATUS_WAITING:
70 case (int32_t)Telephony::TelCallState::CALL_STATUS_INCOMING:
71 return static_cast<int32_t>(CallState::CALL_STATE_RINGING);
72 case (int32_t)Telephony::TelCallState::CALL_STATUS_DISCONNECTED:
73 case (int32_t)Telephony::TelCallState::CALL_STATUS_IDLE:
74 return static_cast<int32_t>(CallState::CALL_STATE_IDLE);
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)144 napi_status NapiReturnToJS(napi_env env, napi_ref callbackRef, napi_value callbackVal)
145 {
146 if (callbackRef == nullptr) {
147 TELEPHONY_LOGE("NapiReturnToJS callbackRef is nullptr");
148 return napi_ok;
149 }
150 napi_value callbackFunc = nullptr;
151 napi_get_reference_value(env, callbackRef, &callbackFunc);
152 napi_value callbackValues[] = { callbackVal };
153 napi_value recv = nullptr;
154 napi_get_undefined(env, &recv);
155 napi_value callbackResult = nullptr;
156 napi_status status =
157 napi_call_function(env, recv, callbackFunc, std::size(callbackValues), callbackValues, &callbackResult);
158 if (status != napi_ok) {
159 TELEPHONY_LOGE("NapiReturnToJS napi_call_function return error : %{public}d", status);
160 }
161 return status;
162 }
163
SignalInfoConversion(napi_env env,int32_t type,int32_t level)164 napi_value SignalInfoConversion(napi_env env, int32_t type, int32_t level)
165 {
166 napi_value val = nullptr;
167 napi_create_object(env, &val);
168 SetPropertyToNapiObject(env, val, "signalType", type);
169 SetPropertyToNapiObject(env, val, "signalLevel", level);
170 return val;
171 }
172
DataOfNetworkConversion(napi_env env,const GsmCellInformation & info)173 napi_value DataOfNetworkConversion(napi_env env, const GsmCellInformation &info)
174 {
175 napi_value val = nullptr;
176 napi_create_object(env, &val);
177 SetPropertyToNapiObject(env, val, "lac", info.GetLac());
178 SetPropertyToNapiObject(env, val, "cellId", info.GetCellId());
179 SetPropertyToNapiObject(env, val, "arfcn", info.GetArfcn());
180 SetPropertyToNapiObject(env, val, "basic", info.GetBsic());
181 SetPropertyToNapiObject(env, val, "mcc", info.GetMcc());
182 SetPropertyToNapiObject(env, val, "mnc", info.GetMnc());
183 return val;
184 }
185
DataOfNetworkConversion(napi_env env,const LteCellInformation & info)186 napi_value DataOfNetworkConversion(napi_env env, const LteCellInformation &info)
187 {
188 napi_value val = nullptr;
189 napi_create_object(env, &val);
190 SetPropertyToNapiObject(env, val, "cgi", 0);
191 SetPropertyToNapiObject(env, val, "pci", info.GetPci());
192 SetPropertyToNapiObject(env, val, "tac", info.GetTac());
193 SetPropertyToNapiObject(env, val, "earfcn", info.GetArfcn());
194 SetPropertyToNapiObject(env, val, "bandwith", 0);
195 SetPropertyToNapiObject(env, val, "mcc", info.GetMnc());
196 SetPropertyToNapiObject(env, val, "mnc", info.GetMnc());
197 SetPropertyToNapiObject(env, val, "isSupportEndc", false);
198 return val;
199 }
200
DataOfNetworkConversion(napi_env env,const WcdmaCellInformation & info)201 napi_value DataOfNetworkConversion(napi_env env, const WcdmaCellInformation &info)
202 {
203 napi_value val = nullptr;
204 napi_create_object(env, &val);
205 SetPropertyToNapiObject(env, val, "lac", info.GetLac());
206 SetPropertyToNapiObject(env, val, "cellId", info.GetCellId());
207 SetPropertyToNapiObject(env, val, "psc", info.GetPsc());
208 SetPropertyToNapiObject(env, val, "uarfcn", info.GetArfcn());
209 SetPropertyToNapiObject(env, val, "mcc", info.GetMcc());
210 SetPropertyToNapiObject(env, val, "mnc", info.GetMnc());
211 return val;
212 }
213
CellInfoConversion(napi_env env,const CellInformation & info)214 napi_value CellInfoConversion(napi_env env, const CellInformation &info)
215 {
216 napi_value val = nullptr;
217 napi_create_object(env, &val);
218 CellInformation::CellType networkType = info.GetNetworkType();
219 SetPropertyToNapiObject(env, val, "networkType", static_cast<int32_t>(networkType));
220 SetPropertyToNapiObject(env, val, "isCamped", info.GetIsCamped());
221 SetPropertyToNapiObject(env, val, "timeStamp", static_cast<int64_t>(info.GetTimeStamp()));
222 SetPropertyToNapiObject(env, val, "signalInfomation",
223 SignalInfoConversion(env, static_cast<int32_t>(networkType), info.GetSignalLevel()));
224
225 switch (networkType) {
226 case CellInformation::CellType::CELL_TYPE_GSM:
227 napi_set_named_property(
228 env, val, "data", DataOfNetworkConversion(env, static_cast<const GsmCellInformation &>(info)));
229 break;
230 case CellInformation::CellType::CELL_TYPE_LTE:
231 napi_set_named_property(
232 env, val, "data", DataOfNetworkConversion(env, static_cast<const LteCellInformation &>(info)));
233 break;
234 case CellInformation::CellType::CELL_TYPE_WCDMA:
235 napi_set_named_property(
236 env, val, "data", DataOfNetworkConversion(env, static_cast<const WcdmaCellInformation &>(info)));
237 break;
238 default:
239 break;
240 }
241 return val;
242 }
243
InitLoop(napi_env env,uv_loop_s ** loop)244 bool InitLoop(napi_env env, uv_loop_s **loop)
245 {
246 #if NAPI_VERSION >= 2
247 napi_status status = napi_get_uv_event_loop(env, loop);
248 if (status != napi_ok) {
249 TELEPHONY_LOGE("napi_get_uv_event_loop napi_status = %{public}d", status);
250 return false;
251 }
252 #endif // NAPI_VERSION >= 2
253 return *loop != nullptr;
254 }
255 } // namespace
256
257 std::map<TelephonyUpdateEventType, void (*)(uv_work_t *work)> EventListenerHandler::workFuncMap_;
258 std::mutex EventListenerHandler::operatorMutex_;
259
EventListenerHandler()260 EventListenerHandler::EventListenerHandler() : AppExecFwk::EventHandler(AppExecFwk::EventRunner::Create())
261 {
262 handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_CALL_STATE_UPDATE] =
263 &EventListenerHandler::HandleCallbackInfoUpdate<CallStateContext, CallStateUpdateInfo,
264 TelephonyUpdateEventType::EVENT_CALL_STATE_UPDATE>;
265 handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_SIGNAL_INFO_UPDATE] =
266 &EventListenerHandler::HandleCallbackInfoUpdate<SignalListContext, SignalUpdateInfo,
267 TelephonyUpdateEventType::EVENT_SIGNAL_STRENGTHS_UPDATE>;
268 handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_NETWORK_STATE_UPDATE] =
269 &EventListenerHandler::HandleCallbackInfoUpdate<NetworkStateContext, NetworkStateUpdateInfo,
270 TelephonyUpdateEventType::EVENT_NETWORK_STATE_UPDATE>;
271 handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_SIM_STATE_UPDATE] =
272 &EventListenerHandler::HandleCallbackInfoUpdate<SimStateContext, SimStateUpdateInfo,
273 TelephonyUpdateEventType::EVENT_SIM_STATE_UPDATE>;
274 handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_CELL_INFOMATION_UPDATE] =
275 &EventListenerHandler::HandleCallbackInfoUpdate<CellInfomationContext, CellInfomationUpdate,
276 TelephonyUpdateEventType::EVENT_CELL_INFO_UPDATE>;
277 handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_CELLULAR_DATA_CONNECTION_UPDATE] =
278 &EventListenerHandler::HandleCallbackInfoUpdate<CellularDataConnectStateContext, CellularDataConnectState,
279 TelephonyUpdateEventType::EVENT_DATA_CONNECTION_UPDATE>;
280 handleFuncMap_[TelephonyCallbackEventId::EVENT_ON_CELLULAR_DATA_FLOW_UPDATE] =
281 &EventListenerHandler::HandleCallbackInfoUpdate<CellularDataFlowContext, CellularDataFlowUpdate,
282 TelephonyUpdateEventType::EVENT_CELLULAR_DATA_FLOW_UPDATE>;
283
284 workFuncMap_[TelephonyUpdateEventType::EVENT_CALL_STATE_UPDATE] = &EventListenerHandler::WorkCallStateUpdated;
285 workFuncMap_[TelephonyUpdateEventType::EVENT_SIGNAL_STRENGTHS_UPDATE] = &EventListenerHandler::WorkSignalUpdated;
286 workFuncMap_[TelephonyUpdateEventType::EVENT_NETWORK_STATE_UPDATE] = &EventListenerHandler::WorkNetworkStateUpdated;
287 workFuncMap_[TelephonyUpdateEventType::EVENT_SIM_STATE_UPDATE] = &EventListenerHandler::WorkSimStateUpdated;
288 workFuncMap_[TelephonyUpdateEventType::EVENT_CELL_INFO_UPDATE] = &EventListenerHandler::WorkCellInfomationUpdated;
289 workFuncMap_[TelephonyUpdateEventType::EVENT_DATA_CONNECTION_UPDATE] =
290 &EventListenerHandler::WorkCellularDataConnectStateUpdate;
291 workFuncMap_[TelephonyUpdateEventType::EVENT_CELLULAR_DATA_FLOW_UPDATE] =
292 &EventListenerHandler::WorkCellularDataFlowUpdate;
293 }
294
~EventListenerHandler()295 EventListenerHandler::~EventListenerHandler()
296 {
297 handleFuncMap_.clear();
298 workFuncMap_.clear();
299 listenerList_.clear();
300 }
301
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)302 void EventListenerHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
303 {
304 if (event == nullptr) {
305 TELEPHONY_LOGE("EventListenerHandler::ProcessEvent event is nullptr");
306 return;
307 }
308 auto itor = handleFuncMap_.find(static_cast<TelephonyCallbackEventId>(event->GetInnerEventId()));
309 if (itor != handleFuncMap_.end()) {
310 (this->*(itor->second))(event);
311 }
312 }
313
CheckEventListenerRegister(EventListener & eventListener)314 int32_t EventListenerHandler::CheckEventListenerRegister(EventListener &eventListener)
315 {
316 int32_t flag = EVENT_LISTENER_DIFF;
317 for (auto &listen : listenerList_) {
318 if (eventListener.env == listen.env && eventListener.slotId == listen.slotId &&
319 eventListener.eventType == listen.eventType &&
320 IsCallBackRegister(eventListener.env, eventListener.callbackRef, listen.callbackRef)) {
321 flag = EVENT_LISTENER_SAME;
322 return flag;
323 }
324 if (eventListener.slotId == listen.slotId && eventListener.eventType == listen.eventType) {
325 flag = EVENT_LISTENER_SLOTID_AND_EVENTTYPE_SAME;
326 }
327 }
328 return flag;
329 }
330
RegisterEventListener(EventListener & eventListener)331 int32_t EventListenerHandler::RegisterEventListener(EventListener &eventListener)
332 {
333 std::lock_guard<std::mutex> lockGuard(operatorMutex_);
334 int32_t registerStatus = CheckEventListenerRegister(eventListener);
335 if (registerStatus == EVENT_LISTENER_SAME) {
336 return TELEPHONY_SUCCESS;
337 }
338 if (registerStatus != EVENT_LISTENER_SLOTID_AND_EVENTTYPE_SAME) {
339 NapiTelephonyObserver *telephonyObserver = std::make_unique<NapiTelephonyObserver>().release();
340 if (telephonyObserver == nullptr) {
341 TELEPHONY_LOGE("error by telephonyObserver nullptr");
342 return TELEPHONY_ERR_LOCAL_PTR_NULL;
343 }
344 sptr<TelephonyObserverBroker> observer(telephonyObserver);
345 if (observer == nullptr) {
346 TELEPHONY_LOGE("error by observer nullptr");
347 return TELEPHONY_ERR_LOCAL_PTR_NULL;
348 }
349 int32_t addResult = TelephonyStateManager::AddStateObserver(
350 observer, eventListener.slotId, ToUint32t(eventListener.eventType), false);
351 if (addResult != TELEPHONY_SUCCESS) {
352 TELEPHONY_LOGE("AddStateObserver failed, ret=%{public}d!", addResult);
353 return addResult;
354 }
355 }
356 listenerList_.push_back(eventListener);
357 TELEPHONY_LOGI("EventListenerHandler::RegisterEventListener listenerList_ size=%{public}d",
358 static_cast<int32_t>(listenerList_.size()));
359 return TELEPHONY_SUCCESS;
360 }
361
SetEventListenerDeleting(std::shared_ptr<bool> isDeleting)362 void EventListenerHandler::SetEventListenerDeleting(std::shared_ptr<bool> isDeleting)
363 {
364 if (isDeleting == nullptr) {
365 TELEPHONY_LOGE("isDeleting is nullptr");
366 return;
367 }
368 *isDeleting = true;
369 }
370
CheckEventTypeExist(int32_t slotId,TelephonyUpdateEventType eventType)371 bool EventListenerHandler::CheckEventTypeExist(int32_t slotId, TelephonyUpdateEventType eventType)
372 {
373 for (auto &listen : listenerList_) {
374 if (slotId == listen.slotId && eventType == listen.eventType) {
375 return true;
376 }
377 }
378 return false;
379 }
380
RemoveEventListenerRegister(napi_env env,TelephonyUpdateEventType eventType,napi_ref ref,std::list<EventListener> & removeListenerList,std::set<int32_t> & soltIdSet)381 void EventListenerHandler::RemoveEventListenerRegister(napi_env env, TelephonyUpdateEventType eventType, napi_ref ref,
382 std::list<EventListener> &removeListenerList, std::set<int32_t> &soltIdSet)
383 {
384 std::list<EventListener>::iterator it = listenerList_.begin();
385 while (it != listenerList_.end()) {
386 if (env == it->env && eventType == it->eventType && IsCallBackRegister(env, ref, it->callbackRef)) {
387 SetEventListenerDeleting(it->isDeleting);
388 soltIdSet.insert(it->slotId);
389 removeListenerList.push_back(*it);
390 it = listenerList_.erase(it);
391 } else {
392 ++it;
393 }
394 }
395 }
396
RemoveEventListenerRegister(napi_env env,TelephonyUpdateEventType eventType,std::list<EventListener> & removeListenerList,std::set<int32_t> & soltIdSet)397 void EventListenerHandler::RemoveEventListenerRegister(napi_env env, TelephonyUpdateEventType eventType,
398 std::list<EventListener> &removeListenerList, std::set<int32_t> &soltIdSet)
399 {
400 std::list<EventListener>::iterator it = listenerList_.begin();
401 while (it != listenerList_.end()) {
402 if (env == it->env && eventType == it->eventType) {
403 SetEventListenerDeleting(it->isDeleting);
404 soltIdSet.insert(it->slotId);
405 removeListenerList.push_back(*it);
406 it = listenerList_.erase(it);
407 } else {
408 ++it;
409 }
410 }
411 }
412
CheckRemoveStateObserver(TelephonyUpdateEventType eventType,int32_t slotId,int32_t & result)413 void EventListenerHandler::CheckRemoveStateObserver(TelephonyUpdateEventType eventType, int32_t slotId, int32_t &result)
414 {
415 if (!CheckEventTypeExist(slotId, eventType)) {
416 int32_t removeRet = TelephonyStateManager::RemoveStateObserver(slotId, ToUint32t(eventType));
417 if (removeRet != TELEPHONY_SUCCESS) {
418 TELEPHONY_LOGE("EventListenerHandler::RemoveStateObserver slotId %{public}d, eventType %{public}d fail!",
419 slotId, static_cast<int32_t>(eventType));
420 result = removeRet;
421 }
422 }
423 }
424
UnregisterEventListener(napi_env env,TelephonyUpdateEventType eventType,napi_ref ref,std::list<EventListener> & removeListenerList)425 int32_t EventListenerHandler::UnregisterEventListener(
426 napi_env env, TelephonyUpdateEventType eventType, napi_ref ref, std::list<EventListener> &removeListenerList)
427 {
428 std::lock_guard<std::mutex> lockGuard(operatorMutex_);
429 if (listenerList_.empty()) {
430 TELEPHONY_LOGI("UnregisterEventListener listener list is empty.");
431 return TELEPHONY_SUCCESS;
432 }
433
434 std::set<int32_t> soltIdSet;
435 RemoveEventListenerRegister(env, eventType, ref, removeListenerList, soltIdSet);
436 int32_t result = TELEPHONY_SUCCESS;
437 for (int32_t slotId : soltIdSet) {
438 CheckRemoveStateObserver(eventType, slotId, result);
439 }
440 TELEPHONY_LOGI("EventListenerHandler::UnregisterEventListener listenerList_ size=%{public}d",
441 static_cast<int32_t>(listenerList_.size()));
442 return result;
443 }
444
UnregisterEventListener(napi_env env,TelephonyUpdateEventType eventType,std::list<EventListener> & removeListenerList)445 int32_t EventListenerHandler::UnregisterEventListener(
446 napi_env env, TelephonyUpdateEventType eventType, std::list<EventListener> &removeListenerList)
447 {
448 std::lock_guard<std::mutex> lockGuard(operatorMutex_);
449 if (listenerList_.empty()) {
450 TELEPHONY_LOGI("UnregisterEventListener listener list is empty.");
451 return TELEPHONY_SUCCESS;
452 }
453
454 std::set<int32_t> soltIdSet;
455 RemoveEventListenerRegister(env, eventType, removeListenerList, soltIdSet);
456 int32_t result = TELEPHONY_SUCCESS;
457 for (int32_t slotId : soltIdSet) {
458 CheckRemoveStateObserver(eventType, slotId, result);
459 }
460 TELEPHONY_LOGI("EventListenerHandler::UnregisterEventListener listenerList_ size=%{public}d",
461 static_cast<int32_t>(listenerList_.size()));
462 return result;
463 }
464
UnRegisterAllListener(napi_env env)465 void EventListenerHandler::UnRegisterAllListener(napi_env env)
466 {
467 std::lock_guard<std::mutex> lockGuard(operatorMutex_);
468 if (listenerList_.empty()) {
469 TELEPHONY_LOGI("UnRegisterAllListener listener list is empty.");
470 return;
471 }
472 std::map<int32_t, std::set<TelephonyUpdateEventType>> removeTypeMap;
473 listenerList_.remove_if([&](EventListener listener) -> bool {
474 bool matched = listener.env == env;
475 if (matched) {
476 SetEventListenerDeleting(listener.isDeleting);
477 if (!removeTypeMap.count(listener.slotId)) {
478 std::set<TelephonyUpdateEventType> eventTypeSet;
479 eventTypeSet.insert(listener.eventType);
480 removeTypeMap.insert(std::make_pair(listener.slotId, eventTypeSet));
481 } else {
482 removeTypeMap[listener.slotId].insert(listener.eventType);
483 }
484 if (listener.env != nullptr && listener.callbackRef != nullptr) {
485 napi_delete_reference(listener.env, listener.callbackRef);
486 }
487 }
488
489 return matched;
490 });
491
492 int32_t result = TELEPHONY_SUCCESS;
493 for (auto &elem : removeTypeMap) {
494 for (auto &innerElem : elem.second) {
495 CheckRemoveStateObserver(innerElem, elem.first, result);
496 }
497 }
498 TELEPHONY_LOGI(
499 "UnRegisterAllListener listener list size finish: %{public}d", static_cast<int32_t>(listenerList_.size()));
500 }
501
IsCallBackRegister(napi_env env,napi_ref ref,napi_ref registeredRef) const502 bool EventListenerHandler::IsCallBackRegister(napi_env env, napi_ref ref, napi_ref registeredRef) const
503 {
504 napi_value callback = nullptr;
505 napi_get_reference_value(env, ref, &callback);
506 napi_value existCallBack = nullptr;
507 napi_get_reference_value(env, registeredRef, &existCallBack);
508 bool result = false;
509 napi_strict_equals(env, callback, existCallBack, &result);
510 return result;
511 }
512
513 template<typename T, typename D, TelephonyUpdateEventType eventType>
HandleCallbackInfoUpdate(const AppExecFwk::InnerEvent::Pointer & event)514 void EventListenerHandler::HandleCallbackInfoUpdate(const AppExecFwk::InnerEvent::Pointer &event)
515 {
516 if (event == nullptr) {
517 TELEPHONY_LOGE("event nullptr");
518 return;
519 }
520
521 std::unique_ptr<D> info = event->GetUniqueObject<D>();
522 if (info == nullptr) {
523 TELEPHONY_LOGE("update info nullptr");
524 return;
525 }
526
527 std::lock_guard<std::mutex> lockGuard(operatorMutex_);
528 for (const EventListener &listen : listenerList_) {
529 if ((listen.eventType == eventType) && (listen.slotId == info->slotId_)) {
530 uv_loop_s *loop = nullptr;
531 if (!InitLoop(listen.env, &loop)) {
532 TELEPHONY_LOGE("loop is null");
533 break;
534 }
535 T *context = std::make_unique<T>().release();
536 if (context == nullptr) {
537 TELEPHONY_LOGE("make context failed");
538 break;
539 }
540 *(static_cast<EventListener *>(context)) = listen;
541 *context = *info;
542 uv_work_t *work = std::make_unique<uv_work_t>().release();
543 if (work == nullptr) {
544 TELEPHONY_LOGE("make work failed");
545 break;
546 }
547 work->data = static_cast<void *>(context);
548 uv_queue_work(
549 loop, work, [](uv_work_t *) {}, WorkUpdated);
550 }
551 }
552 }
553
WorkUpdated(uv_work_t * work,int status)554 void EventListenerHandler::WorkUpdated(uv_work_t *work, int status)
555 {
556 if (work == nullptr || work->data == nullptr) {
557 TELEPHONY_LOGE("work is null");
558 return;
559 }
560 std::lock_guard<std::mutex> lockGuard(operatorMutex_);
561 EventListener *listener = static_cast<EventListener *>(work->data);
562 TELEPHONY_LOGI("WorkUpdated eventType is %{public}d", listener->eventType);
563 if (listener->isDeleting == nullptr || *(listener->isDeleting)) {
564 TELEPHONY_LOGI("listener is deleting");
565 return;
566 }
567 if (workFuncMap_.find(listener->eventType) == workFuncMap_.end() ||
568 workFuncMap_.find(listener->eventType)->second == nullptr) {
569 TELEPHONY_LOGE("listener state update is nullptr");
570 return;
571 }
572 workFuncMap_.find(listener->eventType)->second(work);
573 }
574
WorkCallStateUpdated(uv_work_t * work)575 void EventListenerHandler::WorkCallStateUpdated(uv_work_t *work)
576 {
577 std::unique_ptr<CallStateContext> callStateInfo(static_cast<CallStateContext *>(work->data));
578 napi_value callbackValue = nullptr;
579 napi_create_object(callStateInfo->env, &callbackValue);
580 int32_t wrappedCallState = WrapCallState(callStateInfo->callState);
581 std::string number = NapiUtil::ToUtf8(callStateInfo->phoneNumber);
582 SetPropertyToNapiObject(callStateInfo->env, callbackValue, "state", wrappedCallState);
583 SetPropertyToNapiObject(callStateInfo->env, callbackValue, "number", number);
584 NapiReturnToJS(callStateInfo->env, callStateInfo->callbackRef, callbackValue);
585 }
586
WorkSignalUpdated(uv_work_t * work)587 void EventListenerHandler::WorkSignalUpdated(uv_work_t *work)
588 {
589 std::unique_ptr<SignalListContext> infoListUpdateInfo(static_cast<SignalListContext *>(work->data));
590 napi_value callbackValue = nullptr;
591 const napi_env &env = infoListUpdateInfo->env;
592 napi_create_array(env, &callbackValue);
593 size_t infoSize = infoListUpdateInfo->signalInfoList.size();
594 for (size_t i = 0; i < infoSize; ++i) {
595 sptr<SignalInformation> infoItem = infoListUpdateInfo->signalInfoList[i];
596 napi_value info = nullptr;
597 napi_create_object(env, &info);
598 SetPropertyToNapiObject(env, info, "signalType", WrapNetworkType(infoItem->GetNetworkType()));
599 SetPropertyToNapiObject(env, info, "signalLevel", infoItem->GetSignalLevel());
600 napi_set_element(env, callbackValue, i, info);
601 }
602 NapiReturnToJS(env, infoListUpdateInfo->callbackRef, callbackValue);
603 }
604
WorkNetworkStateUpdated(uv_work_t * work)605 void EventListenerHandler::WorkNetworkStateUpdated(uv_work_t *work)
606 {
607 std::unique_ptr<NetworkStateContext> networkStateUpdateInfo(static_cast<NetworkStateContext *>(work->data));
608 napi_value callbackValue = nullptr;
609 const napi_env &env = networkStateUpdateInfo->env;
610 const sptr<NetworkState> &networkState = networkStateUpdateInfo->networkState;
611 napi_create_object(env, &callbackValue);
612 std::string longOperatorName = networkState->GetLongOperatorName();
613 std::string shortOperatorName = networkState->GetShortOperatorName();
614 std::string plmnNumeric = networkState->GetPlmnNumeric();
615 bool isRoaming = networkState->IsRoaming();
616 int32_t regStatus = static_cast<int32_t>(networkState->GetRegStatus());
617 bool isEmergency = networkState->IsEmergency();
618 int32_t cfgTech = static_cast<int32_t>(networkState->GetCfgTech());
619 int32_t nsaState = static_cast<int32_t>(networkState->GetNrState());
620 SetPropertyToNapiObject(env, callbackValue, "longOperatorName", longOperatorName);
621 SetPropertyToNapiObject(env, callbackValue, "shortOperatorName", shortOperatorName);
622 SetPropertyToNapiObject(env, callbackValue, "plmnNumeric", plmnNumeric);
623 SetPropertyToNapiObject(env, callbackValue, "isRoaming", isRoaming);
624 SetPropertyToNapiObject(env, callbackValue, "regState", WrapRegState(regStatus));
625 SetPropertyToNapiObject(env, callbackValue, "isEmergency", isEmergency);
626 SetPropertyToNapiObject(env, callbackValue, "cfgTech", WrapRadioTech(cfgTech));
627 SetPropertyToNapiObject(env, callbackValue, "nsaState", nsaState);
628 SetPropertyToNapiObject(env, callbackValue, "isCaActive", false);
629 NapiReturnToJS(env, networkStateUpdateInfo->callbackRef, callbackValue);
630 }
631
WorkSimStateUpdated(uv_work_t * work)632 void EventListenerHandler::WorkSimStateUpdated(uv_work_t *work)
633 {
634 std::unique_ptr<SimStateContext> simStateUpdateInfo(static_cast<SimStateContext *>(work->data));
635 napi_value callbackValue = nullptr;
636 int32_t cardType = static_cast<int32_t>(simStateUpdateInfo->cardType);
637 int32_t simState = static_cast<int32_t>(simStateUpdateInfo->simState);
638 int32_t lockReason = static_cast<int32_t>(simStateUpdateInfo->reason);
639 napi_create_object(simStateUpdateInfo->env, &callbackValue);
640 SetPropertyToNapiObject(simStateUpdateInfo->env, callbackValue, "type", cardType);
641 SetPropertyToNapiObject(simStateUpdateInfo->env, callbackValue, "state", simState);
642 SetPropertyToNapiObject(simStateUpdateInfo->env, callbackValue, "reason", lockReason);
643 NapiReturnToJS(simStateUpdateInfo->env, simStateUpdateInfo->callbackRef, callbackValue);
644 }
645
WorkCellInfomationUpdated(uv_work_t * work)646 void EventListenerHandler::WorkCellInfomationUpdated(uv_work_t *work)
647 {
648 std::unique_ptr<CellInfomationContext> cellInfo(static_cast<CellInfomationContext *>(work->data));
649 napi_value callbackValue = nullptr;
650 napi_create_array(cellInfo->env, &callbackValue);
651 for (size_t i = 0; i < cellInfo->cellInfoVec.size(); i++) {
652 napi_value val = CellInfoConversion(cellInfo->env, *(cellInfo->cellInfoVec[i]));
653 napi_set_element(cellInfo->env, callbackValue, i, val);
654 }
655 NapiReturnToJS(cellInfo->env, cellInfo->callbackRef, callbackValue);
656 }
657
WorkCellularDataConnectStateUpdate(uv_work_t * work)658 void EventListenerHandler::WorkCellularDataConnectStateUpdate(uv_work_t *work)
659 {
660 std::unique_ptr<CellularDataConnectStateContext> context(
661 static_cast<CellularDataConnectStateContext *>(work->data));
662 napi_value callbackValue = nullptr;
663 napi_create_object(context->env, &callbackValue);
664 SetPropertyToNapiObject(context->env, callbackValue, "state", context->dataState);
665 SetPropertyToNapiObject(context->env, callbackValue, "network", context->networkType);
666 NapiReturnToJS(context->env, context->callbackRef, callbackValue);
667 }
668
WorkCellularDataFlowUpdate(uv_work_t * work)669 void EventListenerHandler::WorkCellularDataFlowUpdate(uv_work_t *work)
670 {
671 std::unique_ptr<CellularDataFlowContext> dataFlowInfo(static_cast<CellularDataFlowContext *>(work->data));
672 napi_value callbackValue = GetNapiValue(dataFlowInfo->env, dataFlowInfo->flowType_);
673 NapiReturnToJS(dataFlowInfo->env, dataFlowInfo->callbackRef, callbackValue);
674 }
675 } // namespace Telephony
676 } // namespace OHOS
677