Filesystem in Userspace顾名思义,即在用户空间的文件系统。 为什么要强调用户空间呢?接触过Linux内核的同学大概会知道,文件系统一般是实现在内核里面的,比如,Ext4、Fat32、NTFS(Kernel原生版)等常见的文件系统,其代码都在内核中,而FUSE特殊之处就是,其文件系统的核心逻辑是在用户空间实现的。

FUSE实现原理

android 驻留后台权限_科技

图中体现了FUSE的2个关键部分(绿色方框),分别是Kernel中的那个FUSE(这里简称kernel FUSE)和user space中的那个fuse_user程序。其中kernel FUSE是负责把从用户层过来的文件系统操作请求传递给fuse_user程序的,而这个fuse_user程序实现了前面所说的文件系统的核心逻辑。

onStart

private void start() {
 connectStoraged();
 connectVold();
 }private void connectStoraged() {
 IBinder binder = ServiceManager.getService(“storaged”);
 if (binder != null) {
 try {
 // 设置死亡代理以重新建立连接
 binder.linkToDeath(new DeathRecipient() {
 @Override
 public void binderDied() {
 Slog.w(TAG, “storaged died; reconnecting”);
 mStoraged = null;
 connectStoraged();
 }
 }, 0);
 } catch (RemoteException e) {
 binder = null;
 }
 }if (binder != null) {
 // 获取storaged的bp端用于通信
 mStoraged = IStoraged.Stub.asInterface(binder);
 } else {
 Slog.w(TAG, “storaged not found; trying again”);
 }if (mStoraged == null) {
 BackgroundThread.getHandler().postDelayed(() -> {
 connectStoraged();
 }, DateUtils.SECOND_IN_MILLIS);
 } else {
 onDaemonConnected();
 }
 }private void connectVold() {
 IBinder binder = ServiceManager.getService(“vold”);
 if (binder != null) {
 try {
 // 设置死亡代理以重新建立连接
 binder.linkToDeath(new DeathRecipient() {
 @Override
 public void binderDied() {
 Slog.w(TAG, “vold died; reconnecting”);
 mVold = null;
 connectVold();
 }
 }, 0);
 } catch (RemoteException e) {
 binder = null;
 }
 }if (binder != null) {
 // 获取Vold的bp端用于通信
 mVold = IVold.Stub.asInterface(binder);
 try {
 // 关键代码:设置Vold的Listener
 mVold.setListener(mListener);
 } catch (RemoteException e) {
 mVold = null;
 Slog.w(TAG, “vold listener rejected; trying again”, e);
 }
 } else {
 Slog.w(TAG, “vold not found; trying again”);
 }if (mVold == null) {
 BackgroundThread.getHandler().postDelayed(() -> {
 connectVold();
 }, DateUtils.SECOND_IN_MILLIS);
 } else {
 onDaemonConnected();
 }
 }connectStoraged和connectVold分别是获取Vold和Storaged服务的bp端,设置死亡代理, 为Vold设置Listener监听,然后调用onDaemonConnected
