2013年4月4日

Android + docomo MVNO データ通信専用 SIM のセルスタンバイ&アンテナピクト問題対策 Xposed モジュール

English

docomo MVNO データ通信専用 SIM でアンテナピクトが立たない件の話。

Android 4.2.1 で公式に修正された手法を voice_capable の内容に関わらず行い、更に緊急通報のみのフラグを消すパッチをこの記事を参考に Xposed モジュールにしてみました。

今までのやり方との違い

  • 母艦不要
  • 簡単に無効化できる
  • 書き換え方が前よりいい
    (以前のパッチで失敗していた環境で動くかも)
  • SIM なしでも問題が起こらない
  • odexed/deodexed 両対応
  • 環境によっては上手くいかないこともある(MIUI とか)
  • 相変わらず root は必要

使い方の簡単な説明

  1. latest.apk をインストール
  2. DocomoSimPatcherXXXXXXXX.apk をインストール
  3. Xposed Installer を起動して Install/Update ボタンを押す
  4. Modules タブに切り替えて docomo MVNO Dataonly-SIM Patcher の左にチェックを付ける
  5. 再起動する
再起動後は docomo MVNO Dataonly-SIM Patcher にちゃんとチェックが入っているか確認してください。
Xposed モジュールは便利ですが、このように幹線部分の動作ですら簡単に差し替えたりできてしまいます。
モジュールを入れる際はソースコードを読んだりするなどして細心の注意を払ってください。

補足
Android 4.3 限定ですが、DocomoSimPatcher をベースにデータ通信専用 SIM で元々は取得できていなかった Cell ID 取得ができるようになる修正を加えた Xposed モジュールとソースコードが下記の記事で公開されています。 
http://ryutaroh-yamashita.blogspot.jp/2013/12/simcell-id.html

Xposed モジュールについてはこちらを参照するとわかりやすいです。
あと全然 Java 書いたことなかったですがモジュールも簡単にかけました。
まつもさんありがとうございました。

これで上手く行かなかったらまつもさんのモジュール今までの方法で頑張ってください。
手元の環境では上手く行ってるものの、あまりテストしてません。気が向いたら試します。
まだ実験中です。

思い出話を含む経緯

自分が Android スマートフォンを使おうかなと思ったのは Galaxy Nexus が最初で、それでデータ通信専用 SIM を挿したらなんか変だから色々やってきた(ということにしておきたい)のだが Android 4.2.1 の時点で config_voice_capable が false なら上手く動くように修正が入った
これは要するに強引な書き換えをしなくてもこうすればいいんだよ、というひとつの回答であって、こういうアプローチで解決すれば問題ないんだろうなと何となく思っていた。

そもそも switch 部分の書き換えを手段として選んだのは多種多様にカスタマイズされた Android で smali の書き換えが簡単になるように、というのが狙いだったのだけども、酷い手法ながらもこれは一定の成果が得られたように思う。

で、多分実際の電池消費の改善には貢献していないらしいという話も少しずつ広まっているような気がする。計算の重み付けが変わって電池食わなくなったように見えるだけでセルスタンバイは元々寿命には影響してなかった、みたいな話。
(グラフ見づらいし直った方がいいのは間違いないけど)

まあでも自分としては元々アンテナを出したいだけだったし、特定のアプリから回線なしと誤判定されないならそれで十分という感じだった。

とはいえ Windows でしか当てられないパッチをどうにかしたいとは思っていたし、non-deodexed ROM でも動くようにしたいとも思っていたし、直したい部分は色々あって Windows でシェルスクリプト動かせるようにすればいいのかなと思って色々探したり、処理途中まで書いてみたりはした。
ただ結局のところ自分自身が必要としていないコードを書いてる感じもあってモチベーションがアレでナニだったので完成しなかった。

そんなところで、この記事を見つけてすごくいい手法だと思った。
このアプローチで上手く行けば端末だけで完結するし、smali を触らないからそもそも switch 文のところに介入しなくてもいいし(smali 弄らなくていいならもっと綺麗に対策できる)、自分でモジュール作ってみようかなと思った。

というわけで GsmServiceStateTracker::pollStateDone の前でフックして Android 4.2.1 相当の処理を都合のいい形でバックポートしてみた次第。

追記 2013-07-26 -----------------------------------

Android 4.3 からは該当処理の実装箇所が ServiceStateTracker::useDataRegStateForDataOnlyDevices に変わったのでモジュールの中で分岐して対策してあります。

追記 2013-11-01 -----------------------------------

Android 4.4 では恐らくこの周辺に関しては大きな変化はないと思います

追記 2013-11-03 -----------------------------------

Nexus5 + IIJmio の SIM では何も対策しなくてもアンテナピクトは表示されています。
ただしセルスタンバイの圏外時間は 100% のままのように見えます。
電池消費量見ない限りは今のところ問題ないし Xposed 側の問題もあるのでまだ様子見。
現段階ではサポート環境は 4.3 までということにしておきます。
Clip to Evernote