2011/05/05

逆USBテザリングでメール待ち受けができるCyanogenModパッチ(1)

Androidの逆USBテザリング時に通信しないアプリが存在する理由で述べた問題を解決すべく、Androidのベースモジュールに手を入れた。

やったことは、アプリに対してUSBテザリングのON/OFFをWiFiの接続状態に見せかけるようにした。
ConnectivityManager を通じてネットワークの状態を確認しているアプリは、USBテザリングがONになったときWiFiが接続したものと認識するようになる。
また、USBテザリングがON(OFF)になったときにWiFiが接続(切断)したという通知がアプリに伝わるようになる。

すなわち、メーラーの自動受信やAndroid MarketのOATのような待機系の機能が逆USBテザリング時に使えるようになる。


試したアプリの動作は次のとおり。

* K-9 Mail

IMAP IDLE接続でUSBテザリングON/NAT設定すると、"同期停止"の表示がなくなり、メールを自動的に受信した。
USBテザリングをOFFにすると、再び"同期停止"の表示になった。

* Android Market

アプリからのダウンロード、PCサイトからのOTAインストール(USBにつながっているからOn The Airじゃないけど)はできた。
しかしたまにダウンロードが開始しないことがある。そのようなときはダウンロード履歴を何回か開いてみると開始する。Google Talkにログインするとダウンロードが開始した。通常のWiFi接続のときも同様の現象を見たことがあるので、これが今回の変更による問題なのかどうかはわからない。

* NewsRob

WiFi Onlyの定期的な同期を設定。USBテザリングON/NAT設定すると、設定された同期間隔でフィードを取得した。

* なまず速報

USBテザリングON/NAT設定した後すぐに接続した。
USBテザリングをOFFにするとしばらく通知領域にアイコンが残り、"診断情報"のサーバ接続が"はい"のままだった。
これはアプリの性質上、できる限り切断時間を短くするよう、繰り返しリトライを行っているものと推測される。


変更内容は以下のとおり。ものすごくwork aroundなやり方。

* android.net.ConnectivityManager
  • getActiveNetworkInfo() ... テザリングON時に"WiFiで接続した"という情報を返す。
  • getAllNetworkInfo() ... WiFiのNetworkInfoについて、テザリングが有効であれば"WiFiで接続した"という情報に置き換える。
  • getNetworkInfo(type) ... getAllNetworkInfo()と同様。

* com.android.server.connectivity.Tethering
  • TetheredState.enter() ... USBテザリングがONになった直後、"WiFiで接続した"というIntentをbroadcastする。
  • TetheredState.exit() ... USBテザリングがOFFになった直後、"WiFiが切断した"というIntentをbroadcastする。


ビルドした/system/framework配下のファイルとソースコードのパッチを一応ここにおいた。
zipはHTC Desire、CyanogenMod 6.1.1限定なので需要ないと思うが。

最後に問題点を挙げる。

- WiFiとテザリングの同時使用は考えていないので、USBテザリング中にWiFiをONにするとおかしな挙動をするかもしれない。

- 本来の正方向のUSBテザリングを3G回線でするとき、アプリがWiFiだと認識してWiFi向けの機能を実行してしまう。アクティブな接続の種類をアプリに返すとき、3Gより優先してなりすましWiFiの情報を返してしまうため。

- USBテザリングをONにした後、それほど間を空けずホストOS側でrusbtether-natを実行しないと、アプリが通信できないものと判断してしまうかもしれない。

- jarを焼いて直後のOS起動後、USBテザリングをOFFにするとUSBデバッグができない状態となり、USBテザリングをON/OFF繰り替えしても復帰できなくなってしまった。再起動したら直った。その後この現象は発生していない。

0 件のコメント:

コメントを投稿