• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-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 #include "napi_ims_reg_info_callback_manager.h"
16 
17 #include "core_service_client.h"
18 #include "napi_util.h"
19 #include "singleton.h"
20 #include "telephony_errors.h"
21 #include "telephony_log_wrapper.h"
22 
23 namespace OHOS {
24 namespace Telephony {
RegisterImsRegStateCallback(ImsRegStateCallback & stateCallback)25 int32_t NapiImsRegInfoCallbackManager::RegisterImsRegStateCallback(ImsRegStateCallback &stateCallback)
26 {
27     int32_t slotId = stateCallback.slotId;
28     ImsServiceType imsSrvType = stateCallback.imsSrvType;
29     stateCallback.imsCallback = new NapiImsRegInfoCallback();
30     if (stateCallback.imsCallback == nullptr) {
31         TELEPHONY_LOGE("[slot%{public}d] Creat ImsRegInfoCallback failed, type %{public}d,", slotId, imsSrvType);
32         return TELEPHONY_ERR_REGISTER_CALLBACK_FAIL;
33     }
34     if (InsertImsRegCallback(slotId, imsSrvType, stateCallback) != TELEPHONY_SUCCESS) {
35         TELEPHONY_LOGI("[slot%{public}d] Ignore register action, since callback is existent, type %{public}d", slotId,
36             imsSrvType);
37         return TELEPHONY_SUCCESS;
38     }
39     int32_t ret = DelayedRefSingleton<CoreServiceClient>::GetInstance().RegisterImsRegInfoCallback(
40         slotId, imsSrvType, stateCallback.imsCallback);
41     if (ret == TELEPHONY_SUCCESS) {
42         TELEPHONY_LOGI(
43             "[slot%{public}d] Register imsRegState callback successfully, type %{public}d", slotId, imsSrvType);
44     } else {
45         if (stateCallback.imsCallback != nullptr) {
46             stateCallback.imsCallback = nullptr;
47         }
48         RemoveImsRegCallback(slotId, imsSrvType);
49         TELEPHONY_LOGE("[slot%{public}d] Register imsRegState callback failed, type %{public}d, ret %{public}d", slotId,
50             imsSrvType, ret);
51     }
52     return ret;
53 }
54 
UnregisterImsRegStateCallback(napi_env env,int32_t slotId,ImsServiceType imsSrvType)55 int32_t NapiImsRegInfoCallbackManager::UnregisterImsRegStateCallback(
56     napi_env env, int32_t slotId, ImsServiceType imsSrvType)
57 {
58     int32_t ret = TELEPHONY_SUCCESS;
59     RemoveImsRegCallback(slotId, imsSrvType);
60     ret = DelayedRefSingleton<CoreServiceClient>::GetInstance().UnregisterImsRegInfoCallback(slotId, imsSrvType);
61     TELEPHONY_LOGI(
62         "[slot%{public}d] Unregister imsRegState callback successfully, type %{public}d", slotId, imsSrvType);
63     return ret;
64 }
65 
InsertImsRegCallback(int32_t slotId,ImsServiceType imsSrvType,ImsRegStateCallback & stateCallback)66 int32_t NapiImsRegInfoCallbackManager::InsertImsRegCallback(
67     int32_t slotId, ImsServiceType imsSrvType, ImsRegStateCallback &stateCallback)
68 {
69     std::lock_guard<std::mutex> lock(mutex_);
70     for (auto iter : listImsRegStateCallback_) {
71         if ((iter.slotId == slotId) && (iter.imsSrvType == imsSrvType)) {
72             TELEPHONY_LOGD("[slot%{public}d] callback is existent", slotId);
73             return TELEPHONY_ERROR;
74         }
75     }
76     listImsRegStateCallback_.push_back(stateCallback);
77     return TELEPHONY_SUCCESS;
78 }
79 
RemoveImsRegCallback(int32_t slotId,ImsServiceType imsSrvType)80 void NapiImsRegInfoCallbackManager::RemoveImsRegCallback(int32_t slotId, ImsServiceType imsSrvType)
81 {
82     std::lock_guard<std::mutex> lock(mutex_);
83     auto iter = listImsRegStateCallback_.begin();
84     for (; iter != listImsRegStateCallback_.end(); ++iter) {
85         if ((iter->slotId == slotId) && (iter->imsSrvType == imsSrvType)) {
86             if (iter->imsCallback != nullptr) {
87                 iter->imsCallback = nullptr;
88             }
89             listImsRegStateCallback_.erase(iter);
90             break;
91         }
92     }
93 }
94 
ReportImsRegInfo(int32_t slotId,ImsServiceType imsSrvType,const ImsRegInfo & info)95 int32_t NapiImsRegInfoCallbackManager::ReportImsRegInfo(
96     int32_t slotId, ImsServiceType imsSrvType, const ImsRegInfo &info)
97 {
98     int32_t ret = TELEPHONY_ERROR;
99     std::lock_guard<std::mutex> lock(mutex_);
100     for (auto iter : listImsRegStateCallback_) {
101         if ((iter.slotId == slotId) && (iter.imsSrvType == imsSrvType)) {
102             ret = ReportImsRegInfoInner(iter, info);
103             break;
104         }
105     }
106     if (ret != TELEPHONY_SUCCESS) {
107         TELEPHONY_LOGE("[slot%{public}d] Report imsRegState callback failed, type %{public}d, ret %{public}d", slotId,
108             imsSrvType, ret);
109         return ret;
110     }
111     TELEPHONY_LOGI("[slot%{public}d] Report imsRegState callback successfully, type %{public}d", slotId, imsSrvType);
112     return ret;
113 }
114 
ReportImsRegInfoInner(const ImsRegStateCallback & stateCallback,const ImsRegInfo & info)115 int32_t NapiImsRegInfoCallbackManager::ReportImsRegInfoInner(
116     const ImsRegStateCallback &stateCallback, const ImsRegInfo &info)
117 {
118     uv_loop_s *loop = nullptr;
119 #if NAPI_VERSION >= 2
120     napi_get_uv_event_loop(stateCallback.env, &loop);
121 #endif
122     ImsStateWorker *dataWorker = new ImsStateWorker();
123     dataWorker->info = info;
124     dataWorker->callback = stateCallback;
125     uv_work_t *work = new uv_work_t();
126     work->data = (void *)(dataWorker);
127     int32_t resultCode =
128         uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, ReportImsRegInfoWork, uv_qos_default);
129     if (resultCode != TELEPHONY_SUCCESS) {
130         delete dataWorker;
131         dataWorker = nullptr;
132         TELEPHONY_LOGE("ReportImsRegInfo failed, result: %{public}d", resultCode);
133         delete work;
134         work = nullptr;
135         return TELEPHONY_ERROR;
136     }
137     return TELEPHONY_SUCCESS;
138 }
139 
ReportImsRegInfoWork(uv_work_t * work,int32_t status)140 void NapiImsRegInfoCallbackManager::ReportImsRegInfoWork(uv_work_t *work, int32_t status)
141 {
142     ImsStateWorker *dataWorkerData = (ImsStateWorker *)work->data;
143     int32_t ret = ReportImsRegInfo(dataWorkerData->info, dataWorkerData->callback);
144     delete dataWorkerData;
145     dataWorkerData = nullptr;
146     delete work;
147     work = nullptr;
148     if (ret != TELEPHONY_SUCCESS) {
149         TELEPHONY_LOGE("ReportImsRegInfo failed, result: %{public}d", ret);
150         return;
151     }
152     TELEPHONY_LOGI("ReportImsRegInfo successfully");
153 }
154 
ReportImsRegInfo(const ImsRegInfo & info,const ImsRegStateCallback & stateCallback)155 int32_t NapiImsRegInfoCallbackManager::ReportImsRegInfo(
156     const ImsRegInfo &info, const ImsRegStateCallback &stateCallback)
157 {
158     napi_env env = stateCallback.env;
159     napi_handle_scope scope = nullptr;
160     napi_open_handle_scope(env, &scope);
161     if (scope == nullptr) {
162         TELEPHONY_LOGE("scope is nullptr");
163         napi_close_handle_scope(env, scope);
164         return TELEPHONY_ERROR;
165     }
166     napi_value callbackValues[CALLBACK_VALUES_SIZE] = { 0 };
167     napi_create_object(env, &callbackValues[0]);
168     NapiUtil::SetPropertyInt32(env, callbackValues[0], "imsRegState", static_cast<int32_t>(info.imsRegState));
169     NapiUtil::SetPropertyInt32(env, callbackValues[0], "imsRegTech", static_cast<int32_t>(info.imsRegTech));
170     napi_value thisVar = nullptr;
171     napi_get_reference_value(env, stateCallback.thisVar, &thisVar);
172     napi_value callbackFunc = nullptr;
173     napi_get_reference_value(env, stateCallback.callbackRef, &callbackFunc);
174     if (callbackFunc == nullptr) {
175         TELEPHONY_LOGE("callbackFunc is nullptr!");
176         napi_close_handle_scope(env, scope);
177         return TELEPHONY_ERROR;
178     }
179     napi_value callbackResult = nullptr;
180     napi_status ret =
181         napi_call_function(env, thisVar, callbackFunc, std::size(callbackValues), callbackValues, &callbackResult);
182     if (ret != napi_status::napi_ok) {
183         TELEPHONY_LOGE("napi_call_function failed!");
184         napi_close_handle_scope(env, scope);
185         return TELEPHONY_ERROR;
186     }
187     napi_close_handle_scope(env, scope);
188     return TELEPHONY_SUCCESS;
189 }
190 } // namespace Telephony
191 } // namespace OHOS