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://www.mzph.cn/news/872963.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1个Xpath定位可以在Web页面查找到多个元素Selenium

1个Xpath定位可以在Web页面查找到多个元素Selenium//input[id\"transactionId\"] 打开Web页面&#xff0c; 点击F12可以看到压面 点击Ctrl F 可以点图如下图的输入框&#xff0c;输入xpath&#xff0c;看右侧可以找到3个对应的元素 点击Ctrl F 点击Ctrl F 点…

图神经网络实战(17)——深度图生成模型

图神经网络实战&#xff08;17&#xff09;——深度图生成模型 0. 前言1. 变分图自编码器2. 自回归模型3. 生成对抗网络小结系列链接 0. 前言 我们已经学习了经典的图生成算法&#xff0c;虽然它们能够完成图生成任务&#xff0c;但也存在一些问题&#xff0c;促使基于图神经网…

28_EfficientNetV2网络详解

V1&#xff1a;https://blog.csdn.net/qq_51605551/article/details/140487051?spm1001.2014.3001.5502 1.1 简介 EfficientNetV2是Google研究人员Mingxing Tan和Quoc V. Le等人在2021年提出的一种深度学习模型&#xff0c;它是EfficientNet系列的最新迭代&#xff0c;旨在提…

leetcode日记(42)螺旋矩阵

我使用的是递归&#xff0c;每次递归遍历一圈矩阵&#xff0c;将遍历结果塞进结果vector中&#xff0c;每次遍历修改上下左右边界&#xff0c;直至遍历后其中两边界重合或交错。 class Solution { public:vector<int> spiralOrder(vector<vector<int>>&…

好玩的动作单机游戏:鬼泣4 游戏安装包

Devil May Cry 4让玩家沉醉于哥德式的超自然世界之中&#xff1b;体验一个新主角与熟悉的英雄发生冲突的故事。玩家操作新主角Nero&#xff0c;利用游戏独特的新系统──强大的「恶魔之手」能释放令人难以置信的攻击和製作出不间断的连续技。 凭藉PC的高效能图形显示功能&…

收银系统源码-千呼新零售2.0【数据报表】

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

【LeetCode】162. 寻找峰值

1. 题目 2. 分析 这道题的难点有二&#xff1a;第一&#xff0c;知道用二分法求解&#xff1b;第二&#xff0c;二分判断的标准是什么&#xff1f;传统的题目的二分标注都是跟某个固定的值做比较&#xff0c;但是此题不然。此题的比较对象是相邻的元素。 不要硬凭自己的脑子…

C语言·函数(超详细系列·全面总结)

前言&#xff1a;Hello大家好&#x1f618;&#xff0c;我是心跳sy&#xff0c;为了更好地形成一个学习c语言的体系&#xff0c;最近将会更新关于c语言语法基础的知识&#xff0c;今天更新一下函数的知识点&#xff0c;我们一起来看看吧&#xff01; 目录 一、函数是什么 &a…

vue、js截取视频任意一帧图片

html有本地上传替换部分&#xff0c;可以不看 原理&#xff1a;通过video标签对视频进行加载&#xff0c;随后使用canvas对截取的视频帧生成需要的图片 <template> <el-row :gutter"18" class"preview-video"><h4>视频预览<span&…

execv函数简单使用

在Unix-like系统中&#xff0c;execv 函数用于执行一个新的程序&#xff0c;同时可以传递参数给它。这个函数是 exec 系列函数之一&#xff0c;用于替换当前进程映像。 execv 的原型如下&#xff1a; int execv(const char *path, char *const argv[]); path&#xff1a;新程…

【边缘计算网关教程】9.对接ThingsBoard(MQTT协议)

前景回顾-【边缘计算网关教程】8.ModbusTCP采集存储Influxdb-CSDN博客 目录 需求分析 平台配置&#xff1a; 需求实现 第一步&#xff1a;采集Modbus TCP数据 第二步&#xff1a;拼接Json 第三步&#xff1a;MQTT上报 平台配置 第一步&#xff1a;添加设备 ​编辑第二…

