ラベル イースターエッグ の投稿を表示しています。 すべての投稿を表示
ラベル イースターエッグ の投稿を表示しています。 すべての投稿を表示

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)、プロセスが終了する、
の繰り返しになってしまい、新しく来るねこが毎回同じねこになってしまって…

2018/02/07

Andrdoid 8.0/8.1 でのイースターエッグのねこあつめ

Android 7.x の時にあったイースターエッグは Android 8.0/8.1 でも引き続き遊べます。

ただ、最初から Android 8.x が入った端末では Android 7.x と同じ方法ではねこあつめを始めることはできません。
最初から Android 8.x だった端末でイースターエッグのねこあつめを有効にするにはPCから

$ adb shell am start -n com.android.egg/.neko.NekoActivationActivity

を実行します。実行後、Android 7.x でねこあつめを有効にした時と同じようにねこが表示されるので、Android 7.x の時と同じように通知にねこあつめのお皿を置いてあげれば動きます。


2018/08/14 追記
Android 9 でも引き続き遊べます。また、最初からAndroid 9 が入った端末でも上記と同じ方法で猫集めを有効にできます。
追記ここまで

2018/11/24 追記
Android 9でも遊べると以前書いたのですが、Pixelシリーズのソースを見ると、
・Pixel, Pixel XL(発売時Android 7.1.0)ではAndroid 9にアップデートしてもねこあつめが残っている
・Pixel 2, Pixel 2 XL(発売時Android 8.0.0)ではAndroid 9にアップデートするとねこあつめは(おそらく)削除される
・Pixel 3, Pixel 3 XL(発売時Android 9)は最初から無い
というものでした。
他の端末でも発売時にAndroid 8.0/8.1だった端末をAndroid 9にアップデートするとねこあつめが削除されて遊べなくなるかもしれません。
追記ここまで

2019/02/06 追記
Pixel, Pixel XLですが、Android 9 2018-12-05のセキュリティパッチ(該当するイースターエッグのソース)でねこあつめが削除されペイントになっています。
Essential PH-1はAndroid 9 2019-02-05のセキュリティパッチでねこあつめが削除されペイントになっています。
追記ここまで

Android 8.0/8.1 でねこあつめに修正が入ったかソースを見てみると Android 7.1.2 の時から3回修正が入っていました。

51efddbd3bb304de2dd47fa8cd1114ac555958bb

キャストの削除だけなので、見た目などの変更はありません。
参考: Android 8.0 の機能と API # findViewById() 署名の変更

49ddb0de55020320a4f08bd7060cb531a84fb536

Android 8.0 のイースターエッグの追加。見た目などの変更はありませんが、Android 7.x 用のまま Android 8.0 向けでコンパイルしているため、

(1) ねこが来ても通知に表示されない
(2) ねこの画像の共有時、アプリが落ちる

ようになってしまいました。

(1)の原因は Android 8.0 で通知の仕様に変更があったためです。修正する必要があったのですが忘れられていたようです。
参考: Android 8.0 の機能と API #通知

(2)の原因は Android 7.0 から FileProvider クラスを使用してファイルの共有をする必要があるのですが、FileProvider を使用していないため落ちます。
参考: Android 7.0 の動作の変更点 #アプリ間のファイルの共有

7bcd6aa4f71a45b27a7f4486e35ebe29fa9eb507

Android 8.1 では上記の2つのバグの修正と、Treatがドーナツからクッキー(オレオ)に変更されました。(クッキーと書いたのは画像ファイルがfood_cookie.xmlになっていたので)

2017/12/10

3000匹集まったので

Android 7 のイースターエッグ、ねこあつめで3000匹集まった
で3000匹のスクリーンショット










2017/08/25

Android 7 でのイースターエッグで表示されるねこの種類 (2)

前回は、"ねこの色などを決めている乱数のシードを0~231-1まで変えて種類を数えるしかない" となり、種類を数え切れていなかったので、今回はシードを0~2,147,483,647まで変えて数えました。

以下のような結果になりました。

まずは前回、選択可能なパターンで何種類いるか見た定義されている11色。

出現回数 種類
0xFF212121
386,547,201
2,048
0xFFFFFFFF
386,547,151
3,072
0xFF616161
300,647,462
3,072
0xFF795548
300,647,869
3,072
0xFF90A4AE
214,748,370
3,072
0xFFFFF9C4
214,748,365
3,072
0xFFFF8F00
214,748,377
3,072
0xFF29B6F6
10,737,323
3,044
0xFFFFCDD2
10,737,350
3,046
0xFFCE93D8
10,737,557
3,042
0xFF43A047
8,589,885
3,035
合計
2,059,436,909
30,599

0xFF212121 ~ 0xFFFF8F00 の色のねこは全種類出現していました。
0xFF29B6F6 ~ 0xFF43A047 の色のねこは出現回数が減るため、全種類は出ないようです。


