contexhub的代码包括AP和SLPI上的两部分:
contexthub有两个相关的接口层分别是contexthub对应的IContextHubService.hal 和[email protected]对应的IContexthub,两者分别生成client/server代码; IContextHubService的server端调用IContexthub的client端向下通信;IContexthub调用IContextHubService注册的回调函数向上通信。
frameworks/base/core/java/android/hardware/location/
contexthub service的接口定义 xxx.aidl生成对用的client/server 其中主要是IContextHubService.aidl,其中java代码是怎样使用 contexthub service.
IContextHubCallback.aidl
IContextHubClient.aidl
IContextHubClientCallback.aidl
IContextHubService.aidl
IContextHubTransactionCallback.aidl
ContextHubClient.java
ContextHubClientCallback.java
ContextHubInfo.aidl
ContextHubInfo.java
ContextHubManager.java
ContextHubMessage.aidl
ContextHubMessage.java
ContextHubTransaction.java
frameworks/base/services/core/java/com/android/server/location/
该路径的文件实现具体的ContextHubService,实现接口功能,为实现接口功能就有和hidl生成的client通信
ContextHubClientBroker.java
ContextHubClientManager.java
ContextHubService.java
ContextHubServiceTransaction.java
ContextHubServiceUtil.java
ContextHubTransactionManager.java
该aidl文件生成的对应的ava文件位于
out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl
生成的接口类和Stub是个abstract不能被创建对象
public static abstract class Stub extends android.os.Binder implements android.hardware.location.IContextHubService
具体的接口都是在这里实现的
frameworks/base/services/core/java/com/android/server/location/ContextHubService.java
public class ContextHubService extends IContextHubService.Stub{
}
1] IContexthub.getService(true )调用静态函数获得IContexthub的client,用于和IContexthub的通信
2] ContextHubService.java实现 class ContextHubServiceCallback extends IContexthubCallback.Stub并向hidl层注册,这里注册的函数调用了clientManager和transManager等等,这样回调函数最终到client端。
3] contexthub系统service的注册和启动
4] ContextHubService的创建:看下图中的创建
能看出 ContextHubService的实现中有ContextHubClientManager但它管理的是ContextHubClientBroker 而不是从名字上看更贴切的ContextHubClient,这里只关注ContextHubService的实现中使用的IContextHubClient
interface IContextHubClient {
// Sends a message to a nanoapp
int sendMessageToNanoApp(in NanoAppMessage message);
// Closes the connection with the Context Hub
void close();
}
oneway interface IContextHubClientCallback {
// Callback invoked when receiving a message from a nanoapp.
void onMessageFromNanoApp(in NanoAppMessage message);
// Callback invoked when the attached Context Hub has reset.
void onHubReset();
// Callback invoked when a nanoapp aborts at the attached Context Hub.
void onNanoAppAborted(long nanoAppId, int abortCode);
// Callback invoked when a nanoapp is loaded at the attached Context Hub.
void onNanoAppLoaded(long nanoAppId);
// Callback invoked when a nanoapp is unloaded from the attached Context Hub.
void onNanoAppUnloaded(long nanoAppId);
// Callback invoked when a nanoapp is enabled at the attached Context Hub.
void onNanoAppEnabled(long nanoAppId);
// Callback invoked when a nanoapp is disabled at the attached Context Hub.
void onNanoAppDisabled(long nanoAppId);
}
ContextHubClient是通过ContextHubClientManger来管理的,当调用mClientManager.registerClient()时注册client回调函数。
/**
* A class that manages registration/unregistration of clients and manages messages to/from clients.
*
* @hide
*/
class ContextHubClientManager {
ContextHubClientManager(
Context context, IContexthub contextHubProxy) {
mContext = context;
mContextHubProxy = contextHubProxy;
}
1] registerClient: 引入host endpoint ID
IContextHubClient registerClient(//由clientCallback, contextHubId创建Client
IContextHubClientCallback clientCallback, int contextHubId) {
ContextHubClientBroker broker = createNewClientBroker(clientCallback, contextHubId);
try {
broker.attachDeathRecipient();
}
Log.d(TAG, "Registered client with host endpoint ID " + broker.getHostEndPointId());
return IContextHubClient.Stub.asInterface(broker);
}
private synchronized ContextHubClientBroker createNewClientBroker(
IContextHubClientCallback clientCallback, int contextHubId) {
ContextHubClientBroker broker = null;
int id = mNextHostEndpointId;//同一个HubId上可能有多个NanoApp
for (int i = 0; i <= MAX_CLIENT_ID; i++) {
if (!mHostEndPointIdToClientMap.containsKey((short)id)) {
broker = new ContextHubClientBroker(
mContext, mContextHubProxy, this, contextHubId, (short)id, clientCallback);
mHostEndPointIdToClientMap.put((short)id, broker);
mNextHostEndpointId = (id == MAX_CLIENT_ID) ? 0 : id + 1;
break;
}
id = (id == MAX_CLIENT_ID) ? 0 : id + 1;
}
return broker;
}
2] callback: 广播的形式发出还是发给某个具体的nanoApp
void onMessageFromNanoApp(int contextHubId, ContextHubMsg message) {
NanoAppMessage clientMessage = ContextHubServiceUtil.createNanoAppMessage(message);
//广播消息:同一个HubId
if (clientMessage.isBroadcastMessage()) {
broadcastMessage(contextHubId, clientMessage);
} else {//某个具体的NanoApp
ContextHubClientBroker proxy = mHostEndPointIdToClientMap.get(message.hostEndPoint);
if (proxy != null) {
proxy.sendMessageToClient(clientMessage);
} else {
Log.e(TAG, "Cannot send message to unregistered client (host endpoint ID = "
+ message.hostEndPoint + ")");
}
}
}
}
/**
* A class that acts as a broker for the ContextHubClient, which handles messaging and life-cycle
* notification callbacks. This class implements the IContextHubClient object, and the implemented
* APIs must be thread-safe.??
*
* @hide
*/
public class ContextHubClientBroker extends IContextHubClient.Stub
implements IBinder.DeathRecipient {
/*
* The ID of the hub that this client is attached to.
*/
private final int mAttachedContextHubId;
/*
* The host end point ID of this client. ??
*/
private final short mHostEndPointId;
1] 构造函数
/* package */
ContextHubClientBroker(
Context context, IContexthub contextHubProxy, ContextHubClientManager clientManager,
int contextHubId, short hostEndPointId, IContextHubClientCallback callback) {
mContext = context;
mContextHubProxy = contextHubProxy;
mClientManager = clientManager;
mAttachedContextHubId = contextHubId;
mHostEndPointId = hostEndPointId;
mCallbackInterface = callback;
}
2] IContextHubClient
public int sendMessageToNanoApp(NanoAppMessage message) {
ContextHubServiceUtil.checkPermissions(mContext);
int result;
if (mConnectionOpen.get()) {//这里不是hubID而是HostEndPointId
ContextHubMsg messageToNanoApp = ContextHubServiceUtil.createHidlContextHubMessage(
mHostEndPointId, message);
try {
result = mContextHubProxy.sendMessageToHub(mAttachedContextHubId, messageToNanoApp);
}
}
return ContextHubServiceUtil.toTransactionResult(result);
}
public void close() {
if (mConnectionOpen.getAndSet(false)) {
mClientManager.unregisterClient(mHostEndPointId);
}
}
3] 封装一层对IContextHubClientCallback的调用(判断是否连接状态)
void onNanoAppLoaded(long nanoAppId) {
if (mConnectionOpen.get()) {
try {
mCallbackInterface.onNanoAppLoaded(nanoAppId);
}
}
}
}
ContextHubService.java实现了 IContexthubCallback
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; pw.println("Dumping ContextHub Service"); pw.println(""); // dump ContextHubInfo pw.println("=================== CONTEXT HUBS ===================="); for (ContextHubInfo hubInfo : mContextHubIdToInfoMap.values()) { pw.println(hubInfo); } pw.println(""); pw.println("=================== NANOAPPS ===================="); // Dump nanoAppHash for (NanoAppInstanceInfo info : mNanoAppStateManager.getNanoAppInstanceInfoCollection()) { pw.println(info); } // dump eventLog }
Dumping ContextHub Service
=================== CONTEXT HUBS ====================
ID/handle : 0, Name : CHRE on SLPI
Vendor : Google, Toolchain : Hexagon Tools 8.x (clang 5.0.0), Toolchain version: 0x5000000
PlatformVersion : 0x0, SwVersion : 1.2.1, CHRE platform ID: 0x476f6f676c000002
PeakMips : 350.0, StoppedPowerDraw : 0.0 mW, PeakPowerDraw : 15.0 mW, MaxPacketLength : 4000 Bytes
=================== NANOAPPS ====================