1f857971dSopenharmony_ci/*
2f857971dSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3f857971dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4f857971dSopenharmony_ci * you may not use this file except in compliance with the License.
5f857971dSopenharmony_ci * You may obtain a copy of the License at
6f857971dSopenharmony_ci *
7f857971dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8f857971dSopenharmony_ci *
9f857971dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10f857971dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11f857971dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f857971dSopenharmony_ci * See the License for the specific language governing permissions and
13f857971dSopenharmony_ci * limitations under the License.
14f857971dSopenharmony_ci */
15f857971dSopenharmony_ci
16f857971dSopenharmony_ci#include "hot_area.h"
17f857971dSopenharmony_ci
18f857971dSopenharmony_ci#include "display_manager.h"
19f857971dSopenharmony_ci
20f857971dSopenharmony_ci#include "devicestatus_define.h"
21f857971dSopenharmony_ci
22f857971dSopenharmony_ci#undef LOG_TAG
23f857971dSopenharmony_ci#define LOG_TAG "HotArea"
24f857971dSopenharmony_ci
25f857971dSopenharmony_cinamespace OHOS {
26f857971dSopenharmony_cinamespace Msdp {
27f857971dSopenharmony_cinamespace DeviceStatus {
28f857971dSopenharmony_cinamespace Cooperate {
29f857971dSopenharmony_cinamespace {
30f857971dSopenharmony_ciconstexpr int32_t HOT_AREA_WIDTH { 100 };
31f857971dSopenharmony_ciconstexpr int32_t HOT_AREA_MARGIN { 200 };
32f857971dSopenharmony_ci}; // namespace
33f857971dSopenharmony_ci
34f857971dSopenharmony_civoid HotArea::AddListener(const RegisterHotareaListenerEvent &event)
35f857971dSopenharmony_ci{
36f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
37f857971dSopenharmony_ci    std::lock_guard guard(lock_);
38f857971dSopenharmony_ci    HotAreaInfo info {
39f857971dSopenharmony_ci        .pid = event.pid,
40f857971dSopenharmony_ci        .msgId = MessageId::HOT_AREA_ADD_LISTENER,
41f857971dSopenharmony_ci    };
42f857971dSopenharmony_ci    auto [iter, isOk] = callbacks_.emplace(info);
43f857971dSopenharmony_ci    if (!isOk) {
44f857971dSopenharmony_ci        callbacks_.erase(iter);
45f857971dSopenharmony_ci        callbacks_.emplace(info);
46f857971dSopenharmony_ci    }
47f857971dSopenharmony_ci}
48f857971dSopenharmony_ci
49f857971dSopenharmony_civoid HotArea::RemoveListener(const UnregisterHotareaListenerEvent &event)
50f857971dSopenharmony_ci{
51f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
52f857971dSopenharmony_ci    std::lock_guard guard(lock_);
53f857971dSopenharmony_ci    callbacks_.erase(HotAreaInfo { .pid = event.pid });
54f857971dSopenharmony_ci}
55f857971dSopenharmony_ci
56f857971dSopenharmony_civoid HotArea::EnableCooperate(const EnableCooperateEvent &event)
57f857971dSopenharmony_ci{
58f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
59f857971dSopenharmony_ci    std::lock_guard guard(lock_);
60f857971dSopenharmony_ci    auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
61f857971dSopenharmony_ci    CHKPV(display);
62f857971dSopenharmony_ci    width_ = display->GetWidth();
63f857971dSopenharmony_ci    height_ = display->GetHeight();
64f857971dSopenharmony_ci}
65f857971dSopenharmony_ci
66f857971dSopenharmony_ciint32_t HotArea::ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)
67f857971dSopenharmony_ci{
68f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
69f857971dSopenharmony_ci    std::lock_guard guard(lock_);
70f857971dSopenharmony_ci    CHKPR(pointerEvent, RET_ERR);
71f857971dSopenharmony_ci    MMI::PointerEvent::PointerItem pointerItem;
72f857971dSopenharmony_ci    if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
73f857971dSopenharmony_ci        FI_HILOGE("Corrupted pointer event");
74f857971dSopenharmony_ci        return RET_ERR;
75f857971dSopenharmony_ci    }
76f857971dSopenharmony_ci    displayX_ = pointerItem.GetDisplayX();
77f857971dSopenharmony_ci    displayY_ = pointerItem.GetDisplayY();
78f857971dSopenharmony_ci    deltaX_ = pointerItem.GetRawDx();
79f857971dSopenharmony_ci    deltaY_ = pointerItem.GetRawDy();
80f857971dSopenharmony_ci    CheckInHotArea();
81f857971dSopenharmony_ci    CheckPointerToEdge(type_);
82f857971dSopenharmony_ci    NotifyMessage();
83f857971dSopenharmony_ci    return RET_OK;
84f857971dSopenharmony_ci}
85f857971dSopenharmony_ci
86f857971dSopenharmony_civoid HotArea::CheckInHotArea()
87f857971dSopenharmony_ci{
88f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
89f857971dSopenharmony_ci    if (displayX_ <= HOT_AREA_WIDTH && displayY_ >= HOT_AREA_MARGIN &&
90f857971dSopenharmony_ci        displayY_ <= (height_ - HOT_AREA_MARGIN)) {
91f857971dSopenharmony_ci        type_ = HotAreaType::AREA_LEFT;
92f857971dSopenharmony_ci    } else if (displayX_ >= (width_ - HOT_AREA_WIDTH) && displayY_ >= HOT_AREA_MARGIN &&
93f857971dSopenharmony_ci        displayY_ <= (height_ - HOT_AREA_MARGIN)) {
94f857971dSopenharmony_ci        type_ = HotAreaType::AREA_RIGHT;
95f857971dSopenharmony_ci    } else if (displayY_ <= HOT_AREA_WIDTH && displayX_ >= HOT_AREA_MARGIN &&
96f857971dSopenharmony_ci        displayX_ <= (width_ - HOT_AREA_MARGIN)) {
97f857971dSopenharmony_ci        type_ = HotAreaType::AREA_TOP;
98f857971dSopenharmony_ci    } else if (displayY_ >= (height_ - HOT_AREA_WIDTH) && displayX_ >= HOT_AREA_MARGIN &&
99f857971dSopenharmony_ci        displayX_ <= (width_ - HOT_AREA_MARGIN)) {
100f857971dSopenharmony_ci        type_ = HotAreaType::AREA_BOTTOM;
101f857971dSopenharmony_ci    } else {
102f857971dSopenharmony_ci        type_ = HotAreaType::AREA_NONE;
103f857971dSopenharmony_ci    }
104f857971dSopenharmony_ci}
105f857971dSopenharmony_ci
106f857971dSopenharmony_civoid HotArea::CheckPointerToEdge(HotAreaType type)
107f857971dSopenharmony_ci{
108f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
109f857971dSopenharmony_ci    if (type == HotAreaType::AREA_LEFT) {
110f857971dSopenharmony_ci        isEdge_ = displayX_ <= 0 && deltaX_ < 0;
111f857971dSopenharmony_ci    } else if (type == HotAreaType::AREA_RIGHT) {
112f857971dSopenharmony_ci        isEdge_ = displayX_ >= (width_ - 1) && deltaX_ > 0;
113f857971dSopenharmony_ci    } else if (type == HotAreaType::AREA_TOP) {
114f857971dSopenharmony_ci        isEdge_ = displayY_ <= 0 && deltaY_ < 0;
115f857971dSopenharmony_ci    } else if (type == HotAreaType::AREA_BOTTOM) {
116f857971dSopenharmony_ci        isEdge_ = displayY_ >= (height_ - 1) && deltaY_ > 0;
117f857971dSopenharmony_ci    } else {
118f857971dSopenharmony_ci        isEdge_ = false;
119f857971dSopenharmony_ci    }
120f857971dSopenharmony_ci}
121f857971dSopenharmony_ci
122f857971dSopenharmony_civoid HotArea::NotifyMessage()
123f857971dSopenharmony_ci{
124f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
125f857971dSopenharmony_ci    OnHotAreaMessage(type_, isEdge_);
126f857971dSopenharmony_ci}
127f857971dSopenharmony_ci
128f857971dSopenharmony_civoid HotArea::OnHotAreaMessage(HotAreaType msg, bool isEdge)
129f857971dSopenharmony_ci{
130f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
131f857971dSopenharmony_ci    for (const auto &callback : callbacks_) {
132f857971dSopenharmony_ci        NotifyHotAreaMessage(callback.pid, callback.msgId, msg, isEdge);
133f857971dSopenharmony_ci    }
134f857971dSopenharmony_ci}
135f857971dSopenharmony_ci
136f857971dSopenharmony_civoid HotArea::OnClientDied(const ClientDiedEvent &event)
137f857971dSopenharmony_ci{
138f857971dSopenharmony_ci    FI_HILOGI("Remove client died listener, pid: %{public}d", event.pid);
139f857971dSopenharmony_ci    callbacks_.erase(HotAreaInfo { .pid = event.pid });
140f857971dSopenharmony_ci}
141f857971dSopenharmony_ci
142f857971dSopenharmony_civoid HotArea::NotifyHotAreaMessage(int32_t pid, MessageId msgId, HotAreaType msg, bool isEdge)
143f857971dSopenharmony_ci{
144f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
145f857971dSopenharmony_ci    CHKPV(env_);
146f857971dSopenharmony_ci    auto session = env_->GetSocketSessionManager().FindSessionByPid(pid);
147f857971dSopenharmony_ci    CHKPV(session);
148f857971dSopenharmony_ci    NetPacket pkt(msgId);
149f857971dSopenharmony_ci
150f857971dSopenharmony_ci    pkt << displayX_ << displayY_ << static_cast<int32_t>(msg) << isEdge;
151f857971dSopenharmony_ci    if (pkt.ChkRWError()) {
152f857971dSopenharmony_ci        FI_HILOGE("Packet write data failed");
153f857971dSopenharmony_ci        return;
154f857971dSopenharmony_ci    }
155f857971dSopenharmony_ci    if (!session->SendMsg(pkt)) {
156f857971dSopenharmony_ci        FI_HILOGE("Sending failed");
157f857971dSopenharmony_ci        return;
158f857971dSopenharmony_ci    }
159f857971dSopenharmony_ci}
160f857971dSopenharmony_ci} // namespace Cooperate
161f857971dSopenharmony_ci} // namespace DeviceStatus
162f857971dSopenharmony_ci} // namespace Msdp
163f857971dSopenharmony_ci} // namespace OHOS
164