1 /*
2 * Copyright (c) 2022-2023 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 "domain_account_client.h"
17
18 #include "account_error_no.h"
19 #include "account_log_wrapper.h"
20 #include "account_proxy.h"
21 #include "domain_account_callback_adapters.h"
22 #include "domain_account_callback_service.h"
23 #include "domain_account_plugin_service.h"
24 #include "domain_account_proxy.h"
25 #include "domain_account_status_listener.h"
26 #include "domain_account_status_listener_manager.h"
27 #include "ohos_account_kits_impl.h"
28 #include "system_ability_definition.h"
29
30 namespace OHOS {
31 namespace AccountSA {
GetInstance()32 DomainAccountClient &DomainAccountClient::GetInstance()
33 {
34 static DomainAccountClient *instance = new (std::nothrow) DomainAccountClient();
35 return *instance;
36 }
37
callbackFunc()38 std::function<void(int32_t, const std::string &)> callbackFunc()
39 {
40 return [](int32_t systemAbilityId, const std::string &deviceId) {
41 if (systemAbilityId == SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN) {
42 DomainAccountClient::GetInstance().RestoreListenerRecords();
43 DomainAccountClient::GetInstance().RestorePlugin();
44 }
45 };
46 }
47
DomainAccountClient()48 DomainAccountClient::DomainAccountClient()
49 {
50 (void)OhosAccountKitsImpl::GetInstance().SubscribeSystemAbility(callbackFunc());
51 }
52
RegisterPlugin(const std::shared_ptr<DomainAccountPlugin> & plugin)53 ErrCode DomainAccountClient::RegisterPlugin(const std::shared_ptr<DomainAccountPlugin> &plugin)
54 {
55 if (plugin == nullptr) {
56 ACCOUNT_LOGE("plugin is nullptr");
57 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
58 }
59 sptr<DomainAccountPluginService> pluginService = new (std::nothrow) DomainAccountPluginService(plugin);
60 if (pluginService == nullptr) {
61 ACCOUNT_LOGE("failed to create DomainAccountPluginService");
62 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
63 }
64 auto proxy = GetDomainAccountProxy();
65 if (proxy == nullptr) {
66 ACCOUNT_LOGE("failed to get domain account proxy");
67 return ERR_ACCOUNT_COMMON_GET_PROXY;
68 }
69 ErrCode result = proxy->RegisterPlugin(pluginService);
70 if (result == ERR_OK) {
71 pluginService_ = pluginService;
72 }
73 return result;
74 }
75
UnregisterPlugin()76 ErrCode DomainAccountClient::UnregisterPlugin()
77 {
78 auto proxy = GetDomainAccountProxy();
79 if (proxy == nullptr) {
80 ACCOUNT_LOGE("failed to get domain account proxy");
81 return ERR_ACCOUNT_COMMON_GET_PROXY;
82 }
83 return proxy->UnregisterPlugin();
84 }
85
AuthProxyInit(const std::shared_ptr<DomainAccountCallback> & callback,sptr<DomainAccountCallbackService> & callbackService,sptr<IDomainAccount> & proxy)86 ErrCode DomainAccountClient::AuthProxyInit(const std::shared_ptr<DomainAccountCallback> &callback,
87 sptr<DomainAccountCallbackService> &callbackService, sptr<IDomainAccount> &proxy)
88 {
89 if (callback == nullptr) {
90 ACCOUNT_LOGE("callback is nullptr");
91 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
92 }
93 callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
94 if (callbackService == nullptr) {
95 ACCOUNT_LOGE("failed to create DomainAccountCallbackService");
96 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
97 }
98 proxy = GetDomainAccountProxy();
99 if (proxy == nullptr) {
100 ACCOUNT_LOGE("failed to get domain account proxy");
101 return ERR_ACCOUNT_COMMON_GET_PROXY;
102 }
103 return ERR_OK;
104 }
105
GetAccessToken(const DomainAccountInfo & info,const AAFwk::WantParams & parameters,const std::shared_ptr<GetAccessTokenCallback> & callback)106 ErrCode DomainAccountClient::GetAccessToken(const DomainAccountInfo &info, const AAFwk::WantParams ¶meters,
107 const std::shared_ptr<GetAccessTokenCallback> &callback)
108 {
109 if (callback == nullptr) {
110 ACCOUNT_LOGE("callback is nullptr");
111 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
112 }
113 auto callbackPtr = std::make_shared<GetAccessTokenCallbackAdapter>(callback);
114 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callbackPtr);
115 if (callbackService == nullptr) {
116 ACCOUNT_LOGE("failed to new callback service");
117 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
118 }
119 auto proxy = GetDomainAccountProxy();
120 if (proxy == nullptr) {
121 ACCOUNT_LOGE("failed to get domain account proxy");
122 return ERR_ACCOUNT_COMMON_GET_PROXY;
123 }
124 return proxy->GetAccessToken(info, parameters, callbackService);
125 }
126
HasAccount(const DomainAccountInfo & info,const std::shared_ptr<DomainAccountCallback> & callback)127 ErrCode DomainAccountClient::HasAccount(
128 const DomainAccountInfo &info, const std::shared_ptr<DomainAccountCallback> &callback)
129 {
130 if (callback == nullptr) {
131 ACCOUNT_LOGE("callback is nullptr");
132 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
133 }
134 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
135 if (callbackService == nullptr) {
136 ACCOUNT_LOGE("failed to check domain account callback service");
137 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
138 }
139 auto proxy = GetDomainAccountProxy();
140 if (proxy == nullptr) {
141 ACCOUNT_LOGE("failed to get domain account proxy");
142 return ERR_ACCOUNT_COMMON_GET_PROXY;
143 }
144 return proxy->HasDomainAccount(info, callbackService);
145 }
146
Auth(const DomainAccountInfo & info,const std::vector<uint8_t> & password,const std::shared_ptr<DomainAccountCallback> & callback)147 ErrCode DomainAccountClient::Auth(const DomainAccountInfo &info, const std::vector<uint8_t> &password,
148 const std::shared_ptr<DomainAccountCallback> &callback)
149 {
150 sptr<DomainAccountCallbackService> callbackService = nullptr;
151 sptr<IDomainAccount> proxy = nullptr;
152 ErrCode result = AuthProxyInit(callback, callbackService, proxy);
153 if (result != ERR_OK) {
154 return result;
155 }
156 return proxy->Auth(info, password, callbackService);
157 }
158
AuthUser(int32_t userId,const std::vector<uint8_t> & password,const std::shared_ptr<DomainAccountCallback> & callback)159 ErrCode DomainAccountClient::AuthUser(int32_t userId, const std::vector<uint8_t> &password,
160 const std::shared_ptr<DomainAccountCallback> &callback)
161 {
162 sptr<DomainAccountCallbackService> callbackService = nullptr;
163 sptr<IDomainAccount> proxy = nullptr;
164 ErrCode result = AuthProxyInit(callback, callbackService, proxy);
165 if (result != ERR_OK) {
166 return result;
167 }
168 return proxy->AuthUser(userId, password, callbackService);
169 }
170
AuthWithPopup(int32_t userId,const std::shared_ptr<DomainAccountCallback> & callback)171 ErrCode DomainAccountClient::AuthWithPopup(int32_t userId, const std::shared_ptr<DomainAccountCallback> &callback)
172 {
173 sptr<DomainAccountCallbackService> callbackService = nullptr;
174 sptr<IDomainAccount> proxy = nullptr;
175 ErrCode result = AuthProxyInit(callback, callbackService, proxy);
176 if (result != ERR_OK) {
177 return result;
178 }
179 return proxy->AuthWithPopup(userId, callbackService);
180 }
181
UpdateAccountToken(const DomainAccountInfo & info,const std::vector<uint8_t> & token)182 ErrCode DomainAccountClient::UpdateAccountToken(const DomainAccountInfo &info, const std::vector<uint8_t> &token)
183 {
184 auto proxy = GetDomainAccountProxy();
185 if (proxy == nullptr) {
186 ACCOUNT_LOGE("failed to get domain account proxy");
187 return ERR_ACCOUNT_COMMON_GET_PROXY;
188 }
189 return proxy->UpdateAccountToken(info, token);
190 }
191
ResetDomainAccountProxy(const wptr<IRemoteObject> & remote)192 void DomainAccountClient::ResetDomainAccountProxy(const wptr<IRemoteObject>& remote)
193 {
194 std::lock_guard<std::mutex> lock(mutex_);
195 if (proxy_ == nullptr) {
196 ACCOUNT_LOGD("proxy is nullptr");
197 return;
198 }
199 auto serviceRemote = proxy_->AsObject();
200 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
201 serviceRemote->RemoveDeathRecipient(deathRecipient_);
202 }
203 proxy_ = nullptr;
204 deathRecipient_ = nullptr;
205 }
206
GetAccountStatus(const DomainAccountInfo & info,DomainAccountStatus & status)207 ErrCode DomainAccountClient::GetAccountStatus(const DomainAccountInfo &info, DomainAccountStatus &status)
208 {
209 auto proxy = GetDomainAccountProxy();
210 if (proxy == nullptr) {
211 ACCOUNT_LOGE("failed to get domain account proxy");
212 return ERR_ACCOUNT_COMMON_GET_PROXY;
213 }
214 return proxy->GetAccountStatus(info, status);
215 }
216
GetDomainAccountInfo(const DomainAccountInfo & info,const std::shared_ptr<DomainAccountCallback> & callback)217 ErrCode DomainAccountClient::GetDomainAccountInfo(
218 const DomainAccountInfo &info, const std::shared_ptr<DomainAccountCallback> &callback)
219 {
220 if (callback == nullptr) {
221 ACCOUNT_LOGE("callback is nullptr");
222 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
223 }
224 sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
225 auto proxy = GetDomainAccountProxy();
226 if (proxy == nullptr) {
227 ACCOUNT_LOGE("failed to get domain account proxy");
228 return ERR_ACCOUNT_COMMON_GET_PROXY;
229 }
230 return proxy->GetDomainAccountInfo(info, callbackService);
231 }
232
RegisterAccountStatusListener(const std::shared_ptr<DomainAccountStatusListener> & listener)233 ErrCode DomainAccountClient::RegisterAccountStatusListener(const std::shared_ptr<DomainAccountStatusListener> &listener)
234 {
235 if (listener == nullptr) {
236 ACCOUNT_LOGE("callback is nullptr");
237 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
238 }
239 std::lock_guard<std::mutex> lock(recordMutex_);
240 if (listenerManager_ == nullptr) {
241 listenerManager_ = std::make_shared<DomainAccountStatusListenerManager>();
242 }
243 if (!listenerManager_->IsRecordEmpty()) {
244 listenerManager_->InsertRecord(listener);
245 return ERR_OK;
246 }
247 if (callback_ == nullptr) {
248 callback_ = new (std::nothrow) DomainAccountCallbackService(listenerManager_);
249 if (callback_ == nullptr) {
250 ACCOUNT_LOGE("failed to check domain account callback service");
251 return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
252 }
253 }
254 auto proxy = GetDomainAccountProxy();
255 if (proxy == nullptr) {
256 ACCOUNT_LOGE("failed to get domain account proxy");
257 return ERR_ACCOUNT_COMMON_GET_PROXY;
258 }
259 ErrCode result = proxy->RegisterAccountStatusListener(callback_);
260 if (result == ERR_OK) {
261 listenerManager_->InsertRecord(listener);
262 }
263 return result;
264 }
265
UnregisterAccountStatusListener(const std::shared_ptr<DomainAccountStatusListener> & listener)266 ErrCode DomainAccountClient::UnregisterAccountStatusListener(
267 const std::shared_ptr<DomainAccountStatusListener> &listener)
268 {
269 if (listener == nullptr) {
270 ACCOUNT_LOGE("callback is nullptr");
271 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
272 }
273 std::lock_guard<std::mutex> lock(recordMutex_);
274 if (listenerManager_ == nullptr) {
275 ACCOUNT_LOGE("listenerManager_ is nullptr");
276 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
277 }
278 auto proxy = GetDomainAccountProxy();
279 if (proxy == nullptr) {
280 ACCOUNT_LOGE("failed to get domain account proxy");
281 return ERR_ACCOUNT_COMMON_GET_PROXY;
282 }
283 listenerManager_->RemoveRecord(listener);
284 if (!listenerManager_->IsRecordEmpty()) {
285 return ERR_OK;
286 }
287 ErrCode result = proxy->UnregisterAccountStatusListener(callback_);
288 if (result != ERR_OK) {
289 listenerManager_->InsertRecord(listener);
290 return result;
291 }
292 return ERR_OK;
293 }
294
RestoreListenerRecords()295 void DomainAccountClient::RestoreListenerRecords()
296 {
297 if (listenerManager_ == nullptr) {
298 ACCOUNT_LOGI("listenerManager_ is nullptr");
299 return;
300 }
301 sptr<IDomainAccount> proxy = GetDomainAccountProxy();
302 if (proxy == nullptr) {
303 ACCOUNT_LOGE("proxy is nullptr");
304 return;
305 }
306 std::set<std::shared_ptr<DomainAccountStatusListener>> listenerAllRecords;
307 listenerAllRecords = listenerManager_->GetListenerAllRecords();
308 if (!listenerAllRecords.empty()) {
309 (void)proxy->RegisterAccountStatusListener(callback_);
310 }
311 }
312
RestorePlugin()313 void DomainAccountClient::RestorePlugin()
314 {
315 if (pluginService_ == nullptr) {
316 ACCOUNT_LOGI("pluginService_ is nullptr");
317 return;
318 }
319 sptr<IDomainAccount> proxy = GetDomainAccountProxy();
320 if (proxy == nullptr) {
321 ACCOUNT_LOGE("proxy is nullptr");
322 return;
323 }
324 (void)proxy->RegisterPlugin(pluginService_);
325 }
326
OnRemoteDied(const wptr<IRemoteObject> & remote)327 void DomainAccountClient::DomainAccountDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
328 {
329 if (remote == nullptr) {
330 ACCOUNT_LOGE("remote is nullptr");
331 return;
332 }
333 DomainAccountClient::GetInstance().ResetDomainAccountProxy(remote);
334 }
335
GetDomainAccountProxy()336 sptr<IDomainAccount> DomainAccountClient::GetDomainAccountProxy()
337 {
338 std::lock_guard<std::mutex> lock(mutex_);
339 if (proxy_ != nullptr) {
340 return proxy_;
341 }
342 sptr<IRemoteObject> object = OhosAccountKitsImpl::GetInstance().GetDomainAccountService();
343 if (object == nullptr) {
344 ACCOUNT_LOGE("failed to get domain account service");
345 return nullptr;
346 }
347 deathRecipient_ = new (std::nothrow) DomainAccountDeathRecipient();
348 if (deathRecipient_ == nullptr) {
349 ACCOUNT_LOGE("failed to create domain account death recipient");
350 return nullptr;
351 }
352 if (!object->AddDeathRecipient(deathRecipient_)) {
353 ACCOUNT_LOGE("failed to add domain account death recipient");
354 deathRecipient_ = nullptr;
355 return nullptr;
356 }
357 proxy_ = iface_cast<IDomainAccount>(object);
358 return proxy_;
359 }
360 } // namespace AccountSA
361 } // namespace OHOS
362