Android SDCard framework
Android SDCard framework, which generally involves four modules
1. Linux Kernel is used to detect hot plugging. As a framework developer, this does not involve
2. Vold serves as a bridge between the Kernel and Framework
3. Use the Framework to operate Vold and issue operation commands to Vold.
4. UI and Framework interaction, used to mount/uninstall SD cards
Framework source code location
Vold: System/vold
Provides the vold interface: System/Netd
Others: System/core/libsysutils/src
System/core/include/sysutils
Framework: frameworks/base/services/java/com/android/server
Access and provide interface classes: framework/base/core/java/android/OS/storage/
Libraries that may also be referenced: framework/base/libs/storage
Framework/base/native
UI: Settings/src/com/android/setting/deviceinfo
SDCard UnMounted Process Analysis
Initialization
VolumeManager, CommandListener, and NetlinkManager are all initialized in the main () function.
VolumeManager and NetlinkManager adopt the singleton mode.
(1) Class NetlinkManager is mainly used to create a socket for Kernel communication. It receives information from the underlying layer and passes it to VolumeManager for processing.
(2) class CommandListener receives commands sent by MountService on the upper layer through doMountVolume, analyzes the commands, and transfers them to VolumeManager for processing. After VolumeManager processes the information, it reports the information to MountService on the upper layer,
Or hand it over to volume for specific operations. After main () is initialized, CommandListener starts listening. A thread is enabled to continuously listen to messages from the kernel.
Go deep into the main file
In main. cpp of Vold, start a thread to listen to the unMounted uevent generated by the kernel. Code:
NetlinkManager * nm;
// The Singleton mode used internally by NetlinkManager
If (! (Nm = NetlinkManager: Instance ())){
SLOGE ("Unable to create NetlinkManager ");
Exit (1 );
};
// Start listening, which has been listening since the service was started
If (nm-> start ()){
SLOGE ("Unable to start NetlinkManager (% s)", strerror (errno ));
Exit (1 );
}
The start function of NetlinkManager instantiates a NetlinkHandler (inherited relationship: NetlinkHandler-> NetlinkListener-> SocketLinstener) and calls the start method of handler. The following code:
MHandler = new NetlinkHandler (mSock );
If (mHandler-> start ()){
SLOGE ("Unable to start NetlinkHandler: % s", strerror (errno ));
Return-1;
}
Go deep into the start function of NetlinkHandler. See the Code:
Int NetlinkHandler: start (){
Return this-> startListener ();
}
As mentioned above, NetlinkHandler is actually a subclass of SocketLinstener. NetlinkHandler directly calls the startListener method of the parent class. startListener enables a thread to execute the threadStart function. There are too many codes and the main code is pasted:
If (pthread_create (& mThread, NULL, SocketListener: threadStart, this )){
SLOGE ("pthread_create (% s)", strerror (errno ));
Return-1;
}
The threadStart function calls the runListener method. The Code is as follows:
Void * SocketListener: threadStart (void * obj ){
SocketListener * me = reinterpret_cast <SocketListener *> (obj );
Me-> runListener ();
Pthread_exit (NULL );
Return NULL;
}
RunListener checks whether the socket is readable, does not block the UI, and finally calls the onDataAvailable function, code:
Void SocketListener: runListener (){
SocketClientCollection * pendingList = new SocketClientCollection ();
// The code is omitted.
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 will process commands from uEvent and finally call the onEvent function. onDataAvailable is located in System/core/libsysutils/src/NetlinkListener. cpp, which mainly deals with some knowledge about socket methods and generally does not need to be modified.
Finally, it is parsed by Netlinklinstener. The Code is as follows:
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;
}
Summary
NetlinkManager is actually an onEvent that is used to process uEvent commands and finally sent to vold/NetlinkHandler.
From Terry _ Dragon