Revert "Added handling apps query response from context hub"

This reverts commit adf75e31f5.

Change-Id: I8391eb57c3a53e686bd817d27860fa6f785113f1
This commit is contained in:
Ashutosh Joshi
2016-04-01 20:48:13 +00:00
parent 439a298b1f
commit 2c697fb4a8
8 changed files with 170 additions and 575 deletions

View File

@@ -15271,7 +15271,6 @@ 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();
@@ -15299,6 +15298,10 @@ 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 {
@@ -15492,7 +15495,7 @@ package android.hardware.location {
public class NanoAppInstanceInfo {
ctor public NanoAppInstanceInfo();
method public int describeContents();
method public long getAppId();
method public int getAppId();
method public int getAppVersion();
method public int getContexthubId();
method public int getHandle();
@@ -15503,6 +15506,17 @@ 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;
}

View File

@@ -37,7 +37,6 @@ public class ContextHubInfo {
private float mStoppedPowerDrawMw;
private float mSleepPowerDrawMw;
private float mPeakPowerDrawMw;
private int mMaxPacketLengthBytes;
private int[] mSupportedSensors;
@@ -46,27 +45,6 @@ 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
*
@@ -396,4 +374,4 @@ public class ContextHubInfo {
return new ContextHubInfo[size];
}
};
}
}

View File

