2012年5月25日金曜日

Yahoo のリッチテキストメールと Mms.apk

Yahooメールからのリッチテキストメールも文字化けするとTwitterで報告いただいたので調べました。

とりあえず、試しにiPhone宛に送ってみるとGmailのときと同様にまったく受信できませんでした。(異界送りになる)
これについてはSoftbankに報告したほうがいいかもしれません。
参考までに一般のメールアドレスに送ると、iso-2022-jpのHTMLになってますが、これはあまり参考になりません。(MMSはサーバで変換されるので)

さて、Yahooメールでリッチテキストメールを送ると、SoftbankのMMSサーバはShift_JISのHTMLメールとして端末へ送るようです。
Gmailのときと違い、ちゃんと文字コードが指定されているにもかかわらず、メッセージアプリでは文字化けしてしまいます。

いろいろ調べていると、frameworkのPduPersister(dbにメッセージを保存するクラス)がバグっておりました。
こいつは charsetを全く見ずに、バイトデータをDefault Encoding(UTF-8)のつもりでString化し、dbのTEXTフィールドにつっこんでます。
dbから読み取るときも同様に、UTF-8文字列としてバイトデータ化しています。
これを メッセージアプリは送られてきた元々のcharset情報により、Shift_JISのバイトデータとして複合しようとします。
まぁこんなことしてたら2バイトデータはぶっ壊れて文字化けします。

そんなわけで、手っ取り早く対応するにはShift_JISのHTMLパートをすててalternativeとしてくっついてるUTF-8のテキストパートを使う…
というのでもいいのですが、納得いかないのでAOSPにframeworkを修正するパッチを送りました。

Mms.apkではPersisterに渡る前にUTF-8に変換して、charset情報もUTF-8にしてしまうという手段を取りました。
これならframeworkの修正がなくても対応できます。
そもそも、Shift_JISのSoftbank絵文字はそのままUTF-8に変換できないので特別に変換関数を用意して自前で変換する必要があり、frameworkがなおっても必要なプロセスになります。
ともかく、これでHTML表現を維持しつつ文字化けが解消できました。

ついでに、Sense系ROMで報告いただいてるExceptionをできるかぎり潰したものを作りました。
テスト環境がないので動くかわかりませんが、お試しください。
ABSOLUTELY NO WARRANTY です。

ダウンロード (20100908)

sh-01dのroot取得までの手順

■必要なもの
(1)shdisphook
http://goo.gl/Bs6Iq
(2)breaksuidshdisp
http://goo.gl/r87zt
(3)adb接続環境
(4)ターミナルエミュレータ。
私はandroidマーケットからjackpalのターミナルエミュレータをインストールしています。
 
■概要
system権限取得後、以下のことを行ってください。
主に3段階のことをやります。
(1)shdisphookによるsystem権限の取得、/cache/recoveryのリンク作成
(2)/dev/shdispのパーミッションを666にする
(3)breaksuidshdispによるsuid関数の破壊。
 
■手順
あらかじめ、breaksuidshdispを/data/local/に入れておいてください。
 
adb push breaksuidshdisp /data/local/
adb shell chmod 755 /data/local/breaksuidshdisp
 
ここから、adb shellで実行。shdisphookでsystem権限取得状態に
なってください。
 
$ echo 'chmod 777 /cache' > /data/local/oncmd.sh
$ echo 'chmod 666 /cache/recovery' >> /data/local/oncmd.sh
$ chmod 755 /data/local/oncmd.sh
 
ここで、microSDのマウント解除ダイアログを表示させると
/cacheディレクトリのパーミッションが777になっているはず
 
つづいて
$ rm -r /cache/recovery
$ ln -s /dev/shdisp /cache/recovery
 
ここで、再起動。もう一度shdisphookを実行する。
microSDのマウント解除ダイアログを表示させる
 
すると、/dev/shdispが以下の権限になるはず。
$ adb shell ls -l /dev/shdisp
crw-rw-rw- system   cache    232,   0 1980-01-08 10:07 shdisp
 
ここで、breaksuidshdispを実行
 
$/data/local/breaksuidshdisp
afd0a680 : 90 00 2d e9 d5 70 a0 e3 00 00 00 ef 90 00 bd e8
afd0a690 : 00 00 b0 e1 1e ff 2f 51 ec b2 00 ea 00 f0 20 e3
p2 = AFD50000 - B0010000
event_type = 268435456
p3 = 007E15E0
p4 = 0091D8BC
p3 = AFD0A680
p4 = AFE4695C
afd0a680 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
afd0a690 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
これで、suid関数が破壊されますので、ターミナルエミュレータを起動させると
#が表示されていると思います。

