Monday, March 22, 2010

How to create signed update.zip

カスタムROMを導入してシステム全体をアップデートする度にcacerts.bksやフォントをpushするのが面倒なので自前のupdate.zipを作っておいて、リカバリーモードで一緒に更新することにした。

署名付きzipじゃないとあかんぽいので、下記の手順を踏む。

なにはともあれAOSPをビルドする。
部分的にビルドするのでもいいのかもしれないけど。

適切にディレクトリを構成する。
$ mkdir ~/update
$ cd ~/update
$ mkdir -p system
$ mkdir -p META-INF/com/google/android

必要なファイル(自前で更新するファイル)を放り込む。
 $ find .
.
./META-INF
./META-INF/com
./META-INF/com/google
./META-INF/com/google/android
./system
./system/fonts
./system/fonts/DroidSansJapanese.ttf
./system/etc
./system/etc/security
./system/etc/security/cacerts.bks

META-INF/com/google/android/update-script ファイルを書く。
show_progress 0.1 0
copy_dir PACKAGE:system SYSTEM:
set_perm 0 0 0644 SYSTEM:etc/security/cacerts.bks
set_perm 0 0 0644 SYSTEM:fonts/DroidSansJapanese.ttf
show_progress 0.1 10

zipる。
$ zip -r ~/update.zip system META-INF

署名する。
$ java -jar ~/android-source/out/host/linux-x86/framework/signapk.jar \
~/android-source/build/target/product/security/testkey.x509.pem \
~/android-source/build/target/product/security/testkey.pk8 \
~/update.zip ~/update-signed.zip

update-singed.zipをsdcardにいれといてカスタムROM導入後にリカバリで適用してやれば終わり。
一度zip作っておけばあとはリカバリモードだけで完結するので楽チン。

Tuesday, March 16, 2010

iPhoneで時刻自動設定

先日のNexus One時刻同期記事のおまけなんですが。
iPhoneでの時刻自動設定の話。

iPhoneには時刻の自動設定機能があります。
この機能は携帯電話キャリアが携帯電話ネットーワーク上に流しているNITZ(Network Identity and Time Zone)というものを使って実現されています。
つまり、携帯電話キャリアがNITZを流していないと利用できません。

日本で正規にiPhoneを購入するとキャリアはソフトバンクモバイルになりますが、ソフトバンクはNITZを流しておらず、時刻の自動設定はできません。
実際、ソフトバンク用のCarrier Bundleファイル(/System/Linrary/Carrier Bundles/Softbank_jp.bundle/carrier.plist)ではNITZサポートを使わないような設定になっており、設定画面には自動設定の項目が表示されません。

さて、ここでiPhoneをjailbreak, sim unlockしてdocomo SIMを使ったらどうなのかという実験をしました。
(jailbreakやunlockは自己責任でどうぞ)

iPhone 3GS OS 3.1.2をPwnage Tool 3.1.5 でJB, Cydia から blacksn0w, NTTdocomo Carrier bundleをインストール。
docomo SIMを差して通話ができることを確認したものの、CydiaにあるCarrier bundleはNITZが無効になっているので、時刻の設定に自動設定がでてきません。

iFileなどをつかって/System/Library/Carrier Bundles/docomo_jp.bundle/carrier.plistを編集します。
SupportsNITZていうkeyのがあるのでfalseをtrueに変更し、保存します。
(※ 2010/04/05 追記: 現在CydiaにあるNTTdocomo Carrier bundle 0.8-0で有効(true)になっているようです)


設定に自動設定がでてきます。

適当に時計をずらしてから、オンにすると直ちに時刻が修正されるのがわかります。

というわけで、iPhoneでもdocomo SIMなどNITZに対応したキャリアなら時刻の自動設定ができました。
まぁiPhoneはiTunesと同期するときに時刻も同期するし、JBしているならばOpenNTPdだとかいくつか時刻同期ツールもあるわけですが…。

Thursday, March 11, 2010

Nexus One(Android携帯)の時刻同期のしくみ

ここ最近Nexus Oneの時計がずれるという話題があったのです。
それはCyanogenMod-5.0.4.1というカスタムロムに採用されいている2.6.33カーネルが原因だということが判明してます。(詳細はくろぺんさんが書かれています)

しかしながら、単純にカーネルのせいでずれるにしてもずれっぱなしとはなんとも解せない話でありまして、時刻同期のしくみを調べましたのでまとめることにします。
ちなみに、遅れるのはカーネルクロックだけで、デバイスクロックは遅れていないので、再起動時にカーネルがデバイスが取得する時に元に戻ります。(カーネルは起動時に物理デバイスから一度だけ時刻を取得し、以降は自前のロジックで時を刻む)

