Merge "Added handling apps query response from context hub" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a83a1dc34a
@@ -15271,6 +15271,7 @@ package android.hardware.location {
|
||||
ctor public ContextHubInfo();
|
||||
method public int describeContents();
|
||||
method public int getId();
|
||||
method public int getMaxPacketLengthBytes();
|
||||
method public android.hardware.location.MemoryRegion[] getMemoryRegions();
|
||||
method public java.lang.String getName();
|
||||
method public float getPeakMips();
|
||||
@@ -15298,10 +15299,6 @@ package android.hardware.location {
|
||||
method public int sendMessage(int, int, android.hardware.location.ContextHubMessage);
|
||||
method public int unloadNanoApp(int);
|
||||
method public int unregisterCallback(android.hardware.location.ContextHubManager.Callback);
|
||||
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 static abstract class ContextHubManager.Callback {
|
||||
@@ -15495,7 +15492,7 @@ package android.hardware.location {
|
||||
public class NanoAppInstanceInfo {
|
||||
ctor public NanoAppInstanceInfo();
|
||||
method public int describeContents();
|
||||
method public int getAppId();
|
||||
method public long getAppId();
|
||||
method public int getAppVersion();
|
||||
method public int getContexthubId();
|
||||
method public int getHandle();
|
||||
@@ -15506,17 +15503,6 @@ package android.hardware.location {
|
||||
method public int getNeededWriteMemBytes();
|
||||
method public int[] getOutputEvents();
|
||||
method public java.lang.String getPublisher();
|
||||
method public void setAppId(int);
|
||||
method public void setAppVersion(int);
|
||||
method public void setContexthubId(int);
|
||||
method public void setHandle(int);
|
||||
method public void setName(java.lang.String);
|
||||
method public void setNeededExecMemBytes(int);
|
||||
method public void setNeededReadMemBytes(int);
|
||||
method public void setNeededSensors(int[]);
|
||||
method public void setNeededWriteMemBytes(int);
|
||||
method public void setOutputEvents(int[]);
|
||||
method public void setPublisher(java.lang.String);
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final android.os.Parcelable.Creator<android.hardware.location.NanoAppInstanceInfo> CREATOR;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ public class ContextHubInfo {
|
||||
private float mStoppedPowerDrawMw;
|
||||
private float mSleepPowerDrawMw;
|
||||
private float mPeakPowerDrawMw;
|
||||
private int mMaxPacketLengthBytes;
|
||||
|
||||
private int[] mSupportedSensors;
|
||||
|
||||
@@ -45,6 +46,27 @@ public class ContextHubInfo {
|
||||
public ContextHubInfo() {
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the maximum number of bytes that can be sent per message to the hub
|
||||
*
|
||||
* @return int - maximum bytes that can be transmitted in a
|
||||
* single packet
|
||||
*/
|
||||
public int getMaxPacketLengthBytes() {
|
||||
return mMaxPacketLengthBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the context hub unique identifer
|
||||
*
|
||||
* @param bytes - Maximum number of bytes per message
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setMaxPacketLenBytes(int bytes) {
|
||||
mMaxPacketLengthBytes = bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the context hub unique identifer
|
||||
*
|
||||
@@ -374,4 +396,4 @@ public class ContextHubInfo {
|
||||
return new ContextHubInfo[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -42,23 +42,6 @@ public final class ContextHubManager {
|
||||
private Callback mCallback;
|
||||
private Handler mCallbackHandler;
|
||||
|
||||
/**
|
||||
* A special context hub identifier meaning any possible hub on the system.
|
||||
*/
|
||||
public static final int ANY_HUB = -1;
|
||||
/**
|
||||
* A constant denoting a message to load a a Nano App
|
||||
*/
|
||||
public static final int MSG_LOAD_NANO_APP = 1;
|
||||
/**
|
||||
* A constant denoting a message to unload a a Nano App
|
||||
*/
|
||||
public static final int MSG_UNLOAD_NANO_APP = 2;
|
||||
/**
|
||||
* A constant denoting a message to send a message
|
||||
*/
|
||||
public static final int MSG_DATA_SEND = 3;
|
||||
|
||||
/**
|
||||
* An interface to receive asynchronous communication from the context hub.
|
||||
*/
|
||||
@@ -69,7 +52,7 @@ public final class ContextHubManager {
|
||||
* Callback function called on message receipt from context hub.
|
||||
*
|
||||
* @param hubHandle Handle (system-wide unique identifier) of the hub of the message.
|
||||
* @param nanoAppHandle Handle (unique identifier) for the app that sent the message.
|
||||
* @param nanoAppHandle Handle (unique identifier) for app instance that sent the message.
|
||||
* @param message The context hub message.
|
||||
*
|
||||
* @see ContextHubMessage
|
||||
@@ -89,7 +72,7 @@ public final class ContextHubManager {
|
||||
try {
|
||||
retVal = getBinder().getContextHubHandles();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not fetch context hub handles : " + e);
|
||||
Log.w(TAG, "Could not fetch context hub handles : " + e);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
@@ -107,7 +90,7 @@ public final class ContextHubManager {
|
||||
try {
|
||||
retVal = getBinder().getContextHubInfo(hubHandle);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not fetch context hub info :" + e);
|
||||
Log.w(TAG, "Could not fetch context hub info :" + e);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
@@ -126,6 +109,7 @@ public final class ContextHubManager {
|
||||
*/
|
||||
public int loadNanoApp(int hubHandle, NanoApp app) {
|
||||
int retVal = -1;
|
||||
|
||||
if (app == null) {
|
||||
return retVal;
|
||||
}
|
||||
@@ -133,7 +117,7 @@ public final class ContextHubManager {
|
||||
try {
|
||||
retVal = getBinder().loadNanoApp(hubHandle, app);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not fetch load nanoApp :" + e);
|
||||
Log.w(TAG, "Could not load nanoApp :" + e);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
@@ -152,7 +136,7 @@ public final class ContextHubManager {
|
||||
try {
|
||||
retVal = getBinder().unloadNanoApp(nanoAppHandle);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not fetch unload nanoApp :" + e);
|
||||
Log.w(TAG, "Could not fetch unload nanoApp :" + e);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
@@ -172,7 +156,7 @@ public final class ContextHubManager {
|
||||
try {
|
||||
retVal = getBinder().getNanoAppInstanceInfo(nanoAppHandle);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not fetch nanoApp info :" + e);
|
||||
Log.w(TAG, "Could not fetch nanoApp info :" + e);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
@@ -193,7 +177,7 @@ public final class ContextHubManager {
|
||||
try {
|
||||
retVal = getBinder().findNanoAppOnHub(hubHandle, filter);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not query nanoApp instance :" + e);
|
||||
Log.w(TAG, "Could not query nanoApp instance :" + e);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
@@ -212,10 +196,14 @@ public final class ContextHubManager {
|
||||
public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage message) {
|
||||
int retVal = -1;
|
||||
|
||||
if (message == null || message.getData() == null) {
|
||||
Log.w(TAG, "null ptr");
|
||||
return retVal;
|
||||
}
|
||||
try {
|
||||
retVal = getBinder().sendMessage(hubHandle, nanoAppHandle, message);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not fetch send message :" + e.toString());
|
||||
Log.w(TAG, "Could not send message :" + e.toString());
|
||||
}
|
||||
|
||||
return retVal;
|
||||
@@ -247,7 +235,7 @@ public final class ContextHubManager {
|
||||
public int registerCallback(Callback callback, Handler handler) {
|
||||
synchronized(this) {
|
||||
if (mCallback != null) {
|
||||
Log.e(TAG, "Max number of callbacks reached!");
|
||||
Log.w(TAG, "Max number of callbacks reached!");
|
||||
return -1;
|
||||
}
|
||||
mCallback = callback;
|
||||
@@ -268,7 +256,7 @@ public final class ContextHubManager {
|
||||
public int unregisterCallback(Callback callback) {
|
||||
synchronized(this) {
|
||||
if (callback != mCallback) {
|
||||
Log.e(TAG, "Cannot recognize callback!");
|
||||
Log.w(TAG, "Cannot recognize callback!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -311,11 +299,11 @@ public final class ContextHubManager {
|
||||
try {
|
||||
getBinder().registerCallback(mClientCallback);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not register callback:" + e);
|
||||
Log.w(TAG, "Could not register callback:" + e);
|
||||
}
|
||||
|
||||
} else {
|
||||
Log.d(TAG, "failed to getService");
|
||||
Log.w(TAG, "failed to getService");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package android.hardware.location;
|
||||
|
||||
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -32,6 +32,9 @@ public class ContextHubMessage {
|
||||
private int mVersion;
|
||||
private byte[]mData;
|
||||
|
||||
private static final String TAG = "ContextHubMessage";
|
||||
|
||||
|
||||
/**
|
||||
* Get the message type
|
||||
*
|
||||
@@ -106,9 +109,11 @@ public class ContextHubMessage {
|
||||
private ContextHubMessage(Parcel in) {
|
||||
mType = in.readInt();
|
||||
mVersion = in.readInt();
|
||||
byte[] byteBuffer = new byte[in.readInt()];
|
||||
in.readByteArray(byteBuffer);
|
||||
int bufferLength = in.readInt();
|
||||
mData = new byte[bufferLength];
|
||||
in.readByteArray(mData);
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(mType);
|
||||
out.writeInt(mVersion);
|
||||
|
||||
@@ -29,12 +29,30 @@ import java.util.HashMap;
|
||||
*/
|
||||
public class ContextHubService extends IContextHubService.Stub {
|
||||
|
||||
public static final String CONTEXTHUB_SERVICE = "contexthub_service";
|
||||
|
||||
private static final String TAG = "ContextHubService";
|
||||
private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
|
||||
private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '"
|
||||
+ HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware";
|
||||
|
||||
public static final String CONTEXTHUB_SERVICE = "contexthub_service";
|
||||
|
||||
public static final int ANY_HUB = -1;
|
||||
public static final int MSG_LOAD_NANO_APP = 5;
|
||||
public static final int MSG_UNLOAD_NANO_APP = 2;
|
||||
|
||||
private static final String PRE_LOADED_GENERIC_UNKNOWN = "Preloaded app, unknown";
|
||||
private static final String PRE_LOADED_APP_NAME = PRE_LOADED_GENERIC_UNKNOWN;
|
||||
private static final String PRE_LOADED_APP_PUBLISHER = PRE_LOADED_GENERIC_UNKNOWN;
|
||||
private static final int PRE_LOADED_APP_MEM_REQ = 0;
|
||||
|
||||
private static final int MSG_HEADER_SIZE = 4;
|
||||
private static final int MSG_FIELD_TYPE = 0;
|
||||
private static final int MSG_FIELD_VERSION = 1;
|
||||
private static final int MSG_FIELD_HUB_HANDLE = 2;
|
||||
private static final int MSG_FIELD_APP_INSTANCE = 3;
|
||||
|
||||
private static final int OS_APP_INSTANCE = -1;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
@@ -42,44 +60,27 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
private ContextHubInfo[] mContextHubInfo;
|
||||
private IContextHubCallback mCallback;
|
||||
|
||||
private native int nativeSendMessage(int[] header, byte[] data);
|
||||
private native ContextHubInfo[] nativeInitialize();
|
||||
|
||||
|
||||
public ContextHubService(Context context) {
|
||||
mContext = context;
|
||||
mContextHubInfo = nativeInitialize();
|
||||
mNanoAppHash = new HashMap<Integer, NanoAppInstanceInfo>();
|
||||
|
||||
for (int i = 0; i < mContextHubInfo.length; i++) {
|
||||
Log.v(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
|
||||
Log.d(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
|
||||
+ ", name: " + mContextHubInfo[i].getName());
|
||||
}
|
||||
}
|
||||
|
||||
private native int nativeSendMessage(int[] header, byte[] data);
|
||||
private native ContextHubInfo[] nativeInitialize();
|
||||
|
||||
@Override
|
||||
public int registerCallback(IContextHubCallback callback) throws RemoteException{
|
||||
public int registerCallback(IContextHubCallback callback) throws RemoteException {
|
||||
checkPermissions();
|
||||
mCallback = callback;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
try {
|
||||
mCallback.onMessageReceipt(0, 0, msg);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception " + e + " when calling remote callback");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "Message Callback is NULL");
|
||||
synchronized(this) {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -118,14 +119,17 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
}
|
||||
|
||||
// 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
|
||||
int[] msgHeader = new int[MSG_HEADER_SIZE];
|
||||
msgHeader[MSG_FIELD_HUB_HANDLE] = contextHubHandle;
|
||||
msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE;
|
||||
msgHeader[MSG_FIELD_VERSION] = 0;
|
||||
msgHeader[MSG_FIELD_TYPE] = MSG_LOAD_NANO_APP;
|
||||
|
||||
return nativeSendMessage(msgHeader, app.getAppBinary());
|
||||
if (nativeSendMessage(msgHeader, app.getAppBinary()) != 0) {
|
||||
return -1;
|
||||
}
|
||||
// Do not add an entry to mNanoAppInstance Hash yet. The HAL may reject the app
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,12 +141,18 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
}
|
||||
|
||||
// Call Native interface here
|
||||
int[] msgHeader = new int[8];
|
||||
msgHeader[0] = info.getContexthubId();
|
||||
msgHeader[1] = ContextHubManager.MSG_UNLOAD_NANO_APP;
|
||||
msgHeader[2] = info.getHandle();
|
||||
int[] msgHeader = new int[MSG_HEADER_SIZE];
|
||||
msgHeader[MSG_FIELD_HUB_HANDLE] = ANY_HUB;
|
||||
msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE;
|
||||
msgHeader[MSG_FIELD_VERSION] = 0;
|
||||
msgHeader[MSG_FIELD_TYPE] = MSG_UNLOAD_NANO_APP;
|
||||
|
||||
return nativeSendMessage(msgHeader, null);
|
||||
if(nativeSendMessage(msgHeader, null) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Do not add an entry to mNanoAppInstance Hash yet. The HAL may reject the app
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -166,7 +176,7 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
for(Integer nanoAppInstance : mNanoAppHash.keySet()) {
|
||||
NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance);
|
||||
|
||||
if(filter.testMatch(info)){
|
||||
if (filter.testMatch(info)){
|
||||
foundInstances.add(nanoAppInstance);
|
||||
}
|
||||
}
|
||||
@@ -183,12 +193,12 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg)
|
||||
throws RemoteException {
|
||||
checkPermissions();
|
||||
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();
|
||||
|
||||
int[] msgHeader = new int[MSG_HEADER_SIZE];
|
||||
msgHeader[MSG_FIELD_HUB_HANDLE] = hubHandle;
|
||||
msgHeader[MSG_FIELD_APP_INSTANCE] = nanoAppHandle;
|
||||
msgHeader[MSG_FIELD_VERSION] = msg.getVersion();
|
||||
msgHeader[MSG_FIELD_TYPE] = msg.getMsgType();
|
||||
|
||||
return nativeSendMessage(msgHeader, msg.getData());
|
||||
}
|
||||
@@ -196,5 +206,52 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
private void checkPermissions() {
|
||||
mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private int onMessageReceipt(int[] header, byte[] data) {
|
||||
if (header == null || data == null || header.length < MSG_HEADER_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
synchronized(this) {
|
||||
if (mCallback != null) {
|
||||
ContextHubMessage msg = new ContextHubMessage(header[MSG_FIELD_TYPE],
|
||||
header[MSG_FIELD_VERSION],
|
||||
data);
|
||||
|
||||
try {
|
||||
mCallback.onMessageReceipt(header[MSG_FIELD_HUB_HANDLE],
|
||||
header[MSG_FIELD_APP_INSTANCE],
|
||||
msg);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Exception " + e + " when calling remote callback");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "Message Callback is NULL");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int addAppInstance(int hubHandle, int appInstanceHandle, long appId, int appVersion) {
|
||||
// App Id encodes vendor & version
|
||||
NanoAppInstanceInfo appInfo = new NanoAppInstanceInfo();
|
||||
|
||||
appInfo.setAppId(appId);
|
||||
appInfo.setAppVersion(appVersion);
|
||||
appInfo.setName(PRE_LOADED_APP_NAME);
|
||||
appInfo.setContexthubId(hubHandle);
|
||||
appInfo.setHandle(appInstanceHandle);
|
||||
appInfo.setPublisher(PRE_LOADED_APP_PUBLISHER);
|
||||
appInfo.setNeededExecMemBytes(PRE_LOADED_APP_MEM_REQ);
|
||||
appInfo.setNeededReadMemBytes(PRE_LOADED_APP_MEM_REQ);
|
||||
appInfo.setNeededWriteMemBytes(PRE_LOADED_APP_MEM_REQ);
|
||||
|
||||
mNanoAppHash.put(appInstanceHandle, appInfo);
|
||||
Log.d(TAG, "Added app instance " + appInstanceHandle + " with id " + appId
|
||||
+ " version " + appVersion);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ package android.hardware.location;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@@ -27,6 +28,8 @@ import android.os.Parcelable;
|
||||
@SystemApi
|
||||
public class NanoAppFilter {
|
||||
|
||||
private static final String TAG = "NanoAppFilter";
|
||||
|
||||
// The appId, can be set to APP_ID_ANY
|
||||
private long mAppId;
|
||||
|
||||
@@ -54,6 +57,10 @@ public class NanoAppFilter {
|
||||
* If this flag is set, only versions strictly less than the version specified shall match.
|
||||
*/
|
||||
public static final int FLAGS_VERSION_LESS_THAN = 4;
|
||||
/**
|
||||
* If this flag is set, only versions strictly equal to the
|
||||
* version specified shall match.
|
||||
*/
|
||||
public static final int FLAGS_VERSION_STRICTLY_EQUAL = 8;
|
||||
|
||||
/**
|
||||
@@ -117,14 +124,9 @@ public class NanoAppFilter {
|
||||
* @return true if this is a match, false otherwise
|
||||
*/
|
||||
public boolean testMatch(NanoAppInstanceInfo info) {
|
||||
if ((mContextHubId == HUB_ANY || info.getContexthubId() == mContextHubId) &&
|
||||
return (mContextHubId == HUB_ANY || info.getContexthubId() == mContextHubId) &&
|
||||
(mAppId == APP_ANY || info.getAppId() == mAppId) &&
|
||||
// (mAppIdVendorMask == VENDOR_ANY) TODO : Expose Vendor mask cleanly
|
||||
(versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
(versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()));
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<NanoAppFilter> CREATOR
|
||||
|
||||
@@ -29,7 +29,7 @@ public class NanoAppInstanceInfo {
|
||||
private String mPublisher;
|
||||
private String mName;
|
||||
|
||||
private int mAppId;
|
||||
private long mAppId;
|
||||
private int mAppVersion;
|
||||
|
||||
private int mNeededReadMemBytes;
|
||||
@@ -59,6 +59,8 @@ public class NanoAppInstanceInfo {
|
||||
* set the publisher name for the app
|
||||
*
|
||||
* @param publisher - name of the publisher
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setPublisher(String publisher) {
|
||||
mPublisher = publisher;
|
||||
@@ -77,6 +79,8 @@ public class NanoAppInstanceInfo {
|
||||
* set the name of the app
|
||||
*
|
||||
* @param name - name of the app
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setName(String name) {
|
||||
mName = name;
|
||||
@@ -87,7 +91,7 @@ public class NanoAppInstanceInfo {
|
||||
*
|
||||
* @return int - application identifier
|
||||
*/
|
||||
public int getAppId() {
|
||||
public long getAppId() {
|
||||
return mAppId;
|
||||
}
|
||||
|
||||
@@ -95,8 +99,10 @@ public class NanoAppInstanceInfo {
|
||||
* Set the application identifier
|
||||
*
|
||||
* @param appId - application identifier
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setAppId(int appId) {
|
||||
public void setAppId(long appId) {
|
||||
mAppId = appId;
|
||||
}
|
||||
|
||||
@@ -113,6 +119,8 @@ public class NanoAppInstanceInfo {
|
||||
* Set the application version
|
||||
*
|
||||
* @param appVersion - version of the app
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setAppVersion(int appVersion) {
|
||||
mAppVersion = appVersion;
|
||||
@@ -131,6 +139,8 @@ public class NanoAppInstanceInfo {
|
||||
* Set the read memory needed by the app
|
||||
*
|
||||
* @param neededReadMemBytes - readable Memory needed in bytes
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setNeededReadMemBytes(int neededReadMemBytes) {
|
||||
mNeededReadMemBytes = neededReadMemBytes;
|
||||
@@ -150,6 +160,8 @@ public class NanoAppInstanceInfo {
|
||||
*
|
||||
* @param neededWriteMemBytes - writable memory needed by the
|
||||
* app
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setNeededWriteMemBytes(int neededWriteMemBytes) {
|
||||
mNeededWriteMemBytes = neededWriteMemBytes;
|
||||
@@ -169,6 +181,8 @@ public class NanoAppInstanceInfo {
|
||||
*
|
||||
* @param neededExecMemBytes - executable memory needed by the
|
||||
* app
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setNeededExecMemBytes(int neededExecMemBytes) {
|
||||
mNeededExecMemBytes = neededExecMemBytes;
|
||||
@@ -187,6 +201,8 @@ public class NanoAppInstanceInfo {
|
||||
* set the sensors needed by this app
|
||||
*
|
||||
* @param neededSensors - all the sensors needed by this app
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setNeededSensors(int[] neededSensors) {
|
||||
mNeededSensors = neededSensors;
|
||||
@@ -206,6 +222,8 @@ public class NanoAppInstanceInfo {
|
||||
*
|
||||
* @param outputEvents - the events that may be generated by
|
||||
* this app
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setOutputEvents(int[] outputEvents) {
|
||||
mOutputEvents = outputEvents;
|
||||
@@ -224,6 +242,8 @@ public class NanoAppInstanceInfo {
|
||||
* set the context hub identifier
|
||||
*
|
||||
* @param contexthubId - system wide unique identifier
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setContexthubId(int contexthubId) {
|
||||
mContexthubId = contexthubId;
|
||||
@@ -242,6 +262,8 @@ public class NanoAppInstanceInfo {
|
||||
* set the handle for an app instance
|
||||
*
|
||||
* @param handle - handle to this instance
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setHandle(int handle) {
|
||||
mHandle = handle;
|
||||
@@ -252,7 +274,7 @@ public class NanoAppInstanceInfo {
|
||||
mPublisher = in.readString();
|
||||
mName = in.readString();
|
||||
|
||||
mAppId = in.readInt();
|
||||
mAppId = in.readLong();
|
||||
mAppVersion = in.readInt();
|
||||
mNeededReadMemBytes = in.readInt();
|
||||
mNeededWriteMemBytes = in.readInt();
|
||||
@@ -274,7 +296,7 @@ public class NanoAppInstanceInfo {
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(mPublisher);
|
||||
out.writeString(mName);
|
||||
out.writeInt(mAppId);
|
||||
out.writeLong(mAppId);
|
||||
out.writeInt(mAppVersion);
|
||||
out.writeInt(mContexthubId);
|
||||
out.writeInt(mNeededReadMemBytes);
|
||||
@@ -286,7 +308,6 @@ public class NanoAppInstanceInfo {
|
||||
|
||||
out.writeInt(mOutputEvents.length);
|
||||
out.writeIntArray(mOutputEvents);
|
||||
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<NanoAppInstanceInfo> CREATOR
|
||||
|
||||
@@ -16,23 +16,39 @@
|
||||
|
||||
#include "context_hub.h"
|
||||
|
||||
#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "ContextHubService"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <jni.h>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <jni.h>
|
||||
#include "JNIHelp.h"
|
||||
#include "core_jni_helpers.h"
|
||||
#include "stdint.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
//static constexpr int OS_APP_ID=-1;
|
||||
|
||||
static constexpr int MIN_APP_ID=1;
|
||||
static constexpr int MAX_APP_ID=128;
|
||||
|
||||
static constexpr size_t MSG_HEADER_SIZE=4;
|
||||
static constexpr int HEADER_FIELD_MSG_TYPE=0;
|
||||
//static constexpr int HEADER_FIELD_MSG_VERSION=1;
|
||||
static constexpr int HEADER_FIELD_HUB_HANDLE=2;
|
||||
static constexpr int HEADER_FIELD_APP_INSTANCE=3;
|
||||
|
||||
|
||||
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.
|
||||
@@ -64,35 +80,207 @@ struct jniInfo_s {
|
||||
jmethodID contextHubInfoSetPeakPowerDrawMw;
|
||||
jmethodID contextHubInfoSetSupportedSensors;
|
||||
jmethodID contextHubInfoSetMemoryRegions;
|
||||
jmethodID contextHubInfoSetMaxPacketLenBytes;
|
||||
|
||||
jmethodID contextHubServiceMsgReceiptCallback;
|
||||
jmethodID contextHubServiceAddAppInstance;
|
||||
};
|
||||
|
||||
struct context_hub_info_s {
|
||||
int cookie;
|
||||
uint32_t *cookies;
|
||||
int numHubs;
|
||||
const struct context_hub_t *hubs;
|
||||
struct context_hub_module_t *contextHubModule;
|
||||
};
|
||||
|
||||
struct app_instance_info_s {
|
||||
uint32_t hubHandle; // Id of the hub this app is on
|
||||
int instanceId; // systemwide unique instance id - assigned
|
||||
struct hub_app_info appInfo; // returned from the HAL
|
||||
uint64_t truncName; // Possibly truncated name - logging
|
||||
};
|
||||
|
||||
struct contextHubServiceDb_s {
|
||||
int initialized;
|
||||
context_hub_info_s hubInfo;
|
||||
jniInfo_s jniInfo;
|
||||
std::queue<int> freeIds;
|
||||
std::map<int, app_instance_info_s *> appInstances;
|
||||
};
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
static contextHubServiceDb_s db;
|
||||
|
||||
int context_hub_callback(uint32_t hub_id, const struct hub_message_t *msg,
|
||||
int context_hub_callback(uint32_t hubId, const struct hub_message_t *msg,
|
||||
void *cookie);
|
||||
|
||||
const context_hub_t *get_hub_info(int hubHandle) {
|
||||
if (hubHandle >= 0 && hubHandle < db.hubInfo.numHubs) {
|
||||
return &db.hubInfo.hubs[hubHandle];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static int send_msg_to_hub(const hub_message_t *msg, int hubHandle) {
|
||||
const context_hub_t *info = get_hub_info(hubHandle);
|
||||
|
||||
if (info) {
|
||||
return db.hubInfo.contextHubModule->send_message(info->hub_id, msg);
|
||||
} else {
|
||||
ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int set_os_app_as_destination(hub_message_t *msg, int hubHandle) {
|
||||
const context_hub_t *info = get_hub_info(hubHandle);
|
||||
|
||||
if (info) {
|
||||
msg->app = info->os_app_name;
|
||||
return 0;
|
||||
} else {
|
||||
ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_hub_id_for_app_instance(int id) {
|
||||
if (db.appInstances.find(id) == db.appInstances.end()) {
|
||||
ALOGD("%s: Cannot find app for app instance %d", __FUNCTION__, id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int hubHandle = db.appInstances[id]->hubHandle;
|
||||
|
||||
return db.hubInfo.hubs[hubHandle].hub_id;
|
||||
}
|
||||
|
||||
static int set_dest_app(hub_message_t *msg, int id) {
|
||||
if (db.appInstances.find(id) == db.appInstances.end()) {
|
||||
ALOGD("%s: Cannod find app for app instance %d", __FUNCTION__, id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg->app = db.appInstances[id]->appInfo.name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_query_for_apps() {
|
||||
hub_message_t msg;
|
||||
|
||||
msg.message_type = CONTEXT_HUB_QUERY_APPS;
|
||||
msg.message_len = 0;
|
||||
|
||||
for (int i = 0; i < db.hubInfo.numHubs; i++ ) {
|
||||
ALOGD("Sending query for apps to hub %d", i);
|
||||
set_os_app_as_destination(&msg, i);
|
||||
if (send_msg_to_hub(&msg, i) != 0) {
|
||||
ALOGW("Could not query hub %i for apps", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int return_id(int id) {
|
||||
// Note : This method is not thread safe.
|
||||
// id returned is guarenteed to be in use
|
||||
db.freeIds.push(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int generate_id(void) {
|
||||
// Note : This method is not thread safe.
|
||||
int retVal = -1;
|
||||
|
||||
if (!db.freeIds.empty()) {
|
||||
retVal = db.freeIds.front();
|
||||
db.freeIds.pop();
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle, JNIEnv *env) {
|
||||
// Not checking if the apps are indeed distinct
|
||||
|
||||
app_instance_info_s *entry;
|
||||
void *appName;
|
||||
hub_app_name_t *name;
|
||||
|
||||
assert(appInfo && appInfo->name && appInfo->name->app_name);
|
||||
|
||||
entry = (app_instance_info_s *) malloc(sizeof(app_instance_info_s));
|
||||
appName = malloc(appInfo->name->app_name_len);
|
||||
name = (hub_app_name_t *) malloc(sizeof(hub_app_name_t));
|
||||
|
||||
int appInstanceHandle = generate_id();
|
||||
|
||||
if (appInstanceHandle < 0 || !appName || !entry || !name) {
|
||||
ALOGE("Cannot find resources to add app instance %d, %p, %p",
|
||||
appInstanceHandle, appName, entry);
|
||||
|
||||
free(appName);
|
||||
free(entry);
|
||||
free(name);
|
||||
|
||||
if (appInstanceHandle >= 0) {
|
||||
return_id(appInstanceHandle);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(&(entry->appInfo), appInfo, sizeof(entry->appInfo));
|
||||
memcpy(appName, appInfo->name->app_name, appInfo->name->app_name_len);
|
||||
name->app_name = appName;
|
||||
name->app_name_len = appInfo->name->app_name_len;
|
||||
entry->appInfo.name = name;
|
||||
entry->truncName = 0;
|
||||
memcpy(&(entry->truncName), name->app_name,
|
||||
sizeof(entry->truncName) < name->app_name_len ?
|
||||
sizeof(entry->truncName) : name->app_name_len);
|
||||
|
||||
// Not checking for sanity of hubId
|
||||
entry->hubHandle = hubHandle;
|
||||
entry->instanceId = appInstanceHandle;
|
||||
db.appInstances[appInstanceHandle] = entry;
|
||||
|
||||
// Finally - let the service know of this app instance
|
||||
env->CallIntMethod(db.jniInfo.jContextHubService,
|
||||
db.jniInfo.contextHubServiceAddAppInstance,
|
||||
hubHandle, entry->instanceId, entry->truncName,
|
||||
entry->appInfo.version);
|
||||
|
||||
ALOGW("Added App 0x%" PRIx64 " on hub Handle %" PRId32
|
||||
" as appInstance %d, original name_length %" PRId32, entry->truncName,
|
||||
entry->hubHandle, appInstanceHandle, name->app_name_len);
|
||||
|
||||
return appInstanceHandle;
|
||||
}
|
||||
|
||||
int delete_app_instance(int id) {
|
||||
if (db.appInstances.find(id) == db.appInstances.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return_id(id);
|
||||
|
||||
if (db.appInstances[id]) {
|
||||
// Losing the const cast below. This is intentional.
|
||||
free((void *)db.appInstances[id]->appInfo.name->app_name);
|
||||
free((void *)db.appInstances[id]->appInfo.name);
|
||||
free(db.appInstances[id]);
|
||||
db.appInstances.erase(id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void initContextHubService() {
|
||||
int err = 0;
|
||||
db.hubInfo.hubs = NULL;
|
||||
db.hubInfo.hubs = nullptr;
|
||||
db.hubInfo.numHubs = 0;
|
||||
db.hubInfo.cookie = 0;
|
||||
int i;
|
||||
|
||||
err = hw_get_module(CONTEXT_HUB_MODULE_ID,
|
||||
@@ -103,26 +291,45 @@ static void initContextHubService() {
|
||||
strerror(-err));
|
||||
}
|
||||
|
||||
if (db.hubInfo.contextHubModule) {
|
||||
ALOGD("Fetching hub info");
|
||||
db.hubInfo.numHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
|
||||
&db.hubInfo.hubs);
|
||||
// Prep for storing app info
|
||||
for(i = MIN_APP_ID; i <= MAX_APP_ID; i++) {
|
||||
db.freeIds.push(i);
|
||||
}
|
||||
|
||||
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);
|
||||
if (db.hubInfo.contextHubModule) {
|
||||
int retNumHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
|
||||
&db.hubInfo.hubs);
|
||||
ALOGD("ContextHubModule returned %d hubs ", retNumHubs);
|
||||
db.hubInfo.numHubs = retNumHubs;
|
||||
|
||||
if (db.hubInfo.numHubs > 0) {
|
||||
db.hubInfo.numHubs = retNumHubs;
|
||||
db.hubInfo.cookies = (uint32_t *)malloc(sizeof(uint32_t) * db.hubInfo.numHubs);
|
||||
|
||||
if (!db.hubInfo.cookies) {
|
||||
ALOGW("Ran out of memory allocating cookies, bailing");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < db.hubInfo.numHubs; i++) {
|
||||
db.hubInfo.cookies[i] = db.hubInfo.hubs[i].hub_id;
|
||||
if (db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id,
|
||||
context_hub_callback,
|
||||
&db.hubInfo.cookies[i]) == 0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
send_query_for_apps();
|
||||
} else {
|
||||
ALOGW("No Context Hub Module present");
|
||||
}
|
||||
}
|
||||
|
||||
static int onMessageReceipt(int *header, int headerLen, char *msg, int msgLen) {
|
||||
JNIEnv *env;
|
||||
if ((db.jniInfo.vm)->AttachCurrentThread(&env, NULL) != JNI_OK) {
|
||||
|
||||
if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -132,28 +339,131 @@ static int onMessageReceipt(int *header, int headerLen, char *msg, int msgLen) {
|
||||
env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg);
|
||||
env->SetIntArrayRegion(jheader, 0, headerLen, (jint *)header);
|
||||
|
||||
|
||||
return env->CallIntMethod(db.jniInfo.jContextHubService,
|
||||
return (env->CallIntMethod(db.jniInfo.jContextHubService,
|
||||
db.jniInfo.contextHubServiceMsgReceiptCallback,
|
||||
jheader, jmsg);
|
||||
jheader, jmsg) != 0);
|
||||
}
|
||||
|
||||
int context_hub_callback(uint32_t hub_id, const struct hub_message_t *msg,
|
||||
int handle_query_apps_response(char *msg, int msgLen, uint32_t hubHandle) {
|
||||
int i;
|
||||
JNIEnv *env;
|
||||
if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int numApps = msgLen/sizeof(hub_app_info);
|
||||
hub_app_info *info = (hub_app_info *)malloc(msgLen); // handle possible alignment
|
||||
|
||||
if (!info) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(info, msg, msgLen);
|
||||
for (i = 0; i < numApps; i++) {
|
||||
add_app_instance(info, hubHandle, env);
|
||||
info++;
|
||||
}
|
||||
|
||||
free(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int handle_os_message(uint32_t msgType, uint32_t hubHandle,
|
||||
char *msg, int msgLen) {
|
||||
int retVal;
|
||||
|
||||
switch(msgType) {
|
||||
case CONTEXT_HUB_APPS_ENABLE:
|
||||
retVal = 0;
|
||||
break;
|
||||
|
||||
case CONTEXT_HUB_APPS_DISABLE:
|
||||
retVal = 0;
|
||||
break;
|
||||
|
||||
case CONTEXT_HUB_LOAD_APP:
|
||||
retVal = 0;
|
||||
break;
|
||||
|
||||
case CONTEXT_HUB_UNLOAD_APP:
|
||||
retVal = 0;
|
||||
break;
|
||||
|
||||
case CONTEXT_HUB_QUERY_APPS:
|
||||
retVal = handle_query_apps_response(msg, msgLen, hubHandle);
|
||||
break;
|
||||
|
||||
case CONTEXT_HUB_QUERY_MEMORY:
|
||||
retVal = 0;
|
||||
break;
|
||||
|
||||
case CONTEXT_HUB_LOAD_OS:
|
||||
retVal = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
retVal = -1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static bool sanity_check_cookie(void *cookie, uint32_t hub_id) {
|
||||
int *ptr = (int *)cookie;
|
||||
|
||||
if (!ptr || *ptr >= db.hubInfo.numHubs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (db.hubInfo.hubs[*ptr].hub_id != hub_id) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int context_hub_callback(uint32_t hubId,
|
||||
const struct hub_message_t *msg,
|
||||
void *cookie) {
|
||||
int msgHeader[4];
|
||||
int msgHeader[MSG_HEADER_SIZE];
|
||||
|
||||
msgHeader[0] = msg->message_type;
|
||||
msgHeader[1] = 0; // TODO : HAL does not have a version field
|
||||
msgHeader[2] = hub_id;
|
||||
if (!msg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
onMessageReceipt(msgHeader, sizeof(msgHeader), (char *)msg->message, msg->message_len); // TODO : Populate this
|
||||
return 0;
|
||||
msgHeader[HEADER_FIELD_MSG_TYPE] = msg->message_type;
|
||||
|
||||
if (!sanity_check_cookie(cookie, hubId)) {
|
||||
ALOGW("Incorrect cookie %" PRId32 " for cookie %p! Bailing",
|
||||
hubId, cookie);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
msgHeader[HEADER_FIELD_HUB_HANDLE] = *(uint32_t*)cookie;
|
||||
|
||||
if (msgHeader[HEADER_FIELD_MSG_TYPE] < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE &&
|
||||
msgHeader[HEADER_FIELD_MSG_TYPE] != 0 ) {
|
||||
handle_os_message(msgHeader[HEADER_FIELD_MSG_TYPE],
|
||||
msgHeader[HEADER_FIELD_HUB_HANDLE],
|
||||
(char *)msg->message,
|
||||
msg->message_len);
|
||||
} else {
|
||||
onMessageReceipt(msgHeader, sizeof(msgHeader),
|
||||
(char *)msg->message, msg->message_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_jni(JNIEnv *env, jobject instance) {
|
||||
|
||||
if (env->GetJavaVM(&db.jniInfo.vm) != JNI_OK) {
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
db.jniInfo.jContextHubService = env->NewGlobalRef(instance);
|
||||
@@ -167,7 +477,6 @@ static int init_jni(JNIEnv *env, jobject instance) {
|
||||
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 =
|
||||
@@ -209,6 +518,9 @@ static int init_jni(JNIEnv *env, jobject instance) {
|
||||
db.jniInfo.contextHubInfoSetMemoryRegions =
|
||||
env->GetMethodID(db.jniInfo.contextHubInfoClass,
|
||||
"setMemoryRegions", "([Landroid/hardware/location/MemoryRegion;)V");
|
||||
db.jniInfo.contextHubInfoSetMaxPacketLenBytes =
|
||||
env->GetMethodID(db.jniInfo.contextHubInfoClass,
|
||||
"setMaxPacketLenBytes", "(I)V");
|
||||
|
||||
|
||||
db.jniInfo.contextHubServiceMsgReceiptCallback =
|
||||
@@ -218,6 +530,11 @@ static int init_jni(JNIEnv *env, jobject instance) {
|
||||
env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName",
|
||||
"(Ljava/lang/String;)V");
|
||||
|
||||
db.jniInfo.contextHubServiceAddAppInstance =
|
||||
env->GetMethodID(db.jniInfo.contextHubServiceClass,
|
||||
"addAppInstance", "(IIJI)I");
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -245,20 +562,29 @@ static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t
|
||||
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);
|
||||
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);
|
||||
env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMaxPacketLenBytes,
|
||||
hub->max_supported_msg_len);
|
||||
|
||||
|
||||
// TODO : jintBuf = env->NewIntArray(hub->num_connected_sensors);
|
||||
// TODO : env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, hub->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);
|
||||
env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSupportedSensors, jintBuf);
|
||||
|
||||
// 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);
|
||||
jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, nullptr);
|
||||
// Note the zero size above. We do not need to set any elements
|
||||
env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf);
|
||||
|
||||
|
||||
return jHub;
|
||||
}
|
||||
|
||||
@@ -267,18 +593,18 @@ static jobjectArray nativeInitialize(JNIEnv *env, jobject instance)
|
||||
jobject hub;
|
||||
jobjectArray retArray;
|
||||
|
||||
initContextHubService();
|
||||
|
||||
if (init_jni(env, instance) < 0) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (db.hubInfo.numHubs > 1) {
|
||||
ALOGW("Clamping the number of hubs to 1");
|
||||
db.hubInfo.numHubs = 1;
|
||||
}
|
||||
|
||||
retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, nullptr);
|
||||
|
||||
for(int i = 0; i < db.hubInfo.numHubs; i++) {
|
||||
hub = constructJContextHubInfo(env, &db.hubInfo.hubs[i]);
|
||||
@@ -291,28 +617,27 @@ static jobjectArray nativeInitialize(JNIEnv *env, jobject instance)
|
||||
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 retVal = -1; // Default to failure
|
||||
|
||||
jint *header = env->GetIntArrayElements(header_, 0);
|
||||
//int numHeaderElements = env->GetArrayLength(header_);
|
||||
unsigned 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);
|
||||
if (numHeaderElements >= MSG_HEADER_SIZE) {
|
||||
if (set_dest_app(&msg, header[HEADER_FIELD_APP_INSTANCE]) == 0) {
|
||||
msg.message_type = header[HEADER_FIELD_MSG_TYPE];
|
||||
msg.message_len = dataBufferLength;
|
||||
msg.message = data;
|
||||
retVal = db.hubInfo.contextHubModule->send_message(
|
||||
get_hub_id_for_app_instance(header[HEADER_FIELD_APP_INSTANCE]),
|
||||
&msg);
|
||||
} else {
|
||||
ALOGD("Could not find app instance %d", header[HEADER_FIELD_APP_INSTANCE]);
|
||||
}
|
||||
} else {
|
||||
ALOGD("Malformed header len");
|
||||
}
|
||||
|
||||
env->ReleaseIntArrayElements(header_, header, 0);
|
||||
env->ReleaseByteArrayElements(data_, data, 0);
|
||||
|
||||
Reference in New Issue
Block a user