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"

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

バイナリエディタのスクショ

どうやら 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 は基本無視されるっぽいです。