https://www.chromium.org/developers/design-documents/pepper-plugin-implementation
重要なコードの場所早見表
ppapi
-- Root PPAPIコードapi
-- IDL インターフェスc
-- 公開Cバイナリインタフェース(IDLから生成、treeにチェックインされた)cpp
-- CインタフェースをC++で使うラッパgenerators
-- IDLからCへのコンパイラhost
-- コンテントとブラウザがバックエンドを実装するために使うnative_client
-- NaCl 信頼プラグインproxy
-- ChromeのIPCベースのプロキシtests
-- ユニットテストshared_impl
-- Pepperオブジェクトのための実装。プロキシ間(ppapi/proxy)とプロセス内(content/renderer/pepper)で共有したいと思っている。
chrome/browser/renderer_host/pepper/pepper_*_host.*
-- ブラウザプロセスの新スタイルリソースのバックエンド("host")chrome/renderer/pepper/pepper_*_host.*
-- レンダラプロセスの新スタイルのリソースのバックエンド ("host")content/renderer/pepper/ppb_*_impl.*
-- プロセス内リソースの古いスタイルのリソースとWebKitへの接続content/browser/renderer_host/pepper/pepper_*_host.*
-- コンテントブラウザプロセスの新スタイルのリソースのバックエンド("host")実装content/renderer/pepper/pepper_*_host.*
-- コンテントレンダラプロセスの新スタイルのリソースのバックエンド("host")実装content/renderer/pepper/pepper_plugin_delegate_impl.*
-- WebKitコードからブラウザへアクセスするデリゲートインタフェース。content/renderer/render_view.cc
-- プラグインの割当(createPlugin参照)。chrome/test/ppapi/
-- テストコード(Chromeブラウザテストの一部)
問題追跡
PPAPIのバグはChromiumの問題トラッカーの中にある。pepper関連のバグを報告するには以下のラベルのすべてを使うこと:
- Area-Internals
- Cr-Internals-Plugins-Pepper
バグがNative Client関連なら以下のラベルも使う:
- NaCl
現在の"Cr-Internals-Plugins-Pepper"ラベルを参照
プラグインをChromeで実行
プラグインには「トラスト」と「アントラスト」の2つの動作モードが有る。アントラストプラグインはクロスプラットフォームで動作にNaClを使う。トラストプラグインはブラウザプロセスやプラグインプロセス内に直接ロードされプラットフォーム固有のライブラリのように振る舞う。
プラグインをトラストモードで動かすにはAPIを実装したプラットフォーム固有のライブラリを作成する。一例としては2Dグラフィックの「ペイントマネージャ」(ppapi/examples/2d/)がある。トラストプラグインはコマンドラインで処理すべきMIMEタイプを指定して登録する。コマンドラインは完全プラグイン名+セミコロン+MIMEタイプになる。MIMEタイプはページ内のオブジェクトタグの「type」属性と適合する。Linuxにおけるペイントマネージャの例の場合、以下のように実行する:
chrome --register-pepper-plugins="/local/src/out/Debug/lib/libppapi_example_paint_manager.so;application/x-ppapi-example-2d" file:///local/src/ppapi/examples/2d/2d.html
この場合、application/x-ppapi-example-2dがexample.html内で指定されていなければならない。--ppapi-out-of-processを指定するとプロセス外で実行される。プロセス内モードは廃止されてきており、このオプションを使うことが推奨される。
Linuxでは、新規xtermの新規GDBインスタンスでこのプロセスを自動で起動できる。スタートアップ時の問題をデバッグするのに役に立つ。以下のコマンドラインを使う: cpp --ppapi-plugin-launcher='xterm -title plugin -e gdb --eval-command=run --args'
「古い」リソースとプロキシデザイン
ほとんどのリソースは現状では古いプロキシデザインを使って実装されている。多くのレイヤが存在しあるものはプロセス内で、あるものはプロセス外で実装されている。
プロセス内実装はcontent/renderer/pepper/ppb_*_impl.*にある。これらはblinkやcontent/rendererの他のぶぶを使ってChromeの残りの部分と統合される。
プロセス外の場合はプロキシはインタフェースを実装する。ppapi/proxy/ppb_*_proxy.*で実装されている。プロキシはIPCチャネルの各端点にppapi/proxy/dispatcher.hを1つもつ。PluginDispatcherの特化はプラグイン側にあり、HostDispatcherの特化はレンダラ側にある。各インタフェースはプロキシオブジェクトをもち、ディスパッチャもそれと対応したプロキシとPP_Resourceオブジェクトと対応したリソースオブジェクトをもつ。
いくつかのプロキシオブジェクトと実装はコードを共有している。共有コードは重複を避けるためにppapi/shared_impl/ppb_*_shared.*に置かれる。
プラグイン→レンダラ呼び出しのライフサイクル
- プラグインがPPAPI関数を呼び出す。
- サンク層がこれをリソースオブジェクト呼び出しのC++コールへ変換する。
- リソースオブジェクトはPluginDispatcher経由でIPCメッセージをレンダラへ送る。
- HostDispatcherはメッセージを受け取り、レンダラ内の適切なプロキシオブジェクトインタフェースへ転送する。
- インターフェスプロキシはIPCメッセージをPPAPI呼び出しに変換し、プロセス内実装を呼び出す。
- 「impl」リソースが呼び出され処理を実行する。
「新しい」デザインとは異なり、ブラウザとの交信に標準的な方法は存在しない。あるコンポーネント(TCP/UDPソケット)は手巻きのトラッキングでこれを行う。
「新しい」リソースとプロキシデザイン
これからの追加は新しいプロキシデザインを使うべきである。パフォーマンスに優れ、書くコードも少なくて済む。古いものと新しいものは並行して存在し、1個づつ新しくしている。
リソースオブジェクトは一度だけ実装される(ppapi/proxy/*_resource.cc)。このリソースはブラウザやレンダラプロセス内の「host」オブジェクトにIPCを送信し仕事を行う。ホストオブジェクトはPepperAPIを話さず、単にChromeのIPCタイプを使う。これはレンダラプロセスでもブラウザプロセスでもできるし、両方使ったり使わなかったり(すべての機能がプラグインプロセス内にある場合)もできる。chromeやコンテントモジュール内に実装することもできる。
ホストオブジェクトはどこに存在するか?
- content/renderer/pepper/ — おそらく最も普通の場所。blinkや他のレンダラと対話するリソースはここに来る。
- chrome/renderer/pepper/ — Chromeのみのインタフェース(Flash,PDFや他のカスタムGoogleプラグイン)はここを使う。
- content/browser/renderer_host/pepper/ — content/renderer/pepperの代わりにまたは追加としてブラウザプロセスと会話する必要がある場合はここを使う。
- chrome/browser/renderer_host/pepper/ — chrome/renderer/pepperの代わりまたは追加としてブラウザプロセスと会話する必要がある場合はここを使う。
上記のディレクトリは「host factory」ファイルをもっており、それを使ってリソースのためのホストを作成できる。BrowserPpapiHost / RendererPpapiHostによってシステムを呼び出してリソースのコンテキストを取得することもできる。
We support in-process mode for legacy interfaces needed by certain plugins. New resources do not need to support in-process. For resources that need in-process, we have a "fake" IPC channel that allows the "proxy" and "host" to be in the same process. To wire this up, first get your out-of-process implementation working, then hook up creation through content/renderer/pepper/pepper_in_process_resource_creation.cc. Note that this only works for resources implemented in content/renderer. Other types of hosts are not supported in in-process mode.