第35回長岡IT開発者勉強会参加してきました。自分の発表について、「詳細はWebで」なんて書いておきながら、なにも準備していなかったので、このエントリをもって発表にかえさせていだきます。
電子書籍が流行ってて、高解像度重視タブレットが注目されるのもわかりますが、僕は「いや違うんだ」と伝えておきたいです。高解像度でiPadやKindle FireなんかがいいのはPDFや自炊スキャンしたマンガみたいな固定レイアウトの話であって、それは確かに高精細大画面が望ましい領域なんですが、リフロー形式のテキスト系の書籍の場合はでっかい画面はそんなに必要なくて、むしろ軽いことが嬉しかったりするんですよ!電子書籍=固定レイアウトではないので、iPad MiniやKindle端末みたいな軽い端末にもいいところはあると思うので、小さい端末も見捨てないで!それを発表で伝えるのを忘れたのでここに書いておく。
さて、私の発表ですが、要約すると、古くなったKindleをJailbreakして自作Kindletを動かして時計として使おうという話です。まだ未完成なので今後完成度を上げて公開していきたいです。あ、ここで私が使っているのはKindle4(non touch)という世代でして、今売ってるKindle paperwhiteではないです。ご了承ください。
手順としては、Jailbreakして、ssh接続して、開発キット用jarファイルを取り出してから、開発、署名後、keystoreとともに配備するという手順です。
KindletはjavaプログラムでAppletライクなコードで簡単につくれますが、Kindleで動かすためにはjarファイルに署名が必要です。署名はするためのkeystoreを自分で用意してKindle内に配備されているkeystoreを自分のものと置き換えてしまうというハックが行われています。
Jailbreak後のKindleで動かすアプリが色んな所で公開されているわけですが、それを自分のKindleに入れるには自分のKeystore用に署名しなければならないわけです。それって面倒なんで「みんなでこのkeytstore使おうぜ!署名するときは、このdntest、ditest、dktestってkeyで署名しよう。パスはこれな」という形で共用keystoreが知れ渡っています。このkeystoreを使うことで署名済みのKindletをすぐに端末に入れることができます。
keyまで公開されたkeystoreをダウンロードして使うなんて一般的には危険な発想なのですが、まあKindle自体が大したことができる端末ではないのでリスクと引き換えに利便性を求めたというのはアリかなと思います。ただこういった手法は一般的には危ないことだと知っておかないといけないです。
Jailbreak
こちらに書いてある方法でできます。これでSSHでアクセスできるようになります。
SSH
これもこちらを参考にしました。
SSHで接続できるのですが、普通にネットワーク経由でアクセスするわけでなくて、USB接続してそれをUSBネットワークとインターフェースで接続します。wifi経由でつなげるわけではないです。passwordは私のはmarioではなくて、シリアル番号から算出されるパスワードの方でした。
sshでアクセスできればkindle内部を色々いじれるのですが、usbネットワークでつないでいるときと、実際に起動するときはブートするときのパーティションが違うようです。最初それをしらなくて「あるべきところにあるはずのファイルがない」と苦戦しました。
# mount /dev/mmcblk0p1 /mnt/base-mmc
こんな感じでマウントして、その配下からファイルを見つけないとダメでした。
開発用jarファイル取得
こちらを参考にしました。
kindletを開発するためにKindlet用のライブラリが必要にあります。Kindle端末から取得します。さきほど書いたようにマウントしてその配下から取得する必要がありました。先ほどのように /mnt/base-mmc にマウントした場合は、
/mnt/base-mmc/opt/amazon/ebook/lib/Kindle-1.3.jar
になります。
開発
これでKindletを開発できます。Javadocはこちらです。
こちらが参考になりました。
プログラム的には、そんなにとりわけて書くことがないのですが、ハマった点として一定間隔でKLabel上の時刻表示を書き換えていたのですが、書き換わらなくて苦戦しました。
コンポーネントを使っていても描画タイミングは自分で制御しなければならないようです。Swingの感覚としてはコンポーネントに変更を加えれば、コンポーネント側が適切なタイミングで適切な範囲で再描画すると思ってたのですが、自分でrepaintを行って再描画しないとダメでした。
UIスレッド外から更新していることになってるのかも。。Kindletで提供しているTimerを使っていれば大丈夫と思ったのですが、SwingWorkerとかinvokeLaterみたいなのも見当たらないで、変更後に自分でrepaintしています。。
署名
自前でkeystoreを用意して、kindleに入れてもいいのですが、他の野良Kindletも入れたいとなると、先程も書いたように共有Keystoreが楽です。
こちらから、developer.keystore.2012-11-06.zipを取得します。
マウント後のKindleの例として以下の場所のdeveloper.keystoreを(バックアップして)置き換えます。
/mnt/base-mmc/var/local/java/keystore/
で、このkeystoreにあるdktest,ditest,dntestで署名します。パスワードはpasswordです。仕様なんですがdk, di, dnで始まる3つの署名が必要らしいです。
jarsigner -keystore developer.keystore -storepass password Test.jar dktest
jarsigner -keystore developer.keystore -storepass password Test.jar ditest
jarsigner -keystore developer.keystore -storepass password Test.jar dntest
配備
jarファイルに署名したら、拡張子をazw2に変更して、kindleをUSBストレージ接続後のdocumentsフォルダに配置すればOKです。文書と同じようにアプリが並びます。
まだアプリとしてはラベルを更新するだけの寂しい時計なので、もうすこしかっこ良くしたり、天気を取得したりできるようにしたら公開しようかと思います。
それでは快適なKindletライフを!