mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-11-23 07:01:24 +00:00
Description: implement raw input event injecting tool
IssueNo:IAUTBL Feature or Bugfix: Feature Binary Source:No Signed-off-by: jiadexiang <jiadexiang@huawei.com>
This commit is contained in:
parent
20bfe8fe12
commit
37219f3851
@ -162,6 +162,7 @@ adapter/ohos/osal/want_wrap_ohos.cpp @arkui_superman
|
||||
adapter/ohos/osal/want_wrap_ohos.h @arkui_superman
|
||||
adapter/ohos/sa_profile/ @arkuiframework
|
||||
adapter/ohos/services/ @arkuiframework
|
||||
adapter/ohos/tools/raw_input_injector/ @arkuievent
|
||||
|
||||
[Preview adapter]
|
||||
adapter/preview/ @arkuistatemgmt
|
||||
|
@ -18,6 +18,7 @@ import("//foundation/arkui/ace_engine/ace_config.gni")
|
||||
group("ace_packages") {
|
||||
# core library for Ability Cross-platform Environment(ACE) JS
|
||||
deps = [
|
||||
"$ace_root/adapter/ohos/tools:tools_target",
|
||||
"$ace_root/advanced_ui_component:advanced_ui_component",
|
||||
"$ace_root/build:libace",
|
||||
"$ace_root/build:libace_compatible",
|
||||
|
24
adapter/ohos/tools/BUILD.gn
Normal file
24
adapter/ohos/tools/BUILD.gn
Normal file
@ -0,0 +1,24 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
import("//foundation/arkui/ace_engine/ace_config.gni")
|
||||
|
||||
group("tools_target") {
|
||||
if (build_variant == "root") {
|
||||
# only compiling for eng version, and don`t compile for previewer and arkui-x
|
||||
if (is_ohos_standard_system && !use_mingw_win && !use_mac && !use_linux) {
|
||||
deps = [ "raw_input_injector:rawinput" ]
|
||||
}
|
||||
}
|
||||
}
|
55
adapter/ohos/tools/raw_input_injector/BUILD.gn
Normal file
55
adapter/ohos/tools/raw_input_injector/BUILD.gn
Normal file
@ -0,0 +1,55 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
import("//foundation/arkui/ace_engine/ace_config.gni")
|
||||
|
||||
ohos_source_set("rawinput-injector") {
|
||||
sources = [
|
||||
"injecting_executor.cpp",
|
||||
"injector_utils.cpp",
|
||||
"raw_input_command.cpp",
|
||||
"raw_input_injector.cpp",
|
||||
]
|
||||
branch_protector_ret = "pac_ret"
|
||||
|
||||
sanitize = {
|
||||
cfi = true
|
||||
cfi_cross_dso = true
|
||||
debug = false
|
||||
}
|
||||
|
||||
external_deps = [
|
||||
"c_utils:utils",
|
||||
"input:libmmi-client",
|
||||
]
|
||||
part_name = ace_engine_part
|
||||
subsystem_name = ace_engine_subsystem
|
||||
}
|
||||
|
||||
ohos_executable("rawinput") {
|
||||
sources = [ "main.cpp" ]
|
||||
configs = [ "$ace_root:ace_coverage_config" ]
|
||||
|
||||
branch_protector_ret = "pac_ret"
|
||||
sanitize = {
|
||||
cfi = true
|
||||
cfi_cross_dso = true
|
||||
debug = false
|
||||
}
|
||||
|
||||
deps = [ ":rawinput-injector" ]
|
||||
|
||||
part_name = ace_engine_part
|
||||
subsystem_name = ace_engine_subsystem
|
||||
}
|
132
adapter/ohos/tools/raw_input_injector/injecting_executor.cpp
Normal file
132
adapter/ohos/tools/raw_input_injector/injecting_executor.cpp
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "injecting_executor.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "input_manager.h"
|
||||
#include "pointer_event.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Ace {
|
||||
|
||||
int32_t InjectingExecutor::GetPointerActionFromCommandType(CommandType type)
|
||||
{
|
||||
switch (type) {
|
||||
case CommandType::TOUCH_DOWN:
|
||||
return MMI::PointerEvent::POINTER_ACTION_DOWN;
|
||||
case CommandType::TOUCH_MOVE:
|
||||
return MMI::PointerEvent::POINTER_ACTION_MOVE;
|
||||
case CommandType::TOUCH_UP:
|
||||
return MMI::PointerEvent::POINTER_ACTION_UP;
|
||||
case CommandType::TOUCH_CANCEL:
|
||||
return MMI::PointerEvent::POINTER_ACTION_CANCEL;
|
||||
default:
|
||||
return MMI::PointerEvent::POINTER_ACTION_MOVE;
|
||||
}
|
||||
}
|
||||
|
||||
CommandType InjectingExecutor::GetCommandTypeFromPointerAction(int32_t pointerActionType)
|
||||
{
|
||||
switch (pointerActionType) {
|
||||
case MMI::PointerEvent::POINTER_ACTION_DOWN:
|
||||
return CommandType::TOUCH_DOWN;
|
||||
case MMI::PointerEvent::POINTER_ACTION_MOVE:
|
||||
return CommandType::TOUCH_MOVE;
|
||||
case MMI::PointerEvent::POINTER_ACTION_UP:
|
||||
return CommandType::TOUCH_UP;
|
||||
case MMI::PointerEvent::POINTER_ACTION_CANCEL:
|
||||
return CommandType::TOUCH_CANCEL;
|
||||
default:
|
||||
return CommandType::UNKNOWN;
|
||||
}
|
||||
|
||||
return CommandType::UNKNOWN;
|
||||
}
|
||||
|
||||
std::string InjectingExecutor::GetPointerActionName(int32_t pointerActionType)
|
||||
{
|
||||
switch (pointerActionType) {
|
||||
case MMI::PointerEvent::POINTER_ACTION_DOWN:
|
||||
return "down";
|
||||
case MMI::PointerEvent::POINTER_ACTION_MOVE:
|
||||
return "move";
|
||||
case MMI::PointerEvent::POINTER_ACTION_UP:
|
||||
return "up";
|
||||
case MMI::PointerEvent::POINTER_ACTION_CANCEL:
|
||||
return "cancel";
|
||||
default:
|
||||
return "unkown";
|
||||
}
|
||||
|
||||
return "unkown";
|
||||
}
|
||||
|
||||
bool InjectingExecutor::IsEventNeedTriggerImmediatly(int32_t pointerActionType)
|
||||
{
|
||||
if (pointerActionType == MMI::PointerEvent::POINTER_ACTION_DOWN ||
|
||||
pointerActionType == MMI::PointerEvent::POINTER_ACTION_UP ||
|
||||
pointerActionType == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InjectingExecutor::InjectOnePonterEvent(
|
||||
std::vector<InjectingInfo>& activingInjecting, std::vector<InjectingInfo>& allOtherInjectings)
|
||||
{
|
||||
// must have one activing action at least
|
||||
if (activingInjecting.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
for (auto& activingPointer : activingInjecting) {
|
||||
if (ret) {
|
||||
// give a little break 1ms between two actions
|
||||
std::cout << "give a little break between two continus injecting" << std::endl;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
// 1. prepare the pointer event
|
||||
auto pointerEvent = MMI::PointerEvent::Create();
|
||||
pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
|
||||
pointerEvent->SetPointerAction(activingPointer.actionType);
|
||||
pointerEvent->SetPointerId(activingPointer.finger);
|
||||
// 2. add the activing pointer self as the first item
|
||||
MMI::PointerEvent::PointerItem activingItem;
|
||||
activingItem.SetDisplayX(activingPointer.x);
|
||||
activingItem.SetDisplayY(activingPointer.y);
|
||||
activingItem.SetPointerId(activingPointer.finger);
|
||||
pointerEvent->AddPointerItem(activingItem);
|
||||
// 3. pack all other pointers into items
|
||||
for (auto& otherPointer : allOtherInjectings) {
|
||||
MMI::PointerEvent::PointerItem item;
|
||||
item.SetDisplayX(otherPointer.x);
|
||||
item.SetDisplayY(otherPointer.y);
|
||||
item.SetPointerId(otherPointer.finger);
|
||||
pointerEvent->AddPointerItem(item);
|
||||
}
|
||||
// 4. inject
|
||||
MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace Ace
|
||||
} // namespace OHOS
|
56
adapter/ohos/tools/raw_input_injector/injecting_executor.h
Normal file
56
adapter/ohos/tools/raw_input_injector/injecting_executor.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_INJECTING_EXECUTOR_H
|
||||
#define ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_INJECTING_EXECUTOR_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "raw_input_command.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Ace {
|
||||
|
||||
struct InjectingInfo {
|
||||
int32_t actionType;
|
||||
int32_t finger;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int64_t actionTime;
|
||||
int32_t sourceType; // not used for now
|
||||
};
|
||||
|
||||
class InjectingExecutor {
|
||||
public:
|
||||
static int32_t GetPointerActionFromCommandType(CommandType type);
|
||||
static CommandType GetCommandTypeFromPointerAction(int32_t pointerActionType);
|
||||
static std::string GetPointerActionName(int32_t pointerActionType);
|
||||
static bool IsEventNeedTriggerImmediatly(int32_t pointerActionType);
|
||||
// 1. the activing injecting will be used as the pointer event object;
|
||||
// 2. all other injectings will be packed into the activing injecting object;
|
||||
// 3. if there is no any activing injecting, the injecting will be given up, and return false as result;
|
||||
// 4. if there are more than 1 activing injecting, they will be injected one by one, and all other injecting info
|
||||
// will be packed into them seperatly;
|
||||
static bool InjectOnePonterEvent(
|
||||
std::vector<InjectingInfo>& activingInjecting, std::vector<InjectingInfo>& allOtherInjectings);
|
||||
|
||||
private:
|
||||
InjectingExecutor() = default;
|
||||
~InjectingExecutor() = default;
|
||||
};
|
||||
} // namespace Ace
|
||||
} // namespace OHOS
|
||||
#endif // ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_INJECTING_EXECUTOR_H
|
144
adapter/ohos/tools/raw_input_injector/injector_utils.cpp
Normal file
144
adapter/ohos/tools/raw_input_injector/injector_utils.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "injector_utils.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Ace {
|
||||
namespace {
|
||||
constexpr int32_t TIME_TRANSITION = 1000;
|
||||
} // namespace
|
||||
|
||||
bool InjectorUtils::debugEnabled_ = false;
|
||||
|
||||
int64_t InjectorUtils::GetSysClockTime()
|
||||
{
|
||||
struct timespec ts = { 0, 0 };
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
|
||||
return 0;
|
||||
}
|
||||
return (ts.tv_sec * TIME_TRANSITION * TIME_TRANSITION) + (ts.tv_nsec / TIME_TRANSITION);
|
||||
}
|
||||
|
||||
int32_t InjectorUtils::CalculateNextPosValueWithLinear(
|
||||
int32_t startPoint, int32_t targetPoint, int32_t currentIndex, int32_t totalCount)
|
||||
{
|
||||
if (totalCount < 1) {
|
||||
std::cout << "too few total count" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (targetPoint == startPoint) {
|
||||
// no moving
|
||||
return targetPoint;
|
||||
}
|
||||
|
||||
auto distance = targetPoint - startPoint;
|
||||
auto possitive = (distance > 0) ? 1 : -1; // possitive means increasing
|
||||
// distance step
|
||||
float absStep = static_cast<float>(std::abs(distance)) / totalCount;
|
||||
// one px at least
|
||||
absStep = (absStep == 0) ? 1 : absStep;
|
||||
int32_t result = startPoint + static_cast<float>((absStep * (currentIndex + 1)) * possitive);
|
||||
if (possitive) {
|
||||
result = (result > targetPoint) ? targetPoint : result;
|
||||
} else {
|
||||
result = (result < targetPoint) ? targetPoint : result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int InjectorUtils::Combination(int n, int k)
|
||||
{
|
||||
double result = 1.0;
|
||||
for (int i = 1; i <= k; ++i) {
|
||||
result *= static_cast<double>(n - i + 1) / i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Point InjectorUtils::BezierCurve(const std::vector<Point>& controlPoints, double t)
|
||||
{
|
||||
Point result = { 0.0, 0.0 };
|
||||
int n = controlPoints.size() - 1;
|
||||
|
||||
for (int i = 0; i <= n; ++i) {
|
||||
double coeff = static_cast<double>(Combination(n, i)) * pow(t, i) * pow(1 - t, n - i);
|
||||
result.x += coeff * controlPoints[i].x;
|
||||
result.y += coeff * controlPoints[i].y;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// cubic: x < 0.5 ? 4 * x * x * x : 1 - pow(-2 * x + 2, 3) / 2
|
||||
static double EaseInOutCubic(double t)
|
||||
{
|
||||
const double c1 = 0.5;
|
||||
const int c2 = 4;
|
||||
const int c3 = -2;
|
||||
const int c4 = 2;
|
||||
const int c5 = 3;
|
||||
const int c6 = 2;
|
||||
return (t < c1) ? (c2 * t * t * t) : (1 - pow(c3 * t + c4, c5) / c6);
|
||||
}
|
||||
|
||||
// quart: x < 0.5 ? 8 * x * x * x * x : 1 - pow(-2 * x + 2, 4) / 2
|
||||
static double EaseInOutQuart(double t)
|
||||
{
|
||||
const double c1 = 0.5;
|
||||
const int c2 = 8;
|
||||
const int c3 = -2;
|
||||
const int c4 = 2;
|
||||
const int c5 = 4;
|
||||
const int c6 = 2;
|
||||
return (t < c1) ? (c2 * t * t * t * t) : (1 - pow(c3 * t + c4, c5) / c6);
|
||||
}
|
||||
|
||||
double InjectorUtils::EaseInOut(double t, EaseAlgorithm algorithm)
|
||||
{
|
||||
static const std::map<EaseAlgorithm, double (*)(double)> easeAlgorithmMap = {
|
||||
{ EaseAlgorithm::CUBIC, EaseInOutCubic }, { EaseAlgorithm::QUART, EaseInOutQuart }
|
||||
};
|
||||
return easeAlgorithmMap.at(algorithm)(t);
|
||||
}
|
||||
|
||||
Point InjectorUtils::CalculateNextPosValueWithBezier(
|
||||
std::vector<Point>& controlPoints, int32_t currentIndex, int32_t totalCount, CoordinateCurve curve)
|
||||
{
|
||||
Point result;
|
||||
if (currentIndex < 0 || currentIndex > totalCount || totalCount < 1) {
|
||||
std::cout << "wrong count given: currentIndex " << currentIndex << ", totalCount " << totalCount << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (controlPoints.empty()) {
|
||||
std::cout << "start and target point need be given at least" << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
double t = static_cast<double>(currentIndex) / totalCount;
|
||||
if (curve == CoordinateCurve::EASE_IN_OUT) {
|
||||
t = EaseInOut(t, EaseAlgorithm::QUART);
|
||||
}
|
||||
return BezierCurve(controlPoints, t);
|
||||
}
|
||||
} // namespace Ace
|
||||
} // namespace OHOS
|
67
adapter/ohos/tools/raw_input_injector/injector_utils.h
Normal file
67
adapter/ohos/tools/raw_input_injector/injector_utils.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_INJECTOR_UTILS_H
|
||||
#define ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_INJECTOR_UTILS_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace OHOS {
|
||||
namespace Ace {
|
||||
|
||||
// coordinate calculation function curve, used for point calculation of touch move
|
||||
// [Note]: only LINEAR is supported for now
|
||||
enum class CoordinateCurve : size_t { LINEAR = 0, EASE_IN_OUT, EASE_IN, EASE_OUT };
|
||||
|
||||
enum class EaseAlgorithm : size_t { CUBIC = 0, QUART };
|
||||
|
||||
struct Point {
|
||||
double x = 0; // use double for high precision
|
||||
double y = 0;
|
||||
};
|
||||
|
||||
class InjectorUtils final {
|
||||
public:
|
||||
static bool IsDebugOn()
|
||||
{
|
||||
return debugEnabled_;
|
||||
}
|
||||
|
||||
static void SetDebugEnabled(bool debug)
|
||||
{
|
||||
debugEnabled_ = debug;
|
||||
}
|
||||
|
||||
static int64_t GetSysClockTime();
|
||||
|
||||
// calculate one point value in linear way
|
||||
static int32_t CalculateNextPosValueWithLinear(
|
||||
int32_t startPoint, int32_t targetPoint, int32_t currentIndex, int32_t totalCount);
|
||||
static Point CalculateNextPosValueWithBezier(
|
||||
std::vector<Point>& controlPoints, int32_t currentIndex, int32_t totalCount, CoordinateCurve curve);
|
||||
|
||||
private:
|
||||
InjectorUtils() = default;
|
||||
~InjectorUtils() = default;
|
||||
// bezier curve calculation
|
||||
static Point BezierCurve(const std::vector<Point>& controlPoints, double t);
|
||||
static int Combination(int n, int k);
|
||||
static double EaseInOut(double t, EaseAlgorithm algorithm);
|
||||
static bool debugEnabled_;
|
||||
};
|
||||
} // namespace Ace
|
||||
} // namespace OHOS
|
||||
#endif // ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_INJECTOR_H
|
22
adapter/ohos/tools/raw_input_injector/main.cpp
Normal file
22
adapter/ohos/tools/raw_input_injector/main.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "raw_input_injector.h"
|
||||
|
||||
int32_t main(int32_t argc, char** argv)
|
||||
{
|
||||
OHOS::Ace::RawInputInjector injector;
|
||||
return injector.ExecuteInject(argc, argv);
|
||||
}
|
246
adapter/ohos/tools/raw_input_injector/raw_input_command.cpp
Normal file
246
adapter/ohos/tools/raw_input_injector/raw_input_command.cpp
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "raw_input_command.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "string_ex.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Ace {
|
||||
namespace {
|
||||
constexpr int32_t MIN_DATA_COUNT_FOR_RAW_EVENT = 2;
|
||||
constexpr int32_t MAX_DATA_COUNT_FOR_RAW_EVENT = 4;
|
||||
constexpr int32_t RAW_EVENT_X_INDEX = 0;
|
||||
constexpr int32_t RAW_EVENT_Y_INDEX = 1;
|
||||
constexpr int32_t RAW_EVENT_DURATION_INDEX = 2;
|
||||
} // namespace
|
||||
|
||||
std::string BaseCommand::GetCommandTypeName(CommandType type)
|
||||
{
|
||||
switch (type) {
|
||||
case CommandType::TOUCH_DOWN:
|
||||
return "d";
|
||||
case CommandType::TOUCH_MOVE:
|
||||
return "m";
|
||||
case CommandType::TOUCH_UP:
|
||||
return "u";
|
||||
case CommandType::TOUCH_CANCEL:
|
||||
return "c";
|
||||
case CommandType::COMMAND_WAIT:
|
||||
return "w";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string BaseCommand::GetReadableCommandTypeName(CommandType type)
|
||||
{
|
||||
switch (type) {
|
||||
case CommandType::TOUCH_DOWN:
|
||||
return "down";
|
||||
case CommandType::TOUCH_MOVE:
|
||||
return "move";
|
||||
case CommandType::TOUCH_UP:
|
||||
return "up";
|
||||
case CommandType::TOUCH_CANCEL:
|
||||
return "cancel";
|
||||
case CommandType::COMMAND_WAIT:
|
||||
return "wait";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseCommand::Feed(const std::vector<std::string>& data)
|
||||
{
|
||||
if (data.empty()) {
|
||||
return true;
|
||||
}
|
||||
for (const auto& str : data) {
|
||||
int32_t duration;
|
||||
if (!StrToInt(str, duration)) {
|
||||
return false;
|
||||
}
|
||||
SetDuration(duration);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// -d/m/u/c x y duration finger
|
||||
bool BaseRawEventCommand::Feed(const std::vector<std::string>& data)
|
||||
{
|
||||
if (data.size() < MIN_DATA_COUNT_FOR_RAW_EVENT || data.size() > MAX_DATA_COUNT_FOR_RAW_EVENT) {
|
||||
std::cout << "error data count for -" << GetCommandTypeName(GetCommandType()) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool durationSet = false;
|
||||
int32_t paramInd = 0;
|
||||
for (const auto& str : data) {
|
||||
int32_t value;
|
||||
if (!StrToInt(str, value)) {
|
||||
std::cout << "parse error for " << str << std::endl;
|
||||
return false;
|
||||
}
|
||||
switch (paramInd) {
|
||||
case RAW_EVENT_X_INDEX:
|
||||
SetTargetDisplayX(value);
|
||||
break;
|
||||
case RAW_EVENT_Y_INDEX:
|
||||
SetTargetDisplayY(value);
|
||||
break;
|
||||
case RAW_EVENT_DURATION_INDEX:
|
||||
durationSet = true;
|
||||
SetDuration(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
paramInd++;
|
||||
}
|
||||
|
||||
OnFeeded(durationSet, data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string BaseRawEventCommand::ToString() const
|
||||
{
|
||||
std::string typeName = GetReadableCommandTypeName(GetCommandType());
|
||||
std::string result = "";
|
||||
if (GetDuration() != 0) {
|
||||
result = typeName + "(" + std::to_string(GetTargetDisplayX()) + ", " + std::to_string(GetTargetDisplayY()) +
|
||||
")-[" + std::to_string(GetDuration()) + "ms]";
|
||||
} else {
|
||||
result =
|
||||
typeName + "(" + std::to_string(GetTargetDisplayX()) + ", " + std::to_string(GetTargetDisplayY()) + ")";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string WaitCommand::ToString() const
|
||||
{
|
||||
return "wait-[" + std::to_string(GetDuration()) + "]ms";
|
||||
}
|
||||
|
||||
void TouchMoveCommand::OnFeeded(bool durationSet, const std::vector<std::string>& data)
|
||||
{
|
||||
(void)(data); // not used for now
|
||||
if (!durationSet) {
|
||||
// for touch move, the default duration is 1000
|
||||
SetDuration(DEFAULT_MOVE_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandList::AddCommand(std::shared_ptr<BaseCommand> command)
|
||||
{
|
||||
commands_.push_back(command);
|
||||
}
|
||||
|
||||
void CommandList::Clear()
|
||||
{
|
||||
commands_.clear();
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<BaseCommand>>& CommandList::GetCommands() const
|
||||
{
|
||||
return commands_;
|
||||
}
|
||||
|
||||
std::string CommandList::ToString() const
|
||||
{
|
||||
std::string dumpStr = "";
|
||||
for (auto& command : commands_) {
|
||||
dumpStr += (" " + command->ToString());
|
||||
}
|
||||
return dumpStr;
|
||||
}
|
||||
|
||||
bool BaseCommand::ConsumeOnce(int64_t currentTime, ConsumeActionInfo& actionInfo)
|
||||
{
|
||||
// mark the base time line first if not set before this consuming try
|
||||
MarkConsumeBaseTimeLine(currentTime);
|
||||
// check if already consumed out
|
||||
if (IsConsumedOut()) {
|
||||
return false; // running out, can not be consumed any more
|
||||
}
|
||||
|
||||
if (currentTime >= (consumeBaseTimeLine_ + duration_)) {
|
||||
// give the current command at least one chance to be executed
|
||||
isConsumedOut_ = true;
|
||||
}
|
||||
|
||||
// call the func implemented by child class
|
||||
bool ret = DoConsumeOnce(currentTime, actionInfo);
|
||||
// increase consumed count
|
||||
MarkConsumedOnce();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WaitCommand::DoConsumeOnce(int64_t currentTime, ConsumeActionInfo& actionInfo)
|
||||
{
|
||||
actionInfo.type = GetCommandType();
|
||||
actionInfo.curve = GetCoordinateCurve();
|
||||
actionInfo.finger = GetFingerId();
|
||||
actionInfo.targetDisplayX = 0;
|
||||
actionInfo.targetDisplayY = 0;
|
||||
actionInfo.consumeIndex = GetConsumedCount();
|
||||
actionInfo.totalCount = GetTotalCount();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseRawEventCommand::DoConsumeOnce(int64_t currentTime, ConsumeActionInfo& actionInfo)
|
||||
{
|
||||
actionInfo.type = GetCommandType();
|
||||
actionInfo.curve = GetCoordinateCurve();
|
||||
actionInfo.finger = GetFingerId();
|
||||
actionInfo.targetDisplayX = GetTargetDisplayX();
|
||||
actionInfo.targetDisplayY = GetTargetDisplayY();
|
||||
actionInfo.consumeIndex = GetConsumedCount();
|
||||
actionInfo.totalCount = GetTotalCount();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandList::IsAllConsumed() const
|
||||
{
|
||||
for (const auto& command : commands_) {
|
||||
if (!(command->IsConsumedOut())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandList::ConsumeOnce(int64_t currentTime, ConsumeActionInfo& actionInfo)
|
||||
{
|
||||
if (currentConsumingIndex_ >= commands_.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& command = commands_[currentConsumingIndex_];
|
||||
command->ConsumeOnce(currentTime, actionInfo);
|
||||
if (command->IsConsumedOut()) {
|
||||
currentConsumingIndex_++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Ace
|
||||
} // namespace OHOS
|
235
adapter/ohos/tools/raw_input_injector/raw_input_command.h
Normal file
235
adapter/ohos/tools/raw_input_injector/raw_input_command.h
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_COMMAND_H
|
||||
#define ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_COMMAND_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "injector_utils.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Ace {
|
||||
// command types
|
||||
enum class CommandType : size_t { TOUCH_DOWN = 0, TOUCH_UP, TOUCH_MOVE, TOUCH_CANCEL, COMMAND_WAIT, UNKNOWN };
|
||||
|
||||
struct ConsumeActionInfo {
|
||||
CommandType type = CommandType::UNKNOWN;
|
||||
CoordinateCurve curve = CoordinateCurve::EASE_IN_OUT;
|
||||
int32_t finger = 0;
|
||||
int32_t targetDisplayX = 0;
|
||||
int32_t targetDisplayY = 0;
|
||||
int32_t consumeIndex = 0;
|
||||
int32_t totalCount = 1;
|
||||
};
|
||||
|
||||
class BaseCommand {
|
||||
public:
|
||||
BaseCommand() = default;
|
||||
virtual ~BaseCommand() = default;
|
||||
virtual bool Feed(const std::vector<std::string>& data);
|
||||
virtual std::string ToString() const = 0;
|
||||
bool ConsumeOnce(int64_t currentTime, ConsumeActionInfo& actionInfo);
|
||||
// implemented by child for raw event injecting
|
||||
virtual bool DoConsumeOnce(int64_t currentTime, ConsumeActionInfo& actionInfo) = 0;
|
||||
|
||||
static std::string GetCommandTypeName(CommandType type);
|
||||
static std::string GetReadableCommandTypeName(CommandType type);
|
||||
|
||||
bool IsConsumedOut() const
|
||||
{
|
||||
return isConsumedOut_;
|
||||
}
|
||||
|
||||
void SetDuration(int32_t duration)
|
||||
{
|
||||
duration_ = duration;
|
||||
auto total = (duration / eventInjectingInterval_);
|
||||
totalCount_ = (duration % eventInjectingInterval_ != 0) ? (total + 1) : total;
|
||||
}
|
||||
|
||||
int32_t GetDuration() const
|
||||
{
|
||||
return duration_;
|
||||
}
|
||||
|
||||
void SetCommandType(CommandType type)
|
||||
{
|
||||
commandType_ = type;
|
||||
}
|
||||
|
||||
CommandType GetCommandType() const
|
||||
{
|
||||
return commandType_;
|
||||
}
|
||||
|
||||
void SetFingerId(int32_t finger)
|
||||
{
|
||||
fingerId_ = finger;
|
||||
}
|
||||
|
||||
int32_t GetFingerId() const
|
||||
{
|
||||
return fingerId_;
|
||||
}
|
||||
|
||||
int32_t GetConsumedCount() const
|
||||
{
|
||||
return consumedCount_;
|
||||
}
|
||||
|
||||
int32_t GetTotalCount() const
|
||||
{
|
||||
return totalCount_;
|
||||
}
|
||||
|
||||
void SetCoordinateCurve(CoordinateCurve curve)
|
||||
{
|
||||
coordinateCurve_ = curve;
|
||||
}
|
||||
|
||||
CoordinateCurve GetCoordinateCurve() const
|
||||
{
|
||||
return coordinateCurve_;
|
||||
}
|
||||
|
||||
void MarkConsumedOnce()
|
||||
{
|
||||
consumedCount_++;
|
||||
}
|
||||
|
||||
// inject event every 5ms, not use 7ms as we need consider the IPC consumed time
|
||||
static const int32_t EVENT_INJECTING_INTERVAL = 5; // inject event every 5 ms
|
||||
|
||||
private:
|
||||
void MarkConsumeBaseTimeLine(int64_t currentTime)
|
||||
{
|
||||
if (consumeBaseTimeLine_ < 0) {
|
||||
consumeBaseTimeLine_ = currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t eventInjectingInterval_ = EVENT_INJECTING_INTERVAL;
|
||||
int32_t fingerId_ = 0;
|
||||
int32_t duration_ = 0; // the total time for this command can be executed
|
||||
int64_t consumeBaseTimeLine_ = -1; // the base time line for consume this command
|
||||
bool isConsumedOut_ = false;
|
||||
int32_t consumedCount_ = 0;
|
||||
int32_t totalCount_ = 1;
|
||||
CoordinateCurve coordinateCurve_ = CoordinateCurve::EASE_IN_OUT;
|
||||
CommandType commandType_ = CommandType::UNKNOWN;
|
||||
};
|
||||
|
||||
class WaitCommand : public BaseCommand {
|
||||
public:
|
||||
WaitCommand() = default;
|
||||
~WaitCommand() override = default;
|
||||
bool DoConsumeOnce(int64_t currentTime, ConsumeActionInfo& actionInfo) override;
|
||||
std::string ToString() const override;
|
||||
};
|
||||
|
||||
class BaseRawEventCommand : public BaseCommand {
|
||||
public:
|
||||
BaseRawEventCommand() = default;
|
||||
~BaseRawEventCommand() override = default;
|
||||
bool Feed(const std::vector<std::string>& data) override;
|
||||
virtual void OnFeeded(bool durationSet, const std::vector<std::string>& data) {}
|
||||
bool DoConsumeOnce(int64_t currentTime, ConsumeActionInfo& actionInfo) override;
|
||||
std::string ToString() const override;
|
||||
|
||||
void SetTargetDisplayX(int32_t x)
|
||||
{
|
||||
targetDisplayX_ = x;
|
||||
}
|
||||
|
||||
int32_t GetTargetDisplayX() const
|
||||
{
|
||||
return targetDisplayX_;
|
||||
}
|
||||
|
||||
void SetTargetDisplayY(int32_t y)
|
||||
{
|
||||
targetDisplayY_ = y;
|
||||
}
|
||||
|
||||
int32_t GetTargetDisplayY() const
|
||||
{
|
||||
return targetDisplayY_;
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t targetDisplayX_ = 0;
|
||||
int32_t targetDisplayY_ = 0;
|
||||
};
|
||||
|
||||
class TouchDownCommand : public BaseRawEventCommand {
|
||||
public:
|
||||
TouchDownCommand() = default;
|
||||
~TouchDownCommand() override = default;
|
||||
};
|
||||
|
||||
class TouchUpCommand : public BaseRawEventCommand {
|
||||
public:
|
||||
TouchUpCommand() = default;
|
||||
~TouchUpCommand() override = default;
|
||||
};
|
||||
|
||||
class TouchMoveCommand : public BaseRawEventCommand {
|
||||
public:
|
||||
TouchMoveCommand() = default;
|
||||
~TouchMoveCommand() override = default;
|
||||
void OnFeeded(bool durationSet, const std::vector<std::string>& data) override;
|
||||
static const int32_t DEFAULT_MOVE_DURATION = 1000;
|
||||
};
|
||||
|
||||
class TouchCancelCommand : public BaseRawEventCommand {
|
||||
public:
|
||||
TouchCancelCommand() = default;
|
||||
~TouchCancelCommand() override = default;
|
||||
};
|
||||
|
||||
class CommandList final {
|
||||
public:
|
||||
CommandList() = default;
|
||||
~CommandList() = default;
|
||||
|
||||
std::string ToString() const;
|
||||
void AddCommand(std::shared_ptr<BaseCommand> command);
|
||||
void Clear();
|
||||
const std::vector<std::shared_ptr<BaseCommand>>& GetCommands() const;
|
||||
bool ConsumeOnce(int64_t currentTime, ConsumeActionInfo& actionInfo);
|
||||
|
||||
void SetPointerID(int32_t pointerID)
|
||||
{
|
||||
pointerID_ = pointerID;
|
||||
}
|
||||
|
||||
int32_t GetPointerID() const
|
||||
{
|
||||
return pointerID_;
|
||||
}
|
||||
|
||||
bool IsAllConsumed() const;
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<BaseCommand>> commands_;
|
||||
int32_t pointerID_ = 0;
|
||||
int32_t currentConsumingIndex_ = 0;
|
||||
};
|
||||
|
||||
} // namespace Ace
|
||||
} // namespace OHOS
|
||||
#endif // ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_COMMAND_H
|
628
adapter/ohos/tools/raw_input_injector/raw_input_injector.cpp
Normal file
628
adapter/ohos/tools/raw_input_injector/raw_input_injector.cpp
Normal file
@ -0,0 +1,628 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "raw_input_injector.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <getopt.h>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "injector_utils.h"
|
||||
#include "string_ex.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Ace {
|
||||
namespace {
|
||||
constexpr int32_t SLEEPTIME = 20;
|
||||
constexpr int32_t OPT_CHARACTER_COUNT = 2;
|
||||
} // namespace
|
||||
|
||||
void RawInputInjector::PrintAllCommands(int32_t argc, char* argv[])
|
||||
{
|
||||
if (!InjectorUtils::IsDebugOn()) {
|
||||
return;
|
||||
}
|
||||
std::cout << "all args: " << std::endl;
|
||||
for (int32_t i = 0; i < argc; i++) {
|
||||
std::cout << " - args[" << i << "]: " << argv[i] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool RawInputInjector::ExecuteInject(int32_t argc, char* argv[])
|
||||
{
|
||||
if (!ParseAndPackCommandQueue(argc, argv)) {
|
||||
std::cout << "parse commands failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// alway return true if the parse successfully
|
||||
bool ret = true;
|
||||
if (!CheckCommandQueue()) {
|
||||
std::cout << "the commands queue can not be handled" << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!ExecuteQueue()) {
|
||||
std::cout << "execute commands failed" << std::endl;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEPTIME));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t RawInputInjector::GetOptFromCurrentPosAndMoveOn(int32_t argc, char* argv[])
|
||||
{
|
||||
int32_t opt = -1;
|
||||
if (currentParsingPos_ >= argc) {
|
||||
return opt;
|
||||
}
|
||||
|
||||
if (argv[currentParsingPos_] == nullptr || strlen(argv[currentParsingPos_]) != OPT_CHARACTER_COUNT ||
|
||||
argv[currentParsingPos_][0] != '-') {
|
||||
return opt;
|
||||
}
|
||||
|
||||
opt = argv[currentParsingPos_][1];
|
||||
currentParsingPos_++;
|
||||
return opt;
|
||||
}
|
||||
|
||||
std::string RawInputInjector::GetParamFromCurrentPosAndMoveOn(int32_t argc, char* argv[])
|
||||
{
|
||||
if (currentParsingPos_ >= argc) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (argv[currentParsingPos_] == nullptr || strlen(argv[currentParsingPos_]) == 0 ||
|
||||
argv[currentParsingPos_][0] == '-') {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string ret(argv[currentParsingPos_]);
|
||||
currentParsingPos_++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RawInputInjector::ParseAndPackCommandQueue(int32_t argc, char* argv[])
|
||||
{
|
||||
PrintAllCommands(argc, argv);
|
||||
int32_t opt = 0;
|
||||
// check the first opt, it must be -R
|
||||
opt = GetOptFromCurrentPosAndMoveOn(argc, argv);
|
||||
if (opt != 'R') {
|
||||
// quit
|
||||
return false;
|
||||
}
|
||||
opt = GetOptFromCurrentPosAndMoveOn(argc, argv);
|
||||
if (opt == 'D') {
|
||||
InjectorUtils::SetDebugEnabled(true);
|
||||
// move to next
|
||||
opt = GetOptFromCurrentPosAndMoveOn(argc, argv);
|
||||
}
|
||||
switch (opt) {
|
||||
case 'T':
|
||||
ParseAndPackCommandForTouch(argc, argv);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// rawinput -R -T -f 0 -w 333 -d 601 602 -w 603 -m 610 1120 1000 -w 5000 -u 610 1120 -f 1 -d 501 502 -w 503 -m 510 1520
|
||||
// 5000 -w 5000 -u 510 1525
|
||||
bool RawInputInjector::ParseAndPackCommandForTouch(int32_t argc, char* argv[])
|
||||
{
|
||||
int32_t opt = 0;
|
||||
bool packRet = true;
|
||||
// do not use the getopt for the next parsing as it will reorder the args, which will affect the parsing
|
||||
while ((opt = GetOptFromCurrentPosAndMoveOn(argc, argv)) != -1) {
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
packRet = ParseFingerId(argc, argv);
|
||||
break;
|
||||
case 'd':
|
||||
packRet = PackSingleCommandToQueueFromCurrentPos(CommandType::TOUCH_DOWN, argc, argv);
|
||||
break;
|
||||
case 'm':
|
||||
packRet = PackSingleCommandToQueueFromCurrentPos(CommandType::TOUCH_MOVE, argc, argv);
|
||||
break;
|
||||
case 'u':
|
||||
packRet = PackSingleCommandToQueueFromCurrentPos(CommandType::TOUCH_UP, argc, argv);
|
||||
break;
|
||||
case 'c':
|
||||
packRet = PackSingleCommandToQueueFromCurrentPos(CommandType::TOUCH_CANCEL, argc, argv);
|
||||
break;
|
||||
case 'w':
|
||||
packRet = PackSingleCommandToQueueFromCurrentPos(CommandType::COMMAND_WAIT, argc, argv);
|
||||
break;
|
||||
default:
|
||||
std::cout << "unsupprted opt: -" << static_cast<char>(opt) << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (!packRet) {
|
||||
std::cout << "pack single command failed for -" << opt << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RawInputInjector::ParseFingerId(int32_t argc, char* argv[])
|
||||
{
|
||||
if (currentParsingPos_ >= argc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string fingerValue = GetParamFromCurrentPosAndMoveOn(argc, argv);
|
||||
int32_t fingerID = 0;
|
||||
if (!StrToInt(fingerValue, fingerID)) {
|
||||
return false;
|
||||
}
|
||||
const auto& existFinger = commandMap_.find(fingerID);
|
||||
if (existFinger != commandMap_.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CommandList commandList;
|
||||
commandList.SetPointerID(fingerID);
|
||||
commandMap_[fingerID] = std::move(commandList);
|
||||
// mark the current handling finger
|
||||
currentParsingFinger_ = fingerID;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RawInputInjector::PackSingleCommandToQueueFromCurrentPos(CommandType type, int32_t argc, char* argv[])
|
||||
{
|
||||
if (currentParsingPos_ >= argc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<BaseCommand> command = nullptr;
|
||||
switch (type) {
|
||||
case CommandType::TOUCH_DOWN:
|
||||
command = std::make_shared<TouchDownCommand>();
|
||||
break;
|
||||
case CommandType::TOUCH_MOVE:
|
||||
command = std::make_shared<TouchMoveCommand>();
|
||||
break;
|
||||
case CommandType::TOUCH_UP:
|
||||
command = std::make_shared<TouchUpCommand>();
|
||||
break;
|
||||
case CommandType::TOUCH_CANCEL:
|
||||
command = std::make_shared<TouchCancelCommand>();
|
||||
break;
|
||||
case CommandType::COMMAND_WAIT:
|
||||
command = std::make_shared<WaitCommand>();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
command->SetCommandType(type);
|
||||
command->SetFingerId(currentParsingFinger_);
|
||||
|
||||
std::vector<std::string> data;
|
||||
std::string parameter;
|
||||
while ((parameter = GetParamFromCurrentPosAndMoveOn(argc, argv)) != "") {
|
||||
data.push_back(parameter);
|
||||
}
|
||||
|
||||
if (!command->Feed(data)) {
|
||||
return false;
|
||||
}
|
||||
commandMap_[currentParsingFinger_].AddCommand(command);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RawInputInjector::CheckCommandQueue()
|
||||
{
|
||||
if (commandMap_.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto iter = commandMap_.begin(); iter != commandMap_.end(); ++iter) {
|
||||
std::string dumpStr = "finger " + std::to_string(iter->first) + ":";
|
||||
dumpStr += iter->second.ToString();
|
||||
std::cout << dumpStr << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RawInputInjector::ExecuteQueue()
|
||||
{
|
||||
// 先按照7ms步进间隔扫描整个队列,生成所有的待注入的事件action信息
|
||||
std::vector<std::vector<ConsumeActionInfo>> actionList;
|
||||
if (!PrepareAllInjectingActions(actionList)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// dump all injecting actions
|
||||
DumpAllInjectingActions(actionList);
|
||||
|
||||
// 遍历生成的事件序列,按照间隔依次执行注入
|
||||
DoInject(actionList);
|
||||
|
||||
std::cout << "injecting done" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RawInputInjector::PrepareAllInjectingActions(std::vector<std::vector<ConsumeActionInfo>>& allActions)
|
||||
{
|
||||
int64_t currentTime = 0;
|
||||
while (!IsAllConsumed()) {
|
||||
std::vector<ConsumeActionInfo> actionList;
|
||||
for (auto iter = commandMap_.begin(); iter != commandMap_.end(); ++iter) {
|
||||
ConsumeActionInfo action;
|
||||
if (iter->second.ConsumeOnce(currentTime, action)) {
|
||||
actionList.push_back(action);
|
||||
}
|
||||
}
|
||||
currentTime += BaseCommand::EVENT_INJECTING_INTERVAL;
|
||||
allActions.push_back(std::move(actionList));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RawInputInjector::DumpAllInjectingActions(const std::vector<std::vector<ConsumeActionInfo>>& allActions)
|
||||
{
|
||||
if (!InjectorUtils::IsDebugOn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (allActions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t round = 0;
|
||||
for (auto& actionList : allActions) {
|
||||
std::string str = "round " + std::to_string(round) + ": ";
|
||||
for (auto& action : actionList) {
|
||||
str += ("finger " + std::to_string(action.finger) + " " +
|
||||
BaseCommand::GetReadableCommandTypeName(action.type) + ", ");
|
||||
}
|
||||
std::cout << str << std::endl;
|
||||
round++;
|
||||
}
|
||||
}
|
||||
|
||||
void RawInputInjector::DoInject(const std::vector<std::vector<ConsumeActionInfo>>& allActions)
|
||||
{
|
||||
if (allActions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t startTime = InjectorUtils::GetSysClockTime(); // todo: do we need to backforward some ms for robustness
|
||||
int32_t intervalTimeMs = BaseCommand::EVENT_INJECTING_INTERVAL;
|
||||
int64_t currentTime = startTime;
|
||||
int32_t lastActivedFinger = 0;
|
||||
int32_t round = 0;
|
||||
|
||||
for (auto& actionList : allActions) {
|
||||
std::vector<InjectingInfo> activedInjectingInfos;
|
||||
std::vector<InjectingInfo> allOtherInjectingInfos;
|
||||
PackInjectActionForOneRound(
|
||||
actionList, lastActivedFinger, currentTime, activedInjectingInfos, allOtherInjectingInfos);
|
||||
|
||||
// do the injecting
|
||||
DumpInjectingInfo(round, activedInjectingInfos, allOtherInjectingInfos);
|
||||
|
||||
// update last activing finger for next round suggesting
|
||||
if (!activedInjectingInfos.empty()) {
|
||||
lastActivedFinger = activedInjectingInfos[0].finger;
|
||||
}
|
||||
|
||||
InjectingExecutor::InjectOnePonterEvent(activedInjectingInfos, allOtherInjectingInfos);
|
||||
|
||||
// sleep 7ms
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(intervalTimeMs));
|
||||
|
||||
// update current global status
|
||||
UpdateGlobalStatus(actionList, activedInjectingInfos);
|
||||
currentTime += intervalTimeMs;
|
||||
round++;
|
||||
}
|
||||
}
|
||||
|
||||
void RawInputInjector::UpdateGlobalStatus(
|
||||
const std::vector<ConsumeActionInfo>& actionList, const std::vector<InjectingInfo>& activedInjectingInfos)
|
||||
{
|
||||
if (activedInjectingInfos.empty()) {
|
||||
return;
|
||||
}
|
||||
for (auto& info : activedInjectingInfos) {
|
||||
bool isStartUpdateNeeded = false;
|
||||
for (auto& action : actionList) {
|
||||
if (action.finger == info.finger) {
|
||||
isStartUpdateNeeded = (action.consumeIndex == action.totalCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
globalPointerStatus_.UpdatePointerStatusByPointerAction(
|
||||
info.actionType, info.finger, info.x, info.y, isStartUpdateNeeded);
|
||||
}
|
||||
}
|
||||
|
||||
void RawInputInjector::DumpInjectingInfo(int32_t round, std::vector<InjectingInfo>& activedInjectingInfos,
|
||||
std::vector<InjectingInfo>& otherInjectingInfos) const
|
||||
{
|
||||
if (!InjectorUtils::IsDebugOn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto dumpInfoToString = [](const InjectingInfo& info, std::string& targetStr) {
|
||||
targetStr += "[";
|
||||
targetStr += "finger " + std::to_string(info.finger) + " ";
|
||||
targetStr += InjectingExecutor::GetPointerActionName(info.actionType) + " ";
|
||||
targetStr += "(x: " + std::to_string(info.x) + ", y: " + std::to_string(info.y) + ")";
|
||||
targetStr += "] ";
|
||||
};
|
||||
std::string str = "round " + std::to_string(round) + ": ";
|
||||
if (!activedInjectingInfos.empty()) {
|
||||
str += "|-ACTIVE(" + std::to_string(activedInjectingInfos.size()) + "): ";
|
||||
for (auto& info : activedInjectingInfos) {
|
||||
dumpInfoToString(info, str);
|
||||
}
|
||||
}
|
||||
|
||||
if (!otherInjectingInfos.empty()) {
|
||||
str += "|-OTHER(" + std::to_string(otherInjectingInfos.size()) + "): ";
|
||||
for (auto& info : otherInjectingInfos) {
|
||||
dumpInfoToString(info, str);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << str << std::endl;
|
||||
}
|
||||
|
||||
void RawInputInjector::UpdateInjectInfoForTouchEvent(const ConsumeActionInfo& action, InjectingInfo& info) const
|
||||
{
|
||||
info.actionType = InjectingExecutor::GetPointerActionFromCommandType(action.type);
|
||||
// for the immediate event, us target x/y directly
|
||||
if (InjectingExecutor::IsEventNeedTriggerImmediatly(info.actionType)) {
|
||||
info.x = action.targetDisplayX;
|
||||
info.y = action.targetDisplayY;
|
||||
return;
|
||||
}
|
||||
|
||||
// for touch move event, calculate the next pos
|
||||
if (action.type == CommandType::TOUCH_MOVE) {
|
||||
UpdateInjectInfoForTouchMove(action, info);
|
||||
return;
|
||||
}
|
||||
|
||||
// error
|
||||
std::cout << "fatal error, no handling" << std::endl;
|
||||
}
|
||||
|
||||
void RawInputInjector::UpdateInjectInfoForTouchMove(const ConsumeActionInfo& action, InjectingInfo& info) const
|
||||
{
|
||||
if (action.type != CommandType::TOUCH_MOVE) {
|
||||
std::cout << "fatal error, not touch move" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// step 1: try to get the last point info which is already by simulated into system,
|
||||
// if not exsit, use the target position directly
|
||||
if (!globalPointerStatus_.IsPointerExist(action.finger)) {
|
||||
info.x = action.targetDisplayX;
|
||||
info.y = action.targetDisplayY;
|
||||
return;
|
||||
}
|
||||
|
||||
// step 2: get last point from globalPointerStatus_
|
||||
PointerInfo lastPointerInfo = globalPointerStatus_.GetLastPointerInfo(action.finger);
|
||||
// step 3: caluculate next point base on the last point
|
||||
CalculatePosValueBaseOnLastPoint(lastPointerInfo, action, info);
|
||||
}
|
||||
|
||||
void RawInputInjector::CalculatePosValueBaseOnLastPoint(
|
||||
const PointerInfo& lastPoint, const ConsumeActionInfo& action, InjectingInfo& info) const
|
||||
{
|
||||
Point startPoint = { lastPoint.startDisplayX, lastPoint.startDisplayY };
|
||||
Point targetPoint = { action.targetDisplayX, action.targetDisplayY };
|
||||
std::vector<Point> controlPoints; // will support control points in the future
|
||||
// prepare control points
|
||||
controlPoints.push_back(startPoint);
|
||||
// will support extra middle point in the future
|
||||
controlPoints.push_back(targetPoint);
|
||||
Point nextPoint = InjectorUtils::CalculateNextPosValueWithBezier(
|
||||
controlPoints, action.consumeIndex, action.totalCount, action.curve);
|
||||
info.x = static_cast<int32_t>(nextPoint.x);
|
||||
info.y = static_cast<int32_t>(nextPoint.y);
|
||||
}
|
||||
|
||||
void RawInputInjector::UpdateInjectInfoForWaitAction(const ConsumeActionInfo& action, InjectingInfo& info) const
|
||||
{
|
||||
// for wait action, always use the move action
|
||||
info.actionType = InjectingExecutor::GetPointerActionFromCommandType(CommandType::TOUCH_MOVE);
|
||||
if (!globalPointerStatus_.IsPointerExist(action.finger)) {
|
||||
info.x = action.targetDisplayX;
|
||||
info.y = action.targetDisplayY;
|
||||
return;
|
||||
}
|
||||
|
||||
PointerInfo lastPointerInfo = globalPointerStatus_.GetLastPointerInfo(action.finger);
|
||||
info.x = lastPointerInfo.lastDisplayX;
|
||||
info.y = lastPointerInfo.lastDisplayY;
|
||||
return;
|
||||
}
|
||||
|
||||
InjectingInfo RawInputInjector::GetInjectInfoFrom(const ConsumeActionInfo& action, int64_t currentTime) const
|
||||
{
|
||||
InjectingInfo info;
|
||||
info.finger = action.finger;
|
||||
info.actionTime = currentTime;
|
||||
|
||||
if (action.type == CommandType::COMMAND_WAIT) {
|
||||
UpdateInjectInfoForWaitAction(action, info);
|
||||
return info;
|
||||
}
|
||||
|
||||
UpdateInjectInfoForTouchEvent(action, info);
|
||||
return info;
|
||||
}
|
||||
|
||||
void RawInputInjector::PackInjectActionForOneRound(const std::vector<ConsumeActionInfo>& actionList,
|
||||
int32_t lastActivedFinger, int64_t currentTime, std::vector<InjectingInfo>& activedInjectingInfos,
|
||||
std::vector<InjectingInfo>& otherInjectingInfos)
|
||||
{
|
||||
if (actionList.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t estimatedFinger = EstimateActiveFinger(actionList, lastActivedFinger);
|
||||
if (estimatedFinger < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool immediateEventExist = false;
|
||||
for (auto& action : actionList) {
|
||||
InjectingInfo info = GetInjectInfoFrom(action, currentTime);
|
||||
if (InjectingExecutor::IsEventNeedTriggerImmediatly(info.actionType)) {
|
||||
immediateEventExist = true;
|
||||
activedInjectingInfos.push_back(info);
|
||||
continue; // next
|
||||
}
|
||||
// if there is no any event such as down/up/cancel exist, let move as activing event
|
||||
if (info.finger == estimatedFinger && !immediateEventExist) {
|
||||
activedInjectingInfos.push_back(info);
|
||||
} else {
|
||||
otherInjectingInfos.push_back(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t RawInputInjector::EstimateActiveFinger(
|
||||
const std::vector<ConsumeActionInfo>& actionList, int32_t lastActivedFinger) const
|
||||
{
|
||||
if (actionList.empty()) {
|
||||
return -1;
|
||||
}
|
||||
int32_t estimatedFinger = -1;
|
||||
for (auto& action : actionList) {
|
||||
// give other finger chance
|
||||
if (action.finger != lastActivedFinger) {
|
||||
estimatedFinger = action.finger;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if no last actived finger found, use the first directly
|
||||
if (estimatedFinger == -1) {
|
||||
estimatedFinger = actionList[0].finger;
|
||||
}
|
||||
return estimatedFinger;
|
||||
}
|
||||
|
||||
bool RawInputInjector::IsAllConsumed() const
|
||||
{
|
||||
if (commandMap_.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto iter = commandMap_.begin(); iter != commandMap_.end(); ++iter) {
|
||||
if (!(iter->second.IsAllConsumed())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GlobalPointerStatus::UpdatePointerStatusByPointerAction(
|
||||
int32_t pointerAction, int32_t fingerId, int32_t displayX, int32_t displayY, bool isStartUpdateNeeded)
|
||||
{
|
||||
CommandType commandType = InjectingExecutor::GetCommandTypeFromPointerAction(pointerAction);
|
||||
switch (commandType) {
|
||||
case CommandType::TOUCH_DOWN:
|
||||
AddPointerInfo(fingerId, displayX, displayY);
|
||||
return;
|
||||
case CommandType::TOUCH_MOVE:
|
||||
UpdatePointerInfo(fingerId, displayX, displayY, isStartUpdateNeeded);
|
||||
return;
|
||||
case CommandType::TOUCH_UP:
|
||||
case CommandType::TOUCH_CANCEL:
|
||||
RemovePointerInfo(fingerId);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalPointerStatus::AddPointerInfo(int32_t id, int32_t x, int32_t y)
|
||||
{
|
||||
PointerInfo pointerStatus;
|
||||
pointerStatus.fingerId = id;
|
||||
pointerStatus.startDisplayX = x;
|
||||
pointerStatus.startDisplayY = y;
|
||||
pointerStatus.lastDisplayX = x;
|
||||
pointerStatus.lastDisplayY = y;
|
||||
pointerStatusList_.push_back(pointerStatus);
|
||||
}
|
||||
|
||||
void GlobalPointerStatus::UpdatePointerInfo(int32_t id, int32_t x, int32_t y, bool isStartUpdateNeeded)
|
||||
{
|
||||
for (auto& pointerStatus : pointerStatusList_) {
|
||||
if (pointerStatus.fingerId == id) {
|
||||
pointerStatus.lastDisplayX = x;
|
||||
pointerStatus.lastDisplayY = y;
|
||||
if (isStartUpdateNeeded) {
|
||||
pointerStatus.startDisplayX = x;
|
||||
pointerStatus.startDisplayY = y;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalPointerStatus::RemovePointerInfo(int32_t id)
|
||||
{
|
||||
auto iter = pointerStatusList_.begin();
|
||||
while (iter != pointerStatusList_.end()) {
|
||||
auto pointerStatus = *iter;
|
||||
if (pointerStatus.fingerId == id) {
|
||||
pointerStatusList_.erase(iter);
|
||||
break;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
bool GlobalPointerStatus::IsPointerExist(int32_t fingerId) const
|
||||
{
|
||||
for (auto& pointerStatus : pointerStatusList_) {
|
||||
if (pointerStatus.fingerId == fingerId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PointerInfo GlobalPointerStatus::GetLastPointerInfo(int32_t fingerId) const
|
||||
{
|
||||
for (auto& pointerStatus : pointerStatusList_) {
|
||||
if (pointerStatus.fingerId == fingerId) {
|
||||
return pointerStatus;
|
||||
}
|
||||
}
|
||||
|
||||
return PointerInfo();
|
||||
}
|
||||
|
||||
} // namespace Ace
|
||||
} // namespace OHOS
|
108
adapter/ohos/tools/raw_input_injector/raw_input_injector.h
Normal file
108
adapter/ohos/tools/raw_input_injector/raw_input_injector.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_INJECTOR_H
|
||||
#define ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_INJECTOR_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "injecting_executor.h"
|
||||
#include "nocopyable.h"
|
||||
#include "raw_input_command.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Ace {
|
||||
|
||||
struct PointerInfo {
|
||||
int32_t startDisplayX = 0;
|
||||
int32_t startDisplayY = 0;
|
||||
int32_t lastDisplayX = 0;
|
||||
int32_t lastDisplayY = 0;
|
||||
int32_t fingerId = 0;
|
||||
};
|
||||
|
||||
class GlobalPointerStatus {
|
||||
public:
|
||||
GlobalPointerStatus() = default;
|
||||
~GlobalPointerStatus() = default;
|
||||
|
||||
void UpdatePointerStatusByPointerAction(
|
||||
int32_t pointerAction, int32_t fingerId, int32_t displayX, int32_t displayY, bool isStartUpdateNeeded = false);
|
||||
|
||||
bool IsAnyPointerExistOnScreen() const
|
||||
{
|
||||
return pointerStatusList_.size() > 0;
|
||||
}
|
||||
|
||||
const std::vector<PointerInfo>& GetPointerStatusList() const
|
||||
{
|
||||
return pointerStatusList_;
|
||||
}
|
||||
|
||||
bool IsPointerExist(int32_t fingerId) const;
|
||||
PointerInfo GetLastPointerInfo(int32_t fingerId) const;
|
||||
|
||||
private:
|
||||
void AddPointerInfo(int32_t id, int32_t x, int32_t y);
|
||||
void UpdatePointerInfo(int32_t id, int32_t x, int32_t y, bool isStartUpdateNeeded = false);
|
||||
void RemovePointerInfo(int32_t id);
|
||||
|
||||
std::vector<PointerInfo> pointerStatusList_;
|
||||
};
|
||||
|
||||
class RawInputInjector {
|
||||
public:
|
||||
RawInputInjector() = default;
|
||||
DISALLOW_COPY_AND_MOVE(RawInputInjector);
|
||||
bool ExecuteInject(int32_t argc, char* argv[]);
|
||||
|
||||
private:
|
||||
void PrintAllCommands(int32_t argc, char* argv[]);
|
||||
bool ParseAndPackCommandQueue(int32_t argc, char* argv[]);
|
||||
bool ParseAndPackCommandForTouch(int32_t argc, char* argv[]);
|
||||
bool ParseFingerId(int32_t argc, char* argv[]);
|
||||
bool PackSingleCommandToQueueFromCurrentPos(CommandType type, int32_t argc, char* argv[]);
|
||||
bool CheckCommandQueue();
|
||||
bool ExecuteQueue();
|
||||
bool PrepareAllInjectingActions(std::vector<std::vector<ConsumeActionInfo>>& allActions);
|
||||
void DumpAllInjectingActions(const std::vector<std::vector<ConsumeActionInfo>>& allActions);
|
||||
void DoInject(const std::vector<std::vector<ConsumeActionInfo>>& allActions);
|
||||
void PackInjectActionForOneRound(const std::vector<ConsumeActionInfo>& actionList, int32_t lastActivedFinger,
|
||||
int64_t currentTime, std::vector<InjectingInfo>& activedInjectingInfos,
|
||||
std::vector<InjectingInfo>& otherInjectingInfos);
|
||||
InjectingInfo GetInjectInfoFrom(const ConsumeActionInfo& action, int64_t currentTime) const;
|
||||
void UpdateInjectInfoForTouchEvent(const ConsumeActionInfo& action, InjectingInfo& info) const;
|
||||
void UpdateInjectInfoForTouchMove(const ConsumeActionInfo& action, InjectingInfo& info) const;
|
||||
void UpdateInjectInfoForWaitAction(const ConsumeActionInfo& action, InjectingInfo& info) const;
|
||||
void CalculatePosValueBaseOnLastPoint(
|
||||
const PointerInfo& lastPoint, const ConsumeActionInfo& action, InjectingInfo& info) const;
|
||||
void DumpInjectingInfo(int32_t round, std::vector<InjectingInfo>& activedInjectingInfos,
|
||||
std::vector<InjectingInfo>& otherInjectingInfos) const;
|
||||
int32_t EstimateActiveFinger(const std::vector<ConsumeActionInfo>& actionList, int32_t lastActivedFinger) const;
|
||||
void UpdateGlobalStatus(
|
||||
const std::vector<ConsumeActionInfo>& actionList, const std::vector<InjectingInfo>& activedInjectingInfos);
|
||||
bool IsAllConsumed() const;
|
||||
int32_t GetOptFromCurrentPosAndMoveOn(int32_t argc, char* argv[]);
|
||||
std::string GetParamFromCurrentPosAndMoveOn(int32_t argc, char* argv[]);
|
||||
GlobalPointerStatus globalPointerStatus_;
|
||||
std::map<int32_t, CommandList> commandMap_;
|
||||
int32_t currentParsingFinger_ = 0;
|
||||
int32_t currentParsingPos_ = 1;
|
||||
};
|
||||
} // namespace Ace
|
||||
} // namespace OHOS
|
||||
#endif // ARKUI_INPUT_RAW_INPUT_INJECTOR_RAW_INPUT_INJECTOR_H
|
Loading…
Reference in New Issue
Block a user