Android sdcard分区加载过程

Android sdcard分区加载过程

加载分区

MountService()

挂载服务

MountService启动

frameworks/base/services/java/com/android/server/MountService.java

1338     public MountService(Context context) {

1339         mContext = context;

1340

1341         synchronized (mVolumesLock) {

1342             readStorageListLocked();

1343         }

1344

1345         // XXX: This will go away soon infavor of IMountServiceObserver

1346         mPms = (PackageManagerService)ServiceManager.getService("package");

1347

1348         HandlerThread hthread = newHandlerThread(TAG);

1349         hthread.start();

1350         mHandler = newMountServiceHandler(hthread.getLooper());

1351

1352         // Watch for user changes

1353         final IntentFilter userFilter = new IntentFilter();

1354        userFilter.addAction(Intent.ACTION_USER_ADDED);

1355        userFilter.addAction(Intent.ACTION_USER_REMOVED);

1356        mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);

1357

1358         // Watch for USB changes on primaryvolume

1359         final StorageVolume primary =getPrimaryPhysicalVolume();

1360         if (primary != null &&primary.allowMassStorage()) {

1361             mContext.registerReceiver(

1362                     mUsbReceiver, new IntentFilter(UsbManager.ACTION_USB_STATE),null, mHandler);

1363         }

1364

读取需要加载的分区

