mirror of
https://github.com/openharmony/distributedhardware_distributed_input.git
synced 2026-07-18 16:04:40 -04:00
improve touchpad reset functions
Signed-off-by: hwzhangchuang <zhangchuang.zhang@huawei.com>
This commit is contained in:
+1
-1
@@ -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",
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
|
||||
+14
-13
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user