Android SDCard框架
Android SDCard框架,咱們修改通常涉及到四大模塊java
- Linux Kernel 用於檢測熱拔插,做爲框架開發者來講,這者不用涉及
- Vold 做爲Kernel 與 Framework 之間的橋樑
- Framework 操做Vold ,給Vold 下發操做命令
- UI 與Framework 交互,用於掛載/卸載SD卡
框架涉及的源碼位置
Vold :System/voldandroid
爲vold 提供接口:System/Netd框架
其餘涉及的部分:System/core/libsysutils/srcsocket
System/core/include/sysutilside
Framework:frameworks/base/services/java/com/android/server 函數
訪問和提供接口類:framework/base/core/java/android/os/storage/ this
可能還要參考的庫:framework/base/libs/storagespa
framework/base/native線程
UI:Settings/src/com/android/setting/deviceinfocode
SDCard UnMounted流程分析
初始化
VolumeManager, CommandListener, NetlinkManager 都是在 main()函數裏面初始化的。
其中 VolumeManager,NetlinkManager 內部採用單例模式。
(1) Class NetlinkManager 主要是建立於內核通訊的 socket,接收來自底層的信息,而後傳交給VolumeManager 處理。
(2) class CommandListener 主要收到上層 MountService 經過 doMountVolume 發來的命令,分析後,轉交給 VolumeManager 處理;VolumeManager 處理信息後,或報告給上層 MountService,
或交給 volume 執行具體操做。CommandListener在main()初始化後,以後開始監聽,會開一個線程不停的監聽來自內核的消息。
深刻main文件
在Vold 的main.cpp裏面,啓動一個線程用來監聽kernel 發出unMounted 的uevent事件,代碼:
NetlinkManager *nm;
//
NetlinkManager內部使用的單例模式
if (!(nm = NetlinkManager::Instance())) {
SLOGE(
"
Unable to create NetlinkManager
");
exit(
1);
};
//
開始監聽,從服務啓動就一直監聽
if (
nm->start()) {
SLOGE(
"
Unable to start NetlinkManager (%s)
", strerror(errno));
exit(
1);
}
NetlinkManager的start 函數是實例化了一個NetlinkHandler(繼承關係:NetlinkHandler->NetlinkListener->SocketLinstener),並調用handler 的start方法,以下代碼:
mHandler =
new NetlinkHandler(mSock);
if (
mHandler->start()) {
SLOGE(
"
Unable to start NetlinkHandler: %s
", strerror(errno));
return -
1;
}
深刻NetlinkHandler 的start函數,見代碼:
int NetlinkHandler::start() {
return
this->
startListener();
}
上面有說過NetlinkHandler實際上是SocketLinstener的子類,NetlinkHandler直接調用父類的startListener 方法,startListener開啓了一個線程用來執行threadStart函數,代碼太多,貼出主心代碼:
if (pthread_create(&mThread, NULL,
SocketListener::threadStart,
this)) {
SLOGE(
"
pthread_create (%s)
", strerror(errno));
return -
1;
}
而threadStart函數則調用了runListener方法,代碼以下:
void *SocketListener::threadStart(
void *obj) {
SocketListener *me = reinterpret_cast<SocketListener *>(obj);
me->runListener();
pthread_exit(NULL);
return NULL;
}
runListener會判斷socket 有無信息可讀,不會阻滯UI,最後調用onDataAvailable函數,代碼:
void SocketListener::runListener() {
SocketClientCollection *pendingList =
new SocketClientCollection();
//代碼有所省略
while (!pendingList->empty()) {
/* Pop the first item from the list */
it = pendingList->begin();
SocketClient* c = *it;
pendingList->erase(it);
/* Process it, if false is returned and our sockets are
* connection-based, remove and destroy it */
if (!
onDataAvailable(c) && mListen) {
/* Remove the client from our array */
pthread_mutex_lock(&mClientsLock);
for (it = mClients->begin(); it != mClients->end(); ++it) {
if (*it == c) {
mClients->erase(it);
break;
}
}
pthread_mutex_unlock(&mClientsLock);
/* Remove our reference to the client */
c->decRef();
}
}
}
}
onDataAvailable會處理來自uEvent 的命令,並最終調用onEvent函數,onDataAvailable 位於System/core/libsysutils/src/NetlinkListener.cpp 這個主要處理一些socket方法的知識,通常不用修改。
最後由Netlinklinstener 來解析 ,代碼:
bool NetlinkListener::onDataAvailable(SocketClient *cli)
{
int socket = cli->getSocket();
ssize_t count;
count = TEMP_FAILURE_RETRY(
uevent_kernel_multicast_recv(socket, mBuffer,
sizeof(mBuffer)));
if (count <
0) {
SLOGE(
"
recvmsg failed (%s)
", strerror(errno));
return
false;
}
NetlinkEvent *evt =
new NetlinkEvent();
if (!evt->decode(mBuffer, count, mFormat)) {
SLOGE(
"
Error decoding NetlinkEvent
");
}
else {
onEvent(evt);
}
delete evt;
return
true;
}
小結
NetlinkManager其實就是用來處理uEvent 命令,並最終發送到vold/NetlinkHandler 的onEvent 。