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 #define LOG_TAG "AccountDelegateNormalImpl"
16
17 #include "account_delegate_normal_impl.h"
18
19 #include <algorithm>
20 #include <endian.h>
21 #include <regex>
22 #include <thread>
23 #include <unistd.h>
24
25 #include "accesstoken_kit.h"
26 #include "log_print.h"
27 #include "ohos_account_kits.h"
28 #include "os_account_manager.h"
29 #include "os_account_subscribe_info.h"
30
31 namespace OHOS {
32 namespace DistributedData {
33 using namespace OHOS::AAFwk;
34 using namespace OHOS::DistributedData;
35 using namespace Security::AccessToken;
36 __attribute__((used)) static bool g_isInit = AccountDelegateNormalImpl::Init();
37 static constexpr int32_t STOPPING_TIMEOUT = 5;
38 static inline const std::map<int32_t, AccountStatus> STATUS = {
39 { AccountSA::REMOVED, AccountStatus::DEVICE_ACCOUNT_DELETE },
40 { AccountSA::SWITCHED, AccountStatus::DEVICE_ACCOUNT_SWITCHED },
41 { AccountSA::UNLOCKED, AccountStatus::DEVICE_ACCOUNT_UNLOCKED },
42 { AccountSA::STOPPING, AccountStatus::DEVICE_ACCOUNT_STOPPING },
43 { AccountSA::STOPPED, AccountStatus::DEVICE_ACCOUNT_STOPPED }
44 };
45
AccountSubscriber(const OsAccountSubscribeInfo & info,std::shared_ptr<ExecutorPool> executors)46 AccountSubscriber::AccountSubscriber(const OsAccountSubscribeInfo &info, std::shared_ptr<ExecutorPool> executors)
47 : OsAccountSubscriber(info), executors_(executors)
48 {
49 }
50
OnStateChanged(const OsAccountStateData & data)51 void AccountSubscriber::OnStateChanged(const OsAccountStateData &data)
52 {
53 ZLOGI("state change. state:%{public}d, from %{public}d to %{public}d", data.state, data.fromId, data.toId);
54
55 auto it = STATUS.find(data.state);
56 if (it == STATUS.end()) {
57 return;
58 }
59 AccountEventInfo accountEventInfo;
60 accountEventInfo.userId = std::to_string(data.toId);
61 accountEventInfo.status = it->second;
62 int32_t timeout = accountEventInfo.status == AccountStatus::DEVICE_ACCOUNT_STOPPING ? STOPPING_TIMEOUT : 0;
63 eventCallback_(accountEventInfo, timeout);
64 if (data.callback == nullptr) {
65 return;
66 }
67 if (executors_ != nullptr) {
68 executors_->Execute([callback = data.callback]() {
69 callback->OnComplete();
70 });
71 } else {
72 data.callback->OnComplete();
73 }
74 }
75
SetEventCallback(EventCallback callback)76 void AccountSubscriber::SetEventCallback(EventCallback callback)
77 {
78 eventCallback_ = callback;
79 }
80
AccountDelegateNormalImpl()81 AccountDelegateNormalImpl::AccountDelegateNormalImpl()
82 {
83 userDeactivating_.InsertOrAssign(0, false);
84 }
85
GetCurrentAccountId() const86 std::string AccountDelegateNormalImpl::GetCurrentAccountId() const
87 {
88 ZLOGD("start");
89 auto ohosAccountInfo = AccountSA::OhosAccountKits::GetInstance().QueryOhosAccountInfo();
90 if (!ohosAccountInfo.first) {
91 ZLOGE("get ohosAccountInfo from OhosAccountKits is null, return default");
92 return AccountSA::DEFAULT_OHOS_ACCOUNT_UID;
93 }
94 if (ohosAccountInfo.second.uid_.empty()) {
95 ZLOGE("get ohosAccountInfo from OhosAccountKits is null, return default");
96 return AccountSA::DEFAULT_OHOS_ACCOUNT_UID;
97 }
98
99 return Sha256AccountId(ohosAccountInfo.second.uid_);
100 }
101
GetUserByToken(uint32_t tokenId) const102 int32_t AccountDelegateNormalImpl::GetUserByToken(uint32_t tokenId) const
103 {
104 auto type = AccessTokenKit::GetTokenTypeFlag(tokenId);
105 if (type == TOKEN_NATIVE || type == TOKEN_SHELL) {
106 return 0;
107 }
108
109 HapTokenInfo tokenInfo;
110 auto result = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
111 if (result != RET_SUCCESS) {
112 ZLOGE("token:0x%{public}x, result:%{public}d", tokenId, result);
113 return -1;
114 }
115 return tokenInfo.userID;
116 }
117
QueryUsers(std::vector<int> & users)118 bool AccountDelegateNormalImpl::QueryUsers(std::vector<int> &users)
119 {
120 users = { 0 }; // default user
121 return AccountSA::OsAccountManager::QueryActiveOsAccountIds(users) == 0;
122 }
123
QueryForegroundUsers(std::vector<int> & users)124 bool AccountDelegateNormalImpl::QueryForegroundUsers(std::vector<int> &users)
125 {
126 std::vector<AccountSA::ForegroundOsAccount> accounts;
127 if (AccountSA::OsAccountManager::GetForegroundOsAccounts(accounts) != 0) {
128 return false;
129 }
130 for (auto &account : accounts) {
131 users.push_back(account.localId);
132 }
133 return true;
134 }
135
IsLoginAccount()136 bool AccountDelegateNormalImpl::IsLoginAccount()
137 {
138 return GetCurrentAccountId() != AccountSA::DEFAULT_OHOS_ACCOUNT_UID;
139 }
140
IsVerified(int userId)141 bool AccountDelegateNormalImpl::IsVerified(int userId)
142 {
143 auto [success, res] = userStatus_.Find(userId);
144 if (success && res) {
145 return true;
146 }
147 auto status = AccountSA::OsAccountManager::IsOsAccountVerified(userId, res);
148 if (status == 0) {
149 userStatus_.InsertOrAssign(userId, res);
150 }
151 return status == 0 && res;
152 }
153
SubscribeAccountEvent()154 void AccountDelegateNormalImpl::SubscribeAccountEvent()
155 {
156 ZLOGI("Subscribe account event listener start.");
157 if (accountSubscriber_ == nullptr) {
158 std::set<OsAccountState> states;
159 states.insert(AccountSA::REMOVED);
160 states.insert(AccountSA::SWITCHED);
161 states.insert(AccountSA::UNLOCKED);
162 states.insert(AccountSA::STOPPING);
163 states.insert(AccountSA::STOPPED);
164 OsAccountSubscribeInfo info(states, true);
165 accountSubscriber_ = std::make_shared<AccountSubscriber>(info, executors_);
166 accountSubscriber_->SetEventCallback([this](AccountEventInfo &account, int32_t timeout) {
167 UpdateUserStatus(account);
168 account.harmonyAccountId = GetCurrentAccountId();
169 NotifyAccountChanged(account, timeout);
170 });
171 }
172 executors_->Execute(GetTask(0));
173 }
174
UpdateUserStatus(const AccountEventInfo & account)175 void AccountDelegateNormalImpl::UpdateUserStatus(const AccountEventInfo &account)
176 {
177 uint32_t status = static_cast<uint32_t>(account.status);
178 switch (status) {
179 case static_cast<uint32_t>(AccountStatus::DEVICE_ACCOUNT_STOPPING):
180 case static_cast<uint32_t>(AccountStatus::DEVICE_ACCOUNT_DELETE):
181 userStatus_.Erase(atoi(account.userId.c_str()));
182 userDeactivating_.Erase(atoi(account.userId.c_str()));
183 break;
184 case static_cast<uint32_t>(AccountStatus::DEVICE_ACCOUNT_UNLOCKED):
185 userStatus_.InsertOrAssign(atoi(account.userId.c_str()), true);
186 break;
187 case static_cast<uint32_t>(AccountStatus::DEVICE_ACCOUNT_STOPPED):
188 userStatus_.InsertOrAssign(atoi(account.userId.c_str()), false);
189 break;
190 default:
191 break;
192 }
193 }
194
GetTask(uint32_t retry)195 ExecutorPool::Task AccountDelegateNormalImpl::GetTask(uint32_t retry)
196 {
197 return [this, retry] {
198 auto result = OsAccountManager::SubscribeOsAccount(accountSubscriber_);
199 if (result == ERR_OK) {
200 ZLOGI("success to register subscriber.");
201 return;
202 }
203 ZLOGD("fail to register subscriber, error:%{public}d, time:%{public}d", result, retry);
204
205 if (retry + 1 > MAX_RETRY_TIME) {
206 ZLOGE("fail to register subscriber!");
207 return;
208 }
209 executors_->Schedule(std::chrono::seconds(RETRY_WAIT_TIME_S), GetTask(retry + 1));
210 };
211 }
212
~AccountDelegateNormalImpl()213 AccountDelegateNormalImpl::~AccountDelegateNormalImpl()
214 {
215 ZLOGD("destruct");
216 auto res = OsAccountManager::UnsubscribeOsAccount(accountSubscriber_);
217 if (res != ERR_OK) {
218 ZLOGW("unregister account event fail res:%d", res);
219 }
220 }
221
UnsubscribeAccountEvent()222 void AccountDelegateNormalImpl::UnsubscribeAccountEvent()
223 {
224 auto res = OsAccountManager::UnsubscribeOsAccount(accountSubscriber_);
225 if (res != ERR_OK) {
226 ZLOGW("unregister account event fail res:%d", res);
227 }
228 }
229
Sha256AccountId(const std::string & plainText) const230 std::string AccountDelegateNormalImpl::Sha256AccountId(const std::string &plainText) const
231 {
232 std::regex pattern("^[0-9]+$");
233 if (!std::regex_match(plainText, pattern)) {
234 return plainText;
235 }
236
237 int64_t plain;
238 std::string::size_type int64MaxLen(std::to_string(INT64_MAX).size());
239 // plain text length must be less than INT64_MAX string.
240 plain = atoll(plainText.c_str());
241 if (plain == 0) {
242 return plainText;
243 }
244 if (plain == INT64_MAX) {
245 plain = atoll(plainText.substr(plainText.size() - int64MaxLen + 1, int64MaxLen - 1).c_str());
246 }
247
248 auto plainVal = htobe64(plain);
249 return DoHash(static_cast<void *>(&plainVal), sizeof(plainVal), true);
250 }
251
BindExecutor(std::shared_ptr<ExecutorPool> executors)252 void AccountDelegateNormalImpl::BindExecutor(std::shared_ptr<ExecutorPool> executors)
253 {
254 executors_ = executors;
255 }
256
GetUnencryptedAccountId(int32_t userId) const257 std::string AccountDelegateNormalImpl::GetUnencryptedAccountId(int32_t userId) const
258 {
259 AccountSA::OhosAccountInfo info;
260 auto ret = AccountSA::OhosAccountKits::GetInstance().GetOsAccountDistributedInfo(userId, info);
261 if (ret != ERR_OK) {
262 ZLOGE("GetUnencryptedAccountId failed: %{public}d", ret);
263 return "";
264 }
265 return Sha256AccountId(info.GetRawUid());
266 }
267
QueryForegroundUserId(int & foregroundUserId)268 bool AccountDelegateNormalImpl::QueryForegroundUserId(int &foregroundUserId)
269 {
270 int32_t status = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(foregroundUserId);
271 if (status != ERR_OK) {
272 ZLOGE("GetForegroundOsAccountLocalId failed, status: %{public}d", status);
273 return false;
274 }
275 return true;
276 }
277
Init()278 bool AccountDelegateNormalImpl::Init()
279 {
280 static AccountDelegateNormalImpl normalAccountDelegate;
281 static std::once_flag onceFlag;
282 std::call_once(onceFlag, [&]() {
283 AccountDelegate::RegisterAccountInstance(&normalAccountDelegate);
284 });
285 return true;
286 }
287
IsUserForeground(int32_t userId)288 bool AccountDelegateNormalImpl::IsUserForeground(int32_t userId)
289 {
290 bool isForeground = false;
291 if (AccountSA::OsAccountManager::IsOsAccountForeground(userId, isForeground) != 0) {
292 ZLOGE("check foreground user error, userId:%{public}d", userId);
293 return false;
294 }
295 return isForeground;
296 }
297
IsDeactivating(int userId)298 bool AccountDelegateNormalImpl::IsDeactivating(int userId)
299 {
300 auto [success, res] = userDeactivating_.Find(userId);
301 if (success && !res) {
302 return res;
303 }
304 auto status = AccountSA::OsAccountManager::IsOsAccountDeactivating(userId, res);
305 if (status != 0) {
306 ZLOGE("IsOsAccountDeactivating failed: %{public}d, user:%{public}d", status, userId);
307 return true;
308 }
309 userDeactivating_.InsertOrAssign(userId, res);
310 return res;
311 }
312 } // namespace DistributedData
313 } // namespace OHOS