1187     private void readStorageListLocked() {

1188         mVolumes.clear();

1189         mVolumeStates.clear();

1190

1191         Resources resources = mContext.getResources();

1192

1193        int id = com.android.internal.R.xml.storage_list;

1194         XmlResourceParser parser =resources.getXml(id);

1195         AttributeSet attrs =Xml.asAttributeSet(parser);

1196

1197         try {

1198             XmlUtils.beginDocument(parser,TAG_STORAGE_LIST);

1199             while (true) {

1200                 XmlUtils.nextElement(parser);

1201

1202                 String element =parser.getName();

1203                 if (element == null) break;

1204

1205                 if(TAG_STORAGE.equals(element)) {

1206                     TypedArray a =resources.obtainAttributes(attrs,

1207                            com.android.internal.R.styleable.Storage);

1208

1209                     String path = a.getString(

1210                            com.android.internal.R.styleable.Storage_mountPoint);

1211                     int descriptionId =a.getResourceId(

1212                            com.android.internal.R.styleable.Storage_storageDescription, -1);

1213                     CharSequence description =a.getText(

1214                            com.android.internal.R.styleable.Storage_storageDescription);

1215                     boolean primary =a.getBoolean(

1216                             com.android.internal.R.styleable.Storage_primary,false);

1217                     boolean removable =a.getBoolean(

1218                            com.android.internal.R.styleable.Storage_removable, false);

1219                     boolean emulated =a.getBoolean(

1220                            com.android.internal.R.styleable.Storage_emulated, false);

1221                     int mtpReserve = a.getInt(

1222                            com.android.internal.R.styleable.Storage_mtpReserve, 0);

1223                     boolean allowMassStorage = a.getBoolean(

1224                            com.android.internal.R.styleable.Storage_allowMassStorage, false);

1225                     // resource parser doesnot support longs, so XML value is in megabytes

1226                     long maxFileSize = a.getInt(

1227                            com.android.internal.R.styleable.Storage_maxFileSize, 0) * 1024L *1024L;

1228

1229                     Slog.d(TAG, "gotstorage path: " + path + " description: " + description +

1230                             " primary:" + primary + " removable: " + removable +

1231                             " emulated:" + emulated +  " mtpReserve:" + mtpReserve +

1232                             "allowMassStorage: " + allowMassStorage +

1233                             "maxFileSize: " + maxFileSize);

 

frameworks/base/core/res/res/xml/storage_list.xml

<StorageListxmlns:android="http://schemas.android.com/apk/res/android">

<storage android:mountPoint="/storage/sdcard0"

android:storageDescription="@string/storage_internal"

android:primary="true"

android:emulated="false"

android:removable="true"

android:allowMassStorage="true" />

<storage android:mountPoint="/storage/usbotg"

android:storageDescription="@string/storage_usb"

android:removable="true"

android:primary="false"/>

</StorageList>

 

处理系统消息,进行分区加载

406     class MountServiceHandlerextends Handler {

407        ArrayList<UnmountCallBack> mForceUnmounts = newArrayList<UnmountCallBack>();

408        boolean mUpdatingStatus = false;

409

410        MountServiceHandler(Looper l) {

411            super(l);

412        }

413

414        @Override

415        public void handleMessage(Message msg) {

416            switch (msg.what) {

417                 case H_UNMOUNT_PM_UPDATE: {

418                     if (DEBUG_UNMOUNT)Slog.i(TAG, "H_UNMOUNT_PM_UPDATE");

419                     UnmountCallBack ucb =(UnmountCallBack) msg.obj;

420                     mForceUnmounts.add(ucb);

421                     if (DEBUG_UNMOUNT)Slog.i(TAG, " registered = " + mUpdatingStatus);

422                     // Register only ifneeded.

423                     if (!mUpdatingStatus) {

424                         if (DEBUG_UNMOUNT)Slog.i(TAG, "Updating external media status on PackageManager");

425                         mUpdatingStatus =true;

426                        mPms.updateExternalMediaStatus(false, true);

427                     }

428                     break;

429                 }

响应系统ready消息,进行分区挂载

489                 case H_SYSTEM_READY: {

490                     try {

491                         handleSystemReady();

492                     } catch (Exception ex) {

493                         Slog.e(TAG,"Boot-time mount exception", ex);

494                     }

495                     break;

496                 }

497            }

498        }

499    };

526     private void handleSystemReady() {

527         // Snapshot current volume states sinceit‘s not safe to call into vold

528        // while holding locks.

529        final HashMap<String, String> snapshot;

530        synchronized (mVolumesLock) {

531            snapshot = new HashMap<String, String>(mVolumeStates);

532        }

533

534        for (Map.Entry<String, String> entry : snapshot.entrySet()) {

535            final String path = entry.getKey();

536            final String state = entry.getValue();

537

538            if (state.equals(Environment.MEDIA_UNMOUNTED)) {

 539                 int rc = doMountVolume(path);

540                 if (rc !=StorageResultCode.OperationSucceeded) {

541                     Slog.e(TAG,String.format("Boot-time mount failed (%d)",

542                             rc));

543                 }

544            } else if (state.equals(Environment.MEDIA_SHARED)) {

545                 /*

546                  * Bootstrap UMS enabled statesince vold indicates

547                  * the volume is shared(runtime restart while ums enabled)

548                  */

549                 notifyVolumeStateChange(null,path, VolumeState.NoMedia,

550                         VolumeState.Shared);

551            }

552        }

553

554         // Push mounted state for all emulatedstorage

555        synchronized (mVolumesLock) {

556            for (StorageVolume volume : mVolumes) {

557                 if (volume.isEmulated()) {

558                    updatePublicVolumeState(volume, Environment.MEDIA_MOUNTED);

559                 }

560            }

561        }

562

563        /*

564         * If UMS was connected on boot, send the connected event

565         * now that we‘re up.

566         */

567        if (mSendUmsConnectedOnBoot) {

568            sendUmsIntent(true);

569            mSendUmsConnectedOnBoot = false;

570        }

571    }

挂载分区

977     private int doMountVolume(String path) {

978        int rc = StorageResultCode.OperationSucceeded;

979

980        final StorageVolume volume;

981        synchronized (mVolumesLock) {

982            volume = mVolumesByPath.get(path);

983        }

984

985        if (DEBUG_EVENTS) Slog.i(TAG, "doMountVolume: Mouting " +path);

986        try {

 987            mConnector.execute("volume", "mount", path);

988        } catch (NativeDaemonConnectorException e) {

989            /*

990              * Mount failed for some reason

991              */

992            String action = null;

993            int code = e.getCode();

994            if (code == VoldResponseCode.OpFailedNoMedia) {

995                 /*

996                  * Attempt to mount but nomedia inserted

997                  */

998                 rc = StorageResultCode.OperationFailedNoMedia;

999            } else if (code == VoldResponseCode.OpFailedMediaBlank) {

1000                 if (DEBUG_EVENTS) Slog.i(TAG," updating volume state :: media nofs");

1379         mConnector= new
NativeDaemonConnector
(this,"vold",MAX_CONTAINERS * 2, VOLD_TAG, 25);

frameworks/base/services/java/com/android/server/NativeDaemonConnector.java

通过socket向vold发送命令

Vold模块

/system/vold/main.cpp

46 int main() {

47

48    VolumeManager *vm;

49    CommandListener *cl;

50    NetlinkManager *nm;

51

52    SLOGI("Vold 2.1 (the revenge) firing up");

53

54    mkdir("/dev/block/vold", 0755);

55

56    /* For when cryptfs checks and mounts an encrypted filesystem */

57    klog_set_level(6);

58

59    /* Create our singleton managers */

60    if (!(vm = VolumeManager::Instance())) {

61        SLOGE("Unable to create VolumeManager");

62        exit(1);

63    };

64

65    if (!(nm = NetlinkManager::Instance())) {

66        SLOGE("Unable to create NetlinkManager");

67        exit(1);

68    };

69

70

71    cl = new CommandListener();

设置命令响应

 72    vm->setBroadcaster((SocketListener *) cl);

 73    nm->setBroadcaster((SocketListener *) cl);

/system/vold/CommandListener.cpp

121 intCommandListener::VolumeCmd::runCommand(SocketClient*cli,

122                                                      int argc, char **argv) {

123     dumpArgs(argc, argv, -1);

124

125     if (argc < 2) {

126        cli->sendMsg(ResponseCode::CommandSyntaxError, "MissingArgument", false);

127         return 0;

128     }

129

130     VolumeManager *vm =VolumeManager::Instance();

131     int rc = 0;

132

133     if (!strcmp(argv[1], "list")) {

134         return vm->listVolumes(cli);

135     } else if (!strcmp(argv[1],"debug")) {

136         if (argc != 3 || (argc == 3 &&(strcmp(argv[2], "off") && strcmp(argv[2], "on")))){

137            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volumedebug <off/on>", false);

138             return 0;

139         }

140         vm->setDebug(!strcmp(argv[2],"on") ? true : false);

响应mount命令

141    } else if (!strcmp(argv[1], "mount")) {

142        if (argc != 3) {

143            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volumemount <path>", false);                                                                                        

144             return 0;

145        }

146        rc = vm->mountVolume(argv[2]);

147     } else if (!strcmp(argv[1],"unmount")) {

148         if (argc < 3 || argc > 4 ||

149            ((argc == 4 &&strcmp(argv[3], "force")) &&

150             (argc == 4 &&strcmp(argv[3], "force_and_revert")))) {

151            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: volumeunmount <path> [force|force_and_revert]", false);

152             return 0;

153         }

154

155         bool force = false;

156         bool revert = false;

157         if (argc >= 4 &&!strcmp(argv[3], "force")) {

158             force = true;

/system/vold/VolumeManager.cpp

1272 intVolumeManager::mountVolume(const char *label) {

1273     Volume *v = lookupVolume(label);

1274

1275     if (!v) {

1276         errno = ENOENT;

1277         return -1;

1278     }

1279

1280    return v->mountVol();

1281 }

/system/vold/Volume.cpp

315 intVolume::mountVol() {

442         if (!strcmp(getMountpoint(),"/storage/usbotg")){

443             if (Fat::doMount(devicePath,getMountpoint(), false, false, false,

444                     AID_SYSTEM, AID_MEDIA_RW,0000, true)) {

445                 SLOGE("%s failed to mountvia VFAT (%s)\n", devicePath, strerror(errno));

446                 continue;

447             }

448         }else{

449             if (Fat::doMount(devicePath,getMountpoint(), false, false, false,

450                     AID_MEDIA_RW,AID_MEDIA_RW, 0007, true)) {

451                 SLOGE("%s failed to mountvia VFAT (%s)\n", devicePath, strerror(errno));

452                 continue;

453             }

454         }

115 int Fat::doMount(const char *fsPath, const char*mountPoint,

116                  bool ro, bool remount, boolexecutable,

117                  int ownerUid, int ownerGid,int permMask, bool createLost) {

118     int rc;

119     unsigned long flags;

120     char mountData[255];

121

122     flags = MS_NODEV | MS_NOSUID | MS_DIRSYNC;

123

124     flags |= (executable ? 0 : MS_NOEXEC);

125     flags |= (ro ? MS_RDONLY : 0);

126     flags |= (remount ? MS_REMOUNT : 0);

127

128     /*

129      * Note: This is a temporary hack. If thesampling profiler is enabled,

130      * we make the SD card world-writable soany process can write snapshots.

131      *

132      * TODO: Remove this code once we have adrop box in system_server.

133      */

134     char value[PROPERTY_VALUE_MAX];

135    property_get("persist.sampling_profiler", value,"");

136     if (value[0] == ‘1‘) {

137         SLOGW("The SD card isworld-writable because the"

138             " ‘persist.sampling_profiler‘ systemproperty is set to ‘1‘.");

139         permMask = 0;

140     }

141

142     sprintf(mountData,

143            "utf8,uid=%d,gid=%d,fmask=%o,dmask=%o,shortname=mixed",

144             ownerUid, ownerGid, permMask, permMask);

145

146     rc = mount(fsPath, mountPoint,"vfat", flags, mountData);

147

148     if (rc && errno == EROFS) {

149         SLOGE("%s appears to be a readonly filesystem - retrying mount RO", fsPath);

150         flags |= MS_RDONLY;

Linux api挂载分区

 

151         rc = mount(fsPath, mountPoint,"vfat", flags, mountData);

152     }

153

154     if (rc == 0 && createLost) {

155         char *lost_path;

156         asprintf(&lost_path,"%s/LOST.DIR", mountPoint);

157         if (access(lost_path, F_OK)) {

158             /*

159              * Create a LOST.DIR in the rootso we have somewhere to put

160              * lost cluster chains (fsck_msdosdoesn‘t currently do this)

161              */

162             if (mkdir(lost_path, 0755)) {

时间: 2024-11-05 02:19:20

Android sdcard分区加载过程的相关文章

47.Android View的加载过程 (转)

原文地址:http://blog.csdn.net/xyz_lmn/article/details/20122303 大家都知道Android中加载view是从Activity的onCreate方法调用setContentView开始的,那么View的具体加载过程又是怎么的呢?这一节我们做一下分析. 首先追踪一下代码: Activity中: [java] view plain copy print? public void setContentView(int layoutResID) { ge

Android 下分批加载数据以及listView使用过程中的优化

需求:在开发过程中,listview加载的数据如果比较大,这时为了提高用户体验感,我们应该事先分批加载以及下拉刷新功能 1.首先,数据访问层需要提供分批加载功能的接口, 代码如下: package com.zaizai.safty.db.dao; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.

Android系统定制——Download Android System 及加载system镜像文件

定制android系统(配置及相关系统的镜像文件),具体可参考:Driver_All_in_One_V1.0--MT6735_6753.pdf文档,特别需要理解的是Download部分. 与之对应的软件是:Smart Phone Flash Tool,一般是在菜单栏的Download部分进行选择操作. Download-agent(下载代理):选择 \升级固件与升级固件的工具\SP_Flash_Tool_exe_Windows_v5.1536.00.000 文件(通常不用特别选择,使用默认的即可

Android图片异步加载之Android-Universal-Image-Loader

将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就顺便整理记录下来,作为这一个多月来博客的重新开火做饭吧.从今天起我会陆续恢复博客的更新,也希望大家继续支持. 今天要介绍的是Github上一个使用非常广泛的图片异步加载库Android-Universal-Image-Loader,该项目的功能十分强大,可以说是我见过的目前功能最全.性能最优的图片异

Android图片异步加载之Android-Universal-Image-Loader(转)

今天要介绍的是Github上一个使用非常广泛的图片异步加载库Android-Universal-Image-Loader,该项目的功能十分强大,可以说是我见过的目前功能最全.性能最优的图片异步加载解决方案.做Android的同学都知道,Android加载大量图片时,由于系统分配给图片加载的内存大小有限,所以,如果加载图片量非常大的话容易报OOM异常,关于这个异常已经有不少解决方案了,我就不赘述.下面就简要介绍下这个开源项目的主要功能和使用: 一.功能概要 多线程图片加载: 灵活更改ImageLo

Android 图像异步加载之Android-Universal-Image-Loader

概述: 项目地址:https://github.com/nostra13/Android-Universal-Image-Loader UIL(Universal-Image-Loader)异步图像加载.缓存和显示.这个图片异步加载并缓存的类已经被很多开发者所使用,是最常用的几个开源库之一,主流的应用,随便反编译几个火的项目,都可以见到它的身影. 同类类库(Picasso),尽管Picasso拥有更好的API,但其缺乏自定义.而使用UIL构建器几乎可以配置所有(其中最重要的就是在抓取和缓存大型图

图片--Android有效解决加载大图片时内存溢出的问题

Android有效解决加载大图片时内存溢出的问题 博客分类: Android Android游戏虚拟机算法JNI 尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存. 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView

Android图片异步加载之Android-Universal-Image-Loader类库的使用

Android开发中我们会经常遇到图片过多或操作不当造成Out of Memory异常,有时虽然是解决了这个问题但却会影响程序的运行效率,例如:当用户在快速滑动滚动条的过程中,我们程序在仍在艰难的加载服务器端的图片,这样给用户造成了极不好的体验.其实网络上关于图片的异步加载和缓存的讲解很多,但是其实,写一个这方面的程序还是比较麻烦的,要考虑多线程,缓存,内存溢出等很多方面,针对这一广大开发者都会遇到的问题,一些牛人们已经帮我们解决了这一问题,今天我为大家介绍一款很流行的开源类库,可以很很好的解决

Android上拉加载更多ListView——PulmListView

思路 今天带大家实现一个上拉加载更多的ListView.GitHub传送门:PulmListView, 欢迎大家fork&&star. 先带大家理一下思路, 如果我们要实现一个上拉加载更多的ListView, 我们需要实现的功能包括: 一个自定义的ListView, 并且该ListView能够判断当前是否已经处于最底部. 一个自定义的FooterView, 用于在ListView加载更多的过程中进行UI展示. 关联FooterView和ListView, 包括加载时机判断.FooterVi