Android 12系统源码_存储(二)StorageManagerService服务

前言

在 Android 系统中,StorageManagerService是一个用于获取存储设备信息和管理存储设备的服务。它提供了一系列方法,可以获取当前挂载的存储设备信息,以及对存储设备进行挂载和卸载操作。

一、Storage存储模块介绍

1.1、StorageManagerService 简介

Android 外部存储空间由 Vold 服务和 StorageManagerService 系统服务共同管理。外部实体存储卷的装载由 Vold 处理,准备好后上报给 StorageManagerService,然后再将其提供给应用。在 Android 8.0 及以后,MountService 服务已经更名为 StorageManagerServic,并且 StorageManagerService 与 Vold 的通信由 socket 变更为 binder 方式。

代码路径分布:

层级结构 主要文件 代码路径
应用 api 接口层 StorageManager.java android/frameworks/base/core/java/android/os/storage
系统 framework 层 StorageManagerService.java android/frameworks/base/services/core/java/com/android/server
Vold 服务 VoldNativeService.cpp android/system/vold

1.2、StorageManagerService 架构

StorageManagerService架构图
图中描述了 StorageManagerService 模块的架构,上层 framework 服务 StorageManagerService 是由 SystemService 在启动阶段开启;Vold 服务在 init 阶段由 rc 文件启动,StorageManagerService 与 Vold 服务通过 aidl 的方式交互,Vold 服务中 VoldNativeService 实现了 aidl 接口,是作为 aidl 的服务端,但实际处理是在 VolumeManager 中实现,NetlinkManager 是 VolumeManager 与 驱动层通信事件上报的处理类,NetlinkManager 和 kernel 建立 socket 通讯,监听 kernel 的 uevent 事件,当驱动检测到有 U盘 接入/拔出时,会上报 event 事件给到 NetlinkHandler 处理,进入挂载/卸载流程。

1.3、监听U盘插拔的状态

Android 提供了一系列广播,应用可以通过这些广播来获取当前U盘状态。

广播 含义
Intent.ACTION_MEDIA_CHECKING 检查
Intent.ACTION_MEDIA_MOUNTED 挂载
Intent.ACTION_MEDIA_UNMOUNTABLE 无法挂载,挂载失败(常见是U盘挂载节点已经存在无法继续挂载)
Intent.ACTION_MEDIA_EJECT 硬件弹出
Intent.ACTION_MEDIA_UNMOUNTED 卸载
Intent.ACTION_MEDIA_REMOVED volume已经移除,代表移除流程已经走完
Intent.ACTION_MEDIA_BAD_REMOVAL volume已经移除,代表移除流程已经走完,可能节点没有卸载干净

二、StorageManagerService 启动

2.1、 SystemServer 阶段

SystemServer 会在 startOtherServices() 阶段启动 StorageManagerService 服务。

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

public final class SystemServer implements Dumpable {

    private static final String STORAGE_MANAGER_SERVICE_CLASS =
            "com.android.server.StorageManagerService$Lifecycle";
    private SystemServiceManager mSystemServiceManager;
    
    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
        ...代码省略...
        if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
                t.traceBegin("StartStorageManagerService");
                try {
                    /*
                     * NotificationManagerService is dependant on StorageManagerService,
                     * (for media / usb notifications) so we must start StorageManagerService first.
                     */
                    mSystemServiceManager.startService(STORAGE_MANAGER_SERVICE_CLASS);
                    storageManager = IStorageManager.Stub.asInterface(
                            ServiceManager.getService("mount"));
                } catch (Throwable e) {
                    reportWtf("starting StorageManagerService", e);
                }
                t.traceEnd();
                ...代码省略...
            }
        }  
        ...代码省略...        
      }    
}

2.2、SystemServiceManager启动StorageManagerService服务

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