Galaxy NexusでMIUIを使う

・手順1 前準備
Galaxy NexusにMIUIを導入するには、まず、boot loader unlockとかClockwork Mod Recoveryのインストールを行います。

[GNex TOOLKIT V6.0] Drivers, Backup, Unlock, Root, CWM, Flash, Mods + MUCH MORE [GSM]」を使うといいでしょう。
ドライバインストールからboot loader unlock, root取得などが簡単にできます。
(手順の詳細は解説しませんが、機種選択は「Galaxy Nexus GSM」を選ぶこと)

・手順2 MIUIのzip入手
どこのものを持ってきても、結局は日本語のリソースが入っていないので、あまり変わりないとは思いますが、私はMIUI Americaのdownload romから入手しています。
ドコモのGalaxy Nexus SC-04Dは、「Samsung Galaxy Nexus (GSM)」を選びます。

また、MIUI Ameriaトップページのどこかに「Google apps package for MIUI」というものがあるので、それも入手します。

・手順3 MIUI本体のzip適用
ROM managerを起動し、MIUI本体のzipを選択し、書き込みます。

・手順4 Google apps package for MIUIのzip適用
ROM Managerを起動し、Google apps package for MIUIのzipを選択、書き込みます。

・手順5 Bモバイルデータ通信SIMやIIJMIOを使っている場合はこのパッチを適用
ブローヴちゃん:Android + データ専用 SIM での動作修正パッチ
MIUIの場合、「動作モード0」「"緊急通報のみ"は変更しない」で動作します。
また、バッチを起動する前に

1
2
3
> adb shell
# mount -o rw,remount /system
# exit

という感じで/systemボリュームをread-write可能にしておくと、あとで楽です。

・手順6 MoreLocale2をインストール
Google Playストアから、「More Locale2」をインストールして、「日本語」設定にします。
ただし、これで日本語化される範囲は限定的です。
基本的にMIUIの標準インストール関連は英語表記だと思ってください。

・手順7 日本語フォントの追加
標準の日本語フォントが気に入らない人は、ICS用の日本語フォントの組み込み手順にしたがって組み込んでください。

Androidのgps.conf設定

Xperia X10 mini proのカスタムROMで設定されている/system/etc/gps.confは以下の設定値であることが多い。

1
2
3
4
5
6
NTP_SERVER=europe.pool.ntp.org
XTRA_SERVER_1=http://xtra1.gpsonextra.net/xtra.bin
XTRA_SERVER_2=http://xtra2.gpsonextra.net/xtra.bin
XTRA_SERVER_3=http://xtra3.gpsonextra.net/xtra.bin
SUPL_HOST=supl.google.com
SUPL_PORT=7276

実際にどんな値が設定されているのか、他機種を含めて調べてみた。

NTP_SERVERの候補
・asia.pool.ntp.org
・europe.pool.ntp.org
・jp.pool.ntp.org
・north-america.pool.ntp.org
・us.pool.ntp.org
・xtra1.gpsonextra.net

SUPL_HOSTの候補
・dcm-supl.com : 7275 (SPモードonly, mopera U不可)
・supl.google.com : 7276
・supl.sonyericsson.com : 7275
・supl.skyhook.com : 7278
・h-slp.mnc410.mcc310.pub.3gppnetwork.org : 7275

CK2という設定…しかしc2k.pde.comは名前解決不可なの死んでいる?

1
2
C2K_HOST=c2k.pde.com
C2K_PORT=1234

いろいろ調べた結果、うちのXperia X10 mini proでは、gps.confを以下の様な感じに設定した。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
NTP_SERVER=0.jp.pool.ntp.org
NTP_SERVER=1.jp.pool.ntp.org
NTP_SERVER=2.jp.pool.ntp.org
NTP_SERVER=3.jp.pool.ntp.org
XTRA_SERVER_1=http://xtra2.gpsonextra.net/xtra.bin
XTRA_SERVER_2=http://xtra1.gpsonextra.net/xtra.bin
XTRA_SERVER_3=http://xtra3.gpsonextra.net/xtra.bin
# DEBUG LEVELS: 0 - none, 1 - Error, 2 - Warning, 3 - Info
# 4 - Debug, 5 - Verbose
DEBUG_LEVEL =0
# Intermediate position report, 1=enable, 0=disable
INTERMEDIATE_POS=0
# Accuracy threshold for intermediate positions
# less accurate positions are ignored, 0 for passing all positions
ACCURACY_THRES=0
# Report supl ref location as position, 1=enable, 0=disable
REPORT_POSITION_USE_SUPL_REFLOC=1
# Wiper (wifi positioning), 1=enable, 0=disable
ENABLE_WIPER=1
################################
##### AGPS server settings #####
################################
# FOR SUPL SUPPORT, set the following
SUPL_HOST=supl.google.com
SUPL_PORT=7276
SUPL_NO_SECURE_PORT=7276
SUPL_SECURE_PORT=7276
# FOR C2K PDE SUPPORT, set the following
# C2K_HOST=c2k.pde.com or IP
# C2K_PORT=1234
#################################
##### AGPS Carrier settings #####
#################################
CURRENT_CARRIER=common
DEFAULT_AGPS_ENABLE=TRUE
DEFAULT_SSL_ENABLE=FALSE
# TRUE for "User Plane", FALSE for "Control Plane"
DEFAULT_USER_PLANE=TRUE

