在上一篇文章,我们学习了视频数据包解码后如何通过OpenGL渲染。
本篇我们将学习如何通过PC客户端发送MouseEvent、KeyEvent,Android设备端接收到事件消息后模拟操作。
下看一下流程图:
流程分为PC客户端和Android设备端两部分。
Android设备端采用的是scrcpy-server,为了便于理解整个流程,简单作图说明一下。
下面我们重点分析PC客户端的流程。
- PC客户端在采集到MouseEvent和KeyEvent后,按照Android系统的事件规范(参考Android核心的input.h文件)封装成控制消息。
- 控制消息封装完成后放入消息队列待用。
- 控制线程扫描消息队列,发现可用消息后通过control socket发送给Android设备端
按照Android设备的事件规范定义了ControlMsg结构体:
struct ControlMsg {
enum ControlMsgType type;
union {
struct {
enum android_keyevent_action action;
enum android_keycode keycode;
uint32_t repeat;
enum android_metastate metastate;
} inject_keycode;
struct {
char *text; // owned, to be freed by free()
} inject_text;
struct {
enum android_motionevent_action action;
enum android_motionevent_buttons action_button;
enum android_motionevent_buttons buttons;
uint64_t pointer_id;
struct MdcPosition position;
float pressure;
} inject_touch_event;
struct {
struct MdcPosition position;
float hscroll;
float vscroll;
enum android_motionevent_buttons buttons;
} inject_scroll_event;
struct {
enum android_keyevent_action action; // action for the BACK key
// screen may only be turned on on ACTION_DOWN
} back_or_screen_on;
struct {
enum CopyKey ckey;
} get_clipboard;
struct {
uint64_t sequence;
char *text; // owned, to be freed by free()
bool paste;
} set_clipboard;
struct {
enum ScreenPowerMode mode;
} set_screen_power_mode;
};
static ssize_t serialize(const struct ControlMsg *msg, unsigned char *buf);
};
为了操作方便,将一些常用的操作,例如:后退、返回主界面、锁屏等封装成了快捷消息:
void actionHome();
void actionBack();
void actionAppSwitch();
void actionPower();
void actionVolumeUp();
void actionVolumeDown();
void actionMenu();
void pressBackOrTurnScreenOn();
void setScreenPowerMode(bool state);
void expandNotificationPanel();
void expandSettingsPanel();
void collapsePanels();
void rotateDevice();
控制消息发送部分代码较多,放到了github.
GitHub: linkedbyte
QQ:2276769057