Palm Programmer's Laboratory

トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

Palm OS Programmer's Companion Volume I/7-5

← 4 節に戻る ↑7 章トップへ 6 節に進む →


7-5 カードの挿入と取出し

 拡張マネージャは任意のタイミングでの拡張メディアの挿入や取出しをサポートしています。カードの挿入によってアプリケーションの切換えが発生しても、ハンドヘルドは動作を続けます。ハンドヘルドをリセットしたり、カードの挿入や取出しをその他の明確な方法でハンドヘルドに知らせる必要はありません。

WARNING!
拡張カードの作りによっては、書込み中に拡張カードを抜き取ると、稀にカードが使用不能になるか再フォーマットが必要なほどのダメージを与えてしまう場合があります。そのような可能性をできる限りなくすため、アプリケーションはカードへの書込みポイントを明確にし、さらにユーザーに対して警告 ─― “お待ち下さい”やプログレスダイアログ ―― を表示してカードを抜かないように通知すべきです。アプリケーションによるデータの読み込み中は、ダメージの心配なしにカードを抜き取ることができます。

Palm OS は、カードの着脱やボリュームのマウント、アンマウントを通知するための一連のノティフィケーションを使用します。以下の表に、これらのノティフィケーションと、それらが拡張マネージャやVFSマネージャによって登録される優先順位を示します。この優先順位は将来変更される可能性があるため、アプリケーション側でこれらの厳密な順序に依存しないようにして下さい。これらのノティフィケーションを通常のプライオリティで登録するアプリケーションは妥当な動作をすることができます。

表 7.1 拡張カードのノティフィケーション

ノティフィケーション 登録元 プライオリティ
sysNotifyCardInsertedEvent 拡張マネージャ 20
sysNotifyCardRemovedEvent 拡張マネージャ -20
sysNotifyVolumeMountedEvent 拡張マネージャ -20
sysNotifyVolumeMountedEvent VFS マネージャ 10
sysNotifyVolumeUnmountedEvent 拡張マネージャ -20

以下の図は、Palm ハンドヘルドの拡張スロットにカードを挿入した時に発生するイベントシーケンスを示しています。わかり易さのため、エラーは発生しないものと仮定しています。カードにマウント可能なボリュームがなく、かつフォーマットしてマウントすることもできなければ、このシーケンスは中断してカードはマウントされないままになります。しかしカード挿入を通知するノティフィケーションはブロードキャストされます。

図 7.2 カード挿入時のイベントシーケンス

拡張マネージャは sysNotifyCardInsertedEvent をプライオリティ値 20 で登録します。これは、通常のプライオリティで登録された他のハンドラよりも後に呼ばれるようにするためです。拡張マネージャのデフォルトハンドラを置き換えるには、sysNotifyCardInsertedEvent を受信するハンドラを通常のプライオリティで登録し、 SysNotifyParamType 構造体の handled メンバに適切なビットをセットします。

  • expHandledVolume はカードに関連するボリュームが全て処理されたことを示しており、拡張マネージャがカードをマウントあるいはアンマウントするのを抑止します。
  • expHandledSound はアプリケーションが適切なサウンドの再生を行なったことを示しており、拡張マネージャがカードの着脱に際してサウンドを鳴らすのを抑止します。

カードが挿入されたスロットの番号は、SysNotifyParamType 構造体の notifyDetailsP メンバ ―― ここでは UInt16 値を void* にキャストしたもの ―― を使用してハンドラに渡されます。

多くのアプリケーションはボリュームのマウントとアンマウントのノティフィケーションを登録するだけですが、拡張マネージャが管理するスロットからユーザーがカードを取出した際にノティフィケーションを受信する必要がある場合、sysNotifyCardRemovedEvent の受信を登録します。sysNotifyCardInsertedEvent とは違い、拡張マネージャは sysNotifyCardRemovedEvent をプライオリティ値 -20 で登録します。これは、通常のプライオリティ登録している他のハンドラよりも先にノティフィケーションを受信するためです。このノティフィケーションも、カードが取り出されたスロットの番号を SysNotifyParamType 構造体の notifyDetailsP メンバ ―― UInt16 値を void* にキャストしたもの ―― を使用してハンドラに渡します。

