1 /*
2  * Copyright (c) 2021-2024 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 #include "os_account_interface.h"
16 
17 #include <cerrno>
18 #include <condition_variable>
19 #include <thread>
20 
21 #include "ability_manager_adapter.h"
22 #include "account_log_wrapper.h"
23 #include "bundle_manager_adapter.h"
24 #ifdef HAS_CES_PART
25 #include "common_event_manager.h"
26 #include "common_event_support.h"
27 #endif // HAS_CES_PART
28 #include "datetime_ex.h"
29 #include "account_hisysevent_adapter.h"
30 #include "hitrace_adapter.h"
31 #include "if_system_ability_manager.h"
32 #include "iservice_registry.h"
33 #ifdef HAS_STORAGE_PART
34 #include "istorage_manager.h"
35 #endif
36 #include "os_account_constants.h"
37 #include "os_account_delete_user_idm_callback.h"
38 #include "os_account_user_callback.h"
39 #include "os_account_subscribe_manager.h"
40 #ifdef HAS_STORAGE_PART
41 #include "storage_manager_proxy.h"
42 #endif
43 #include "iinner_os_account_manager.h"
44 #include "system_ability_definition.h"
45 #ifdef HAS_USER_IDM_PART
46 #include "user_idm_client.h"
47 #endif // HAS_USER_IDM_PART
48 #ifdef HAS_CES_PART
49 #include "want.h"
50 #endif // HAS_CES_PART
51 
52 
53 namespace OHOS {
54 namespace AccountSA {
55 namespace {
56 #ifdef HAS_STORAGE_PART
57 constexpr uint32_t CRYPTO_FLAG_EL1 = 1;
58 constexpr uint32_t CRYPTO_FLAG_EL2 = 2;
59 constexpr int32_t E_ACTIVE_EL2 = 30;
60 #endif
61 
62 constexpr int32_t DELAY_FOR_EXCEPTION = 100;
63 constexpr int32_t MAX_RETRY_TIMES = 10;
64 }
65 
SendToAMSAccountStart(OsAccountInfo & osAccountInfo,const OsAccountStartCallbackFunc & callbackFunc)66 ErrCode OsAccountInterface::SendToAMSAccountStart(OsAccountInfo &osAccountInfo,
67     const OsAccountStartCallbackFunc &callbackFunc)
68 {
69     int32_t localId = osAccountInfo.GetLocalId();
70     ACCOUNT_LOGI("Start OS account %{public}d", localId);
71     sptr<OsAccountUserCallback> osAccountStartUserCallback = new (std::nothrow) OsAccountUserCallback(callbackFunc);
72     if (osAccountStartUserCallback == nullptr) {
73         ACCOUNT_LOGE("alloc memory for start user callback failed!");
74         ReportOsAccountOperationFail(localId, Constants::OPERATION_START,
75             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, "malloc for OsAccountUserCallback failed!");
76         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
77     }
78     StartTraceAdapter("AbilityManagerAdapter StartUser");
79 
80     std::unique_lock<std::mutex> lock(osAccountStartUserCallback->mutex_);
81     ErrCode code = AbilityManagerAdapter::GetInstance()->StartUser(osAccountInfo.GetLocalId(),
82         osAccountStartUserCallback);
83     if (code != ERR_OK) {
84         ACCOUNT_LOGE("AbilityManagerAdapter StartUser failed! errcode is %{public}d", code);
85         ReportOsAccountOperationFail(localId, Constants::OPERATION_ACTIVATE, code,
86             "AbilityManager failed to start user");
87         FinishTraceAdapter();
88         return code;
89     }
90     osAccountStartUserCallback->onStartCondition_.wait(lock);
91     FinishTraceAdapter();
92     if (!osAccountStartUserCallback->isReturnOk_) {
93         ACCOUNT_LOGE("failed to AbilityManagerService in call back");
94         return ERR_OSACCOUNT_SERVICE_INTERFACE_TO_AM_ACCOUNT_START_ERROR;
95     }
96     ACCOUNT_LOGI("end, succeed %{public}d", localId);
97     return code;
98 }
99 
SendToAMSAccountStop(OsAccountInfo & osAccountInfo)100 ErrCode OsAccountInterface::SendToAMSAccountStop(OsAccountInfo &osAccountInfo)
101 {
102     int32_t localId = osAccountInfo.GetLocalId();
103     ACCOUNT_LOGI("Stop OS account %{public}d", localId);
104     sptr<OsAccountUserCallback> osAccountStopUserCallback = new (std::nothrow) OsAccountUserCallback();
105     if (osAccountStopUserCallback == nullptr) {
106         ACCOUNT_LOGE("alloc memory for stop user callback failed!");
107         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP,
108             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, "malloc for OsAccountUserCallback failed!");
109         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
110     }
111     StartTraceAdapter("AbilityManagerAdapter StopUser");
112 
113     std::unique_lock<std::mutex> lock(osAccountStopUserCallback->mutex_);
114     ErrCode code = AbilityManagerAdapter::GetInstance()->StopUser(osAccountInfo.GetLocalId(),
115         osAccountStopUserCallback);
116     if (code != ERR_OK) {
117         ACCOUNT_LOGE("failed to AbilityManagerAdapter stop errcode is %{public}d", code);
118         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP, code,
119             "AbilityManager failed to stop user");
120         FinishTraceAdapter();
121         return code;
122     }
123     osAccountStopUserCallback->onStopCondition_.wait(lock);
124     FinishTraceAdapter();
125     if (!osAccountStopUserCallback->isReturnOk_) {
126         ACCOUNT_LOGE("failed to AbilityManagerService in call back");
127         return ERR_OSACCOUNT_SERVICE_INTERFACE_TO_AM_ACCOUNT_START_ERROR;
128     }
129     ACCOUNT_LOGI("end, succeed %{public}d", localId);
130     return code;
131 }
132 
SendToAMSAccountDeactivate(OsAccountInfo & osAccountInfo)133 ErrCode OsAccountInterface::SendToAMSAccountDeactivate(OsAccountInfo &osAccountInfo)
134 {
135     int32_t localId = osAccountInfo.GetLocalId();
136     ACCOUNT_LOGI("Deactivate OS account %{public}d", localId);
137     StartTraceAdapter("AbilityManagerAdapter LogoutUser");
138     ErrCode code = AbilityManagerAdapter::GetInstance()->LogoutUser(osAccountInfo.GetLocalId());
139     if (code != ERR_OK) {
140         ACCOUNT_LOGE("failed to AbilityManagerAdapter logout errcode is %{public}d", code);
141         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP, code,
142             "AbilityManager failed to logout user");
143     }
144     FinishTraceAdapter();
145     return code;
146 }
147 
148 #ifdef HAS_THEME_SERVICE_PART
InitThemeResource(int32_t localId)149 void OsAccountInterface::InitThemeResource(int32_t localId)
150 {
151     StartTraceAdapter("ThemeManager InitResource");
152     bool ret = ThemeManager::ThemeManagerClient::GetInstance().InitResource(localId);
153     if (!ret) {
154         ACCOUNT_LOGE("Init theme failed, localId=%{public}d.", localId);
155         FinishTraceAdapter();
156         return;
157     }
158     ACCOUNT_LOGI("Init theme successful.");
159     FinishTraceAdapter();
160     return;
161 }
162 #endif
163 
SendToBMSAccountCreate(OsAccountInfo & osAccountInfo,const std::vector<std::string> & disallowedHapList)164 ErrCode OsAccountInterface::SendToBMSAccountCreate(
165     OsAccountInfo &osAccountInfo, const std::vector<std::string> &disallowedHapList)
166 {
167     ErrCode errCode = ERR_OK;
168     int32_t retryTimes = 0;
169     while (retryTimes < MAX_RETRY_TIMES) {
170         errCode = BundleManagerAdapter::GetInstance()->CreateNewUser(osAccountInfo.GetLocalId(), disallowedHapList);
171         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
172             break;
173         }
174         ACCOUNT_LOGE("Fail to SendToBMSAccountCreate, errCode %{public}d.", errCode);
175         retryTimes++;
176         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
177     }
178     return errCode;
179 }
180 
SendToBMSAccountDelete(OsAccountInfo & osAccountInfo)181 ErrCode OsAccountInterface::SendToBMSAccountDelete(OsAccountInfo &osAccountInfo)
182 {
183     return BundleManagerAdapter::GetInstance()->RemoveUser(osAccountInfo.GetLocalId());
184 }
185 
186 #ifdef HAS_USER_IDM_PART
SendToIDMAccountDelete(OsAccountInfo & osAccountInfo)187 ErrCode OsAccountInterface::SendToIDMAccountDelete(OsAccountInfo &osAccountInfo)
188 {
189     std::shared_ptr<OsAccountDeleteUserIdmCallback> callback = std::make_shared<OsAccountDeleteUserIdmCallback>();
190     if (callback == nullptr) {
191         ACCOUNT_LOGE("get idm callback ptr failed! insufficient memory!");
192         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
193             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR,
194             "Failed to malloc for OsAccountDeleteUserIdmCallback");
195         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
196     }
197     StartTraceAdapter("UserIDMClient EnforceDelUser");
198     int32_t ret = UserIam::UserAuth::UserIdmClient::GetInstance().EraseUser(osAccountInfo.GetLocalId(), callback);
199     if (ret != 0) {
200         ACCOUNT_LOGE("idm enforce delete user failed! error %{public}d", ret);
201         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE, ret,
202             "UserIDM failed to erase user");
203         FinishTraceAdapter();
204         return ERR_OK;    // do not return fail
205     }
206 
207     // wait callback
208     struct tm startTime = {0};
209     struct tm nowTime = {0};
210     OHOS::GetSystemCurrentTime(&startTime);
211     OHOS::GetSystemCurrentTime(&nowTime);
212     while (OHOS::GetSecondsBetween(startTime, nowTime) < Constants::TIME_WAIT_TIME_OUT &&
213         !callback->isIdmOnResultCallBack_) {
214         std::this_thread::sleep_for(std::chrono::milliseconds(Constants::WAIT_ONE_TIME));
215         OHOS::GetSystemCurrentTime(&nowTime);
216     }
217     if (!callback->isIdmOnResultCallBack_) {
218         ACCOUNT_LOGE("idm did not call back! timeout!");
219         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE, -1,
220             "UserIDM erase user timeout");
221         FinishTraceAdapter();
222         return ERR_OK;    // do not return fail
223     }
224     ACCOUNT_LOGI("send to idm account delete and get callback succeed!");
225     FinishTraceAdapter();
226     return ERR_OK;
227 }
228 #endif // HAS_USER_IDM_PART
229 
SendToCESAccountCreate(OsAccountInfo & osAccountInfo)230 void OsAccountInterface::SendToCESAccountCreate(OsAccountInfo &osAccountInfo)
231 {
232     int osAccountID = osAccountInfo.GetLocalId();
233 #ifdef HAS_CES_PART
234     StartTraceAdapter("PublishCommonEvent account create");
235     OHOS::AAFwk::Want want;
236     want.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_ADDED);
237     OHOS::EventFwk::CommonEventData data;
238     data.SetCode(osAccountID);
239     data.SetWant(want);
240     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
241         ACCOUNT_LOGE("PublishCommonEvent for create account %{public}d failed!", osAccountID);
242         ReportOsAccountOperationFail(osAccountID, Constants::OPERATION_CREATE, -1, "PublishCommonEvent failed!");
243     } else {
244         ACCOUNT_LOGI("PublishCommonEvent for create account %{public}d succeed!", osAccountID);
245     }
246     FinishTraceAdapter();
247 #else // HAS_CES_PART
248     ACCOUNT_LOGI("No common event part, do not publish for account %{public}d create!", osAccountID);
249 #endif // HAS_CES_PART
250 }
251 
SendToCESAccountDelete(OsAccountInfo & osAccountInfo)252 void OsAccountInterface::SendToCESAccountDelete(OsAccountInfo &osAccountInfo)
253 {
254     int osAccountID = osAccountInfo.GetLocalId();
255 #ifdef HAS_CES_PART
256     StartTraceAdapter("PublishCommonEvent account delete");
257     OHOS::AAFwk::Want want;
258     want.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED);
259     OHOS::EventFwk::CommonEventData data;
260     data.SetCode(osAccountID);
261     data.SetWant(want);
262     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
263         ACCOUNT_LOGE("PublishCommonEvent for delete account %{public}d failed!", osAccountID);
264         ReportOsAccountOperationFail(osAccountID, Constants::OPERATION_REMOVE, -1, "Failed to publish common event");
265     } else {
266         ACCOUNT_LOGI("PublishCommonEvent for delete account %{public}d succeed!", osAccountID);
267     }
268     FinishTraceAdapter();
269 #else // HAS_CES_PART
270     ACCOUNT_LOGI("No common event part, do not publish for account %{public}d delete!", osAccountID);
271 #endif // HAS_CES_PART
272 }
273 
PublishCommonEvent(const OsAccountInfo & osAccountInfo,const std::string & commonEvent,const std::string & operation)274 void OsAccountInterface::PublishCommonEvent(
275     const OsAccountInfo &osAccountInfo, const std::string &commonEvent, const std::string &operation)
276 {
277     int osAccountID = osAccountInfo.GetLocalId();
278 #ifdef HAS_CES_PART
279     StartTraceAdapter("PublishCommonEvent account");
280     OHOS::AAFwk::Want want;
281     want.SetAction(commonEvent);
282     OHOS::EventFwk::CommonEventData data;
283     data.SetCode(osAccountID);
284     data.SetWant(want);
285     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
286         ACCOUNT_LOGE("PublishCommonEvent %{public}d failed!", osAccountID);
287         ReportOsAccountOperationFail(osAccountID, operation, -1, "PublishCommonEvent failed!");
288     } else {
289         ACCOUNT_LOGI("PublishCommonEvent %{public}d succeed!", osAccountID);
290     }
291     FinishTraceAdapter();
292 #else  // HAS_CES_PART
293     ACCOUNT_LOGI("No common event part, do not publish for account %{public}d!", osAccountID);
294 #endif // HAS_CES_PART
295 }
296 
SendToCESAccountSwitched(int newId,int oldId)297 void OsAccountInterface::SendToCESAccountSwitched(int newId, int oldId)
298 {
299 #ifdef HAS_CES_PART
300     StartTraceAdapter("PublishCommonEvent account switched");
301     OHOS::AAFwk::Want want;
302     want.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
303     want.SetParam("oldId", std::to_string(oldId));
304     OHOS::EventFwk::CommonEventData data;
305     data.SetCode(newId);
306     data.SetWant(want);
307     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
308         ACCOUNT_LOGE("PublishCommonEvent failed, account switched:%{public}d->%{public}d", oldId, newId);
309         ReportOsAccountOperationFail(newId, Constants::OPERATION_SWITCH, -1, "PublishCommonEvent switched failed!");
310     } else {
311         ACCOUNT_LOGI("PublishCommonEvent successful, account switched:%{public}d->%{public}d", oldId, newId);
312     }
313     FinishTraceAdapter();
314 #else // HAS_CES_PART
315     ACCOUNT_LOGI("No common event part, do not publish for account switched:%{public}d->%{public}d", oldId, newId);
316 #endif // HAS_CES_PART
317 }
318 
SendToStorageAccountCreate(OsAccountInfo & osAccountInfo)319 ErrCode OsAccountInterface::SendToStorageAccountCreate(OsAccountInfo &osAccountInfo)
320 {
321     ErrCode errCode = ERR_OK;
322     int32_t retryTimes = 0;
323     while (retryTimes < MAX_RETRY_TIMES) {
324         errCode = InnerSendToStorageAccountCreate(osAccountInfo);
325         if (errCode != Constants::E_IPC_ERROR && errCode != Constants::E_IPC_SA_DIED) {
326             break;
327         }
328         ACCOUNT_LOGE("Fail to SendToStorageAccountCreate,id=%{public}d, errCode %{public}d.",
329             osAccountInfo.GetLocalId(), errCode);
330         retryTimes++;
331         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
332     }
333     return errCode;
334 }
335 
336 #ifdef HAS_STORAGE_PART
PrepareAddUser(const sptr<StorageManager::IStorageManager> & proxy,int32_t userId)337 static ErrCode PrepareAddUser(const sptr<StorageManager::IStorageManager> &proxy, int32_t userId)
338 {
339     ErrCode err = proxy->PrepareAddUser(userId, CRYPTO_FLAG_EL1 | CRYPTO_FLAG_EL2);
340     if (err == 0) {
341         return ERR_OK;
342     }
343     ReportOsAccountOperationFail(userId, Constants::OPERATION_CREATE, err, "StorageManager failed to add user");
344     if (err == -EEXIST) {
345         return ERR_OK;
346     }
347     return err;
348 }
349 #endif
350 
InnerSendToStorageAccountCreate(OsAccountInfo & osAccountInfo)351 ErrCode OsAccountInterface::InnerSendToStorageAccountCreate(OsAccountInfo &osAccountInfo)
352 {
353 #ifdef HAS_STORAGE_PART
354     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
355     int32_t localId = osAccountInfo.GetLocalId();
356     if (!systemAbilityManager) {
357         ACCOUNT_LOGE("failed to get system ability mgr.");
358         ReportOsAccountOperationFail(localId, Constants::OPERATION_CREATE,
359             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
360             "GetSystemAbilityManager for storage failed!");
361         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
362     }
363     auto remote = systemAbilityManager->CheckSystemAbility(STORAGE_MANAGER_MANAGER_ID);
364     if (!remote) {
365         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID service.");
366         ReportOsAccountOperationFail(localId, Constants::OPERATION_CREATE,
367             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
368             "CheckSystemAbility for storage failed!");
369         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
370     }
371     auto proxy = iface_cast<StorageManager::IStorageManager>(remote);
372     if (!proxy) {
373         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
374         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
375     }
376     StartTraceAdapter("StorageManager PrepareAddUser");
377     ErrCode err = PrepareAddUser(proxy, localId);
378     if (err == ERR_OK) {
379         FinishTraceAdapter();
380         return ERR_OK;
381     }
382 
383     ACCOUNT_LOGI("PrepareAddUser Failed, start check and clean accounts.");
384     auto &osAccountManager = IInnerOsAccountManager::GetInstance();
385     if (osAccountManager.CleanGarbageOsAccounts(localId) <= 0) {
386         FinishTraceAdapter();
387         return err;
388     }
389     ACCOUNT_LOGI("Clean garbage account data, Retry Storage PrepareAddUser.");
390     err = PrepareAddUser(proxy, localId);
391     FinishTraceAdapter();
392     return err;
393 #endif
394     return ERR_OK;
395 }
396 
SendToStorageAccountRemove(OsAccountInfo & osAccountInfo)397 ErrCode OsAccountInterface::SendToStorageAccountRemove(OsAccountInfo &osAccountInfo)
398 {
399     ACCOUNT_LOGI("start");
400 #ifdef HAS_STORAGE_PART
401     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
402     if (!systemAbilityManager) {
403         ACCOUNT_LOGE("failed to get system ability mgr.");
404         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
405             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
406             "Failed to get SystemAbilityManager");
407         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
408     }
409     auto remote = systemAbilityManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
410     if (!remote) {
411         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID service.");
412         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
413             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
414             "Failed to get StorageManager service");
415         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
416     }
417     auto proxy = iface_cast<StorageManager::IStorageManager>(remote);
418     if (!proxy) {
419         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
420         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
421     }
422 
423     StartTraceAdapter("StorageManager RemoveUser");
424     int err = proxy->RemoveUser(osAccountInfo.GetLocalId(),
425         CRYPTO_FLAG_EL1 | CRYPTO_FLAG_EL2);
426     if (err != 0) {
427         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
428             err, "StorageManager failed to remove user");
429         ACCOUNT_LOGE("Storage RemoveUser failed, ret %{public}d", err);
430         FinishTraceAdapter();
431         return err;
432     }
433 
434     ACCOUNT_LOGI("end, Storage RemoveUser ret %{public}d.", err);
435     FinishTraceAdapter();
436 #endif
437     return ERR_OK;
438 }
439 
440 #ifdef HAS_STORAGE_PART
GetStorageProxy(sptr<StorageManager::IStorageManager> & proxy)441 static ErrCode GetStorageProxy(sptr<StorageManager::IStorageManager> &proxy)
442 {
443     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
444     if (!systemAbilityManager) {
445         ACCOUNT_LOGE("failed to get system ability mgr.");
446         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
447     }
448     auto remote = systemAbilityManager->CheckSystemAbility(STORAGE_MANAGER_MANAGER_ID);
449     if (!remote) {
450         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID service.");
451         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
452     }
453     proxy = iface_cast<StorageManager::IStorageManager>(remote);
454     return ERR_OK;
455 }
456 #endif
457 
SendToStorageAccountStart(OsAccountInfo & osAccountInfo)458 ErrCode OsAccountInterface::SendToStorageAccountStart(OsAccountInfo &osAccountInfo)
459 {
460     ACCOUNT_LOGI("start");
461     bool isUserUnlocked = false;
462 #ifdef HAS_STORAGE_PART
463     sptr<StorageManager::IStorageManager> proxy = nullptr;
464     if (GetStorageProxy(proxy) != ERR_OK) {
465         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
466         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_ACTIVATE,
467             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER, "Failed to get StorageManager service");
468         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
469     }
470     StartTraceAdapter("StorageManager PrepareStartUser");
471     std::vector<uint8_t> emptyData;
472     int32_t err = proxy->ActiveUserKey(osAccountInfo.GetLocalId(), emptyData, emptyData);
473     ACCOUNT_LOGI("Storage ActiveUserKey end, ret %{public}d.", err);
474     if (err == 0) {
475         isUserUnlocked = true;
476     }
477     if (err != E_ACTIVE_EL2) {
478         err = proxy->PrepareStartUser(osAccountInfo.GetLocalId());
479         if (err != 0) {
480             ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_ACTIVATE,
481                 err, "Storage PrepareStartUser failed!");
482         }
483     }
484     ACCOUNT_LOGI("end, Storage PrepareStartUser ret %{public}d.", err);
485     FinishTraceAdapter();
486 #else
487     isUserUnlocked = true;
488 #endif
489     if (!osAccountInfo.GetIsVerified() && isUserUnlocked) {
490         osAccountInfo.SetIsVerified(true);
491         bool hasCredential = osAccountInfo.GetCredentialId() > 0;
492         if (!hasCredential) {
493             osAccountInfo.SetIsLoggedIn(true);
494             osAccountInfo.SetLastLoginTime(std::chrono::duration_cast<std::chrono::seconds>(
495                 std::chrono::system_clock::now().time_since_epoch()).count());
496         }
497     }
498     ACCOUNT_LOGI("end, succeed!");
499     return ERR_OK;
500 }
501 
SendToStorageAccountStop(OsAccountInfo & osAccountInfo)502 ErrCode OsAccountInterface::SendToStorageAccountStop(OsAccountInfo &osAccountInfo)
503 {
504     ACCOUNT_LOGI("Stop storage, account id = %{public}d", osAccountInfo.GetLocalId());
505 #ifdef HAS_STORAGE_PART
506     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
507     if (!systemAbilityManager) {
508         ACCOUNT_LOGE("failed to get system ability mgr.");
509         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
510             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
511             "GetSystemAbilityManager for storage failed!");
512         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
513     }
514     auto remote = systemAbilityManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
515     if (!remote) {
516         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID service.");
517         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
518             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
519             "GetSystemAbility for storage failed!");
520         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
521     }
522     auto proxy = iface_cast<StorageManager::IStorageManager>(remote);
523     if (!proxy) {
524         ACCOUNT_LOGE("failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
525         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
526     }
527     StartTraceAdapter("StorageManager StopUser");
528     int localId = osAccountInfo.GetLocalId();
529     int err = proxy->StopUser(localId);
530     if (err != 0) {
531         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
532             err, "StorageManager failed to stop user");
533     }
534     err = proxy->InactiveUserKey(localId);
535     if (err != 0) {
536         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
537             err, "StorageManager failed to inactivate user key");
538     }
539     FinishTraceAdapter();
540 #endif
541     osAccountInfo.SetIsVerified(false);
542     return ERR_OK;
543 }
544 
SendToStorageAccountCreateComplete(int32_t localId)545 ErrCode OsAccountInterface::SendToStorageAccountCreateComplete(int32_t localId)
546 {
547     ErrCode errCode = ERR_OK;
548     int32_t retryTimes = 0;
549     while (retryTimes < MAX_RETRY_TIMES) {
550         errCode = InnerSendToStorageAccountCreateComplete(localId);
551         if (errCode == ERR_OK) {
552             break;
553         }
554         ACCOUNT_LOGE("Fail to complete account, localId=%{public}d, errCode=%{public}d.", localId, errCode);
555         retryTimes++;
556         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
557     }
558     return errCode;
559 }
560 
InnerSendToStorageAccountCreateComplete(int32_t localId)561 ErrCode OsAccountInterface::InnerSendToStorageAccountCreateComplete(int32_t localId)
562 {
563 #ifdef HAS_STORAGE_PART
564     sptr<StorageManager::IStorageManager> proxy = nullptr;
565     if (GetStorageProxy(proxy) != ERR_OK) {
566         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
567         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
568     }
569     StartTraceAdapter("StorageManager CompleteAddUser");
570     int errCode = proxy->CompleteAddUser(localId);
571     if (errCode != 0) {
572         ACCOUNT_LOGE("Failed to CompleteAddUser, localId=%{public}d, errCode=%{public}d", localId, errCode);
573         ReportOsAccountOperationFail(localId, Constants::OPERATION_CREATE, errCode,
574             "StorageManager failed to complete add user");
575         return errCode;
576     }
577     FinishTraceAdapter();
578 #endif
579     return ERR_OK;
580 }
581 }  // namespace AccountSA
582 }  // namespace OHOS
583