android存储3--初始化.unlock事件的处理

这篇具有很好参考价值的文章主要介绍了android存储3--初始化.unlock事件的处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

android版本:android-11.0.0_r21
http://aospxref.com/android-11.0.0_r21

概述:SystemServiceManager收到unlock事件后,遍历service链表,执行各个service的onUserUnlocking。对于存储service,执行的是StorageManagerService$Lifecycle中的onUserUnlocking,在这个方法中,存储的StorageSessionController、vold、storaged模块进行各自初始化操作。

一、SystemServiceManager处理unlock事件

设备解锁后,loop线程处理unlock消息,最终会执行到存储的StorageManagerService$Lifecycle中的onUserUnlocking方法,整个流程如下:

loop() //android.os.Looper
|
|-->msg.target.dispatchMessage(msg) //android.os.Handler
   |
   |--mCallback.handleMessage(msg) //com.android.server.am.UserController
      |
      |--case USER_UNLOCK_MSG:
                mInjector.getSystemServiceManager().unlockUser(userId) //com.android.server.SystemServiceManager
                |
               ①|--onUser(UNLOCKING, userHandle) //com.android.server.SystemServiceManager
                  |
                 ②|--onUser(TimingsTraceAndSlog.newAsyncLog(), onWhat, userHandle) //com.android.server.SystemServiceManager 
                       |
                      ③|--onUser(t, onWhat, userHandle, UserHandle.USER_NULL) //com.android.server.SystemServiceManager
                          |
                          |--case UNLOCKING:
                                    service.onUserUnlocking(curUser) //com.android.server.SystemService
                                    |
                                    |--onUnlockUser(user.getUserInfo()) //com.android.server.SystemService
                                       |
                                       |--onUnlockUser(userInfo.id) //com.android.server.StorageManagerService$Lifecycle                         

1)loop线程处理Android消息队列中的消息和事件,从队列中获取事件,将unlock事件通知其他系统服务。

2)系统服务UserController管理用户和用户操作,接收到USER_UNLOCK_MSG消息后执行SystemServiceManager中的unlockUser方法。

3)unlockUser方法经过几次转换(①②③见下,只是做了参数转换。参数差异见下)。

SystemServiceManager::(final @UserIdInt int userHandle)
    --> onUser(@NonNull String onWhat, @UserIdInt int userHandle)  ①
        --> onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat,
                   @UserIdInt int userHandle)  ②
             ​​​​​​​-->onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat,
                   @UserIdInt int curUserId, @UserIdInt int prevUserId)  ③
(如果未写明方法所属class,默认所属class与前面相同,所以这些onUser方法都是SystemServiceManager类中实现的)

UserController收到USER_UNLOCK_MSG后的处理细节见其他文章。

最终③处的onUser会遍历mServices链表,执行各个service的 onUserUnlocking,简化后的代码如下:
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java#onUser

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

private void onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat,
            @UserIdInt int curUserId, @UserIdInt int prevUserId) {

        final TargetUser curUser = new TargetUser(getUserInfo(curUserId));

        final int serviceLen = mServices.size();

        // 遍历系统服务,执行每个servie的onUserUnlocking方法
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
            final String serviceName = service.getClass().getName();

            try {
                switch (onWhat) {
 
                    case UNLOCKING:
                        	service.onUserUnlocking(curUser);  // ④,存储的sevice是"StorageManagerService$Lifecycle"
                        break;
                     ……
                }
            } 
    }

《android存储2--初始化.存储service的启动》中“mount service”一节已经阐述了StorageManagerService$Lifecycle发布的流程,所以上面代码执行for循环时,SystemService service = mServices.get(i)将会获取到StorageManagerService$Lifecycle。在④处,service.onUserUnlocking(curUser)将会执行StorageManagerService$Lifecycle中的onUserUnlocking方法。

二、存储模块处理unlock事件

2.1  StorageManagerService$Lifecycle::onUserUnlocking

StorageManagerService中定义了静态内部类StorageManagerService$Lifecycle,这个内部类用来控制StorageManagerService的Lifecycle,代码见下:http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/StorageManagerService.java#246

public class StorageManagerService extends IStorageManager.Stub
        implements Watchdog.Monitor, ScreenObserver {

        public static class Lifecycle extends SystemService {
                protected StorageManagerService mStorageManagerService;

                @Override
                public void onUnlockUser(int userHandle) {
                    mStorageManagerService.onUnlockUser(userHandle);
                }
                ……
            }
}

