Binder JNI注册

  • 通过上两个篇章,对于Binder的整体框架,以及其中驱动层的逻辑梳理之后,接下来需要对Binder的JNI层注册进行一个梳理

1. Zygote进程的启动

  1. 解析init.rc文件

    • Zygote是由init进程通过解析对应的init.zygote.rc文件进行创建的,这里可以看一下 init.zygote32.rc 文件

      • 文件路径:android/system/core/rootdir/init.zygote32.rc
      //这里会去找app_process文件夹下的app_main.cpp文件
      service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
          class main
          priority -20
          user root
          group root readproc reserved_disk
          socket zygote stream 660 root system
          socket usap_pool_primary stream 660 root system
          onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
          onrestart write /sys/power/state on
          onrestart restart audioserver
          onrestart restart cameraserver
          onrestart restart media
          onrestart restart netd
          onrestart restart wificond
          writepid /dev/cpuset/foreground/tasks
      
      
  2. 执行app_main.cpp文件

    • 文件路径:android/frameworks/base/cmds/app_process/app_main.cpp

      int main(int argc, char* const argv[])
      {
          ....
          AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
          ....
          while (i < argc) {
              const char* arg = argv[i++];
              if (strcmp(arg, "--zygote") == 0) {		//这里会去判断当下启动的是否是zygote
                  zygote = true;		//如果是zygote,那么将zygote标志为置为true
                  niceName = ZYGOTE_NICE_NAME;
              } else if (strcmp(arg, "--start-system-server") == 0) {
                  startSystemServer = true;
              } else if (strcmp(arg, "--application") == 0) {
                  application = true;
              } else if (strncmp(arg, "--nice-name=", 12) == 0) {
                  niceName.setTo(arg + 12);
              } else if (strncmp(arg, "--", 2) != 0) {
                  className.setTo(arg);
                  break;
              } else {
                  --i;
                  break;
              }
          }
          ...
              
          if (zygote) {	//这里判断如果是为zygote,那么会去启动ZygoteInit
              runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
          } else if (className) {
              runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
          } else {
              fprintf(stderr, "Error: no class name or --zygote supplied.\n");
              app_usage();
              LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
          }
      }
      

      app_main.cpp中的main()函数中,最终调用了 runtime.start(),而runtime就是 AppRuntime

      class AppRuntime : public AndroidRuntime {}
      

      AppRuntime继承了 AndroidRuntime类,所以最终调用的是 AndroidRuntime.start()函数

2. Binder JNI的注册

  • 如上面的分析,接下来会去调用 AndroidRuntime.start()函数

    • 文件路径:android/framework/base/core/jni/AndroidRuntime.cpp

      void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
       {
           .....
           /*
            * Register android functions.
            */
           if (startReg(env) < 0) {		//注册方法
               ALOGE("Unable to register all android natives\n");
               return;
           }
           .....
       }
       
       /*
        * Register android native functions with the VM.
        */
       /*static*/ int AndroidRuntime::startReg(JNIEnv* env)
       {
           ATRACE_NAME("RegisterAndroidNatives");
           /*
            * This hook causes all future threads created in this process to be
            * attached to the JavaVM.  (This needs to go away in favor of JNI
            * Attach calls.)
            */
           androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
       
           ALOGV("--- registering native functions ---\n");
       
           /*
            * Every "register" function calls one or more things that return
            * a local reference (e.g. FindClass).  Because we haven't really
            * started the VM yet, they're all getting stored in the base frame
            * and never released.  Use Push/Pop to manage the storage.
            */
           env->PushLocalFrame(200);
       
           if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {		//通过此处进行系统JNI的注册
               env->PopLocalFrame(NULL);
               return -1;
           }
           env->PopLocalFrame(NULL);
       
           //createJavaThread("fubar", quickTest, (void*) "hello");
       
           return 0;
       }
       
       static const RegJNIRec gRegJNI[] = {
           ....
           REG_JNI(register_android_os_Binder),
           ....
       }
       
       static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
       {
           for (size_t i = 0; i < count; i++) {
               if (array[i].mProc(env) < 0) {		//这里会循环注册所有的系统JNI,当下只关注Binder的注册
       #ifndef NDEBUG
                   ALOGD("----------!!! %s failed to load\n", array[i].mName);
       #endif
                   return -1;
               }
           }
           return 0;
       }
      

      接下来会调用到register_android_os_Binder()函数

