Android源码分析--MediaServer源码分析(一)
MediaServer中包括了系統中的許多重要的Server:
- AudioFlinger:音頻系統中的核心服務
- AudioPolicyService:音頻系統中關于音頻策略的重要服務
- MediaPlayerService:多媒體系統中的重要服務
- CameraService:有關照相和攝像的重要服務
同時,分析MediaServer對于理解Android中的IPC機制能夠提供較好的幫助。Android系統基本上可以看做是一個基于Binder機制的C/S架構,對于Binder機制的理解相對比較復雜,如果能夠通過具體的例子入手會比較容易理解。
Android的通信體制架構
Android的通信機制基本上可以看做是Client、Server和ServiceManager三者之間的交互:
在這些交互的過程中,Android系統都是使用的Binder來進行通信。
MediaServer入口函數
MS是一個可執行程序,它的入口函數是main函數,所在文件位置:frameworks\base\media\mediaserver\main_mediaserver.cpp?
代碼如下:
可以看到,在main函數中,
ProcessState類的分析
文件位置:frameworks\base\libs\binder\ProcessState.cpp?
self方法:在main函數中,我們調用了self方法得到了一個ProcessState實例,下面我們來看看這個方法
可以看到,不出所料,ProcessState使用的就是單例模式。?
接下來我們來看一看ProcessState的構造函數:
可以看到,在構造函數中首先調用了open_driver函數并將返回值賦給了mDriverFD,讓我們來看看這個函數:
<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函數主要是打開了/dev/binder這個設備并返回了這個設備的fd。
接下來我繼續回到構造函數中,在mDriverFD中保存了這個設備的fd,接著我們又對其他的成員變量做了一些初始化,然后調用mmap函數為Binder設備開辟一塊內存由于接收數據。
總結一下,我們的ProcessState類的任務:
defaultServiceManager函數分析
文件位置: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函數主要是對gDefaultServiceManager 進行賦值,首先我們來看看這個函數的傳入參數: 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;">// 如果現在不存在或者我們不能得到它的引用時,我們需要創建一個新的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>可以看到其實我們返回了一個BpBinder(handle);handle的值為0。
interface_cast看起來像一個強制類型轉換,其實是一個模板函數,下面我們來看看它的廬山真面目:
<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,則實際上調用的就是IServiceManager的asInterface方法。?
asInterface方法的聲明和實現實際上是通過兩個宏定義實現的,位于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方法最終實際上返回了一個BpServiceManager對象。?
總結一下defaultServiceManager方法的工作:
類關系總結
看到這里,已經有點眼花繚亂了,又是IBinder,又是IServiceManager,又是BpBinder,又是BpServiceManager,是時候來總結一下這些類的關系了,翻了一下這些類,下面用一個不標準的UML圖來說明一下:?
需要注意的是:
總結
以上是生活随笔為你收集整理的Android源码分析--MediaServer源码分析(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android mediaRecorde
- 下一篇: Android源码分析--MediaSe