続いて定義されている11色以外となるねこは

2,147,483,647 - 2,059,436,909 = 88,046,738 回

出現し、種類は結果だけを書くと 85,516,367 種類となりました。

このうち、定義されている11色と被る種類が、
  0xFF8F00 で 2種類
  0x29B6F6 で 3種類
  0x43A047 で 21種類
いたので、定義されている11色以外のねこは

85,516,367 - 2 - 3 - 21 = 85,516,341 種類

となります。

以上からねこの種類は

30,599 + 85,516,341 = 85,546,940 種類

となります。(書いたプログラムが合っていればですが…)

2017/08/21

Android 7 でのイースターエッグで表示されるねこの種類 (1)

先に結論を書いておくと、数え切れてません。

Android 7でのイースターエッグのねこの体の色は、定義されている11色以外に多くの色を取り得ること、各部位の色の全てのパターンが現れるとも限らないので、ねこの色などを決めている乱数のシードを0~231-1まで変えて種類を数えるしかないと思います。

2017/08/25 追記: シードを0~2,147,483,647まで変えて数えました → Android 7 でのイースターエッグで表示されるねこの種類 (2)

ひとまず、選択可能なパターンでねこが何種類いるかソースを見ながら計算してみる。
(体の色が定義されている11色以外の色があるが、今回は考えない。)




2. 目、口、鼻

https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#158

体の色が暗いか(isDark(mBodyColor))どうかで決まる。
体の色が暗いなら白、そうでなければそのまま(黒)。



3. 耳の内側

https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#161

目、口、鼻と同様に体の色が暗いかどうかで決まる。
暗ければ 0xFFEF9A9A、そうでなければ 0x20D50000。画像は"2. 目、口、鼻"と同じ。


4. 腹

https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#163,
https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#108
より、0(透明、つまり体の色と同じ)か0xFFFFFFFF(白)の2通り



5. 顔の色(というか鼻と口周り)

https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#165

腹と同じで0(透明、つまり体の色と同じ)か0xFFFFFFFF(白)の 2通り
Cat.java の167行目では顔の色が明るければ(!isDark(faceColor))口と鼻を黒くする。


顔の色が明るくなったので、口と鼻が黒くなる(右)



6. つま先

https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#172
Cat.javaの172行目からどのつま先を白くするかの処理。
174行目、4本とも白。
178行目、前足2本(Android 7.0の場合は右前足、右後ろ足)が白。
181行目、後ろ足2本(Android 7.0の場合は左前足、左後ろ足)が白。
184行目、4本のうちどれか1本が白。
172, 176, 179, 182行目の各条件を満たさない場合は、白くならない。
全部で 1 + 1 + 1 + 4 + 1= 8通り



7. しっぽの先

https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#188
白か体の色と同じになるので 2通り



8. 頭

https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#190,
https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#119,
https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#113

体の色が暗ければ(isDark(mBodyColor))、P_LIGHT_SPOT_COLORS、暗くなければP_DARK_SPOT_COLORS の各配列の中から選択。
P_LIGHT_SPOT_COLORS は Cat.java の119行目で0(透明、つまり体の色と同じ)か0xFFFFFFFF (白) の2通り。
P_DARK_SPOT_COLORS は Cat.java の113行目で0(透明、つまり体の色と同じ)、0xFF212121、0xFF6D4C41 の3通り。
暗いか暗くないかで2通り、または3通りになる。
1.の体の色では、黒いねこ(色は0xFF212121)のみisDarkがtrueになる。

体の色が暗い場合

体の色が明るい場合


9.襟

https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#194,
https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#97

P_COLLAR_COLORSで、定義されている8色
0xFFFFFFFF, 0xFF000000, 0xFFF44336, 0xFF1976D2, 0xFFFDD835, 0xFFFB8C00, 0xFFF48FB1, 0xFF4CAF50



10.蝶ネクタイ

https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#196
Cat.java の196~197行目。
0(透明、つまり蝶ネクタイを描画しない)か襟と同じ色の2通り



以上から、
1. 体の色
4. 腹
5. 顔の色(というか鼻と口周り)
6. つま先
7. しっぽの先
8. 頭
9.襟
10.蝶ネクタイ
が変わる。

黒いねこ(色は0xFF212121)の場合、
1 x 2 x 2 x 8 x 2 x 2 x 8 x 2 = 2,048 通り
それ以外のねこの場合、
10 x 2 x 2 x 8 x 2 x 3 x 8 x 2 = 30,720 通り
合計 32,768 通り

定義されている体の色だけで、これだけのパターンが考えられるので、えさを置いてねこが来て、では全部集めるのは厳しい。


おまけ: 背中

https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#164

背中も腹と同様に0(透明、つまり体の色と同じ)か0xFFFFFFFF(白)の2通りあるのですが、
https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r50/packages/EasterEgg/src/com/android/egg/neko/Cat.java#411
での戻り値の配列に back が抜けているため、描画されません。
backを描画するとこんなねこになります。