結論から申し上げまするに、Nexus One,あるいはHTCのAndroid携帯,もしくはAndroid携帯全般について言えば、NTP(SNTP)を使った時刻同期のしくみは用意されていません。(Nexus One, HT-03Aで確認)
つまりは、WiFiのみで運用している場合、時刻同期の手段がありません。
もっというなれば、SBM(少くとも黒SIM)で運用している場合も時刻同期の手段がありません。

勘違いされがちなのが、設定にある「日付と時刻」の「自動(ネットワーク自動設定)」というもの。
これはNTPなどインターネット経由での時刻同期のしくみではありません。携帯電話のネットワークで流れている時刻情報を元に時刻設定するもので、日本の場合、SBMはこれに対応していません。(NITZというらしい)
(仮にNTP機能だとしたら、NTPサーバを設定する項目がないのもおかしな話です)
実際のところ、docomoのSIMを差してこの機能を有効にすれば時刻同期はされます。OFFにして、時計をずらし、再びOにすると修正されるのがわかります。(no-SIMやSBMのSIMでは修正されない)
※ 実はiPhoneにも同様の機能がありますが、販売しているSBMで対応していないため、日本向けのiPhoneでは設定自体が表示されないようになっています。
ただし、この機能も端末起動時あるいは機内モードからの復帰時にしか時刻を取得しません。(トグルで調整されてるように見えるのはデバイスクロックと時刻取得時の差分をカーネルクロックに再適用しているだけっぽい)

さらに勘違いの元になっている /system/etc/gps.conf というファイル。
このファイルの中にはNTP_SERVER=north-america.pool.ntp.org などと記載されており、いかにもNTPで時刻あわせをしているかのように見えますが違います。
じゃぁこれはなんなのかと言われれば、GPSの原理の話になるんですが、かいつまんで言うとGPSってのは衛星から光の速さで送られてくる、衛星に搭載された原子時計の時刻情報と、それを受けとった地表での時刻情報を比較して衛星との距離を割りだし、位置を特定するというテクノロジらしい。(詳細)
つまり、地表での正確な時刻を知らなければ正しく測位できませんが、その時刻のためのNTPサーバを設定するファイルなのです。
Androidではこの時刻をデバイスクロックあるいはカーネルクロックには適用せず、GPSハードウェアへ知らせているだけです。(ちなみに4時間に一回問い合せており、失敗した場合は5分間隔でリトライしてます(ハードコード))
実際のところ、詳しくないのでよくわかりませんが、カーネルクロックと同期してないだけで、デバイスクロックは同期されているのかもしれません。(GPSデバイスがクロックソースなのかも)

そんなわけで、Nexus OneあるいはHT-03AなどたいしてカスタマイズされていないAndroid端末では、時刻同期の手段は携帯キャリアを使うしかないと思われます。

追記: 現在はNTPクライアントアプリがいくつかあります。

Saturday, February 6, 2010

Nexus One (Android端末) に CA証明書をインストールする

オレオレ証明書でSSLサイトを運用してるような人向けの話題です。

どうやらNexus OneというかAndroidは任意のCA証明書をインストール出来ない様です。
実際に cert ファイルをダウロードなりすると、証明書インストールツールが起動しますが、これはサイト証明書をインストールして次回以降この証明書を信頼するというようなもの。


CAの証明書をインストールしてもそのCAから発行した証明書は信頼してくれません。


ではどうするのか。cacerts.bksに手で追加するしかありません。

root化必須で、Java実行環境とAndroid SDKが必要です。
まず http://bouncycastle.org/download/bcprov-jdk16-141.jar をダウンロード。

$JAVA_HOME/jre/lib/ext にコピーします。
Macだと /Library/Java/Home/lib/ext/ あたり?
Debian だと/usr/lib/jvm/java-1.5.0-sun/jre/lib/ext/ とか /usr/lib/jvm/java-6-sun/jre/lib/ext/ あたり

android端末からCA証明書ストレージファイルを取り出します。
$ adb pull /system/etc/security/cacerts.bks cacerts.bks

ストレージファイルに CA cert ファイル(cacert.pem)を追加します
$ keytool -keystore cacerts.bks -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -storepass changeit -importcert -trustcacerts -alias OREORE_CA -file cacert.pem
keytoolはJREに含まれてるはずです。
OREORE_CA は適当な名前をつけたらいいです。

