18 March 2015

IdeaPad A1をAndroid 4.0.4 (ICS)にアップデートした使い心地

Lenovo製IdeaPad A1(欧米ではIdeaTab A1107)がエラーを頻発するようになったため、ファームウエアを書き戻して初期化するついでに、最新のAndroid 4.0.4 (ICE = Ice Cram Sandwich)を入れて、遅いと酷評されている使い心地を試してみることにした

検証環境

  • 機種 : Lenovo製 IdePad A1 , 16GBytes版 2228-3DJ
  • 購入価格 : 16,907円 (2012年9月 Amazon.co.jp)
  • CPU : OMAP 3622, シングルコア 1GHz
  • メモリー : 512 MB RAM, 内蔵SDカード 16GB, microSDスロット×1
  • 画面 : 1024 x 600 pixels, 7 inch
  • 質量 : 400g

OSのアップデート

OSの書き換えは2種類の方法があり、(1)OSイメージを含んだブート可能なmicroSDカードを用いる場合、(2)IdeaPad本体のアップデート機構を利用して、microSDカードのOSイメージを読み込ませる場合、という2種類。

(1)の方法については、Lenovo公式サイトに記載されている方法『How to Unbrick fix/full factory restore - IdeaTab A1 and A1107』で、同サイトからブート可能なmicroSDイメージも入手できる。

もうひとつは、Lenovo公式サイトの「OSイメージ配布場所」よりOSイメージのzipファイルを入手して、それをmicroSDカードに単純にファイルコピーして使う。

今回は、(2)の方法を試してみることとする。

OSイメージのダウンロードと、パッチ適用

Lenovo公式サイトの「OSイメージ配布場所」より次のファームウエアをダウンロードする。なお、配布されているのはUS版1個だけなので、中華フォントは後ほどルート権限を奪取して日本語フォントに入れ替える必要がある。

A107I0_A404_001_013_0116_US.zip 25-Jul-2012 06:38 261M

公式サイトでは、これをmicroSDカードにupdate.zipと改名して書き込んで、OTAでアップデートできるとされているが、起動時に固まってしまうため、次のサイトに示されているようにパッチを当てる必要がある。

Update – Lenovo(R) IdeaPad A1-07 (16GB) + Android(TM) 4.0.4 (Ice Cream Sandwich)
Lenovo(R) IdeaPad A1-07 (16GB) + Android(TM) 4.0.4 (Ice Cream Sandwich AKA ICS)

具体的には、上記のサイトよりダウンロードしたパッチ・ファイル updater-script.a404.patch を、OSイメージzipの中のMETA-INF/com/google/android/updater-scriptに適用して書き戻してやれば良い。コマンドラインでは次のようになり、

$ wget http://download.lenovo.com/slates/a1/ICS_OTA/A107I0_A404_001_013_0116_US.zip
$ unzip A107I0_A404_001_013_0116_US.zip
$ patch META-INF/com/google/android/updater-script updater-script.a404.patch
$ zip -r update * -x updater-script.a404.patch update.zip

実際にパッチを当てたupdater-scriptは次のようになっている。元のファイルは2GB, 16GB版それぞれの処理が全てコメントアウトされているので、該当機種のものを生かしてやるという処理のようだ

念の為、それぞれのファイルをここに置いておく : updater-script.a404.patchをダウンロードする書き換え後 updater-scriptをダウンロードする元のupdater-scriptをダウンロードする

META-INF/com/google/android/updater-script
#updater-script needed to upgrade Lenovo(R) IdeaPad A1-07 (16GB) to Android(TM) 4.0.4 (firmware A107I0_A404_001_013_0116_US.zip).
 
ui_print("");
ui_print("1. extract fuse");
assert(show_progress(0.010000, 1));
assert(package_extract_file("fuse", "/tmp/fuse"));
assert(set_perm(0, 0, 0755, "/tmp/fuse"));
assert(package_extract_file("mg_up", "/tmp/mg_up"));
assert(set_perm(0, 0, 0755, "/tmp/mg_up"));
assert(set_progress(0.010000));
 
