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.javaandroid/frameworks/base/core/java/android/os/storage
系统 framework 层StorageManagerService.javaandroid/frameworks/base/services/core/java/com/android/server
Vold 服务VoldNativeService.cppandroid/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_REMOVEDvolume已经移除,代表移除流程已经走完
Intent.ACTION_MEDIA_BAD_REMOVALvolume已经移除,代表移除流程已经走完,可能节点没有卸载干净

二、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.Stubimplements Watchdog.Monitor, ScreenObserver {public static class Lifecycle extends SystemService {private StorageManagerService mStorageManagerService;public Lifecycle(Context context) {super(context);}@Overridepublic void onStart() {mStorageManagerService = new StorageManagerService(getContext());publishBinderService("mount", mStorageManagerService);mStorageManagerService.start();}@Overridepublic 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();}}@Overridepublic 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;}}@Overridepublic void onUserUnlocking(@NonNull TargetUser user) {mStorageManagerService.onUnlockUser(user.getUserIdentifier());}@Overridepublic void onUserStopped(@NonNull TargetUser user) {mStorageManagerService.onCleanupUser(user.getUserIdentifier());}@Overridepublic void onUserStopping(@NonNull TargetUser user) {mStorageManagerService.onStopUser(user.getUserIdentifier());}@Overridepublic void onUserStarting(TargetUser user) {mStorageManagerService.snapshotAndMonitorLegacyStorageAppOp(user.getUserHandle());}}
}

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

class StorageManagerService extends IStorageManager.Stubimplements 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”的线程,并创建对应的HandlerHandlerThread 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 necessaryFile 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",
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3248226.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Android 10.0 Launcher3拖拽图标进入hotseat自适应布局功能实现一

1.前言 在10.0的系统rom定制化开发中&#xff0c;在对于launcher3的一些开发定制中&#xff0c;在对hotseat的一些开发中&#xff0c;需要实现动态hotseat居中 的功能&#xff0c;就是在拖拽图标进入和拖出hotseat&#xff0c;都可以保持hotseat居中的功能&#xff0c;接下来分…

阿里云短信PHP集成api类

无需安装sdk扩展包&#xff0c;直接引入类即可使用 V3版本请求体&签名机制:自研请求体和签名机制 - 阿里云SDK - 阿里云 模版内容&#xff1a; <?phpnamespace common\components;use common\constant\UserConst; use common\models\bee\SmsReferer; use common\mode…

C++从入门到起飞之——类的定义/实例化 全方位剖析!

个人主页&#xff1a;秋风起&#xff0c;再归来~ C从入门到起飞 个人格言&#xff1a;悟已往之不谏&#xff0c;知来者犹可追 克心守己&#xff0c;律己则安&#xff01; 目录 1.类的定义 1.1、类定义格式 1.2、访问限定符 1.3、类域 2.实例化 2.…

备忘录删除了怎么恢复 备忘录误删恢复办法

备忘录作为我们日常生活中的得力助手&#xff0c;帮助我们记录重要事项和灵感&#xff0c;然而&#xff0c;使用中偶尔会出现误删的情况。若不能及时找回误删的内容&#xff0c;可能会造成重要信息的丢失&#xff0c;给我们的工作和生活带来不必要的麻烦。 如果你也担心备忘录…

tinymce富文本支持word内容同时粘贴文字图片上传 vue2

效果图 先放文件 文件自取tinymce: tinymce富文本简单配置及word内容粘贴图片上传 封装tinymce 文件自取&#xff1a;tinymce: tinymce富文本简单配置及word内容粘贴图片上传 页面引用组件 <TinymceSimplify refTinymceSimplify v-model"knowledgeBlockItem.content…

还在羡慕别人的爆款视频是怎么做出来的?Transform Video给你答案,让你轻松制作出爆款的作品!

大家好&#xff01;我是闷声轻创&#xff01;最近我发现了一个牛批的AI视频编辑工具——Transform Video。这款软件将彻底改变你的视频创作体验&#xff0c;来看看都有什么功能吧 先了解一下Transform Video是什么&#xff1f; Transform Video是一个革命性的AI视频编辑平台&a…

vxe-grid 实现配置式form搜索条件 form搜索条件框可折叠 配置式table

文章目录 效果图代码 效果图 代码 <template><div class"app-container"><vxe-grid refxGrid v-bind"gridOptions" v-if"tableHeight" :height"tableHeight"><template #billDate"{ data }"><e…

Linux内核编程(八) 添加自定义目录驱动菜单 (Kconfig文件使用)

本文目录 一、Linux 内核驱动目录二、自定义驱动的Kconfig编写●示例&#xff1a;在 drivers 菜单添加一个自己驱动的子菜单。 三、自写驱动的Makefile编写四、总结 一个Linux内核源码&#xff0c;其中包含了很多驱动程序&#xff0c;对应不同的功能。我们在编译内核时。如果将…

《TF2.x强化学习手册》P59-P65-SARSA-Q-learning

