Android + b-mobile データ専用 SIM で電界強度を表示する

ここの内容を Galaxy Nexus に限定せずに大半を自動化するバッチファイルを作りました(2012/01/10)が、Android 4.0.3 以降の場合は今はもっとマシな方法があります(2013/04/04)。

docomo の MVNO のデータ専用 SIM で変な挙動を起こす話はそこそこ有名だと思う。
Android だと電界強度が出ずに電波なしに見えるとか、セルスタンバイが異常にバッテリーを食うとか。
よく回避策として電界強度はウィジェットとかアプリで、セルスタンバイに対しては機内モードで対応する話を見かけるのだが、そうではなくて根本的に問題を解決する方法がないか調べた。
わかりやすい解決策は出てこなかったものの、原因らしきものは見えてきたのでそれに対して応急処置をする形で対応させてみた。


参考になったのは Google+ 内での以下の投稿とコメント。
https://plus.google.com/106863374597317906686/posts/H4BjBm8P5Td

b-mobile のデータ専用 SIM で「電波なし」+「緊急通話モード」の状態になっていて、コメントの内容も考慮すれば GsmServiceStateTracker.java 内のこの辺に該当するものと思われるのでここの動作を変更してみることにした。

GsmServiceStateTracker.java#L1169
case 13:// same as 3, but indicates that emergency call is poiblndoe.

元々のコードでは ServiceState.STATE_OUT_OF_SERVICE を返しているので、これを ServiceState.STATE_IN_SERVICE を返すように変更したい。ついでに 3 の場合にも ServiceState.STATE_IN_SERVICE を返すようにしてみる。
電話サービスが使えない状態でも使えるように装うことで実現しようというわけ。

----

※自分がやった手順を書くけど保証もしないし質問に答える脳みそも無いのでやる場合は自己責任でやってください。

作業環境は GALAXY NEXUS GT-I9250 に ICL53F Deodexed Rooted Busyboxed を入れた状態。Deodexed じゃない環境で framework.jar を改変して上手く動かす方法は俺にはわからなかった。
まずボリューム上下を押しながら電源ボタンを押して、ClockworkMod Recovery を起動する。
fastboot boot recovery-clockwork-5.5.0.2-maguro.img
起動したらメニューから mounts and storage を選んで、mount /system する。
Deodexed なので framework.odex は存在しない。
なので framework.jar だけを取り出す(この時にバックアップを取っておきましょうね)。
(※Android 4.2 では telephony-common.jar に変わっていたり、framework2.jar が存在する ROM の場合はそちらも怪しいので GsmServiceStateTracker.smali が見つからなかったらその辺も疑ってください
adb pull /system/framework/framework.jar
jar の中から classes.dex を取り出す。7-Zip File Manager が好きなのでこれを使った。
取り出したファイルに対して baksmali で smali ファイルに逆コンパイルする。
java -jar baksmali-1.3.0.jar -a 14 classes.dex
out ディレクトリが作られるので、out\com\android\internal\telephony\gsm\GsmServiceStateTracker.smali をテキストエディタで開いて「.method private regCodeToServiceState(I)I」の少し後の方ぐらいにあるコードを以下のような感じに修正する。
:pswitch_data_22
    .packed-switch 0x0
        :pswitch_1c ← ※ Motorola の DROID Pro と DROID 3 はここ変えると動くようになるらしい
        :pswitch_1d ← ここを見て
        :pswitch_1c ← ※ Xperia 系ではここを(も)変えないとダメらしい
        :pswitch_1d ← ここを :pswitch_1c から :pswitch_1d に変更した 
        :pswitch_1c
        :pswitch_1f
        :pswitch_5
        :pswitch_5
        :pswitch_5
        :pswitch_5
        :pswitch_1c
        :pswitch_5
        :pswitch_1c ← ※ Xperia 系ではここを(も)変えないとダメらしい
        :pswitch_1d ← ここも :pswitch_1c から :pswitch_1d に変更した
        :pswitch_1c
    .end packed-switch
要するに 3 と 13 の時に変更したいので、0 1 2 3 と数えて4番目と14番目を :pswitch_1d か :pswitch_1f にすればいい(1 か 5 の時の処理と同じにすればいい)と思われる。
編集が終わったら smali で classes.dex に再コンパイルする。
java -jar smali-1.3.0.jar -a 14 -o classes.dex out
classes.dex が生成されたので、また framework.jar に突っ込みなおす。これも 7-Zip File Manager でいい。
ファイルが出来上がったら、この改変したファイルを端末に戻す。
adb push framework.jar /system/framework/framework.jar
最後に ClockworkMod Recovery のメニューから advanced を選び、Wipe Dalvik Cache を選ぶ。自分でやった時はこの他に Wipe cache partition もやったけど、これも必要だったのかはわからん。

全部済んだら端末を再起動して様子を見てみる。

REMOTE_HOST が *.bmobile.ne.jp で右上に 3G アンテナ表示
こんな感じ。セルスタンバイの電池消耗もおとなしくなっていることを確認。

追記 2012-08-08 ----
http://techlog.iij.ad.jp/archives/487 IIJの中の人による詳しい解説。