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
GetImsCoreServiceProxy()87 sptr<ImsCoreServiceInterface> ImsCoreServiceClient::GetImsCoreServiceProxy()
88 {
89 Utils::UniqueWriteGuard<Utils::RWLock> guard(rwClientLock_);
90 if (imsCoreServiceProxy_ != nullptr) {
91 return imsCoreServiceProxy_;
92 }
93 auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
94 if (managerPtr == nullptr) {
95 TELEPHONY_LOGE("GetImsCoreServiceProxy return, get system ability manager error.");
96 return nullptr;
97 }
98 auto remoteObjectPtr = managerPtr->CheckSystemAbility(TELEPHONY_IMS_SYS_ABILITY_ID);
99 if (remoteObjectPtr == nullptr) {
100 TELEPHONY_LOGE("GetImsCoreServiceProxy return, remote service not exists.");
101 return nullptr;
102 }
103
104 imsCoreServiceProxy_ = iface_cast<ImsCoreServiceInterface>(remoteObjectPtr);
105 if (imsCoreServiceProxy_ == nullptr) {
106 TELEPHONY_LOGE("GetImsCoreServiceProxy return, iface_cast is nullptr.");
107 return nullptr;
108 }
109 // register callback
110 RegisterImsCoreServiceCallback();
111 TELEPHONY_LOGI("GetImsCoreServiceProxy success.");
112 return imsCoreServiceProxy_;
113 }
114
IsConnect() const115 bool ImsCoreServiceClient::IsConnect() const
116 {
117 return (imsCoreServiceProxy_ != nullptr);
118 }
119
RegisterImsCoreServiceCallback()120 int32_t ImsCoreServiceClient::RegisterImsCoreServiceCallback()
121 {
122 if (imsCoreServiceProxy_ == nullptr) {
123 TELEPHONY_LOGE("imsCoreServiceProxy_ is null!");
124 return TELEPHONY_ERR_LOCAL_PTR_NULL;
125 }
126 imsCoreServiceCallback_ = new ImsCoreServiceCallbackStub();
127 int32_t ret = imsCoreServiceProxy_->RegisterImsCoreServiceCallback(imsCoreServiceCallback_);
128 if (ret) {
129 TELEPHONY_LOGE("RegisterImsCoreServiceCallback return, register callback error.");
130 return TELEPHONY_ERR_FAIL;
131 }
132 for (int32_t slotId = SimSlotId::SIM_SLOT_0; slotId < SIM_SLOT_COUNT; slotId++) {
133 if (GetHandler(slotId) != nullptr) {
134 GetImsRegistrationStatus(slotId);
135 }
136 }
137 TELEPHONY_LOGI("RegisterImsCoreServiceCallback success.");
138 return TELEPHONY_SUCCESS;
139 }
140
RegisterImsCoreServiceCallbackHandler(int32_t slotId,const std::shared_ptr<AppExecFwk::EventHandler> & handler)141 int32_t ImsCoreServiceClient::RegisterImsCoreServiceCallbackHandler(int32_t slotId,
142 const std::shared_ptr<AppExecFwk::EventHandler> &handler)
143 {
144 if (handler == nullptr) {
145 TELEPHONY_LOGE("RegisterImsCoreServiceCallbackHandler return, handler is null.");
146 return TELEPHONY_ERR_LOCAL_PTR_NULL;
147 }
148
149 handlerMap_.insert(std::make_pair(slotId, handler));
150 if (IsConnect()) {
151 GetImsRegistrationStatus(slotId);
152 }
153 TELEPHONY_LOGI("RegisterImsCoreServiceCallbackHandler success.");
154 return TELEPHONY_SUCCESS;
155 }
156
GetHandler(int32_t slotId)157 std::shared_ptr<AppExecFwk::EventHandler> ImsCoreServiceClient::GetHandler(int32_t slotId)
158 {
159 auto itor = handlerMap_.find(slotId);
160 if (itor != handlerMap_.end()) {
161 return itor->second;
162 }
163 return nullptr;
164 }
165
ReConnectService()166 int32_t ImsCoreServiceClient::ReConnectService()
167 {
168 if (imsCoreServiceProxy_ == nullptr) {
169 TELEPHONY_LOGI("try to reconnect ims core service now...");
170 GetImsCoreServiceProxy();
171 if (imsCoreServiceProxy_ == nullptr) {
172 TELEPHONY_LOGE("Connect service failed");
173 return TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL;
174 }
175 }
176 return TELEPHONY_SUCCESS;
177 }
178
Clean()179 void ImsCoreServiceClient::Clean()
180 {
181 Utils::UniqueWriteGuard<Utils::RWLock> guard(rwClientLock_);
182 if (imsCoreServiceProxy_ != nullptr) {
183 imsCoreServiceProxy_.clear();
184 imsCoreServiceProxy_ = nullptr;
185 }
186 if (imsCoreServiceCallback_ != nullptr) {
187 imsCoreServiceCallback_.clear();
188 imsCoreServiceCallback_ = nullptr;
189 }
190 }
191
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)192 void ImsCoreServiceClient::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId,
193 const std::string& deviceId)
194 {
195 TELEPHONY_LOGI("SA:%{public}d is added!", systemAbilityId);
196 if (!CheckInputSysAbilityId(systemAbilityId)) {
197 TELEPHONY_LOGE("add SA:%{public}d is invalid!", systemAbilityId);
198 return;
199 }
200
201 auto imsCoreServiceClient = DelayedSingleton<ImsCoreServiceClient>::GetInstance();
202 if (imsCoreServiceClient->IsConnect()) {
203 TELEPHONY_LOGI("SA:%{public}d already connected!", systemAbilityId);
204 return;
205 }
206
207 imsCoreServiceClient->Clean();
208 int32_t res = imsCoreServiceClient->ReConnectService();
209 if (res != TELEPHONY_SUCCESS) {
210 TELEPHONY_LOGE("SA:%{public}d reconnect service failed!", systemAbilityId);
211 return;
212 }
213 TELEPHONY_LOGI("SA:%{public}d reconnect service successfully!", systemAbilityId);
214 }
215
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)216 void ImsCoreServiceClient::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
217 const std::string& deviceId)
218 {
219 TELEPHONY_LOGI("SA:%{public}d is removed!", systemAbilityId);
220 auto imsCoreServiceClient = DelayedSingleton<ImsCoreServiceClient>::GetInstance();
221 if (!imsCoreServiceClient->IsConnect()) {
222 return;
223 }
224 imsCoreServiceClient->Clean();
225 }
226 } // namespace Telephony
227 } // namespace OHOS
228