# This choose which mbr to use
ui_print("2. fuse mbr.img");
assert(show_progress(0.010000, 1));
#ui_print("#. choose mbr.");
#assert(package_extract_file("mbr2GB.img", "/tmp/mbr2GB.img"));
assert(package_extract_file("mbr16GB.img", "/tmp/mbr16GB.img"));
#ifelse(is_16Ginand("/dev/block/mmcblk0"),assert(run_program("/tmp/fuse", "mbr", "/tmp/mbr16GB.img")),assert(run_program("/tmp/fuse", "mbr", "/tmp/mbr2GB.img")));
assert(run_program("/tmp/fuse", "mbr", "/tmp/mbr16GB.img"));
#ifelse(is_16Ginand("/dev/block/mmcblk0"),ui_print("fuse mbr 16GB"),ui_print("fuse mbr 2GB"));
ui_print("fuse mbr 16GB");
#delete("/tmp/mbr2GB.img");
delete("/tmp/mbr16GB.img");
#ui_print("#. out off choose mbr.");
assert(set_progress(0.020000));
 
ui_print("3. format partitions");
assert(show_progress(0.450000, 60));
assert(run_program("/tmp/fuse", "system", "format"));
assert(run_program("/tmp/fuse", "cache", "format"));
assert(run_program("/tmp/fuse", "userdata", "format"));
assert(run_program("/tmp/fuse", "inand-secure", "format"));
assert(run_program("/tmp/fuse", "inand-storage", "format"));
 
 
# This segment is masked when inand is invalid
ui_print("4 fuse mbr_boot");
assert(show_progress(0.010000, 1));
assert(package_extract_file("mbr_boot", "/tmp/mbr_boot"));
assert(run_program("/tmp/fuse", "mbr_boot", "/tmp/mbr_boot"));
delete("/tmp/mbr_boot");
assert(set_progress(0.030000));
 
ui_print("5. fuse xloader");
assert(show_progress(0.020000, 3));
assert(package_extract_file("MLO", "/tmp/MLO"));
assert(run_program("/tmp/fuse", "xloader", "/tmp/MLO"));
delete("/tmp/MLO");
assert(set_progress(0.590000));
 
ui_print("6. fuse u-boot.bin");
assert(show_progress(0.020000, 3));
assert(package_extract_file("u-boot.bin", "/tmp/u-boot.bin"));
assert(run_program("/tmp/fuse", "uboot", "/tmp/u-boot.bin"));
delete("/tmp/u-boot.bin");
assert(set_progress(0.590000));
 
ui_print("7. fuse uImage.img");
assert(show_progress(0.030000, 5));
assert(package_extract_file("uImage", "/tmp/uImage"));
assert(run_program("/tmp/fuse", "kernel", "/tmp/uImage"));
delete("/tmp/uImage");
assert(set_progress(0.620000));
 
ui_print("8. fuse ramdisk_mmc.img");
assert(show_progress(0.030000, 5));
assert(package_extract_file("ramdisk-uboot.img", "/tmp/ramdisk_mmc.img"));
assert(run_program("/tmp/fuse", "ramdisk", "/tmp/ramdisk_mmc.img"));
delete("/tmp/ramdisk_mmc.img");
assert(set_progress(0.650000));
 
ui_print("9. fuse recovery_mmc.img");
assert(show_progress(0.030000, 5));
assert(package_extract_file("recovery_mmc.img", "/tmp/recovery_mmc.img"));
assert(run_program("/tmp/fuse", "recovery", "/tmp/recovery_mmc.img"));
delete("/tmp/recovery_mmc.img");
assert(set_progress(0.680000));
 
ui_print("10. fuse logo.img");
assert(show_progress(0.030000, 5));
assert(package_extract_file("logo.img", "/tmp/logo.img"));
assert(run_program("/tmp/fuse", "logo", "/tmp/logo.img"));
delete("/tmp/logo.img");
assert(set_progress(0.680000));
 
ui_print("11. fuse system.img");
assert(show_progress(0.300000, 50));
assert(package_extract_file("system.zip", "/tmp/system.zip"));
assert(run_program("/tmp/fuse", "system", "/tmp/system.zip"));
delete("/tmp/system.zip");
assert(set_progress(0.700000));
 
ui_print("12. fuse data.img");
assert(show_progress(0.020000, 50));
assert(package_extract_file("data.zip", "/tmp/data.zip"));
assert(run_program("/tmp/fuse", "userdata", "/tmp/data.zip"));
delete("/tmp/data.zip");
assert(set_progress(0.800000));
 
