1c29fa5a6Sopenharmony_ci/*
2c29fa5a6Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3c29fa5a6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4c29fa5a6Sopenharmony_ci * you may not use this file except in compliance with the License.
5c29fa5a6Sopenharmony_ci * You may obtain a copy of the License at
6c29fa5a6Sopenharmony_ci *
7c29fa5a6Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8c29fa5a6Sopenharmony_ci *
9c29fa5a6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10c29fa5a6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11c29fa5a6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c29fa5a6Sopenharmony_ci * See the License for the specific language governing permissions and
13c29fa5a6Sopenharmony_ci * limitations under the License.
14c29fa5a6Sopenharmony_ci */
15c29fa5a6Sopenharmony_ci
16c29fa5a6Sopenharmony_ci#include "cooperate_context.h"
17c29fa5a6Sopenharmony_ci
18c29fa5a6Sopenharmony_ci#include <algorithm>
19c29fa5a6Sopenharmony_ci
20c29fa5a6Sopenharmony_ci#include "cooperate_hisysevent.h"
21c29fa5a6Sopenharmony_ci#include "ddm_adapter.h"
22c29fa5a6Sopenharmony_ci#include "devicestatus_define.h"
23c29fa5a6Sopenharmony_ci#include "dsoftbus_handler.h"
24c29fa5a6Sopenharmony_ci#include "utility.h"
25c29fa5a6Sopenharmony_ci
26c29fa5a6Sopenharmony_ci#undef LOG_TAG
27c29fa5a6Sopenharmony_ci#define LOG_TAG "CooperateContext"
28c29fa5a6Sopenharmony_ci
29c29fa5a6Sopenharmony_cinamespace OHOS {
30c29fa5a6Sopenharmony_cinamespace Msdp {
31c29fa5a6Sopenharmony_cinamespace DeviceStatus {
32c29fa5a6Sopenharmony_cinamespace Cooperate {
33c29fa5a6Sopenharmony_cinamespace {
34c29fa5a6Sopenharmony_ciconst std::string COOPERATE_SWITCH { "currentStatus" };
35c29fa5a6Sopenharmony_ciconst std::string THREAD_NAME { "os_Cooperate_EventHandler" };
36c29fa5a6Sopenharmony_ciconstexpr double PERCENT { 100.0 };
37c29fa5a6Sopenharmony_ci} // namespace
38c29fa5a6Sopenharmony_ci
39c29fa5a6Sopenharmony_ciclass BoardObserver final : public IBoardObserver {
40c29fa5a6Sopenharmony_cipublic:
41c29fa5a6Sopenharmony_ci    explicit BoardObserver(Channel<CooperateEvent>::Sender sender) : sender_(sender) {}
42c29fa5a6Sopenharmony_ci    ~BoardObserver() = default;
43c29fa5a6Sopenharmony_ci    DISALLOW_COPY_AND_MOVE(BoardObserver);
44c29fa5a6Sopenharmony_ci
45c29fa5a6Sopenharmony_ci    void OnBoardOnline(const std::string &networkId) override
46c29fa5a6Sopenharmony_ci    {
47c29fa5a6Sopenharmony_ci        FI_HILOGD("\'%{public}s\' is online", Utility::Anonymize(networkId).c_str());
48c29fa5a6Sopenharmony_ci        auto ret = sender_.Send(CooperateEvent(
49c29fa5a6Sopenharmony_ci            CooperateEventType::DDM_BOARD_ONLINE,
50c29fa5a6Sopenharmony_ci            DDMBoardOnlineEvent {
51c29fa5a6Sopenharmony_ci                .networkId = networkId
52c29fa5a6Sopenharmony_ci            }));
53c29fa5a6Sopenharmony_ci        if (ret != Channel<CooperateEvent>::NO_ERROR) {
54c29fa5a6Sopenharmony_ci            FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
55c29fa5a6Sopenharmony_ci        }
56c29fa5a6Sopenharmony_ci    }
57c29fa5a6Sopenharmony_ci
58c29fa5a6Sopenharmony_ci    void OnBoardOffline(const std::string &networkId) override
59c29fa5a6Sopenharmony_ci    {
60c29fa5a6Sopenharmony_ci        FI_HILOGD("\'%{public}s\' is offline", Utility::Anonymize(networkId).c_str());
61c29fa5a6Sopenharmony_ci        auto ret = sender_.Send(CooperateEvent(
62c29fa5a6Sopenharmony_ci            CooperateEventType::DDM_BOARD_OFFLINE,
63c29fa5a6Sopenharmony_ci            DDMBoardOfflineEvent {
64c29fa5a6Sopenharmony_ci                .networkId = networkId
65c29fa5a6Sopenharmony_ci            }));
66c29fa5a6Sopenharmony_ci        if (ret != Channel<CooperateEvent>::NO_ERROR) {
67c29fa5a6Sopenharmony_ci            FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
68c29fa5a6Sopenharmony_ci        }
69c29fa5a6Sopenharmony_ci    }
70c29fa5a6Sopenharmony_ci
71c29fa5a6Sopenharmony_ciprivate:
72c29fa5a6Sopenharmony_ci    Channel<CooperateEvent>::Sender sender_;
73c29fa5a6Sopenharmony_ci};
74c29fa5a6Sopenharmony_ci
75c29fa5a6Sopenharmony_ciclass HotplugObserver final : public IDeviceObserver {
76c29fa5a6Sopenharmony_cipublic:
77c29fa5a6Sopenharmony_ci    explicit HotplugObserver(Channel<CooperateEvent>::Sender sender) : sender_(sender) {}
78c29fa5a6Sopenharmony_ci    ~HotplugObserver() = default;
79c29fa5a6Sopenharmony_ci
80c29fa5a6Sopenharmony_ci    void OnDeviceAdded(std::shared_ptr<IDevice> dev) override;
81c29fa5a6Sopenharmony_ci    void OnDeviceRemoved(std::shared_ptr<IDevice> dev) override;
82c29fa5a6Sopenharmony_ci
83c29fa5a6Sopenharmony_ciprivate:
84c29fa5a6Sopenharmony_ci    Channel<CooperateEvent>::Sender sender_;
85c29fa5a6Sopenharmony_ci};
86c29fa5a6Sopenharmony_ci
87c29fa5a6Sopenharmony_civoid HotplugObserver::OnDeviceAdded(std::shared_ptr<IDevice> dev)
88c29fa5a6Sopenharmony_ci{
89c29fa5a6Sopenharmony_ci    CHKPV(dev);
90c29fa5a6Sopenharmony_ci    auto ret = sender_.Send(CooperateEvent(
91c29fa5a6Sopenharmony_ci        CooperateEventType::INPUT_HOTPLUG_EVENT,
92c29fa5a6Sopenharmony_ci        InputHotplugEvent {
93c29fa5a6Sopenharmony_ci            .deviceId = dev->GetId(),
94c29fa5a6Sopenharmony_ci            .type = InputHotplugType::PLUG,
95c29fa5a6Sopenharmony_ci            .isKeyboard = dev->IsKeyboard(),
96c29fa5a6Sopenharmony_ci        }));
97c29fa5a6Sopenharmony_ci    if (ret != Channel<CooperateEvent>::NO_ERROR) {
98c29fa5a6Sopenharmony_ci        FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
99c29fa5a6Sopenharmony_ci    }
100c29fa5a6Sopenharmony_ci}
101c29fa5a6Sopenharmony_ci
102c29fa5a6Sopenharmony_civoid HotplugObserver::OnDeviceRemoved(std::shared_ptr<IDevice> dev)
103c29fa5a6Sopenharmony_ci{
104c29fa5a6Sopenharmony_ci    CHKPV(dev);
105c29fa5a6Sopenharmony_ci    auto ret = sender_.Send(CooperateEvent(
106c29fa5a6Sopenharmony_ci        CooperateEventType::INPUT_HOTPLUG_EVENT,
107c29fa5a6Sopenharmony_ci        InputHotplugEvent {
108c29fa5a6Sopenharmony_ci            .deviceId = dev->GetId(),
109c29fa5a6Sopenharmony_ci            .type = InputHotplugType::UNPLUG,
110c29fa5a6Sopenharmony_ci            .isKeyboard = dev->IsKeyboard(),
111c29fa5a6Sopenharmony_ci        }));
112c29fa5a6Sopenharmony_ci    if (ret != Channel<CooperateEvent>::NO_ERROR) {
113c29fa5a6Sopenharmony_ci        FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
114c29fa5a6Sopenharmony_ci    }
115c29fa5a6Sopenharmony_ci}
116c29fa5a6Sopenharmony_ci
117c29fa5a6Sopenharmony_ciContext::Context(IContext *env)
118c29fa5a6Sopenharmony_ci    : dsoftbus_(env), eventMgr_(env), hotArea_(env), mouseLocation_(env), inputDevMgr_(env),
119c29fa5a6Sopenharmony_ci      inputEventBuilder_(env), inputEventInterceptor_(env), env_(env)
120c29fa5a6Sopenharmony_ci{}
121c29fa5a6Sopenharmony_ci
122c29fa5a6Sopenharmony_civoid Context::AttachSender(Channel<CooperateEvent>::Sender sender)
123c29fa5a6Sopenharmony_ci{
124c29fa5a6Sopenharmony_ci    sender_ = sender;
125c29fa5a6Sopenharmony_ci    dsoftbus_.AttachSender(sender);
126c29fa5a6Sopenharmony_ci}
127c29fa5a6Sopenharmony_ci
128c29fa5a6Sopenharmony_civoid Context::AddObserver(std::shared_ptr<ICooperateObserver> observer)
129c29fa5a6Sopenharmony_ci{
130c29fa5a6Sopenharmony_ci    CHKPV(observer);
131c29fa5a6Sopenharmony_ci    observers_.insert(observer);
132c29fa5a6Sopenharmony_ci}
133c29fa5a6Sopenharmony_ci
134c29fa5a6Sopenharmony_civoid Context::RemoveObserver(std::shared_ptr<ICooperateObserver> observer)
135c29fa5a6Sopenharmony_ci{
136c29fa5a6Sopenharmony_ci    observers_.erase(observer);
137c29fa5a6Sopenharmony_ci}
138c29fa5a6Sopenharmony_ci
139c29fa5a6Sopenharmony_civoid Context::Enable()
140c29fa5a6Sopenharmony_ci{
141c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
142c29fa5a6Sopenharmony_ci    StartEventHandler();
143c29fa5a6Sopenharmony_ci    EnableDDM();
144c29fa5a6Sopenharmony_ci    EnableDevMgr();
145c29fa5a6Sopenharmony_ci    EnableInputDevMgr();
146c29fa5a6Sopenharmony_ci}
147c29fa5a6Sopenharmony_ci
148c29fa5a6Sopenharmony_civoid Context::Disable()
149c29fa5a6Sopenharmony_ci{
150c29fa5a6Sopenharmony_ci    CALL_DEBUG_ENTER;
151c29fa5a6Sopenharmony_ci    DisableDevMgr();
152c29fa5a6Sopenharmony_ci    DisableDDM();
153c29fa5a6Sopenharmony_ci    DisableInputDevMgr();
154c29fa5a6Sopenharmony_ci    StopEventHandler();
155c29fa5a6Sopenharmony_ci}
156c29fa5a6Sopenharmony_ci
157c29fa5a6Sopenharmony_ciint32_t Context::StartEventHandler()
158c29fa5a6Sopenharmony_ci{
159c29fa5a6Sopenharmony_ci    auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME);
160c29fa5a6Sopenharmony_ci    CHKPR(runner, RET_ERR);
161c29fa5a6Sopenharmony_ci    eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
162c29fa5a6Sopenharmony_ci    return RET_OK;
163c29fa5a6Sopenharmony_ci}
164c29fa5a6Sopenharmony_ci
165c29fa5a6Sopenharmony_civoid Context::StopEventHandler()
166c29fa5a6Sopenharmony_ci{
167c29fa5a6Sopenharmony_ci    eventHandler_.reset();
168c29fa5a6Sopenharmony_ci}
169c29fa5a6Sopenharmony_ci
170c29fa5a6Sopenharmony_ciint32_t Context::EnableDDM()
171c29fa5a6Sopenharmony_ci{
172c29fa5a6Sopenharmony_ci    boardObserver_ = std::make_shared<BoardObserver>(sender_);
173c29fa5a6Sopenharmony_ci    ddm_.AddBoardObserver(boardObserver_);
174c29fa5a6Sopenharmony_ci    return ddm_.Enable();
175c29fa5a6Sopenharmony_ci}
176c29fa5a6Sopenharmony_ci
177c29fa5a6Sopenharmony_civoid Context::DisableDDM()
178c29fa5a6Sopenharmony_ci{
179c29fa5a6Sopenharmony_ci    ddm_.Disable();
180c29fa5a6Sopenharmony_ci    ddm_.RemoveBoardObserver(boardObserver_);
181c29fa5a6Sopenharmony_ci    boardObserver_.reset();
182c29fa5a6Sopenharmony_ci}
183c29fa5a6Sopenharmony_ci
184c29fa5a6Sopenharmony_ciint32_t Context::EnableDevMgr()
185c29fa5a6Sopenharmony_ci{
186c29fa5a6Sopenharmony_ci    hotplugObserver_ = std::make_shared<HotplugObserver>(sender_);
187c29fa5a6Sopenharmony_ci    env_->GetDeviceManager().AddDeviceObserver(hotplugObserver_);
188c29fa5a6Sopenharmony_ci    return RET_OK;
189c29fa5a6Sopenharmony_ci}
190c29fa5a6Sopenharmony_ci
191c29fa5a6Sopenharmony_civoid Context::DisableDevMgr()
192c29fa5a6Sopenharmony_ci{
193c29fa5a6Sopenharmony_ci    env_->GetDeviceManager().RemoveDeviceObserver(hotplugObserver_);
194c29fa5a6Sopenharmony_ci    hotplugObserver_.reset();
195c29fa5a6Sopenharmony_ci}
196c29fa5a6Sopenharmony_ci
197c29fa5a6Sopenharmony_ciint32_t Context::EnableInputDevMgr()
198c29fa5a6Sopenharmony_ci{
199c29fa5a6Sopenharmony_ci    inputDevMgr_.Enable();
200c29fa5a6Sopenharmony_ci    return RET_OK;
201c29fa5a6Sopenharmony_ci}
202c29fa5a6Sopenharmony_ci
203c29fa5a6Sopenharmony_civoid Context::DisableInputDevMgr()
204c29fa5a6Sopenharmony_ci{
205c29fa5a6Sopenharmony_ci    inputDevMgr_.Disable();
206c29fa5a6Sopenharmony_ci}
207c29fa5a6Sopenharmony_ci
208c29fa5a6Sopenharmony_ciNormalizedCoordinate Context::NormalizedCursorPosition() const
209c29fa5a6Sopenharmony_ci{
210c29fa5a6Sopenharmony_ci    auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
211c29fa5a6Sopenharmony_ci    if (display == nullptr) {
212c29fa5a6Sopenharmony_ci        FI_HILOGE("No default display");
213c29fa5a6Sopenharmony_ci        return cursorPos_;
214c29fa5a6Sopenharmony_ci    }
215c29fa5a6Sopenharmony_ci    Rectangle displayRect {
216c29fa5a6Sopenharmony_ci        .width = display->GetWidth(),
217c29fa5a6Sopenharmony_ci        .height = display->GetHeight(),
218c29fa5a6Sopenharmony_ci    };
219c29fa5a6Sopenharmony_ci    if ((displayRect.width <= 0) || (displayRect.height <= 0)) {
220c29fa5a6Sopenharmony_ci        FI_HILOGE("Invalid display information");
221c29fa5a6Sopenharmony_ci        return cursorPos_;
222c29fa5a6Sopenharmony_ci    }
223c29fa5a6Sopenharmony_ci    return NormalizedCoordinate {
224c29fa5a6Sopenharmony_ci        .x = static_cast<int32_t>((cursorPos_.x + 1) * PERCENT / displayRect.width),
225c29fa5a6Sopenharmony_ci        .y = static_cast<int32_t>((cursorPos_.y + 1) * PERCENT / displayRect.height),
226c29fa5a6Sopenharmony_ci    };
227c29fa5a6Sopenharmony_ci}
228c29fa5a6Sopenharmony_ci
229c29fa5a6Sopenharmony_civoid Context::EnableCooperate(const EnableCooperateEvent &event)
230c29fa5a6Sopenharmony_ci{
231c29fa5a6Sopenharmony_ci}
232c29fa5a6Sopenharmony_ci
233c29fa5a6Sopenharmony_civoid Context::DisableCooperate(const DisableCooperateEvent &event)
234c29fa5a6Sopenharmony_ci{
235c29fa5a6Sopenharmony_ci}
236c29fa5a6Sopenharmony_ci
237c29fa5a6Sopenharmony_civoid Context::StartCooperate(const StartCooperateEvent &event)
238c29fa5a6Sopenharmony_ci{
239c29fa5a6Sopenharmony_ci    remoteNetworkId_ = event.remoteNetworkId;
240c29fa5a6Sopenharmony_ci    startDeviceId_ = event.startDeviceId;
241c29fa5a6Sopenharmony_ci}
242c29fa5a6Sopenharmony_ci
243c29fa5a6Sopenharmony_civoid Context::OnPointerEvent(const InputPointerEvent &event)
244c29fa5a6Sopenharmony_ci{
245c29fa5a6Sopenharmony_ci    if ((event.sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
246c29fa5a6Sopenharmony_ci        ((event.pointerAction == MMI::PointerEvent::POINTER_ACTION_MOVE) ||
247c29fa5a6Sopenharmony_ci         (event.pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_MOVE))) {
248c29fa5a6Sopenharmony_ci        cursorPos_ = event.position;
249c29fa5a6Sopenharmony_ci    }
250c29fa5a6Sopenharmony_ci}
251c29fa5a6Sopenharmony_ci
252c29fa5a6Sopenharmony_civoid Context::RemoteStartSuccess(const DSoftbusStartCooperateFinished &event)
253c29fa5a6Sopenharmony_ci{
254c29fa5a6Sopenharmony_ci    remoteNetworkId_ = event.originNetworkId;
255c29fa5a6Sopenharmony_ci    flag_ = event.extra.flag;
256c29fa5a6Sopenharmony_ci    SetCursorPosition(event.cursorPos);
257c29fa5a6Sopenharmony_ci}
258c29fa5a6Sopenharmony_ci
259c29fa5a6Sopenharmony_civoid Context::RelayCooperate(const DSoftbusRelayCooperate &event)
260c29fa5a6Sopenharmony_ci{
261c29fa5a6Sopenharmony_ci    remoteNetworkId_ = event.targetNetworkId;
262c29fa5a6Sopenharmony_ci}
263c29fa5a6Sopenharmony_ci
264c29fa5a6Sopenharmony_civoid Context::UpdateCooperateFlag(const UpdateCooperateFlagEvent &event)
265c29fa5a6Sopenharmony_ci{
266c29fa5a6Sopenharmony_ci    flag_ = ((flag_ & ~event.mask) | (event.flag & event.mask));
267c29fa5a6Sopenharmony_ci}
268c29fa5a6Sopenharmony_ci
269c29fa5a6Sopenharmony_cibool Context::IsAllowCooperate()
270c29fa5a6Sopenharmony_ci{
271c29fa5a6Sopenharmony_ci    FI_HILOGI("Notify observers of allow cooperate");
272c29fa5a6Sopenharmony_ci    return std::all_of(observers_.cbegin(), observers_.cend(), [](const auto &observer) {
273c29fa5a6Sopenharmony_ci        return observer->IsAllowCooperate();
274c29fa5a6Sopenharmony_ci    });
275c29fa5a6Sopenharmony_ci}
276c29fa5a6Sopenharmony_ci
277c29fa5a6Sopenharmony_civoid Context::OnStartCooperate(StartCooperateData &data)
278c29fa5a6Sopenharmony_ci{
279c29fa5a6Sopenharmony_ci    std::for_each(observers_.cbegin(), observers_.cend(), [&data](const auto &observer) {
280c29fa5a6Sopenharmony_ci        return observer->OnStartCooperate(data);
281c29fa5a6Sopenharmony_ci    });
282c29fa5a6Sopenharmony_ci}
283c29fa5a6Sopenharmony_ci
284c29fa5a6Sopenharmony_civoid Context::OnRemoteStartCooperate(RemoteStartCooperateData &data)
285c29fa5a6Sopenharmony_ci{
286c29fa5a6Sopenharmony_ci    std::for_each(observers_.cbegin(), observers_.cend(), [&data](const auto &observer) {
287c29fa5a6Sopenharmony_ci        return observer->OnRemoteStartCooperate(data);
288c29fa5a6Sopenharmony_ci    });
289c29fa5a6Sopenharmony_ci}
290c29fa5a6Sopenharmony_ci
291c29fa5a6Sopenharmony_civoid Context::OnTransitionOut()
292c29fa5a6Sopenharmony_ci{
293c29fa5a6Sopenharmony_ci    CHKPV(eventHandler_);
294c29fa5a6Sopenharmony_ci    FI_HILOGI("Notify observers of transition out");
295c29fa5a6Sopenharmony_ci    for (const auto &observer : observers_) {
296c29fa5a6Sopenharmony_ci        eventHandler_->PostTask(
297c29fa5a6Sopenharmony_ci            [observer, remoteNetworkId = Peer(), cursorPos = NormalizedCursorPosition()] {
298c29fa5a6Sopenharmony_ci                FI_HILOGI("Notify one observer of transition out");
299c29fa5a6Sopenharmony_ci                CHKPV(observer);
300c29fa5a6Sopenharmony_ci                observer->OnTransitionOut(remoteNetworkId, cursorPos);
301c29fa5a6Sopenharmony_ci            });
302c29fa5a6Sopenharmony_ci    }
303c29fa5a6Sopenharmony_ci}
304c29fa5a6Sopenharmony_ci
305c29fa5a6Sopenharmony_civoid Context::OnTransitionIn()
306c29fa5a6Sopenharmony_ci{
307c29fa5a6Sopenharmony_ci    CHKPV(eventHandler_);
308c29fa5a6Sopenharmony_ci    FI_HILOGI("Notify observers of transition in");
309c29fa5a6Sopenharmony_ci    for (const auto &observer : observers_) {
310c29fa5a6Sopenharmony_ci        eventHandler_->PostTask(
311c29fa5a6Sopenharmony_ci            [observer, remoteNetworkId = Peer(), cursorPos = NormalizedCursorPosition()] {
312c29fa5a6Sopenharmony_ci                FI_HILOGI("Notify one observer of transition in");
313c29fa5a6Sopenharmony_ci                CHKPV(observer);
314c29fa5a6Sopenharmony_ci                observer->OnTransitionIn(remoteNetworkId, cursorPos);
315c29fa5a6Sopenharmony_ci            });
316c29fa5a6Sopenharmony_ci    }
317c29fa5a6Sopenharmony_ci}
318c29fa5a6Sopenharmony_ci
319c29fa5a6Sopenharmony_civoid Context::OnBack()
320c29fa5a6Sopenharmony_ci{
321c29fa5a6Sopenharmony_ci    CHKPV(eventHandler_);
322c29fa5a6Sopenharmony_ci    FI_HILOGI("Notify observers of come back");
323c29fa5a6Sopenharmony_ci    for (const auto &observer : observers_) {
324c29fa5a6Sopenharmony_ci        eventHandler_->PostTask(
325c29fa5a6Sopenharmony_ci            [observer, remoteNetworkId = Peer(), cursorPos = NormalizedCursorPosition()] {
326c29fa5a6Sopenharmony_ci                FI_HILOGI("Notify one observer of come back");
327c29fa5a6Sopenharmony_ci                CHKPV(observer);
328c29fa5a6Sopenharmony_ci                observer->OnBack(remoteNetworkId, cursorPos);
329c29fa5a6Sopenharmony_ci            });
330c29fa5a6Sopenharmony_ci    }
331c29fa5a6Sopenharmony_ci}
332c29fa5a6Sopenharmony_ci
333c29fa5a6Sopenharmony_civoid Context::OnRelayCooperation(const std::string &networkId, const NormalizedCoordinate &cursorPos)
334c29fa5a6Sopenharmony_ci{
335c29fa5a6Sopenharmony_ci    CHKPV(eventHandler_);
336c29fa5a6Sopenharmony_ci    FI_HILOGI("Notify observers of relay cooperation");
337c29fa5a6Sopenharmony_ci    for (const auto &observer : observers_) {
338c29fa5a6Sopenharmony_ci        eventHandler_->PostTask(
339c29fa5a6Sopenharmony_ci            [observer, networkId, cursorPos] {
340c29fa5a6Sopenharmony_ci                FI_HILOGI("Notify one observer of relay cooperation");
341c29fa5a6Sopenharmony_ci                CHKPV(observer);
342c29fa5a6Sopenharmony_ci                observer->OnRelay(networkId, cursorPos);
343c29fa5a6Sopenharmony_ci            });
344c29fa5a6Sopenharmony_ci    }
345c29fa5a6Sopenharmony_ci}
346c29fa5a6Sopenharmony_ci
347c29fa5a6Sopenharmony_civoid Context::CloseDistributedFileConnection(const std::string &remoteNetworkId)
348c29fa5a6Sopenharmony_ci{
349c29fa5a6Sopenharmony_ci    CHKPV(eventHandler_);
350c29fa5a6Sopenharmony_ci    FI_HILOGI("Notify observers of device offline");
351c29fa5a6Sopenharmony_ci    for (const auto &observer : observers_) {
352c29fa5a6Sopenharmony_ci        eventHandler_->PostTask(
353c29fa5a6Sopenharmony_ci            [observer, remoteNetworkId] {
354c29fa5a6Sopenharmony_ci                FI_HILOGI("Notify one observer of device offline, remoteNetworkId:%{public}s",
355c29fa5a6Sopenharmony_ci                    Utility::Anonymize(remoteNetworkId).c_str());
356c29fa5a6Sopenharmony_ci                CHKPV(observer);
357c29fa5a6Sopenharmony_ci                observer->CloseDistributedFileConnection(remoteNetworkId);
358c29fa5a6Sopenharmony_ci            });
359c29fa5a6Sopenharmony_ci    }
360c29fa5a6Sopenharmony_ci}
361c29fa5a6Sopenharmony_ci
362c29fa5a6Sopenharmony_civoid Context::OnResetCooperation()
363c29fa5a6Sopenharmony_ci{
364c29fa5a6Sopenharmony_ci    CHKPV(eventHandler_);
365c29fa5a6Sopenharmony_ci    FI_HILOGI("Notify observers of reset cooperation");
366c29fa5a6Sopenharmony_ci    for (const auto &observer : observers_) {
367c29fa5a6Sopenharmony_ci        eventHandler_->PostTask(
368c29fa5a6Sopenharmony_ci            [observer] {
369c29fa5a6Sopenharmony_ci                FI_HILOGI("Notify one observer of reset cooperation");
370c29fa5a6Sopenharmony_ci                CHKPV(observer);
371c29fa5a6Sopenharmony_ci                observer->OnReset();
372c29fa5a6Sopenharmony_ci            });
373c29fa5a6Sopenharmony_ci    }
374c29fa5a6Sopenharmony_ci}
375c29fa5a6Sopenharmony_ci
376c29fa5a6Sopenharmony_civoid Context::SetCursorPosition(const Coordinate &cursorPos)
377c29fa5a6Sopenharmony_ci{
378c29fa5a6Sopenharmony_ci    double xPercent = (PERCENT - std::clamp<double>(cursorPos.x, 0.0, PERCENT)) / PERCENT;
379c29fa5a6Sopenharmony_ci    double yPercent = std::clamp<double>(cursorPos.y, 0.0, PERCENT) / PERCENT;
380c29fa5a6Sopenharmony_ci
381c29fa5a6Sopenharmony_ci    auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
382c29fa5a6Sopenharmony_ci    CHKPV(display);
383c29fa5a6Sopenharmony_ci    cursorPos_.x = static_cast<int32_t>(xPercent * display->GetWidth());
384c29fa5a6Sopenharmony_ci    cursorPos_.y = static_cast<int32_t>(yPercent * display->GetHeight());
385c29fa5a6Sopenharmony_ci    env_->GetInput().SetPointerLocation(cursorPos_.x, cursorPos_.y);
386c29fa5a6Sopenharmony_ci    FI_HILOGI("Set cursor position (%{public}d,%{public}d)(%{public}d,%{public}d)(%{public}d,%{public}d)",
387c29fa5a6Sopenharmony_ci        cursorPos.x, cursorPos.y, cursorPos_.x, cursorPos_.y, display->GetWidth(), display->GetHeight());
388c29fa5a6Sopenharmony_ci}
389c29fa5a6Sopenharmony_ci
390c29fa5a6Sopenharmony_civoid Context::UpdateCursorPosition()
391c29fa5a6Sopenharmony_ci{
392c29fa5a6Sopenharmony_ci    env_->GetInput().SetPointerLocation(cursorPos_.x, cursorPos_.y);
393c29fa5a6Sopenharmony_ci    FI_HILOGI("Update cursor position (%{public}d,%{public}d)", cursorPos_.x, cursorPos_.y);
394c29fa5a6Sopenharmony_ci}
395c29fa5a6Sopenharmony_ci
396c29fa5a6Sopenharmony_civoid Context::ResetCursorPosition()
397c29fa5a6Sopenharmony_ci{
398c29fa5a6Sopenharmony_ci    constexpr Coordinate defaultCursorPos {
399c29fa5a6Sopenharmony_ci        .x = 50,
400c29fa5a6Sopenharmony_ci        .y = 50,
401c29fa5a6Sopenharmony_ci    };
402c29fa5a6Sopenharmony_ci    SetCursorPosition(defaultCursorPos);
403c29fa5a6Sopenharmony_ci}
404c29fa5a6Sopenharmony_ci
405c29fa5a6Sopenharmony_ci#ifdef ENABLE_PERFORMANCE_CHECK
406c29fa5a6Sopenharmony_civoid Context::StartTrace(const std::string &name)
407c29fa5a6Sopenharmony_ci{
408c29fa5a6Sopenharmony_ci    std::lock_guard guard { lock_ };
409c29fa5a6Sopenharmony_ci    if (traces_.find(name) != traces_.end()) {
410c29fa5a6Sopenharmony_ci        return;
411c29fa5a6Sopenharmony_ci    }
412c29fa5a6Sopenharmony_ci    traces_.emplace(name, std::chrono::steady_clock::now());
413c29fa5a6Sopenharmony_ci    FI_HILOGI("[PERF] Start tracing \'%{public}s\'", name.c_str());
414c29fa5a6Sopenharmony_ci}
415c29fa5a6Sopenharmony_ci
416c29fa5a6Sopenharmony_civoid Context::FinishTrace(const std::string &name)
417c29fa5a6Sopenharmony_ci{
418c29fa5a6Sopenharmony_ci    std::lock_guard guard { lock_ };
419c29fa5a6Sopenharmony_ci    if (auto iter = traces_.find(name); iter != traces_.end()) {
420c29fa5a6Sopenharmony_ci        FI_HILOGI("[PERF] Finish tracing \'%{public}s\', elapsed:%{public}lld ms", name.c_str(),
421c29fa5a6Sopenharmony_ci            std::chrono::duration_cast<std::chrono::milliseconds>(
422c29fa5a6Sopenharmony_ci                std::chrono::steady_clock::now() - iter->second).count());
423c29fa5a6Sopenharmony_ci        traces_.erase(iter);
424c29fa5a6Sopenharmony_ci    }
425c29fa5a6Sopenharmony_ci}
426c29fa5a6Sopenharmony_ci#endif // ENABLE_PERFORMANCE_CHECK
427c29fa5a6Sopenharmony_ci
428c29fa5a6Sopenharmony_ci} // namespace Cooperate
429c29fa5a6Sopenharmony_ci} // namespace DeviceStatus
430c29fa5a6Sopenharmony_ci} // namespace Msdp
431c29fa5a6Sopenharmony_ci} // namespace OHOS
432