zoukankan      html  css  js  c++  java
  • Android native进程间通信实例-binder篇之——HAL层访问JAVA层的服务

    有一天在群里聊天的时候,有人提出一个问题,怎样才能做到HAL层访问JAVA层的接口?刚好我不会,所以做了一点研究。

    之前的文章末尾部分说过了service call 可以用来调试系统的binder服务。 传送门: Android native进程间通信实例-binder篇之——简单的单工通信

    这次可以用到这个命令了!

    1. 随机选取一个java层的服务。

    adb shell 中输入命令 service list,选取一个服务来做研究,这次看中的是 textservices, 注意第一个服务 bysysui 后面的 "[ ]" 里面没有内容,不能选取这样的服务来做这次的研究。

    2. 搜寻这个服务相关的源码。

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

    frameworks/base/core/java/com/android/internal/textservice/ITextServicesManager.aidl

    out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/textservice/ITextServicesManager.java

    3. 选择一个接口用于被 HAL 层的代码访问

    可以知道TextServicesManagerService.java 中 有一行 public class TextServicesManagerService extends ITextServicesManager.Stub,

    所以我从 ITextServicesManager.aidl 来选择要访问的接口, 这次选的就是 boolean isSpellCheckerEnabled(); 这个函数应该就是返回一个bool变量而已,越简单越好。

    4. 搜寻 binder 中 transact 需要输入的 code

    因为吧啦吧啦的原因(可以自行去别的博文搜索原理,本系列博文侧重实际操作),所以在out目录下可以获取到每个服务中各个接口访问锁需要传入的code。

    在out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/textservice/ITextServicesManager.java中可以发现熟悉的onTransact接口,

    同时发现调用 sSpellCheckerEnabled 的code为TRANSACTION_isSpellCheckerEnabled,

    它的定义是:static final int TRANSACTION_isSpellCheckerEnabled = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);

    因为android.os.IBinder.FIRST_CALL_TRANSACTION的值是1, 所以可知code为 8

    5. 使用service call 来撩一下 isSpellCheckerEnabled 

    可以看到Parcel有两个值,第一个是00000000,第二个是00000001.

    再看看ITextServicesManager.java中TRANSACTION_isSpellCheckerEnabled这个code的处理,果然write了两次,而第二次writeInt的值就是我们需要获取的bool值了!

    ITextServicesManager.java

    case TRANSACTION_isSpellCheckerEnabled:
    {
        data.enforceInterface(DESCRIPTOR);
        boolean _result = this.isSpellCheckerEnabled();
        reply.writeNoException();
        reply.writeInt(((_result)?(1):(0)));
        return true;
    }
    

      

    按照之前分析的方法,传送门:Android native进程间通信实例-binder篇之——用parcel传输数组

    1. 首先data.enforceInterface 传进去了一个组字符串 private static final java.lang.String DESCRIPTOR = "com.android.internal.textservice.ITextServicesManager"; 

    感觉这组字符串是和校验有关了,查看了Parcel.cpp 源码, 发现enforceInterface果然是对比字符串用的,在这个接口的上面有个接口名字叫做 writeInterfaceToken,

    所以到时候要用 writeInterfaceToken 来写这组字符串用于比对校验。

    2. writeNoException 和 writeInt 最终调用的是 Parcel.cpp 里面writeInt32,所以reply部分要 readInt32 两次。

    6. HAL层代码怎么写

    就直接在之前写的mybinderclient.cpp 上面贴源码吧transct 前写校验字符串,然后传入code 值为8,最后readInt32 两次,第二次就是要读取的JAVA 层服务isSpellCheckerEnabled  的值啦!

    #include <binder/IServiceManager.h>
    #include <binder/IPCThreadState.h>
    #include <binder/Parcel.h>
    #include <binder/IInterface.h>
    
    #include<stdio.h>
    
    #define LOG_TAG "binderclient"
    
    using namespace android;
    
    
    int main(int argc, char** argv)
    {
        static  int TRANSACTION_isSpellCheckerEnabled = (/*android.os.IBinder.FIRST_CALL_TRANSACTION*/1 + 7);
    
        sp<IBinder> ITextServicesBinder = defaultServiceManager()->getService(String16("textservices"));
    
        Parcel ITextServicesData, ITextServicesReply;
    
        ITextServicesData.writeInterfaceToken(String16("com.android.internal.textservice.ITextServicesManager"));
        
        ITextServicesBinder->transact(TRANSACTION_isSpellCheckerEnabled, ITextServicesData, &ITextServicesReply);
    
        int ret = ITextServicesReply.readInt32();
        int ret2 = ITextServicesReply.readInt32();
    
        printf("ret = %d, isSpellCheckerEnabled = %d
    ", ret, ret2);
    
        return 0;
    }
    

      

    执行结果:

    这次在HAL层通过binder 访问 JAVA 层服务的简单例子就讲解到这里,希望大家看完以后能够触类旁通,在这个例子上面得到启发。

    希望读者多多吐槽,我们一起共同进步!!

  • 相关阅读:
    Prometheus 简介
    Cassandra spring data 试用
    nginx fastcgi 优化
    mysql 用户管理
    js之iframe子页面与父页面通信
    ORACLE中SID和SERVICE_NAME的区别
    报“ Got minus one from a read call”的错误
    linux下重启oracle服务:监听器和实例
    25种提高网页加载速度的方法和技巧
    如何让你的网页加载时间降低到 1s 内
  • 原文地址:https://www.cnblogs.com/songsongman/p/11100760.html
Copyright © 2011-2022 走看看