@@ -42,6 +42,23 @@ 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.
*/
@@ -52,7 +69,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 app instance that sent the message.
* @param nanoAppHandle Handle (unique identifier) for the app that sent the message.
* @param message The context hub message.
*
* @see ContextHubMessage
@@ -72,7 +89,7 @@ public final class ContextHubManager {
try {
retVal = getBinder().getContextHubHandles();
} catch (RemoteException e) {
Log.w(TAG, "Could not fetch context hub handles : " + e);
Log.e(TAG, "Could not fetch context hub handles : " + e);
}
return retVal;
}
@@ -90,7 +107,7 @@ public final class ContextHubManager {
try {
retVal = getBinder().getContextHubInfo(hubHandle);
} catch (RemoteException e) {
Log.w(TAG, "Could not fetch context hub info :" + e);
Log.e(TAG, "Could not fetch context hub info :" + e);
}
return retVal;
@@ -109,7 +126,6 @@ public final class ContextHubManager {
*/
public int loadNanoApp(int hubHandle, NanoApp app) {
int retVal = -1;
if (app == null) {
return retVal;
}
@@ -117,7 +133,7 @@ public final class ContextHubManager {
try {
retVal = getBinder().loadNanoApp(hubHandle, app);
} catch (RemoteException e) {
Log.w(TAG, "Could not load nanoApp :" + e);
Log.e(TAG, "Could not fetch load nanoApp :" + e);
}
return retVal;
@@ -136,7 +152,7 @@ public final class ContextHubManager {
try {
retVal = getBinder().unloadNanoApp(nanoAppHandle);
} catch (RemoteException e) {
Log.w(TAG, "Could not fetch unload nanoApp :" + e);
Log.e(TAG, "Could not fetch unload nanoApp :" + e);
}
return retVal;
@@ -156,7 +172,7 @@ public final class ContextHubManager {
try {
retVal = getBinder().getNanoAppInstanceInfo(nanoAppHandle);
} catch (RemoteException e) {
Log.w(TAG, "Could not fetch nanoApp info :" + e);
Log.e(TAG, "Could not fetch nanoApp info :" + e);
}
return retVal;
@@ -177,7 +193,7 @@ public final class ContextHubManager {
try {
retVal = getBinder().findNanoAppOnHub(hubHandle, filter);
} catch (RemoteException e) {
Log.w(TAG, "Could not query nanoApp instance :" + e);
Log.e(TAG, "Could not query nanoApp instance :" + e);
}
return retVal;
}
@@ -196,14 +212,10 @@ 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.w(TAG, "Could not send message :" + e.toString());
Log.e(TAG, "Could not fetch send message :" + e.toString());
}
return retVal;
@@ -235,7 +247,7 @@ public final class ContextHubManager {
public int registerCallback(Callback callback, Handler handler) {
synchronized(this) {
if (mCallback != null) {
Log.w(TAG, "Max number of callbacks reached!");
Log.e(TAG, "Max number of callbacks reached!");
return -1;
}
mCallback = callback;
@@ -256,7 +268,7 @@ public final class ContextHubManager {
public int unregisterCallback(Callback callback) {
synchronized(this) {
if (callback != mCallback) {
Log.w(TAG, "Cannot recognize callback!");
Log.e(TAG, "Cannot recognize callback!");
return -1;
}
@@ -299,11 +311,11 @@ public final class ContextHubManager {
try {
getBinder().registerCallback(mClientCallback);
} catch (RemoteException e) {
Log.w(TAG, "Could not register callback:" + e);
Log.e(TAG, "Could not register callback:" + e);
}
} else {
Log.w(TAG, "failed to getService");
Log.d(TAG, "failed to getService");
}
}

View File

@@ -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,9 +32,6 @@ public class ContextHubMessage {
private int mVersion;
private byte[]mData;
private static final String TAG = "ContextHubMessage";
/**
* Get the message type
*
@@ -109,11 +106,9 @@ public class ContextHubMessage {
private ContextHubMessage(Parcel in) {
mType = in.readInt();
mVersion = in.readInt();
int bufferLength = in.readInt();
mData = new byte[bufferLength];
in.readByteArray(mData);
byte[] byteBuffer = new byte[in.readInt()];
in.readByteArray(byteBuffer);
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mType);
out.writeInt(mVersion);

View File

@@ -29,30 +29,12 @@ 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 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;
public static final String CONTEXTHUB_SERVICE = "contexthub_service";
private final Context mContext;
@@ -60,27 +42,44 @@ 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.d(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
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();
@Override
public int registerCallback(IContextHubCallback callback) throws RemoteException {
public int registerCallback(IContextHubCallback callback) throws RemoteException{
checkPermissions();
synchronized(this) {
mCallback = callback;
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");
}
return 0;
}
@@ -119,17 +118,14 @@ public class ContextHubService extends IContextHubService.Stub {
}
// Call Native interface here
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;
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
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;
return nativeSendMessage(msgHeader, app.getAppBinary());
}
@Override
@@ -141,18 +137,12 @@ public class ContextHubService extends IContextHubService.Stub {
}
// Call Native interface here
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;
int[] msgHeader = new int[8];
msgHeader[0] = info.getContexthubId();
msgHeader[1] = ContextHubManager.MSG_UNLOAD_NANO_APP;
msgHeader[2] = info.getHandle();
if(nativeSendMessage(msgHeader, null) != 0) {
return -1;
}
// Do not add an entry to mNanoAppInstance Hash yet. The HAL may reject the app
return 0;
return nativeSendMessage(msgHeader, null);
}
@Override
@@ -176,7 +166,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);
}
}
@@ -193,12 +183,12 @@ public class ContextHubService extends IContextHubService.Stub {
public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg)
throws RemoteException {
checkPermissions();
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();
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());
}
@@ -206,52 +196,5 @@ 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;
}
}

View File

@@ -20,7 +20,6 @@ package android.hardware.location;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
/**
* @hide
@@ -28,8 +27,6 @@ import android.util.Log;
@SystemApi
public class NanoAppFilter {
private static final String TAG = "NanoAppFilter";
// The appId, can be set to APP_ID_ANY
private long mAppId;
@@ -57,10 +54,6 @@ 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;
/**
@@ -124,9 +117,14 @@ public class NanoAppFilter {
* @return true if this is a match, false otherwise
*/
public boolean testMatch(NanoAppInstanceInfo info) {
return (mContextHubId == HUB_ANY || info.getContexthubId() == mContextHubId) &&
if ((mContextHubId == HUB_ANY || info.getContexthubId() == mContextHubId) &&
(mAppId == APP_ANY || info.getAppId() == mAppId) &&
(versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()));
// (mAppIdVendorMask == VENDOR_ANY) TODO : Expose Vendor mask cleanly
(versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()))) {
return true;
} else {
return false;
}
}
public static final Parcelable.Creator<NanoAppFilter> CREATOR

View File

@@ -29,7 +29,7 @@ public class NanoAppInstanceInfo {
private String mPublisher;
private String mName;
private long mAppId;
private int mAppId;
private int mAppVersion;
private int mNeededReadMemBytes;
@@ -59,8 +59,6 @@ public class NanoAppInstanceInfo {
* set the publisher name for the app
*
* @param publisher - name of the publisher
*
* @hide
*/
public void setPublisher(String publisher) {
mPublisher = publisher;
@@ -79,8 +77,6 @@ public class NanoAppInstanceInfo {
* set the name of the app
*
* @param name - name of the app
*
* @hide
*/
public void setName(String name) {
mName = name;
@@ -91,7 +87,7 @@ public class NanoAppInstanceInfo {
*
* @return int - application identifier
*/
public long getAppId() {
public int getAppId() {
return mAppId;
}
@@ -99,10 +95,8 @@ public class NanoAppInstanceInfo {
* Set the application identifier
*
* @param appId - application identifier
*
* @hide
*/
public void setAppId(long appId) {
public void setAppId(int appId) {
mAppId = appId;
}
@@ -119,8 +113,6 @@ public class NanoAppInstanceInfo {
* Set the application version
*
* @param appVersion - version of the app
*
* @hide
*/
public void setAppVersion(int appVersion) {
mAppVersion = appVersion;
@@ -139,8 +131,6 @@ 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;
@@ -160,8 +150,6 @@ public class NanoAppInstanceInfo {
*
* @param neededWriteMemBytes - writable memory needed by the
* app
*
* @hide
*/
public void setNeededWriteMemBytes(int neededWriteMemBytes) {
mNeededWriteMemBytes = neededWriteMemBytes;
@@ -181,8 +169,6 @@ public class NanoAppInstanceInfo {
*
* @param neededExecMemBytes - executable memory needed by the
* app
*
* @hide
*/
public void setNeededExecMemBytes(int neededExecMemBytes) {
mNeededExecMemBytes = neededExecMemBytes;
@@ -201,8 +187,6 @@ 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;
@@ -222,8 +206,6 @@ public class NanoAppInstanceInfo {
*
* @param outputEvents - the events that may be generated by
* this app
*
* @hide
*/
public void setOutputEvents(int[] outputEvents) {
mOutputEvents = outputEvents;
@@ -242,8 +224,6 @@ public class NanoAppInstanceInfo {
* set the context hub identifier
*
* @param contexthubId - system wide unique identifier
*
* @hide
*/
public void setContexthubId(int contexthubId) {
mContexthubId = contexthubId;
@@ -262,8 +242,6 @@ public class NanoAppInstanceInfo {
* set the handle for an app instance
*
* @param handle - handle to this instance
*
* @hide
*/
public void setHandle(int handle) {
mHandle = handle;
@@ -274,7 +252,7 @@ public class NanoAppInstanceInfo {
mPublisher = in.readString();
mName = in.readString();
mAppId = in.readLong();
mAppId = in.readInt();
mAppVersion = in.readInt();
mNeededReadMemBytes = in.readInt();
mNeededWriteMemBytes = in.readInt();
@@ -296,7 +274,7 @@ public class NanoAppInstanceInfo {
public void writeToParcel(Parcel out, int flags) {
out.writeString(mPublisher);
out.writeString(mName);
out.writeLong(mAppId);
out.writeInt(mAppId);
out.writeInt(mAppVersion);
out.writeInt(mContexthubId);
out.writeInt(mNeededReadMemBytes);
@@ -308,6 +286,7 @@ public class NanoAppInstanceInfo {
out.writeInt(mOutputEvents.length);
out.writeIntArray(mOutputEvents);
}
public static final Parcelable.Creator<NanoAppInstanceInfo> CREATOR

View File

@@ -16,39 +16,23 @@
#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"
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;
#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.
@@ -80,207 +64,35 @@ struct jniInfo_s {
jmethodID contextHubInfoSetPeakPowerDrawMw;
jmethodID contextHubInfoSetSupportedSensors;
jmethodID contextHubInfoSetMemoryRegions;
jmethodID contextHubInfoSetMaxPacketLenBytes;
jmethodID contextHubServiceMsgReceiptCallback;
jmethodID contextHubServiceAddAppInstance;
};
struct context_hub_info_s {
uint32_t *cookies;
int cookie;
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 hubId, const struct hub_message_t *msg,
int context_hub_callback(uint32_t hub_id, 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, %d, %d",
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 = nullptr;
db.hubInfo.hubs = NULL;
db.hubInfo.numHubs = 0;
db.hubInfo.cookie = 0;
int i;
err = hw_get_module(CONTEXT_HUB_MODULE_ID,
@@ -291,45 +103,26 @@ static void initContextHubService() {
strerror(-err));
}
// Prep for storing app info
for(i = MIN_APP_ID; i <= MAX_APP_ID; i++) {
db.freeIds.push(i);
}
if (db.hubInfo.contextHubModule) {
int retNumHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
ALOGD("Fetching hub info");
db.hubInfo.numHubs = 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) {
}
}
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);
}
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, nullptr) != JNI_OK) {
if ((db.jniInfo.vm)->AttachCurrentThread(&env, NULL) != JNI_OK) {
return -1;
}
@@ -339,131 +132,28 @@ 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) != 0);
jheader, jmsg);
}
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,
int context_hub_callback(uint32_t hub_id, const struct hub_message_t *msg,
void *cookie) {
int msgHeader[MSG_HEADER_SIZE];
int msgHeader[4];
if (!msg) {
return -1;
}
msgHeader[0] = msg->message_type;
msgHeader[1] = 0; // TODO : HAL does not have a version field
msgHeader[2] = hub_id;
msgHeader[HEADER_FIELD_MSG_TYPE] = msg->message_type;
if (!sanity_check_cookie(cookie, hubId)) {
ALOGW("Incorrect cookie %" PRId32 " for cookie %lu! 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;
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;
return -1;
}
db.jniInfo.jContextHubService = env->NewGlobalRef(instance);
@@ -477,6 +167,7 @@ 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 =
@@ -518,9 +209,6 @@ 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 =
@@ -530,11 +218,6 @@ 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;
}
@@ -562,28 +245,20 @@ 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.contextHubInfoSetMaxPacketLenBytes,
hub->max_supported_msg_len);
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);
// 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, nullptr);
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;
}
@@ -592,18 +267,18 @@ static jobjectArray nativeInitialize(JNIEnv *env, jobject instance)
jobject hub;
jobjectArray retArray;
initContextHubService();
if (init_jni(env, instance) < 0) {
return nullptr;
return NULL;
}
// Note : The service is clamping the number of hubs to 1
db.hubInfo.numHubs = 1;
initContextHubService();
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);
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]);
@@ -616,27 +291,28 @@ static jobjectArray nativeInitialize(JNIEnv *env, jobject instance)
static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_,
jbyteArray data_) {
hub_message_t msg;
jint retVal = -1; // Default to failure
hub_app_name_t dest;
uint8_t os_name[8];
memset(os_name, 0, sizeof(os_name));
jint *header = env->GetIntArrayElements(header_, 0);
unsigned int numHeaderElements = env->GetArrayLength(header_);
//int numHeaderElements = env->GetArrayLength(header_);
jbyte *data = env->GetByteArrayElements(data_, 0);
int dataBufferLength = env->GetArrayLength(data_);
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");
}
/* 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);