Exposing Context Hub service.
Adding the Context hub service. This is the service that exposes
the context hub HAL to the system. The API exposed is a System API.
Change-Id: I854141714ecd21f6386e6b15b7bc9a997483ccf6
diff --git a/core/java/android/hardware/location/ContextHubService.java b/core/java/android/hardware/location/ContextHubService.java
index a2a13c6..658d90b 100644
--- a/core/java/android/hardware/location/ContextHubService.java
+++ b/core/java/android/hardware/location/ContextHubService.java
@@ -29,175 +29,157 @@
/**
* @hide
*/
-public class ContextHubService extends Service {
+public class ContextHubService extends IContextHubService.Stub {
private static final String TAG = "ContextHubService";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static ContextHubService sSingletonInstance;
- private static final Object sSingletonInstanceLock = new Object();
+ public static final String CONTEXTHUB_SERVICE = "contexthub_service";
- private HashMap<Integer, ContextHubInfo> mHubHash;
+ private final Context mContext;
+
private HashMap<Integer, NanoAppInstanceInfo> mNanoAppHash;
- private ContextHubInfo[] mContexthubInfo;
+ private ContextHubInfo[] mContextHubInfo;
+ private IContextHubCallback mCallback;
+ public ContextHubService(Context context) {
+ mContext = context;
+ mContextHubInfo = nativeInitialize();
+
+ for (int i = 0; i < mContextHubInfo.length; i++) {
+ Log.v(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
+ + ", name: " + mContextHubInfo[i].getName());
+ }
+ }
private native int nativeSendMessage(int[] header, byte[] data);
private native ContextHubInfo[] nativeInitialize();
- private int onMessageReceipt(int[] header, byte[] data) {
+ @Override
+ public int registerCallback(IContextHubCallback callback) throws RemoteException{
+ mCallback = callback;
return 0;
}
- private void initialize() {
- mContexthubInfo = nativeInitialize();
- mHubHash = new HashMap<Integer, ContextHubInfo>();
- for (int i = 0; i < mContexthubInfo.length; i++) {
- mHubHash.put(i + 1, mContexthubInfo[i]); // Avoiding zero
- }
- }
+ private int onMessageReceipt(int[] header, byte[] data) {
+ if (mCallback != null) {
+ // TODO : Defend against unexpected header sizes
+ // Add abstraction for magic numbers
+ // onMessageRecipt should pass the right arguments
+ ContextHubMessage msg = new ContextHubMessage(header[0], header[1], data);
- private ContextHubService(Context context) {
- initialize();
- Log.d(TAG, "Created from " + context.toString());
- }
-
- public static ContextHubService getInstance(Context context) {
- synchronized (sSingletonInstanceLock) {
- if (sSingletonInstance == null) {
- sSingletonInstance = new ContextHubService(context);
+ try {
+ mCallback.onMessageReceipt(0, 0, msg);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e + " when calling remote callback");
+ return -1;
}
- return sSingletonInstance;
+ } else {
+ Log.d(TAG, "Message Callback is NULL");
+ }
+
+ return 0;
+ }
+
+ @Override
+ public int[] getContextHubHandles() throws RemoteException {
+ int [] returnArray = new int[mContextHubInfo.length];
+
+ for (int i = 0; i < returnArray.length; ++i) {
+ returnArray[i] = i + 1; //valid handles from 1...n
+ Log.d(TAG, String.format("Hub %s is mapped to %d",
+ mContextHubInfo[i].getName(), returnArray[i]));
+ }
+
+ return returnArray;
+ }
+
+ @Override
+ public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException {
+ contextHubHandle -= 1;
+ if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) {
+ return null; // null means fail
+ }
+
+ return mContextHubInfo[contextHubHandle];
+ }
+
+ @Override
+ public int loadNanoApp(int contextHubHandle, NanoApp app) throws RemoteException {
+ contextHubHandle -= 1;
+
+ if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) {
+ return -1; // negative handle are invalid, means failed
+ }
+
+ // Call Native interface here
+ int[] msgHeader = new int[8];
+ msgHeader[0] = contextHubHandle;
+ msgHeader[1] = app.getAppId();
+ msgHeader[2] = app.getAppVersion();
+ msgHeader[3] = ContextHubManager.MSG_LOAD_NANO_APP;
+ msgHeader[4] = 0; // Loading hints
+
+ return nativeSendMessage(msgHeader, app.getAppBinary());
+ }
+
+ @Override
+ public int unloadNanoApp(int nanoAppInstanceHandle) throws RemoteException {
+ NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstanceHandle);
+ if (info == null) {
+ return -1; //means failed
+ }
+
+ // Call Native interface here
+ int[] msgHeader = new int[8];
+ msgHeader[0] = info.getContexthubId();
+ msgHeader[1] = ContextHubManager.MSG_UNLOAD_NANO_APP;
+ msgHeader[2] = info.getHandle();
+
+ return nativeSendMessage(msgHeader, null);
+ }
+
+ @Override
+ public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle) throws RemoteException {
+ // This assumes that all the nanoAppInfo is current. This is reasonable
+ // for the use cases for tightly controlled nanoApps.
+ if (mNanoAppHash.containsKey(nanoAppInstanceHandle)) {
+ return mNanoAppHash.get(nanoAppInstanceHandle);
+ } else {
+ return null;
}
}
@Override
- public void onCreate() {
- super.onCreate();
+ public int[] findNanoAppOnHub(int hubHandle, NanoAppFilter filter) throws RemoteException {
+ ArrayList<Integer> foundInstances = new ArrayList<Integer>();
+
+ for(Integer nanoAppInstance : mNanoAppHash.keySet()) {
+ NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance);
+
+ if(filter.testMatch(info)){
+ foundInstances.add(nanoAppInstance);
+ }
+ }
+
+ int[] retArray = new int[foundInstances.size()];
+ for (int i = 0; i < foundInstances.size(); i++) {
+ retArray[i] = foundInstances.get(i).intValue();
+ }
+
+ return retArray;
}
@Override
- public IBinder onBind(Intent intent) {
- return null;
+ public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg) throws RemoteException {
+ int[] msgHeader = new int[8];
+ msgHeader[0] = ContextHubManager.MSG_DATA_SEND;
+ msgHeader[1] = hubHandle;
+ msgHeader[2] = nanoAppHandle;
+ msgHeader[3] = msg.getMsgType();
+ msgHeader[4] = msg.getVersion();
+
+ return nativeSendMessage(msgHeader, msg.getData());
}
-
- private final IContextHubService.Stub mBinder = new IContextHubService.Stub() {
-
- private IContextHubCallback callback;
-
- @Override
- public int registerCallBack(IContextHubCallback callback) throws RemoteException{
- this.callback = callback;
- return 0;
- }
-
- @Override
- public int[] getContextHubHandles() throws RemoteException {
- int [] returnArray = new int[mHubHash.size()];
- int i = 0;
- for (int key : mHubHash.keySet()) {
- // Add any filtering here
- returnArray[i] = key;
- i++;
- }
- return returnArray;
- }
-
- @Override
- public ContextHubInfo getContextHubInfo(int contexthubHandle) throws RemoteException {
- return mHubHash.get(contexthubHandle);
- }
-
- @Override
- public int loadNanoApp(int hubHandle, NanoApp app) throws RemoteException {
- if (!mHubHash.containsKey(hubHandle)) {
- return -1;
- } else {
- // Call Native interface here
- int[] msgHeader = new int[8];
- msgHeader[0] = ContextHubManager.MSG_LOAD_NANO_APP;
- msgHeader[1] = app.getAppId();
- msgHeader[2] = app.getAppVersion();
- msgHeader[3] = 0; // LOADING_HINTS
- msgHeader[4] = hubHandle;
-
- int handle = nativeSendMessage(msgHeader, app.getAppBinary());
-
- // if successful, add an entry to mNanoAppHash
-
- if(handle > 0) {
- return 0;
- } else {
-
- return -1;
- }
- }
- }
-
- @Override
- public int unloadNanoApp(int nanoAppInstanceHandle) throws RemoteException {
- if(!mNanoAppHash.containsKey(nanoAppInstanceHandle)) {
- return -1;
- } else {
- NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstanceHandle);
- // Call Native interface here
- int[] msgHeader = new int[8];
- msgHeader[0] = ContextHubManager.MSG_UNLOAD_NANO_APP;
- msgHeader[1] = info.getContexthubId();
- msgHeader[2] = info.getHandle();
-
- int result = nativeSendMessage(msgHeader, null);
- // if successful, remove the entry in mNanoAppHash
- if(result == 0) {
- mNanoAppHash.remove(nanoAppInstanceHandle);
- }
- return(result);
- }
- }
-
- @Override
- public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle) throws RemoteException {
- // This assumes that all the nanoAppInfo is current. This is reasonable
- // for the use cases for tightly controlled nanoApps.
- //
- if(!mNanoAppHash.containsKey(nanoAppInstanceHandle)) {
- return(mNanoAppHash.get(nanoAppInstanceHandle));
- } else {
- return null;
- }
- }
-
- @Override
- public int[] findNanoAppOnHub(int hubHandle, NanoAppFilter filter) throws RemoteException {
- ArrayList<Integer> foundInstances = new ArrayList<Integer>();
-
- for(Integer nanoAppInstance : mNanoAppHash.keySet()) {
- NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance);
-
- if(filter.testMatch(info)){
- foundInstances.add(nanoAppInstance);
- }
- }
-
- int[] retArray = new int[foundInstances.size()];
- for (int i = 0; i < foundInstances.size(); i++) {
- retArray[i] = foundInstances.get(i).intValue();
- }
-
- return retArray;
- }
-
- @Override
- public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg) throws RemoteException {
- int[] msgHeader = new int[8];
- msgHeader[0] = ContextHubManager.MSG_DATA_SEND;
- msgHeader[1] = hubHandle;
- msgHeader[2] = nanoAppHandle;
- msgHeader[3] = msg.getMsgType();
- msgHeader[4] = msg.getVersion();
-
- return (nativeSendMessage(msgHeader, msg.getData()));
- }
- };
}
+