連載
» 2012年09月18日 10時00分 UPDATE

実践しながら学ぶ Android USBガジェットの仕組み(7):Androidアプリケーションフレームワーク層を改造しよう! (1/2)

引き続き、起動不能になったPCを救出する「PCRescuroid」の開発を進める。今回は、CDイメージをマウントすべく、アプリケーションフレームワーク層の修正ポイントを詳しく見ていく。

[中垣内勇祐、村上雅彦、森崇、中谷洋一(永和システムマネジメント),@IT MONOist]

はじめに

 前回「緊急事態発生!? 起動不能になったPCをAndroidで救出せよ!」では、壊れたPCを救出すべく、私たちは「PCRescuroid(ピーシーレスキュロイド)」というAndroidアプリを考案し、Android端末上でCDイメージ(Linux)のマウント設定を行うためのユーザーインタフェースまで開発しました(図1)。

 で、その先の動作はというと……。現時点では、アプリケーションから下の層にCDイメージをマウントできるようなAPIセットがないため、図2のようにマウントに失敗してしまいます……。うーん。


CDイメージをマウントするUICDイメージをマウントした結果 (左)図1 CDイメージをマウントするUI/(右)図2 CDイメージをマウントした結果

 この問題を解決するためには、Androidの「アプリケーションフレームワーク層」と「Linuxカーネル層」を修正する必要があります。

 当初、私たちはPCRescuroidをきちんと完成させ、Google Play(旧Android Market)を通じて世界に配信するという野望を抱いていました。しかし、Android端末をCD-ROMドライブとして認識させるためには、USBドライバ層にSCSIコマンドなどを追加する必要があり、

Androidプラットフォームの改造は避けて通ることができない!


という結論に至りました……。

 Androidプラットフォームを改造するということは、Google Play上で配信されているアプリケーションのように、“それ単体”では機能を実現できません。つまり、私たちが今回考案したPCRescuroidは、どちらかというと、Android端末に始めから搭載されている(組み込まれている)ベース機能という位置付けになります。残念ながら、PCRescuroidを世界に配信するという夢は諦めざるを得ませんが、今後、どこかのスマートフォン開発メーカーがベース機能として採用してくれるかも……という大きな夢を思い描きつつ、PCRescuroidを完成させたいと思います。

おさらい

 PCRescuroidは、以下の4つのユースケースからなります。その中で、特に実現方法の検討が必要な“重要ユースケース”は、「3.CDイメージをマウントする」です。

ユースケース

要求3.Android端末上でブート対象CDイメージを選択し、PCをUSB接続してブートする

ユースケース名 CDイメージをマウントする
目的 壊れたPCを復旧するため、PCブート可能なCDイメージを選択することで、PCブートできるようにする
事前条件 ブート可能なCDイメージが管理対象となっている
正常終了条件 PCとUSB接続すると、CD-ROMドライブとして認識され、CDイメージ内のOSでブートできるようになる

Android USBマスストレージクラスのアーキテクチャ

 改造に着手する前に、AndroidのUSBマスストレージクラスのアーキテクチャ(ソフトウェアの構成要素とその役割および関連)を把握し、改造すべきポイントの大枠を押さえておきましょう。

 Androidの階層アーキテクチャ上で、関連する論理的なクラス構成を図3に示します。なぜ、論理クラスで説明する必要があるのかというと、Androidのバージョンによって実装上のクラス名が変わってしまうことがあるためです。実装に依存しない機能的な役割という視点から、“論理クラス名”をきちんと定義することで、仕様変更やバグ修正などの影響を受けにくい設計を実現できます(注1)。

Android USBマスストレージの論理クラス構造 図3 Android USBマスストレージの論理クラス構造
※注1:筆者は以前、Android 2.1(Eclair)をターゲットとしたプロジェクトで、vold(C言語)の改修をしていました。ある日、プロジェクトの方針が変わり、Android 2.2(Froyo)へと切り替えることになったのですが、目が点になりました。voldのソースコードを見てみると……。何と、実装がC++言語に変わっていたのです。


 関連するのは、「アプリケーション層」「アプリケーションフレームワーク層」「Linuxカーネル層」の3つです。それでは、各層に属する3つのクラス(UsbMassStorageNotification、UsbMassStorageService、UsbMassStorageClassDriver)がどのように関係しているのかを、代表的な処理シーケンスを眺めながら理解していきましょう。

 図4に示すシーケンスでは、最初に環境設定として、Android上のSDカードを自動でマウントできるように設定しておきます。そして、PCとUSB接続することで、Android端末をUSBメモリとして認識させて利用します。

SDカードをマウントするシーケンス 図4 SDカードをマウントするシーケンス 【画像クリックで拡大表示】

アプリケーション層(UsbMassStorageNotification)

 アプリケーション層では、USB接続時の設定を行います。ただし、この設定情報はAndroid端末ベンダーごとに独自定義する場合が多く、設定内容は異なります。ここでは、説明を単純化するために、“SDカードの自動マウントの有無”を設定します。自動マウントありの場合は、USB接続するとSDカードが自動的にマウントされ、PC上からSDカードへアクセスできるようになります。自動マウントなしの場合は、USB接続時にポップアップ通知し、マウントの有無をユーザーに選択させます。このシーケンスでは、“自動マウントあり”の設定を行っています。

アプリケーションフレームワーク層(UsbMassStorageService)

 アプリケーションフレームワーク層では、USB接続する際、環境設定情報を基にマウント処理を行います。ここでの「マウント」とは、“Android端末内のSDカードをあたかもUSBメモリのようにPC側からアクセス可能にする”ことです。マウント処理における、アプリケーションフレームワーク層でのタスクは大きく以下の2つがあります。

  1. SDカードのデバイスパスをドライバに通知すること
  2. SDカードをアンマウントすること

 PC側からSDカードへアクセスするための仕組みは、Linuxカーネル層のドライバ側が提供します。そのため、アプリケーションフレームワーク層では、PCとのデータのやりとりは不要となり、1.を実施するだけで済みます。

 ただし、1.を実施する前にやっておかなければならない重要なタスクがあります。それが2.のアンマウントです。この時点では、Android端末からSDカードへアクセスできている状態ですから、これを解除(アンマウント)する必要があります。もし、そのままにしておくと、AndroidとPCから同時にアクセスを許可することになり、最悪、データ破壊が発生してしまいます。

Linuxカーネル層(UsbMassStorageClassDriver)

 Linuxカーネル層では、USB接続時にコンフィギュレーションを行った後、USBマスストレージクラスのドライバがPC側とSCSIコマンドでのやりとりを行い、SDカードへアクセスできるようにします。このあたりの内容は非常に奥が深いので、別の機会にじっくりと解説したいと思います。

 以上が、通常のAndroid端末のUSB接続時の処理シーケンスになります。これを踏まえた上で、CDイメージをマウントする術(すべ)を検討していきます。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.