assert(show_progress(0.37000, 50));
ui_print("13. backup data.img");
assert(mount("ext3","/dev/block/mmcblk0p1","/tmp/system"));
assert(package_extract_file("data.zip", "/tmp/system/data.zip"));
assert(unmount("/tmp/system"));
assert(set_progress(0.850000));
#assert(run_program("/tmp/fuse", "inand-storage", "format"));
#ui_print(".Copy music...");
#assert(package_extract_file("storage.zip", "/tmp/storage.zip"));
#assert(run_program("/tmp/fuse", "inand-storage", "/tmp/storage.zip"));
#delete("/tmp/storage.zip");
assert(set_progress(0.900000));
delete("/tmp/fuse");
assert(set_progress(1.000000));
 
ui_print("14. Upgrade finish...");

このようにして出来たOSイメージファイル(update.zip)を、FAT32で普通にフォーマットしたmicroSDカードに書き込む。(dd コマンドでイメージ書込するのではなく、cp コマンドでファイルコピーする)

IdeaPad A1の電源を切り、「ボリューム・ダウン・ボタン」と「電源ボタン」を同時に押したままにして電源を入れ、“Lenovo”ロゴが出たら「電源ボタン」のみ手を離し、「ボリューム・ダウン・ボタン」はOSイメージzipが読み込まれる画面になるまで押したままにする。

Android 4.0.4インストール後の画面

タッチ操作に対するレスポンスがやたら悪い。 タップしてから、一呼吸おいて認識されるというのが通例で、中には処理中のまま数秒間フリーズ状態になることもしばしば。 これは使い物にならん…

20150318-a1107-ics-lockscr.jpg
ロック画面

20150318-a1107-ics-homescr.jpg
ホーム画面

20150318-a1107-ics-apps1page.jpg
アプリケーション画面1ページ目

20150318-a1107-ics-apps2page.jpg
アプリケーション画面2ページ目

20150318-a1107-ics-widget1page.jpg
ウィジェット画面1ページ目

20150318-a1107-ics-widget2page.jpg
ウィジェット画面2ページ目

20150318-a1107-ics-widget3page.jpg
ウィジェット画面3ページ目

20150318-a1107-ics-widget4page.jpg
ウィジェット画面4ページ目

20150318-a1107-ics-statusbar_expand.jpg
ステータスバーを開いた画面

なぜか、ステータスバーが下にある。違和感を感じる…

20150318-a1107-ics-systeminfo.jpg
設定画面のシステム情報表示

20150318-a1107-ics-storage.jpg
設定画面のストレージ情報

20150318-a1107-ics-apps-installed.jpg
設定画面のダウンロード済みアプリ一覧

メーカーがインストールした「余計なアプリ」は、おそらくこの程度。ルート権限が無いと消せないアプリが数個あるが、それでもアプリてんこ盛り状態の日本メーカー製タブに比べれば優秀だ。

20150318-a1107-ics-apps-exec.jpg
設定画面の実行中アプリ一覧

LenovoAppShopというのが真っ先に削除対象だが、ルート権限が必要。

ルート権限の奪取

先人の知恵がかかれたページ 『IdeaPad Tablet A1をAndoroid 4.0.4(ICS)へ&root化のやり方』、『Idea Pad A1にICSいれる

などではA1_rooter.zipというツールを使うことでルート権限が奪取できるとされているが、これらの記事が書かれてから期間が経っており、OS側でどうも対策が施されてしまったようだ。この方法では奪取不可能。

で、どの機種にも適用可能な一般ツール Framaroot を使う

20150318-a1107-ics-framaroot1.jpg

Framarootを起動すると、オススメのRoot権限奪取のためのExploit名が表示された。Exploit名Gimliをクリックすると、root権限の奪取が完了。

20150318-a1107-ics-framaroot2.jpg
root権限奪取完了表示

microSDカード認識エラーの修正

2GBytes版のIdeaPadではmicroSDカードの認識に問題があるらしい。root権限奪取の情報が書かれたページには、SDカード問題の修正パッチA1_ICS_SD-Card.zipも登録されているので、ついでにそれも適用した。

不要アプリの無効化

