一、这里拿电池温度警告框的例子来学习一下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是对应的,这个是调用的核心的。