Upload
magoroku-yamamoto
View
8.288
Download
9
Embed Size (px)
Citation preview
Android プロセス間通信の仕組み
(Android IPC Mechanism)
Jim Huang (黃敬群)
Developer, 0xlab [email protected]
March 19, 2012 / 南台科大
http://www.slideshare.net/jserv/android-ipc-mechanism を許可を得て@magoroku15が翻訳
Rights to copy
Attribution – ShareAlike 3.0
You are free
to copy, distribute, display, and perform the work
to make derivative works
to make commercial use of the work
Under the following conditions
Attribution. You must give the original author credit.
Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.
For any reuse or distribution, you must make clear to others the license terms of this work.
Any of these conditions can be waived if you get permission from the copyright holder.
Your fair use and other rights are in no way affected by the above.
License text: http://creativecommons.org/licenses/by-sa/3.0/legalcode
© Copyright 2012 0xlab http://0xlab.org/
Corrections, suggestions, contributions and translations are welcome!
Latest update: Mar 21, 2012
2
この資料の内容
• AndroidとBinder IPC
• デザインパターン
• Binderの構造
• Graphicsでの利用例
3
ANDROIDとBINDER IPC
4
Androidのタスク Process A Process B
Task Activity Activity
.apk package
.apk package
Content Provider
Activity
Service
5
Component View
• コンポーネントタイプ – Activity – Service – Content Provider – Broadcast Reciver
6
Application Components System
Application Components System 7
IPC = Inter-Process Communication プロセス間通信
Activity Manager
Window Manager
Alarm Manager
Activity
Kernel
8
なぜIPCなのか
• それぞれのプロセスは固有のアドレス空間を持ち、 分離・保護されている
• 2つの異なるプロセス間が直接かかわりを持って、問題を引き起こさないようにしている
• 場合によっては2つのプロセスの間の通信が必要となる
9
IPCの例
• Linuxの場合 – Signal シグナル
– Pipe パイプ
– Socket ソケット
– Semaphore セマフォ
– Message queue メッセージキュー
– Shared memory 共用メモリ
• Androidの場合 – Binder Lightweight RPC を提供
10
Binderの歴史
• Palm社がOpenBinderとして開発 – Dianne Hackbornが開発リーダ
• Android BinderはOpenBinderのカスタマイズと再実装 – 手続きとデータを他のプロセスに送って実行する
11
背景
• アプリケーションとサービスはそれぞれ異なるプロセスで実行しているが、相互の通信とデータの共有が必要
• IPCは処理のオーバーヘッドとセキュリティホールをもたらす場合がある
12
Androidでの解決 Binder
• プロセス間通信をドライバで実装
• 共用メモリを利用した高速処理
• 処理要求のためのプロセス毎にスレッドプールを用意
• 参照カウントとプロセスと超えてオブジェクトの参照
• プロセス間の同期呼び出し
“In the Android platform, the binder is used for nearly everything that happens across processes in the core platform. " – Dianne Hackborn https://lkml.org/lkml/2009/6/25/3
13
Binder: IPCの抽象化
• Intent – 高位の抽象化
• AIDL – Android InterfaceDefinition Language – プロセス間通信呼び出し
• Binder – カーネルドライバ
• Ashmem – 共用メモリ
Binder
AIDL
Intent More abstract
14
手続きの呼び出し
caller
callee
同じプロセスの場合
15
プロセス間の手続き呼び出し
caller
callee
callee
caller
interface
interface
interface
どうやって?
16
プロセス間の手続き呼び出し
caller
callee
Binder in kernel
callee
caller
Proxy
Binder Thread
Stub
interface
interface
interface
17
デザインパターン
18
Binderを用いた場合
• Proxy方式
• Mediator方式
• Bridge方式
19
Proxy方式
• プロキシがネットワーク接続、メモリ上の巨大オブジェクト、ファイル、その他すべての資源を仲介 – 処理が重く、複製ができない場合がある
20
AndroidのProxy方式
• Binder が手続き呼び出しと関連する全てのデータをLinuxが扱えるレベルに分解
• 送信元のアドレス空間から、送信先のアドレス空間へ転送 • 転送後は送信先でデータを再構成して手続きを実行
ローカル側 リモート側
アプリで記述
システムで用意
AIDLでインタフェースを生成
21
Mediator方式
• オブジェクト間の通信はmediatorオブジェクトがカプセル化する
22
Bridge方式
• 抽象化部分と実装部分を分離し、それぞれの独立性を保持
23
Android: BridgeとMediatorの併用
Java と C++によるBridge方式
Mediator方式
24
UMLでの表現
<<interface>>
Proxy Stub
implements
25
UMLでの表現
<<interface>>
Proxy Stub
caller
callee
calls
implements
extends
26
AIDL
<<interface>>
Proxy Stub
caller
callee
.aidl ファイルから自動生成
27
ActivityのonPause()を呼ぶのは誰か?
Activity Manager
Kernel
Binder Thread #1
Main Thread
Looper
Main threadから OnPause() が 呼び出される
プロセスを跨いで ”schedulePauseActivity”
を呼び出す
Handlerを利用して プロセス内でメッセージ
を送る Activity
3
2
1
queue
28
IPC Interaction in Android
Framework
getService 1 call
interface
2
29
Binderの動作
Process B Process A
30
BINDERの内部処理
31
用語
• Binder
– Binder Object
• Binderインターフェイスが生成するクラスのインスタンス
• 1つのBinder objectは複数のBinderを実装する
• Binder Protocol
– IBinder インターフェイス
• 事前に定義されたBinderが実装可能な手続き、プロパティ、イベントの集合
– Binder Token
• Binderを識別するユニークな数値
32
Binderの機能
• シンプルなプロセス間メッセージング
• Managing/管理
• Identifying/識別
• Calls/呼び出し
• Notification/通知
• Binder as a security access token
–セキュリティアクセストークン
33
Binderの機能
• Binder framework は単純なプロセス間メッセージ以上の機能を備えている
• 遠隔の手続きをローカルな手続きと同様に呼び出す事ができる
34
Binderプロトコル
・あるプロセスが他のプロセスにデータを送る事をトランザクションと呼ぶ ・送るデータをトランザクションデータと呼ぶ
35
Service Manager (SM)
• あらかじめ、アドレスがわかっている特殊なBinderノード – クライアントは接続先のBinderのアドレスを知らない – Binder interfaceだけが自分のアドレスを知っている
• Binder Interfaceは自分の名前とトークンをSMに登録する – クライアントは利用するサービス名をSMに問い合わせてBinderのアドレスを解決する
36
SMからサービスの一覧を取得
$ adb shell service list
Found 71 services:
0 stub_isms: [com.android.internal.telephony.ISms]
1 stub_phone: [com.android.internal.telephony.ITelephony]
2 stub_iphonesubinfo:
[com.android.internal.telephony.IPhoneSubInfo]
..
5 stub_telephony.registry:
[com.android.internal.telephony.ITelephonyRegistry]
...
7 stub_activity: [android.app.IActivityManager]
...
9 phone: [com.android.internal.telephony.ITelephony]
…
56 activity: [android.app.IActivityManager]
...
64 SurfaceFlinger: [android.ui.ISurfaceComposer]
...
37
ActivityManagerの手続き呼び出し $ adb shell service list
...
56 activity: [android.app.IActivityManager]
...
$ adb service call activity 1598968902
Result: Parcel(
0x00000000: 0000001c 006e0061 00720064 0069006f '....a.n.d.r.o.i.'
0x00000010: 002e0064 00700061 002e0070 00410049 'd...a.p.p...I.A.'
0x00000020: 00740063 00760069 00740069 004d0079 'c.t.i.v.i.t.y.M.'
0x00000030: 006e0061 00670061 00720065 00000000 'a.n.a.g.e.r.....')
public abstract interface IBinder {
...
field public static final int INTERFACE_TRANSACTION
= 1598968902; // 0x5f4e5446
…
} Source: frameworks/base/api/current.txt
38
Serviceとの関係 $ adb service call phone 1 s16 "123"
Result: Parcel(00000000 '....')
$ adb shell service list
Found 71 services:
...
9 phone: [com.android.internal.telephony.ITelephony]
interface ITelephony {
/* Dial a number. This doesn't place the call. It displays
* the Dialer screen. */
void dial(String number);
Source: frameworks/base/ telephony/java/com/android/internal/telephony/ITelephony.aidl
電話アプリに”123”と表示される
parameter “1” → dial()
s16 "123" → String("123")
39
Binderの実装レイヤ
Cで記述
C++で記述
Javaで記述
40
APIレイヤ
• AIDLはリモートサービスの実装を容易にする
• AIDLパーサが以下を生
成しミドルウェアを隠ぺいする
– Proxy class
– Stub class
– Java API Wrapper
41
AIDL
• データ型
• Javaプリミティブ
• コンテナ
• String,List,Map,CharSequence,List<>,多次元配列、
• Parcelable
• Interface Reference
• 方向 in, out, inout, oneway
• Android os Ibinder FLAG_ONEWAY
42
AIDL コンパイラ
• Javaのみをサポート
• StubとProxyを生成
// Interface
interface IRemoteService
{
void ping();
}
public class RemoteService extends Service {
public IBinder onBind(Intent intent) { return mBinder; }
private final IRemoteService.Stub mBinder =
new IRemoteService.Stub() {
public void ping() { // Nothing }
};
}
Server
IRemoteService mService =
IRemoteService.Stub.asInterface(service);
Client
43
タイトル
44
ParcelsとMarshalling
• プロセス間メッセージの仕組み
• オブジェクト指向の外観にparcelと呼ぶデータを飛ばす
• Parcelを組み立てる処理をMarshallingと呼ぶ
• Parcelからobjectを生成する処理をunmarshallingと呼ぶ
45
Parcel
• Marshalling プロセスの境界を越えて、データを転送する
–ネイティブなバイナリで表現
• ほとんどのコードはAIDLが生成
• Extensible - Parclabe
46
android.os.Parcel
展開して 組み立て 転送して
引数を受け渡す仕組み
47
Parceelの定義
• IBinderを経て送信可能なメッセージのコンテナ
• Parcelはフラットに展開したデータと転送先で有効なオブジェクトして利用可能なデータを含む
48
Parcelのrepresentation
• Parcelは汎用的なserializationでは無い –高速なIPCのためのClass API
–永続的なストレージにparcelを置く事は不適切
• 基本データ型を読み・書きする機能 –writeByte(byte) / readByte()
–writeDouble(double) / readDouble()
–writeFloat(float) / readFloat()
–writeInt(int) / readInt()
–writeLong(long) / readLong()
–writeString(String) / readString()
49
Parcelable
• ParcelabeプロトコルはParcelが自身を読み書きする効率的なプロトコル – writeParcelable(Parcelable, int)
– readParcelable(ClassLoader)
– writeParcelableArray(T[],int)
– readParcelableArray(ClassLoader)
• これらの手続きはクラスタイプとparcelへのデータ書き込みの双方で用いられて、後に適切なクラスローダを用いて復元される
50
Bundles
• 特別な型付けのないコンテナをBundleと呼び、ヘテロジニアスな値をKey/Valueのマップで保持
• これは、データの読み書きの性能向上に効果があり、Parcelの中にデータをmarshallingする際に発生する、型付け無APIが型付けに関わるディバックの難しさを避ける
51
ミドルウェアレイヤ
• ユーザ空間に実装された、C++のBinderフレームワーク
• スレッドの生成と管理のための構造と手続きを実現している
• Binderのカーネルドライバを呼び出す
52
• frameworks/base/include/binder/IServiceManager.h – sp<IServiceManager> defaultServiceManager()
• frameworks/base/include/binder/IInterface.h – template BpInterface
53
Kernel Driver レイヤ
• Binderドライバは次のシステムコールをサポート – open,mmap,release,poll,ioctl
• Ioctlの引数 – コマンドコード
• BINDER_WRITE_READ
• BINDER_SET_MAX_THREADS
• BINDER_SET_CONTEXT_MGR
• BINDER_THREAD_EXIT
• BINDER_VERSION
– データバッファ
54
Binderドライバ
• マルチスレッドに対応 – スレッド毎に内部状態を持つ
• UNIXのソケットはファイルディスクリプタ毎に状態を持つ点が異なる
55
Binder Driver
• 受け付けたIPC毎のサービスを処理するためのスレッドのプールを持つ
• Binderは2つのプロセス間のオブジェクトの対応を付けを行う
• Binderはプロセスのアドレス空間内でオブジェクトの参照を行う
• 同期呼び出し、参照カウント
56
UNIX socketとbinderの比較
socket binder
内部状態 FDで管理 PIDで管理
read&write ストリームI/O 単発のIoctl
ネットワーク透過性 有 無
57
Binder
$ adb cat /sys/devices/virtual/misc/binder/uevent MAJOR=10 MINOR=47 DEVNAME=binder
58
SMからBinder Driver Client
Server
Service Manager
Binder Driver: /dev/binder Kernel Space
User Space
Handle=0
Name:Handle
Name:Handle
Name:Handle
service list IXXX
onTransact(…)
thread pool
memory mapping
transact(…)
1
2
3 4 5
登録
問い合わせ
59
Transaction
ioctl(fd, BINDER_WRITE_READ, &bwt ) >= 0)
write buffer
read buffer
write_size
write_consumed
write_buffer
read_size
read_consumed
read_buffer
binder_write_read
BR BinderDriverReturnProtocol BC BinderDriverCommandProtocol
60
BinderのTransaction
Android の内部では Binderを用いてプロセス間で描画データを処理している
Process A
Process B
Binder
Process A
Binder
Process B
copy_from _userでメモリコピーし、Bを起こす
copy_to_userでメモリコピー
プロセスA とB は異なるアドレス空間を持つので、直接メモリ転送はできない
Kernel
Kernel
61
Binder IPCの限界
• Dalvik VMはメモリを共有していないので、Binder IPCがプロセスの境界を跨いだ通信を行う
–お互いのメモリオブジェクトを直接参照できない
• Binderは大きなデータストリームの転送には向いていない
– Audio/VideoをParcelに変換して転送するのには向かない
62
Binderの特性
• 良い点 – コンパクトな手続きの呼び出し
– バイナリデータの転送
– Ashmemのショートカット
– GUIDを利用しない
• 悪い点 – DalvikのParcel処理のオーバヘッド
– Ioctl経由での冗長な処理
– 名前解決のオーバヘッド
– 大域ロックの欠如
63
Binderのセキュリティ
• Binderのセキュリティ機能 – セキュリティはクライアント識別で行う
• Binder.getCallingUid(), Binder.getCallingPid()
– UNIXドメインソケットに似ている • getsockopt(…, SO_PEERCRED, …)
– クライアントはInterfaceの利用状況を推測できない
• Service Manager – システムサービスのディレクトリサービス
• サーバがクライアントのパミッションをチェック – Context.checkPermission(permission, pid, uid)
64
Binderのサンプルプログラム
• Build binder benchmark program % cd system/extras/tests/binder/benchmarks % mm % adb push ¥ ../../../../out/target/product/crespo/data/nativebenchmark/binderAddInts ¥ /data/local/
• Execute % adb shell $ su # /data/local/binderAddInts -d 5 -n 5 & # ps ... root 17133 16754 4568 860 ffffffff 400e6284 S /data/local/binderAddInts root 17135 17133 2520 616 00000000 400e5cb0 R /data/local/binderAddInts
65
Binder sample program • Execute # /data/local/binderAddInts -d 5 -n 5 &
# ps
...
root 17133 16754 4568 860 ffffffff 400e6284 S /data/local/binderAddInts
root 17135 17133 2520 616 00000000 400e5cb0 R /data/local/binderAddInts
#cat /sys/kernel/debug/binder/transaction_log
transaction_log:3439847: call from 17133:17133 to 72:0 node 1 handle 0 size 124:4
transaction_log:3439850: reply from 72:72 to 17133:17133 node 0 handle 0 size 4:0
transaction_log:3439855: call from 17135:17135 to 17133:0 node 3439848 handle 1 size 8:0
...
66
Binderをsysfsで見る
% adb shell ls /sys/kernel/debug/binder
failed_transaction_log
proc
state
stats
transaction_log
transactions
67
リモートプロシジャーコール
68
BINDER_WRITE_READ
69
Binder Transaction
• Target Method – handle : Remote Interface
– ptr & cookie : Local Interface
– code : Method ID
• Parcel - Input/Output Parameters – data.ptr.buffer
– data_size
• Object Reference Management – data.ptr.offsets
– offsets_size
• Security – sender_pid
– sender_euid
• No Transaction GUID – Transparent Recursion
70
オブジェクトの参照
71
Serviceの登録と検索
• 登録 – System serviceはISserviceManager::addServiceの呼び出しで登録 – パラメータはBinder Driverのhandle
• 検索 – Binder Driver Mapの中を指定された名前で検索 – IServiceManager::getService()が登録済みのサービスのhandleを返す
• Android.os.Ibinder.INTERFACE_TRANSACTIONが実際の名前
72
BINDERの利用例 GRAPHICS
73
実際の例
Binder IPC is used for communicating between Graphics client and server. Taken from http://www.cnblogs.com/xl19862005/archive/2011/11/17/2215363.html 74
Surface
Source: frameworks/base/core/java/android/view/Surface.java
/* Handle on to a raw buffer that is being managed by the screen compositor */
public class Surface implements Parcelable {
public Surface() {
mCanvas = new CompatibleCanvas();
}
private class CompatibleCanvas
extends Canvas { /* ... */ }
}
Surface のinstancesはParcelとして読み書きできる
75
引数の受け渡し
”flatten” ”unflatten”
transmit
76
Android SurfaceFlinger
• 2D/3D のsurfaceを重ね合わせる • surfaceは複数のアプリケーションが生成 • surfaces はbuffers をBinder IPC callsで渡す • OpenGL ES and 2D hardware accelerator を重ね合わせ • ダブルバッファをページ切り替え
77
Surface flingerの構成
78
Camera+SurfaceFlinger+Binder
79
Reference
• Inter-process communication of Android, Tetsuyuki Kobayashi
• 淺談Android系統進程間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路
• http://blog.goggb.com/?post=1580
• Android Binder – Android Interprocess Communication, Thorsten Schreiber
• Design Patterns in the Android Framework, Prof. Sheng-De Wang
80
http://0xlab.org
81