Android源码分析--MediaServer源码分析(一)
MediaServer中包括了系統(tǒng)中的許多重要的Server:
- AudioFlinger:音頻系統(tǒng)中的核心服務(wù)
- AudioPolicyService:音頻系統(tǒng)中關(guān)于音頻策略的重要服務(wù)
- MediaPlayerService:多媒體系統(tǒng)中的重要服務(wù)
- CameraService:有關(guān)照相和攝像的重要服務(wù)
同時(shí),分析MediaServer對(duì)于理解Android中的IPC機(jī)制能夠提供較好的幫助。Android系統(tǒng)基本上可以看做是一個(gè)基于Binder機(jī)制的C/S架構(gòu),對(duì)于Binder機(jī)制的理解相對(duì)比較復(fù)雜,如果能夠通過具體的例子入手會(huì)比較容易理解。
Android的通信體制架構(gòu)
Android的通信機(jī)制基本上可以看做是Client、Server和ServiceManager三者之間的交互:
在這些交互的過程中,Android系統(tǒng)都是使用的Binder來進(jìn)行通信。
MediaServer入口函數(shù)
MS是一個(gè)可執(zhí)行程序,它的入口函數(shù)是main函數(shù),所在文件位置:frameworks\base\media\mediaserver\main_mediaserver.cpp?
代碼如下:
可以看到,在main函數(shù)中,
ProcessState類的分析
文件位置:frameworks\base\libs\binder\ProcessState.cpp?
self方法:在main函數(shù)中,我們調(diào)用了self方法得到了一個(gè)ProcessState實(shí)例,下面我們來看看這個(gè)方法
可以看到,不出所料,ProcessState使用的就是單例模式。?
接下來我們來看一看ProcessState的構(gòu)造函數(shù):
可以看到,在構(gòu)造函數(shù)中首先調(diào)用了open_driver函數(shù)并將返回值賦給了mDriverFD,讓我們來看看這個(gè)函數(shù):
<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">static <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> open_driver() {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> fd = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">open</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/dev/binder"</span>, O_RDWR);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (fd >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">fcntl</span>(fd, F_SETFD, FD_CLOEXEC);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> vers;status_t result = ioctl(fd, BINDER_VERSION, &vers);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result == -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {ALOGE(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Binder ioctl to obtain version failed: <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%s</span>"</span>, strerror(errno));<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">close</span>(fd);fd = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> || vers != BINDER_CURRENT_PROTOCOL_VERSION) {ALOGE(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Binder driver protocol does not match user space protocol!"</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">close</span>(fd);fd = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;}size_t maxThreads = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15</span>;result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result == -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {ALOGE(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Binder ioctl to set max threads failed: <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%s</span>"</span>, strerror(errno));}} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {ALOGW(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Opening '/dev/binder' failed: <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%s</span>\n"</span>, strerror(errno));}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> fd; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul>可以看到open_driver函數(shù)主要是打開了/dev/binder這個(gè)設(shè)備并返回了這個(gè)設(shè)備的fd。
接下來我繼續(xù)回到構(gòu)造函數(shù)中,在mDriverFD中保存了這個(gè)設(shè)備的fd,接著我們又對(duì)其他的成員變量做了一些初始化,然后調(diào)用mmap函數(shù)為Binder設(shè)備開辟一塊內(nèi)存由于接收數(shù)據(jù)。
總結(jié)一下,我們的ProcessState類的任務(wù):
defaultServiceManager函數(shù)分析
文件位置:frameworks\base\libs\binder\IServiceManager.cpp
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">sp<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>IServiceManager<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> defaultServiceManager() {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (gDefaultServiceManager <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> gDefaultServiceManager;{AutoMutex _l(gDefaultServiceManagerLock);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (gDefaultServiceManager <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">==</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>) {gDefaultServiceManager <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> interface_cast<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>IServiceManager<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span>(ProcessState<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::self</span>()<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>getContextObject(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>));}}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> gDefaultServiceManager; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>可以看到gDefaultServiceManager函數(shù)主要是對(duì)gDefaultServiceManager 進(jìn)行賦值,首先我們來看看這個(gè)函數(shù)的傳入?yún)?shù): ProcessState::self()->getContextObject(NULL)
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">sp<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>IBinder<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> ProcessState<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::getContextObject</span>(const sp<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>IBinder<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">>&</span> caller) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> getStrongProxyForHandle(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); }sp<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>IBinder<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> ProcessState<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::getStrongProxyForHandle</span>(int32_t <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">handle</span>) {sp<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>IBinder<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> result;AutoMutex _l(mLock);handle_entry<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> e <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> lookupHandleLocked(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">handle</span>);<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (e <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>) {<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 如果現(xiàn)在不存在或者我們不能得到它的引用時(shí),我們需要?jiǎng)?chuàng)建一個(gè)新的BpBinder, </span>IBinder<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span> b <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> e<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>binder;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (b <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">==</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">||</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!</span>e<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>refs<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>attemptIncWeak(this)) {b <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> BpBinder(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">handle</span>); e<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>binder <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> b;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (b) e<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>refs <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> b<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>getWeakRefs();result <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> b;} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {result<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>force_set(b);e<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>refs<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>decWeak(this);}}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> result; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li></ul>可以看到其實(shí)我們返回了一個(gè)BpBinder(handle);handle的值為0。
interface_cast看起來像一個(gè)強(qiáng)制類型轉(zhuǎn)換,其實(shí)是一個(gè)模板函數(shù),下面我們來看看它的廬山真面目:
<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">template</span><<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typename</span> INTERFACE> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">inline</span> sp<INTERFACE> interface_cast(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> sp<IBinder>& obj) {<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> INTERFACE::asInterface(obj); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul> 我們傳入的模板是IServiceManager,則實(shí)際上調(diào)用的就是IServiceManager的asInterface方法。?
asInterface方法的聲明和實(shí)現(xiàn)實(shí)際上是通過兩個(gè)宏定義實(shí)現(xiàn)的,位于IInterface.h文件中:
將INTERFACE替換為IServiceManager后可以得到:
<code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">static const <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">android:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:String16</span> descriptor; static <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">android:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:sp<IServiceManager></span> asInterface( const <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">android:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:sp<android</span><span class="hljs-constant" style="box-sizing: border-box;">::IBinder</span>>& obj); virtual const <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">android:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:String16&</span> getInterfaceDescriptor() const; <span class="hljs-constant" style="box-sizing: border-box;">IServiceManager</span>(); virtual ~<span class="hljs-constant" style="box-sizing: border-box;">IServiceManager</span>(); const <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">android:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:String16</span> <span class="hljs-constant" style="box-sizing: border-box;">IServiceManager::</span>descriptor(<span class="hljs-constant" style="box-sizing: border-box;">NAME</span>); const <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">android:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:String16&</span> <span class="hljs-constant" style="box-sizing: border-box;">IServiceManager::</span>getInterfaceDescriptor() const { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-constant" style="box-sizing: border-box;">IServiceManager::</span>descriptor; } <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">android:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:sp<IServiceManager></span> <span class="hljs-constant" style="box-sizing: border-box;">IServiceManager::</span>asInterface( const <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">android:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:sp<android</span><span class="hljs-constant" style="box-sizing: border-box;">::IBinder</span>>& obj) { <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">android:</span><span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:sp<IServiceManager></span> intr; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (obj != <span class="hljs-constant" style="box-sizing: border-box;">NULL</span>) { intr = static_cast<<span class="hljs-constant" style="box-sizing: border-box;">IServiceManager</span>*>( obj->queryLocalInterface( <span class="hljs-constant" style="box-sizing: border-box;">IServiceManager::</span>descriptor).get()); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (intr == <span class="hljs-constant" style="box-sizing: border-box;">NULL</span>) { intr = new <span class="hljs-constant" style="box-sizing: border-box;">BpServiceManager</span>(obj); } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> intr; } <span class="hljs-constant" style="box-sizing: border-box;">IServiceManager::IServiceManager</span>() { } <span class="hljs-constant" style="box-sizing: border-box;">IServiceManager::</span>~<span class="hljs-constant" style="box-sizing: border-box;">IServiceManager</span>() { } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li></ul> 可以看到asInterface方法最終實(shí)際上返回了一個(gè)BpServiceManager對(duì)象。?
總結(jié)一下defaultServiceManager方法的工作:
類關(guān)系總結(jié)
看到這里,已經(jīng)有點(diǎn)眼花繚亂了,又是IBinder,又是IServiceManager,又是BpBinder,又是BpServiceManager,是時(shí)候來總結(jié)一下這些類的關(guān)系了,翻了一下這些類,下面用一個(gè)不標(biāo)準(zhǔn)的UML圖來說明一下:?
需要注意的是:
總結(jié)
以上是生活随笔為你收集整理的Android源码分析--MediaServer源码分析(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android mediaRecorde
- 下一篇: Android源码分析--MediaSe