Android C++语言 通过Binder通信调用activity: [android.app.IActivityManager] 服务发广播

Posted 海月汐辰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android C++语言 通过Binder通信调用activity: [android.app.IActivityManager] 服务发广播相关的知识,希望对你有一定的参考价值。

一、这里拿电池温度警告框的例子来学习一下C++语言 通过Binder通信调用activity: [android.app.IActivityManager] 服务发广播。

二、vendor\\mediatek\\proprietary\\frameworks\\opt\\batterywarning\\batterywarning.cpp 发广播的地方。

bool sendBroadcastMessage(String8 action, int value)

    ALOGD("sendBroadcastMessage(): Action: %s, Value: %d ", (char *)(action.string()), value);
    sp<IServiceManager> sm = defaultServiceManager();
    sp<IBinder> am = sm->getService(String16("activity"));
    if (am != NULL) 
        Parcel data, reply;
        data.writeInterfaceToken(String16("android.app.IActivityManager"));
        data.writeStrongBinder(NULL);
        // Add for match AMS change on O
        data.writeInt32(1);
        // intent begin
        data.writeString8(action); // action
        data.writeInt32(0); // URI data type
        data.writeString8(NULL, 0); // type
        data.writeString8(NULL, 0); // mIdentifier
        data.writeInt32(0x04000000); // flags: FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
        data.writeString8(NULL, 0); // package name
        data.writeString8(NULL, 0); // component name
        data.writeInt32(0); // source bound - size
        data.writeInt32(0); // categories - size
        data.writeInt32(0); // selector - size
        data.writeInt32(0); // clipData - size
        data.writeInt32(-2); // contentUserHint: -2 -> UserHandle.USER_CURRENT
        data.writeInt32(-1); // bundle extras length
        data.writeInt32(0x4C444E42); // 'B' 'N' 'D' 'L'
        int oldPos = data.dataPosition();
        data.writeInt32(1);  // size
        // data.writeInt32(0); // VAL_STRING, need to remove because of analyze common intent
        data.writeString16(String16(TYPE));
        data.writeInt32(1); // VAL_INTEGER
        data.writeInt32(value);
        int newPos = data.dataPosition();
        data.setDataPosition(oldPos - 8);
        data.writeInt32(newPos - oldPos); // refill bundle extras length
        data.setDataPosition(newPos);
        // intent end
        data.writeString8(NULL, 0); // resolvedType
        data.writeStrongBinder(NULL); // resultTo
        data.writeInt32(0); // resultCode
        data.writeString8(NULL, 0); // resultData
        data.writeInt32(-1); // resultExtras
        data.writeString8(NULL, 0); // permission
        data.writeInt32(0); // appOp
        data.writeInt32(-1); // option
        data.writeInt32(1); // serialized: != 0 -> ordered
        data.writeInt32(0); // sticky
        data.writeInt32(-2); // userId: -2 -> UserHandle.USER_CURRENT

        status_t ret = am->transact(IBinder::FIRST_CALL_TRANSACTION + 13, data, &reply); // BROADCAST_INTENT_TRANSACTION
        if (ret == NO_ERROR) 
            int exceptionCode = reply.readExceptionCode();
            if (exceptionCode) 
                ALOGE("sendBroadcastMessage(%s) caught exception %d\\n",
                        (char *)(action.string()), exceptionCode);
                return false;
            
         else 
            return false;
        
     else 
        ALOGE("getService() couldn't find activity service!\\n");
        return false;
    
    return true;

 三、从上面可以知道会调用一个activity服务,adb shell service list查看系统的service。

 四、那这个service哪里来的呢?咱们一步一步来分析一些吧。

        4、1 服务文件frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\ActivityManagerService.java

         4、2  frameworks\\base\\core\\java\\android\\app\\IActivityManager.aidl 文件

         4、3 开启服务

               frameworks\\base\\services\\java\\com\\android\\server\\SystemServer.java里面调用setSystemProcess打开服务。

 

 

          4、4 看一下setSystemProcess的内容,   public static final String ACTIVITY_SERVICE = "activity";

          4、5 到这里就可以知道服务名是activity: [android.app.IActivityManager]是如何而来的了。

四、上面提到status_t ret = am->transact(IBinder::FIRST_CALL_TRANSACTION + 13, data, &reply); // BROADCAST_INTENT_TRANSACTION

这个会调用哪个函数呢?上面的13是如何而来的呢?这个得分析一下frameworks\\base\\core\\java\\android\\app\\IActivityManager.aidl,可以知道    int broadcastIntent(in IApplicationThread caller, in Intent intent,
            in String resolvedType, in IIntentReceiver resultTo, int resultCode,
            in String resultData, in Bundle map, in String[] requiredPermissions,
            int appOp, in Bundle options, boolean serialized, boolean sticky, int userId);对应第13项。仔细观察会发现transact后面的data参数跟broadcastIntent是对应的,这个是调用的核心的。

 

以上是关于Android C++语言 通过Binder通信调用activity: [android.app.IActivityManager] 服务发广播的主要内容,如果未能解决你的问题,请参考以下文章

android binder深入分析之承上启下的native层

系统稳定性 - 调优3.4 常见Binder相关异常调优总结

没有 addService() 的 C++ Binder

Android之Binder通信篇

初识Android进程间通信之----Binder机制

Android Binder(C语言版本)