StorageManagerService.java中的mVold.mount

android源码:android-11.0.0_r21(网址:Search (aospxref.com)

一、问题

2243行mVold.mount执行的是哪个mount函数?
StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java

2239      private void mount(VolumeInfo vol) {
2240          try {
2241              // TODO(b/135341433): Remove paranoid logging when FUSE is stable
2242              Slog.i(TAG, "Mounting volume " + vol);

                  //这里的mVold.mount执行的是哪个函数????
2243              mVold.mount(vol.id, vol.mountFlags, vol.mountUserId, new IVoldMountCallback.Stub() {
2244                  @Override
2245                  public boolean onVolumeChecking(FileDescriptor fd, String path,
2246                          String internalPath) {
2247                      vol.path = path;
2248                      vol.internalPath = internalPath;
2249                      ParcelFileDescriptor pfd = new ParcelFileDescriptor(fd);
2250                      try {
2251                          mStorageSessionController.onVolumeMount(pfd, vol);
2252                          return true;
2253                      } catch (ExternalStorageServiceException e) {

二、分析过程

1,找到mVold变量

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

569      private volatile IVold mVold;

2,找到Ivold类型

http://aospxref.com/android-11.0.0_r21/xref/system/vold/binder/android/os/IVold.aidl

 这是个aidl文件,Android Interface Definition Language,即Android接口定义语言,aidl文件中会定义很多函数,用于多进程间远程调用。

aidl文件编译后,生成.java文件,并且会生成一个Stub内部类。我们可以在android编译的out目录搜索IVold$Stub.java,如果没有这个文件,可以搜索IVold$Stub.class,反编译class后得到IVold$Stub.java,IVold$Stub.java文件部分内容如下:

public abstract class IVold$Stub extends Binder implements IVold {
    ……
    static final int TRANSACTION_mount = 15;

    public void mount(String var1, int var2, int var3, IVoldMountCallback var4) throws RemoteException;

    ……

   public IVold$Stub() {
      this.attachInterface(this, "android.os.IVold");
   }

   //这里是关键
   public static IVold asInterface(IBinder obj) {
      if(obj == null) {
         return null;
      } else {
         IInterface iin = obj.queryLocalInterface("android.os.IVold");
         return (IVold)(iin != null && iin instanceof IVold?(IVold)iin:new Proxy(obj));
      }
   }

   public IBinder asBinder() {
      return this;
   }
    ……
}

从上面代码片段可以得到如下信息:
1)public abstract class IVold$Stub extends Binder implements IVold定义了一个抽象类IVold$Stub,该抽象类继承自Binder类,同时实现了IVold接口。它的定义中包含了抽象方法,这些方法的具体实现需要在该类的子类中完成
2)从IVold$Stub可知,Stub是一个内部类。Stub类会根据AIDL文件中定义的接口自动生成,并实现该接口的方法,同时提供一个静态的asInterface()方法和一个默认的构造方法。在客户端通过bindService()方法绑定服务时,会通过getService()方法获取到一个Binder对象,通过asInterface()方法将其转换为服务端实现的IMyService接口。在服务端,Binder对象会通过Stub类的onTransact()方法来处理客户端发送的请求。

举例来说,A绑定了服务端B的service,那么A可以通过下面方法执行B中的方法:

private volatile IVold mVold;
//根据binder找到对应的aidl interface
mVold = IVold.Stub.asInterface(Binder-x)
//执行服务端方法
mVold.mount()

3,IVold赋值

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

1928	private void connectVold() {
1929          IBinder binder = ServiceManager.getService("vold");
1930          if (binder != null) {
1931              try {
1932                  binder.linkToDeath(new DeathRecipient() {
1933                      @Override
1934                      public void binderDied() {
1935                          Slog.w(TAG, "vold died; reconnecting");
1936                          mVold = null;
1937                          connectVold();
1938                      }
1939                  }, 0);
1940              } catch (RemoteException e) {
1941                  binder = null;
1942              }
1943          }
1944  
1945          if (binder != null) {
1946              mVold = IVold.Stub.asInterface(binder);
1947              try {
1948                  mVold.setListener(mListener);
1949              } catch (RemoteException e) {
1950                  mVold = null;
1951                  Slog.w(TAG, "vold listener rejected; trying again", e);
1952              }
1953          } else {
1954              Slog.w(TAG, "vold not found; trying again");
1955          }
1956  
1957          if (mVold == null) {
1958              BackgroundThread.getHandler().postDelayed(() -> {
1959                  connectVold();
1960              }, DateUtils.SECOND_IN_MILLIS);
1961          } else {
1962              onDaemonConnected();
1963          }
1964      }

1929行获取vold service的IBinder对象。一个Service在启动时会创建一个IBinder对象,其他进程可以通过这个IBinder对象与Service通信。因此,getService()方法返回的是服务的IBinder对象,以便客户端可以通过它与服务进行通信。具体来说,客户端可以使用服务的IBinder对象来调用服务提供的接口方法。

1946行根据IBinder找到aidl定义的mVold(是一个interface),找到mVold后,就可以调用他实现的方法了,比如mVold.mount。总结就是,找到了vold service就能找到具体的函数实现了,所以现在的问题是vold service在哪、是什么?

4,vold service是什么

如果没看过vold的启动流程,在茫茫大海的android代码里搜vold service还是比较困难的,现在直接给答案,后面再简单描述vold的启动流程。

http://aospxref.com/android-11.0.0_r21/xref/system/vold/VoldNativeService.h#31

 可以看到VoldNativeService.h文件中定义了VoldNativeService类。这个类有很多函数定义,我们重点看getServiceName方法。VoldNativeService.getServiceName返回的就是“vold”,所以VoldNativeService类中的函数就是aidl接口中各个函数的具体实现。比如mVold.mount的具体实现就是VoldNativeService::mount(见VoldNativeService.cpp)。

三、vold进程的启动及vold service的注册

vold的源头在 /etc/init/hw/init.rc,系统开机后会执行这个文件,启动vold进程。init.rc对应的源码路径为: http://aospxref.com/android-11.0.0_r21/xref/system/vold/vold.rc

文件内容:

1 service vold /system/bin/vold \
2         --blkid_context=u:r:blkid:s0 --blkid_untrusted_context=u:r:blkid_untrusted:s0 \
3         --fsck_context=u:r:fsck:s0 --fsck_untrusted_context=u:r:fsck_untrusted:s0
4     class core
5     ioprio be 2
6     writepid /dev/cpuset/foreground/tasks
7     shutdown critical
8     group root reserved_disk
vold相关的源码在system/vold目录下,/system/bin/vold是从http://aospxref.com/android-11.0.0_r21/xref/system/vold/main.cpp的main函数开始执行的。
主要关注vold进程向ServiceManager注册service的过程。
54  int main(int argc, char** argv) {

        ……
 
113      ATRACE_BEGIN("VoldNativeService::start");
114      if (android::vold::VoldNativeService::start() != android::OK) {
115          LOG(ERROR) << "Unable to start VoldNativeService";
116          exit(1);
117      }

        ……

114行VoldNativeService::start()启动VoldNativeService,并将其注册到ServiceManager中。


http://aospxref.com/android-11.0.0_r21/xref/system/vold/VoldNativeService.cpp#120

120  status_t VoldNativeService::start() {
121      IPCThreadState::self()->disableBackgroundScheduling(true);
122      status_t ret = BinderService<VoldNativeService>::publish();
123      if (ret != android::OK) {
124          return ret;
125      }
126      sp<ProcessState> ps(ProcessState::self());
127      ps->startThreadPool();
128      ps->giveThreadPoolName();
129      return android::OK;
130  }

122行BinderService<VoldNativeService>::publish()执行具体的注册操作。

http://aospxref.com/android-11.0.0_r21/xref/frameworks/native/include/binder/BinderService.h#34

33  template<typename SERVICE>
34  class BinderService
35  {
36  public:
37      static status_t publish(bool allowIsolated = false,
38                              int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
39          sp<IServiceManager> sm(defaultServiceManager());
40          return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
41                                dumpFlags);

根据33行typename SERVICE及 VoldNativeService::start()中122行BinderService<VoldNativeService>::publish(),可以知道SERVICE就是VoldNativeService,所以SERVICE::getServiceName()就是VoldNativeService::getServiceName()。通过第二节第4段【vold service是什么】可知getServiceName()将返回字符串“vold”。总结就是,VoldNativeService以“vold”名称注册到ServiceManager中,VoldNativeService类中实现了很多函数,这些函数就是跨进程调用的具体函数,比如mVold.mount。

四、mVold.mount是什么

在第二节第3段【IVold赋值】,1929行ServiceManager.getService("vold")获取vold service关联的binder,也就是VoldNativeService了,然后1946行mVold = IVold.Stub.asInterface(binder)获取binder对象关联的aidl接口,所以mVold.mount就是VoldNativeService中mount函数http://aospxref.com/android-11.0.0_r21/xref/system/vold/VoldNativeService.cpp#mount

262  binder::Status VoldNativeService::mount(
263          const std::string& volId, int32_t mountFlags, int32_t mountUserId,
264          const android::sp<android::os::IVoldMountCallback>& callback) {
265      ENFORCE_SYSTEM_OR_ROOT;
266      CHECK_ARGUMENT_ID(volId);
267      ACQUIRE_LOCK;
268  
269      auto vol = VolumeManager::Instance()->findVolume(volId);
270      if (vol == nullptr) {
271          return error("Failed to find volume " + volId);
272      }
273  
274      vol->setMountFlags(mountFlags);
275      vol->setMountUserId(mountUserId);
276  
277      vol->setMountCallback(callback);
278      int res = vol->mount();
279      vol->setMountCallback(nullptr);
280  
281      if (res != OK) {
282          return translate(res);
283      }
284  
285      if ((mountFlags & MOUNT_FLAG_PRIMARY) != 0) {
286          res = VolumeManager::Instance()->setPrimary(vol);
287          if (res != OK) {
288              return translate(res);
289          }
290      }
291      return translate(OK);
292  }
您好!要在Java实现WebSocket的连接和消息传递,您可以使用Java的WebSocket API。下面是一个简单的示例代码来展示如何创建和使用WebSocket连接: ```java import javax.websocket.*; import java.net.URI; @ClientEndpoint public class WebSocketClient { @OnOpen public void onOpen(Session session) { System.out.println("WebSocket连接已打开: " + session.getId()); } @OnMessage public void onMessage(String message, Session session) { System.out.println("收到消息: " + message); } @OnClose public void onClose(Session session, CloseReason closeReason) { System.out.println("WebSocket连接已关闭: " + closeReason.getReasonPhrase()); } public static void main(String[] args) { WebSocketContainer container = ContainerProvider.getWebSocketContainer(); String uri = "ws://your-websocket-url"; try { Session session = container.connectToServer(WebSocketClient.class, URI.create(uri)); session.getBasicRemote().sendText("Hello, WebSocket!"); Thread.sleep(5000); session.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 请将`your-websocket-url`替换为您要连接的WebSocket服务器的URL。在`onOpen`方法,您可以执行一些操作来处理连接打开事件。`onMessage`方法将处理接收到的消息。`onClose`方法将处理连接关闭事件。 在`main`方法,我们使用`WebSocketContainer`来创建WebSocket连接,并指定要连接的URL。然后,我们发送一条消息,并在5秒后关闭连接。 希望这可以帮助到您!如果您有任何其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值