1 /*
2 * Copyright (C) 2022 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 "ims_core_service_client.h"
17
18 #include "ims_core_service_callback_stub.h"
19 #include "iservice_registry.h"
20 #include "system_ability_definition.h"
21 #include "telephony_errors.h"
22 #include "telephony_log_wrapper.h"
23 #include "telephony_types.h"
24
25
26 namespace OHOS {
27 namespace Telephony {
28 ImsCoreServiceClient::ImsCoreServiceClient() = default;
29
~ImsCoreServiceClient()30 ImsCoreServiceClient::~ImsCoreServiceClient()
31 {
32 UnInit();
33 }
34
Init()35 void ImsCoreServiceClient::Init()
36 {
37 TELEPHONY_LOGI("Init start");
38 if (IsConnect()) {
39 TELEPHONY_LOGE("Init, IsConnect return true");
40 return;
41 }
42
43 GetImsCoreServiceProxy();
44 if (imsCoreServiceProxy_ == nullptr) {
45 TELEPHONY_LOGE("Init, get ims core service proxy failed!");
46 }
47
48 statusChangeListener_ = new (std::nothrow) SystemAbilityListener();
49 if (statusChangeListener_ == nullptr) {
50 TELEPHONY_LOGE("Init, failed to create statusChangeListener.");
51 return;
52 }
53 auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
54 if (managerPtr == nullptr) {
55 TELEPHONY_LOGE("Init, get system ability manager error.");
56 return;
57 }
58 int32_t ret = managerPtr->SubscribeSystemAbility(TELEPHONY_IMS_SYS_ABILITY_ID,
59 statusChangeListener_);
60 if (ret) {
61 TELEPHONY_LOGE("Init, failed to subscribe sa:%{public}d", TELEPHONY_IMS_SYS_ABILITY_ID);
62 return;
63 }
64 TELEPHONY_LOGI("Init successfully");
65 }
66
UnInit()67 void ImsCoreServiceClient::UnInit()
68 {
69 Clean();
70 if (statusChangeListener_ != nullptr) {
71 statusChangeListener_.clear();
72 statusChangeListener_ = nullptr;
73 }
74 handlerMap_.clear();
75 }
76
GetImsRegistrationStatus(int32_t slotId)77 int32_t ImsCoreServiceClient::GetImsRegistrationStatus(int32_t slotId)
78 {
79 if (ReConnectService() != TELEPHONY_SUCCESS) {
80 TELEPHONY_LOGE("ipc reconnect failed!");
81 return TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL;
82 }
83
84 return imsCoreServiceProxy_->GetImsRegistrationStatus(slotId);
85 }
86
GetPhoneNumberFromIMPU(int32_t slotId,std::string & phoneNumber)87 int32_t ImsCoreServiceClient::GetPhoneNumberFromIMPU(int32_t slotId, std::string &phoneNumber)
88 {
89 if (ReConnectService() != TELEPHONY_SUCCESS) {
90 TELEPHONY_LOGE("ipc reconnect failed!");
91 return TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL;
92 }
93
94 return imsCoreServiceProxy_->GetPhoneNumberFromIMPU(slotId, phoneNumber);
95 }
96
GetImsCoreServiceProxy()97 sptr<ImsCoreServiceInterface> ImsCoreServiceClient::GetImsCoreServiceProxy()
98 {
99 Utils::UniqueWriteGuard<Utils::RWLock> guard(rwClientLock_);
100 if (imsCoreServiceProxy_ != nullptr) {
101 return imsCoreServiceProxy_;
102 }
103 auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
104 if (managerPtr == nullptr) {
105 TELEPHONY_LOGE("GetImsCoreServiceProxy return, get system ability manager error.");
106 return nullptr;
107 }
108 auto remoteObjectPtr = managerPtr->CheckSystemAbility(TELEPHONY_IMS_SYS_ABILITY_ID);
109 if (remoteObjectPtr == nullptr) {
110 TELEPHONY_LOGE("GetImsCoreServiceProxy return, remote service not exists.");
111 return nullptr;
112 }
113
114 imsCoreServiceProxy_ = iface_cast<ImsCoreServiceInterface>(remoteObjectPtr);
115 if (imsCoreServiceProxy_ == nullptr) {
116 TELEPHONY_LOGE("GetImsCoreServiceProxy return, iface_cast is nullptr.");
117 return nullptr;
118 }
119 // register callback
120 RegisterImsCoreServiceCallback();
121 TELEPHONY_LOGI("GetImsCoreServiceProxy success.");
122 return imsCoreServiceProxy_;
123 }
124
IsConnect() const125 bool ImsCoreServiceClient::IsConnect() const
126 {
127 return (imsCoreServiceProxy_ != nullptr);
128 }
129
RegisterImsCoreServiceCallback()130 int32_t ImsCoreServiceClient::RegisterImsCoreServiceCallback()
131 {
132 if (imsCoreServiceProxy_ == nullptr) {
133 TELEPHONY_LOGE("imsCoreServiceProxy_ is null!");
134 return TELEPHONY_ERR_LOCAL_PTR_NULL;
135 }
136 imsCoreServiceCallback_ = new ImsCoreServiceCallbackStub();
137 int32_t ret = imsCoreServiceProxy_->RegisterImsCoreServiceCallback(imsCoreServiceCallback_);
138 if (ret) {
139 TELEPHONY_LOGE("RegisterImsCoreServiceCallback return, register callback error.");
140 return TELEPHONY_ERR_FAIL;
141 }
142 for (int32_t slotId = SimSlotId::SIM_SLOT_0; slotId < SIM_SLOT_COUNT; slotId++) {
143 if (GetHandler(slotId) != nullptr) {
144 GetImsRegistrationStatus(slotId);
145 }
146 }
147 TELEPHONY_LOGI("RegisterImsCoreServiceCallback success.");
148 return TELEPHONY_SUCCESS;
149 }
150
RegisterImsCoreServiceCallbackHandler(int32_t slotId,const std::shared_ptr<AppExecFwk::EventHandler> & handler)151 int32_t ImsCoreServiceClient::RegisterImsCoreServiceCallbackHandler(int32_t slotId,
152 const std::shared_ptr<AppExecFwk::EventHandler> &handler)
153 {
154 if (handler == nullptr) {
155 TELEPHONY_LOGE("RegisterImsCoreServiceCallbackHandler return, handler is null.");
156 return TELEPHONY_ERR_LOCAL_PTR_NULL;
157 }
158
159 handlerMap_.insert(std::make_pair(slotId, handler));
160 if (IsConnect()) {
161 GetImsRegistrationStatus(slotId);
162 }
163 TELEPHONY_LOGI("RegisterImsCoreServiceCallbackHandler success.");
164 return TELEPHONY_SUCCESS;
165 }
166
GetHandler(int32_t slotId)167 std::shared_ptr<AppExecFwk::EventHandler> ImsCoreServiceClient::GetHandler(int32_t slotId)
168 {
169 auto itor = handlerMap_.find(slotId);
170 if (itor != handlerMap_.end()) {
171 return itor->second;
172 }
173 return nullptr;
174 }
175
ReConnectService()176 int32_t ImsCoreServiceClient::ReConnectService()
177 {
178 if (imsCoreServiceProxy_ == nullptr) {
179 TELEPHONY_LOGI("try to reconnect ims core service now...");
180 GetImsCoreServiceProxy();
181 if (imsCoreServiceProxy_ == nullptr) {
182 TELEPHONY_LOGE("Connect service failed");
183 return TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL;
184 }
185 }
186 return TELEPHONY_SUCCESS;
187 }
188
Clean()189 void ImsCoreServiceClient::Clean()
190 {
191 Utils::UniqueWriteGuard<Utils::RWLock> guard(rwClientLock_);
192 if (imsCoreServiceProxy_ != nullptr) {
193 imsCoreServiceProxy_.clear();
194 imsCoreServiceProxy_ = nullptr;
195 }
196 if (imsCoreServiceCallback_ != nullptr) {
197 imsCoreServiceCallback_.clear();
198 imsCoreServiceCallback_ = nullptr;
199 }
200 }
201
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)202 void ImsCoreServiceClient::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId,
203 const std::string& deviceId)
204 {
205 TELEPHONY_LOGI("SA:%{public}d is added!", systemAbilityId);
206 if (!CheckInputSysAbilityId(systemAbilityId)) {
207 TELEPHONY_LOGE("add SA:%{public}d is invalid!", systemAbilityId);
208 return;
209 }
210
211 auto imsCoreServiceClient = DelayedSingleton<ImsCoreServiceClient>::GetInstance();
212 if (imsCoreServiceClient->IsConnect()) {
213 TELEPHONY_LOGI("SA:%{public}d already connected!", systemAbilityId);
214 return;
215 }
216
217 imsCoreServiceClient->Clean();
218 int32_t res = imsCoreServiceClient->ReConnectService();
219 if (res != TELEPHONY_SUCCESS) {
220 TELEPHONY_LOGE("SA:%{public}d reconnect service failed!", systemAbilityId);
221 return;
222 }
223 TELEPHONY_LOGI("SA:%{public}d reconnect service successfully!", systemAbilityId);
224 }
225
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)226 void ImsCoreServiceClient::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
227 const std::string& deviceId)
228 {
229 TELEPHONY_LOGI("SA:%{public}d is removed!", systemAbilityId);
230 auto imsCoreServiceClient = DelayedSingleton<ImsCoreServiceClient>::GetInstance();
231 if (!imsCoreServiceClient->IsConnect()) {
232 return;
233 }
234 imsCoreServiceClient->Clean();
235 }
236 } // namespace Telephony
237 } // namespace OHOS
238