ストレージファイルを戻します。
$ adb remount
$ adb push cacerts.bks /system/etc/security/
これで、このCAから発行した証明書を信頼するようになり、エラーがでなくなります。

ここからは蛇足。
Androidのブラウザか、SSLのframeworkかはわかりませんが、サイト証明書のsubjectAltNameを見ない仕様(RFC的には見るべきなはずですが)のようで、
具体的にはサイト名が証明書と一致しない旨のエラーがでます。


そういうサイト運用の場合はCNを複数定義しておかねばならないようです。
証明書を発行する際の openssl.cnf [ req_distinguished_name ] で、
0.commonName                    = Common Name (eg, YOUR name)
0.commonName_max = 64
1.commonName = Common Name (eg, YOUR name)
1.commonName_max = 64
のようにしておけば、二つのCNを定義することができます。

Thursday, February 4, 2010

続: Nexus One と iPhone を SIM 1枚で運用する(MyWi編)

先日は Nexus One を親にしたテザリングでiPhoneを使ってましたが今回は逆になります。
この方法は iPhoneをjailbreakする必要があり、Nexus OneもカスタムROMにしなくてはならないため、積極的にオススメはできません。
が、既に条件を満たしているのであれば試してみるのもよいかと思います。

さて、Nexus One はカスタムROM CyanogenMod 5.0 beta3以降にします。 (参考)
それだけで準備OKです。

iPhoneのほうはJBアプリのMyWi (No Rock)というのをCydiaから入れます。しかしながらこれは有料で$9.99かかります。

MyWiはadhocネットワークでテザリングを可能にするアプリで、テザリングは純正同様にバックグラウンドで動作するので、テザリング中でも電話やネットワークが通常通りに利用できます。


また、純正テザリングは3.1.2で使えなくなってしまいましたが、MyWiをインストールすることにより再び有効化することが可能となりますので、そのために購入するのも悪くないかもしれません。

MyWiを起動したらSSIDとWEPを適当に設定して ON にします。

するとNexus Oneの無線LAN設定のところにSSIDが現れます。

WEPキーいれて接続するだけでOK。

さて、このCM5.0で実装されてるadhocネットワークのコードをみて比較してみますと、オリジナルのコードではどうやら意図的にadhocを無視して、関連するコードも省いてるようです。

