2012/06/20

root化した端末で、Settings.secure.*の設定値を勝手に書き換える。


電池もちの悪いスマホをどうにかしようと、LTEにアタッチさせない方法をいろいろ探っているときに、たまたま見つけたHackテクニックを紹介。

すでに、某所にて回答として書いたネタだったりするのですが、結構いろいろできておもしろいので、こちらでも紹介。

そもそもSettings.secureがいじれると何が嬉しい?
私自身、何が嬉しいかはよく知りません(爆)
本来、getすることができてもsetすることはできない設定値をいじれることが嬉しい、ってだけの完全にダメなハッカーです。はい。

一応リファレンス見てみると…
http://developer.android.com/reference/android/provider/Settings.Secure.html

う〜ん、なんかピンと来るもんはないですね。パーミッションさえあればAndroid標準で提供されているAPIを経由して設定できるものが多いです。
WIFI系の設定値で、AP_COUNTとかWATCH_DOGなんとか、みたいなのがある程度でしょうか。

あ、Settings.systemのほうもいじれますよ。念のため。ただ、system設定をいじったところで、そんなにおもしろいことはできないような。。偏見ですが。


どうやっていじるか

Settings.systemとかSettings.secureって、実体は何かって知ってます?
Androidのソースを読むと分かるんですが、結局のところ
/data/data/com.android.providers.settings/databases/settings.dbを、
コンテントプロバイダ経由で読み書きしてるだけなんですね。

root@android:/ #sqlite3 /data/data/com.android.providers.settings/databases/settings.db

SQLite version 3.7.2
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .table

android_metadata   bookmarks          system          bluetooth_devices  secure  

こんな具合に、root権があると、sqlite使って覗けちゃうんですよね。

ということは! ですよ。

su -c "echo | sqlite3 <上記settings.dbのパス>"

って、アプリからrootシェルたちあげて実行すれば、putInt(Settings.secureなんちゃら)みたいの書いたりせずとも、ましてや、AndroidManifestでパーミッションを設定していなくても、設定値を読み書きできちゃうんですね。

アイディアとしてはそんな感じです。
実装はここをみてください。SuperUser+su環境でrootシェルを動かすための補助クラスを使って8行程度と、非常に簡単にできてしまうのです。。
あんまりおおっぴらに言ってしまうと、よろしくない内容なので、多くは語りません(^^;;

2012/06/03

スマートフォンのLTE待受で電池がもたなさすぎな件についてAndroidソースコードを読んで考える

職業柄、毎日のようにスマホをさわっているのだけども、どうも気になって仕方がないことがある。
それが、電池もちの悪さだ。
企業秘密とかもあるので、多くは語れないのだけど、語れる部分をいうと、概してLTE待受の電池もちが悪い。

うちの製品だけだったら、富士通がんばれよ、と2chに書けば済む話だが、
実際には他の会社も同じようなのだ。

あのSamsungが珍しくフィーバーを起こした、Galaxy Note。
docomo版はLTE対応。無駄に羊が歩いているのはrootをとって根っから削除したとしても、1日とちょっとしか電池が持たない。
いっぽう、国際版の3G only版はというと、余裕で2日はもつ。もちろん、特段の配慮など全くしていない。普段使いのままで、である。

そこで、簡単に思いつくのは、3Gだけにしかアタッチしないようにすればいいのではないか?という話。
イーモバイルのルーターだと回線接続を安定させる目的ではあるがLTE onlyや3G onlyにする裏技が用意されている。
これはAndroidで実現できない訳がない。

ということで、ためしにAndroidのソースコード検索で「WCDMA only」で検索してみた。

あったwwww

モデム側が実装しているかどうか、は別として、Androidの仕組みとしては存在しているらしい。
じゃあ、どこから設定ができるのだろう。

アプリ側のルートを追ってみた。
ここNT_MODE_WCDMA_ONLYという変数が定義されててこいつが使われているところをたどると...

意外にもPhoneであった。
あれ、これって、あのAPN設定とかあの辺の並びじゃない?

でも、手元の端末にはそのような設定はないぞ?
うーん、ソースコード的には選べるはずなんだけどな。。
ってことは、何? わざわざWCDMA onlyという選択肢をメーカーのカスタマイズで消してるってこと?
(勝手なイメージコード)
418     <string-array name="preferred_network_mode_choices">
419         <item>LTE / CDMA</item>
420         <!--<item>EvDo only</item>-->
421         <!--<item>CDMA w/o EvDo</item>-->
422         <!--<item>CDMA / EvDo auto</item>-->
423         <item>GSM / WCDMA auto</item>
424         <!--<item>WCDMA only</item>-->
425         <item>GSM only</item>
426         <!--<item>GSM / WCDMA preferred</item>-->
427     </string-array>
428     <string-array name="preferred_network_mode_values"  translatable="false">
429         <item>"7"</item>
430         <!--<item>"6"</item>-->
431         <!--<item>"5"</item>-->
432         <!--<item>"4"</item>-->
433         <item>"3"</item>
434         <!--<item>"2"</item>-->
435         <item>"1"</item>
436         <!--<item>"0"</item>-->
437     </string-array>
べつに電池がもつならそれでいいんだけど、速度いらない、むしろ電池持つ方がうれしい!っていう時もあるんじゃないの?
そんなわけで、ちょっとrootとって、3Gだけにしかアタッチしない電話を作ってみようと思う。

いじるのは↑のリソースファイル。ここでWCDMA only(value=2)を選択可能にしてあげれば良さげーである。

まあ、国内版Galaxy note LTEに使われているモデム側が実装ないとダメなところではあるが。モノは試しである。