153c3577eSopenharmony_ci/* 253c3577eSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 353c3577eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 453c3577eSopenharmony_ci * you may not use this file except in compliance with the License. 553c3577eSopenharmony_ci * You may obtain a copy of the License at 653c3577eSopenharmony_ci * 753c3577eSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 853c3577eSopenharmony_ci * 953c3577eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1053c3577eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1153c3577eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1253c3577eSopenharmony_ci * See the License for the specific language governing permissions and 1353c3577eSopenharmony_ci * limitations under the License. 1453c3577eSopenharmony_ci */ 1553c3577eSopenharmony_ci 1653c3577eSopenharmony_ci#define LOG_TAG "UserDelegate" 1753c3577eSopenharmony_ci#include "user_delegate.h" 1853c3577eSopenharmony_ci 1953c3577eSopenharmony_ci#include <chrono> 2053c3577eSopenharmony_ci#include <cinttypes> 2153c3577eSopenharmony_ci#include <thread> 2253c3577eSopenharmony_ci 2353c3577eSopenharmony_ci#include "communicator/device_manager_adapter.h" 2453c3577eSopenharmony_ci#include "log_print.h" 2553c3577eSopenharmony_ci#include "metadata/meta_data_manager.h" 2653c3577eSopenharmony_ci#include "utils/anonymous.h" 2753c3577eSopenharmony_ci 2853c3577eSopenharmony_cinamespace OHOS::DistributedData { 2953c3577eSopenharmony_ciusing namespace OHOS::DistributedKv; 3053c3577eSopenharmony_ciusing namespace std::chrono; 3153c3577eSopenharmony_cistd::string GetLocalDeviceId() 3253c3577eSopenharmony_ci{ 3353c3577eSopenharmony_ci return DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid; 3453c3577eSopenharmony_ci} 3553c3577eSopenharmony_ci 3653c3577eSopenharmony_cistd::vector<UserStatus> UserDelegate::GetLocalUserStatus() 3753c3577eSopenharmony_ci{ 3853c3577eSopenharmony_ci ZLOGI("begin"); 3953c3577eSopenharmony_ci auto deviceId = GetLocalDeviceId(); 4053c3577eSopenharmony_ci if (deviceId.empty()) { 4153c3577eSopenharmony_ci ZLOGE("failed to get local device id"); 4253c3577eSopenharmony_ci return {}; 4353c3577eSopenharmony_ci } 4453c3577eSopenharmony_ci return GetUsers(deviceId); 4553c3577eSopenharmony_ci} 4653c3577eSopenharmony_ci 4753c3577eSopenharmony_cistd::set<std::string> UserDelegate::GetLocalUsers() 4853c3577eSopenharmony_ci{ 4953c3577eSopenharmony_ci auto deviceId = GetLocalDeviceId(); 5053c3577eSopenharmony_ci if (deviceId.empty()) { 5153c3577eSopenharmony_ci ZLOGE("failed to get local device id"); 5253c3577eSopenharmony_ci return {}; 5353c3577eSopenharmony_ci } 5453c3577eSopenharmony_ci std::set<std::string> users; 5553c3577eSopenharmony_ci deviceUser_.Compute(deviceId, [&users](const auto &key, auto &value) { 5653c3577eSopenharmony_ci if (value.empty()) { 5753c3577eSopenharmony_ci UserMetaData userMetaData; 5853c3577eSopenharmony_ci MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(key), userMetaData); 5953c3577eSopenharmony_ci for (const auto &user : userMetaData.users) { 6053c3577eSopenharmony_ci value[user.id] = user.isActive; 6153c3577eSopenharmony_ci } 6253c3577eSopenharmony_ci } 6353c3577eSopenharmony_ci for (const auto [user, active] : value) { 6453c3577eSopenharmony_ci users.emplace(std::to_string(user)); 6553c3577eSopenharmony_ci } 6653c3577eSopenharmony_ci return !value.empty(); 6753c3577eSopenharmony_ci }); 6853c3577eSopenharmony_ci return users; 6953c3577eSopenharmony_ci} 7053c3577eSopenharmony_ci 7153c3577eSopenharmony_cistd::vector<DistributedData::UserStatus> UserDelegate::GetRemoteUserStatus(const std::string &deviceId) 7253c3577eSopenharmony_ci{ 7353c3577eSopenharmony_ci if (deviceId.empty()) { 7453c3577eSopenharmony_ci ZLOGE("error input device id"); 7553c3577eSopenharmony_ci return {}; 7653c3577eSopenharmony_ci } 7753c3577eSopenharmony_ci return GetUsers(deviceId); 7853c3577eSopenharmony_ci} 7953c3577eSopenharmony_ci 8053c3577eSopenharmony_cistd::vector<UserStatus> UserDelegate::GetUsers(const std::string &deviceId) 8153c3577eSopenharmony_ci{ 8253c3577eSopenharmony_ci std::vector<UserStatus> userStatus; 8353c3577eSopenharmony_ci deviceUser_.Compute(deviceId, [&userStatus](const auto &key, auto &users) { 8453c3577eSopenharmony_ci if (users.empty()) { 8553c3577eSopenharmony_ci UserMetaData userMetaData; 8653c3577eSopenharmony_ci MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(key), userMetaData); 8753c3577eSopenharmony_ci for (const auto &user : userMetaData.users) { 8853c3577eSopenharmony_ci users[user.id] = user.isActive; 8953c3577eSopenharmony_ci } 9053c3577eSopenharmony_ci } 9153c3577eSopenharmony_ci for (const auto [key, value] : users) { 9253c3577eSopenharmony_ci userStatus.emplace_back(key, value); 9353c3577eSopenharmony_ci } 9453c3577eSopenharmony_ci return !users.empty(); 9553c3577eSopenharmony_ci }); 9653c3577eSopenharmony_ci auto time = static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count()); 9753c3577eSopenharmony_ci ZLOGI("device:%{public}s, users:%{public}s times %{public}" PRIu64 ".", Anonymous::Change(deviceId).c_str(), 9853c3577eSopenharmony_ci Serializable::Marshall(userStatus).c_str(), time); 9953c3577eSopenharmony_ci return userStatus; 10053c3577eSopenharmony_ci} 10153c3577eSopenharmony_ci 10253c3577eSopenharmony_civoid UserDelegate::DeleteUsers(const std::string &deviceId) 10353c3577eSopenharmony_ci{ 10453c3577eSopenharmony_ci deviceUser_.Erase(deviceId); 10553c3577eSopenharmony_ci} 10653c3577eSopenharmony_ci 10753c3577eSopenharmony_civoid UserDelegate::UpdateUsers(const std::string &deviceId, const std::vector<UserStatus> &userStatus) 10853c3577eSopenharmony_ci{ 10953c3577eSopenharmony_ci ZLOGI("begin, device:%{public}s, users:%{public}zu", Anonymous::Change(deviceId).c_str(), userStatus.size()); 11053c3577eSopenharmony_ci deviceUser_.Compute(deviceId, [&userStatus](const auto &key, std::map<int, bool> &users) { 11153c3577eSopenharmony_ci users = {}; 11253c3577eSopenharmony_ci for (const auto &user : userStatus) { 11353c3577eSopenharmony_ci users[user.id] = user.isActive; 11453c3577eSopenharmony_ci } 11553c3577eSopenharmony_ci ZLOGI("end, device:%{public}s, users:%{public}zu", Anonymous::Change(key).c_str(), users.size()); 11653c3577eSopenharmony_ci return true; 11753c3577eSopenharmony_ci }); 11853c3577eSopenharmony_ci} 11953c3577eSopenharmony_ci 12053c3577eSopenharmony_cibool UserDelegate::InitLocalUserMeta() 12153c3577eSopenharmony_ci{ 12253c3577eSopenharmony_ci std::vector<int> users; 12353c3577eSopenharmony_ci auto ret = AccountDelegate::GetInstance()->QueryUsers(users); 12453c3577eSopenharmony_ci if (!ret || users.empty()) { 12553c3577eSopenharmony_ci ZLOGE("failed to query os accounts, ret:%{public}d", ret); 12653c3577eSopenharmony_ci return false; 12753c3577eSopenharmony_ci } 12853c3577eSopenharmony_ci std::vector<UserStatus> userStatus = { { 0, true } }; 12953c3577eSopenharmony_ci for (const auto &user : users) { 13053c3577eSopenharmony_ci userStatus.emplace_back(user, true); 13153c3577eSopenharmony_ci } 13253c3577eSopenharmony_ci UserMetaData userMetaData; 13353c3577eSopenharmony_ci userMetaData.deviceId = GetLocalDeviceId(); 13453c3577eSopenharmony_ci UpdateUsers(userMetaData.deviceId, userStatus); 13553c3577eSopenharmony_ci deviceUser_.ComputeIfPresent(userMetaData.deviceId, [&userMetaData](const auto &, std::map<int, bool> &users) { 13653c3577eSopenharmony_ci for (const auto &[key, value] : users) { 13753c3577eSopenharmony_ci userMetaData.users.emplace_back(key, value); 13853c3577eSopenharmony_ci } 13953c3577eSopenharmony_ci return true; 14053c3577eSopenharmony_ci }); 14153c3577eSopenharmony_ci ZLOGI("put user meta data save meta data"); 14253c3577eSopenharmony_ci return MetaDataManager::GetInstance().SaveMeta(UserMetaRow::GetKeyFor(userMetaData.deviceId), userMetaData); 14353c3577eSopenharmony_ci} 14453c3577eSopenharmony_ci 14553c3577eSopenharmony_ciUserDelegate &UserDelegate::GetInstance() 14653c3577eSopenharmony_ci{ 14753c3577eSopenharmony_ci static UserDelegate instance; 14853c3577eSopenharmony_ci return instance; 14953c3577eSopenharmony_ci} 15053c3577eSopenharmony_ci 15153c3577eSopenharmony_civoid UserDelegate::Init(const std::shared_ptr<ExecutorPool> &executors) 15253c3577eSopenharmony_ci{ 15353c3577eSopenharmony_ci auto ret = AccountDelegate::GetInstance()->Subscribe(std::make_shared<LocalUserObserver>(*this)); 15453c3577eSopenharmony_ci MetaDataManager::GetInstance().Subscribe( 15553c3577eSopenharmony_ci UserMetaRow::KEY_PREFIX, [this](const std::string &key, const std::string &value, int32_t flag) -> auto { 15653c3577eSopenharmony_ci UserMetaData metaData; 15753c3577eSopenharmony_ci if (value.empty()) { 15853c3577eSopenharmony_ci MetaDataManager::GetInstance().LoadMeta(key, metaData); 15953c3577eSopenharmony_ci } else { 16053c3577eSopenharmony_ci UserMetaData::Unmarshall(value, metaData); 16153c3577eSopenharmony_ci } 16253c3577eSopenharmony_ci ZLOGD("flag:%{public}d, value:%{public}s", flag, Anonymous::Change(metaData.deviceId).c_str()); 16353c3577eSopenharmony_ci if (metaData.deviceId == GetLocalDeviceId()) { 16453c3577eSopenharmony_ci ZLOGD("ignore local device user meta change"); 16553c3577eSopenharmony_ci return false; 16653c3577eSopenharmony_ci } 16753c3577eSopenharmony_ci if (flag == MetaDataManager::INSERT || flag == MetaDataManager::UPDATE) { 16853c3577eSopenharmony_ci UpdateUsers(metaData.deviceId, metaData.users); 16953c3577eSopenharmony_ci } else if (flag == MetaDataManager::DELETE) { 17053c3577eSopenharmony_ci DeleteUsers(metaData.deviceId); 17153c3577eSopenharmony_ci } else { 17253c3577eSopenharmony_ci ZLOGD("ignored operation"); 17353c3577eSopenharmony_ci } 17453c3577eSopenharmony_ci return true; 17553c3577eSopenharmony_ci }); 17653c3577eSopenharmony_ci if (!executors_) { 17753c3577eSopenharmony_ci executors_ = executors; 17853c3577eSopenharmony_ci } 17953c3577eSopenharmony_ci executors_->Execute(GeTask()); 18053c3577eSopenharmony_ci ZLOGD("subscribe os account ret:%{public}d", ret); 18153c3577eSopenharmony_ci} 18253c3577eSopenharmony_ci 18353c3577eSopenharmony_ciExecutorPool::Task UserDelegate::GeTask() 18453c3577eSopenharmony_ci{ 18553c3577eSopenharmony_ci return [this] { 18653c3577eSopenharmony_ci auto ret = InitLocalUserMeta(); 18753c3577eSopenharmony_ci if (ret) { 18853c3577eSopenharmony_ci return; 18953c3577eSopenharmony_ci } 19053c3577eSopenharmony_ci executors_->Schedule(std::chrono::milliseconds(RETRY_INTERVAL), GeTask()); 19153c3577eSopenharmony_ci }; 19253c3577eSopenharmony_ci} 19353c3577eSopenharmony_ci 19453c3577eSopenharmony_cibool UserDelegate::NotifyUserEvent(const UserDelegate::UserEvent &userEvent) 19553c3577eSopenharmony_ci{ 19653c3577eSopenharmony_ci // update all local user status 19753c3577eSopenharmony_ci (void)userEvent; 19853c3577eSopenharmony_ci return InitLocalUserMeta(); 19953c3577eSopenharmony_ci} 20053c3577eSopenharmony_ci 20153c3577eSopenharmony_ciUserDelegate::LocalUserObserver::LocalUserObserver(UserDelegate &userDelegate) : userDelegate_(userDelegate) {} 20253c3577eSopenharmony_ci 20353c3577eSopenharmony_civoid UserDelegate::LocalUserObserver::OnAccountChanged(const DistributedKv::AccountEventInfo &eventInfo) 20453c3577eSopenharmony_ci{ 20553c3577eSopenharmony_ci ZLOGI("event info:%{public}s, %{public}d", eventInfo.userId.c_str(), eventInfo.status); 20653c3577eSopenharmony_ci userDelegate_.NotifyUserEvent({}); // just notify 20753c3577eSopenharmony_ci} 20853c3577eSopenharmony_ci 20953c3577eSopenharmony_cistd::string UserDelegate::LocalUserObserver::Name() 21053c3577eSopenharmony_ci{ 21153c3577eSopenharmony_ci return "user_delegate"; 21253c3577eSopenharmony_ci} 21353c3577eSopenharmony_ci} // namespace OHOS::DistributedData