public final class SystemServiceManager implements Dumpable {
    /**
     * 创建一个系统服务,该服务必须是com.android.server.SystemService的子类
     *
     * @param serviceClass 一个实现了SystemService接口的Java类
     * @return 返回一个服务实例对象
     */
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            Slog.i(TAG, "Starting " + name);
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + 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 {
                //获取参数为Context的构造方法,通过反射创建service对象
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (InvocationTargetException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service constructor threw an exception", ex);
            }
            //继续调用startService方法
            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
}

SystemManagerService通过反射构建com.android.server.StorageManagerService$Lifecycle实例对象并调用onStart() 方法。

2.3、StorageManagerService阶段

1、StorageManagerService$Lifecycle的onStart方法会构建StorageManagerService实例对象并调用该对象的start方法。

frameworks/base/services/core/java/com/android/server/StorageManagerService.java

class StorageManagerService extends IStorageManager.Stub
        implements Watchdog.Monitor, ScreenObserver {
    public static class Lifecycle extends SystemService {
        private StorageManagerService mStorageManagerService;

        public Lifecycle(Context context) {
            super(context);
        }

        @Override
        public void onStart() {
            mStorageManagerService = new StorageManagerService(getContext());
            publishBinderService("mount", mStorageManagerService);
            mStorageManagerService.start();
        }

        @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();
            }
        }

        @Override
        public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
            int currentUserId = to.getUserIdentifier();
            mStorageManagerService.mCurrentUserId = currentUserId;

            UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class);
            if (umInternal.isUserUnlocked(currentUserId)) {
                Slog.d(TAG, "Attempt remount volumes for user: " + currentUserId);
                mStorageManagerService.maybeRemountVolumes(currentUserId);
                mStorageManagerService.mRemountCurrentUserVolumesOnUnlock = false;
            } else {
                Slog.d(TAG, "Attempt remount volumes for user: " + currentUserId + " on unlock");
                mStorageManagerService.mRemountCurrentUserVolumesOnUnlock = true;
            }
        }

        @Override
        public void onUserUnlocking(@NonNull TargetUser user) {
            mStorageManagerService.onUnlockUser(user.getUserIdentifier());
        }

        @Override
        public void onUserStopped(@NonNull TargetUser user) {
            mStorageManagerService.onCleanupUser(user.getUserIdentifier());
        }

        @Override
        public void onUserStopping(@NonNull TargetUser user) {
            mStorageManagerService.onStopUser(user.getUserIdentifier());
        }

        @Override
        public void onUserStarting(TargetUser user) {
            mStorageManagerService.snapshotAndMonitorLegacyStorageAppOp(user.getUserHandle());
        }
    }
}

2、StorageManagerService$Lifecycle的onStart方法会构建StorageManagerService实例对象并调用该对象的start方法。

class StorageManagerService extends IStorageManager.Stub
        implements Watchdog.Monitor, ScreenObserver {
    public StorageManagerService(Context context) {
        sSelf = this;
         // 前面先是读取一些属性状态,其中关于FUSE下面会稍微介绍一下
        mVoldAppDataIsolationEnabled = SystemProperties.getBoolean(
                ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false);
        mContext = context;
        mResolver = mContext.getContentResolver();
        mCallbacks = new Callbacks(FgThread.get().getLooper());
        mLockPatternUtils = new LockPatternUtils(mContext);
        
		// 创建名为“StorageManagerService”的线程,并创建对应的Handler
        HandlerThread hthread = new HandlerThread(TAG);
        hthread.start();
        mHandler = new StorageManagerServiceHandler(hthread.getLooper());

		//mObbActionHandler对应“android.io”线程
        // Add OBB Action Handler to StorageManagerService thread.
        mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper());
        mStorageSessionController = new StorageSessionController(mContext);
		//启动installd服务
        mInstaller = new Installer(mContext);
        mInstaller.onStart();

        // Initialize the last-fstrim tracking if necessary
        File dataDir = Environment.getDataDirectory();
        File systemDir = new File(dataDir, "system");
        mLastMaintenanceFile = new File(systemDir, LAST_FSTRIM_FILE);
        //判断/data/system/last-fstrim文件,不存在则创建,存在则更新最后修改时间
        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();
        }
        
		// 读取data/system/storage.xml配置
        mSettingsFile = new AtomicFile(
                new File(Environment.getDataSystemDirectory(), "storage.xml"), "storage-settings");

        synchronized (mLock) {
            readSettingsLocked();
        }

        LocalServices.addService(StorageManagerInternal.class, mStorageManagerInternal);

 		// 监听ACTION_USER_ADDED、ACTION_USER_REMOVED广播
        final IntentFilter userFilter = new IntentFilter();
        userFilter.addAction(Intent.ACTION_USER_ADDED);
        userFilter.addAction(Intent.ACTION_USER_REMOVED);
        mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);

		// 内部私有volume的路径为/data,该volume通过dumpsys mount是不会显示的
        synchronized (mLock) {
            addInternalVolumeLocked();
        }

        // Add ourself to the Watchdog monitors if enabled.
        if (WATCHDOG_ENABLE) {
            Watchdog.getInstance().addMonitor(this);
        }
		// 汽车应用支持
        mIsAutomotive = context.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_AUTOMOTIVE);
    }

    private void start() {
        connectStoraged();
        connectVold();
    }
}

