2018/08/14

イースターエッグ ねこあつめのねこの数え方

先日リリースされたAndroid 9でもイースターエッグのねこあつめは残っており、「Andrdoid 8.0/8.1 でのイースターエッグのねこあつめ」に書いてある手順と同じ方法でねこあつめを有効化できます。

Android 8.xの時の「たこ」も残っており、

$ adb shell am start -n com.android.egg/.octo.Ocquarium

で起動できます。


ここから本題

Android 7.x, 8.x, 9.xのイースターエッグ ねこあつめで集まったねこの数を画面上で数えようとすると手間が掛かります。そこでねこの情報が格納されている設定ファイルからねこを数えてみます。


イースターエッグ ねこあつめの設定ファイルはソースから
/data/data/com.android.egg/shared_prefs/mPrefs.xml
にあることが分かります。

設定ファイルの内容は(既にねこが集まっている場合)、以下の様になっています。

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="cat:1871912869">Cat #869</string>
    <string name="cat:771645645">Cat #645</string>
    <int name="food" value="3" />
    <string name="cat:2101744869">Cat #869</string>
</map>

このうち、ねこ以外の行は
・XML宣言
・<map>
・<int name="food" value="n" /> (現在置いているエサの種類)
・</map>
の4行なので、XMLファイルの行数から4行引いてあげればねこの数になります。

root権限がある場合

直接設定ファイルの行数を数えて4引きます。

端末上なら

# wc -l < /data/data/com.android.egg/shared_prefs/mPrefs.xml

PCからだとadbで接続して

$ adb shell "su -c \"wc -l < /data/data/com.android.egg/shared_prefs/mPrefs.xml\""

で設定ファイルの行数が表示されるのでここから4引いた数がねこの数になります。

root権限がない場合

root権限がない場合、/data以下のファイルは直接読むことができません。しかし、設定ファイルはadb backupで取得することができます。手順としては、

(1) PCからadb backupでイースターエッグ (com.android.egg) の設定をバックアップ
(2) PC上でAndroid Backup Extractorを使用してバックアップファイルをTAR形式に変換
(3) TAR形式に変換したファイルから設定ファイル (mPrefs.xml) を抽出して行数 -4

でねこの数を数えることができます。
adb backupの説明は公式サイト (https://developer.android.com/studio/command-line/adb?hl=en) を参照。


(1) PCからadb backupでイースターエッグ (com.android.egg) の設定をバックアップ
-f でバックアップファイル名を指定 (この場合egg.ab) し、バックアップします。
端末とPCを接続後、

$ adb backup -f egg.ab com.android.egg

でPC側に egg.ab が作成されます。


(2) PC上でAndroid Backup Extractorを使用してバックアップファイルをTAR形式に変換
次にAndroid Backup Extractorのサイトから、
android-backup-extractor-YYYYMMDD-bin.zip (YYYYMMDDはリリース年月日)
というファイルをダウンロードし、ZIPファイルの中から abe.jar を抽出します。
(Android Backup Extractorの実行にはJREが必要になります)

引数に unpack、読み込むバックアップファイル (egg.ab)、出力するファイル名 (egg.tar) を指定して、

$ java -jar abe.jar unpack egg.ab egg.tar

でバックファイル (egg.ab) がTAR形式 (egg.tar) で出力されます。


(3) TAR形式に変換したファイルから設定ファイル (mPrefs.xml) を抽出して行数 -4
あとはtarファイルの中から mPrefs.xml を抽出し、ファイルの行数から4を引けばねこの数になります。

$ tar xOf egg.tar apps/com.android.egg/sp/mPrefs.xml | wc -l

で mPrefs.xml の行数が表示されるのでここから4引いた数がねこの数になります。


--

ここまで書いておいてなんですが、
Android 8.0 の 2018/03/01 以降のセキュリティパッチを当てるとThreadLocalRandomの動作が変わるようで、(Android 8.1, Android 9も含む。Android 7系は不明)

https://android.googlesource.com/platform/frameworks/base/+/7bcd6aa4f71a45b27a7f4486e35ebe29fa9eb507/packages/EasterEgg/src/com/android/egg/neko/Cat.java#203

で新しいねこが来る時に生成される乱数が端末を再起動しない限り同じ値を返すようになってしまって、ねこがなかなか増えない状態になってます。

プロセスが生きている間は 10 → 24 → 49 → 34 → ... のようにランダムに値を返すのですが、プロセスが一旦終了し再び実行されると 10 → 24 → 49 → 34 → ... と同じ値を返すようになっています。つまり、
新しいねこがくる(乱数で生成された値がnnn)、プロセスが終了する、
新しいねこがくる(乱数で生成された値がnnn)、プロセスが終了する、
の繰り返しになってしまい、新しく来るねこが毎回同じねこになってしまって…