Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 四極管: android4.2 大容量存儲及掛載PC(一)

四極管: android4.2 大容量存儲及掛載PC(一)

編輯:關於Android編程

[cpp]     USB On-The-Go and Embedded Host Virtually every portable device now uses USB for PC connectivity. As these products increase in popularity, there is a growing need for them to communicate both with USB peripherals and directly with each other when a PC is not available. There is also an increase in the number of other, non-PC hosts (Embedded Hosts) which support USB in order to connect to USB peripherals.      先看android VOLD:   [cpp]   root@ubuntu:/cm10/4.2/system/vold# ls   [cpp]   Android.mk           Devmapper.h       logwrapper.c        Process.cpp       Volume.cpp        Asec.h               DirectVolume.cpp  Loop.cpp            Process.h         Volume.h        CleanSpec.mk         DirectVolume.h    Loop.h              ResponseCode.cpp  VolumeManager.cpp        CommandListener.cpp  Ext4.cpp          main.cpp            ResponseCode.h    VolumeManager.h        CommandListener.h    Ext4.h            NetlinkHandler.cpp  tests             Xwarp.cpp        cryptfs.c            Fat.cpp           NetlinkHandler.h    vdc.c             Xwarp.h        cryptfs.h            Fat.h             NetlinkManager.cpp  VoldCommand.cpp        Devmapper.cpp        hash.h            NetlinkManager.h    VoldCommand.h   簡單梳理一下,在vold中處理otg,將需要與PC機共享的磁盤設備寫到一個文件裡面,作為一個標志,再廣播給上層,傳播一個大容量存儲的狀態。 查看源碼: [cpp]   vi ./CommandListener.cpp   [cpp]   #define MASS_STORAGE_FILE_PATH  "/sys/class/android_usb/android0/f_mass_storage/lun/file"   //標志文件    1、連接PC部分。 在該函數中做分支解析: [cpp]   int CommandListener::VolumeCmd::runCommand(SocketClient *cli,                                                            int argc, char **argv)         [cpp]   else if (!strcmp(argv[1], "share")) {              if (argc != 4) {                  cli->sendMsg(ResponseCode::CommandSyntaxError,                          "Usage: volume share <path> <method>", false);                  return 0;              }              rc = vm->shareVolume(argv[2], argv[3]);   //進入shareVolume函數對各狀態進行判斷,其中可判斷INAND或SD卡狀態,如果不存在或者忙狀態,則返回錯誤值。     具體看看shareVolume函數如何實現: [cpp]  vi VoldCommand.cpp       [cpp]  int VolumeManager::shareVolume(const char *label, const char *method) {          Volume *v = lookupVolume(label);               if (!v) {              errno = ENOENT;              return -1;          }               /*          * Eventually, we'll want to support additional share back-ends,          * some of which may work while the media is mounted. For now,          * we just support UMS          */       if (strcmp(method, "ums")) {              errno = ENOSYS;              return -1;          }               if (v->getState() == Volume::State_NoMedia) {              errno = ENODEV;              return -1;          }               if (v->getState() != Volume::State_Idle) {              // You need to unmount manually befoe sharing              errno = EBUSY;              return -1;          }               if (mVolManagerDisabled) {              errno = EBUSY;              return -1;          }        /*getShareDevice函數直接返回SD卡的設備號,部分版本該函數為getDiskDeve*/‍        dev_t d = v->getShareDevice();          if ((MAJOR(d) == 0) && (MINOR(d) == 0)) {              // This volume does not support raw disk access              errno = EINVAL;              return -1;          }               int fd;          char nodepath[255];          snprintf(nodepath,                   sizeof(nodepath), "/dev/block/vold/%d:%d",                   MAJOR(d), MINOR(d));        /*重要的文件讀寫函數在這裡體現,PC機欲識別android設備中的存儲器,需將SD卡的設備節點路徑寫到MASS_STORAGE_FILE_PATH 文件中去,打開大容量存儲功能*/       if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {              SLOGE("Unable to open ums lunfile (%s)", strerror(errno));              return -1;          }               if (write(fd, nodepath, strlen(nodepath)) < 0) {              SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));              close(fd);              return -1;          }               close(fd);         ​         v->handleVolumeShared();   /*該函數在Volume中,在子類DirectVolume中實現,廣播ums狀態。*/       if (mUmsSharingCount++ == 0) {   /*4.0以上的版本增加了一下的判斷*/           FILE* fp;              mSavedDirtyRatio = -1; // in case we fail              if ((fp = fopen("/proc/sys/vm/dirty_ratio", "r+"))) {                  char line[16];                  if (fgets(line, sizeof(line), fp) && sscanf(line, "%d", &mSavedDirtyRatio)) {                      fprintf(fp, "%d\n", mUmsDirtyRatio);                  } else {                      SLOGE("Failed to read dirty_ratio (%s)", strerror(errno));                  }                  fclose(fp);              } else {                  SLOGE("Failed to open /proc/sys/vm/dirty_ratio (%s)", strerror(errno));              }          }          return 0;      }    二、斷開PC部分 [cpp]   int VolumeManager::unshareVolume(const char *label, const char *method) {       Volume *v = lookupVolume(label);       if (!v) {           errno = ENOENT;           return -1;       }       if (strcmp(method, "ums")) {           errno = ENOSYS;           return -1;       }       if (v->getState() != Volume::State_Shared) {           errno = EINVAL;           return -1;       }       int fd;       if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) {           SLOGE("Unable to open ums lunfile (%s)", strerror(errno));           return -1;       }    /*斷開連接,使用ums模式,磁盤不能多處操作,只能使用PC或者只是使用android設備,將控制權交給PC機,斷開時將MASS_STORAGE_FILE_PATH 寫為空值。後期升級為MTP方式,可實現同時控制。*/       char ch = 0;       if (write(fd, &ch, 1) < 0) {           SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));           close(fd);           return -1;       }       close(fd);   /*和連接電腦一樣,如下函數為廣播OTG斷開狀態*/       v->handleVolumeUnshared();       if (--mUmsSharingCount == 0 && mSavedDirtyRatio != -1) {           FILE* fp;           if ((fp = fopen("/proc/sys/vm/dirty_ratio", "r+"))) {               fprintf(fp, "%d\n", mSavedDirtyRatio);               fclose(fp);           } else {               SLOGE("Failed to open /proc/sys/vm/dirty_ratio (%s)", strerror(errno));           }           mSavedDirtyRatio = -1;       }       return 0;   }   3、將狀態廣播Framework [cpp]   vi ./CommandListener.cpp   [cpp]   if (!rc) {         cli->sendMsg(ResponseCode::CommandOkay, "volume operation succeeded", false);     } else {         int erno = errno;         rc = ResponseCode::convertFromErrno();         cli->sendMsg(rc, "volume operation failed", true);     }       接下來往kernel方向分析傳入的接口。
  1. 上一頁:
  2. 下一頁:
Copyright © Android教程網 All Rights Reserved