2017/07/07

Android 7.0/7.1.1 でのイースターエッグで表示されるねこの違い

Android 7.0の正式版がリリースされて1年近くたち、Android 8.0のデベロッパープレビューも出てますが、Android 7.0/7.1.1 でのイースターエッグ(ねこあつめ、Android Neko)で表示されるねこの違いが気になったのでソースを見てみました。

Android 7.0でのソースは
https://android.googlesource.com/platform/frameworks/base/+log/android-7.0.0_r33/packages/EasterEgg
Android 7.1.1でのソースは
https://android.googlesource.com/platform/frameworks/base/+log/android-7.1.1_r46/packages/EasterEgg
を見ています。
Android 7.1.1と7.1.2のソースは同じでした。

Android 7.0のリリース後に修正された点は以下の7つです。
a801d40531b71f8c75bb03bb8fec429f503e391e
1bdc770e664d7052ae277ea07bd40bd36037d822
753762c8fa3fae29f20a0fc34531ecef3fef85a9 (1)
4a1bcd966b1c271909f38b41031cc012e233fbdd (2)
1e52909888fc27bc8d7f63ceeabba0a87b65e419
7c2e730f637ee40f2be642b08a3956895dbb178b (Android 7.1.0でのソース) (3)
946c2b89396554b2618ea5bbaff4652f75768016 (Android 7.1.1, 7.1.2でのソース)

この中で見た目が変わる修正が入ったのは3つありました。

(1) 753762c8fa3fae29f20a0fc34531ecef3fef85a9

一覧でのソート処理が入りました。ねこの体の色(HSV色空間の色相)でソートされます。
Android 7.0
Android 7.1.1

黒いねこ(色は0xFF212121)、白いねこ(色は0xFFFFFFFF)、ここにはいませんが灰色のねこ(色は0xFF616161)は色相の値が0.0のため、黒だけ、白だけ、灰だけの並びにはなりません。

(2) 4a1bcd966b1c271909f38b41031cc012e233fbdd

・ねこのデザインの調整
・一覧からの削除時にダイアログを表示
・共有時の画像サイズの変更(512x512 → 600x600)
が行われました。
ねこのデザインの調整で一番分かりやすい部分は、Android 7.0では足先が白くなるパターンとして右側だけ、左側だけというのがありましたが、Android 7.1.xでは前だけ、後ろだけになっています。(上の画像だと #139, #131, #574)

(3) 7c2e730f637ee40f2be642b08a3956895dbb178b

生成されたねこに付ける名前が修正されています。(ここまでの修正がAndroid 7.1.0に含まれています)

Android 7.0, 7.1.xともにねこの生成には乱数が使用されているのですが、乱数の生成に必要なシードから名前が付けられます。
Android 7.0ではシードの上3桁、Android 7.1.xではシードの下3桁(正確にはシードを1000で割った余り)になっています。
Android 7.0ではシードが3桁未満だとアプリが(多分)落ちます。
シードは https://android.googlesource.com/platform/frameworks/base/+/android-7.0.0_r33/packages/EasterEgg/src/com/android/egg/neko/Cat.java#182 で生成されていて、 Math.abs(ThreadLocalRandom.current().nextInt()) となっているので、3桁未満になる可能性は低いです。
Android 7.1.xは下3桁になったのでアプリが落ちることは無くなりました。この修正で名前の数字部分が1桁、2桁のねこが現れるようになったと思います。


補足:
・シードの上3桁(Android 7.0)、下3桁(Android 7.1.x)をねこの名前にしているので、名前は同じなのに色が違うというのが起こります。
・ねこを全部集めようと思ってもシードが231個あるのでねこもその数だけいます。ただ、全く同じ柄のねこになる場合があるので柄の種類としては231より少なくなると思われます。(2017/07/10訂正: シードは232個ではなく231個でした)
Android 7 でのイースターエッグで表示されるねこの種類 (1)
Android 7 でのイースターエッグで表示されるねこの種類 (2)

おまけ:
ねこの体の色は
https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r46/packages/EasterEgg/src/com/android/egg/neko/Cat.java#82 で設定されていて、11個が定義されています。
P_BODY_COLORS の最後が "0" になっていますが、これは透明ではなく、
https://android.googlesource.com/platform/frameworks/base/+/android-7.1.1_r46/packages/EasterEgg/src/com/android/egg/neko/Cat.java#152 で乱数を使って体の色を決めています。(Color.HSVToColor(new float[]{}) はアルファ値を 0xFF でHSVToColor(int alpha, float hsv[])を呼び出しているので生成される色は透明になりません。)

P_BODY_COLORSで定義されている11色はこのようになっています。

P_BODY_COLORSの最後の "0" に当たった場合、色はランダムになります。