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/api/current.txt b/api/current.txt
index e6a5b1a..e253ae1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9327,6 +9327,7 @@
field public int flags;
field public int largestWidthLimitDp;
field public java.lang.String manageSpaceActivityName;
+ field public java.lang.String minSdkVersion;
field public java.lang.String nativeLibraryDir;
field public java.lang.String permission;
field public java.lang.String processName;
diff --git a/api/system-current.txt b/api/system-current.txt
index e70b6f6..8bd4e50 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8408,6 +8408,7 @@
field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
field public static final java.lang.String CONSUMER_IR_SERVICE = "consumer_ir";
+ field public static final java.lang.String CONTEXTHUB_SERVICE = "contexthub";
field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
field public static final int CONTEXT_INCLUDE_CODE = 1; // 0x1
field public static final int CONTEXT_RESTRICTED = 4; // 0x4
@@ -9649,6 +9650,7 @@
field public int flags;
field public int largestWidthLimitDp;
field public java.lang.String manageSpaceActivityName;
+ field public java.lang.String minSdkVersion;
field public java.lang.String nativeLibraryDir;
field public java.lang.String permission;
field public java.lang.String processName;
@@ -15288,37 +15290,31 @@
method public java.lang.String getToolchain();
method public int getToolchainVersion();
method public java.lang.String getVendor();
- method public void setId(int);
- method public void setMemoryRegions(android.hardware.location.MemoryRegion[]);
- method public void setName(java.lang.String);
- method public void setPeakMips(float);
- method public void setPeakPowerDrawMw(float);
- method public void setPlatformVersion(int);
- method public void setSleepPowerDrawMw(float);
- method public void setStaticSwVersion(int);
- method public void setStoppedPowerDrawMw(float);
- method public void setSupportedSensors(int[]);
- method public void setToolchain(java.lang.String);
- method public void setToolchainVersion(int);
- method public void setVendor(java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.hardware.location.ContextHubInfo> CREATOR;
}
public final class ContextHubManager {
method public java.lang.Integer[] findNanoAppOnHub(int, android.hardware.location.NanoAppFilter);
- method public int[] getContexthubHandles();
- method public android.hardware.location.ContextHubInfo getContexthubInfo(int);
+ method public int[] getContextHubHandles();
+ method public android.hardware.location.ContextHubInfo getContextHubInfo(int);
method public android.hardware.location.NanoAppInstanceInfo getNanoAppInstanceInfo(int);
method public int loadNanoApp(int, android.hardware.location.NanoApp);
+ method public int registerContextHubCallback(android.hardware.location.ContextHubManager.ContextHubCallback);
+ method public int registerContextHubCallback(android.hardware.location.ContextHubManager.ContextHubCallback, android.os.Handler);
method public int sendMessage(int, int, android.hardware.location.ContextHubMessage);
method public int unloadNanoApp(int);
+ method public int unregisterContextHubCallback(android.hardware.location.ContextHubManager.ContextHubCallback);
field public static final int ANY_HUB = -1; // 0xffffffff
field public static final int MSG_DATA_SEND = 3; // 0x3
field public static final int MSG_LOAD_NANO_APP = 1; // 0x1
field public static final int MSG_UNLOAD_NANO_APP = 2; // 0x2
}
+ public abstract class ContextHubManager.ContextHubCallback {
+ ctor public ContextHubManager.ContextHubCallback();
+ }
+
public class ContextHubMessage {
ctor public ContextHubMessage(int, int, byte[]);
method public int describeContents();
diff --git a/api/test-current.txt b/api/test-current.txt
index 40e1156..a7b434c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -9336,6 +9336,7 @@
field public int flags;
field public int largestWidthLimitDp;
field public java.lang.String manageSpaceActivityName;
+ field public java.lang.String minSdkVersion;
field public java.lang.String nativeLibraryDir;
field public java.lang.String permission;
field public java.lang.String processName;
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 6c0b69c..9d7f724 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -51,6 +51,7 @@
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.IHdmiControlService;
import android.hardware.input.InputManager;
+import android.hardware.location.ContextHubManager;
import android.hardware.usb.IUsbManager;
import android.hardware.usb.UsbManager;
import android.hardware.radio.RadioManager;
@@ -765,6 +766,14 @@
public SystemHealthManager createService(ContextImpl ctx) {
return new SystemHealthManager();
}});
+
+ registerService(Context.CONTEXTHUB_SERVICE, ContextHubManager.class,
+ new CachedServiceFetcher<ContextHubManager>() {
+ @Override
+ public ContextHubManager createService(ContextImpl ctx) {
+ return new ContextHubManager(ctx.getOuterContext(),
+ ctx.mMainThread.getHandler().getLooper());
+ }});
}
/**
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 825dd5b..e80f7c8 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2681,6 +2681,7 @@
HARDWARE_PROPERTIES_SERVICE,
//@hide: SOUND_TRIGGER_SERVICE,
SHORTCUT_SERVICE,
+ //@hide: CONTEXTHUB_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ServiceName {}
@@ -3585,6 +3586,18 @@
public static final String SHORTCUT_SERVICE = "shortcut";
/**
+ * Use with {@link #getSystemService} to retrieve a {@link
+ * android.hardware.location.ContextHubManager} for accessing context hubs.
+ *
+ * @see #getSystemService
+ * @see android.hardware.location.ContextHubManager
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String CONTEXTHUB_SERVICE = "contexthub";
+
+ /**
* Use with {@link #getSystemService} to retrieve a
* {@link android.os.health.SystemHealthManager} for accessing system health (battery, power,
* memory, etc) metrics.
diff --git a/core/java/android/hardware/location/ContextHubInfo.aidl b/core/java/android/hardware/location/ContextHubInfo.aidl
index 1a9221a..8de03da 100644
--- a/core/java/android/hardware/location/ContextHubInfo.aidl
+++ b/core/java/android/hardware/location/ContextHubInfo.aidl
@@ -15,7 +15,7 @@
*/
package android.hardware.location;
-/*
-@hide
-*/
+/**
+ * @hide
+ */
parcelable ContextHubInfo;
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
index e47c541..644e29f 100644
--- a/core/java/android/hardware/location/ContextHubInfo.java
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -23,7 +23,7 @@
/**
* @hide
- */
+ */
@SystemApi
public class ContextHubInfo {
private int mId;
@@ -58,6 +58,8 @@
* set the context hub unique identifer
*
* @param id - unique system wide identifier for the hub
+ *
+ * @hide
*/
public void setId(int id) {
mId = id;
@@ -75,7 +77,9 @@
/**
* set a string as the hub name
*
- * @param String - the name for the hub
+ * @param name - the name for the hub
+ *
+ * @hide
*/
public void setName(String name) {
mName = name;
@@ -93,7 +97,9 @@
/**
* set a string as the vendor name
*
- * @param String - a name for the vendor
+ * @param vendor - a name for the vendor
+ *
+ * @hide
*/
public void setVendor(String vendor) {
mVendor = vendor;
@@ -111,7 +117,9 @@
/**
* set tool chain string
*
- * @param String - description of the tool chain
+ * @param toolchain - description of the tool chain
+ *
+ * @hide
*/
public void setToolchain(String toolchain) {
mToolchain = toolchain;
@@ -130,6 +138,8 @@
* set platform version
*
* @param platformVersion - platform version number
+ *
+ * @hide
*/
public void setPlatformVersion(int platformVersion) {
mPlatformVersion = platformVersion;
@@ -148,6 +158,8 @@
* set platform software version
*
* @param staticSwVersion - platform static s/w version number
+ *
+ * @hide
*/
public void setStaticSwVersion(int staticSwVersion) {
mStaticSwVersion = staticSwVersion;
@@ -166,6 +178,8 @@
* set the tool chain version number
*
* @param toolchainVersion - tool chain version number
+ *
+ * @hide
*/
public void setToolchainVersion(int toolchainVersion) {
mToolchainVersion = toolchainVersion;
@@ -184,6 +198,8 @@
* set the peak mips that this hub can support
*
* @param peakMips - peak mips this hub can deliver
+ *
+ * @hide
*/
public void setPeakMips(float peakMips) {
mPeakMips = peakMips;
@@ -206,6 +222,8 @@
* Set the power consumed by the hub in stopped state
*
* @param stoppedPowerDrawMw - stopped power in milli watts
+ *
+ * @hide
*/
public void setStoppedPowerDrawMw(float stoppedPowerDrawMw) {
mStoppedPowerDrawMw = stoppedPowerDrawMw;
@@ -230,6 +248,8 @@
* Set the sleep power draw in milliwatts
*
* @param sleepPowerDrawMw - sleep power draw in milliwatts.
+ *
+ * @hide
*/
public void setSleepPowerDrawMw(float sleepPowerDrawMw) {
mSleepPowerDrawMw = sleepPowerDrawMw;
@@ -250,6 +270,8 @@
*
* @param peakPowerDrawMw - peak power draw of the hub in
* milliwatts.
+ *
+ * @hide
*/
public void setPeakPowerDrawMw(float peakPowerDrawMw) {
mPeakPowerDrawMw = peakPowerDrawMw;
@@ -281,6 +303,8 @@
* set the supported sensors on this hub
*
* @param supportedSensors - supported sensors on this hub
+ *
+ * @hide
*/
public void setSupportedSensors(int[] supportedSensors) {
mSupportedSensors = Arrays.copyOf(supportedSensors, supportedSensors.length);
@@ -292,6 +316,8 @@
* @param memoryRegions - memory regions information
*
* @see MemoryRegion
+ *
+ * @hide
*/
public void setMemoryRegions(MemoryRegion[] memoryRegions) {
mMemoryRegions = Arrays.copyOf(memoryRegions, memoryRegions.length);
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 301b2e4..38a760a 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -15,18 +15,24 @@
*/
package android.hardware.location;
+import android.Manifest;
import android.annotation.SystemApi;
-import android.hardware.location.NanoAppInstanceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.ServiceConnection;
-import android.Manifest;
+import android.hardware.location.ContextHubService;
+import android.hardware.location.NanoAppInstanceInfo;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* A class that exposes the Context hubs on a device to
@@ -48,9 +54,12 @@
private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '"
+ HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware";
- private Context mContext;
+ private final Context mContext;
+ private final Looper mMainLooper;
private IContextHubService mContextHubService;
private boolean mContextHubConnected;
+ private ContextHubCallback mCallback;
+ private Handler mCallbackHandler;
/**
* A special context hub identifer meaning any possible hub on
@@ -70,19 +79,32 @@
*/
public static final int MSG_DATA_SEND = 3;
+ /**
+ * an interface to receive asynchronous communication from the context hub
+ */
+ public abstract class ContextHubCallback {
+ /**
+ * callback function called on message receipt from context hub
+ *
+ * @param hubId id of the hub of the message
+ * @param nanoAppId identifier for the app that sent the message
+ * @param msg the context hub message
+ *
+ * @see ContextHubMessage
+ */
+ abstract void onMessageReceipt(int hubId, int nanoAppId, ContextHubMessage msg);
+ }
/**
* Get a handle to all the context hubs in the system
* @return array of context hub handles
*/
- public int[] getContexthubHandles() {
+ public int[] getContextHubHandles() {
int[] retVal = null;
- if(mContextHubConnected) {
- try {
- retVal = mContextHubService.getContextHubHandles();
- }catch (RemoteException e) {
- Log.e (TAG, "Could not fetch context hub handles :" + e.toString());
- }
+ try {
+ retVal = getBinder().getContextHubHandles();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not fetch context hub handles :" + e.toString());
}
return retVal;
}
@@ -96,17 +118,15 @@
*
* @see ContextHubInfo
*/
- public ContextHubInfo getContexthubInfo(int contexthubHandle) {
+ public ContextHubInfo getContextHubInfo(int contexthubHandle) {
ContextHubInfo retVal = null;
- if(mContextHubConnected) {
- try {
- retVal = mContextHubService.getContextHubInfo(contexthubHandle);
- }catch (RemoteException e) {
- Log.e (TAG, "Could not fetch context hub info :" + e.toString());
- }
+ try {
+ retVal = getBinder().getContextHubInfo(contexthubHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not fetch context hub info :" + e.toString());
}
- return(retVal);
+ return retVal;
}
/**
@@ -122,13 +142,14 @@
*/
public int loadNanoApp(int hubHandle, NanoApp app) {
int retVal = -1;
+ if (app == null) {
+ return retVal;
+ }
- if(mContextHubConnected) {
- try {
- retVal = mContextHubService.loadNanoApp(hubHandle, app);
- }catch (RemoteException e) {
- Log.e (TAG, "Could not fetch load nanoApp :" + e.toString());
- }
+ try {
+ retVal = getBinder().loadNanoApp(hubHandle, app);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not fetch load nanoApp :" + e.toString());
}
return retVal;
@@ -144,12 +165,10 @@
public int unloadNanoApp(int nanoAppInstanceHandle) {
int retVal = -1;
- if(mContextHubConnected) {
- try {
- retVal = mContextHubService.unloadNanoApp(nanoAppInstanceHandle);
- }catch (RemoteException e) {
- Log.e (TAG, "Could not fetch unload nanoApp :" + e.toString());
- }
+ try {
+ retVal = getBinder().unloadNanoApp(nanoAppInstanceHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not fetch unload nanoApp :" + e.toString());
}
return retVal;
@@ -168,12 +187,10 @@
public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle) {
NanoAppInstanceInfo retVal = null;
- if(mContextHubConnected) {
- try {
- retVal = mContextHubService.getNanoAppInstanceInfo(nanoAppInstanceHandle);
- }catch (RemoteException e) {
- Log.e (TAG, "Could not fetch nanoApp info :" + e.toString());
- }
+ try {
+ retVal = getBinder().getNanoAppInstanceInfo(nanoAppInstanceHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not fetch nanoApp info :" + e.toString());
}
return retVal;
@@ -193,16 +210,14 @@
int[] temp;
Integer[] retVal = null;
- if(mContextHubConnected) {
- try {
- temp = mContextHubService.findNanoAppOnHub(hubHandle, filter);
- retVal = new Integer[temp.length];
- for (int i = 0; i < temp.length; i++) {
- retVal[i] = temp[i];
- }
- }catch (RemoteException e) {
- Log.e (TAG, "Could not query nanoApp instance :" + e.toString());
+ try {
+ temp = getBinder().findNanoAppOnHub(hubHandle, filter);
+ retVal = new Integer[temp.length];
+ for (int i = 0; i < temp.length; i++) {
+ retVal[i] = temp[i];
}
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not query nanoApp instance :" + e.toString());
}
return retVal;
@@ -221,58 +236,129 @@
*
* @return int 0 on success, -1 otherwise
*/
- public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg) {
+ public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage message) {
int retVal = -1;
- if(mContextHubConnected) {
- try {
- retVal = mContextHubService.sendMessage(hubHandle, nanoAppHandle, msg);
- }catch (RemoteException e) {
- Log.e (TAG, "Could not fetch send message :" + e.toString());
- }
+ try {
+ retVal = getBinder().sendMessage(hubHandle, nanoAppHandle, message);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not fetch send message :" + e.toString());
}
return retVal;
}
+ /**
+ * Set a callback to receive messages from the context hub
+ *
+ *
+ * @param callback Callback object
+ *
+ * @see ContextHubCallback
+ *
+ * @return int 0 on success, -1 otherwise
+ */
+ public int registerContextHubCallback(ContextHubCallback callback) {
+ return registerContextHubCallback(callback, null);
+ }
+
+ /**
+ * Set a callback to receive messages from the context hub
+ *
+ *
+ * @param callback Callback object
+ * @param hander Hander object
+ *
+ * @see ContextHubCallback
+ *
+ * @return int 0 on success, -1 otherwise
+ */
+ public int registerContextHubCallback(ContextHubCallback callback, Handler handler) {
+ synchronized(this) {
+ if (mCallback != null) {
+ Log.e(TAG, "Max number of callbacks reached!");
+ return -1;
+ }
+ mCallback = callback;
+ mCallbackHandler = handler;
+ }
+ return 0;
+ }
+
+ /**
+ * Unregister a callback for receive messages from the context
+ * hub
+ *
+ * @see ContextHubCallback
+ *
+ * @param callback method to deregister
+ *
+ * @return int 0 on success, -1 otherwise
+ */
+ public int unregisterContextHubCallback(ContextHubCallback callback) {
+ synchronized(this) {
+ if (callback != mCallback) {
+ Log.e(TAG, "Cannot recognize callback!");
+ return -1;
+ }
+
+ mCallback = null;
+ mCallbackHandler = null;
+ }
+ return 0;
+ }
+
private void checkPermissions() {
mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE);
}
private IContextHubCallback.Stub mClientCallback = new IContextHubCallback.Stub() {
@Override
- public void onMessageReceipt(int hubId, int nanoAppId, ContextHubMessage msg) throws RemoteException {
-
+ public void onMessageReceipt(final int hubId, final int nanoAppId,
+ final ContextHubMessage message) throws RemoteException {
+ if (mCallback != null) {
+ synchronized(this) {
+ final ContextHubCallback callback = mCallback;
+ Handler handler = mCallbackHandler == null ?
+ new Handler(mMainLooper) : mCallbackHandler;
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onMessageReceipt(hubId, nanoAppId, message);
+ }
+ });
+ }
+ } else {
+ Log.d(TAG, "Context hub manager client callback is NULL");
+ }
}
};
- private ContextHubManager(Context context) {
+ /** @hide */
+ public ContextHubManager(Context context, Looper mainLooper) {
checkPermissions();
mContext = context;
- mContextHubConnected = false;
+ mMainLooper = mainLooper;
+
+ IBinder b = ServiceManager.getService(ContextHubService.CONTEXTHUB_SERVICE);
+ if (b != null) {
+ mContextHubService = IContextHubService.Stub.asInterface(b);
+
+ try {
+ getBinder().registerCallback(mClientCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not register callback:" + e.toString());
+ }
+
+ } else {
+ Log.d(TAG, "failed to getService");
+ }
}
- private ServiceConnection mServiceConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- mContextHubService = IContextHubService.Stub.asInterface(service);
- mContextHubConnected = true;
-
- // Register our Callback
- try {
- mContextHubService.registerCallBack(mClientCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "Could not register callback with context hub service :" + e.toString());
- }
- Log.d(TAG, "contexthub manager connected to " + name.toString());
+ private IContextHubService getBinder() throws RemoteException {
+ if (mContextHubService == null) {
+ throw new RemoteException("Service not connected.");
}
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- mContextHubService = null;
- mContextHubConnected = false;
- Log.d(TAG, "contexthub manager disconnected from " + name.toString());
- }
- };
-
+ return mContextHubService;
+ }
}
diff --git a/core/java/android/hardware/location/ContextHubMessage.aidl b/core/java/android/hardware/location/ContextHubMessage.aidl
index 915f1ec..56704e7 100644
--- a/core/java/android/hardware/location/ContextHubMessage.aidl
+++ b/core/java/android/hardware/location/ContextHubMessage.aidl
@@ -15,8 +15,8 @@
*/
package android.hardware.location;
-/*
-@hide
-*/
+/**
+ * @hide
+ */
parcelable ContextHubMessage;
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()));
- }
- };
}
+
diff --git a/core/java/android/hardware/location/IContextHubCallback.aidl b/core/java/android/hardware/location/IContextHubCallback.aidl
index 45b1ef4..141fcf6 100644
--- a/core/java/android/hardware/location/IContextHubCallback.aidl
+++ b/core/java/android/hardware/location/IContextHubCallback.aidl
@@ -18,7 +18,9 @@
import android.hardware.location.ContextHubMessage;
-/** @hide */
+/**
+ * @hide
+ */
oneway interface IContextHubCallback {
void onMessageReceipt(int hubId, int nanoAppId, in ContextHubMessage msg);
}
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
index b2db0b2..ff8c1d0 100644
--- a/core/java/android/hardware/location/IContextHubService.aidl
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -24,11 +24,13 @@
import android.hardware.location.NanoAppFilter;
import android.hardware.location.IContextHubCallback;
-/** @hide */
+/**
+ * @hide
+ */
interface IContextHubService {
// register a callback to receive messages
- int registerCallBack(in IContextHubCallback callback);
+ int registerCallback(in IContextHubCallback callback);
// Gets a list of available context hub handles
int[] getContextHubHandles();
diff --git a/core/java/android/hardware/location/MemoryRegion.java b/core/java/android/hardware/location/MemoryRegion.java
index e8c7615..d100de2 100644
--- a/core/java/android/hardware/location/MemoryRegion.java
+++ b/core/java/android/hardware/location/MemoryRegion.java
@@ -23,7 +23,6 @@
/**
* @hide
*/
-
@SystemApi
public class MemoryRegion implements Parcelable{
diff --git a/core/java/android/hardware/location/NanoApp.aidl b/core/java/android/hardware/location/NanoApp.aidl
index d32c44a..9df9a08 100644
--- a/core/java/android/hardware/location/NanoApp.aidl
+++ b/core/java/android/hardware/location/NanoApp.aidl
@@ -15,7 +15,7 @@
*/
package android.hardware.location;
-/*
-@hide
-*/
+/**
+ * @hide
+ */
parcelable NanoApp;
diff --git a/core/java/android/hardware/location/NanoApp.java b/core/java/android/hardware/location/NanoApp.java
index 36d181f..b447b62 100644
--- a/core/java/android/hardware/location/NanoApp.java
+++ b/core/java/android/hardware/location/NanoApp.java
@@ -13,16 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package android.hardware.location;
-
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-/**
- * A class describing nano apps.
+/** A class describing nano apps.
* A nano app is a piece of executable code that can be
* downloaded onto a specific architecture. These are targtted
* for low power compute domains on a device.
diff --git a/core/java/android/hardware/location/NanoAppFilter.aidl b/core/java/android/hardware/location/NanoAppFilter.aidl
index cc6d475..5f10201 100644
--- a/core/java/android/hardware/location/NanoAppFilter.aidl
+++ b/core/java/android/hardware/location/NanoAppFilter.aidl
@@ -15,7 +15,7 @@
*/
package android.hardware.location;
-/*
-@hide
-*/
+/**
+ * @hide
+ */
parcelable NanoAppFilter;
diff --git a/core/java/android/hardware/location/NanoAppFilter.java b/core/java/android/hardware/location/NanoAppFilter.java
index ac341e4..369f9e4 100644
--- a/core/java/android/hardware/location/NanoAppFilter.java
+++ b/core/java/android/hardware/location/NanoAppFilter.java
@@ -110,8 +110,9 @@
return true;
}
/**
+ * Test match method.
*
- * @param nano app instance info
+ * @param info nano app instance info
*
* @return true if this is a match, false otherwise
*/
diff --git a/core/java/android/hardware/location/NanoAppInstanceInfo.aidl b/core/java/android/hardware/location/NanoAppInstanceInfo.aidl
index c8c40d7..2db5566 100644
--- a/core/java/android/hardware/location/NanoAppInstanceInfo.aidl
+++ b/core/java/android/hardware/location/NanoAppInstanceInfo.aidl
@@ -15,7 +15,7 @@
*/
package android.hardware.location;
-/*
-@hide
-*/
-parcelable NanoAppInstanceInfo;
\ No newline at end of file
+/**
+ * @hide
+ */
+parcelable NanoAppInstanceInfo;
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 623b603..8ef1a22 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -161,6 +161,7 @@
android_hardware_UsbDevice.cpp \
android_hardware_UsbDeviceConnection.cpp \
android_hardware_UsbRequest.cpp \
+ android_hardware_location_ContextHubService.cpp \
android_hardware_location_ActivityRecognitionHardware.cpp \
android_util_FileObserver.cpp \
android/opengl/poly_clip.cpp.arm \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 2a04526..e4acbbe 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -95,6 +95,7 @@
extern int register_android_hardware_UsbDeviceConnection(JNIEnv *env);
extern int register_android_hardware_UsbRequest(JNIEnv *env);
extern int register_android_hardware_location_ActivityRecognitionHardware(JNIEnv* env);
+extern int register_android_hardware_location_ContextHubService(JNIEnv* env);
extern int register_android_media_AudioRecord(JNIEnv *env);
extern int register_android_media_AudioSystem(JNIEnv *env);
@@ -1358,6 +1359,7 @@
REG_JNI(register_android_hardware_UsbDeviceConnection),
REG_JNI(register_android_hardware_UsbRequest),
REG_JNI(register_android_hardware_location_ActivityRecognitionHardware),
+ REG_JNI(register_android_hardware_location_ContextHubService),
REG_JNI(register_android_media_AudioRecord),
REG_JNI(register_android_media_AudioSystem),
REG_JNI(register_android_media_AudioTrack),
diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp
new file mode 100644
index 0000000..8724729
--- /dev/null
+++ b/core/jni/android_hardware_location_ContextHubService.cpp
@@ -0,0 +1,344 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "context_hub.h"
+
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <jni.h>
+#include "JNIHelp.h"
+#include "core_jni_helpers.h"
+#include "stdint.h"
+#include "stdlib.h"
+
+
+namespace android {
+
+namespace {
+
+// TODO: We should share this array_length function widely around Android
+// code.
+/*
+ * Finds the length of a statically-sized array using template trickery that
+ * also prevents it from being applied to the wrong type.
+ */
+template <typename T, size_t N>
+constexpr size_t array_length(T (&)[N]) { return N; }
+
+struct jniInfo_s {
+ JavaVM *vm;
+ jclass contextHubInfoClass;
+ jclass contextHubServiceClass;
+ jclass memoryRegionsClass;
+
+ jobject jContextHubService;
+
+ jmethodID msgReceiptCallBack;
+
+ jmethodID contextHubInfoCtor;
+ jmethodID contextHubInfoSetId;
+ jmethodID contextHubInfoSetName;
+ jmethodID contextHubInfoSetVendor;
+ jmethodID contextHubInfoSetToolchain;
+ jmethodID contextHubInfoSetPlatformVersion;
+ jmethodID contextHubInfoSetStaticSwVersion;
+ jmethodID contextHubInfoSetToolchainVersion;
+ jmethodID contextHubInfoSetPeakMips;
+ jmethodID contextHubInfoSetStoppedPowerDrawMw;
+ jmethodID contextHubInfoSetSleepPowerDrawMw;
+ jmethodID contextHubInfoSetPeakPowerDrawMw;
+ jmethodID contextHubInfoSetSupportedSensors;
+ jmethodID contextHubInfoSetMemoryRegions;
+
+ jmethodID contextHubServiceMsgReceiptCallback;
+};
+
+struct context_hub_info_s {
+ int cookie;
+ int numHubs;
+ const struct context_hub_t *hubs;
+ struct context_hub_module_t *contextHubModule;
+};
+
+struct contextHubServiceDb_s {
+ int initialized;
+ context_hub_info_s hubInfo;
+ jniInfo_s jniInfo;
+};
+
+} // unnamed namespace
+
+static contextHubServiceDb_s db;
+
+int context_hub_callback(uint32_t hub_id, const struct hub_message_t *msg,
+ void *cookie);
+
+static void initContextHubService() {
+ int err = 0;
+ db.hubInfo.hubs = NULL;
+ db.hubInfo.numHubs = 0;
+ db.hubInfo.cookie = 0;
+ int i;
+
+ err = hw_get_module(CONTEXT_HUB_MODULE_ID,
+ (hw_module_t const**)(&db.hubInfo.contextHubModule));
+
+ if (err) {
+ ALOGE("** Could not load %s module : err %s", CONTEXT_HUB_MODULE_ID,
+ strerror(-err));
+ }
+
+ if (db.hubInfo.contextHubModule) {
+ ALOGD("Fetching hub info");
+ db.hubInfo.numHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
+ &db.hubInfo.hubs);
+
+ if (db.hubInfo.numHubs > 0) {
+ for (i = 0; i < db.hubInfo.numHubs; i++) {
+ // TODO : Event though one cookie is OK for now, lets change
+ // this to be one per hub
+ db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id,
+ context_hub_callback,
+ &db.hubInfo.cookie);
+ }
+ }
+ }
+}
+
+static int onMessageReceipt(int *header, int headerLen, char *msg, int msgLen) {
+ JNIEnv *env;
+ if ((db.jniInfo.vm)->AttachCurrentThread(&env, NULL) != JNI_OK) {
+ return -1;
+ }
+
+ jbyteArray jmsg = env->NewByteArray(msgLen);
+ jintArray jheader = env->NewIntArray(headerLen);
+
+ env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg);
+ env->SetIntArrayRegion(jheader, 0, headerLen, (jint *)header);
+
+
+ return env->CallIntMethod(db.jniInfo.jContextHubService,
+ db.jniInfo.contextHubServiceMsgReceiptCallback,
+ jheader, jmsg);
+}
+
+int context_hub_callback(uint32_t hub_id, const struct hub_message_t *msg,
+ void *cookie) {
+ int msgHeader[4];
+
+ msgHeader[0] = msg->message_type;
+ msgHeader[1] = 0; // TODO : HAL does not have a version field
+ msgHeader[2] = hub_id;
+
+ onMessageReceipt(msgHeader, sizeof(msgHeader), (char *)msg->message, msg->message_len); // TODO : Populate this
+ return 0;
+}
+
+static int init_jni(JNIEnv *env, jobject instance) {
+
+ if (env->GetJavaVM(&db.jniInfo.vm) != JNI_OK) {
+ return -1;
+ }
+
+ db.jniInfo.jContextHubService = env->NewGlobalRef(instance);
+
+ db.jniInfo.contextHubInfoClass =
+ env->FindClass("android/hardware/location/ContextHubInfo");
+
+ db.jniInfo.contextHubServiceClass =
+ env->FindClass("android/hardware/location/ContextHubService");
+
+ db.jniInfo.memoryRegionsClass =
+ env->FindClass("android/hardware/location/MemoryRegion");
+
+ //TODO :: Add error checking
+ db.jniInfo.contextHubInfoCtor =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass, "<init>", "()V");
+ db.jniInfo.contextHubInfoSetId =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass, "setId", "(I)V");
+ db.jniInfo.contextHubInfoSetName =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName",
+ "(Ljava/lang/String;)V");
+
+ db.jniInfo.contextHubInfoSetVendor =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setVendor", "(Ljava/lang/String;)V");
+ db.jniInfo.contextHubInfoSetToolchain =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setToolchain", "(Ljava/lang/String;)V");
+ db.jniInfo.contextHubInfoSetPlatformVersion =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setPlatformVersion", "(I)V");
+ db.jniInfo.contextHubInfoSetStaticSwVersion =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setStaticSwVersion", "(I)V");
+ db.jniInfo.contextHubInfoSetToolchainVersion =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setToolchainVersion", "(I)V");
+ db.jniInfo.contextHubInfoSetPeakMips =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setPeakMips", "(F)V");
+ db.jniInfo.contextHubInfoSetStoppedPowerDrawMw =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setStoppedPowerDrawMw", "(F)V");
+ db.jniInfo.contextHubInfoSetSleepPowerDrawMw =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setSleepPowerDrawMw", "(F)V");
+ db.jniInfo.contextHubInfoSetPeakPowerDrawMw =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setPeakPowerDrawMw", "(F)V");
+ db.jniInfo.contextHubInfoSetSupportedSensors =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setSupportedSensors", "([I)V");
+ db.jniInfo.contextHubInfoSetMemoryRegions =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass,
+ "setMemoryRegions", "([Landroid/hardware/location/MemoryRegion;)V");
+
+
+ db.jniInfo.contextHubServiceMsgReceiptCallback =
+ env->GetMethodID(db.jniInfo.contextHubServiceClass, "onMessageReceipt",
+ "([I[B)I");
+ db.jniInfo.contextHubInfoSetName =
+ env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName",
+ "(Ljava/lang/String;)V");
+
+
+ return 0;
+}
+
+static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t *hub) {
+ jstring jstrBuf;
+ jintArray jintBuf;
+ jobjectArray jmemBuf;
+
+ int dummyConnectedSensors[] = {1, 2, 3, 4, 5};
+
+ jobject jHub = env->NewObject(db.jniInfo.contextHubInfoClass,
+ db.jniInfo.contextHubInfoCtor);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetId, hub->hub_id);
+
+ jstrBuf = env->NewStringUTF(hub->name);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetName, jstrBuf);
+
+ jstrBuf = env->NewStringUTF(hub->vendor);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetVendor, jstrBuf);
+
+ jstrBuf = env->NewStringUTF(hub->toolchain);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchain, jstrBuf);
+
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPlatformVersion, hub->platform_version);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchainVersion, hub->toolchain_version);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakMips, hub->peak_mips);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw, hub->stopped_power_draw_mw);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw, hub->sleep_power_draw_mw);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw, hub->peak_power_draw_mw);
+
+ // TODO : jintBuf = env->NewIntArray(hub->num_connected_sensors);
+ // TODO : env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, hub->connected_sensors);
+ jintBuf = env->NewIntArray(array_length(dummyConnectedSensors));
+ env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, dummyConnectedSensors);
+
+ // We are not getting the memory regions from the CH Hal - change this when it is available
+ jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, NULL);
+ // Note the zero size above. We do not need to set any elements
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf);
+
+ return jHub;
+}
+
+static jobjectArray nativeInitialize(JNIEnv *env, jobject instance)
+{
+ jobject hub;
+ jobjectArray retArray;
+
+ initContextHubService();
+
+ if (init_jni(env, instance) < 0) {
+ return NULL;
+ }
+
+ // Note : The service is clamping the number of hubs to 1
+ db.hubInfo.numHubs = 1;
+
+ initContextHubService();
+
+ retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, NULL);
+
+ for(int i = 0; i < db.hubInfo.numHubs; i++) {
+ hub = constructJContextHubInfo(env, &db.hubInfo.hubs[i]);
+ env->SetObjectArrayElement(retArray, i, hub);
+ }
+
+ return retArray;
+}
+
+static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_,
+ jbyteArray data_) {
+ hub_message_t msg;
+ hub_app_name_t dest;
+ uint8_t os_name[8];
+
+ memset(os_name, 0, sizeof(os_name));
+
+ jint *header = env->GetIntArrayElements(header_, 0);
+ //int numHeaderElements = env->GetArrayLength(header_);
+ jbyte *data = env->GetByteArrayElements(data_, 0);
+ int dataBufferLength = env->GetArrayLength(data_);
+
+ /* Assume an int - thats all we understand */
+ dest.app_name_len = array_length(os_name); // TODO : Check this
+ //dest.app_name = &header[1];
+ dest.app_name = os_name;
+
+ msg.app = &dest;
+
+ msg.message_type = header[3];
+ msg.message_len = dataBufferLength;
+ msg.message = data;
+
+ jint retVal = db.hubInfo.contextHubModule->send_message(header[0], &msg);
+
+ env->ReleaseIntArrayElements(header_, header, 0);
+ env->ReleaseByteArrayElements(data_, data, 0);
+
+ return retVal;
+}
+
+//--------------------------------------------------------------------------------------------------
+//
+static const JNINativeMethod gContextHubServiceMethods[] = {
+ {"nativeInitialize",
+ "()[Landroid/hardware/location/ContextHubInfo;",
+ (void*)nativeInitialize },
+ {"nativeSendMessage",
+ "([I[B)I",
+ (void*)nativeSendMessage }
+};
+
+}//namespace android
+
+using namespace android;
+
+int register_android_hardware_location_ContextHubService(JNIEnv *env)
+{
+ RegisterMethodsOrDie(env, "android/hardware/location/ContextHubService",
+ gContextHubServiceMethods, NELEM(gContextHubServiceMethods));
+
+ return 0;
+}
diff --git a/services/core/java/com/android/server/ContextHubSystemService.java b/services/core/java/com/android/server/ContextHubSystemService.java
new file mode 100644
index 0000000..1b85632
--- /dev/null
+++ b/services/core/java/com/android/server/ContextHubSystemService.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.hardware.location.ContextHubService;
+import android.content.Context;
+import android.util.Log;
+
+class ContextHubSystemService extends SystemService {
+ private static final String TAG = "ContextHubSystemService";
+ private final ContextHubService mContextHubService;
+
+ public ContextHubSystemService(Context context) {
+ super(context);
+ mContextHubService = new ContextHubService(context);
+ }
+
+ @Override
+ public void onStart() {
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
+ Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY");
+ publishBinderService(ContextHubService.CONTEXTHUB_SERVICE, mContextHubService);
+ }
+ }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e7daaa1..c30bafb 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1020,6 +1020,7 @@
mSystemServiceManager.startService(GestureLauncherService.class);
}
mSystemServiceManager.startService(SensorNotificationService.class);
+ mSystemServiceManager.startService(ContextHubSystemService.class);
}
traceBeginAndSlog("StartDiskStatsService");