OpenHarmony 源碼解析之賬號子系統(tǒng)
1 簡介
在標準系統(tǒng)上,賬號子系統(tǒng)主要提供分布式帳號登錄狀態(tài)管理能力,支持在端側(cè)對接廠商云帳號應用,提供云帳號登錄狀態(tài)查詢和更新的管理能力
1.1 OpenHarmony架構圖

1.2 賬號子系統(tǒng)架構圖

1.3 賬號子系統(tǒng)目錄結(jié)構
- /base/account/os_account
- ├── frameworks
- │ ├── appaccount # 應用賬號kit代碼
- │ ├── ohosaccount # 云賬號kit代碼
- │ ├── common # 共通基礎代碼
- │ │ ├── account_error # 錯誤碼
- │ │ ├── database # 數(shù)據(jù)庫基礎代碼
- │ │ ├── log # 打印日志代碼
- │ │ └── perf_stat # 性能統(tǒng)計
- ├── interfaces
- │ ├── innerkits
- │ │ ├── appaccount # 應用賬號內(nèi)部接口
- │ │ ├── ohosaccount # 云賬號內(nèi)部接口
- │ └── kits
- │ └── napi
- │ ├── appaccount # 應用賬號對外接口
- │ └── distributedaccount # 分布式賬號對外接口
- ├── sa_profile # 帳號SA配置文件定義目錄
- └── services
- └── accountmgr # 帳號管理服務
2 賬號管理服務的啟動
2.1 rc啟動服務
- #base\account\os_account\services\accountmgr\accountmgr.rc
- on post-fs-data
- start accountmgr
- service accountmgr /system/bin/sa_main /system/profile/accountmgr.xml
- class z_core
- user system
- group system shell
- seclabel u:r:accountmgr:s0
- writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks /dev/blkio/foreground/tasks
2.1.1 rc文件結(jié)構解析
rc文件是以模塊為單位的,模塊分為3種類型:on、service、import
- import: 導入其它的rc文件
- on: 執(zhí)行chown、mkdir、write、export、symlink等簡單的shell指令,如:
- on post-fs-data
- start accountmgr
post-fs-data將一個section里的所有命令加入到一個執(zhí)行隊列,在未來的某個時候會順序執(zhí)行隊列里的命令
- service: 執(zhí)行可執(zhí)行程序,如:
- service accountmgr /system/bin/sa_main /system/profile/accountmgr.xml
- class z_core
- user system
- group system shell
- seclabel u:r:accountmgr:s0
- writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks /dev/blkio/foreground/tasks
accountmgr為可執(zhí)行程序名
/system/bin/sa_main /system/profile/accountmgr.xml為可執(zhí)行文件的路徑
class、user、group、seclabel、writepid這些關鍵字所對應的行是用來描述service一些特點,不同的service有著不同的特點
service什么時候被執(zhí)行?
在某個on模塊的指令里會存在“class_start”,例如:
- class_start core
- class_start main
- on nonencrypted
- class_start late_start
當執(zhí)行到這里是service模塊就會被調(diào)用
2.2 AccountMgrService的啟動流程