public void onDaemonConnected() {
 mDaemonConnected = true;
 mHandler.obtainMessage(H_DAEMON_CONNECTED).sendToTarget();
 }private void handleDaemonConnected() {
 initIfBootedAndConnected();
 resetIfBootedAndConnected();// On an encrypted device we can’t see system properties yet, so pull
 // the system locale out of the mount service.
 if (“”.equals(VoldProperties.encrypt_progress().orElse(“”))) {
 copyLocaleFromMountService();
 }
 }private void initIfBootedAndConnected() {
 Slog.d(TAG, “Thinking about init, mBootCompleted=” + mBootCompleted• “, mDaemonConnected=” + mDaemonConnected);
 if (mBootCompleted && mDaemonConnected
 && !StorageManager.isFileEncryptedNativeOnly()) {
 // 根据persist.sys.emulate_fbe确定用户目录的加锁/解锁状态
 final boolean initLocked = StorageManager.isFileEncryptedEmulatedOnly();
 Slog.d(TAG, “Setting up emulation state, initlocked=” + initLocked);
 final List users = mContext.getSystemService(UserManager.class).getUsers();
 for (UserInfo user : users) {
 try {
 if (initLocked) {
 mVold.lockUserKey(user.id);
 } else {
 mVold.unlockUserKey(user.id, user.serialNumber, encodeBytes(null),
 encodeBytes(null));
 }
 } catch (Exception e) {
 Slog.wtf(TAG, e);
 }
 }
 }
 }private void resetIfBootedAndConnected() {
 Slog.d(TAG, “Thinking about reset, mBootCompleted=” + mBootCompleted• “, mDaemonConnected=” + mDaemonConnected);
 // systemserver启动进入bootcomplete阶段
 if (mBootCompleted && mDaemonConnected) {
 final UserManager userManager = mContext.getSystemService(UserManager.class);
 final List users = userManager.getUsers();if (mIsFuseEnabled) {
 mStorageSessionController.onReset(mVold, () -> {
 mHandler.removeCallbacksAndMessages(null);
 });
 } else {
 killMediaProvider(users);
 }final int[] systemUnlockedUsers;
 synchronized (mLock) {
 // make copy as sorting can change order
 systemUnlockedUsers = Arrays.copyOf(mSystemUnlockedUsers,
 mSystemUnlockedUsers.length);
 // 清空mDisk和mVolumes两个ArrayMap
 mDisks.clear();
 mVolumes.clear();
 // 将/data为路径的private volume添加到mVolumes
 addInternalVolumeLocked();
 }try {
 // 通过Vold的bp端调用reset()方法
 // TODO(b/135341433): Remove paranoid logging when FUSE is stable
 Slog.i(TAG, “Resetting vold…”);
 mVold.reset();
 Slog.i(TAG, “Reset vold”);// 通知Vold所有的用户和已解锁用户
 for (UserInfo user : users) {
 mVold.onUserAdded(user.id, user.serialNumber);
 }
 for (int userId : systemUnlockedUsers) {
 mVold.onUserStarted(userId);
 mStoraged.onUserStarted(userId);
 }
 if (mIsAutomotive) {
 restoreAllUnlockedUsers(userManager, users, systemUnlockedUsers);
 }
 mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
 mStorageManagerInternal.onReset(mVold);
 } catch (Exception e) {
 Slog.wtf(TAG, e);
 }
 }
 }

onBootPhase

@Override();
 public void onBootPhase(int phase) {
 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
 mStorageManagerService.servicesReady();
 } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
 mStorageManagerService.systemReady();
 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
 mStorageManagerService.bootCompleted();
 }
 }

SystemServiceManager的startBootPhase()贯穿system_server进程的整个启动过程

android 驻留后台权限_gitee_02

1. servicesReady
private void servicesReady() {
 mPmInternal = LocalServices.getService(PackageManagerInternal.class);mIPackageManager = IPackageManager.Stub.asInterface(
 ServiceManager.getService(“package”));
 mIAppOpsService = IAppOpsService.Stub.asInterface(
 ServiceManager.getService(Context.APP_OPS_SERVICE));// MediaProvider
 ProviderInfo provider = getProviderInfo(MediaStore.AUTHORITY);
 if (provider != null) {
 mMediaStoreAuthorityAppId = UserHandle.getAppId(provider.applicationInfo.uid);
 sMediaStoreAuthorityProcessName = provider.applicationInfo.processName;
 }// DownloadsProvider
 provider = getProviderInfo(Downloads.Impl.AUTHORITY);
 if (provider != null) {
 mDownloadsAuthorityAppId = UserHandle.getAppId(provider.applicationInfo.uid);
 }// DocumentsUiProvider
 provider = getProviderInfo(DocumentsContract.EXTERNAL_STORAGE_PROVIDER_AUTHORITY);