improve touchpad reset functions

Signed-off-by: hwzhangchuang <zhangchuang.zhang@huawei.com>
This commit is contained in:
hwzhangchuang
2023-12-27 22:02:17 +08:00
parent 9fdf01a00b
commit 8dd205bfe1
22 changed files with 593 additions and 420 deletions
+1 -1
View File
@@ -64,7 +64,7 @@
"//foundation/distributedhardware/distributed_input/services/sink/transport:libdinput_sink_trans",
"//foundation/distributedhardware/distributed_input/services/sink/inputcollector:libdinput_collector",
"//foundation/distributedhardware/distributed_input/services/transportbase:libdinput_trans_base",
"//foundation/distributedhardware/distributed_input/services/state:libdinput_state",
"//foundation/distributedhardware/distributed_input/services/state:libdinput_sink_state",
"//foundation/distributedhardware/distributed_input/sourcehandler:libdinput_source_handler",
"//foundation/distributedhardware/distributed_input/sinkhandler:libdinput_sink_handler",
"//foundation/distributedhardware/distributed_input/inputdevicehandler:libdinput_handler",
+30 -36
View File
@@ -33,7 +33,7 @@
#include "dinput_context.h"
#include "dinput_errcode.h"
#include "dinput_log.h"
#include "dinput_state.h"
#include "dinput_sink_state.h"
#include "dinput_utils_tool.h"
namespace OHOS {
@@ -220,49 +220,43 @@ bool InputHub::IsTouchPad(const InputDevice &inputDevice)
void InputHub::MatchAndDealEvent(Device *device, const RawEvent &event)
{
// Deal key state
DealKeyEvent(event);
if (IsTouchPad(device) && event.type == EV_KEY && event.code == BTN_MOUSE && event.value == KEY_UP_STATE &&
!DInputState::GetInstance().IsDhIdDown(event.descriptor)) {
DHLOGI("Find touchpad BTN_MOUSE UP state that not down effective at sink side, dhId: %s",
event.descriptor.c_str());
DInputState::GetInstance().SimulateTouchPadBtnMouseUpState(event.descriptor, event);
}
if (IsTouchPad(device) && event.type == EV_KEY && event.code == BTN_TOUCH && event.value == KEY_UP_STATE &&
!DInputState::GetInstance().IsDhIdDown(event.descriptor)) {
DHLOGI("Find touchpad BTN_TOUCH UP state that not down effective at sink side, dhId: %s",
event.descriptor.c_str());
DInputState::GetInstance().SimulateTouchPadBtnTouchUpState(event.descriptor, event);
}
if (IsCuror(device) && event.type == EV_KEY && event.code == BTN_MOUSE && event.value == KEY_UP_STATE &&
!DInputState::GetInstance().IsDhIdDown(event.descriptor)) {
DHLOGI("Find mouse BTN_MOUSE UP state that not down effective at sink side, dhId: %s",
event.descriptor.c_str());
DInputState::GetInstance().SimulateMouseBtnMouseUpState(event.descriptor, event);
bool isTouchPad = IsTouchPad(device);
if (!isTouchPad) {
// Deal Normal key state, such as keys of keyboard or mouse
DealNormalKeyEvent(device, event);
} else {
// Deal TouchPad events
DealTouchPadEvent(event);
}
}
void InputHub::DealKeyEvent(const RawEvent &event)
void InputHub::DealTouchPadEvent(const RawEvent &event)
{
if (event.type == EV_KEY && event.code != BTN_TOOL_FINGER && event.value == KEY_DOWN_STATE) {
DInputState::GetInstance().AddKeyDownState(event);
auto ret = DInputSinkState::GetInstance().GetTouchPadEventFragMgr()->PushEvent(event.descriptor, event);
if (ret.first) {
DInputSinkState::GetInstance().SimulateTouchPadStateReset(ret.second);
}
}
void InputHub::DealNormalKeyEvent(Device *device, const RawEvent &event)
{
if (event.type == EV_KEY && event.value == KEY_DOWN_STATE) {
DInputSinkState::GetInstance().AddKeyDownState(event);
RecordChangeEventLog(event);
}
if (event.type == EV_KEY && event.value == KEY_UP_STATE) {
DInputState::GetInstance().RemoveKeyDownState(event);
// Deal mouse left keydown reset
if (IsCuror(device) && event.code == BTN_MOUSE &&
!DInputSinkState::GetInstance().IsDhIdDown(event.descriptor)) {
DHLOGI("Find mouse BTN_MOUSE UP state that not down effective at sink side, dhId: %s",
event.descriptor.c_str());
DInputSinkState::GetInstance().SimulateMouseBtnMouseUpState(event.descriptor, event);
}
DInputSinkState::GetInstance().RemoveKeyDownState(event);
RecordChangeEventLog(event);
}
if (event.type == EV_KEY && event.value == KEY_REPEAT) {
DInputState::GetInstance().CheckAndSetLongPressedKeyOrder(event);
}
if (event.type == EV_ABS && (event.code == ABS_MT_POSITION_X || event.code == ABS_X)) {
DInputState::GetInstance().RefreshABSPosition(event.descriptor, event.value, -1);
}
if (event.type == EV_ABS && (event.code == ABS_MT_POSITION_Y || event.code == ABS_Y)) {
DInputState::GetInstance().RefreshABSPosition(event.descriptor, -1, event.value);
DInputSinkState::GetInstance().CheckAndSetLongPressedKeyOrder(event);
}
}
@@ -1457,7 +1451,7 @@ void InputHub::SavePressedKeyState(const InputHub::Device *dev, int32_t keyCode)
.descriptor = dev->identifier.descriptor,
.path = dev->path
};
DInputState::GetInstance().AddKeyDownState(event);
DInputSinkState::GetInstance().AddKeyDownState(event);
DHLOGI("Find Pressed key: %d, device path: %s, dhId: %s", keyCode, dev->path.c_str(),
dev->identifier.descriptor.c_str());
}
@@ -1559,7 +1553,7 @@ void InputHub::RecordDeviceStates()
void InputHub::ClearDeviceStates()
{
DHLOGI("Clear Device state");
DInputState::GetInstance().ClearDeviceStates();
DInputSinkState::GetInstance().ClearDeviceStates();
}
void InputHub::ClearSkipDevicePaths()
+3 -1
View File
@@ -19,6 +19,7 @@
#include <atomic>
#include <mutex>
#include <map>
#include <memory>
#include <set>
#include <unordered_map>
@@ -182,7 +183,8 @@ private:
*/
void RecordDeviceChangeStates(Device *device, struct input_event readBuffer[], const size_t count);
void MatchAndDealEvent(Device *device, const RawEvent &event);
void DealKeyEvent(const RawEvent &event);
void DealTouchPadEvent(const RawEvent &event);
void DealNormalKeyEvent(Device *device, const RawEvent &event);
/*
* Scan the input device node and save info.
*/
+1 -1
View File
@@ -52,7 +52,7 @@ ohos_shared_library("libdinput_handler") {
]
deps = [
"${services_state_path}:libdinput_state",
"${services_state_path}:libdinput_sink_state",
"${utils_path}:libdinput_utils",
"//third_party/libevdev:libevdev",
"//third_party/openssl:libcrypto_shared",
+1 -1
View File
@@ -51,7 +51,7 @@ ohos_shared_library("libdinput_collector") {
]
deps = [
"${services_state_path}:libdinput_state",
"${services_state_path}:libdinput_sink_state",
"${utils_path}:libdinput_utils",
"//third_party/libevdev:libevdev",
"//third_party/openssl:libcrypto_shared",
@@ -62,7 +62,7 @@ ohos_unittest("distributed_input_inner_sinkcollector_test") {
]
deps = [
"${services_state_path}:libdinput_state",
"${services_state_path}:libdinput_sink_state",
"${utils_path}:libdinput_utils",
"//third_party/libevdev:libevdev",
"//third_party/openssl:libcrypto_shared",
+1 -1
View File
@@ -63,7 +63,7 @@ ohos_shared_library("libdinput_sink") {
deps = [
"${dfx_utils_path}:libdinput_dfx_utils",
"${distributedinput_path}/services/state:libdinput_state",
"${distributedinput_path}/services/state:libdinput_sink_state",
"${distributedinput_path}/services/transportbase:libdinput_trans_base",
"${innerkits_path}:libdinput_sdk",
"${services_sink_path}/inputcollector:libdinput_collector",
@@ -38,7 +38,7 @@
#include "dinput_sink_trans_callback.h"
#include "distributed_input_sink_stub.h"
#include "distributed_input_sink_event_handler.h"
#include "dinput_state.h"
#include "dinput_sink_state.h"
namespace OHOS {
namespace DistributedHardware {
@@ -242,7 +242,7 @@ void DistributedInputSinkManager::DInputSinkListener::OnStartRemoteInput(
DHLOGI("deviceInfo dhId, %s", GetAnonyString(deviceInfo.second).c_str());
std::vector<std::string> devDhIds;
SplitStringToVector(deviceInfo.second, INPUT_STRING_SPLIT_POINT, devDhIds);
DInputState::GetInstance().RecordDhIds(devDhIds, DhIdState::THROUGH_OUT, sessionId);
DInputSinkState::GetInstance().RecordDhIds(devDhIds, DhIdState::THROUGH_OUT, sessionId);
}
}
}
@@ -302,7 +302,7 @@ void DistributedInputSinkManager::DInputSinkListener::OnStartRemoteInputDhid(con
std::vector<std::string> devDhIds;
SplitStringToVector(strDhids, INPUT_STRING_SPLIT_POINT, devDhIds);
DInputState::GetInstance().RecordDhIds(devDhIds, DhIdState::THROUGH_OUT, sessionId);
DInputSinkState::GetInstance().RecordDhIds(devDhIds, DhIdState::THROUGH_OUT, sessionId);
AffectDhIds affDhIds = DistributedInputCollector::GetInstance().SetSharingDhIds(true, devDhIds);
sinkManagerObj_->StoreStartDhids(sessionId, affDhIds.sharingDhIds);
DistributedInputCollector::GetInstance().ReportDhIdSharingState(affDhIds);
@@ -321,7 +321,7 @@ void DistributedInputSinkManager::DInputSinkListener::OnStopRemoteInputDhid(cons
stopIndeedOnes.noSharingDhIds = stopIndeedDhIds;
DistributedInputCollector::GetInstance().ReportDhIdSharingState(stopIndeedOnes);
DInputState::GetInstance().RecordDhIds(stopOnCmdDhIds, DhIdState::THROUGH_IN, sessionId);
DInputSinkState::GetInstance().RecordDhIds(stopOnCmdDhIds, DhIdState::THROUGH_IN, sessionId);
if (DistributedInputCollector::GetInstance().IsAllDevicesStoped()) {
DHLOGE("All dhid stop sharing, sessionId: %d is closed.", sessionId);
@@ -369,7 +369,7 @@ void DistributedInputSinkManager::DInputSinkListener::OnRelayStartDhidRemoteInpu
std::vector<std::string> devDhIds;
SplitStringToVector(strDhids, INPUT_STRING_SPLIT_POINT, devDhIds);
DInputState::GetInstance().RecordDhIds(devDhIds, DhIdState::THROUGH_OUT, toSinkSessionId);
DInputSinkState::GetInstance().RecordDhIds(devDhIds, DhIdState::THROUGH_OUT, toSinkSessionId);
AffectDhIds affDhIds = DistributedInputCollector::GetInstance().SetSharingDhIds(true, devDhIds);
sinkManagerObj_->StoreStartDhids(toSinkSessionId, affDhIds.sharingDhIds);
DistributedInputCollector::GetInstance().ReportDhIdSharingState(affDhIds);
@@ -388,7 +388,7 @@ void DistributedInputSinkManager::DInputSinkListener::OnRelayStopDhidRemoteInput
stopIndeedOnes.noSharingDhIds = stopIndeedDhIds;
DistributedInputCollector::GetInstance().ReportDhIdSharingState(stopIndeedOnes);
DInputState::GetInstance().RecordDhIds(stopOnCmdDhIds, DhIdState::THROUGH_IN, toSinkSessionId);
DInputSinkState::GetInstance().RecordDhIds(stopOnCmdDhIds, DhIdState::THROUGH_IN, toSinkSessionId);
if (DistributedInputCollector::GetInstance().IsAllDevicesStoped()) {
DHLOGE("All dhid stop sharing, sessionId: %d is closed.", toSinkSessionId);
@@ -463,7 +463,7 @@ void DistributedInputSinkManager::DInputSinkListener::OnRelayStartTypeRemoteInpu
DHLOGI("deviceInfo dhId, %s", GetAnonyString(deviceInfo.second).c_str());
std::vector<std::string> devDhIds;
SplitStringToVector(deviceInfo.second, INPUT_STRING_SPLIT_POINT, devDhIds);
DInputState::GetInstance().RecordDhIds(devDhIds, DhIdState::THROUGH_OUT, toSinkSessionId);
DInputSinkState::GetInstance().RecordDhIds(devDhIds, DhIdState::THROUGH_OUT, toSinkSessionId);
}
}
@@ -611,9 +611,9 @@ int32_t DistributedInputSinkManager::Init()
return ERR_DH_INPUT_SERVER_SINK_MANAGER_INIT_FAIL;
}
ret = DInputState::GetInstance().Init();
ret = DInputSinkState::GetInstance().Init();
if (ret != DH_SUCCESS) {
DHLOGE("DInputState init fail!");
DHLOGE("DInputSinkState init fail!");
return ERR_DH_INPUT_SERVER_SINK_MANAGER_INIT_FAIL;
}
@@ -92,7 +92,7 @@ ohos_unittest("distributed_input_sinkmanager_test") {
deps = [
"${dfx_utils_path}:libdinput_dfx_utils",
"${distributedinput_path}/services/state:libdinput_state",
"${distributedinput_path}/services/state:libdinput_sink_state",
"${distributedinput_path}/services/transportbase:libdinput_trans_base",
"${services_sink_path}/transport:libdinput_sink_trans",
"${utils_path}:libdinput_utils",
@@ -79,7 +79,7 @@ ohos_unittest("distributed_input_sinktrans_test") {
deps = [
"${dfx_utils_path}:libdinput_dfx_utils",
"${distributedinput_path}/services/state:libdinput_state",
"${distributedinput_path}/services/state:libdinput_sink_state",
"${services_sink_path}/inputcollector:libdinput_collector",
"${services_sink_path}/sinkmanager:libdinput_sink",
"${utils_path}:libdinput_utils",
+1 -1
View File
@@ -57,7 +57,7 @@ ohos_shared_library("libdinput_inject") {
deps = [
"${dfx_utils_path}:libdinput_dfx_utils",
"${services_state_path}:libdinput_state",
"${services_state_path}:libdinput_sink_state",
"${utils_path}:libdinput_utils",
"//third_party/libevdev:libevdev",
"//third_party/openssl:libcrypto_shared",
@@ -111,7 +111,7 @@ ohos_unittest("distributed_input_sourcemanager_test") {
deps = [
"${dfx_utils_path}:libdinput_dfx_utils",
"${distributedinput_path}/services/state:libdinput_state",
"${distributedinput_path}/services/state:libdinput_sink_state",
"${innerkits_path}:libdinput_sdk",
"${services_source_path}/transport:libdinput_source_trans",
"${utils_path}:libdinput_utils",
@@ -75,7 +75,7 @@ ohos_unittest("distributed_input_sourcetrans_test") {
deps = [
"${dfx_utils_path}:libdinput_dfx_utils",
"${distributedinput_path}/services/state:libdinput_state",
"${distributedinput_path}/services/state:libdinput_sink_state",
"${services_source_path}/inputinject:libdinput_inject",
"${services_source_path}/sourcemanager:libdinput_source",
"${utils_path}:libdinput_utils",
+7 -3
View File
@@ -15,7 +15,7 @@ import("//build/ohos.gni")
import(
"//foundation/distributedhardware/distributed_input/distributedinput.gni")
ohos_shared_library("libdinput_state") {
ohos_shared_library("libdinput_sink_state") {
sanitize = {
boundary_sanitize = true
integer_overflow = true
@@ -38,11 +38,15 @@ ohos_shared_library("libdinput_state") {
"${fwk_common_path}/utils/include",
]
sources = [ "src/dinput_state.cpp" ]
sources = [
"src/dinput_sink_state.cpp",
"src/touchpad_event_fragment.cpp",
"src/touchpad_event_fragment_mgr.cpp"
]
defines = [
"HI_LOG_ENABLE",
"DH_LOG_TAG=\"distributedinputstate\"",
"DH_LOG_TAG=\"distributeDInputSinkState\"",
"LOG_DOMAIN=0xD004100",
]
@@ -17,12 +17,14 @@
#define DISTRIBUTED_INPUT_STATE_BASE_H
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <linux/input.h>
#include "constants_dinput.h"
#include "constants_dinput.h"
#include "single_instance.h"
#include "touchpad_event_fragment_mgr.h"
namespace OHOS {
namespace DistributedHardware {
@@ -37,8 +39,8 @@ enum class DhIdState {
THROUGH_OUT,
};
class DInputState {
DECLARE_SINGLE_INSTANCE_BASE(DInputState);
class DInputSinkState {
DECLARE_SINGLE_INSTANCE_BASE(DInputSinkState);
public:
int32_t Init();
int32_t Release();
@@ -61,13 +63,8 @@ public:
* Clear Device stats if unprepare.
*/
void ClearDeviceStates();
void RefreshABSPosition(const std::string &dhId, int32_t absX, int32_t absY);
std::pair<int32_t, int32_t> GetAndClearABSPosition(const std::string &dhId);
void SimulateTouchPadBtnMouseUpState(const std::string &dhId, const struct RawEvent &event);
void SimulateTouchPadBtnTouchUpState(const std::string &dhId, const struct RawEvent &event);
void SimulateMouseBtnMouseUpState(const std::string &dhId, const struct RawEvent &event);
void SimulateTouchPadStateReset(const std::vector<RawEvent> &events);
/**
* @brief check is one device in down state
*
@@ -76,13 +73,15 @@ public:
* @return false NOT in down state
*/
bool IsDhIdDown(const std::string &dhId);
std::shared_ptr<TouchPadEventFragmentMgr> GetTouchPadEventFragMgr();
private:
DInputState() = default;
~DInputState();
DInputSinkState() = default;
~DInputSinkState();
// Simulate device state to the pass through target device.
void SimulateEventInjectToSrc(const int32_t sessionId, const std::vector<std::string> &dhIds);
void SimulateBtnTouchEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event);
void SimulateNormalEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event);
void SimulateKeyDownEvents(const int32_t sessionId, const std::string &dhId);
void SimulateKeyDownEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event);
void SimulateTouchPadEvents(const int32_t sessionId, const std::string &dhId);
private:
std::mutex operationMutex_;
std::map<std::string, DhIdState> dhIdStateMap_;
@@ -95,6 +94,8 @@ private:
// Record abs x/y of touchpad
std::unordered_map<std::string, std::pair<int32_t, int32_t>> absPositionsMap_;
std::atomic<int32_t> lastSessionId_ {0};
std::shared_ptr<TouchPadEventFragmentMgr> touchPadEventFragMgr_;
};
} // namespace DistributedInput
} // namespace DistributedHardware
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2023 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 <vector>
#include <string>
#include "constants_dinput.h"
namespace OHOS {
namespace DistributedHardware {
namespace DistributedInput {
class TouchPadEventFragment {
public:
TouchPadEventFragment() : events({}) {};
bool IsShouldDrop();
bool IsTouchPadOptFinish() const;
bool IsTouchPadOptStart() const;
void PushEvent(const RawEvent &event);
std::vector<RawEvent> GetEvents();
private:
std::vector<RawEvent> events;
};
} // namespace DistributedInput
} // namespace DistributedHardware
} // namespace OHOS
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2023 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 "touchpad_event_fragment.h"
#include <map>
#include <mutex>
#include <string>
#include <vector>
#include "constants_dinput.h"
namespace OHOS {
namespace DistributedHardware {
namespace DistributedInput {
class TouchPadEventFragmentMgr {
public:
TouchPadEventFragmentMgr() : fragments_({}) {}
/**
* @brief Push the touchpad event
*
* @param dhId the device dhId where event from
* @param event the event
* @return std::pair<bool, std::vector<RawEvent>>
* true for NOT whole touchpad event that need simulate back to the other device.
* false for DO Nothing.
*/
std::pair<bool, std::vector<RawEvent>> PushEvent(const std::string &dhId, const RawEvent &event);
void Clear(const std::string &dhId);
std::vector<RawEvent> GetAndClearEvents(const std::string &dhId);
private:
bool IsPositionEvent(const RawEvent &event);
bool IsSynEvent(const RawEvent &event);
bool IsWholeTouchFragments(const std::vector<TouchPadEventFragment> &fragments);
std::pair<bool, std::vector<RawEvent>> DealSynEvent(const std::string &dhId);
private:
std::mutex fragmentsMtx_;
// record the event fragments for the dhid. { dhId, { events }}
std::map<std::string, std::vector<TouchPadEventFragment>> fragments_;
};
} // namespace DistributedInput
} // namespace DistributedHardware
} // namespace OHOS
+246
View File
@@ -0,0 +1,246 @@
/*
* Copyright (c) 2023 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 "dinput_sink_state.h"
#include <dirent.h>
#include <fcntl.h>
#include <pthread.h>
#include <thread>
#include <unistd.h>
#include <vector>
#include "dinput_errcode.h"
#include "dinput_log.h"
#include "dinput_utils_tool.h"
#include "distributed_input_collector.h"
#include "distributed_input_sink_transport.h"
namespace OHOS {
namespace DistributedHardware {
namespace DistributedInput {
IMPLEMENT_SINGLE_INSTANCE(DInputSinkState);
DInputSinkState::~DInputSinkState()
{
Release();
}
int32_t DInputSinkState::Init()
{
DHLOGI("DInputSinkState Init.");
touchPadEventFragMgr_ = std::make_shared<TouchPadEventFragmentMgr>();
return DH_SUCCESS;
}
int32_t DInputSinkState::Release()
{
DHLOGI("DInputSinkState Release.");
{
std::lock_guard<std::mutex> mapLock(operationMutex_);
dhIdStateMap_.clear();
}
ClearDeviceStates();
return DH_SUCCESS;
}
int32_t DInputSinkState::RecordDhIds(const std::vector<std::string> &dhIds, DhIdState state, const int32_t sessionId)
{
DHLOGI("RecordDhIds dhIds size = %zu", dhIds.size());
std::lock_guard<std::mutex> mapLock(operationMutex_);
for (const auto &dhid : dhIds) {
DHLOGD("add dhid : %s, state : %d.", GetAnonyString(dhid).c_str(), state);
dhIdStateMap_[dhid] = state;
}
if (state == DhIdState::THROUGH_OUT) {
SimulateEventInjectToSrc(sessionId, dhIds);
}
lastSessionId_ = sessionId;
return DH_SUCCESS;
}
int32_t DInputSinkState::RemoveDhIds(const std::vector<std::string> &dhIds)
{
DHLOGI("RemoveDhIds dhIds size = %zu", dhIds.size());
std::lock_guard<std::mutex> mapLock(operationMutex_);
for (const auto &dhid : dhIds) {
DHLOGD("delete dhid : %s", GetAnonyString(dhid).c_str());
dhIdStateMap_.erase(dhid);
}
return DH_SUCCESS;
}
std::shared_ptr<TouchPadEventFragmentMgr> DInputSinkState::GetTouchPadEventFragMgr()
{
return this->touchPadEventFragMgr_;
}
DhIdState DInputSinkState::GetStateByDhid(const std::string &dhId)
{
std::lock_guard<std::mutex> mapLock(operationMutex_);
if (dhIdStateMap_.find(dhId) == dhIdStateMap_.end()) {
DHLOGE("dhId : %s not exist.", GetAnonyString(dhId).c_str());
return DhIdState::THROUGH_IN;
}
return dhIdStateMap_[dhId];
}
void DInputSinkState::SimulateMouseBtnMouseUpState(const std::string &dhId, const struct RawEvent &event)
{
DHLOGI("Sinmulate Mouse BTN_MOUSE UP state to source, dhId: %s", dhId.c_str());
int32_t scanId = GetRandomInt32();
RawEvent mscScanEv = { event.when, EV_MSC, MSC_SCAN, scanId, dhId, event.path };
RawEvent btnMouseUpEv = { event.when, EV_KEY, BTN_MOUSE, KEY_UP_STATE, dhId, event.path };
RawEvent sycReportEv = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path };
std::vector<RawEvent> simEvents = { mscScanEv, btnMouseUpEv, sycReportEv };
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(lastSessionId_, simEvents);
}
void DInputSinkState::SimulateTouchPadStateReset(const std::vector<RawEvent> &events)
{
DHLOGI("SimulateTouchPadStateReset events size: %d", events.size());
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(lastSessionId_, events);
}
void DInputSinkState::SimulateEventInjectToSrc(const int32_t sessionId, const std::vector<std::string> &dhIds)
{
DHLOGI("SimulateEventInject enter, sessionId %d, dhIds size %d", sessionId, dhIds.size());
// mouse/keyboard/touchpad/touchscreen event send to remote device if these device pass through.
if (sessionId == -1) {
DHLOGE("SimulateEventInjectToSrc SessionId invalid");
return;
}
for (const std::string &dhId : dhIds) {
SimulateKeyDownEvents(sessionId, dhId);
SimulateTouchPadEvents(sessionId, dhId);
}
}
void DInputSinkState::SimulateKeyDownEvents(const int32_t sessionId, const std::string &dhId)
{
// check if this device is key event
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
auto iter = keyDownStateMap_.find(dhId);
if (iter == keyDownStateMap_.end()) {
DHLOGI("The shared Device not has down state key, dhId: %s", dhId.c_str());
return;
}
for (const auto &event : iter->second) {
DHLOGI("Simulate Key event for device path: %s, dhId: %s",
event.path.c_str(), event.descriptor.c_str());
SimulateKeyDownEvent(sessionId, dhId, event);
}
keyDownStateMap_.erase(dhId);
}
void DInputSinkState::SimulateKeyDownEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event)
{
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId,
EV_KEY, event.code, KEY_DOWN_STATE);
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId,
EV_SYN, SYN_REPORT, 0x0);
}
void DInputSinkState::SimulateTouchPadEvents(const int32_t sessionId, const std::string &dhId)
{
std::vector<RawEvent> events = this->touchPadEventFragMgr_->GetAndClearEvents(dhId);
if (events.empty()) {
return;
}
DHLOGI("SimulateTouchPadEvents dhId: %s, event size: %d", dhId.c_str(), events.size());
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(sessionId, events);
}
bool DInputSinkState::IsDhIdDown(const std::string &dhId)
{
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
auto iter = keyDownStateMap_.find(dhId);
return iter != keyDownStateMap_.end();
}
void DInputSinkState::AddKeyDownState(struct RawEvent event)
{
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
keyDownStateMap_[event.descriptor].push_back(event);
}
void DInputSinkState::RemoveKeyDownState(struct RawEvent event)
{
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
auto iter = keyDownStateMap_.find(event.descriptor);
if (iter == keyDownStateMap_.end()) {
return;
}
auto evIter = std::find(keyDownStateMap_[event.descriptor].begin(),
keyDownStateMap_[event.descriptor].end(), event);
if (evIter == keyDownStateMap_[event.descriptor].end()) {
return;
}
keyDownStateMap_[event.descriptor].erase(evIter);
if (keyDownStateMap_[event.descriptor].empty()) {
keyDownStateMap_.erase(event.descriptor);
}
}
void DInputSinkState::CheckAndSetLongPressedKeyOrder(struct RawEvent event)
{
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
auto iter = keyDownStateMap_.find(event.descriptor);
if (iter == keyDownStateMap_.end()) {
DHLOGI("Find new pressed key, save it, node id: %s, type: %d, key code: %d, value: %d",
event.descriptor.c_str(), event.type, event.code, event.value);
keyDownStateMap_[event.descriptor].push_back(event);
return;
}
auto evIter = std::find(keyDownStateMap_[event.descriptor].begin(),
keyDownStateMap_[event.descriptor].end(), event);
// If not find the cache key on pressing, save it
if (evIter == keyDownStateMap_[event.descriptor].end()) {
DHLOGI("Find new pressed key, save it, node id: %s, type: %d, key code: %d, value: %d",
event.descriptor.c_str(), event.type, event.code, event.value);
keyDownStateMap_[event.descriptor].push_back(event);
return;
}
// it is already the last one, just return
if (evIter == (keyDownStateMap_[event.descriptor].end() - 1)) {
DHLOGI("Pressed key already last one, node id: %s, type: %d, key code: %d, value: %d",
event.descriptor.c_str(), event.type, event.code, event.value);
return;
}
// Ohterwhise, move the key to the last cached position.
RawEvent backEv = *evIter;
keyDownStateMap_[event.descriptor].erase(evIter);
keyDownStateMap_[event.descriptor].push_back(backEv);
DHLOGI("Find long pressed key: %d, move the cached pressed key: %d to the last position", event.code, backEv.code);
}
void DInputSinkState::ClearDeviceStates()
{
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
keyDownStateMap_.clear();
}
} // namespace DistributedInput
} // namespace DistributedHardware
} // namespace OHOSs
-348
View File
@@ -1,348 +0,0 @@
/*
* Copyright (c) 2023 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 "dinput_state.h"
#include <dirent.h>
#include <fcntl.h>
#include <pthread.h>
#include <thread>
#include <unistd.h>
#include <vector>
#include "dinput_errcode.h"
#include "dinput_log.h"
#include "dinput_utils_tool.h"
#include "distributed_input_collector.h"
#include "distributed_input_sink_transport.h"
namespace OHOS {
namespace DistributedHardware {
namespace DistributedInput {
IMPLEMENT_SINGLE_INSTANCE(DInputState);
DInputState::~DInputState()
{
Release();
}
int32_t DInputState::Init()
{
DHLOGI("DInputState Init.");
return DH_SUCCESS;
}
int32_t DInputState::Release()
{
DHLOGI("DInputState Release.");
{
std::lock_guard<std::mutex> mapLock(operationMutex_);
dhIdStateMap_.clear();
}
ClearDeviceStates();
{
std::lock_guard<std::mutex> lock(absPosMtx_);
absPositionsMap_.clear();
}
return DH_SUCCESS;
}
int32_t DInputState::RecordDhIds(const std::vector<std::string> &dhIds, DhIdState state, const int32_t sessionId)
{
DHLOGI("RecordDhIds dhIds size = %zu", dhIds.size());
std::lock_guard<std::mutex> mapLock(operationMutex_);
for (const auto &dhid : dhIds) {
DHLOGD("add dhid : %s, state : %d.", GetAnonyString(dhid).c_str(), state);
dhIdStateMap_[dhid] = state;
}
if (state == DhIdState::THROUGH_OUT) {
SimulateEventInjectToSrc(sessionId, dhIds);
}
lastSessionId_ = sessionId;
return DH_SUCCESS;
}
int32_t DInputState::RemoveDhIds(const std::vector<std::string> &dhIds)
{
DHLOGI("RemoveDhIds dhIds size = %zu", dhIds.size());
std::lock_guard<std::mutex> mapLock(operationMutex_);
for (const auto &dhid : dhIds) {
DHLOGD("delete dhid : %s", GetAnonyString(dhid).c_str());
dhIdStateMap_.erase(dhid);
}
return DH_SUCCESS;
}
DhIdState DInputState::GetStateByDhid(const std::string &dhId)
{
std::lock_guard<std::mutex> mapLock(operationMutex_);
if (dhIdStateMap_.find(dhId) == dhIdStateMap_.end()) {
DHLOGE("dhId : %s not exist.", GetAnonyString(dhId).c_str());
return DhIdState::THROUGH_IN;
}
return dhIdStateMap_[dhId];
}
void DInputState::SimulateEventInjectToSrc(const int32_t sessionId, const std::vector<std::string> &dhIds)
{
DHLOGI("SimulateEventInject enter, sessionId %d, dhIds size %d", sessionId, dhIds.size());
// mouse/keyboard/touchpad/touchscreen event send to remote device if these device pass through.
if (sessionId == -1) {
DHLOGE("SimulateEventInjectToSrc SessionId invalid");
return;
}
for (const std::string &dhId : dhIds) {
// check if this device is key event
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
auto iter = keyDownStateMap_.find(dhId);
if (iter == keyDownStateMap_.end()) {
DHLOGI("The shared Device not has down state key, dhId: %s", dhId.c_str());
continue;
}
for (const auto &event : iter->second) {
if (event.code == BTN_TOUCH) {
DHLOGI("Simulate Touch Down event for device path: %s, dhId: %s",
event.path.c_str(), event.descriptor.c_str());
SimulateBtnTouchEvent(sessionId, dhId, event);
} else {
DHLOGI("Simulate Key event for device path: %s, dhId: %s",
event.path.c_str(), event.descriptor.c_str());
SimulateNormalEvent(sessionId, dhId, event);
}
}
keyDownStateMap_.erase(dhId);
}
}
void DInputState::SimulateBtnTouchEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event)
{
int32_t simTrackingId = GetRandomInt32();
std::vector<struct RawEvent> simEvents;
RawEvent touchTrackingIdEv = { event.when, EV_ABS, ABS_MT_TRACKING_ID, simTrackingId, dhId, event.path };
simEvents.push_back(touchTrackingIdEv);
std::pair<int32_t, int32_t> absPos = GetAndClearABSPosition(event.descriptor);
if (absPos.first != -1) {
RawEvent absMTXEv = { event.when, EV_ABS, ABS_MT_POSITION_X, absPos.first, dhId, event.path };
simEvents.push_back(absMTXEv);
}
if (absPos.second != -1) {
RawEvent absMTYEv = { event.when, EV_ABS, ABS_MT_POSITION_Y, absPos.second, dhId, event.path };
simEvents.push_back(absMTYEv);
}
RawEvent keyDownEv = { event.when, EV_KEY, event.code, KEY_DOWN_STATE, dhId, event.path };
simEvents.push_back(keyDownEv);
RawEvent fingerEv = { event.when, EV_KEY, BTN_TOOL_FINGER, KEY_DOWN_STATE, dhId, event.path };
simEvents.push_back(fingerEv);
if (absPos.first != -1) {
RawEvent absXEv = { event.when, EV_ABS, ABS_X, absPos.first, dhId, event.path };
simEvents.push_back(absXEv);
}
if (absPos.second != -1) {
RawEvent absYEv = { event.when, EV_ABS, ABS_Y, absPos.second, dhId, event.path };
simEvents.push_back(absYEv);
}
RawEvent mscEv = { event.when, EV_MSC, MSC_TIMESTAMP, 0x0, dhId, event.path };
simEvents.push_back(mscEv);
RawEvent sycReportEv = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path };
simEvents.push_back(sycReportEv);
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(sessionId, simEvents);
}
void DInputState::SimulateTouchPadBtnMouseUpState(const std::string &dhId, const struct RawEvent &event)
{
std::pair<int32_t, int32_t> touchPos = GetAndClearABSPosition(dhId);
int32_t dx = touchPos.first;
int32_t dy = touchPos.second;
DHLOGI("Sinmulate touch pad BTN_MOUSE UP state to source, dhId: %s, dx: %d, dy: %d", dhId.c_str(), dx, dy);
int32_t simTrackingId = GetRandomInt32();
RawEvent touchTrackingIdEv1 = { event.when, EV_ABS, ABS_MT_TRACKING_ID, simTrackingId, dhId, event.path };
RawEvent btnToolFingerDownEv = { event.when, EV_KEY, BTN_TOOL_FINGER, KEY_DOWN_STATE, dhId, event.path };
RawEvent btnToolDoubleTapUpEv = { event.when, EV_KEY, BTN_TOOL_DOUBLETAP, KEY_UP_STATE, dhId, event.path };
RawEvent mscEv1 = { event.when, EV_MSC, MSC_TIMESTAMP, 0x0, dhId, event.path };
RawEvent sycReportEv1 = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path };
RawEvent absMtSlot = { event.when, EV_ABS, ABS_MT_SLOT, 0x0, dhId, event.path };
RawEvent absMtPosX1 = { event.when, EV_ABS, ABS_MT_POSITION_X, dx, dhId, event.path };
RawEvent absMtPosY1 = { event.when, EV_ABS, ABS_MT_POSITION_Y, dy, dhId, event.path };
RawEvent absPosX1 = { event.when, EV_ABS, ABS_X, dx, dhId, event.path };
RawEvent absPosY1 = { event.when, EV_ABS, ABS_Y, dy, dhId, event.path };
RawEvent mscEv2 = { event.when, EV_MSC, MSC_TIMESTAMP, 0x0, dhId, event.path };
RawEvent sycReportEv2 = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path };
RawEvent absMtPosX2 = { event.when, EV_ABS, ABS_MT_POSITION_X, dx, dhId, event.path };
RawEvent absMtPosY2 = { event.when, EV_ABS, ABS_MT_POSITION_Y, dy, dhId, event.path };
RawEvent btnMouseUpEv = { event.when, EV_KEY, BTN_MOUSE, KEY_UP_STATE, dhId, event.path };
RawEvent absPosX2 = { event.when, EV_ABS, ABS_X, dx, dhId, event.path };
RawEvent absPosY2 = { event.when, EV_ABS, ABS_Y, dy, dhId, event.path };
RawEvent mscEv3 = { event.when, EV_MSC, MSC_TIMESTAMP, 0x0, dhId, event.path };
RawEvent sycReportEv3 = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path };
RawEvent touchTrackingIdEv2 = { event.when, EV_ABS, ABS_MT_TRACKING_ID, simTrackingId, dhId, event.path };
RawEvent btnTouchUpEv = { event.when, EV_KEY, BTN_TOUCH, KEY_UP_STATE, dhId, event.path };
RawEvent btnToolFingerUpEv = { event.when, EV_KEY, BTN_TOOL_FINGER, KEY_UP_STATE, dhId, event.path };
RawEvent mscEv4 = { event.when, EV_MSC, MSC_TIMESTAMP, 0x0, dhId, event.path };
RawEvent sycReportEv4 = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path };
std::vector<RawEvent> simEvents = {
touchTrackingIdEv1, btnToolFingerDownEv, btnToolDoubleTapUpEv, mscEv1, sycReportEv1,
absMtSlot, absMtPosX1, absMtPosY1, absPosX1, absPosY1, mscEv2, sycReportEv2,
absMtPosX2, absMtPosY2, btnMouseUpEv, absPosX2, absPosY2, mscEv3, sycReportEv3,
touchTrackingIdEv2, btnTouchUpEv, btnToolFingerUpEv, mscEv4, sycReportEv4 };
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(lastSessionId_, simEvents);
}
void DInputState::SimulateTouchPadBtnTouchUpState(const std::string &dhId, const struct RawEvent &event)
{
DHLOGI("Sinmulate touch pad BTN_TOUCH UP state to source, dhId: %s", dhId.c_str());
int32_t simTrackingId = GetRandomInt32();
RawEvent touchTrackingIdEv = { event.when, EV_ABS, ABS_MT_TRACKING_ID, simTrackingId, dhId, event.path };
RawEvent btnTouchUpEv = { event.when, EV_KEY, BTN_TOUCH, KEY_UP_STATE, dhId, event.path };
RawEvent btnToolFingerUpEv = { event.when, EV_KEY, BTN_TOOL_FINGER, KEY_UP_STATE, dhId, event.path };
RawEvent mscEv = { event.when, EV_MSC, MSC_TIMESTAMP, 0x0, dhId, event.path };
RawEvent sycReportEv = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path };
std::vector<RawEvent> simEvents = { touchTrackingIdEv, btnTouchUpEv, btnToolFingerUpEv, mscEv, sycReportEv };
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(lastSessionId_, simEvents);
}
void DInputState::SimulateMouseBtnMouseUpState(const std::string &dhId, const struct RawEvent &event)
{
DHLOGI("Sinmulate Mouse BTN_MOUSE UP state to source, dhId: %s", dhId.c_str());
int32_t scanId = GetRandomInt32();
RawEvent mscScanEv = { event.when, EV_MSC, MSC_SCAN, scanId, dhId, event.path };
RawEvent btnMouseUpEv = { event.when, EV_KEY, BTN_MOUSE, KEY_UP_STATE, dhId, event.path };
RawEvent sycReportEv = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path };
std::vector<RawEvent> simEvents = { mscScanEv, btnMouseUpEv, sycReportEv };
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(lastSessionId_, simEvents);
}
void DInputState::SimulateNormalEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event)
{
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId,
EV_KEY, event.code, KEY_DOWN_STATE);
DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId,
EV_SYN, SYN_REPORT, 0x0);
}
void DInputState::RefreshABSPosition(const std::string &dhId, int32_t absX, int32_t absY)
{
std::lock_guard<std::mutex> lock(absPosMtx_);
if (absX != -1) {
absPositionsMap_[dhId].first = absX;
}
if (absY != -1) {
absPositionsMap_[dhId].second = absY;
}
}
std::pair<int32_t, int32_t> DInputState::GetAndClearABSPosition(const std::string &dhId)
{
std::lock_guard<std::mutex> lock(absPosMtx_);
std::pair<int32_t, int32_t> absPos = { -1, -1 };
if (absPositionsMap_.find(dhId) == absPositionsMap_.end()) {
return absPos;
}
absPos = absPositionsMap_[dhId];
absPositionsMap_.erase(dhId);
return absPos;
}
bool DInputState::IsDhIdDown(const std::string &dhId)
{
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
auto iter = keyDownStateMap_.find(dhId);
return iter != keyDownStateMap_.end();
}
void DInputState::AddKeyDownState(struct RawEvent event)
{
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
keyDownStateMap_[event.descriptor].push_back(event);
}
void DInputState::RemoveKeyDownState(struct RawEvent event)
{
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
auto iter = keyDownStateMap_.find(event.descriptor);
if (iter == keyDownStateMap_.end()) {
return;
}
auto evIter = std::find(keyDownStateMap_[event.descriptor].begin(),
keyDownStateMap_[event.descriptor].end(), event);
if (evIter == keyDownStateMap_[event.descriptor].end()) {
return;
}
keyDownStateMap_[event.descriptor].erase(evIter);
if (keyDownStateMap_[event.descriptor].empty()) {
keyDownStateMap_.erase(event.descriptor);
}
}
void DInputState::CheckAndSetLongPressedKeyOrder(struct RawEvent event)
{
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
auto iter = keyDownStateMap_.find(event.descriptor);
if (iter == keyDownStateMap_.end()) {
DHLOGI("Find new pressed key, save it, node id: %s, type: %d, key code: %d, value: %d",
event.descriptor.c_str(), event.type, event.code, event.value);
keyDownStateMap_[event.descriptor].push_back(event);
return;
}
auto evIter = std::find(keyDownStateMap_[event.descriptor].begin(),
keyDownStateMap_[event.descriptor].end(), event);
// If not find the cache key on pressing, save it
if (evIter == keyDownStateMap_[event.descriptor].end()) {
DHLOGI("Find new pressed key, save it, node id: %s, type: %d, key code: %d, value: %d",
event.descriptor.c_str(), event.type, event.code, event.value);
keyDownStateMap_[event.descriptor].push_back(event);
return;
}
// it is already the last one, just return
if (evIter == (keyDownStateMap_[event.descriptor].end() - 1)) {
DHLOGI("Pressed key already last one, node id: %s, type: %d, key code: %d, value: %d",
event.descriptor.c_str(), event.type, event.code, event.value);
return;
}
// Ohterwhise, move the key to the last cached position.
RawEvent backEv = *evIter;
keyDownStateMap_[event.descriptor].erase(evIter);
keyDownStateMap_[event.descriptor].push_back(backEv);
DHLOGI("Find long pressed key: %d, move the cached pressed key: %d to the last position", event.code, backEv.code);
}
void DInputState::ClearDeviceStates()
{
std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_);
keyDownStateMap_.clear();
}
} // namespace DistributedInput
} // namespace DistributedHardware
} // namespace OHOSs
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2023 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 "touchpad_event_fragment.h"
namespace OHOS {
namespace DistributedHardware {
namespace DistributedInput {
namespace {
constexpr size_t MIN_EVENT_FRAG_SIZE = 2;
}
bool TouchPadEventFragment::IsShouldDrop()
{
return events.size() == MIN_EVENT_FRAG_SIZE;
}
bool TouchPadEventFragment::IsTouchPadOptFinish() const
{
bool isFinish = false;
for (const auto &ev : events) {
if (ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == KEY_UP_STATE) {
isFinish = true;
break;
}
}
return isFinish;
}
bool TouchPadEventFragment::IsTouchPadOptStart() const
{
bool isStart = false;
for (const auto &ev : events) {
if (ev.type == EV_KEY && ev.code == BTN_TOUCH && ev.value == KEY_DOWN_STATE) {
isStart = true;
break;
}
}
return isStart;
}
void TouchPadEventFragment::PushEvent(const RawEvent &event)
{
this->events.push_back(event);
}
std::vector<RawEvent> TouchPadEventFragment::GetEvents()
{
return this->events;
}
} // namespace DistributedInput
} // namespace DistributedHardware
} // namespace OHOS
@@ -0,0 +1,113 @@
/*
* Copyright (c) 2023 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 "touchpad_event_fragment_mgr.h"
#include <linux/input.h>
#include "dinput_log.h"
namespace OHOS {
namespace DistributedHardware {
namespace DistributedInput {
bool TouchPadEventFragmentMgr::IsPositionEvent(const RawEvent &event)
{
if (event.type == EV_ABS && (event.code == ABS_MT_POSITION_X || event.code == ABS_MT_POSITION_Y ||
event.code == ABS_X || event.code == ABS_Y)) {
return true;
}
return false;
}
bool TouchPadEventFragmentMgr::IsSynEvent(const RawEvent &event)
{
return event.type == EV_SYN && event.code == SYN_REPORT;
}
bool TouchPadEventFragmentMgr::IsWholeTouchFragments(const std::vector<TouchPadEventFragment> &events)
{
return events.front().IsTouchPadOptStart() && events.back().IsTouchPadOptFinish();
}
std::pair<bool, std::vector<RawEvent>> TouchPadEventFragmentMgr::PushEvent(const std::string &dhId, const RawEvent &event)
{
if (IsPositionEvent(event)) {
return {false, {}};
}
std::lock_guard<std::mutex> lock(fragmentsMtx_);
if (fragments_.find(dhId) == fragments_.end()) {
fragments_[dhId] = {{}};
}
fragments_[dhId].back().PushEvent(event);
if (IsSynEvent(event)) {
return DealSynEvent(dhId);
}
return {false, {}};
}
std::pair<bool, std::vector<RawEvent>> TouchPadEventFragmentMgr::DealSynEvent(const std::string &dhId)
{
if (fragments_[dhId].back().IsTouchPadOptFinish()) {
bool needSim = false;
std::vector<RawEvent> allEvents = {};
if (!IsWholeTouchFragments(fragments_[dhId])) {
// If not whole touch events, this means the down event occurs on the other device,
// so we need simulate the up actions to the other side to reset the touchpad states.
for (auto &frag : fragments_[dhId]) {
std::vector<RawEvent> fragEvents = frag.GetEvents();
allEvents.insert(allEvents.end(), fragEvents.begin(), fragEvents.end());
}
needSim = true;
DHLOGI("Find NOT Whole touchpad events need send back, dhId: %s", dhId.c_str());
}
fragments_[dhId].clear();
fragments_[dhId].push_back({});
return {needSim, allEvents};
}
if (fragments_[dhId].back().IsShouldDrop()) {
fragments_[dhId].pop_back();
}
fragments_[dhId].push_back({});
return {false, {}};
}
void TouchPadEventFragmentMgr::Clear(const std::string &dhId)
{
std::lock_guard<std::mutex> lock(fragmentsMtx_);
fragments_.erase(dhId);
}
std::vector<RawEvent> TouchPadEventFragmentMgr::GetAndClearEvents(const std::string &dhId)
{
std::lock_guard<std::mutex> lock(fragmentsMtx_);
std::vector<RawEvent> allEvents;
if (fragments_.find(dhId) == fragments_.end()) {
return {};
}
for (auto &frag : fragments_[dhId]) {
std::vector<RawEvent> fragEvents = frag.GetEvents();
allEvents.insert(allEvents.end(), fragEvents.begin(), fragEvents.end());
}
fragments_.erase(dhId);
return allEvents;
}
} // namespace DistributedInput
} // namespace DistributedHardware
} // namespace OHOS