パッケージ名アプリ名
com.amazon.kindleAmazon Kindle
com.android.LeLohasLenovo UI intro
com.android.emailAndroid標準メールアプリ
com.android.exchangeExchangeサービス
com.android.smspushSMS
com.google.android.apps.booksPlayブックス
com.google.android.apps.plusGoogle+
com.google.android.googlequicksearchboxGoogle検索ウィジェット
com.google.android.musicPlayミュージック
com.google.android.talkGoogleトーク(ハングアウト)
com.lenovo.leos.userhelpLenovo User Guide
com.mobihand.skylightLenovo App Shop
lenovo.jb.gokeyboardGo Keyboard

中国語フォントを日本語フォントに入れ替え

20150318-a1107-ics-font-china.jpg
中国語フォントでの表示

たとえば1行目の「急転直下」の『直』に注目

20150318-a1107-ics-font-japan.jpg
日本語フォントでの表示

Unicodeで無理やり両国のフォントを統合するから、このような悲劇が起こる。

Lenovo公式サイトの「OSイメージ配布場所」より、Android 2.3.4の日本語対応化したイメージをダウンロードし、その中から日本語フォントを抽出する。

A107W0_A234_001_015_2643_ROW.zip 27-Feb-2012 05:27 160M

このイメージの中の/system.zipを解凍し、その中の/fonts/MTLmr3m.ttfを取り出す。このファイルを、IdeaPadの/system/fontsにコピーすると共に、フォント設定ファイルに次のような記述を追加する

/system/etc/fallback_fonts.xml
<?xml version="1.0" encoding="utf-8"?>
<familyset>
    <family>
        <fileset>
            <file>DroidNaskh-Regular.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>DroidSansEthiopic-Regular.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>DroidSansHebrew-Regular.ttf</file>
            <file>DroidSansHebrew-Bold.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>DroidSansThai.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>DroidSansArmenian.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>DroidSansGeorgian.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>Lohit-Devanagari.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>Lohit-Bengali.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>Lohit-Tamil.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>MTLmr3m.ttf</file>
        </fileset>
    </family>
    <family>
        <fileset>
            <file>DroidSansFallback.ttf</file>
        </fileset>
    </family>
</familyset>

先人の知恵では MTLmr3m.ttf は DroidSansJapanese.ttf に改名すべしとなっているので、そのようにしても良いかもしれない。

既存フォントの日本語対応状況

truetypeフォントの属性を抜き出してみると、

$ fc-scan DroidSansFallback.ttf
Pattern has 22 elts (size 32)
        family: "Droid Sans Fallback"(s)
        familylang: "en"(s)
        style: "Regular"(s)
        stylelang: "en"(s)
        fullname: "Droid Sans Fallback"(s)
        fullnamelang: "en"(s)
        slant: 0(i)(s)
        weight: 80(i)(s)
        width: 100(i)(s)
        foundry: "unknown"(s)
        file: "DroidSansFallback.ttf"(s)
        index: 0(i)(s)
        outline: True(s)
        scalable: True(s)
        charset: 
        0000: 00000001 ffffffff ffffffff 7fffffff 00000000 f7dfe593 c1810040 578d3743
 〜略〜
	01d3: 00001000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
(s)
	lang: bg|fj|ho|ia|ie|io|ja|ko|kum|nr|om|os|ru|sel|sm|so|ss|st|sw|to|ts|uz|xh|zh-cn|zh-sg|zh-tw|zu|kj|kwm|lg|ms|ng|rn|rw|sn|za(s)
	fontversion: 165806(i)(s)
	capability: "otlayout:cyrl otlayout:grek otlayout:latn"(s)
	fontformat: "TrueType"(s)
	decorative: False(s)
	hash: "sha256:ef275eb8cb6380dbf8c7a897a780d4132623519be4ee17340fecd77f2a2c697a"(s)
	postscriptname: "DroidSansFallback"(s)

DroidSansFallback.ttf は一応「日本語も対応」の属性があるのだが、中国語優先なのかねぇ…

使い心地は

画面をタップした時のレスポンスが、ワンテンポどころか、1秒位遅れたり、プチフリーズを繰り返したり…。 そもそも、タブレットを起動してホーム画面が表示されてからアプリを使えるようになるまで、30秒以上待たされるなど、レスポンスの遅さは群を抜いている。

やはり、シングルコアCPUではAndroid 4は無理なのだろう。 やはり、Android 2.3.4に戻すことにする。