Android6.0 MountService和vold详解(一)Mountservice的初始化

来源:互联网 发布:不用网络的游戏大全免费下载 编辑:程序博客网 时间:2024/05/20 13:10

Android6.0对存储这块的改动还是比较大的,前面我们讲过了Android5.1上相关的代码,这里我们主要讲下区别,至于相同的部分,比如通信部分就不讲了,大家感兴趣可以看我之前5.1MountService和vold相关的博客。


一、MountService实例化

我们先从MountService的实例化开始:

mSystemServiceManager.startService(MOUNT_SERVICE_CLASS);//这个是MountService的lifecycle静态类

在SystemServer中调用了上面函数,

    public <T extends SystemService> T startService(Class<T> serviceClass) {        final String name = serviceClass.getName();        Slog.i(TAG, "Starting " + name);        // Create the service.        if (!SystemService.class.isAssignableFrom(serviceClass)) {            throw new RuntimeException("Failed to create " + name                    + ": service must extend " + SystemService.class.getName());        }        final T service;        try {            Constructor<T> constructor = serviceClass.getConstructor(Context.class);            service = constructor.newInstance(mContext);//实例化        } catch (InstantiationException ex) {         ...........        // Register it.        mServices.add(service);//放入自己列表        // Start it.        try {            service.onStart();//调用onStart方法        } catch (RuntimeException ex) {            throw new RuntimeException("Failed to start service " + name                    + ": onStart threw an exception", ex);        }        return service;    }

在SystemServiceManager的

startService函数中我们看到,是将Service实例化,然后放入自己维护的一个列表,最后调用了Service的onstart函数。

    public static class Lifecycle extends SystemService {        private MountService mMountService;        public Lifecycle(Context context) {            super(context);        }        @Override        public void onStart() {            mMountService = new MountService(getContext());            publishBinderService("mount", mMountService);        }        @Override        public void onBootPhase(int phase) {            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {                mMountService.systemReady();            }        }        @Override        public void onStartUser(int userHandle) {            mMountService.onStartUser(userHandle);        }        @Override        public void onCleanupUser(int userHandle) {            mMountService.onCleanupUser(userHandle);        }    }

在静态类Lifecycle 中的onStart函数,实例化了MountService,以及调用publishBinderService函数,把它放入ServiceManager中。

下面我们先看看MountService的构造函数:几乎和之前一样,我们说下区别的地方

 public MountService(Context context) {        sSelf = this;        mContext = context;        mCallbacks = new Callbacks(FgThread.get().getLooper());//回调,后面详细说        // XXX: This will go away soon in favor of IMountServiceObserver        mPms = (PackageManagerService) ServiceManager.getService("package");        HandlerThread hthread = new HandlerThread(TAG);        hthread.start();        mHandler = new MountServiceHandler(hthread.getLooper());        // Add OBB Action Handler to MountService thread.        mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper());        // Initialize the last-fstrim tracking if necessary        File dataDir = Environment.getDataDirectory();        File systemDir = new File(dataDir, "system");        mLastMaintenanceFile = new File(systemDir, LAST_FSTRIM_FILE);        if (!mLastMaintenanceFile.exists()) {            // Not setting mLastMaintenance here means that we will force an            // fstrim during reboot following the OTA that installs this code.            try {                (new FileOutputStream(mLastMaintenanceFile)).close();            } catch (IOException e) {                Slog.e(TAG, "Unable to create fstrim record " + mLastMaintenanceFile.getPath());            }        } else {            mLastMaintenance = mLastMaintenanceFile.lastModified();        }        mSettingsFile = new AtomicFile(                new File(Environment.getSystemSecureDirectory(), "storage.xml"));        synchronized (mLock) {            readSettingsLocked();        }        LocalServices.addService(MountServiceInternal.class, mMountServiceInternal);        /*         * Create the connection to vold with a maximum queue of twice the         * amount of containers we'd ever expect to have. This keeps an         * "asec list" from blocking a thread repeatedly.         */        mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG, 25,                null);        mConnector.setDebug(true);        Thread thread = new Thread(mConnector, VOLD_TAG);        thread.start();        // Reuse parameters from first connector since they are tested and safe        mCryptConnector = new NativeDaemonConnector(this, "cryptd",                MAX_CONTAINERS * 2, CRYPTD_TAG, 25, null);        mCryptConnector.setDebug(true);        Thread crypt_thread = new Thread(mCryptConnector, CRYPTD_TAG);        crypt_thread.start();        final IntentFilter userFilter = new IntentFilter();        userFilter.addAction(Intent.ACTION_USER_ADDED);        userFilter.addAction(Intent.ACTION_USER_REMOVED);        mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);        addInternalVolume();//添加内部Volume        // Add ourself to the Watchdog monitors if enabled.        if (WATCHDOG_ENABLE) {            Watchdog.getInstance().addMonitor(this);        }    }

MountService在Volume这块改动比较大,我们先看下addInterVolume方法:

    private void addInternalVolume() {        // Create a stub volume that represents internal storage        final VolumeInfo internal = new VolumeInfo(VolumeInfo.ID_PRIVATE_INTERNAL,                VolumeInfo.TYPE_PRIVATE, null, null);        internal.state = VolumeInfo.STATE_MOUNTED;        internal.path = Environment.getDataDirectory().getAbsolutePath();        mVolumes.put(internal.id, internal);    }

其实就是在mVolumes增加了一个volume。

在看看MountServicesystemReady函数会发一个消息,最后由handleSystemReady执行

    private void handleSystemReady() {        synchronized (mLock) {            resetIfReadyAndConnectedLocked();        }        // Start scheduling nominally-daily fstrim operations        MountServiceIdler.scheduleIdlePass(mContext);    }
resetIfReadyAndConnectedLocked函数
    private void resetIfReadyAndConnectedLocked() {        if (mSystemReady && mDaemonConnected) {            killMediaProvider();            mDisks.clear();            mVolumes.clear();            addInternalVolume();            try {                mConnector.execute("volume", "reset");//通知vold执行reset                // Tell vold about all existing and started users                final UserManager um = mContext.getSystemService(UserManager.class);                final List<UserInfo> users = um.getUsers();                for (UserInfo user : users) {                    mConnector.execute("volume", "user_added", user.id, user.serialNumber);                }                for (int userId : mStartedUsers) {                    mConnector.execute("volume", "user_started", userId);                }            } catch (NativeDaemonConnectorException e) {                Slog.w(TAG, "Failed to reset vold", e);            }        }    }
通知vold执行reset以及user_add、user_started命令


二、onStartUser函数

我们再看onStartUser函数,这个函数是统一由SystemServiceManager调用

    public void startUser(final int userHandle) {        final int serviceLen = mServices.size();        for (int i = 0; i < serviceLen; i++) {            final SystemService service = mServices.get(i);            try {                service.onStartUser(userHandle);            } catch (Exception ex) {                Slog.wtf(TAG, "Failure reporting start of user " + userHandle                        + " to service " + service.getClass().getName(), ex);            }        }    }
而在SystemServer中,把这个SystemServiceManager传给了ActivityManagerService中,最后在AMS中调用它的startUser方法。

        mActivityManagerService = mSystemServiceManager.startService(                ActivityManagerService.Lifecycle.class).getService();        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);        mActivityManagerService.setInstaller(installer);

我们再来看看MountService的onStartUser方法:

    private void onStartUser(int userId) {        Slog.d(TAG, "onStartUser " + userId);        // We purposefully block here to make sure that user-specific        // staging area is ready so it's ready for zygote-forked apps to        // bind mount against.        try {            mConnector.execute("volume", "user_started", userId);//往vold传user_started        } catch (NativeDaemonConnectorException ignored) {        }        synchronized (mVolumes) {            for (int i = 0; i < mVolumes.size(); i++) {//遍历mVolumes                final VolumeInfo vol = mVolumes.valueAt(i);                if (vol.isVisibleForRead(userId) && vol.isMountedReadable()) {                    final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, false);                    mHandler.obtainMessage(H_VOLUME_BROADCAST, userVol).sendToTarget();                    final String envState = VolumeInfo.getEnvironmentForState(vol.getState());                    mCallbacks.notifyStorageStateChanged(userVol.getPath(), envState, envState);//通知回调                }            }            mStartedUsers = ArrayUtils.appendInt(mStartedUsers, userId);        }    }

onStartUser会通知回调现在有的volume,就是primary的volume。在构造函数中已经添加。

我们再来看看这个回调

        private void notifyStorageStateChanged(String path, String oldState, String newState) {            final SomeArgs args = SomeArgs.obtain();            args.arg1 = path;            args.arg2 = oldState;            args.arg3 = newState;            obtainMessage(MSG_STORAGE_STATE_CHANGED, args).sendToTarget();        }
然后发送消息,因为注册的回调有好多个,所以需要遍历。最后调用了IMountServiceListener 的接口
@Override        public void handleMessage(Message msg) {            final SomeArgs args = (SomeArgs) msg.obj;            final int n = mCallbacks.beginBroadcast();            for (int i = 0; i < n; i++) {                final IMountServiceListener callback = mCallbacks.getBroadcastItem(i);                try {                    invokeCallback(callback, msg.what, args);                } catch (RemoteException ignored) {                }            }            mCallbacks.finishBroadcast();            args.recycle();        }        private void invokeCallback(IMountServiceListener callback, int what, SomeArgs args)                throws RemoteException {            switch (what) {                case MSG_STORAGE_STATE_CHANGED: {                    callback.onStorageStateChanged((String) args.arg1, (String) args.arg2,                            (String) args.arg3);                    break;                }                case MSG_VOLUME_STATE_CHANGED: {                    callback.onVolumeStateChanged((VolumeInfo) args.arg1, args.argi2, args.argi3);                    break;                }                case MSG_VOLUME_RECORD_CHANGED: {                    callback.onVolumeRecordChanged((VolumeRecord) args.arg1);                    break;                }                case MSG_VOLUME_FORGOTTEN: {                    callback.onVolumeForgotten((String) args.arg1);                    break;                }                case MSG_DISK_SCANNED: {                    callback.onDiskScanned((DiskInfo) args.arg1, args.argi2);                    break;                }                case MSG_DISK_DESTROYED: {                    callback.onDiskDestroyed((DiskInfo) args.arg1);                    break;                }            }        }
下一步我们看MountService的onEvent函数,这个需要结合vold来看。




1 0