opensource android

48
プンソ スなAd id プンソスなAndroid ~ソースが公開されたAndroidどのように活用するか~ 京都マイクロコンピュータ 小林哲之 1

Upload: tetsuyuki-kobayashi

Post on 20-May-2015

22.465 views

Category:

Technology


0 download

DESCRIPTION

「オープンソースなAndroid」~ソースが公開されたAndroidをどのように活用するか~

TRANSCRIPT

Page 1: Opensource Android

オ プンソ スなA d idオープンソースなAndroid

~ソースが公開されたAndroidをどのように活用するか~

京都マイクロコンピュータ小林哲之

1

Page 2: Opensource Android

はじめにはじめに

年• 2008年10月22日についにAndroidのソースコードが公開されました。

• Androidに関してはさまざまなトピックがありますが 今日はソ スコ ドを主題としますすが、今日はソースコードを主題とします。

• 内容は発表者個人の主観に基づいています。

• 正確性については「無保障」です。☺

2

Page 3: Opensource Android

Who am I?Who am I?

組み込み 筋 十年• 組み込み一筋N十年。– リアルタイムOS iTRON– 組み込み向けJava実行環境

– 組み込み向けLinux組 込 向け

– gccクロスコンパイルツール

• ブログ 「組み込みの人 」• ブログ 「組み込みの人。」– http://d.hatena.ne.jp/embedded/

京都マイクロ ンピ タ 年 月入社• 京都マイクロコンピュータ 2008年3月入社– http://www.kmckk.co.jp/

3

Page 4: Opensource Android

本日お話すること本日お話すること

• Androidの概要について

• ソースの概要について• ソースの概要について

• ソースから読み取れることソ 読 取れる

• ソースの活用方法

• まとめ

4

Page 5: Opensource Android

• Androidの概要についてAndroidの概要に いて

5

Page 6: Opensource Android

AndroidとはAndroidとは

社が主導 た携帯電話• Google社が主導で開発した携帯電話用ソフトウェアプラットフォーム。

• 2008年11月にHTC社からAndroid搭載の携帯電話 “G1”が発売されました電話 G1  が発売されました。

6

Page 7: Opensource Android

7

出典:http://ja.wikipedia.org/wiki/Android_(%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0)

Page 8: Opensource Android

Androidプラットフォームの構造Androidプラットフォームの構造ブラウザ

各種アプリケーションラウザ

GoogleMAPメール・・・

Java仮想マシン(Dalvik VM)libc

各種ミドルウェアWebkitSQLite

OpenGL EL・・・

Linux Kernel・・・

携帯電話H/W

Page 9: Opensource Android

Androidプラットフォームの構造Androidプラットフォームの構造

ブラウザ

各種アプリケーションブラウザ

GoogleMAPメール・・・

JavaCode

Java仮想マシン(Dalvik VM)

libc

各種ミドルウェアlibc

WebkitSQLite

OpenGL ELARMCode

Linux Kernel・・・

携帯電話ハードウェア

Page 10: Opensource Android

Androidプラットフォームの構造Androidプラットフォ ムの構造シミュレータの場合

ブラウザ

各種アプリケーションブラウザ

GoogleMAPメール・・・

JavaCode

Java仮想マシン(Dalvik VM)

libc

各種ミドルウェアlibc

WebkitSQLite

OpenGL ELARMCode

Linux Kernel・・・

QEMUシミュレータx86Code

Windows Code

Page 11: Opensource Android

プラットフォームとしての特徴プラットフォームとしての特徴

オ プンソ ス• オープンソース– 殆ど全てのソースコードが開示されました

カ ネルのみを使用• Linuxカーネルのみを使用– libcやルートファイルシステムは、通常の組み込みLinuxで使われている物と異なる使われている物と異なる

• アプリケーションレイヤはJavaで開発ネイティブコ ドで記述されたミドルウ アと 上位アプリ– ネイティブコードで記述されたミドルウェアと、上位アプリケーションの分離

• QEMUシミュレータの採用QEMUシミュレ タの採用– PC上でARM CPUのバイナリ互換を実現

Page 12: Opensource Android

• ソースの概要についてソ スの概要に いて

12

Page 13: Opensource Android

ソースのある場所ソースのある場所

• ここ

– http://source.android.com/p // /

