Android binder-ipc

Preview:

Citation preview

Android プロセス間通信の仕組み

(Android IPC Mechanism)

Jim Huang (黃敬群)

Developer, 0xlab jserv@0xlab.org

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/

contact@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