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