从StorageManagerService$Lifecycle函数可知道:

  • Lifecycle继承自SystemService抽象类
  • ​​​​​​​子类Lifecycle覆写了父类SystemService的onUnlockUser方法,但没有覆写onUserUnlocking

上文④处service.onUserUnlocking(curUser)调用的是父类SystemService::onUserUnlocking方法(因为StorageManagerService$Lifecycle没有覆写onUserUnlocking),见下。

http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/SystemService.java#onUserUnlocking

// SystemService类中的实现

public void onUserUnlocking(@NonNull TargetUser user) {
    onUnlockUser(user.getUserInfo());
}

onUnlockUser(user.getUserInfo())执行SystemService::onUnlockUser(@NonNull UserInfo userInfo)方法(注意重载参数类型)。

http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/SystemService.java#onUnlockUser

// SystemService类中的实现

public void onUnlockUser(@NonNull UserInfo userInfo) {
    onUnlockUser(userInfo.id);
}

onUnlockUser(userInfo.id)执行的是被StorageManagerService$Lifecycle覆写后的方法:

http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/StorageManagerService.java#onUnlockUser

//StorageManagerService$Lifecycle类中的实现

@Override
public void onUnlockUser(int userHandle) {
    mStorageManagerService.onUnlockUser(userHandle);
}

mStorageManagerService.onUnlockUser代码:

http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/StorageManagerService.java#1162

//StorageManagerService类中的实现

1162      private void onUnlockUser(int userId) {
1163          Slog.d(TAG, "onUnlockUser " + userId);
1164  
1165          // We purposefully block here to make sure that user-specific
1166          // staging area is ready so it's ready for zygote-forked apps to
1167          // bind mount against.
1168          try {
1169              mStorageSessionController.onUnlockUser(userId); // ⑤
1170              mVold.onUserStarted(userId); // ⑥
1171              mStoraged.onUserStarted(userId); // ⑦
1172          } catch (Exception e) {
1173              Slog.wtf(TAG, e);
1174          }
1175  
1176          mHandler.obtainMessage(H_COMPLETE_UNLOCK_USER, userId).sendToTarget();
1177      }

http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/StorageManagerService.java#1162即StorageManagerService$Lifecycle中的onUserUnlocking方法最终执行到StorageManagerService::onUnlockUser方法。⑤⑥⑦是存储内部各模块处理unlock user后的逻辑,后面分段分析。

2.2  ⑤处代码mStorageSessionController.onUnlockUser分析

StorageManagerService::onUnlockUser中,mStorageManagerService.onUnlockUser执行的是StorageSessionController::onUnlockUser:

// 初始化 mExternalStorageServiceComponent变量(ComponentName类型)
StorageManagerService::onUnlockUser
    --> StorageSessionController::initExternalStorageServiceComponent

mExternalStorageServiceComponent用于提供外部存储服务,初始化后mExternalStorageServiceComponent的信息如下:

mExternalStorageServiceComponent.getPackageName()
值为:com.android.providers.media.module

mExternalStorageServiceComponent.getClassName()
值为:com.android.providers.media.fuse.ExternalStorageServiceImpl

ComponentName
值为:com.android.providers.media.module/com.android.providers.media.fuse.ExternalStorageServiceImpl

⑤处代码很简单,就是初始化了mExternalStorageServiceComponent变量。

附上mExternalStorageServiceComponent是何时使用的:

StorageSessionController::getExternalStorageServiceComponentName获取mExternalStorageServiceComponent,即com.android.providers.media.module/com.android.providers.media.fuse.ExternalStorageServiceImpl。这个服务是在provider/media/fuse目录实现的:

http://aospxref.com/android-11.0.0_r21/xref/packages/providers/MediaProvider/src/com/android/providers/media/fuse/

mExternalStorageServiceComponent在mount emulated 存储时,用于连接ExternalStorageServiceImpl服务,流程如下:

