81
Android プロセス間通信の仕組み (Android IPC Mechanism) Jim Huang (黃敬群) Developer, 0xlab [email protected] March 19, 2012 / 南台科大 http://www.slideshare.net/jserv/android-ipc-mechanism を許可を得て@magoroku15が翻訳

Android binder-ipc

Embed Size (px)

Citation preview

Page 1: Android binder-ipc

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

(Android IPC Mechanism)

Jim Huang (黃敬群)

Developer, 0xlab [email protected]

March 19, 2012 / 南台科大

http://www.slideshare.net/jserv/android-ipc-mechanism を許可を得て@magoroku15が翻訳

Page 2: Android binder-ipc

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/

[email protected]

Corrections, suggestions, contributions and translations are welcome!

Latest update: Mar 21, 2012

2

Page 3: Android binder-ipc

この資料の内容

• AndroidとBinder IPC

• デザインパターン

• Binderの構造

• Graphicsでの利用例

3

Page 4: Android binder-ipc

ANDROIDとBINDER IPC

4

Page 5: Android binder-ipc

Androidのタスク Process A Process B

Task Activity Activity

.apk package

.apk package

Content Provider

Activity

Service

5

Page 6: Android binder-ipc

Component View

• コンポーネントタイプ – Activity – Service – Content Provider – Broadcast Reciver

6

Page 7: Android binder-ipc

Application Components System

Application Components System 7

Page 8: Android binder-ipc

IPC = Inter-Process Communication プロセス間通信

Activity Manager

Window Manager

Alarm Manager

Activity

Kernel

8

Page 9: Android binder-ipc

なぜIPCなのか

• それぞれのプロセスは固有のアドレス空間を持ち、 分離・保護されている

• 2つの異なるプロセス間が直接かかわりを持って、問題を引き起こさないようにしている

• 場合によっては2つのプロセスの間の通信が必要となる

9

Page 10: Android binder-ipc

IPCの例

• Linuxの場合 – Signal シグナル

– Pipe パイプ

– Socket ソケット

– Semaphore セマフォ

– Message queue メッセージキュー

– Shared memory 共用メモリ

• Androidの場合 – Binder Lightweight RPC を提供

10

Page 11: Android binder-ipc

Binderの歴史

• Palm社がOpenBinderとして開発 – Dianne Hackbornが開発リーダ

• Android BinderはOpenBinderのカスタマイズと再実装 – 手続きとデータを他のプロセスに送って実行する

11

Page 12: Android binder-ipc

背景

• アプリケーションとサービスはそれぞれ異なるプロセスで実行しているが、相互の通信とデータの共有が必要

• IPCは処理のオーバーヘッドとセキュリティホールをもたらす場合がある

12

Page 13: Android binder-ipc

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

Page 14: Android binder-ipc

Binder: IPCの抽象化

• Intent – 高位の抽象化

• AIDL – Android InterfaceDefinition Language – プロセス間通信呼び出し

• Binder – カーネルドライバ

• Ashmem – 共用メモリ

Binder

AIDL

Intent More abstract

14

Page 15: Android binder-ipc

手続きの呼び出し

caller

callee

同じプロセスの場合

15

Page 16: Android binder-ipc

プロセス間の手続き呼び出し

caller

callee

callee

caller

interface

interface

interface

どうやって?

16

Page 17: Android binder-ipc

プロセス間の手続き呼び出し

caller

callee

Binder in kernel

callee

caller

Proxy

Binder Thread

Stub

interface

interface

interface

17

Page 18: Android binder-ipc

デザインパターン

18

Page 19: Android binder-ipc

Binderを用いた場合

• Proxy方式

• Mediator方式

• Bridge方式

19

Page 20: Android binder-ipc

Proxy方式

• プロキシがネットワーク接続、メモリ上の巨大オブジェクト、ファイル、その他すべての資源を仲介 – 処理が重く、複製ができない場合がある

20

Page 21: Android binder-ipc

AndroidのProxy方式

• Binder が手続き呼び出しと関連する全てのデータをLinuxが扱えるレベルに分解

• 送信元のアドレス空間から、送信先のアドレス空間へ転送 • 転送後は送信先でデータを再構成して手続きを実行

ローカル側 リモート側

アプリで記述

システムで用意

AIDLでインタフェースを生成

21

Page 22: Android binder-ipc

Mediator方式

• オブジェクト間の通信はmediatorオブジェクトがカプセル化する

22

Page 23: Android binder-ipc

Bridge方式

• 抽象化部分と実装部分を分離し、それぞれの独立性を保持

23

Page 24: Android binder-ipc

Android: BridgeとMediatorの併用

Java と C++によるBridge方式

Mediator方式

24

Page 25: Android binder-ipc

UMLでの表現

<<interface>>

Proxy Stub

implements

25

