博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android SDCard UnMounted 流程分析(一)
阅读量:5231 次
发布时间:2019-06-14

本文共 3606 字,大约阅读时间需要 12 分钟。

Android SDCard框架 

Android SDCard框架,我们修改一般涉及到四大模块

  1. Linux Kernel 用于检测热拔插,作为框架开发者来说,这者不用涉及
  2. Vold 作为Kernel 与 Framework 之间的桥梁
  3. Framework 操作Vold ,给Vold 下发操作命令
  4. UI 与Framework 交互,用于挂载/卸载SD卡

框架涉及的源码位置

Vold :System/vold

        为vold 提供接口:System/Netd

        其他涉及的部分:System/core/libsysutils/src

                               System/core/include/sysutils

 

Framework:frameworks/base/services/java/com/android/server 

                 访问和提供接口类:framework/base/core/java/android/os/storage/ 

                 可能还要参考的库:framework/base/libs/storage

                                          framework/base/native

UI:Settings/src/com/android/setting/deviceinfo

 

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 。

 

 

 

 

 

转载于:https://www.cnblogs.com/TerryBlog/archive/2012/03/22/2411628.html

你可能感兴趣的文章
如何在chrome上打开SSL3.0
查看>>
应该是实例化对象的没有对属性赋值时,自动赋值为null,但不是空指针对象引用...
查看>>
从网易与淘宝的font-size思考前端设计稿与工作流
查看>>
原生HttpClient详细使用示例
查看>>
几道面试题
查看>>
搜索引擎-SHODAN
查看>>
Factory Design Pattern
查看>>
python中贪婪与非贪婪
查看>>
guava API整理
查看>>
无锁编程笔记
查看>>
jquery mobile
查看>>
sql 技巧
查看>>
在Windows环境下使用短信猫收发短信的简单配置:
查看>>
如何在vue单页应用中使用百度地图
查看>>
Ubuntu 下安装Go语言
查看>>
Application对象
查看>>
命令查看当前电脑安装所有版本.NET Core SKD
查看>>
《Photoshop CS4手绘艺术技法》
查看>>
random
查看>>
使用CSP防止XSS攻击
查看>>