2.2.1 AccountMgrService通過OnStart調(diào)用Init
- AccountMgrService繼承自SystemAbility,當應用啟動時首先應用程序框架會調(diào)用AccountMgrService的生命周期函數(shù)OnStart();
- OnStart()首先判斷服務運行狀態(tài)是否已經(jīng)開啟,如果沒有開啟,則調(diào)用Init()進行初始化操作
- 初始化操作完成并返回true給OnStart()后,服務運行狀態(tài)則更新為開啟狀態(tài)
- //base\account\os_account\services\accountmgr\src\account_mgr_service.cpp
- void AccountMgrService::OnStart()
- {
- //判斷服務運行狀態(tài)是否已經(jīng)開啟
- if (state_ == ServiceRunningState::STATE_RUNNING) {
- ACCOUNT_LOGI("AccountMgrService has already started.");
- return;
- }
- PerfStat::GetInstance().SetInstanceStartTime(GetTickCount());
- ACCOUNT_LOGI("start is triggered");
- //如果服務運行狀態(tài)沒有開啟,則調(diào)用Init()進行初始化操作
- if (!Init()) {
- ACCOUNT_LOGE("failed to init AccountMgrService");
- return;
- }
- //初始化操作完成并返回true給OnStart()后,服務運行狀態(tài)則更新為開啟狀態(tài)
- state_ = ServiceRunningState::STATE_RUNNING;
- ACCOUNT_LOGI("AccountMgrService::OnStart start service success.");
- }
2.2.2 AccountMgrService的Init()實現(xiàn)
- Init()被調(diào)用后,依然要先判斷服務運行狀態(tài)是否已經(jīng)開啟
- 隨后,檢查DEVICE_OWNER_DIR是否存在,如果不存在就強制創(chuàng)建
- 如果服務還沒有被注冊,則調(diào)用Publish()來注冊服務,Publish()執(zhí)行成功后,標記服務已經(jīng)被注冊
- 創(chuàng)建OhosAccountManager對象,并調(diào)用它的OnInitialize方法
- //base\account\os_account\services\accountmgr\src\account_mgr_service.cpp
- bool AccountMgrService::Init()
- {
- //判斷服務運行狀態(tài)是否已經(jīng)開啟
- if (state_ == ServiceRunningState::STATE_RUNNING) {
- ACCOUNT_LOGW("Service is already running!");
- return false;
- }
- //檢查DEVICE_OWNER_DIR是否存在,如果不存在就強制創(chuàng)建
- if (!OHOS::FileExists(DEVICE_OWNER_DIR)) {
- ACCOUNT_LOGI("Device owner dir not exist, create!");
- if (!OHOS::ForceCreateDirectory(DEVICE_OWNER_DIR)) {
- ACCOUNT_LOGW("Create device owner dir failure!");
- }
- }
- bool ret = false;
- //如果服務還沒有被注冊,則調(diào)用Publish()來注冊服務,Publish()執(zhí)行成功后,標記服務已經(jīng)被注冊
- if (!registerToService_) {
- ret = Publish(&DelayedRefSingleton<AccountMgrService>::GetInstance());
- if (!ret) {
- HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCOUNT, "AccountServiceStartFailed",
- HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_TYPE", ERR_ACCOUNT_MGR_ADD_TO_SA_ERROR);
- ACCOUNT_LOGE("AccountMgrService::Init Publish failed!");
- return false;
- }
- registerToService_ = true;
- }
- PerfStat::GetInstance().SetInstanceInitTime(GetTickCount());
- //創(chuàng)建OhosAccountManager對象
- ohosAccountMgr_ = std::make_shared<OhosAccountManager>();
- //調(diào)用OhosAccountManager的OnInitialize方法
- ret = ohosAccountMgr_->OnInitialize();
- if (!ret) {
- ACCOUNT_LOGE("Ohos account manager initialize failed");
- HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCOUNT, "AccountServiceStartFailed",
- HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_TYPE", ret);
- return ret;
- }
- dumpHelper_ = std::make_unique<AccountDumpHelper>(ohosAccountMgr_);
- IAccountContext::SetInstance(this);
- ACCOUNT_LOGI("init end success");
- return true;
- }
2.2.3 OhosAccountManager的初始化
- OhosAccountManager::OnInitialize首先調(diào)用BuildEventsMapper()進行事件映射,查看BuildEventsMapper()實現(xiàn)可發(fā)現(xiàn),寫死的事件有賬號登入、登出、注銷和Token失效,并與對應的方法綁定
- 組織賬號配置文件路徑,作為參數(shù)創(chuàng)建OhosAccountDataDeal對象,并調(diào)用它的Init方法,查看Init()實現(xiàn)可發(fā)現(xiàn),Init()讀取賬號配置文件并保存到jsonData_中
- 調(diào)用AccountInfoFromJson()獲取賬號信息并保存到currentAccount_中
- //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp
- bool OhosAccountManager::OnInitialize()
- {
- accountState_ = std::make_unique<AccountStateMachine>();
- //事件映射
- BuildEventsMapper();
- //組織賬號配置文件路徑
- std::int32_t userId = GetUserId();
- std::string filePath;
- filePath.append(ACCOUNT_CFG_DIR_ROOT_PATH).append(std::to_string(userId)).append(ACCOUNT_CFG_FILE_NAME);
- //創(chuàng)建OhosAccountDataDeal對象
- dataDealer_ = std::make_unique<OhosAccountDataDeal>(filePath);
- std::int32_t tryTimes = 0;
- while (tryTimes < MAX_RETRY_TIMES) {
- tryTimes++;
- //調(diào)用ohos_account_data_deal的Init方法
- ErrCode errCode = dataDealer_->Init();
- if (errCode == ERR_OK) {
- break;
- }
- // when json file corrupted, have it another try
- if ((tryTimes == MAX_RETRY_TIMES) || (errCode != ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION)) {
- ACCOUNT_LOGE("parse json file failed: %{public}d, tryTime: %{public}d", errCode, tryTimes);
- eventMap_.clear();
- eventFuncMap_.clear();
- return false;
- }
- }
- // get account info from config file
- dataDealer_->AccountInfoFromJson(currentAccount_);
- accountState_->SetAccountState(currentAccount_.ohosAccountStatus_);
- return true;
- }
2.2.4 OhosAccountManager::BuildEventsMapper()
- OhosAccountManager::BuildEventsMapper()將賬號登入、登出、注銷和Token失效四個事件與相應的處理函數(shù)綁定
- //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp
- void OhosAccountManager::BuildEventsMapper()
- {
- eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGIN,
- ACCOUNT_BIND_SUCCESS_EVT));
- eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGOUT,
- ACCOUNT_MANUAL_UNBOUND_EVT));
- eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_TOKEN_INVALID,
- ACCOUNT_TOKEN_EXPIRED_EVT));
- eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGOFF,
- ACCOUNT_MANUAL_LOGOFF_EVT));
- eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGIN, &OhosAccountManager::LoginOhosAccount));
- eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGOUT, &OhosAccountManager::LogoutOhosAccount));
- eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGOFF, &OhosAccountManager::LogoffOhosAccount));
- eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_TOKEN_INVALID,
- &OhosAccountManager::HandleOhosAccountTokenInvalidEvent));
- }
2.2.5 ohos_account_data_deal的Init()實現(xiàn)
- OhosAccountDataDeal::Init()首先檢查賬號配置文件存不存在,如果不存在則創(chuàng)建,如果存在則讀取賬號配置文件內(nèi)容并保存到jsonData_中
- //base\account\os_account\services\accountmgr\src\ohos_account_data_deal.cpp
- ErrCode OhosAccountDataDeal::Init()
- {
- if (!FileExists(configFile_)) {
- ACCOUNT_LOGI("file %{public}s not exist, create!", configFile_.c_str());
- BuildJsonFileFromScratch();
- }
- std::ifstream fin(configFile_);
- if (!fin) {
- ACCOUNT_LOGE("Failed to open file %{public}s", configFile_.c_str());
- return ERR_ACCOUNT_DATADEAL_INPUT_FILE_ERROR;
- }
- // NOT-allow exceptions when parse json file
- nlohmann::json jsonData = json::parse(fin, nullptr, false);
- if (!jsonData.is_structured()) {
- ACCOUNT_LOGE("Invalid json file, remove");
- fin.close();
- if (RemoveFile(configFile_)) {
- ACCOUNT_LOGE("Remove invalid json file failed");
- }
- return ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION;
- }
- // jsonData_ keeps well-structured json key-values
- jsonData_ = jsonData;
- initOk_ = true;
- fin.close();
- return ERR_OK;
- }
3 分布式賬號模塊接口說明
分布式帳號模塊的功能主要包括獲取、查詢和更新分布式賬號信息,僅支持系統(tǒng)應用
在分布式賬號模塊的初始化中,可發(fā)現(xiàn)以下函數(shù)的注冊:
- //base\account\os_account\interfaces\kits\napi\distributedaccount\src\napi_distributed_account.cpp
- napi_value NapiDistributedAccount::Init(napi_env env, napi_value exports)
- {
- ACCOUNT_LOGI("enter");
- napi_property_descriptor descriptor[] = {
- DECLARE_NAPI_FUNCTION("getDistributedAccountAbility", GetDistributedAccountAbility),
- };
- napi_define_properties(env, exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor);
- napi_property_descriptor properties[] = {
- DECLARE_NAPI_FUNCTION("queryOsAccountDistributedInfo", QueryOhosAccountInfo),
- DECLARE_NAPI_FUNCTION("updateOsAccountDistributedInfo", UpdateOsAccountDistributedInfo),
- };
- napi_value cons = nullptr;
- napi_define_class(env, DISTRIBUTED_ACCOUNT_CLASS_NAME.c_str(), DISTRIBUTED_ACCOUNT_CLASS_NAME.size(),
- JsConstructor, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons);
- napi_create_reference(env, cons, 1, &constructorRef_);
- napi_set_named_property(env, exports, DISTRIBUTED_ACCOUNT_CLASS_NAME.c_str(), cons);
- return exports;
- }
4 分布式賬號模塊接口調(diào)用流程
這里以queryOsAccountDistributedInfo為例,來分析調(diào)用流程:


NapiDistributedAccount::QueryOhosAccountInfo實際調(diào)用的是OhosAccountKits::GetInstance().QueryOhosAccountInfo()
- //base\account\os_account\interfaces\kits\napi\distributedaccount\src\napi_distributed_account.cpp
- napi_value NapiDistributedAccount::QueryOhosAccountInfo(napi_env env, napi_callback_info cbInfo)
- {
- ......
- napi_create_async_work(
- env, nullptr, resource,
- [](napi_env env, void *data) {
- DistributedAccountAsyncContext *asyncContext = (DistributedAccountAsyncContext*)data;
- std::pair<bool, OhosAccountInfo> accountInfo = OhosAccountKits::GetInstance().QueryOhosAccountInfo();
- ......
- return result;
- }
OhosAccountKitsImpl::QueryOhosAccountInfo()實際調(diào)用的是AccountProxy::QueryOhosAccountInfo()
- //base\account\os_account\interfaces\innerkits\ohosaccount\native\src\ohos_account_kits_impl.cpp
- std::pair<bool, OhosAccountInfo> OhosAccountKitsImpl::QueryOhosAccountInfo()
- {
- auto accountProxy = GetService();
- if (accountProxy == nullptr) {
- ACCOUNT_LOGE("Get proxy failed");
- return std::make_pair(false, OhosAccountInfo());
- }
- //調(diào)用AccountProxy::QueryOhosAccountInfo()
- return accountProxy->QueryOhosAccountInfo();
- }
AccountProxy::QueryOhosAccountInfo()調(diào)用SendRequest()發(fā)送QUERY_OHOS_ACCOUNT_INFO請求
- //base\account\os_account\frameworks\ohosaccount\native\src\account_proxy.cpp
- std::pair<bool, OhosAccountInfo> AccountProxy::QueryOhosAccountInfo(void)
- {
- ...
- //調(diào)用SendRequest()發(fā)送QUERY_OHOS_ACCOUNT_INFO請求
- auto ret = Remote()->SendRequest(QUERY_OHOS_ACCOUNT_INFO, data, reply, option);
- if (ret != ERR_NONE) {
- ACCOUNT_LOGE("SendRequest failed %d", ret);
- return std::make_pair(false, OhosAccountInfo());
- }
- ...
- return std::make_pair(true, OhosAccountInfo(Str16ToStr8(name), Str16ToStr8(uid), status));
- }
我們看看它的對端AccountStub::OnRemoteRequest是如何處理發(fā)送端的請求并返回什么樣的結(jié)果的:
從stubFuncMap_匹配請求碼,然后獲取stubFuncMap_的第二項來處理請求
- //base\account\os_account\services\accountmgr\src\account_stub.cpp
- std::int32_t AccountStub::OnRemoteRequest(std::uint32_t code, MessageParcel &data,
- MessageParcel &reply, MessageOption &option)
- {
- ...
- //從stubFuncMap_匹配請求碼
- const auto &itFunc = stubFuncMap_.find(code);
- if (itFunc != stubFuncMap_.end()) {
- return (this->*(itFunc->second))(data, reply);
- }
- ACCOUNT_LOGW("remote request unhandled: %{public}d", code);
- return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
- }
我們來看看stubFuncMap_長啥樣:
很容易看出,QUERY_OHOS_ACCOUNT_INFO請求碼對應的是AccountStub::CmdQueryOhosAccountInfo()
- //base\account\os_account\services\accountmgr\src\account_stub.cpp
- const std::map<std::uint32_t, AccountStubFunc> AccountStub::stubFuncMap_ {
- std::make_pair(UPDATE_OHOS_ACCOUNT_INFO, &AccountStub::CmdUpdateOhosAccountInfo),
- std::make_pair(QUERY_OHOS_ACCOUNT_INFO, &AccountStub::CmdQueryOhosAccountInfo),
- std::make_pair(QUERY_OHOS_ACCOUNT_QUIT_TIPS, &AccountStub::CmdQueryOhosQuitTips),
- std::make_pair(QUERY_DEVICE_ACCOUNT_ID, &AccountStub::CmdQueryDeviceAccountId),
- std::make_pair(QUERY_DEVICE_ACCOUNT_ID_FROM_UID, &AccountStub::CmdQueryDeviceAccountIdFromUid),
- };
我們看看AccountStub::CmdQueryOhosAccountInfo()的實現(xiàn):
- CmdQueryOhosAccountInfo()中首先檢查調(diào)用的進程是不是root或者system,從這可以看出,Account的相關接口只有系統(tǒng)用戶才能使用
- 接著檢查是否有PERMISSION_MANAGE_USERS權限
- 然后獲取AccountInfo的其實是QueryOhosAccountInfo(),它的實現(xiàn)是在AccountMgrService里面
- //base\account\os_account\services\accountmgr\src\account_stub.cpp
- std::int32_t AccountStub::CmdQueryOhosAccountInfo(MessageParcel &data, MessageParcel &reply)
- {
- //檢查調(diào)用的進程是不是root或者system
- //檢查是否有PERMISSION_MANAGE_USERS權限
- if (!IsRootOrSystemAccount() && !HasAccountRequestPermission(PERMISSION_MANAGE_USERS)) {
- ACCOUNT_LOGE("Check permission failed");
- return ERR_ACCOUNT_ZIDL_CHECK_PERMISSION_ERROR;
- }
- //調(diào)用AccountMgrService::QueryOhosAccountInfo
- std::pair<bool, OhosAccountInfo> info = QueryOhosAccountInfo();
- if (!info.first) {
- ACCOUNT_LOGE("Query ohos account info failed");
- return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR;
- }
- ...
- return ERR_OK;
- }
在AccountMgrService::QueryOhosAccountInfo()里調(diào)用OhosAccountManager的GetAccountInfo()
- //base\account\os_account\services\accountmgr\src\account_mgr_service.cpp
- std::pair<bool, OhosAccountInfo> AccountMgrService::QueryOhosAccountInfo(void)
- {
- //調(diào)用OhosAccountManager::GetAccountInfo
- AccountInfo accountInfo = ohosAccountMgr_->GetAccountInfo();
- if (accountInfo.ohosAccountUid_.empty()) {
- ACCOUNT_LOGE("invalid id");
- accountInfo.clear();
- }
- ...
- return std::make_pair(true, OhosAccountInfo(name, id, status));
- }
- //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp
- AccountInfo OhosAccountManager::GetAccountInfo()
- {
- std::lock_guard<std::mutex> mutexLock(mgrMutex_);
- return currentAccount_;
- }
- AccountInfo currentAccount_;
這里只是返回currentAccount_變量,它是一個AccountInfo,在前面的賬號管理服務啟動的時候,我們知道currentAccount_是在初始化過程中通過讀取賬號配置文件到jsonData_中得到的
5 賬號登入、登出、注銷以及Token失效
前面提到,OhosAccountManager::OnInitialize會首先調(diào)用BuildEventsMapper()進行事件映射
- //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp
- void OhosAccountManager::BuildEventsMapper()
- {
- eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGIN,
- ACCOUNT_BIND_SUCCESS_EVT));
- eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGOUT,
- ACCOUNT_MANUAL_UNBOUND_EVT));
- eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_TOKEN_INVALID,
- ACCOUNT_TOKEN_EXPIRED_EVT));
- eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGOFF,
- ACCOUNT_MANUAL_LOGOFF_EVT));
- eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGIN, &OhosAccountManager::LoginOhosAccount));
- eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGOUT, &OhosAccountManager::LogoutOhosAccount));
- eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGOFF, &OhosAccountManager::LogoffOhosAccount));
- eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_TOKEN_INVALID,
- &OhosAccountManager::HandleOhosAccountTokenInvalidEvent));
- }
可以看到,監(jiān)聽的事件處理回調(diào)有登入、登出、注銷以及Token失效四種類型,下面以LoginOhosAccount為例看看它們具體做了什么:
- //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp
- bool OhosAccountManager::LoginOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr)
- {
- std::lock_guard<std::mutex> mutexLock(mgrMutex_);
- bool ret = HandleEvent(eventStr); // update account status
- if (!ret) {
- ACCOUNT_LOGE("LoginOhosAccount: HandleEvent %{public}s failed", eventStr.c_str());
- return false;
- }
- AccountInfo accountInfo(name, uid, currentAccount_.ohosAccountStatus_);
- accountInfo.bindTime_ = std::time(nullptr);
- accountInfo.userId_ = GetUserId();
- ret = SetAccount(accountInfo); // set account info
- if (!ret) {
- ACCOUNT_LOGE("LoginOhosAccount: SetAccount failed");
- return false;
- }
- ACCOUNT_LOGI("LoginOhosAccount success");
- return true;
- }
- ...
從上面可以看出,登錄、登出、注銷及Token失效操作步驟基本一致,首先對收到的事件進行處理,然后將賬號信息更新到緩存和配置文件中
因此,這里我們只需要看看HandleEvent()做了什么處理:
這里首先根據(jù)eventStr找到對應的事件類型,然后將事件更新到賬號狀態(tài)機
- //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp
- bool OhosAccountManager::HandleEvent(const std::string &eventStr)
- {
- //根據(jù)eventStr找到對應的事件類型
- auto iter = eventMap_.find(eventStr);
- if (iter == eventMap_.end()) {
- ACCOUNT_LOGE("invalid event: %{public}s", eventStr.c_str());
- return false;
- }
- int event = iter->second;
- //將事件更新到賬號狀態(tài)機
- bool ret = accountState_->StateChangeProcess(event);
- if (!ret) {
- ACCOUNT_LOGE("Handle event %{public}d failed", event);
- return false;
- }
- std::int32_t newState = accountState_->GetAccountState();
- if (newState != currentAccount_.ohosAccountStatus_) {
- HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCOUNT, "AccountServiceStateMachineEvent",
- HiviewDFX::HiSysEvent::EventType::FAULT, "DEVICE_MODE", currentAccount_.userId_,
- "OPERATION_TYPE", event, "OLD_STATE", currentAccount_.ohosAccountStatus_, "NEW_STATE", newState);
- currentAccount_.ohosAccountStatus_ = newState;
- }
- return true;
- }
- //base\account\os_account\services\accountmgr\src\account_state_machine.cpp
- bool AccountStateMachine::StateChangeProcess(int evt)
- {
- // for performance record
- std::string stateRecordStr;
- int64_t processTicks = GetTickCount();
- stateRecordStr.append("state from[").append(std::to_string(currentState_)).append("] to [");
- // get all the current state event action
- auto stateIter = stateMachineMap_.find(currentState_);
- if (stateIter == stateMachineMap_.end()) {
- ACCOUNT_LOGE("current state %d is not in state machine map.", currentState_);
- return false;
- }
- // get the current event action
- auto eventIter = stateIter->second.find(evt);
- if (eventIter == stateIter->second.end()) {
- ACCOUNT_LOGE("event %d is not in state machine map.", evt);
- return false;
- }
- // maybe action is null
- if (eventIter->second == nullptr) {
- ACCOUNT_LOGI("event %d has no action.", evt);
- return true;
- }
- int nextState = eventIter->second->GetNextState();
- if (currentState_ != nextState) {
- ACCOUNT_LOGI("account state change, (oldstate, newstate) = (%d, %d)", currentState_, nextState);
- currentState_ = nextState;
- }
- // Record state change performance
- processTicks = GetTickCount() - processTicks;
- stateRecordStr.append(std::to_string(nextState)).append("], event[").append(std::to_string(evt)).append("] Cost");
- PerfStat::GetInstance().SetAccountStateChangeTime(stateRecordStr, processTicks);
- return true;
- }
可以看到,在狀態(tài)機里面只是簡單完成狀態(tài)的切換
6 總結(jié)
通過本文的學習可了解到賬號子系統(tǒng)源碼架構的各個組成部分的實現(xiàn)以及流程(包括框架代碼、內(nèi)部接口、外部接口、系統(tǒng)服務等),結(jié)合上文內(nèi)容,可進一步對賬號子系統(tǒng)其它組件進行深入的學習。
下一步,
(1) 著重理解賬號子系統(tǒng)框架代碼,為開發(fā)的可重用性和擴充性做準備;
(2) 著重理解賬號管理服務模塊,看看賬號管理服務是如何為各功能模塊的業(yè)務請求提供應答的;