• gitとそのラッパースクリプト(repo)を使用してソ スをダウンロ ドするソースをダウンロードする。

– Googleのアカウント(GMAIL)が必要。無償。

• ブラウザで閲覧するならここ

– http://git source android com/– http://git.source.android.com/

13

Page 14: Opensource Android

何が含まれている?何が含まれている?

d id S を再ビルドに必要なものが全て• Android SDKを再ビルドに必要なものが全て。

• Linux カーネル、デバイスドライバ、標準Cライブラリ、コンパイラツ ルチ イン D l ik VM 2D/3Dグラフィッコンパイラツールチェイン、Dalvik VM、2D/3Dグラフィックライブラリ、コーデック、アプリケーションフレームワーク webkit(WEBブラウザ)ワ ク、webkit(WEBブラウザ)、 ....

• ただし、MAPアプリケーションは含まれていない。

• HTC G1のソース? (デフォルトではダウンロードされないがリポジトリに存在する。けっこう頻繁に更新。)– kernel/msm.git– platform/hardware/msm7k.git– platform/vender/htc/dream.git

14

Page 15: Opensource Android

全てのソースがあるのか?全てのソースがあるのか?

• コンパイラツールチェインと一部のライブラリはバイナリで入っている。

– $(TOP)/prebuilt 以下

それらをリビルドするために必要なソ スの• それらをリビルドするために必要なソースのありかが明記されている。

– 各ディレクトリのREBUILTというファイルに

15

Page 16: Opensource Android

全部で何行?全部で何行?

• ダウンロードしたファイルのうち、ファイル名の末尾が .c .h .cpp .S .java のものだけを選んでpp jwc –l でカウントすると約1600万行。

• このうちLinux kernelのソ スコ ドを除くと• このうちLinux kernelのソースコードを除くと約770 万行。

• 詳細はhttp://d.hatena.ne.jp/embedded/20081127/p1http://d.hatena.ne.jp/embedded/20081127/p1

16

Page 17: Opensource Android

Androidでの新規ソースは?Androidでの新規ソースは?

たくさ プ 成• Androidではたくさんのオープンソースの成果を利用している。

• では、Androidで新規に起こされたファイルはどのくらいの規模か?どのくらいの規模か?

• /Copyright.*Android/ というパターンのあるファイルだけを集計すると約160万行。

• 詳細• 詳細http://d.hatena.ne.jp/embedded/20081130/p1

17

Page 18: Opensource Android

ライセンス条件は?ライセンス条件は?

基本• 基本はApache 2.0

• 多数のオープンソースの成果を利用している多数のオ プンソ スの成果を利用しているので、それはそれぞれのライセンス条件

モジ ルごとに *** とい• モジュールごとにMODULE_LICENSE_*** とい

うファイルがあり、簡単に確認できるように整備されている。

• また それぞれライセンス表示のための• また、それぞれライセンス表示のためのNOTICEというファイルがおかれている。

18

Page 19: Opensource Android

$ find . -name "MODULE_LICENSE_*“ ./system/extras/showmap/MODULE_LICENSE_APACHE2./system/extras/showslab/MODULE_LICENSE_APACHE2./system/extras/librank/MODULE_LICENSE_APACHE2/system/extras/procrank/MODULE LICENSE APACHE2

$ fi d " *" | d ' ^ */

./system/extras/procrank/MODULE_LICENSE_APACHE2

./system/extras/latencytop/MODULE_LICENSE_APACHE2...

$ find . -name "MODULE_LICENSE_*" |sed 's,^.*/,,' |sort |uniq -c |sort -r

117 MODULE_LICENSE_APACHE224 MODULE LICENSE BSD LIKE_ _ _11 MODULE_LICENSE_BSD10 MODULE_LICENSE_GPL9 MODULE_LICENSE_EPL7 MODULE LICENSE LGPL7 MODULE_LICENSE_LGPL4 MODULE_LICENSE_PUBLIC_DOMAIN4 MODULE_LICENSE_LGPL_AND_GPL2 MODULE LICENSE CPL_ _1 MODULE_LICENSE_W3C1 MODULE_LICENSE_OSL11 MODULE_LICENSE_MIT1 MODULE LICENSE HP

19

1 MODULE_LICENSE_HP1 MODULE_LICENSE_AFL_AND_GPL

