1 /*
2  * Copyright (c) 2021-2024 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 #include "access_manager.h"
17 
18 #include <new>
19 #include <unistd.h>
20 #include <vector>
21 
22 #include "device_manager.h"
23 
24 #include "anonymous_string.h"
25 #include "constants.h"
26 #include "dh_context.h"
27 #include "dh_utils_tool.h"
28 #include "distributed_hardware_errno.h"
29 #include "distributed_hardware_log.h"
30 #include "distributed_hardware_manager_factory.h"
31 
32 namespace OHOS {
33 namespace DistributedHardware {
34 #undef DH_LOG_TAG
35 #define DH_LOG_TAG "AccessManager"
36 
37 constexpr int32_t DH_RETRY_INIT_DM_COUNT = 6;
38 constexpr int32_t DH_RETRY_INIT_DM_INTERVAL_US = 1000 * 500;
39 
~AccessManager()40 AccessManager::~AccessManager()
41 {
42     UnInit();
43 }
44 
GetInstance()45 std::shared_ptr<AccessManager> AccessManager::GetInstance()
46 {
47     static std::shared_ptr<AccessManager> instance = std::make_shared<AccessManager>();
48     return instance;
49 }
50 
Init()51 int32_t AccessManager::Init()
52 {
53     DHLOGI("start");
54     if (InitDeviceManager() != DH_FWK_SUCCESS) {
55         DHLOGE("InitDeviceManager failed");
56         return ERR_DH_FWK_ACCESS_INIT_DM_FAILED;
57     }
58     if (RegisterDevStateCallback() != DH_FWK_SUCCESS) {
59         DHLOGE("RegisterDevStateCallback failed");
60         return ERR_DH_FWK_ACCESS_REGISTER_DM_FAILED;
61     }
62     if (RegDevTrustChangeCallback() != DH_FWK_SUCCESS) {
63         DHLOGE("RegDevTrustChangeCallback failed");
64         return ERR_DH_FWK_ACCESS_REGISTER_DM_FAILED;
65     }
66     return DH_FWK_SUCCESS;
67 }
68 
UnInit()69 int32_t AccessManager::UnInit()
70 {
71     DHLOGI("start");
72     if (UnInitDeviceManager() != DH_FWK_SUCCESS) {
73         DHLOGE("UnInitDeviceManager failed");
74         return ERR_DH_FWK_ACCESS_UNINIT_DM_FAILED;
75     }
76 
77     if (UnRegisterDevStateCallback() != DH_FWK_SUCCESS) {
78         DHLOGE("UnRegisterDevStateCallback failed");
79         return ERR_DH_FWK_ACCESS_UNREGISTER_DM_FAILED;
80     }
81     return DH_FWK_SUCCESS;
82 }
83 
InitDeviceManager()84 int32_t AccessManager::InitDeviceManager()
85 {
86     DHLOGI("start");
87     return DeviceManager::GetInstance().InitDeviceManager(DH_FWK_PKG_NAME, shared_from_this());
88 }
89 
UnInitDeviceManager()90 int32_t AccessManager::UnInitDeviceManager()
91 {
92     DHLOGI("start");
93     return DeviceManager::GetInstance().UnInitDeviceManager(DH_FWK_PKG_NAME);
94 }
95 
RegisterDevStateCallback()96 int32_t AccessManager::RegisterDevStateCallback()
97 {
98     return DeviceManager::GetInstance().RegisterDevStateCallback(DH_FWK_PKG_NAME, "", shared_from_this());
99 }
100 
UnRegisterDevStateCallback()101 int32_t AccessManager::UnRegisterDevStateCallback()
102 {
103     return DeviceManager::GetInstance().UnRegisterDevStateCallback(DH_FWK_PKG_NAME);
104 }
105 
RegDevTrustChangeCallback()106 int32_t AccessManager::RegDevTrustChangeCallback()
107 {
108     return DeviceManager::GetInstance().RegDevTrustChangeCallback(DH_FWK_PKG_NAME, shared_from_this());
109 }
110 
OnRemoteDied()111 void AccessManager::OnRemoteDied()
112 {
113     for (int32_t tryCount = 0; tryCount < DH_RETRY_INIT_DM_COUNT; ++tryCount) {
114         usleep(DH_RETRY_INIT_DM_INTERVAL_US);
115         if (Init() == DH_FWK_SUCCESS) {
116             DHLOGI("DeviceManager onDied, try to init success, tryCount = %{public}d", tryCount);
117             return;
118         }
119         DHLOGW("DeviceManager onDied, try to init failed, tryCount = %{public}d", tryCount);
120     }
121     DHLOGE("DeviceManager onDied, try to init has reached the maximum, but still failed");
122     return;
123 }
124 
OnDeviceOnline(const DmDeviceInfo &deviceInfo)125 void AccessManager::OnDeviceOnline(const DmDeviceInfo &deviceInfo)
126 {
127     std::lock_guard<std::mutex> lock(accessMutex_);
128     DHLOGI("AccessManager online, networkId: %{public}s, deviceName: %{public}s, deviceTypeId: %{public}d",
129         GetAnonyString(deviceInfo.networkId).c_str(), GetAnonyString(deviceInfo.deviceName).c_str(),
130         deviceInfo.deviceTypeId);
131 
132     auto networkId = std::string(deviceInfo.networkId);
133     if (!IsIdLengthValid(networkId)) {
134         return;
135     }
136     auto uuid = GetUUIDByDm(networkId);
137     if (!IsIdLengthValid(uuid)) {
138         return;
139     }
140     auto udid = GetUDIDByDm(networkId);
141     if (!IsIdLengthValid(udid)) {
142         return;
143     }
144     int32_t osType = GetDeviceSystemType(deviceInfo.extraData);
145     auto ret = DistributedHardwareManagerFactory::GetInstance().SendOnLineEvent(networkId, uuid, udid,
146         deviceInfo.deviceTypeId, osType);
147     DHLOGI("AccessManager online result: %{public}d, networkId: %{public}s, uuid: %{public}s, udid: %{public}s,"
148         "osType = %{public}d", ret, GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str(),
149         GetAnonyString(udid).c_str(), osType);
150 }
151 
OnDeviceOffline(const DmDeviceInfo &deviceInfo)152 void AccessManager::OnDeviceOffline(const DmDeviceInfo &deviceInfo)
153 {
154     std::lock_guard<std::mutex> lock(accessMutex_);
155     DHLOGI("AccessManager offline, networkId: %{public}s, deviceName: %{public}s, deviceTypeId: %{public}d",
156         GetAnonyString(deviceInfo.networkId).c_str(), GetAnonyString(deviceInfo.deviceName).c_str(),
157         deviceInfo.deviceTypeId);
158 
159     auto networkId = std::string(deviceInfo.networkId);
160     if (!IsIdLengthValid(networkId)) {
161         return;
162     }
163     std::string uuid = DHContext::GetInstance().GetUUIDByNetworkId(networkId);
164     if (!IsIdLengthValid(uuid)) {
165         return;
166     }
167     std::string udid = DHContext::GetInstance().GetUDIDByNetworkId(networkId);
168     if (!IsIdLengthValid(udid)) {
169         return;
170     }
171 
172     auto ret = DistributedHardwareManagerFactory::GetInstance().SendOffLineEvent(networkId, uuid, udid,
173         deviceInfo.deviceTypeId);
174     DHLOGI("offline result: %{public}d, networkId: %{public}s, uuid: %{public}s, udid: %{public}s",
175         ret, GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str(), GetAnonyString(udid).c_str());
176 }
177 
OnDeviceReady(const DmDeviceInfo &deviceInfo)178 void AccessManager::OnDeviceReady(const DmDeviceInfo &deviceInfo)
179 {
180     (void)deviceInfo;
181     return;
182 }
183 
OnDeviceChanged(const DmDeviceInfo &deviceInfo)184 void AccessManager::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
185 {
186     (void)deviceInfo;
187     return;
188 }
189 
OnDeviceTrustChange(const std::string &peerudid, const std::string &peeruuid, DmAuthForm authform)190 void AccessManager::OnDeviceTrustChange(const std::string &peerudid, const std::string &peeruuid, DmAuthForm authform)
191 {
192     DHLOGI("Peerdevice logout, peerudid: %{public}s, peeruuid: %{public}s", GetAnonyString(peerudid).c_str(),
193         GetAnonyString(peeruuid).c_str());
194     if (!IsIdLengthValid(peerudid) || !IsIdLengthValid(peeruuid)) {
195         return;
196     }
197 
198     if (authform != DmAuthForm::IDENTICAL_ACCOUNT) {
199         DHLOGE("Peer is not same account");
200         return;
201     }
202     DistributedHardwareManagerFactory::GetInstance().ClearRemoteDeviceMetaInfoData(peerudid, peeruuid);
203 }
204 
CheckTrustedDeviceOnline()205 void AccessManager::CheckTrustedDeviceOnline()
206 {
207     std::vector<DmDeviceInfo> deviceList;
208     DeviceManager::GetInstance().GetTrustedDeviceList(DH_FWK_PKG_NAME, "", deviceList);
209     if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
210         DHLOGE("DeviceList size is invalid!");
211         return;
212     }
213     for (const auto &deviceInfo : deviceList) {
214         const auto networkId = std::string(deviceInfo.networkId);
215         const auto uuid = GetUUIDByDm(networkId);
216         const auto udid = GetUDIDByDm(networkId);
217         int32_t osType = GetDeviceSystemType(deviceInfo.extraData);
218         DHLOGI("Send trusted device online, networkId = %{public}s, uuid = %{public}s, udid = %{public}s,"
219             "osType = %{public}d", GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str(),
220             GetAnonyString(udid).c_str(), osType);
221         DistributedHardwareManagerFactory::GetInstance().SendOnLineEvent(networkId, uuid, udid,
222             deviceInfo.deviceTypeId, osType);
223     }
224 }
225 
Dump(const std::vector<std::string> &argsStr, std::string &result)226 int32_t AccessManager::Dump(const std::vector<std::string> &argsStr, std::string &result)
227 {
228     return DistributedHardwareManagerFactory::GetInstance().Dump(argsStr, result);
229 }
230 } // namespace DistributedHardware
231 } // namespace OHOS
232