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 #include "dev_manager.h"
16 
17 #include <logger.h>
18 #include <thread>
19 
20 #include "device_manager.h"
21 #include "device_manager_callback.h"
22 #include "dm_device_info.h"
23 #include "softbus_adapter.h"
24 #include "app_types.h"
25 
26 namespace OHOS {
27 namespace ObjectStore {
28 using namespace OHOS::DistributedHardware;
29 using DevInfo = OHOS::DistributedHardware::DmDeviceInfo;
30 constexpr int32_t DM_OK = 0;
31 constexpr int32_t DM_ERROR = -1;
32 constexpr const char *PKG_NAME = "ohos.objectstore";
33 class DMStateCallback : public DeviceStateCallback {
34 public:
DMStateCallback(std::shared_ptr<SoftBusAdapter> softBusAdapter)35     explicit DMStateCallback(std::shared_ptr<SoftBusAdapter> softBusAdapter) : softBusAdapter_(softBusAdapter){};
36     void OnDeviceOnline(const DmDeviceInfo &deviceInfo) override;
37     void OnDeviceOffline(const DmDeviceInfo &deviceInfo) override;
38     void OnDeviceChanged(const DmDeviceInfo &deviceInfo) override;
39     void OnDeviceReady(const DmDeviceInfo &deviceInfo) override;
40 
41 private:
42     std::shared_ptr<SoftBusAdapter> softBusAdapter_;
43     void NotifyAll(const DmDeviceInfo &deviceInfo, DeviceChangeType type);
44 };
45 
OnDeviceOnline(const DmDeviceInfo & deviceInfo)46 void DMStateCallback::OnDeviceOnline(const DmDeviceInfo &deviceInfo)
47 {
48     std::string uuid = DevManager::GetInstance()->GetUuidByNodeId(std::string(deviceInfo.networkId));
49     LOG_INFO("[Online] id:%{public}s, name:%{public}s, typeId:%{public}d", SoftBusAdapter::ToBeAnonymous(uuid).c_str(),
50         deviceInfo.deviceName, deviceInfo.deviceTypeId);
51     NotifyAll(deviceInfo, DeviceChangeType::DEVICE_ONLINE);
52 }
53 
OnDeviceOffline(const DmDeviceInfo & deviceInfo)54 void DMStateCallback::OnDeviceOffline(const DmDeviceInfo &deviceInfo)
55 {
56     std::string uuid = DevManager::GetInstance()->GetUuidByNodeId(std::string(deviceInfo.networkId));
57     LOG_INFO("[Offline] id:%{public}s, name:%{public}s, typeId:%{public}d",
58         SoftBusAdapter::ToBeAnonymous(uuid).c_str(), deviceInfo.deviceName, deviceInfo.deviceTypeId);
59     NotifyAll(deviceInfo, DeviceChangeType::DEVICE_OFFLINE);
60 }
61 
OnDeviceChanged(const DmDeviceInfo & deviceInfo)62 void DMStateCallback::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
63 {
64     std::string uuid = DevManager::GetInstance()->GetUuidByNodeId(std::string(deviceInfo.networkId));
65     LOG_INFO("[InfoChange] id:%{public}s, name:%{public}s", SoftBusAdapter::ToBeAnonymous(uuid).c_str(),
66         deviceInfo.deviceName);
67 }
68 
OnDeviceReady(const DmDeviceInfo & deviceInfo)69 void DMStateCallback::OnDeviceReady(const DmDeviceInfo &deviceInfo)
70 {
71 }
72 
73 class DmDeathCallback : public DmInitCallback {
74 public:
DmDeathCallback(DevManager & devManager)75     explicit DmDeathCallback(DevManager &devManager) : devManager_(devManager){};
76     void OnRemoteDied() override;
77 
78 private:
79     DevManager &devManager_;
80 };
81 
OnRemoteDied()82 void DmDeathCallback::OnRemoteDied()
83 {
84     LOG_INFO("dm device manager died, init it again");
85     devManager_.RegisterDevCallback();
86 }
87 
NotifyAll(const DmDeviceInfo & deviceInfo,DeviceChangeType type)88 void DMStateCallback::NotifyAll(const DmDeviceInfo &deviceInfo, DeviceChangeType type)
89 {
90     DeviceInfo di = { std::string(deviceInfo.networkId), std::string(deviceInfo.deviceName),
91         std::to_string(deviceInfo.deviceTypeId) };
92     softBusAdapter_->NotifyAll(di, type);
93 }
94 
DevManager()95 DevManager::DevManager()
96 {
97 }
98 
~DevManager()99 DevManager::~DevManager()
100 {
101 }
102 
Init()103 int32_t DevManager::Init()
104 {
105     auto &deviceManager = DeviceManager::GetInstance();
106     auto deviceInitCallback = std::make_shared<DmDeathCallback>(*this);
107     auto deviceStateCallback = std::make_shared<DMStateCallback>(SoftBusAdapter::GetInstance());
108     int32_t status = deviceManager.InitDeviceManager(PKG_NAME, deviceInitCallback);
109     if (status != DM_OK) {
110         return status;
111     }
112     status = deviceManager.RegisterDevStateCallback(PKG_NAME, "", deviceStateCallback);
113     return status;
114 }
115 
RegisterDevCallback()116 void DevManager::RegisterDevCallback()
117 {
118     int32_t status = Init();
119     if (status == DM_OK) {
120         return;
121     }
122     LOG_INFO("register device callback failed, try again.");
123     std::thread th = std::thread([this]() {
124         pthread_setname_np(pthread_self(), "Data_Object_InitDevManager");
125         constexpr int RETRY_TIMES = 300;
126         int i = 0;
127         int32_t status = DM_ERROR;
128         while (i++ < RETRY_TIMES) {
129             status = Init();
130             if (status == DM_OK) {
131                 break;
132             }
133             std::this_thread::sleep_for(std::chrono::milliseconds(100));
134         }
135         LOG_INFO("register device callback exit now: %{public}d times, status: %{public}d", i, status);
136     });
137     th.detach();
138 }
139 
GetUuidByNodeId(const std::string & nodeId) const140 std::string DevManager::GetUuidByNodeId(const std::string &nodeId) const
141 {
142     std::string uuid = "";
143     int32_t ret = DistributedHardware::DeviceManager::GetInstance().GetEncryptedUuidByNetworkId(
144         "ohos.objectstore", nodeId.c_str(), uuid);
145     if (ret != DM_OK) {
146         LOG_WARN("GetEncryptedUuidByNetworkId error, nodeId:%{public}s", SoftBusAdapter::ToBeAnonymous(nodeId).c_str());
147         return "";
148     }
149     return uuid;
150 }
151 
GetLocalDevice()152 const DevManager::DetailInfo &DevManager::GetLocalDevice()
153 {
154     std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
155     if (!localInfo_.uuid.empty()) {
156         return localInfo_;
157     }
158     DevInfo info;
159     auto ret = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, info);
160     if (ret != DM_OK) {
161         LOG_ERROR("get local device info fail");
162         return invalidDetail_;
163     }
164     auto networkId = std::string(info.networkId);
165     std::string uuid;
166     DeviceManager::GetInstance().GetEncryptedUuidByNetworkId(PKG_NAME, networkId, uuid);
167     if (uuid.empty() || networkId.empty()) {
168         return invalidDetail_;
169     }
170     localInfo_.networkId = std::move(networkId);
171     localInfo_.uuid = std::move(uuid);
172     return localInfo_;
173 }
174 } // namespace ObjectStore
175 } // namespace OHOS