Page 26: Android binder-ipc

UMLでの表現

<<interface>>

Proxy Stub

caller

callee

calls

implements

extends

26

Page 27: Android binder-ipc

AIDL

<<interface>>

Proxy Stub

caller

callee

.aidl ファイルから自動生成

27

Page 28: Android binder-ipc

ActivityのonPause()を呼ぶのは誰か?

Activity Manager

Kernel

Binder Thread #1

Main Thread

Looper

Main threadから OnPause() が 呼び出される

プロセスを跨いで ”schedulePauseActivity”

を呼び出す

Handlerを利用して プロセス内でメッセージ

を送る Activity

3

2

1

queue

28

Page 29: Android binder-ipc

IPC Interaction in Android

Framework

getService 1 call

interface

2

29

Page 30: Android binder-ipc

Binderの動作

Process B Process A

30

Page 31: Android binder-ipc

BINDERの内部処理

31

Page 32: Android binder-ipc

用語

• Binder

– Binder Object

• Binderインターフェイスが生成するクラスのインスタンス

• 1つのBinder objectは複数のBinderを実装する

• Binder Protocol

– IBinder インターフェイス

• 事前に定義されたBinderが実装可能な手続き、プロパティ、イベントの集合

– Binder Token

• Binderを識別するユニークな数値

32

Page 33: Android binder-ipc

Binderの機能

• シンプルなプロセス間メッセージング

• Managing/管理

• Identifying/識別

• Calls/呼び出し

• Notification/通知

• Binder as a security access token

–セキュリティアクセストークン

33

Page 34: Android binder-ipc

Binderの機能

• Binder framework は単純なプロセス間メッセージ以上の機能を備えている

• 遠隔の手続きをローカルな手続きと同様に呼び出す事ができる

34

Page 35: Android binder-ipc

Binderプロトコル

・あるプロセスが他のプロセスにデータを送る事をトランザクションと呼ぶ ・送るデータをトランザクションデータと呼ぶ

35

Page 36: Android binder-ipc

Service Manager (SM)

• あらかじめ、アドレスがわかっている特殊なBinderノード – クライアントは接続先のBinderのアドレスを知らない – Binder interfaceだけが自分のアドレスを知っている

• Binder Interfaceは自分の名前とトークンをSMに登録する – クライアントは利用するサービス名をSMに問い合わせてBinderのアドレスを解決する

36

Page 37: Android binder-ipc

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

Page 38: Android binder-ipc

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

Page 39: Android binder-ipc

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

Page 40: Android binder-ipc

Binderの実装レイヤ

Cで記述

C++で記述

Javaで記述

40

Page 41: Android binder-ipc

APIレイヤ

• AIDLはリモートサービスの実装を容易にする

• AIDLパーサが以下を生

成しミドルウェアを隠ぺいする

– Proxy class

– Stub class

– Java API Wrapper

41

Page 42: Android binder-ipc

AIDL

• データ型

• Javaプリミティブ

• コンテナ

• String,List,Map,CharSequence,List<>,多次元配列、

• Parcelable

• Interface Reference

• 方向 in, out, inout, oneway

• Android os Ibinder FLAG_ONEWAY

42

Page 43: Android binder-ipc

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

Page 44: Android binder-ipc

タイトル

44

Page 45: Android binder-ipc

ParcelsとMarshalling

• プロセス間メッセージの仕組み

• オブジェクト指向の外観にparcelと呼ぶデータを飛ばす

• Parcelを組み立てる処理をMarshallingと呼ぶ

• Parcelからobjectを生成する処理をunmarshallingと呼ぶ

45

Page 46: Android binder-ipc

Parcel

• Marshalling プロセスの境界を越えて、データを転送する

–ネイティブなバイナリで表現

• ほとんどのコードはAIDLが生成

• Extensible - Parclabe

46

Page 47: Android binder-ipc

android.os.Parcel

展開して 組み立て 転送して

引数を受け渡す仕組み

47

Page 48: Android binder-ipc

Parceelの定義

• IBinderを経て送信可能なメッセージのコンテナ

• Parcelはフラットに展開したデータと転送先で有効なオブジェクトして利用可能なデータを含む

48

Page 49: Android binder-ipc

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

Page 50: Android binder-ipc

Parcelable

• ParcelabeプロトコルはParcelが自身を読み書きする効率的なプロトコル – writeParcelable(Parcelable, int)

– readParcelable(ClassLoader)

– writeParcelableArray(T[],int)

– readParcelableArray(ClassLoader)

• これらの手続きはクラスタイプとparcelへのデータ書き込みの双方で用いられて、後に適切なクラスローダを用いて復元される

50

Page 51: Android binder-ipc

Bundles

• 特別な型付けのないコンテナをBundleと呼び、ヘテロジニアスな値をKey/Valueのマップで保持