Page 20: Opensource Android

ちなみにGPLのものは$ find . -name "MODULE_LICENSE_*" |grep GPL./external/iptables/MODULE_LICENSE_GPL./external/elfcopy/MODULE_LICENSE_GPL./external/jdiff/MODULE LICENSE LGPL./external/jdiff/MODULE_LICENSE_LGPL./external/yaffs2/MODULE_LICENSE_GPL./external/qemu/MODULE_LICENSE_GPL./external/webkit/WebCore/MODULE_LICENSE_LGPL./external/dbus/MODULE LICENSE AFL AND GPL./external/dbus/MODULE_LICENSE_AFL_AND_GPL./external/oprofile/MODULE_LICENSE_GPL./prebuilt/windows/sdl/MODULE_LICENSE_LGPL./prebuilt/windows/ccache/MODULE_LICENSE_GPL./prebuilt/darwin-x86/sdl/MODULE LICENSE LGPL./p ebu t/da w 86/sd / O U _ C S _ G./prebuilt/darwin-x86/toolchain/i686-apple-darwin8-4.0.1/MODULE_LICENSE_LGPL_AND_GPL./prebuilt/darwin-x86/toolchain/arm-eabi-4.2.1/MODULE_LICENSE_LGPL_AND_GPL./prebuilt/darwin-x86/ccache/MODULE LICENSE GPL/p / / / _ _./prebuilt/darwin-x86/make/MODULE_LICENSE_GPL./prebuilt/common/jfreechart/MODULE_LICENSE_LGPL./prebuilt/common/swing-worker/MODULE_LICENSE_LGPL./prebuilt/common/netbeans-visual/MODULE LICENSE GPL/p / / / _ _./prebuilt/linux-x86/sdl/MODULE_LICENSE_LGPL./prebuilt/linux-x86/toolchain/i686-linux-gnu-3.4.6/MODULE_LICENSE_LGPL_AND_GPL./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/MODULE LICENSE LGPL AND GPL

20

/p / / / / _ _ _ _./prebuilt/linux-x86/ccache/MODULE_LICENSE_GPL

Page 21: Opensource Android

ビルドのしかたビルドのしかた

Li ( b t ) M OS(i t l)でのビルドがサポ トされ• Linux (ubuntu), MacOS(intel)でのビルドがサポートされている。– http://source.android.com/downloadhttp://source.android.com/download– 他に必要なライブラリ

– sudo apt‐get install zlib1g‐dev libncruses5‐dev unzip

• 手軽な方法VMWare上にubuntu 8 04 i386をクリ ンインスト ル– VMWare上にubuntu 8.04 i386をクリーンインストール

– 無料のVMWare player利用可能– ビルド時間 40分くらい?ビルド時間 0分くらい

• 困った時はネットで検索。☺• make sdkでSDK一式が再ビルド。

21

Page 22: Opensource Android

ビルドのTipsビルドのTips

ド 表• make showcommands でコマンドライン表示

• ccacheを使うためには環境変数ccache を使うためには環境変数USE_CCACHE=1

環境ではデフ ルト設定が無難• VMWare環境ではデフォルト設定が無難(512MBメモリ、プロセッサ1個)

• make sdkJDK6でなくJDK5でないとjavadocでエラ になる– JDK6でなくJDK5でないとjavadocでエラーになる

22

Page 23: Opensource Android

移植性?移植性?

タ ゲットCPUはARMのみだ たが 2008年12月のアッ• ターゲットCPUはARMのみだったが 2008年12月のアップデートでx86向けのビルドが追加された。– armv5t (ARM926以降、Xscale)armv5t (ARM926以降、Xscale)

• パス名に’arm’を含むファイルが多いもの– bionic– dalvik– external/opencore– external/sonivox– external/qemuexternal/openssl– external/openssl

• これらの移植に目途がつけば、他のCPUでもいけそう。

23

Page 24: Opensource Android

移植性?: Bionic移植性?: Bionic

標準ライブラリとランタイムロ ダ• 標準ライブラリとランタイムローダ– libc, libm, libdl, libthread_db, linkerF BSD O BSD N tBSDからのファイルをベ• FreeBSD, OpenBSD, NetBSDからのファイルをベースにしているようだ。