3. register_android_os_Binder()

  • 文件路径:android/framework/base/core/jni/android_util_Binder.cpp

    int register_android_os_Binder(JNIEnv* env)
    {
        //调用下面三个函数实现注册
        if (int_register_android_os_Binder(env) < 0)
            return -1;
        if (int_register_android_os_BinderInternal(env) < 0)
            return -1;
        if (int_register_android_os_BinderProxy(env) < 0)
            return -1;
    
        jclass clazz = FindClassOrDie(env, "android/util/Log");
        gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
                "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");
    
        clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
        gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
                                                                     "(Ljava/io/FileDescriptor;)V");
    
        clazz = FindClassOrDie(env, "android/os/StrictMode");
        gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
                "onBinderStrictModePolicyChange", "(I)V");
    
        clazz = FindClassOrDie(env, "java/lang/Thread");
        gThreadDispatchOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gThreadDispatchOffsets.mDispatchUncaughtException = GetMethodIDOrDie(env, clazz,
                "dispatchUncaughtException", "(Ljava/lang/Throwable;)V");
        gThreadDispatchOffsets.mCurrentThread = GetStaticMethodIDOrDie(env, clazz, "currentThread",
                "()Ljava/lang/Thread;");
    
        return 0;
    }
    

    int_register_android_os_Binder() int_register_android_os_BinderInternal() int_register_android_os_BinderProxy()三个函数其实做的工作是一样的,都是完成java层对应Binder类的注册,从而实现JAVA层和Native层相关函数可以相互调用,下面以int_register_android_os_Binder()函数进行示例解析:

    static const JNINativeMethod gBinderMethods[] = {
         /* name, signature, funcPtr */
        // @CriticalNative
        { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
        // @CriticalNative
        { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
        // @CriticalNative
        { "isHandlingTransaction", "()Z", (void*)android_os_Binder_isHandlingTransaction },
        // @CriticalNative
        { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
        { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
        // @CriticalNative
        { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
        // @CriticalNative
        { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
        // @CriticalNative
        { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid },
        // @CriticalNative
        { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid },
        // @CriticalNative
        { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource },
        { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource },
        { "markVintfStability", "()V", (void*)android_os_Binder_markVintfStability},
        { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
        { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
        { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
        { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable },
        { "getExtension", "()Landroid/os/IBinder;", (void*)android_os_Binder_getExtension },
        { "setExtension", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension },
    };
    
    const char* const kBinderPathName = "android/os/Binder";        //sdk中的Binder类路径,即该cpp文件对应的是那个JAVA类
    
    static int int_register_android_os_Binder(JNIEnv* env)
    {
        jclass clazz = FindClassOrDie(env, kBinderPathName);
    
        //下面这三步都是在将Binder.java类相关的信息记录到gBinderOffsets结构中,可以类比为反射获取类信息
        //经过这一层注册,将Binder.java类信息记录在gBinderOffsets结构体中之后,就可以通过gBinderOffsets结构体,在JNI中调用Java层对应的函数
        gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
        gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
            "()Ljava/lang/String;");
        gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
    
        //入上面的gBinderMethods数组定义,此处是进行JNI层函数和java层函数的映射关联,后续想找到对应java函数的JNI层实现,
        //需要通过这个关系表找到java函数对应的JNI层的函数名
        //经过这一层注册,就可以根据Java函数找到对应的JNI层函数
        return RegisterMethodsOrDie(
            env, kBinderPathName,
            gBinderMethods, NELEM(gBinderMethods));
    }
    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值