1 /*
2 * Copyright (C) 2025 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 "hdc_subscriber.h"
16 #include <filesystem>
17 #include "credential_base.h"
18
19 using namespace Hdc;
20 using namespace OHOS::AccountSA;
21 namespace fs = std::filesystem;
22
23 namespace {
24 static const std::string USER_DIR_PREFIX_PATH = "/data/service/el1/public/hdc_server/";
25 static const mode_t MODE = (S_IRWXU | S_IRWXG | S_IXOTH | S_ISGID);
26 }
27
OnStateChanged(const OHOS::AccountSA::OsAccountStateData & data)28 void HdcSubscriber::OnStateChanged(const OHOS::AccountSA::OsAccountStateData& data)
29 {
30 WRITE_LOG(LOG_INFO, "Recv data.state:%d, data.toId:%d", data.state, data.toId);
31 std::string path = USER_DIR_PREFIX_PATH + std::to_string(data.toId);
32 switch (data.state) {
33 case OsAccountState::CREATED:
34 if (HdcCredentialBase::CreatePathWithMode(path.c_str(), MODE) != 0) {
35 WRITE_LOG(LOG_FATAL, "Failed to create directory, error is:%s", strerror(errno));
36 }
37 break;
38 case OsAccountState::REMOVED:
39 if (HdcCredentialBase::RemovePath(path.c_str()) != 0) {
40 WRITE_LOG(LOG_FATAL, "Failed to remove directory, error is:%s", strerror(errno));
41 }
42 break;
43 default:
44 WRITE_LOG(LOG_FATAL, "This state is not support,state is:%d", data.state);
45 break;
46 }
47 }
48
OnAccountsChanged(const int & id)49 void HdcSubscriber::OnAccountsChanged(const int& id)
50 {
51 }
52
HdcAccountSubscriberMonitor()53 int HdcAccountSubscriberMonitor()
54 {
55 static std::shared_ptr<HdcSubscriber> subscriber;
56 std::set<OsAccountState> states = { OsAccountState::CREATED, OsAccountState::REMOVED };
57 OsAccountSubscribeInfo subscribeInfo(states, false);
58 subscriber = std::make_shared<HdcSubscriber>(subscribeInfo);
59
60 const int maxRetry = 10;
61 int retryCount = 0;
62
63 while (retryCount < maxRetry &&
64 (OsAccountManager::SubscribeOsAccount(subscriber) != 0)) {
65 ++retryCount;
66 std::this_thread::sleep_for(std::chrono::seconds(1));
67 WRITE_LOG(LOG_FATAL, "SubscribeOsAccount failed, %d/%d", retryCount, maxRetry);
68 }
69
70 if (retryCount < maxRetry) {
71 WRITE_LOG(LOG_DEBUG, "SubscribeOsAccount success.");
72 } else {
73 WRITE_LOG(LOG_FATAL, "SubscribeOsAccount failed after %d retries.", maxRetry);
74 return -1;
75 }
76
77 return 0;
78 }
79
FreshAccountsPath()80 void FreshAccountsPath()
81 {
82 std::vector<OHOS::AccountSA::OsAccountInfo> osAccountInfos;
83 OHOS::ErrCode err = OHOS::AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(osAccountInfos);
84 if (err != 0) {
85 WRITE_LOG(LOG_FATAL, "QueryAllCreatedOsAccounts failed, error is:%d", err);
86 return;
87 }
88 std::vector<std::string> existUserIds;
89 for (const auto& info : osAccountInfos) {
90 existUserIds.push_back(std::to_string(info.GetLocalId()));
91 }
92 std::vector<std::string> existUserDirs;
93 for (const auto& entry : fs::directory_iterator(USER_DIR_PREFIX_PATH)) {
94 std::string dir = entry.path().filename().string();
95 if (HdcCredentialBase::IsUserDir(dir)) {
96 existUserDirs.push_back(dir);
97 }
98 }
99 std::vector<std::string> needCreate = HdcCredentialBase::Substract<std::string>(existUserIds, existUserDirs);
100 std::vector<std::string> needRemove = HdcCredentialBase::Substract<std::string>(existUserDirs, existUserIds);
101 for (const auto& item : needCreate) {
102 std::string path = USER_DIR_PREFIX_PATH + item;
103 if (!HdcCredentialBase::CreatePathWithMode(path.c_str(), MODE)) {
104 WRITE_LOG(LOG_FATAL, "Failed to create directory, error is:%s", strerror(errno));
105 }
106 }
107 for (const auto& item : needRemove) {
108 std::string path = USER_DIR_PREFIX_PATH + item;
109 if (HdcCredentialBase::RemovePath(path.c_str()) != 0) {
110 WRITE_LOG(LOG_FATAL, "Failed to remove directory, error is:%s", strerror(errno));
111 }
112 }
113 }