StorageManagerService::mount
   --> mStorageSessionController.onVolumeMount(pfd, vol) // StorageSessionController::onVolumeMount
         // sessionId: emulated;0
         // deviceFd代表的文件:/dev/fuse
         // vol.getPath().getPath()对应upperPath,值为:/storage/emulated
         // vol.getInternalPath().getPath()对应lowerPath,值为:/data/media
         --> connection.startSession(sessionId, deviceFd, vol.getPath().getPath(),
                    vol.getInternalPath().getPath())  // StorageUserConnection::startSession
               // sessionId, upperPath, lowerPath封装进session
               --> session = new Session(sessionId, upperPath, lowerPath)
               --> mActiveConnection.startSession(session, pfd)  // StorageUserConnection$ActiveConnection::startSession
                      // fd代表的文件:/dev/fuse
                      -->  waitForAsync((service, callback) -> service.startSession(session.sessionId,
                        FLAG_SESSION_TYPE_FUSE | FLAG_SESSION_ATTRIBUTE_INDEXABLE,
                        fd, session.upperPath, session.lowerPath, callback))
                            --> serviceFuture = connectIfNeeded()
                                   //获取外部存储组件名称com.android.providers.media.module/com.android.providers.media.fuse.ExternalStorageServiceImpl
                                   --> name = mSessionController.getExternalStorageServiceComponentName()
                                   --> mContext.bindServiceAsUser(new Intent().setComponent(name),
                                mServiceConnection,
                                Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
                                mHandlerThread.getThreadHandler(),
                                UserHandle.of(mUserId))) // ContextImpl::bindServiceAsUser
                                         --> bindServiceCommon(service, conn, flags, null, handler, null, user) // ContextImpl::bindServiceCommon
                                                 --> ActivityManager.getService().bindIsolatedService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver())

MediaProvider::openFile --> openFileCommon --> openFileAndEnforcePathPermissionsHelper中:

// MediaProvider.java  openFileAndEnforcePathPermissionsHelper函数

 // 通过ExternalStorageServiceImpl.getFuseDaemon获取daemon
 daemon = getFuseDaemonForFile(file);

 boolean shouldOpenWithFuse = daemon != null
           && daemon.shouldOpenWithFuse(filePath, true /* forRead */, 
 lowerFsFd.getFd());

 if (SystemProperties.getBoolean(PROP_FUSE, false) && shouldOpenWithFuse) {
        // 走fuse流程
        pfd = FileUtils.openSafely(getFuseFile(file), modeBits);
        try {
               lowerFsFd.close();
         } 
   } else {
         // 绕过fuse,直接走底层文件系统
         Log.i(TAG, "Using lower FS for " + filePath);
    }

2.3  ⑥处代码mVold.onUserStarted(userId)分析

StorageManagerService::onUnlockUser中,mVold.onUserStarted(userId)是核心代码,比较复杂。这篇文章简单说一下mVold.onUserStarted功能,它主要是为外部存储创建、挂载相关目录,以主用户0为例,挂载视图如下:

android存储3--初始化.unlock事件的处理

 注意,图中⑦⑧⑨⑯处在代码中bind mount挂载的分别是:
⑦:/mnt/runtime/default/emulated/0/Android/data  on  /mnt/user/0/emulated/0/Android/data
⑧:/mnt/runtime/default/emulated/0/Android/obb  on  /mnt/user/0/emulated/0/Android/obb
⑨:/mnt/runtime/write/emulated/0/Android/obb  on  /mnt/installer/0/emulated/0/Android/obb
⑯:/mnt/runtime/full/emulated  on  /mnt/pass_through/0/emulated
但mount命令看到的却是/data/media目录被bind mount到其他目录:
/data/media on /mnt/user/0/emulated/0/Android/data 
/data/media on /mnt/user/0/emulated/0/Android/obb
……

流程在下一篇文章中讲解。

2.4  StorageManagerService::onUnlockUser⑦处代码mStoraged.onUserStarted(userId)分析

StorageManagerService::onUnlockUser中,mStoraged.onUserStarted(userId)功能比较简单,为storaged加载/data/misc_ce/0/storaged.proto文件

storaged周期地将统计结果写入/data/misc_ce/0/storaged.proto(默认1小时更新一次,见DEFAULT_PERIODIC_CHORES_INTERVAL_FLUSH_PROTO宏),这个文件按照system/core/storaged/storaged.proto格式编码。执行storaged -p命令时从/data/misc_ce/0/storaged.proto读取数据输出到终端上。示例如下:

cp15:/data/misc_ce/0/storaged # ls
storaged.proto
cp15:/data/misc_ce/0/storaged # storaged -p

