• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #define LOG_TAG "UserDelegate"
17 #include "user_delegate.h"
18 
19 #include <thread>
20 #include "communicator/device_manager_adapter.h"
21 #include "log_print.h"
22 #include "metadata/meta_data_manager.h"
23 #include "utils/anonymous.h"
24 
25 namespace OHOS::DistributedData {
26 using namespace OHOS::DistributedKv;
GetLocalDeviceId()27 std::string GetLocalDeviceId()
28 {
29     return DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid;
30 }
31 
GetLocalUserStatus()32 std::vector<UserStatus> UserDelegate::GetLocalUserStatus()
33 {
34     ZLOGI("begin");
35     auto deviceId = GetLocalDeviceId();
36     if (deviceId.empty()) {
37         ZLOGE("failed to get local device id");
38         return {};
39     }
40     return GetUsers(deviceId);
41 }
42 
GetLocalUsers()43 std::set<std::string> UserDelegate::GetLocalUsers()
44 {
45     auto deviceId = GetLocalDeviceId();
46     if (deviceId.empty()) {
47         ZLOGE("failed to get local device id");
48         return {};
49     }
50     std::set<std::string> users;
51     deviceUser_.Compute(deviceId, [&users](const auto &key, auto &value) {
52         if (value.empty()) {
53             UserMetaData userMetaData;
54             MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(key), userMetaData);
55             for (const auto &user : userMetaData.users) {
56                 value[user.id] = user.isActive;
57             }
58         }
59         for (const auto [user, active] : value) {
60             users.emplace(std::to_string(user));
61         }
62         return !value.empty();
63     });
64     return users;
65 }
66 
GetRemoteUserStatus(const std::string & deviceId)67 std::vector<DistributedData::UserStatus> UserDelegate::GetRemoteUserStatus(const std::string &deviceId)
68 {
69     if (deviceId.empty()) {
70         ZLOGE("error input device id");
71         return {};
72     }
73     return GetUsers(deviceId);
74 }
75 
GetUsers(const std::string & deviceId)76 std::vector<UserStatus> UserDelegate::GetUsers(const std::string &deviceId)
77 {
78     std::vector<UserStatus> userStatus;
79     deviceUser_.Compute(deviceId, [&userStatus](const auto &key, auto &users) {
80         if (users.empty()) {
81             UserMetaData userMetaData;
82             MetaDataManager::GetInstance().LoadMeta(UserMetaRow::GetKeyFor(key), userMetaData);
83             for (const auto &user : userMetaData.users) {
84                 users[user.id] = user.isActive;
85             }
86         }
87         for (const auto [key, value] : users) {
88             userStatus.emplace_back(key, value);
89         }
90         return !users.empty();
91     });
92     ZLOGI("device:%{public}s, users:%{public}s", Anonymous::Change(deviceId).c_str(),
93         Serializable::Marshall(userStatus).c_str());
94     return userStatus;
95 }
96 
DeleteUsers(const std::string & deviceId)97 void UserDelegate::DeleteUsers(const std::string &deviceId)
98 {
99     deviceUser_.Erase(deviceId);
100 }
101 
UpdateUsers(const std::string & deviceId,const std::vector<UserStatus> & userStatus)102 void UserDelegate::UpdateUsers(const std::string &deviceId, const std::vector<UserStatus> &userStatus)
103 {
104     ZLOGI("begin, device:%{public}s, users:%{public}zu", Anonymous::Change(deviceId).c_str(), userStatus.size());
105     deviceUser_.Compute(deviceId, [&userStatus](const auto &key, std::map<int, bool> &users) {
106         users = {};
107         for (const auto &user : userStatus) {
108             users[user.id] = user.isActive;
109         }
110         ZLOGI("end, device:%{public}s, users:%{public}zu", Anonymous::Change(key).c_str(), users.size());
111         return true;
112     });
113 }
114 
InitLocalUserMeta()115 bool UserDelegate::InitLocalUserMeta()
116 {
117     std::vector<int> users;
118     auto ret = AccountDelegate::GetInstance()->QueryUsers(users);
119     if (!ret || users.empty()) {
120         ZLOGE("failed to query os accounts, ret:%{public}d", ret);
121         return false;
122     }
123     std::vector<UserStatus> userStatus = { { 0, true } };
124     for (const auto &user : users) {
125         userStatus.emplace_back(user, true);
126     }
127     UserMetaData userMetaData;
128     userMetaData.deviceId = GetLocalDeviceId();
129     UpdateUsers(userMetaData.deviceId, userStatus);
130     deviceUser_.ComputeIfPresent(userMetaData.deviceId, [&userMetaData](const auto &, std::map<int, bool> &users) {
131         for (const auto &[key, value] : users) {
132             userMetaData.users.emplace_back(key, value);
133         }
134         return true;
135     });
136     ZLOGI("put user meta data save meta data");
137     return MetaDataManager::GetInstance().SaveMeta(UserMetaRow::GetKeyFor(userMetaData.deviceId), userMetaData);
138 }
139 
GetInstance()140 UserDelegate &UserDelegate::GetInstance()
141 {
142     static UserDelegate instance;
143     return instance;
144 }
145 
Init(const std::shared_ptr<ExecutorPool> & executors)146 void UserDelegate::Init(const std::shared_ptr<ExecutorPool>& executors)
147 {
148     auto ret = AccountDelegate::GetInstance()->Subscribe(std::make_shared<LocalUserObserver>(*this));
149     MetaDataManager::GetInstance().Subscribe(
150         UserMetaRow::KEY_PREFIX, [this](const std::string &key, const std::string &value, int32_t flag) -> auto {
151             UserMetaData metaData;
152             UserMetaData::Unmarshall(value, metaData);
153             ZLOGD("flag:%{public}d, value:%{public}s", flag, Anonymous::Change(metaData.deviceId).c_str());
154             if (metaData.deviceId == GetLocalDeviceId()) {
155                 ZLOGD("ignore local device user meta change");
156                 return false;
157             }
158             if (flag == MetaDataManager::INSERT || flag == MetaDataManager::UPDATE) {
159                 UpdateUsers(metaData.deviceId, metaData.users);
160             } else if (flag == MetaDataManager::DELETE) {
161                 DeleteUsers(metaData.deviceId);
162             } else {
163                 ZLOGD("ignored operation");
164             }
165             return true;
166     });
167     if (!executors_) {
168         executors_ = executors;
169     }
170     executors_->Execute(GeTask());
171     ZLOGD("subscribe os account ret:%{public}d", ret);
172 }
173 
GeTask()174 ExecutorPool::Task UserDelegate::GeTask()
175 {
176     return [this] {
177         auto ret = InitLocalUserMeta();
178         if (ret) {
179             return;
180         }
181         executors_->Schedule(std::chrono::milliseconds(RETRY_INTERVAL), GeTask());
182     };
183 }
184 
NotifyUserEvent(const UserDelegate::UserEvent & userEvent)185 bool UserDelegate::NotifyUserEvent(const UserDelegate::UserEvent &userEvent)
186 {
187     // update all local user status
188     (void) userEvent;
189     return InitLocalUserMeta();
190 }
191 
LocalUserObserver(UserDelegate & userDelegate)192 UserDelegate::LocalUserObserver::LocalUserObserver(UserDelegate &userDelegate) : userDelegate_(userDelegate)
193 {
194 }
195 
OnAccountChanged(const DistributedKv::AccountEventInfo & eventInfo)196 void UserDelegate::LocalUserObserver::OnAccountChanged(const DistributedKv::AccountEventInfo &eventInfo)
197 {
198     ZLOGI("event info:%{public}s, %{public}d", eventInfo.userId.c_str(), eventInfo.status);
199     userDelegate_.NotifyUserEvent({}); // just notify
200 }
201 
Name()202 std::string UserDelegate::LocalUserObserver::Name()
203 {
204     return "user_delegate";
205 }
206 } // namespace OHOS::DistributedData
207