* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "hot_area.h"
#include "display_manager.h"
#include "devicestatus_define.h"
#undef LOG_TAG
#define LOG_TAG "HotArea"
namespace OHOS {
namespace Msdp {
namespace DeviceStatus {
namespace Cooperate {
namespace {
constexpr int32_t HOT_AREA_WIDTH { 100 };
constexpr int32_t HOT_AREA_MARGIN { 200 };
};
void HotArea::AddListener(const RegisterHotareaListenerEvent &event)
{
CALL_DEBUG_ENTER;
std::lock_guard guard(lock_);
HotAreaInfo info {
.pid = event.pid,
.msgId = MessageId::HOT_AREA_ADD_LISTENER,
};
auto [iter, isOk] = callbacks_.emplace(info);
if (!isOk) {
callbacks_.erase(iter);
callbacks_.emplace(info);
}
}
void HotArea::RemoveListener(const UnregisterHotareaListenerEvent &event)
{
CALL_DEBUG_ENTER;
std::lock_guard guard(lock_);
callbacks_.erase(HotAreaInfo { .pid = event.pid });
}
void HotArea::EnableCooperate(const EnableCooperateEvent &event)
{
CALL_DEBUG_ENTER;
std::lock_guard guard(lock_);
auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
CHKPV(display);
width_ = display->GetWidth();
height_ = display->GetHeight();
}
int32_t HotArea::ProcessData(std::shared_ptr<MMI::PointerEvent> pointerEvent)
{
CALL_DEBUG_ENTER;
std::lock_guard guard(lock_);
CHKPR(pointerEvent, RET_ERR);
MMI::PointerEvent::PointerItem pointerItem;
if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
FI_HILOGE("Corrupted pointer event");
return RET_ERR;
}
displayX_ = pointerItem.GetDisplayX();
displayY_ = pointerItem.GetDisplayY();
deltaX_ = pointerItem.GetRawDx();
deltaY_ = pointerItem.GetRawDy();
CheckInHotArea();
CheckPointerToEdge(type_);
NotifyMessage();
return RET_OK;
}
void HotArea::CheckInHotArea()
{
CALL_DEBUG_ENTER;
if (displayX_ <= HOT_AREA_WIDTH && displayY_ >= HOT_AREA_MARGIN &&
displayY_ <= (height_ - HOT_AREA_MARGIN)) {
type_ = HotAreaType::AREA_LEFT;
} else if (displayX_ >= (width_ - HOT_AREA_WIDTH) && displayY_ >= HOT_AREA_MARGIN &&
displayY_ <= (height_ - HOT_AREA_MARGIN)) {
type_ = HotAreaType::AREA_RIGHT;
} else if (displayY_ <= HOT_AREA_WIDTH && displayX_ >= HOT_AREA_MARGIN &&
displayX_ <= (width_ - HOT_AREA_MARGIN)) {
type_ = HotAreaType::AREA_TOP;
} else if (displayY_ >= (height_ - HOT_AREA_WIDTH) && displayX_ >= HOT_AREA_MARGIN &&
displayX_ <= (width_ - HOT_AREA_MARGIN)) {
type_ = HotAreaType::AREA_BOTTOM;
} else {
type_ = HotAreaType::AREA_NONE;
}
}
void HotArea::CheckPointerToEdge(HotAreaType type)
{
CALL_DEBUG_ENTER;
if (type == HotAreaType::AREA_LEFT) {
isEdge_ = displayX_ <= 0 && deltaX_ < 0;
} else if (type == HotAreaType::AREA_RIGHT) {
isEdge_ = displayX_ >= (width_ - 1) && deltaX_ > 0;
} else if (type == HotAreaType::AREA_TOP) {
isEdge_ = displayY_ <= 0 && deltaY_ < 0;
} else if (type == HotAreaType::AREA_BOTTOM) {
isEdge_ = displayY_ >= (height_ - 1) && deltaY_ > 0;
} else {
isEdge_ = false;
}
}
void HotArea::NotifyMessage()
{
CALL_DEBUG_ENTER;
OnHotAreaMessage(type_, isEdge_);
}
void HotArea::OnHotAreaMessage(HotAreaType msg, bool isEdge)
{
CALL_DEBUG_ENTER;
for (const auto &callback : callbacks_) {
NotifyHotAreaMessage(callback.pid, callback.msgId, msg, isEdge);
}
}
void HotArea::OnClientDied(const ClientDiedEvent &event)
{
FI_HILOGI("Remove client died listener, pid: %{public}d", event.pid);
callbacks_.erase(HotAreaInfo { .pid = event.pid });
}
void HotArea::NotifyHotAreaMessage(int32_t pid, MessageId msgId, HotAreaType msg, bool isEdge)
{
CALL_DEBUG_ENTER;
CHKPV(env_);
auto session = env_->GetSocketSessionManager().FindSessionByPid(pid);
CHKPV(session);
NetPacket pkt(msgId);
pkt << displayX_ << displayY_ << static_cast<int32_t>(msg) << isEdge;
if (pkt.ChkRWError()) {
FI_HILOGE("Packet write data failed");
return;
}
if (!session->SendMsg(pkt)) {
FI_HILOGE("Sending failed");
return;
}
}
}
}
}
}