なお、手に入れたばかりのMUCHTEL A1 Android 2.2のgps.confはこんな感じでした。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
NTP_SERVER=xtra1.gpsonextra.net
XTRA_SERVER_1=http://xtra1.gpsonextra.net/xtra.bin
XTRA_SERVER_2=http://xtra2.gpsonextra.net/xtra.bin
XTRA_SERVER_3=http://xtra3.gpsonextra.net/xtra.bin
# DEBUG LEVELS: 0 - none, 1 - Error, 2 - Warning, 3 - Info
#               4 - Debug, 5 - Verbose
DEBUG_LEVEL = 4
# Intermediate position report, 1=enable, 0=disable
INTERMEDIATE_POS=0
# Accuracy threshold for intermediate positions
# less accurate positions are ignored, 0 for passing all positions
ACCURACY_THRES=500
################################
##### AGPS server settings #####
################################
# FOR SUPL SUPPORT, set the following
# SUPL_HOST=supl.host.com or IP
# SUPL_PORT=1234
# FOR C2K PDE SUPPORT, set the following
# C2K_HOST=c2k.pde.com or IP
# C2K_PORT=1234
################################
# EXTRA SETTINGS
################################
#

ちなみに、この記事、ほんとはメモ書きで、公開する予定はなかったのですが、間違えて公開してしまったので・・・

— 2012/01/04 追記 —
[DEC.05.2011] Instantaneous GPS Fixation v1.2! *FOR ALL ANDROIDS PHONES!*
これで配布しているasia-v1.2.zip内のgps.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
NTP_SERVER=0.asia.pool.ntp.org
NTP_SERVER=1.asia.pool.ntp.org
NTP_SERVER=2.asia.pool.ntp.org
NTP_SERVER=3.asia.pool.ntp.org
NTP_SERVER=ph.pool.ntp.org
NTP_SERVER=my.pool.ntp.org
NTP_SERVER=tr.pool.ntp.org
NTP_SERVER=sg.pool.ntp.org
NTP_SERVER=in.pool.ntp.org
NTP_SERVER=hk.pool.ntp.org
NTP_SERVER=ae.pool.ntp.org
NTP_SERVER=jp.pool.ntp.org
NTP_SERVER=bd.pool.ntp.org
NTP_SERVER=il.pool.ntp.org
NTP_SERVER=kr.pool.ntp.org
NTP_SERVER=th.pool.ntp.org
NTP_SERVER=ir.pool.ntp.org
NTP_SERVER=tw.pool.ntp.org
NTP_SERVER=cn.pool.ntp.org
NTP_SERVER=id.pool.ntp.org
NTP_SERVER=vn.pool.ntp.org
NTP_SERVER=pk.pool.ntp.org
NTP_SERVER=om.pool.ntp.org
NTP_SERVER=uz.pool.ntp.org
NTP_SERVER=lk.pool.ntp.org
NTP_SERVER=kg.pool.ntp.org
NTP_SERVER=kh.pool.ntp.org
NTP_SERVER=qa.pool.ntp.org
XTRA_SERVER_1=http://xtra1.gpsonextra.net/xtra.bin
XTRA_SERVER_2=http://xtra2.gpsonextra.net/xtra.bin
XTRA_SERVER_3=http://xtra3.gpsonextra.net/xtra.bin
INTERMEDIATE_POS=1
C2K_HOST=c2k.pde.com
C2K_PORT=1234
SUPL_HOST=FQDN
SUPL_HOST=supl.google.com
SUPL_PORT=7276
SUPL_SECURE_PORT=7275
SUPL_NO_SECURE_PORT=3425
SUPL_TLS_HOST=FQDN
SUPL_TLS_CERT=/etc/SuplRootCert
ACCURACY_THRES=5000
CURRENT_CARRIER=common
DEFAULT_USER_PLANE=TRUE
REPORT_POSITION_USE_SUPL_REFLOC=1