国内新能源汽车芯片自给,承认差距,任重道远

【科技明说 &#xff5c; 科技热点关注】 据近日工信部电子五所元器件与材料研究院高级副院长罗道军表示&#xff0c;中国拥有最大的新能源车产能&#xff0c;芯片用量也是越来越多。但是芯片的自给率目前不到10%&#xff0c;是结构性的短缺。 中国拥有最大新能源车产能&#…

自学网络安全:从菜鸟到守护者的蜕变之旅

在这个数字化时代&#xff0c;网络安全不再是遥不可及的专业术语&#xff0c;而是与我们每个人的生活息息相关。随着网络攻击事件的频发&#xff0c;掌握一定的网络安全知识&#xff0c;不仅是对个人隐私的保护&#xff0c;更是对社会安全的贡献。今天&#xff0c;就让我们一起…

从太阳神到弥勒佛

对于学习英语的人来说&#xff0c;太阳神&#xff0c;最为知名的&#xff0c;就是阿波罗&#xff08;Apollo&#xff09;&#xff0c;人类最近的历史&#xff0c;最知名的&#xff0c;就是阿波罗计划。 说白了&#xff0c;阿波罗计划&#xff0c;这个音译词&#xff0c;对于英语…

用Docker来开发

未完成。。。 现在好像用Docker是越来越多了。之前其实也看过docker的原理&#xff0c;大概就是cgroup那些&#xff0c;不过现在就不看原理了&#xff0c;不谈理论&#xff0c;只看实际中怎么用&#xff0c;解决眼前问题。 用docker来做开发&#xff0c;其实就是解决的编译环境…

InceptionV3代码实现(Pytorch)

文章目录 Inception介绍InceptionV3代码实现第一步&#xff1a;定义基础卷积模块第二步&#xff1a;定义Inceptionv3模块InceptionAInceptionBInceptionCInceptionDInceptionE 第三步&#xff1a;定义辅助分类器InceptionAux第四步&#xff1a;搭建GoogLeNet网络第五步*&#x…

PJA1介导的焦亡抑制是鼻咽癌产生耐药性的驱动因素

引用信息 文 章&#xff1a;PJA1-mediated suppression of pyroptosis as a driver of docetaxel resistance in nasopharyngeal carcinoma. 期 刊&#xff1a;Nature Communications&#xff08;影响因子&#xff1a;14.7&#xff09; 发表时间&#xff1a;2024年6月2…

unity 把Vuforia的Image做成预制件prefab后,通过ab加载或者其他动态加载后,扫描图片不会出现模型

//通过ab加载资源&#xff08;自己封装的ab加载的脚本&#xff09;GameObject go LoadHandle.Instance.LoadPrefab.LoadPrefabAssets("ImagePrefab");GameObject game GameObject.Instantiate(go);//加载预制件后&#xff0c;加载图片的数据库// 初始化 Vuforia I…

链接追踪系列-10.mall-swarm微服务运行并整合elk-上一篇的番外

因为上一篇没对微服务代码很详细地说明&#xff0c;所以在此借花献佛&#xff0c;使用开源的微服务代码去说明如何去做链路追踪。 项目是开源项目&#xff0c;fork到github以及gitee中&#xff0c;然后拉取到本地 后端代码&#xff1a; https://gitee.com/jelex/mall-swarm.gi…

【字幕】字幕特效入门

前言 最近两周调研了一下字幕特效的底层程序逻辑&#xff0c;因为工作内容的原因&#xff0c;就分享几个自己找的链接具体细节就不分享了&#xff0c;CSDN也是我的个人笔记&#xff0c;只记录一些简单的内容用于后续自己方便查询&#xff0c;顺便帮助一下正在苦苦查阅资料入门…