totorajの開発日記

僕がなんかメモる

adbを使ってAndroid端末の画面操作をしたときのメモ

よく使われているやり方を試す

tapとswipe

adb shell input tap x y
adb shell input swipe x1 y1 x2 y2 duration

遅いしPC側の操作を再現できないのでボツ。

sendevent

adb shell setevent /dev/input/eventX type code value

参考: Emulating touchscreen interaction with sendevent in Android

/dev/input/eventXのeventXは端末によって変わるので

adb shell getevent -pl > getevent.txt

とかで調べてください。

これなら再現できそう!っと思っていた時期が僕にもありました。

どうやらsendevent毎にファイルに書き込むという動作が入るのでめちゃくちゃ遅いです。

これもボツです。

別のやり方を試す

まずはsendeventの仕組みを調べました。

参考: adb - Android simulate fast swipe - Stack Overflow

どうやらtoolbox/sendevent.cってのが正体っぽい。

適当に探したらソースコードがあった。

toolbox/sendevent.c - platform/system/core - Git at Google

/dev/input/eventXに対してinput_eventという構造体を書き込んでいるっぽい。

/dev/input/eventXを覗いてみる

adb shell "dd if=/dev/input/eventX of=/sdcard/event_copy"

とかで適当にコピーして中を覗いてみた。

f:id:totorachan:20170925134000p:plain

どうやら1つのinput_eventが24byteずつで書き込まれているようだ。

まとめると、

timeval: 16byte
type: 2byte
code: 2byte
value: 4byte

timevalだけよくわからんので調べると、どうやらマイクロ秒までのUNIX時間っぽい。

なので結局

秒以上の部分: 8byte
秒未満の部分: 8byte
type: 2byte
code: 2byte
value: 4byte

になるようだ。

あとは適当にリトルエンディアンで書き込めば大丈夫そう。

/dev/input/eventXに書き込んでみる

PC側からバイナリを書き込む方法ですが、

adb shell print "\x01\x02\x03..." ^> /dev/input/eventX

てな感じで何とかなりました。

もっといい方法があったら教えてほしいです。

参考: shell - echo bytes to a file - Unix & Linux Stack Exchange

結果

sendeventが遅い原因はinput_eventを一つずつ書き込んでいることだった。

ある程度まとめて/dev/input/eventXに書き込んでやることでそれなりの速度が出ました。

あと、timevalは基本無視されるっぽいです。