• これは、データの読み書きの性能向上に効果があり、Parcelの中にデータをmarshallingする際に発生する、型付け無APIが型付けに関わるディバックの難しさを避ける

51

Page 52: Android binder-ipc

ミドルウェアレイヤ

• ユーザ空間に実装された、C++のBinderフレームワーク

• スレッドの生成と管理のための構造と手続きを実現している

• Binderのカーネルドライバを呼び出す

52

Page 53: Android binder-ipc

• frameworks/base/include/binder/IServiceManager.h – sp<IServiceManager> defaultServiceManager()

• frameworks/base/include/binder/IInterface.h – template BpInterface

53

Page 54: Android binder-ipc

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

Page 55: Android binder-ipc

Binderドライバ

• マルチスレッドに対応 – スレッド毎に内部状態を持つ

• UNIXのソケットはファイルディスクリプタ毎に状態を持つ点が異なる

55

Page 56: Android binder-ipc

Binder Driver

• 受け付けたIPC毎のサービスを処理するためのスレッドのプールを持つ

• Binderは2つのプロセス間のオブジェクトの対応を付けを行う

• Binderはプロセスのアドレス空間内でオブジェクトの参照を行う

• 同期呼び出し、参照カウント

56

Page 57: Android binder-ipc

UNIX socketとbinderの比較

socket binder

内部状態 FDで管理 PIDで管理

read&write ストリームI/O 単発のIoctl

ネットワーク透過性 有 無

57

Page 58: Android binder-ipc

Binder

$ adb cat /sys/devices/virtual/misc/binder/uevent MAJOR=10 MINOR=47 DEVNAME=binder

58

Page 59: Android binder-ipc

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

Page 60: Android binder-ipc

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

Page 61: Android binder-ipc

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

Page 62: Android binder-ipc

Binder IPCの限界

• Dalvik VMはメモリを共有していないので、Binder IPCがプロセスの境界を跨いだ通信を行う

–お互いのメモリオブジェクトを直接参照できない

• Binderは大きなデータストリームの転送には向いていない

– Audio/VideoをParcelに変換して転送するのには向かない

62

Page 63: Android binder-ipc

Binderの特性

• 良い点 – コンパクトな手続きの呼び出し

– バイナリデータの転送

– Ashmemのショートカット

– GUIDを利用しない

• 悪い点 – DalvikのParcel処理のオーバヘッド

– Ioctl経由での冗長な処理

– 名前解決のオーバヘッド

– 大域ロックの欠如

63

Page 64: Android binder-ipc

Binderのセキュリティ

• Binderのセキュリティ機能 – セキュリティはクライアント識別で行う

• Binder.getCallingUid(), Binder.getCallingPid()

– UNIXドメインソケットに似ている • getsockopt(…, SO_PEERCRED, …)

– クライアントはInterfaceの利用状況を推測できない

• Service Manager – システムサービスのディレクトリサービス

• サーバがクライアントのパミッションをチェック – Context.checkPermission(permission, pid, uid)

64

Page 65: Android binder-ipc

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

Page 66: Android binder-ipc

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

Page 67: Android binder-ipc

Binderをsysfsで見る

% adb shell ls /sys/kernel/debug/binder

failed_transaction_log

proc

state

stats

transaction_log

transactions

67

Page 68: Android binder-ipc

リモートプロシジャーコール

68

Page 69: Android binder-ipc

BINDER_WRITE_READ

69

Page 70: Android binder-ipc

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

Page 71: Android binder-ipc

オブジェクトの参照

71

Page 72: Android binder-ipc

Serviceの登録と検索

• 登録 – System serviceはISserviceManager::addServiceの呼び出しで登録 – パラメータはBinder Driverのhandle

• 検索 – Binder Driver Mapの中を指定された名前で検索 – IServiceManager::getService()が登録済みのサービスのhandleを返す

• Android.os.Ibinder.INTERFACE_TRANSACTIONが実際の名前

72

Page 73: Android binder-ipc

BINDERの利用例 GRAPHICS

73

Page 74: Android binder-ipc

実際の例

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

Page 75: Android binder-ipc

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

Page 76: Android binder-ipc

引数の受け渡し

”flatten” ”unflatten”

transmit

76

Page 77: Android binder-ipc

Android SurfaceFlinger

• 2D/3D のsurfaceを重ね合わせる • surfaceは複数のアプリケーションが生成 • surfaces はbuffers をBinder IPC callsで渡す • OpenGL ES and 2D hardware accelerator を重ね合わせ • ダブルバッファをページ切り替え

77

Page 78: Android binder-ipc

Surface flingerの構成

78

Page 79: Android binder-ipc

Camera+SurfaceFlinger+Binder

79

Page 80: Android binder-ipc

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

Page 81: Android binder-ipc

http://0xlab.org

81