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_sms_client.h"
17
18 #include "ims_sms_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
24 namespace OHOS {
25 namespace Telephony {
26 ImsSmsClient::ImsSmsClient() = default;
27
~ImsSmsClient()28 ImsSmsClient::~ImsSmsClient()
29 {
30 UnInit();
31 }
32
Init()33 void ImsSmsClient::Init()
34 {
35 TELEPHONY_LOGI("Init start");
36 if (IsConnect()) {
37 TELEPHONY_LOGE("Init, IsConnect return true");
38 return;
39 }
40
41 GetImsSmsProxy();
42 if (imsSmsProxy_ == nullptr) {
43 TELEPHONY_LOGE("Init, get ims sms proxy failed!");
44 }
45
46 statusChangeListener_ = new (std::nothrow) SystemAbilityListener();
47 if (statusChangeListener_ == nullptr) {
48 TELEPHONY_LOGE("Init, failed to create statusChangeListener.");
49 return;
50 }
51 auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
52 if (managerPtr == nullptr) {
53 TELEPHONY_LOGE("Init, get system ability manager error.");
54 return;
55 }
56 int32_t ret = managerPtr->SubscribeSystemAbility(TELEPHONY_IMS_SYS_ABILITY_ID,
57 statusChangeListener_);
58 if (ret) {
59 TELEPHONY_LOGE("Init, failed to subscribe sa:%{public}d", TELEPHONY_IMS_SYS_ABILITY_ID);
60 return;
61 }
62 TELEPHONY_LOGI("Init successfully");
63 }
64
UnInit()65 void ImsSmsClient::UnInit()
66 {
67 Clean();
68 if (statusChangeListener_ != nullptr) {
69 statusChangeListener_.clear();
70 statusChangeListener_ = nullptr;
71 }
72 std::lock_guard<std::mutex> lock(mutex_);
73 handlerMap_.clear();
74 }
75
GetImsSmsProxy()76 sptr<ImsSmsInterface> ImsSmsClient::GetImsSmsProxy()
77 {
78 if (imsSmsProxy_ != nullptr) {
79 return imsSmsProxy_;
80 }
81 auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
82 if (managerPtr == nullptr) {
83 TELEPHONY_LOGE("GetImsSmsProxy return, get system ability manager error.");
84 return nullptr;
85 }
86 auto remoteObjectPtr = managerPtr->CheckSystemAbility(TELEPHONY_IMS_SYS_ABILITY_ID);
87 if (remoteObjectPtr == nullptr) {
88 TELEPHONY_LOGE("GetImsSmsProxy return, remote service not exists.");
89 return nullptr;
90 }
91 imsCoreServiceProxy_ = iface_cast<ImsCoreServiceInterface>(remoteObjectPtr);
92 if (imsCoreServiceProxy_ == nullptr) {
93 TELEPHONY_LOGE("GetImsSmsProxy return, imsCoreServiceProxy_ is nullptr.");
94 return nullptr;
95 }
96 sptr<IRemoteObject> imsSmsRemoteObjectPtr = imsCoreServiceProxy_->GetProxyObjectPtr(PROXY_IMS_SMS);
97 if (imsSmsRemoteObjectPtr == nullptr) {
98 TELEPHONY_LOGE("GetImsSmsProxy return, ImsCallRemoteObjectPtr is nullptr.");
99 return nullptr;
100 }
101
102 imsSmsProxy_ = iface_cast<ImsSmsInterface>(imsSmsRemoteObjectPtr);
103 if (imsSmsProxy_ == nullptr) {
104 TELEPHONY_LOGE("GetImsSmsProxy return, iface_cast<imsSmsProxy_> failed!");
105 return nullptr;
106 }
107 // register callback
108 RegisterImsSmsCallback();
109 TELEPHONY_LOGI("GetImsSmsProxy success.");
110 return imsSmsProxy_;
111 }
112
IsConnect() const113 bool ImsSmsClient::IsConnect() const
114 {
115 return (imsSmsProxy_ != nullptr);
116 }
117
RegisterImsSmsCallback()118 int32_t ImsSmsClient::RegisterImsSmsCallback()
119 {
120 if (imsSmsProxy_ == nullptr) {
121 TELEPHONY_LOGE("imsSmsProxy_ is null!");
122 return TELEPHONY_ERR_LOCAL_PTR_NULL;
123 }
124 std::lock_guard<std::mutex> lock(mutexCallback_);
125 imsSmsCallback_ = (std::make_unique<ImsSmsCallbackStub>()).release();
126 if (imsSmsCallback_ == nullptr) {
127 TELEPHONY_LOGE("RegisterImsSmsCallback return, make unique error.");
128 return TELEPHONY_ERR_LOCAL_PTR_NULL;
129 }
130 int32_t ret = imsSmsProxy_->RegisterImsSmsCallback(imsSmsCallback_);
131 if (ret) {
132 TELEPHONY_LOGE("RegisterImsSmsCallback return, register callback error.");
133 return TELEPHONY_ERR_FAIL;
134 }
135 TELEPHONY_LOGI("RegisterImsSmsCallback success.");
136 return TELEPHONY_SUCCESS;
137 }
138
ImsSendMessage(int32_t slotId,const ImsMessageInfo & imsMessageInfo)139 int32_t ImsSmsClient::ImsSendMessage(int32_t slotId, const ImsMessageInfo &imsMessageInfo)
140 {
141 if (imsSmsProxy_ != nullptr) {
142 return imsSmsProxy_->ImsSendMessage(slotId, imsMessageInfo);
143 } else {
144 TELEPHONY_LOGE("imsSmsProxy_ is null!");
145 return TELEPHONY_ERR_LOCAL_PTR_NULL;
146 }
147 }
148
ImsSetSmsConfig(int32_t slotId,int32_t imsSmsConfig)149 int32_t ImsSmsClient::ImsSetSmsConfig(int32_t slotId, int32_t imsSmsConfig)
150 {
151 if (ReConnectService() != TELEPHONY_SUCCESS) {
152 TELEPHONY_LOGE("ipc reconnect failed!");
153 return TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL;
154 }
155 return imsSmsProxy_->ImsSetSmsConfig(slotId, imsSmsConfig);
156 }
157
ImsGetSmsConfig(int32_t slotId)158 int32_t ImsSmsClient::ImsGetSmsConfig(int32_t slotId)
159 {
160 if (ReConnectService() != TELEPHONY_SUCCESS) {
161 TELEPHONY_LOGE("ipc reconnect failed!");
162 return TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL;
163 }
164 return imsSmsProxy_->ImsGetSmsConfig(slotId);
165 }
166
RegisterImsSmsCallbackHandler(int32_t slotId,const std::shared_ptr<AppExecFwk::EventHandler> & handler)167 int32_t ImsSmsClient::RegisterImsSmsCallbackHandler(
168 int32_t slotId, const std::shared_ptr<AppExecFwk::EventHandler> &handler)
169 {
170 if (handler == nullptr) {
171 TELEPHONY_LOGE("RegisterImsSmsCallbackHandler return, handler is null.");
172 return TELEPHONY_ERR_LOCAL_PTR_NULL;
173 }
174
175 std::lock_guard<std::mutex> lock(mutex_);
176 handlerMap_.insert(std::make_pair(slotId, handler));
177 TELEPHONY_LOGI("RegisterImsSmsCallbackHandler success.");
178 return TELEPHONY_SUCCESS;
179 }
180
GetHandler(int32_t slotId)181 std::shared_ptr<AppExecFwk::EventHandler> ImsSmsClient::GetHandler(int32_t slotId)
182 {
183 std::lock_guard<std::mutex> lock(mutex_);
184 if (handlerMap_.find(slotId) != handlerMap_.end()) {
185 return handlerMap_[slotId];
186 } else {
187 TELEPHONY_LOGE("GetHandler nullptr");
188 return nullptr;
189 }
190 }
191
ReConnectService()192 int32_t ImsSmsClient::ReConnectService()
193 {
194 if (imsSmsProxy_ == nullptr) {
195 TELEPHONY_LOGI("try to reconnect ims sms service now...");
196 GetImsSmsProxy();
197 if (imsSmsProxy_ == nullptr) {
198 TELEPHONY_LOGE("Connect service failed");
199 return TELEPHONY_ERR_IPC_CONNECT_STUB_FAIL;
200 }
201 }
202 return TELEPHONY_SUCCESS;
203 }
204
Clean()205 void ImsSmsClient::Clean()
206 {
207 Utils::UniqueWriteGuard<Utils::RWLock> guard(rwClientLock_);
208 if (imsCoreServiceProxy_ != nullptr) {
209 imsCoreServiceProxy_.clear();
210 imsCoreServiceProxy_ = nullptr;
211 }
212 if (imsSmsProxy_ != nullptr) {
213 imsSmsProxy_.clear();
214 imsSmsProxy_ = nullptr;
215 }
216 std::lock_guard<std::mutex> lock(mutexCallback_);
217 if (imsSmsCallback_ != nullptr) {
218 imsSmsCallback_.clear();
219 imsSmsCallback_ = nullptr;
220 }
221 }
222
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)223 void ImsSmsClient::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId,
224 const std::string& deviceId)
225 {
226 TELEPHONY_LOGI("SA:%{public}d is added!", systemAbilityId);
227 if (!CheckInputSysAbilityId(systemAbilityId)) {
228 TELEPHONY_LOGE("add SA:%{public}d is invalid!", systemAbilityId);
229 return;
230 }
231
232 auto imsSmsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
233 if (imsSmsClient->IsConnect()) {
234 TELEPHONY_LOGI("SA:%{public}d already connected!", systemAbilityId);
235 return;
236 }
237
238 imsSmsClient->Clean();
239 int32_t res = imsSmsClient->ReConnectService();
240 if (res != TELEPHONY_SUCCESS) {
241 TELEPHONY_LOGE("SA:%{public}d reconnect service failed!", systemAbilityId);
242 return;
243 }
244 TELEPHONY_LOGI("SA:%{public}d reconnect service successfully!", systemAbilityId);
245 }
246
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)247 void ImsSmsClient::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId,
248 const std::string& deviceId)
249 {
250 TELEPHONY_LOGI("SA:%{public}d is removed!", systemAbilityId);
251 auto imsSmsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
252 if (!imsSmsClient->IsConnect()) {
253 return;
254 }
255
256 imsSmsClient->Clean();
257 }
258 } // namespace Telephony
259 } // namespace OHOS
260