抜粋
@@ -1147,9 +1167,10 @@
* Ignore adhoc, enterprise-secured, or hidden networks.
* Hidden networks show up with empty SSID.
*/
- if (AccessPointState.isAdhoc(scanResult)
- || TextUtils.isEmpty(scanResult.SSID)) {
- continue;
+ //if (AccessPointState.isAdhoc(scanResult)
+ // || TextUtils.isEmpty(scanResult.SSID)) {
+ if (TextUtils.isEmpty(scanResult.SSID)) {
+ continue;
}


大して難しくない内容なので移植してCM不要でできないかやってみようとしましたが、frameworkまで入れ替えねばならなくなり、この部分だけピンポイントで入れ替えるのが難しそうなので断念しました。


そんなわけで、今はiPhoneにSBMのSIMを差して2台を1枚のSIMで運用しております。
Nexus OneでのSBMのMMSがどうにも安定しないのでしばらくこの体制でいきます。

Tuesday, February 2, 2010

mobile power supply items

携帯端末を複数持つようになったので。

僕のような人間はスマートフォンの電池がきれると死にます。
そんなわけで、補助電源をいつも持ち歩くことにしています。

まず、旅行や超長時間の移動の際には eneloopのmobile booster KBC-L2AS

去年の暮に新型がでてiPhoneに正式対応しました。逆に旧型のだと充電できないことがあるらしいです。
長距離じゃなくても、GPSやWiFi,3Gを駆使した使い方をする時にも活躍します。
たとえば、iPhoneをGPSロガーとして使用する時とか。

次に不意に電池がやばくなってしまったときのために、eneloopのmobile stick booster

なんといっても場所をとらないのがよいです。
iPhone, Nexus Oneともに充電可能ですが、単体で電池を充電できないないので注意。
とにかくいつもカバンに忍ばせておけば、いつバッテリーがやばくなっても安心できます。

ケーブルはリール式のコンパクトなやつがおすすめですね。
iPhoneのモノは多数発売されてるのでいいとして、Nexus OneのMicro-USB Bタイプのものはミヤビックスのものしか見つかりませんでした。


また、Micro-USB変換アダプタをつかえばMini-USBのものが使えます。

Mini-USB Bのケーブルは世の中に大量に溢れいてるのでこれも一つ持っておくといいかもしれません。
ただし、中には粗悪な変換ケーブルもあったりするので気を付けた方がいいかもしれません。
これを経由したmobile stick boosterでのNexus One充電は問題なくできました。

そんなわけで、わたくしは KBC-D1ASとケーブルx2、変換アダプタをいつも持ち歩いています。
KBC-D1ASでアルカリ乾電池が使えればさらによいのですが…。パッケージの説明書によると効率はeneloopより落ちるらしいです。
緊急用ならアリかもしれません。

Saturday, January 30, 2010

Nexus One に custom rom を install する

カスタムROMについては最悪端末を文鎮にしてしまう恐れがあるので自己責任で。

Nexus One用のカスタムROMがいくつか出ているので試すことにします。
ついでに、カーネルの入れ替えもします。

今回試すのは CyanogenMod 5.0 for Nexus One
現時点で beta3 + kernel update (2.6.32-59940)がでています。
http://forum.xda-developers.com/showthread.php?t=623496
* Can be used with or without Google applications
* Latest 2.6.29.6 kernel which supports tethering, vpn, and other modules (cifs, nfs, aufs, fuse)
* Clean shudown/startup system
* NO APPS2SD. I've implemented a hack that will store the dalvik-cache of system apps in /cache, which saves you ~40MB on /data
* Built in USB tether
* Minor graphical enhancements and an excellent wallpaper by Prash
* ARM NEON optimizations (mostly to the pixelflinger library) which have not been included in the stock build yet
* Includes BusyBox, htop, nano, powertop, openvpn, and all engineering commandline utilities
* Multitouch browser using native API and code from Luke Hutchison. More MT integration coming.
* FLAC audio support from Kenny Root
* Phone enhancements from Cytown
* Contacts enhancements from Wysie
* Perform zipalign-on-install of applications
* DeskClock tweaks- longer autosilence and "require unlock" option
* Compcache is available via Spare Parts, but I don't recommend it
* Massive APN list
* Huge collection of ringtones and audio
* All available locales are included thanks to PsychoBoy
* Many other bugfixes and tweaks from AOSP contributors

こんな感じでいろいろ変わります。
普通に使う範囲だと、マルチタッチブラウザとかUSBテザリングあたりが大きいですかね。JITを有効化することによる高速化も大きいかもしれません。

さて。導入には root化あるいはbootloaderのunlockが前提となります。

フォーラムから update-cm-5.0-N1-beta3-signed.zip をダウンロード、純正アプリが必要であれば、gapps-passion-ERD79-signed.zip もダウンロードしてSDカードにコピーしておきます。

まず fastboot でリカバリモードを起動します。
Wipe により設定情報の掃除を行います。あらゆる初期状態に戻ってしまうので注意。

次に Flash zip from sdcardで update-cm-5.0-N1-beta3-signed.zip を導入、その後必要であれば gapps-passion-ERD79-signed.zip を。
これで reboot すれば導入は終りですが、フォーラムによるとそのままCM5.0b3のカーネルではバッテリーと充電関連に不具合があり、充電できなくなったり、バッテリーが死ぬとの報告がいくつかみられます。

そこでDwang氏がビルドしたカーネル2.6.32 に差し替えます。
カーネルを替えると、無線LANドライバのモジュールがloadができなくなるので、一緒においてある bcm4329.ko もダウンロードしておきます。

fastbootで起動する。
次のコマンドによりカーネルを入れ替える。
$ sudo ./fastboot-linux flash zimage zImage
$ sudo ./fastboot-linux reboot

zImage はダウンロードしたカーネル。
起動したら無線LANが使えなくなってるのを確認。
adbによりダウンロードしておいたbcm4329.koをぶち込みます。
$ ./adb remount
$ ./adb shell cp /system/lib/modules/bcm4329.ko /system/lib/modules/bcm4329.ko.29
$ ./adb push bcm4329.ko /system/lib/modules/
$ ./adb reboot

2行目はバックアップです。
これで無線LANが使えるようになっているはずです。



どうやらこのカーネルはhimemが有効になっているようで、合計メモリが395MB(395,152kB)になります


個人的にカスタムロムを導入する目的は前述のリストにはなく、アドホックネットワークへの参加が大きいです。
その詳細はまた別のエントリで。

ちなみにこのROMはまだベータなのでxdaのフォーラムは随時追っかけておいた方がよさそうです。