• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-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 
16 #include "device/dev_profile.h"
17 #include <thread>
18 
19 #include "device/device_profile_proxy.h"
20 #include "device/dm_adapter.h"
21 #include "ffrt/ffrt_utils.h"
22 #include "pasteboard_error.h"
23 #include "pasteboard_event_ue.h"
24 #include "pasteboard_hilog.h"
25 namespace OHOS {
26 namespace MiscServices {
27 constexpr const char *UE_SWITCH_OPERATION = "PASTEBOARD_SWITCH_OPERATION";
28 
GetInstance()29 DevProfile &DevProfile::GetInstance()
30 {
31     static DevProfile instance;
32     return instance;
33 }
34 
OnProfileUpdate(const std::string & udid,bool status)35 void DevProfile::OnProfileUpdate(const std::string &udid, bool status)
36 {
37     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "udid=%{public}.5s, status=%{public}d", udid.c_str(), status);
38     DevProfile::GetInstance().UpdateEnabledStatus(udid, status);
39     DevProfile::GetInstance().Notify(status);
40 }
41 
PostDelayReleaseProxy()42 void DevProfile::PostDelayReleaseProxy()
43 {
44     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "post delay task start");
45     constexpr uint32_t DELAY_TIME = 60 * 1000; // 60s
46     static FFRTTimer ffrtTimer("release_dp_proxy");
47 
48     FFRTTask task = [this]() {
49         std::thread thread([=]() {
50             std::lock_guard lock(proxyMutex_);
51             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "execute delay task");
52             if (proxy_ == nullptr) {
53                 return;
54             }
55 
56             if (subscribeUdidList_.empty()) {
57                 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "deinit dp proxy");
58                 proxy_ = nullptr;
59             }
60         });
61         thread.detach();
62     };
63 
64     ffrtTimer.SetTimer("release_dp_proxy", task, DELAY_TIME);
65     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "post delay task end");
66 }
67 
PutDeviceStatus(bool status)68 void DevProfile::PutDeviceStatus(bool status)
69 {
70     std::string networkId = DMAdapter::GetInstance().GetLocalNetworkId();
71     std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
72     PASTEBOARD_CHECK_AND_RETURN_LOGE(!udid.empty(), PASTEBOARD_MODULE_SERVICE,
73         "get udid failed, netId=%{public}.5s", networkId.c_str());
74 
75     UpdateEnabledStatus(udid, status);
76     UE_SWITCH(UE_SWITCH_OPERATION, UeReporter::UE_OPERATION_TYPE, status ?
77         UeReporter::SwitchStatus::SWITCH_OPEN : UeReporter::SwitchStatus::SWITCH_CLOSE);
78 
79     std::lock_guard lock(proxyMutex_);
80     PostDelayReleaseProxy();
81     if (proxy_ == nullptr) {
82         proxy_ = std::make_shared<DeviceProfileProxy>();
83     }
84     auto adapter = proxy_->GetAdapter();
85     PASTEBOARD_CHECK_AND_RETURN_LOGE(adapter != nullptr, PASTEBOARD_MODULE_SERVICE, "adapter is null");
86     int32_t ret = adapter->PutDeviceStatus(udid, status);
87     PASTEBOARD_CHECK_AND_RETURN_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), PASTEBOARD_MODULE_SERVICE,
88         "put dp status failed, ret=%{public}d", ret);
89 
90     Notify(status);
91 }
92 
GetDeviceStatus(const std::string & networkId,bool & status)93 int32_t DevProfile::GetDeviceStatus(const std::string &networkId, bool &status)
94 {
95     std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
96     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(!udid.empty(),
97         static_cast<int32_t>(PasteboardError::GET_LOCAL_DEVICE_ID_ERROR), PASTEBOARD_MODULE_SERVICE,
98         "get udid failed, netId=%{public}.5s", networkId.c_str());
99 
100     bool cachedStatus = enabledStatusCache_.ComputeIfPresent(udid, [&status](const auto &key, auto &value) {
101         status = value;
102         return true;
103     });
104     if (cachedStatus) {
105         return static_cast<int32_t>(PasteboardError::E_OK);
106     }
107 
108     std::lock_guard lock(proxyMutex_);
109     PostDelayReleaseProxy();
110     if (proxy_ == nullptr) {
111         proxy_ = std::make_shared<DeviceProfileProxy>();
112     }
113     auto adapter = proxy_->GetAdapter();
114     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(adapter != nullptr, static_cast<int32_t>(PasteboardError::DLOPEN_FAILED),
115         PASTEBOARD_MODULE_SERVICE, "adapter is null");
116     int32_t ret = adapter->GetDeviceStatus(udid, status);
117     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
118         PASTEBOARD_MODULE_SERVICE, "get dp status failed, udid=%{public}.5s, ret=%{public}d", udid.c_str(), ret);
119 
120     UpdateEnabledStatus(udid, status);
121     return static_cast<int32_t>(PasteboardError::E_OK);
122 }
123 
GetDeviceVersion(const std::string & networkId,uint32_t & versionId)124 bool DevProfile::GetDeviceVersion(const std::string &networkId, uint32_t &versionId)
125 {
126     std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
127     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(!udid.empty(), false,
128         PASTEBOARD_MODULE_SERVICE, "get udid failed, netId=%{public}.5s", networkId.c_str());
129 
130     std::lock_guard lock(proxyMutex_);
131     PostDelayReleaseProxy();
132     if (proxy_ == nullptr) {
133         proxy_ = std::make_shared<DeviceProfileProxy>();
134     }
135     auto adapter = proxy_->GetAdapter();
136     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(adapter != nullptr, false, PASTEBOARD_MODULE_SERVICE, "adapter is null");
137     bool ret = adapter->GetDeviceVersion(udid, versionId);
138     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false,
139         PASTEBOARD_MODULE_SERVICE, "get dp version failed, udid=%{public}.5s", udid.c_str());
140 
141     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "netid=%{public}.5s, udid=%{public}.5s, version=%{public}u",
142         networkId.c_str(), udid.c_str(), versionId);
143     return true;
144 }
145 
SubscribeProfileEvent(const std::string & networkId)146 void DevProfile::SubscribeProfileEvent(const std::string &networkId)
147 {
148     std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
149     PASTEBOARD_CHECK_AND_RETURN_LOGE(!udid.empty(), PASTEBOARD_MODULE_SERVICE,
150         "get udid failed, netId=%{public}.5s", networkId.c_str());
151 
152     std::lock_guard lock(proxyMutex_);
153     PostDelayReleaseProxy();
154     if (proxy_ == nullptr) {
155         proxy_ = std::make_shared<DeviceProfileProxy>();
156     }
157     auto adapter = proxy_->GetAdapter();
158     PASTEBOARD_CHECK_AND_RETURN_LOGE(adapter != nullptr, PASTEBOARD_MODULE_SERVICE, "adapter is null");
159 
160     int32_t ret = adapter->RegisterUpdateCallback(&DevProfile::OnProfileUpdate);
161     PASTEBOARD_CHECK_AND_RETURN_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), PASTEBOARD_MODULE_SERVICE,
162         "register dp update callback failed, ret=%{public}d", ret);
163 
164     ret = adapter->SubscribeProfileEvent(udid);
165     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "udid=%{public}.5s, ret=%{public}d", udid.c_str(), ret);
166 
167     subscribeUdidList_.emplace(udid);
168 }
169 
UnSubscribeProfileEvent(const std::string & networkId)170 void DevProfile::UnSubscribeProfileEvent(const std::string &networkId)
171 {
172     std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
173     PASTEBOARD_CHECK_AND_RETURN_LOGE(!udid.empty(), PASTEBOARD_MODULE_SERVICE,
174         "get udid failed, netId=%{public}.5s", networkId.c_str());
175 
176     std::lock_guard lock(proxyMutex_);
177     PostDelayReleaseProxy();
178     if (proxy_ == nullptr) {
179         proxy_ = std::make_shared<DeviceProfileProxy>();
180     }
181     auto adapter = proxy_->GetAdapter();
182     PASTEBOARD_CHECK_AND_RETURN_LOGE(adapter != nullptr, PASTEBOARD_MODULE_SERVICE, "adapter is null");
183 
184     int32_t ret = adapter->UnSubscribeProfileEvent(udid);
185     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "udid=%{public}.5s, ret=%{public}d", udid.c_str(), ret);
186 
187     subscribeUdidList_.erase(udid);
188 }
189 
UnSubscribeAllProfileEvents()190 void DevProfile::UnSubscribeAllProfileEvents()
191 {
192     std::lock_guard lock(proxyMutex_);
193     PASTEBOARD_CHECK_AND_RETURN_LOGD(!subscribeUdidList_.empty(), PASTEBOARD_MODULE_SERVICE, "udid list empty");
194 
195     PostDelayReleaseProxy();
196     if (proxy_ == nullptr) {
197         proxy_ = std::make_shared<DeviceProfileProxy>();
198     }
199     auto adapter = proxy_->GetAdapter();
200     PASTEBOARD_CHECK_AND_RETURN_LOGE(adapter != nullptr, PASTEBOARD_MODULE_SERVICE, "adapter is null");
201 
202     int32_t ret = static_cast<int32_t>(PasteboardError::E_OK);
203     for (const std::string &udid : subscribeUdidList_) {
204         ret = adapter->UnSubscribeProfileEvent(udid);
205         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "udid=%{public}.5s, ret=%{public}d", udid.c_str(), ret);
206     }
207 
208     subscribeUdidList_.clear();
209 }
210 
SendSubscribeInfos()211 void DevProfile::SendSubscribeInfos()
212 {
213     std::lock_guard lock(proxyMutex_);
214     PASTEBOARD_CHECK_AND_RETURN_LOGD(!subscribeUdidList_.empty(), PASTEBOARD_MODULE_SERVICE, "udid list empty");
215 
216     PostDelayReleaseProxy();
217     if (proxy_ == nullptr) {
218         proxy_ = std::make_shared<DeviceProfileProxy>();
219     }
220     auto adapter = proxy_->GetAdapter();
221     PASTEBOARD_CHECK_AND_RETURN_LOGE(adapter != nullptr, PASTEBOARD_MODULE_SERVICE, "adapter is null");
222 
223     adapter->SendSubscribeInfos();
224 }
225 
ClearDeviceProfileService()226 void DevProfile::ClearDeviceProfileService()
227 {
228     std::lock_guard lock(proxyMutex_);
229     PASTEBOARD_CHECK_AND_RETURN_LOGD(proxy_ != nullptr, PASTEBOARD_MODULE_SERVICE, "not need clear");
230 
231     enabledStatusCache_.Clear();
232     PostDelayReleaseProxy();
233     auto adapter = proxy_->GetAdapter();
234     PASTEBOARD_CHECK_AND_RETURN_LOGE(adapter != nullptr, PASTEBOARD_MODULE_SERVICE, "adapter is null");
235 
236     adapter->ClearDeviceProfileService();
237 }
238 
Watch(Observer observer)239 void DevProfile::Watch(Observer observer)
240 {
241     observer_ = std::move(observer);
242 }
243 
Notify(bool isEnable)244 void DevProfile::Notify(bool isEnable)
245 {
246     if (observer_ != nullptr) {
247         observer_(isEnable);
248     }
249 }
250 
UpdateEnabledStatus(const std::string & udid,bool status)251 void DevProfile::UpdateEnabledStatus(const std::string &udid, bool status)
252 {
253     enabledStatusCache_.Compute(udid, [&status](const auto &key, auto &value) {
254         value = status;
255         return true;
256     });
257 }
258 
EraseEnabledStatus(const std::string & udid)259 void DevProfile::EraseEnabledStatus(const std::string &udid)
260 {
261     enabledStatusCache_.Erase(udid);
262 }
263 } // namespace MiscServices
264 } // namespace OHOS
265