1 /*
2  * Copyright (c) 2023 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 "ddm_adapter_impl.h"
17 
18 #include <algorithm>
19 
20 #include "devicestatus_define.h"
21 #include "i_dsoftbus_adapter.h"
22 #include "ipc_skeleton.h"
23 #include "ohos_account_kits.h"
24 #include "os_account_manager.h"
25 #include "utility.h"
26 
27 #undef LOG_TAG
28 #define LOG_TAG "DDMAdapterImpl"
29 
30 namespace OHOS {
31 namespace Msdp {
32 namespace DeviceStatus {
33 #define D_DEV_MGR   DistributedHardware::DeviceManager::GetInstance()
34 
~DDMAdapterImpl()35 DDMAdapterImpl::~DDMAdapterImpl()
36 {
37     Disable();
38 }
39 
Enable()40 int32_t DDMAdapterImpl::Enable()
41 {
42     CALL_DEBUG_ENTER;
43     std::lock_guard guard(lock_);
44     std::string pkgName(FI_PKG_NAME);
45     std::string extra;
46     initCb_ = std::make_shared<DmInitCb>();
47 
48     int32_t ret = D_DEV_MGR.InitDeviceManager(pkgName, initCb_);
49     if (ret != 0) {
50         FI_HILOGE("DM::InitDeviceManager fail");
51         goto INIT_FAIL;
52     }
53     boardStateCb_ = std::make_shared<DmBoardStateCb>(shared_from_this());
54 
55     ret = D_DEV_MGR.RegisterDevStateCallback(pkgName, extra, boardStateCb_);
56     if (ret != 0) {
57         FI_HILOGE("DM::RegisterDevStateCallback fail");
58         goto REG_FAIL;
59     }
60     return RET_OK;
61 
62 REG_FAIL:
63     ret = D_DEV_MGR.UnInitDeviceManager(pkgName);
64     if (ret != 0) {
65         FI_HILOGE("DM::UnInitDeviceManager fail");
66     }
67     boardStateCb_.reset();
68 
69 INIT_FAIL:
70     initCb_.reset();
71     return RET_ERR;
72 }
73 
Disable()74 void DDMAdapterImpl::Disable()
75 {
76     CALL_DEBUG_ENTER;
77     std::lock_guard guard(lock_);
78     std::string pkgName(FI_PKG_NAME);
79 
80     if (boardStateCb_ != nullptr) {
81         boardStateCb_.reset();
82         int32_t ret = D_DEV_MGR.UnRegisterDevStateCallback(pkgName);
83         if (ret != 0) {
84             FI_HILOGE("DM::UnRegisterDevStateCallback fail");
85         }
86     }
87     if (initCb_ != nullptr) {
88         initCb_.reset();
89         int32_t ret = D_DEV_MGR.UnInitDeviceManager(pkgName);
90         if (ret != 0) {
91             FI_HILOGE("DM::UnInitDeviceManager fail");
92         }
93     }
94 }
95 
AddBoardObserver(std::shared_ptr<IBoardObserver> observer)96 void DDMAdapterImpl::AddBoardObserver(std::shared_ptr<IBoardObserver> observer)
97 {
98     CALL_DEBUG_ENTER;
99     std::lock_guard guard(lock_);
100     CHKPV(observer);
101     observers_.erase(Observer());
102     observers_.emplace(observer);
103 }
104 
RemoveBoardObserver(std::shared_ptr<IBoardObserver> observer)105 void DDMAdapterImpl::RemoveBoardObserver(std::shared_ptr<IBoardObserver> observer)
106 {
107     CALL_DEBUG_ENTER;
108     std::lock_guard guard(lock_);
109     CHKPV(observer);
110     observers_.erase(Observer());
111     if (auto iter = observers_.find(Observer(observer)); iter != observers_.end()) {
112         observers_.erase(iter);
113     }
114 }
115 
GetTrustedDeviceList(std::vector<DistributedHardware::DmDeviceInfo> & deviceList)116 int32_t DDMAdapterImpl::GetTrustedDeviceList(std::vector<DistributedHardware::DmDeviceInfo> &deviceList)
117 {
118     CALL_INFO_TRACE;
119     deviceList.clear();
120     if (int32_t ret = D_DEV_MGR.GetTrustedDeviceList(FI_PKG_NAME, "", deviceList); ret != RET_OK) {
121         FI_HILOGE("GetTrustedDeviceList failed, ret %{public}d.", ret);
122         return RET_ERR;
123     }
124     return RET_OK;
125 }
126 
CheckSameAccountToLocal(const std::string & networkId)127 bool DDMAdapterImpl::CheckSameAccountToLocal(const std::string &networkId)
128 {
129     CALL_INFO_TRACE;
130     std::vector<int32_t> ids;
131     ErrCode ret = OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
132     if (ret != ERR_OK || ids.empty()) {
133         FI_HILOGE("Get userId from active Os AccountIds fail, ret : %{public}d", ret);
134         return false;
135     }
136     OHOS::AccountSA::OhosAccountInfo osAccountInfo;
137     ret = OHOS::AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfo(osAccountInfo);
138     if (ret != 0 || osAccountInfo.uid_ == "") {
139         FI_HILOGE("Get accountId from Ohos account info fail, ret: %{public}d.", ret);
140         return false;
141     }
142     DistributedHardware::DmAccessCaller Caller = {
143         .accountId = osAccountInfo.uid_,
144         .networkId = IDSoftbusAdapter::GetLocalNetworkId(),
145         .userId = ids[0],
146         .tokenId = IPCSkeleton::GetCallingTokenID(),
147     };
148     DistributedHardware::DmAccessCallee Callee = {
149         .networkId = networkId,
150         .peerId = "",
151     };
152     if (D_DEV_MGR.CheckIsSameAccount(Caller, Callee)) {
153             return true;
154         }
155     FI_HILOGI("check same account fail, will try check access Group by hichain");
156     return false;
157 }
158 
OnBoardOnline(const std::string & networkId)159 void DDMAdapterImpl::OnBoardOnline(const std::string &networkId)
160 {
161     CALL_DEBUG_ENTER;
162     std::lock_guard guard(lock_);
163     FI_HILOGI("Board \'%{public}s\' is online", Utility::Anonymize(networkId).c_str());
164     std::for_each(observers_.cbegin(), observers_.cend(),
165         [&networkId](const auto &item) {
166             if (auto observer = item.Lock(); observer != nullptr) {
167                 observer->OnBoardOnline(networkId);
168             }
169         });
170 }
171 
OnBoardOffline(const std::string & networkId)172 void DDMAdapterImpl::OnBoardOffline(const std::string &networkId)
173 {
174     CALL_DEBUG_ENTER;
175     std::lock_guard guard(lock_);
176     FI_HILOGI("Board \'%{public}s\' is offline", Utility::Anonymize(networkId).c_str());
177     std::for_each(observers_.cbegin(), observers_.cend(),
178         [&networkId](const auto &item) {
179             if (auto observer = item.Lock(); observer != nullptr) {
180                 observer->OnBoardOffline(networkId);
181             }
182         });
183 }
184 } // namespace DeviceStatus
185 } // namespace Msdp
186 } // namespace OHOS
187