文章目录 实现SARSA算法和对应的强化学习智能体前期准备实现步骤工作原理初始化算法流程 构建基于Q学习的智能体前期准备实现步骤工作原理SARSA 算法的收敛性&#xff1a;SARSA 适合在线学习和真实系统&#xff1a;Q 学习算法的适用性&#xff1a; 实现SARSA算法和对应的强化学…

linux|多线程(一)

主要介绍了为什么要有线程 和线程的调用 和简单的对线程进行封装。 背景知识 a.重谈地址空间 我们知道物理内存的最小单元大小是4kB 物理内存是4G那么这样的单元友1M个 操作系统先描述再组织struct page[1M] 对于32位数据字长的机器&#xff0c;页表有2^32条也就是4G条&#…

随笔一、泰山派RK3566开发板调试串口波特率修改

摘要&#xff1a;立创泰山派RK3566开发板默认调试串口波特率是1500000bps&#xff0c;一般串口助手工具没有此波特率&#xff0c;为适应各种调试环境需要&#xff0c;打算修改调试串口波特率为115200bps 需要修改三个部分 1. uboot引导部分 修改tspi_linux_sdk/u-boot/config…

python数据可视化(10)——绘制地图图表

课程学习来源&#xff1a;b站up&#xff1a;【蚂蚁学python】 【课程链接&#xff1a;【【数据可视化】Python数据图表可视化入门到实战】】 【课程资料链接&#xff1a;【链接】】 python&#xff1a;3.12.3 所有库都使用最新版。 Python绘制中国地图和城市图表 from pyech…

CSS技巧专栏:一日一例 7 - 纯CSS实现炫光边框按钮特效

CSS技巧专栏&#xff1a;一日一例 7 - 纯CSS实现炫光边框按钮特效 本例效果图 案例分析 相信你可能已经在网络见过类似这样的流光的按钮&#xff0c;在羡慕别人做的按钮这么酷的时候&#xff0c;你有没有扒一下它的源代码的冲动&#xff1f;或者你当时有点冲动&#xff0c;却…

[第一期]带日期时间的LED滚动广告屏美化

效果图&#xff1a; 源代码&#xff1a; <style type"text/css">.studytextgzbox {background: #F9F9F9; border: 1px solid #999999;margin: 1px;text-align:center; float: left;line-height: 28px;height: 28px;overflow: hidden;width: 236px; }.hulik…

最新电子书|使用Anybus网关,轻松实现工业设备互联

无论何时&#xff0c;确保多网络连接 工业网关的关键角色 工业网关&#xff0c;又称为协议网关、协议转换器或协议翻译器&#xff0c;是实现工业设备互联的最简捷方法。作为信息的翻译器&#xff0c;它们使得不同工业协议的设备、机器、系统或网络能够无缝交换数据&#xff0c…

数据架构新篇章:存算一体与存算分离的协同演进

数据架构新篇章&#xff1a;存算一体与存算分离的协同演进 前言被误解的存算分离存算一体的概念存算一体的过往存算一体的演进 存算分离的定义存算分离的过往存算分离的演进 存算一体和分离示例总结 前言 降本增效大环境下&#xff0c;存算分离架构如火如荼&#xff0c;Why&am…

【STC89C51单片机】定时器中断系统

中断概念 中断是一种重要的硬件机制&#xff0c;用于在处理器正在执行程序时&#xff0c;能够及时响应某些外部或内部事件。中断可以临时中止当前正在执行的指令序列&#xff0c;转而去执行专门的中断服务程序&#xff08;ISR&#xff0c;Interrupt Service Routine&#xff0…

Stable Diffusion:解锁AI绘画新纪元的保姆级入门指南

在这个数字艺术日新月异的时代&#xff0c;Stable Diffusion如同一股清新的风&#xff0c;吹散了传统绘画的界限&#xff0c;让每个人都能成为创意无限的数字艺术家。作为一款基于Transformer结构的文本到图像生成模型&#xff0c;Stable Diffusion以其惊人的生成速度、细腻的画…

ubuntu22.04 配置grpc(优化官方教程)

优化了官方教程&#xff0c;2024.7.17顺利打通。 一&#xff1a;添加环境变量 打开root文件夹下的 .bashrc 文件 编辑文件&#xff1a;滚动到文件的底部&#xff0c;然后添加以下行&#xff1a; export MY_INSTALL_DIR$HOME/.local mkdir -p "$MY_INSTALL_DIR" exp…

AMEYA360:思瑞浦推出汽车级理想二极管ORing控制器TPS65R01Q

聚焦高性能模拟芯片和嵌入式处理器的半导体供应商思瑞浦3PEAK(股票代码&#xff1a;688536)发布汽车级理想二极管ORing控制器TPS65R01Q。 TPS65R01Q拥有20mV正向调节功能&#xff0c;降低系统损耗。快速反向关断(Typ&#xff1a;0.39μs)&#xff0c;在电池反向和各种汽车电气瞬…