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层