1 /*
2 * Copyright (c) 2021-2025 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 "ohos_account_kits_impl.h"
17 #include "account_error_no.h"
18 #include "account_log_wrapper.h"
19 #include "account_proxy.h"
20 #include "if_system_ability_manager.h"
21 #include "system_ability_status_change_listener.h"
22
23 namespace OHOS {
24 namespace AccountSA {
25 const size_t INTERCEPT_HEAD_PART_LEN_FOR_NAME = 1;
26 const char DEFAULT_ANON_STR[] = "**********";
27
ohosCallbackFunc()28 std::function<void(int32_t, const std::string &)> ohosCallbackFunc()
29 {
30 return [](int32_t systemAbilityId, const std::string &dvid) {
31 if (systemAbilityId == SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN) {
32 OhosAccountKitsImpl::GetInstance().RestoreSubscribe();
33 }
34 };
35 }
36
AnonymizeNameStr(const std::string & nameStr)37 static std::string AnonymizeNameStr(const std::string& nameStr)
38 {
39 if (nameStr.empty()) {
40 return nameStr;
41 }
42 return nameStr.substr(0, INTERCEPT_HEAD_PART_LEN_FOR_NAME) + DEFAULT_ANON_STR;
43 }
44
GetInstance()45 OhosAccountKitsImpl &OhosAccountKitsImpl::GetInstance()
46 {
47 static OhosAccountKitsImpl *instance = new (std::nothrow) OhosAccountKitsImpl();
48 return *instance;
49 }
50
ResetService(const wptr<IRemoteObject> & remote)51 void OhosAccountKitsImpl::ResetService(const wptr<IRemoteObject>& remote)
52 {
53 ACCOUNT_LOGI("Remote is dead, reset service instance");
54
55 std::lock_guard<std::mutex> lock(accountProxyLock_);
56 if (accountProxy_ != nullptr) {
57 sptr<IRemoteObject> object = accountProxy_->AsObject();
58 if ((object != nullptr) && (remote == object)) {
59 object->RemoveDeathRecipient(deathRecipient_);
60 accountProxy_ = nullptr;
61 }
62 }
63 if (!isSubscribeSA_) {
64 isSubscribeSA_ = true;
65 SubscribeSystemAbility(ohosCallbackFunc());
66 }
67 }
68
GetService()69 sptr<IAccount> OhosAccountKitsImpl::GetService()
70 {
71 std::lock_guard<std::mutex> lock(accountProxyLock_);
72 if (accountProxy_ != nullptr) {
73 return accountProxy_;
74 }
75
76 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
77 if (samgr == nullptr) {
78 ACCOUNT_LOGE("Get samgr failed");
79 return nullptr;
80 }
81 sptr<IRemoteObject> object = samgr->GetSystemAbility(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN);
82 if (object == nullptr) {
83 ACCOUNT_LOGE("Get account object from samgr failed");
84 return nullptr;
85 }
86
87 if (deathRecipient_ == nullptr) {
88 deathRecipient_ = new (std::nothrow) DeathRecipient();
89 if (deathRecipient_ == nullptr) {
90 ACCOUNT_LOGE("deathRecipient_ is nullptr.");
91 return nullptr;
92 }
93 }
94
95 if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
96 ACCOUNT_LOGE("Failed to add death recipient");
97 }
98
99 accountProxy_ = iface_cast<AccountProxy>(object);
100 if (accountProxy_ == nullptr) {
101 ACCOUNT_LOGE("account iface_cast failed");
102 }
103 return accountProxy_;
104 }
105
OnRemoteDied(const wptr<IRemoteObject> & remote)106 void OhosAccountKitsImpl::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
107 {
108 OhosAccountKitsImpl::GetInstance().ResetService(remote);
109 }
110
UpdateOhosAccountInfo(const std::string & accountName,const std::string & uid,const std::string & eventStr)111 ErrCode OhosAccountKitsImpl::UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid,
112 const std::string& eventStr)
113 {
114 auto accountProxy = GetService();
115 if (accountProxy == nullptr) {
116 ACCOUNT_LOGE("Get proxy failed");
117 return ERR_ACCOUNT_COMMON_GET_PROXY;
118 }
119 return accountProxy->UpdateOhosAccountInfo(accountName, uid, eventStr);
120 }
121
SetOhosAccountInfo(const OhosAccountInfo & ohosAccountInfo,const std::string & eventStr)122 ErrCode OhosAccountKitsImpl::SetOhosAccountInfo(
123 const OhosAccountInfo &ohosAccountInfo, const std::string &eventStr)
124 {
125 auto accountProxy = GetService();
126 if (accountProxy == nullptr) {
127 ACCOUNT_LOGE("Get proxy failed");
128 return ERR_ACCOUNT_COMMON_GET_PROXY;
129 }
130 if (!ohosAccountInfo.IsValid()) {
131 ACCOUNT_LOGE("OhosAccountInfo check failed");
132 NativeErrMsg() = "Invalid accountInfo. Please check the value of accountInfo."
133 "(1) The length of the accountInfo.nickname must be less than 1025."
134 "(2) The avatar must be less than 10MB."
135 "(3) The length of the accountInfo.scalableData must be less than 1025.";
136 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
137 }
138 return accountProxy->SetOhosAccountInfo(ohosAccountInfo, eventStr);
139 }
140
SetOsAccountDistributedInfo(const int32_t localId,const OhosAccountInfo & ohosAccountInfo,const std::string & eventStr)141 ErrCode OhosAccountKitsImpl::SetOsAccountDistributedInfo(
142 const int32_t localId, const OhosAccountInfo& ohosAccountInfo, const std::string& eventStr)
143 {
144 auto accountProxy = GetService();
145 if (accountProxy == nullptr) {
146 ACCOUNT_LOGE("Get proxy failed");
147 return ERR_ACCOUNT_COMMON_GET_PROXY;
148 }
149 if (!ohosAccountInfo.IsValid()) {
150 ACCOUNT_LOGE("OhosAccountInfo check failed");
151 NativeErrMsg() = "Invalid accountInfo. Please check the value of accountInfo."
152 "(1) The length of the accountInfo.nickname must be less than 1025."
153 "(2) The avatar must be less than 10MB."
154 "(3) The length of the accountInfo.scalableData must be less than 1025.";
155 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
156 }
157 return accountProxy->SetOsAccountDistributedInfo(localId, ohosAccountInfo, eventStr);
158 }
159
QueryOhosAccountInfo()160 std::pair<bool, OhosAccountInfo> OhosAccountKitsImpl::QueryOhosAccountInfo()
161 {
162 OhosAccountInfo accountInfo;
163 ErrCode result = QueryOhosAccountInfo(accountInfo);
164 return std::make_pair(result == ERR_OK, accountInfo);
165 }
166
QueryDistributedVirtualDeviceId(std::string & dvid)167 ErrCode OhosAccountKitsImpl::QueryDistributedVirtualDeviceId(std::string &dvid)
168 {
169 auto accountProxy = GetService();
170 if (accountProxy == nullptr) {
171 ACCOUNT_LOGE("Get proxy failed");
172 return ERR_ACCOUNT_COMMON_GET_PROXY;
173 }
174
175 return accountProxy->QueryDistributedVirtualDeviceId(dvid);
176 }
177
QueryDistributedVirtualDeviceId(const std::string & bundleName,int32_t localId,std::string & dvid)178 ErrCode OhosAccountKitsImpl::QueryDistributedVirtualDeviceId(const std::string &bundleName, int32_t localId,
179 std::string &dvid)
180 {
181 auto accountProxy = GetService();
182 if (accountProxy == nullptr) {
183 ACCOUNT_LOGE("Get proxy failed");
184 return ERR_ACCOUNT_COMMON_GET_PROXY;
185 }
186
187 return accountProxy->QueryDistributedVirtualDeviceId(bundleName, localId, dvid);
188 }
189
QueryOhosAccountInfo(OhosAccountInfo & accountInfo)190 ErrCode OhosAccountKitsImpl::QueryOhosAccountInfo(OhosAccountInfo &accountInfo)
191 {
192 auto accountProxy = GetService();
193 if (accountProxy == nullptr) {
194 ACCOUNT_LOGE("Get proxy failed");
195 return ERR_ACCOUNT_COMMON_GET_PROXY;
196 }
197 return accountProxy->QueryOhosAccountInfo(accountInfo.name_, accountInfo.uid_, accountInfo.status_);
198 }
199
GetOhosAccountInfo(OhosAccountInfo & accountInfo)200 ErrCode OhosAccountKitsImpl::GetOhosAccountInfo(OhosAccountInfo &accountInfo)
201 {
202 auto accountProxy = GetService();
203 if (accountProxy == nullptr) {
204 ACCOUNT_LOGE("Get proxy failed");
205 return ERR_ACCOUNT_COMMON_GET_PROXY;
206 }
207
208 auto ret = accountProxy->GetOhosAccountInfo(accountInfo);
209 if (ret == ERR_OK) {
210 ACCOUNT_LOGI("Get ohos account %{public}s.", AnonymizeNameStr(accountInfo.nickname_).c_str());
211 }
212 return ret;
213 }
214
GetOsAccountDistributedInfo(int32_t localId,OhosAccountInfo & accountInfo)215 ErrCode OhosAccountKitsImpl::GetOsAccountDistributedInfo(int32_t localId, OhosAccountInfo &accountInfo)
216 {
217 auto accountProxy = GetService();
218 if (accountProxy == nullptr) {
219 ACCOUNT_LOGE("Get proxy failed");
220 return ERR_ACCOUNT_COMMON_GET_PROXY;
221 }
222
223 auto ret = accountProxy->GetOsAccountDistributedInfo(localId, accountInfo);
224 if (ret == ERR_OK) {
225 ACCOUNT_LOGI("Get distributed ohos account %{public}s.", AnonymizeNameStr(accountInfo.nickname_).c_str());
226 }
227 return ret;
228 }
229
QueryOsAccountDistributedInfo(std::int32_t localId)230 std::pair<bool, OhosAccountInfo> OhosAccountKitsImpl::QueryOsAccountDistributedInfo(std::int32_t localId)
231 {
232 OhosAccountInfo accountInfo;
233 ErrCode result = QueryOsAccountDistributedInfo(localId, accountInfo);
234 return std::make_pair(result == ERR_OK, accountInfo);
235 }
236
QueryOsAccountDistributedInfo(std::int32_t localId,OhosAccountInfo & accountInfo)237 ErrCode OhosAccountKitsImpl::QueryOsAccountDistributedInfo(std::int32_t localId, OhosAccountInfo &accountInfo)
238 {
239 auto accountProxy = GetService();
240 if (accountProxy == nullptr) {
241 ACCOUNT_LOGE("Get proxy failed");
242 return ERR_ACCOUNT_COMMON_GET_PROXY;
243 }
244
245 return accountProxy->QueryOsAccountDistributedInfo(
246 localId, accountInfo.name_, accountInfo.uid_, accountInfo.status_);
247 }
248
QueryDeviceAccountId(std::int32_t & accountId)249 ErrCode OhosAccountKitsImpl::QueryDeviceAccountId(std::int32_t& accountId)
250 {
251 auto accountProxy = GetService();
252 if (accountProxy == nullptr) {
253 ACCOUNT_LOGE("Get proxy failed");
254 return ERR_ACCOUNT_COMMON_GET_PROXY;
255 }
256
257 return accountProxy->QueryDeviceAccountId(accountId);
258 }
259
SubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,const std::shared_ptr<DistributedAccountSubscribeCallback> & callback)260 ErrCode OhosAccountKitsImpl::SubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,
261 const std::shared_ptr<DistributedAccountSubscribeCallback> &callback)
262 {
263 ACCOUNT_LOGI("Subscribe distributed account event in client.");
264 if (callback == nullptr) {
265 ACCOUNT_LOGE("Callback is nullptr.");
266 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
267 }
268
269 auto accountProxy = GetService();
270 if (accountProxy == nullptr) {
271 ACCOUNT_LOGE("Get proxy failed.");
272 return ERR_ACCOUNT_COMMON_GET_PROXY;
273 }
274
275 sptr<IRemoteObject> listener = nullptr;
276 std::lock_guard<std::mutex> lock(eventListenersMutex_);
277 bool needNotifyService = true;
278 std::set<DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE> typeList;
279 DistributedAccountEventService::GetInstance()->GetAllType(typeList);
280 if (typeList.find(type) != typeList.end()) {
281 needNotifyService = false;
282 }
283 ErrCode result = CreateDistributedAccountEventService(type, callback, listener);
284 if (result == ERR_OHOSACCOUNT_KIT_CALLBACK_ALREADY_REGISTERED_ERROR) {
285 ACCOUNT_LOGE("Callback already registered.");
286 return ERR_OK;
287 }
288 if (listener == nullptr) {
289 ACCOUNT_LOGE("Create event service failed.");
290 return ERR_OHOSACCOUNT_KIT_SUBSCRIBE_ERROR;
291 }
292
293 if (!needNotifyService) {
294 return ERR_OK;
295 }
296 result = accountProxy->SubscribeDistributedAccountEvent(static_cast<int32_t>(type), listener);
297 if (result != ERR_OK) {
298 DistributedAccountEventService::GetInstance()->DeleteType(type, callback);
299 }
300 return result;
301 }
302
UnsubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,const std::shared_ptr<DistributedAccountSubscribeCallback> & callback)303 ErrCode OhosAccountKitsImpl::UnsubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,
304 const std::shared_ptr<DistributedAccountSubscribeCallback> &callback)
305 {
306 ACCOUNT_LOGI("Unsubscribe distributed account event in client.");
307 if (callback == nullptr) {
308 ACCOUNT_LOGE("Callback is nullptr.");
309 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
310 }
311
312 auto accountProxy = GetService();
313 if (accountProxy == nullptr) {
314 ACCOUNT_LOGE("Get proxy failed.");
315 return ERR_ACCOUNT_COMMON_GET_PROXY;
316 }
317
318 std::lock_guard<std::mutex> lock(eventListenersMutex_);
319 if (!(DistributedAccountEventService::GetInstance()->IsTypeExist(type, callback))) {
320 ACCOUNT_LOGE("No specified callback has been registered.");
321 return ERR_OHOSACCOUNT_KIT_NO_SPECIFIED_CALLBACK_HAS_BEEN_REGISTERED;
322 }
323 DistributedAccountEventService::GetInstance()->DeleteType(type, callback);
324
325 std::set<DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE> typeList;
326 DistributedAccountEventService::GetInstance()->GetAllType(typeList);
327 if (typeList.find(type) != typeList.end()) {
328 return ERR_OK;
329 }
330
331 ErrCode result = accountProxy->UnsubscribeDistributedAccountEvent(static_cast<int32_t>(type),
332 DistributedAccountEventService::GetInstance()->AsObject());
333 if (result != ERR_OK) {
334 DistributedAccountEventService::GetInstance()->AddType(type, callback);
335 }
336
337 return result;
338 }
339
CreateDistributedAccountEventService(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,const std::shared_ptr<DistributedAccountSubscribeCallback> & callback,sptr<IRemoteObject> & subscribeListener)340 ErrCode OhosAccountKitsImpl::CreateDistributedAccountEventService(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,
341 const std::shared_ptr<DistributedAccountSubscribeCallback> &callback,
342 sptr<IRemoteObject> &subscribeListener)
343 {
344 if (callback == nullptr) {
345 ACCOUNT_LOGE("Callback is nullptr");
346 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
347 }
348
349 if (DistributedAccountEventService::GetInstance()->IsTypeExist(type, callback)) {
350 ACCOUNT_LOGI("Callback already has distributed account event listener.");
351 return ERR_OHOSACCOUNT_KIT_CALLBACK_ALREADY_REGISTERED_ERROR;
352 }
353
354 if (DistributedAccountEventService::GetInstance()->GetCallbackSize() ==
355 Constants::DISTRIBUTED_SUBSCRIBER_MAX_SIZE) {
356 ACCOUNT_LOGE("The maximum number of eventListeners has been reached.");
357 return ERR_OHOSACCOUNT_KIT_SUBSCRIBE_MAX_SIZE_ERROR;
358 }
359
360 subscribeListener = DistributedAccountEventService::GetInstance()->AsObject();
361
362 DistributedAccountEventService::GetInstance()->AddType(type, callback);
363 return ERR_OK;
364 }
365
RestoreSubscribe()366 void OhosAccountKitsImpl::RestoreSubscribe()
367 {
368 auto accountProxy = GetService();
369 if (accountProxy == nullptr) {
370 ACCOUNT_LOGE("Get proxy failed.");
371 return ;
372 }
373
374 std::lock_guard<std::mutex> lock(eventListenersMutex_);
375 std::set<DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE> typeList;
376 DistributedAccountEventService::GetInstance()->GetAllType(typeList);
377 for (const auto &type : typeList) {
378 ErrCode subscribeState = accountProxy->SubscribeDistributedAccountEvent(static_cast<int32_t>(type),
379 DistributedAccountEventService::GetInstance()->AsObject());
380 if (subscribeState != ERR_OK) {
381 ACCOUNT_LOGE("Restore subscribe failed, res=%{public}d.", subscribeState);
382 }
383 }
384 }
385
GetDeviceAccountIdByUID(std::int32_t & uid)386 std::int32_t OhosAccountKitsImpl::GetDeviceAccountIdByUID(std::int32_t& uid)
387 {
388 std::int32_t accountID = uid / UID_TRANSFORM_DIVISOR;
389 return accountID;
390 }
391
SubscribeSystemAbility(const DomainAccountSubscribeSACallbackFunc & callbackFunc)392 ErrCode OhosAccountKitsImpl::SubscribeSystemAbility(const DomainAccountSubscribeSACallbackFunc& callbackFunc)
393 {
394 sptr<ISystemAbilityStatusChange> statusChangeListener =
395 new (std::nothrow) SystemAbilityStatusChangeListener(callbackFunc);
396 if (statusChangeListener == nullptr) {
397 ACCOUNT_LOGE("statusChangeListener is nullptr");
398 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
399 }
400 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
401 if (samgrProxy == NULL) {
402 ACCOUNT_LOGE("samgrProxy is NULL");
403 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
404 }
405 int32_t ret = samgrProxy->SubscribeSystemAbility(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN, statusChangeListener);
406 if (ret != ERR_OK) {
407 ACCOUNT_LOGE("SubscribeSystemAbility is failed");
408 return ret;
409 }
410 return ERR_OK;
411 }
412
GetDomainAccountService()413 sptr<IRemoteObject> OhosAccountKitsImpl::GetDomainAccountService()
414 {
415 auto accountProxy = GetService();
416 if (accountProxy == nullptr) {
417 ACCOUNT_LOGE("Get proxy failed");
418 return nullptr;
419 }
420 sptr<IRemoteObject> result = nullptr;
421 accountProxy->GetDomainAccountService(result);
422 return result;
423 }
424
GetOsAccountService()425 sptr<IRemoteObject> OhosAccountKitsImpl::GetOsAccountService()
426 {
427 auto accountProxy = GetService();
428 if (accountProxy == nullptr) {
429 ACCOUNT_LOGE("Get proxy failed");
430 return nullptr;
431 }
432 sptr<IRemoteObject> result = nullptr;
433 accountProxy->GetOsAccountService(result);
434 return result;
435 }
436
GetAppAccountService()437 sptr<IRemoteObject> OhosAccountKitsImpl::GetAppAccountService()
438 {
439 auto accountProxy = GetService();
440 if (accountProxy == nullptr) {
441 ACCOUNT_LOGE("Get proxy failed");
442 return nullptr;
443 }
444 sptr<IRemoteObject> result = nullptr;
445 accountProxy->GetAppAccountService(result);
446 return result;
447 }
448
GetAccountIAMService()449 sptr<IRemoteObject> OhosAccountKitsImpl::GetAccountIAMService()
450 {
451 auto accountProxy = GetService();
452 if (accountProxy == nullptr) {
453 ACCOUNT_LOGE("Get proxy failed");
454 return nullptr;
455 }
456 sptr<IRemoteObject> result = nullptr;
457 accountProxy->GetAccountIAMService(result);
458 return result;
459 }
460 } // namespace AccountSA
461 } // namespace OHOS
462