现在的位置: 首页 > 综合 > 正文

Android磁盘管理-之vold源码分析(4)

2013年09月20日 ⁄ 综合 ⁄ 共 2908字 ⁄ 字号 评论关闭

作者:gzshun. 原创作品,转载请标明出处!

上篇文章分析到了NetlinkHandler类中的onEvent函数,该函数由NetlinkListener::onDataAvailable函数调用,当SocketListener类监听到内核的uevent事件,调用该函数,之后的事情交给onEvent来负责。


file:system/vold/NetlinkHandler.cpp
现在来说onEvent函数,在vold中,磁盘的热插拔事件都是通过上述那些间接的过程来调用到

该函数,该函数再调用vold中的处理事件的函数,这样vold就能得到最新的磁盘热插拔事件;

void NetlinkHandler::onEvent(NetlinkEvent *evt) {  
    VolumeManager *vm = VolumeManager::Instance();  
    const char *subsys = evt->getSubsystem();  
      
    if (!subsys) {  
        SLOGW("No subsystem found in netlink event");  
        return;  
    }  
      
    if (!strcmp(subsys, "block")) {  
        vm->handleBlockEvent(evt);  
    } else if (!strcmp(subsys, "switch")) {  
        vm->handleSwitchEvent(evt);  
    } else if (!strcmp(subsys, "battery")) {  
    } else if (!strcmp(subsys, "power_supply")) {  
    }  
}  

file:system/vold/VolumeManager.cpp
vm->handleSwitchEvent(evt)函数涉及的比较少,先来分析;
该函数是用来处理大容量存储设备,也就是otg功能,NetlinkEvent类提供的findParam函数
可以获取到该事件的具体信息,比如设备路径,设备名称,状态,分区数量等等。。
如果判断是“online”状态,那么就向framework发送状态消息。使用notifyUmsConnected函数
进行广播。

void VolumeManager::handleSwitchEvent(NetlinkEvent *evt) {  
    const char *devpath = evt->findParam("DEVPATH");  
    const char *name = evt->findParam("SWITCH_NAME");  
    const char *state = evt->findParam("SWITCH_STATE");  
      
    if (!name || !state) {  
        SLOGW("Switch %s event missing name/state info", devpath);  
        return;  
    }  
      
    if (!strcmp(name, "usb_mass_storage")) {  
        if (!strcmp(state, "online"))  {  
            notifyUmsConnected(true);  
        } else {  
            notifyUmsConnected(false);  
        }  
        } else {  
            SLOGW("Ignoring unknown switch '%s'", name);  
        }  
}  

notifyUmsConnected函数将otg的状态发送给framework,
命令为:Share method ums now available/unavailable;
getBroadcaster()->sendBroadcast()广播函数,这在main函数分析中就涉及到了,
源码:
cl = new CommandListener();
vm->setBroadcaster((SocketListener *) cl);
nm->setBroadcaster((SocketListener *) cl);
将CommandListener对象强制转换成SocketListener类型,这样cl对象就能够调用SocketListener
类的setBroadcaster广播函数;
getBroadcaster()的源码:
SocketListener *getBroadcaster() { return mBroadcaster; }
直接将刚才被强制转换成SocketListener类型返回,相当于如下:
(SocketListener *)cl->sendBroadcast(xxx);

  1. void VolumeManager::notifyUmsConnected(bool connected) {  
  2.     char msg[255];  
  3.       
  4.     if (connected) {  
  5.         mUsbMassStorageConnected = true;  
  6.     } else {  
  7.         mUsbMassStorageConnected = false;  
  8.     }  
  9.     snprintf(msg, sizeof(msg), "Share method ums now %s",   (connected ? "available" : "unavailable"));  
  10.       
  11.     getBroadcaster()->sendBroadcast(ResponseCode::ShareAvailabilityChange, msg, false);  
  12. }  


file:system/vold/ResponseCode.cpp
该类没做什么事,也就是提供一些出错标志,下面将写出出错原因;
这些标志都会在不同的操作(命令)反馈不同的值。

  1. class ResponseCode {  
  2. public:  
  3.     // 100 series - Requestion action was initiated; expect another reply  
  4.     // before proceeding with a new command.  
  5.     static const int ActionInitiated  = 100;  
  6.       
  7.     static const int VolumeListResult         = 110;  
  8.     static const int AsecListResult           = 111;  
  9.     static const int StorageUsersListResult   = 112;  
  10.       
  11.     // 200 series - Requested action has been successfully completed  
  12.     static const int CommandOkay              = 200;  
  13.     static const int ShareStatusResult        = 210;  
  14.     static const

抱歉!评论已关闭.