• アセンブラで書いてあるのは• アセンブラで書いてあるのは– カーネルのシステムコール呼び出し部分memcpyなどのアセンブラ版– memcpyなどのアセンブラ版

• 現在はARM,x86用のものしかないが、同じように*BSDから持ってくれば他のCPU用のものも準備BSDから持ってくれば他のCPU用のものも準備できそう。

24

Page 25: Opensource Android

移植性?: Dalvik VM移植性?: Dalvik VM

ドのインタプリタが何種類か用意され• DXコードのインタプリタが何種類か用意されている。– 高速版 (アセンブラで書かれている)– 移植用 (Cで書かれている)(– デバッグ用、プロファイル用

• それ以外のARM依存ファイルはABIを定義しそれ以外のARM依存ファイルはABIを定義しているファイルのみ。

とりあえずC版インタプリタを使えば移植は簡• とりあえずC版インタプリタを使えば移植は簡単?

25

Page 26: Opensource Android

互換性テスト互換性テスト

• 各モジュールに単体テスト用のファイルらしき

ものがあるが システム全体に渡る互換性はものがあるが、システム全体に渡る互換性は

どうなるのだろう ?どうなるのだろう... ?

• キラーアプリ、キラーデバイスによるデファクキラ アプリ、キラ デバイスによるデファク

トスタンダード?

• サブセット化OK?

26

Page 27: Opensource Android

ここまでの感想ここまでの感想

「本当に 全部のソ スが公開された• 「本当に」全部のソースが公開された。– iPhoneとの 大の違い。

• 扱いやすいライセンス。

• 用途は携帯電話に限定されない。用途 携帯電話 限定されな 。

• まさに、Google 太っ腹!ここから直接収益を上げることは全く考えていないようだ。「どうぞげることは全く考えていないようだ。「どうぞ、使ってください」という感じ。

• 組み込みLinuxのメジャーなディストリビューショ• 組み込みLinuxのメジャ なディストリビュ ションになるかも。

27

Page 28: Opensource Android

• ソースから読み取れることソ スから読み取れる と

28

Page 29: Opensource Android

Bionic(標準Cライブラリ)Bionic(標準Cライブラリ)

制約事• CAVEATS(制約事項)– $(TOP)/bionic/libc/CAVEATS$( )/ / /

– 基本はPOSIX準拠だが...

C++の例外をサポ トしない 組み込みシステム– C++の例外をサポートしない。組み込みシステムではひどく遅いコードになるから。

h dのキ ンセル機能はサポ トしない– pthreadのキャンセル機能はサポートしない。

– ロケールやワイドキャラクタはサポートしない。国際化対応には代わりにICUを使う。

29

Page 30: Opensource Android

AndroidでのC++プログラミングの制限AndroidでのC++プログラミングの制限

例外は使用できない• 例外は使用できない。– newはmallocと同等。

– メモリがないときはNULLを返す。

• 実行時型情報は使用できない。– type_infoは空実装。

– pure virtual functionは使用できない。

• STL(標準テンプレートライブラリ)は使用できない。– Vector.h, List.hはframeworks/base/include/utilsにある。

• コンパイル時にはオプション –fno‐exceptions –fno‐rttiをつける。

30

Page 31: Opensource Android

libstdc++の中身はたったこれだけ$ nm -C out/target/product/generic/symbols/system/lib/libstdc++.so |grep ' [TDRB] '000019dd T type_info::type_info(type_info const&)000019a5 T type info::type info()

libstdc++ の中身はたったこれだけ。

000019a5 T type_info::type_info()000019dd T type_info::type_info(type_info const&)000019a5 T type_info::type_info()000019f5 T type_info::~type_info()00001a19 T type_info::~type_info()

i i00001a19 T type_info::~type_info()000019bd T type_info::name() const000019d9 T type_info::before(type_info const&) const000019d1 T type_info::operator==(type_info const&) const000019d5 T type info::operator!=(type info const&) const_ _00001a30 R std::nothrow00002000 D vtable for type_info0000192d T operator delete[](void*)0000190d T operator delete[](void*, std::nothrow_t const&)0000193d T operator delete(void*)0000193d T operator delete(void )0000191d T operator delete(void*, std::nothrow_t const&)00001965 T operator new[](unsigned int)0000194d T operator new[](unsigned int, std::nothrow_t const&)00001971 T operator new(unsigned int)00001959 T t ( i d i t td th t t )00001959 T operator new(unsigned int, std::nothrow_t const&)0000189d T __cxa_guard_abort000018d9 T __cxa_guard_acquire000018b5 T __cxa_guard_release0000197d T __cxa_pure_virtual

31

__ _ _$

Page 32: Opensource Android

ダイナミックリンクダイナミックリンク

• linker– ld.so ではない。Android 新規設計。

– libdlの機能はある。 dlsym, dlopen

• prelink (apriori)prelink (apriori) – ライブラリを固定アドレスにマッピング

• build/core/prelink linux arm map• build/core/prelink‐linux‐arm.map

– 実行ファイル(executable)はprelinkしてない

起動高速化というより共有メモリの効率化のため?– 起動高速化というより共有メモリの効率化のため?

• stripコマンドの代わりにsoslimコマンド

32

Page 33: Opensource Android

各ライブラリの配置アドレス$ cat build/core/prelink-linux-arm.map

# 0xC0000000 - 0xFFFFFFFF Kernel

各ライブラリの配置アドレス

# 0xC0000000 - 0xFFFFFFFF Kernel# 0xB0100000 - 0xBFFFFFFF Thread 0 Stack# 0xB0000000 - 0xB00FFFFF Linker# 0xA0000000 - 0xBFFFFFFF Prelinked System Libraries# 0x90000000 - 0x9FFFFFFF Prelinked App Libraries# i i i# 0x80000000 - 0x8FFFFFFF Non-prelinked Libraries# 0x40000000 - 0x7FFFFFFF mmap'd stuff# 0x10000000 - 0x3FFFFFFF Thread Stacks# 0x00000000 - 0x0FFFFFFF .text / .data / heap

# core system librarieslibdl.so 0xAFF00000libc.so 0xAFE00000libstdc++.so 0xAFD00000libm so 0xAFC00000libm.so 0xAFC00000liblog.so 0xAFBC0000libcutils.so 0xAFB00000libthread_db.so 0xAFA00000libz.so 0xAF900000lib t 0 AF800000libevent.so 0xAF800000libssl.so 0xAF700000libcrypto.so 0xAF500000

....

33

Page 34: Opensource Android

DalvikDalvik

ブ プ ジ 成• クラスライブラリはHarmonyプロジェクトの成果。(既存のCLASSPATHプロジェクトだとGPL)( )

• アプリ起動時、zygoteというプロセスからfork され 新しいプロセスのmainメソッドをDalvikされ、新しいプロセスのmainメソッドをDalvik VMのレベルでインボークされる。exec システム は使用していないムコールは使用していない。

– なるべく多くの共有メモリをzygoteから引き継ぐ。yg

– アプリ起動時間の短縮にもなる。

34

Page 35: Opensource Android

DXコードインタプリタDXコードインタプリタ

装備 な• JIT(Just In Time compiler)は装備していない。

• 複数のインタープリタ実装複数のインタ プリタ実装

– 高速版 (ARMのアセンブラで書いてある。)

デバ グ プロフ イル用– デバッグ、プロファイル用

– 移植用(C言語で書いてある。)

• ARMアセンブラではFPU命令が使われていない (ARM1136jf向けにチューンする余地)ない。(ARM1136jf向けにチュ ンする余地)

35

Page 36: Opensource Android

Linux KernelLinux Kernel

• 2.6.27 

• Android特有の部分• Android特有の部分

–binder

– ashmem

ザ 空間デバイスドライバ?• ユーザー空間デバイスドライバ?

– libhardwarelibhardware

36

Page 37: Opensource Android

binderbinder

プ• プロセス間通信

• OpenBinder orgのものをベースにしてい• OpenBinder.org のものをベースにしていたが今は互換性はない。

• Androidのアプリケーションフレームワークの根幹をなすクの根幹をなす。

• 上位層は AIDLにつながっている。上位層は AIDL に ながっている。

37

Page 38: Opensource Android

ashmemashmem

• Android / Anonymous SHared MEMory subsystem

• $(TOP)/system/core/cutils/ashmem.h– int ashmem_create_region(const char *name, size_t size) → returns fd

– int ashmem_set_prot_region(int fd, int prot)

– int ashmem pin region(int fd, size t offset, size t len)_p _ g ( , _ , _ )

– int ashmem_unpin_region(int fd, size_t offset, size_t len)

• ‘pin’していないメモリはカーネルが回収して再利用

• Javaの weak reference に似ている概念。キャッシュの実装に便利。実装 便利。

• Javaから利用するときはandroid.os.MemoryFile

38

Page 39: Opensource Android

• ソースの活用方法ソ スの活用方法

39

Page 40: Opensource Android

ソースの活用方法ソースの活用方法

大部分• Androidのソースの大部分はApachライセンス

で改変は自由。あらゆる活用方法が考えられ改変 自由。あらゆる活用方法 考 られる。

自分の製品にそのまま移植して アプリケーショ– 自分の製品にそのまま移植して、アプリケーションをJava言語で開発する。

分解して必要な部分だけ使用する– 分解して必要な部分だけ使用する。

• いずれにせよ、ソースから学べることは多い。

40

Page 41: Opensource Android

Androidを部分的に利用するとしたらAndroidを部分的に利用するとしたら

使う• 小システムで使う

– Linuxカーネルとinit, toolbox, 標準Cライブラリだけカ ネル , ,標準 ライ ラリだけ

– グラフィックスやDalvik VMをはずしてしまう

小システム スクリプト言語• 小システム + スクリプト言語

– 例えば ruby。 C言語で実装されているものならば移植は難しくない。

41

Page 42: Opensource Android

Dalvik VMを他のOSに移植?Dalvik VMを他のOSに移植?

l k 自身は があれば移植でき• Dalvik VM自身はPOSIX APIがあれば移植できそう。

• アプリケーションのフレームワークはbinderに強く依存している。binderはLinuxカーネルのド強 依存 。ライバとして実装されていてGPLライセンス。

• Android独自のカーネルドライバ binderやAndroid独自のカ ネルドライバ binderやashmemをGPL以外のOSに移植するにはスクラッチから互換性のあるものを作る必要があラッチから互換性のあるものを作る必要がある。

42

Page 43: Opensource Android

• まとめまとめ

43

Page 44: Opensource Android

Androidの強み:過去のしがらみがない

現在またはこの先利用できる技術を前提• 現在またはこの先利用できる技術を前提– メモリ, CPUはJavaを動かすのに十分ある。

• アプリケーションは全てJavaで書く• アプリケーションは全てJavaで書く。• アプリケーションフレームワークはJavaで統一されてネイティブアプリケーションとの競合を考慮しなくてよい。

は 固定– OSはLinux固定。• 仮想メモリシステムを活用。

GPUによる高速3D描画– GPUによる高速3D描画。• 2DグラフィックスもOpenGLで。そのため2Dと3Dの重ね合わせの問題を考慮しなくてよい。

無料 定額制 パケ 通信– 無料のWiFi, 定額制の3Gパケット通信。• バックグランドでシームレスにネットワークの切り替え。

44

Page 45: Opensource Android

Androidの強み:オープンソースであること

• 特別な契約なしで誰でもソースを見ることができる。

• Apacheライセンスは商用利用で扱いやすい。

無償のツ ルだけでビルド環境を構築できる• 無償のツールだけでビルド環境を構築できる。

• このため世界中の優秀な技術者でにぎわう。

ぎわう技術は急速 進歩する• にぎわう技術は急速に進歩する。

45

Page 46: Opensource Android

AndroidのインパクトAndroidのインパクト

組 与 る• 組み込みシステム開発にAndroidの与えるインパクトは少なくないだろう。

• 直接的インパクト

A d idを採用しての製品開発– Androidを採用しての製品開発

– Androidソースの部分利用

• 間接的インパクト

他の組み込みプラットフォームもソース公開の流– 他の組み込みプラットフォームもソース公開の流れに

46

Page 47: Opensource Android

オープンソースオープンソース

• 組み込みソフト開発でもオープンソースを避けて通ることができなくなった。

• ソースは無償で入手できるが、それを読み解き 活用するためには技術力が必要き、活用するためには技術力が必要。

• 技術力の向上にはまず情報交換を。

日本A d idの会• 日本Androidの会– http://www.android‐group.jp/index.php?FrontPage

47

Page 48: Opensource Android

ご静聴ありがとうございました。

48