I/O perf history (KB/s) :  most_recent  <---------  least_recent
last 24 hours : 66468 33941 44126 35316 45839 37312
last 7 days   : 0 0 0 0 0 0 0
last 52 weeks : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
cp15:/data/misc_ce/0/storaged #

下一篇文章分析mVold.onUserStarted为外部存储挂载目录的流程。文章来源地址https://www.toymoban.com/news/detail-496915.html

到了这里,关于android存储3--初始化.unlock事件的处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 9 蓝牙协议初始化

    先讲一下Application类的使用 要使用自定义的Application,首先就是要自己新建一个Application的子类,然后把它的名字写在manifest文件里面的application标签里的android:name属性就行,如我的Application子类名字是BaseApplication,则: 1. 初始化资源 由于Application类是在APP启动的时候就启动,

    2024年02月11日
    浏览(51)
  • 数据结构与算法——顺序表(顺序存储结构)及初始化详解

    顺序表 ,全名 顺序存储结构 ,是线性表的一种。通过《什么是线性表》一节的学习我们知道,线性表用于存储逻辑关系为“一对一”的数据,顺序表自然也不例外。 不仅如此,顺序表对数据的物理存储结构也有要求。 顺序表存储数据时,会提前申请一整块足够大小的物理

    2024年02月16日
    浏览(41)
  • Android 11属性系统初始化流程

    在init进程启动的第二阶段,调用PropertyInit 对属性系统进行初始化 PropertyInit函数在systemcoreinitproperty_service.cpp 中实现 注释1处在dev下创建__properties__文件夹。注释2处会收集读取各个分区下的property_contexts文件,将读取到的信息系列化之后,写到/dev/ properties /property_info文件中。

    2024年04月09日
    浏览(64)
  • android系列-init 初始化日志

    1.FirstStageMain 2.InitKernelLogging  3.KernelLogger  4.OpenKmsg 

    2024年02月02日
    浏览(80)
  • C++结构体分别在:栈空间、堆空间、静态存储区中初始化

    1,指定每个成员的初始值 这种初始化方法的存储位置取决于定义变量的位置,如果定义在函数内,则存储在栈空间;如果定义在全局作用域,则存储在静态存储区。 2,只初始化部分成员 这种初始化方法的存储位置取决于定义变量的位置,如果定义在函数内,则存储在栈空

    2024年02月03日
    浏览(42)
  • 某60区块链安全之未初始化的存储指针实战一学习记录

    学会使用python3的web3模块 学会分析以太坊智能合约未初始化的存储指针漏洞 找到合约漏洞进行分析并形成利用 Ubuntu18.04操作机 python3 在solidity语言中,像动态的数组、struct、mapping这样的复杂数据结构是不能直接在”栈”里面保存的,因为”栈”里只能保存单独的”字”,也就

    2024年02月03日
    浏览(42)
  • 某60区块链安全之未初始化的存储指针实战二学习记录

    学会使用python3的web3模块 学会分析以太坊智能合约未初始化的存储指针漏洞 找到合约漏洞进行分析并形成利用 Ubuntu18.04操作机 python3 在solidity语言中,像动态的数组、struct、mapping这样的复杂数据结构是不能直接在”栈”里面保存的,因为”栈”里只能保存单独的”字”,也就

    2024年02月05日
    浏览(39)
  • Android OpenGL 教程——Native 工程初始化

    NDK 的适用场景官方给出三点: 平台间的 App 移植 复用现有库 对软件性能要求较高的场合比如游戏等 有两种方式可以实现 native activity。 native_activity.h android_native_app_glue 由于第二种方法启用另一个线程处理回调和输入事件,NDK 的例子中就采用了这个实现方式。       NDK 工程

    2024年02月16日
    浏览(38)
  • Android12 P2P 初始化

    目录  学习资料:Android Miracast 投屏 1. 开机log 2. WifiP2pService 启动

    2024年02月06日
    浏览(50)
  • android 添加ro属性字段并初始化

    硬件平台:QCS6125 软件平台:Android11 需求:硬件需通过硬件电路区分为多款型号,需要初始化到相应的系统属性字段展示。   这种型号属性适合做成ro类型,类似于原生系统的ro.product.model,由于android层面拿到这个具体的型号值是内核通过传递cmdline而获取的,内核层面拿到硬

    2024年01月16日
    浏览(84)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包