VFSマネージャは sysNotifyVolumeMountedEvent をプライオリティ値 10 で登録します。VFSマネージャのデフォルトハンドラを置き換えるには、sysNotifyVolumeMountedEvent を受信するハンドラを通常のプライオリティで登録し、 SysNotifyParamType 構造体の handled メンバに適切なビットをセットします。

  • vfsHandledUIAppSwitch は、アプリケーションが start.prc に対する SysUIAppSwitch 呼び出しを行なったことを示しています。このビットは VFS マネージャが SysUIAppSwitch を呼び出して start.prc を起動することを抑止し(ただし start.prc はロードされて SysAppLaunch は実行されます )、ランチャが自分自身に切り替えることも抑止します。
  • vfsHandledStartPrc は、アプリケーションが start.prc の自動実行を処理したことを示します。VFS マネージャは start.prc のロードも、SysAppLaunch や SysUIAppSwitch の呼び出しも行ないません。

アプリケーションで start.prc の実行を処理する場合、セキュリティに注意する必要があります。拡張カードが挿入された時点でハンドヘルドがロックされている場合、VFSマネージャによるハンドラではユーザーがハンドヘルドをアンロックするまで start.prc の実行を延期します。

カードの取出しも同じシーケンスになります。ただし、自動的に実行される start.prc に該当するものはありません。このシーケンスは以下のように図示されます。

図 7.3 カード取出し時のイベントシーケンス

カードの取出しでは、拡張マネージャはカードの取出しを通知するノティフィケーションの受信を登録している全てのアプリケーションにノティフィケーションをブロードキャストし、そのカードのマウントされているボリュームを全てアンマウントします。これにより、VFS マネージャはボリュームのアンマウントを通知するノティフィケーションを発行します。カードの取出しによってエラーが発生する可能性のあるアプリケーションは、ボリュームのアンマウントに関するノティフィケーションの受信を登録し、適切なエラー処理を実装すべきです。

カードの着脱に関するノティフィケーションは本来システムによる使用を意図したものであり、必要に応じてアプリケーションでも登録できるようになっているということに注意して下さい。ファイルシステムや VFS マネージャだけを扱うアプリケーションはボリュームのマウントやアンマウントのノティフィケーションを受信するべきではありません。

 

Start.prc

まだ処理されていない(かどうかは前のセクションで説明した vfsHandledStartPrc ビットの状態が示しています)sysNotifyVolumeMountedEvent を受信すると、VFSマネージャは /Palm/start.prc と(もしあれば)そのオーバレイをストレージヒープにコピーして実行します。これにより、“アプリケーションカード”―― カードの挿入によって自動実行される単機能のカード ―― が実現できます。また、コンボカードにおいてカード I/O をサポートするためのドライバーとアプリケーションを自動的にロードすることも可能になります。

start.prc を起動するために、VFSマネージャはまず特殊な起動コードである sysAppLaunchCmdCardLaunch を発行します。もしアプリケーションでするべきことがほとんどなく、すぐに復帰できるのであれば、それを済ませてから sysAppLaunchStartFlagNoUISwitch ビットを start フラグにセットします。これは sysAppLaunchCmdCardLaunch のパラメータブロックの一部です。この時点ではグローバル領域にアクセスできず、ユーザーとやりとりすべきでもないことに注意して下さい。sysAppLaunchStartFlagNoUISwitch がセットされていない場合、あるいはアプリケーションが sysAppLaunchCmdCardLaunch 起動コードを無視した場合、VFSマネージャはアプリケーションの通常起動のために sysAppLaunchCmdNormalLaunch を発行します。これにより、sysAppLaunchCmdCardLaunch 起動コードを知らないアプリケーションとの後方互換性も確保されます。アプリケーションがユーザーとやりとりすることができるのはこのタイミングで、アプリケーションによっては sysAppLaunchCmdCardLaunch を受信した際になんらかの情報を保存しておき、sysAppLaunchCmdNormalLaunch を受信した時点でその情報を利用するといった要望もあるかもしれません。

スタック領域を使いきってしまうのを防ぐため、VFSマネージャは start.prc を起動する際に“new stack”ビットをセットします。start.prc アプリケーションは、それがコピーされたボリュームが取り外されるまでシステムメモリに留まります。start.prc が削除されるのは、VFSVolumeUnmount が sysNotifyVolumeUnmountedEvent をブロードキャストするよりも前で、かつ拡張マネージャが sysNotifyCardRemovedEvent をブロードキャストした後です。sysNotifyCardRemovedEvent を登録することにより、start.prc は自身が削除される前に取り外されようとしているボリュームに対して反応をすることができます。

NOTE
ハンドヘルドがロックされている状態で拡張カードが挿入された場合、start.prc はハンドヘルドのロックが解除されるまで実行されません。

 


← 4 節に戻る ↑7 章トップへ 6 節に進む →