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