三、AIDL 接口层

1、aidl接口文件

Vold 的 aidl 文件定义在 /system/vold/binder/android/os/ 目录下。
在这里插入图片描述
该目录存在四个aidl文件:IVold.aidl、IVoldListener.aidl、IVoldMountCallback.aidl、IVoldTaskListener.aidl。

2、Vold模块Android.bp文件

Vold模块对应的Android.bp文件关于aild的编译语法如下所示:

package {
    default_applicable_licenses: ["Android-Apache-2.0"],
}
...代码省略...
cc_library_static {
    name: "libvold_binder",
    defaults: ["vold_default_flags"],

    srcs: [
        ":vold_aidl",
    ],
    shared_libs: [
        "libbinder",
        "libutils",
    ],
    aidl: {
        local_include_dirs: ["binder"],
        include_dirs: [
            "frameworks/native/aidl/binder",
            "frameworks/base/core/java",
        ],
        export_aidl_headers: true,
    },
    whole_static_libs: [
        "libincremental_aidl-cpp",
    ],
    export_shared_lib_headers: [
        "libbinder",
    ],
}

...代码省略...

filegroup {
    name: "vold_aidl",
    srcs: [
        "binder/android/os/IVold.aidl",
        "binder/android/os/IVoldListener.aidl",
        "binder/android/os/IVoldMountCallback.aidl",
        "binder/android/os/IVoldTaskListener.aidl",
    ],
    path: "binder",
}

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 12:16:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 12:16:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 12:16:02       58 阅读
  4. Python语言-面向对象

    2024-07-18 12:16:02       69 阅读

热门阅读

  1. python常用内置数据类型

    2024-07-18 12:16:02       18 阅读
  2. 支付平台系统遭遇黑客攻击怎么办

    2024-07-18 12:16:02       24 阅读
  3. MySQL 实现模糊匹配

    2024-07-18 12:16:02       24 阅读
  4. Linux 驱动开发

    2024-07-18 12:16:02       26 阅读
  5. LeetCode 227. 基本计算器 II

    2024-07-18 12:16:02       23 阅读
  6. 如何实现MySQL的高可用

    2024-07-18 12:16:02       23 阅读
  7. docker安装指导

    2024-07-18 12:16:02       21 阅读
  8. 使用lxml库提取HTML中a标签的href和文本内容

    2024-07-18 12:16:02       23 阅读
  9. 一些数据库专家称,最新的 MySQL 版本令人失望

    2024-07-18 12:16:02       27 阅读
  10. NLP篇8 自然语言处理 使用注意力模型

    2024-07-18 12:16:02       21 阅读
  11. 测试用例设计方法

    2024-07-18 12:16:02       17 阅读