Merge "Exposing Context Hub service." into nyc-dev

am: ac329d3

* commit 'ac329d3e34e99e10243906d32cc4e36c626ac8ee':
  Exposing Context Hub service.
This commit is contained in:
Peng Xu
2016-03-16 17:28:16 +00:00
committed by android-build-merger
21 changed files with 772 additions and 269 deletions

View File

@@ -8409,6 +8409,7 @@ package android.content {
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
@@ -15277,37 +15278,31 @@ package android.hardware.location {
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();

View File

@@ -51,6 +51,7 @@ import android.hardware.display.DisplayManager;
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 @@ final class SystemServiceRegistry {
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());
}});
}
/**

View File

@@ -2681,6 +2681,7 @@ public abstract class Context {
HARDWARE_PROPERTIES_SERVICE,
//@hide: SOUND_TRIGGER_SERVICE,
SHORTCUT_SERVICE,
//@hide: CONTEXTHUB_SERVICE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ServiceName {}
@@ -3584,6 +3585,18 @@ public abstract class Context {
*/
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,

View File

@@ -15,7 +15,7 @@
*/
package android.hardware.location;
/*
@hide
*/
/**
* @hide
*/
parcelable ContextHubInfo;

View File

@@ -23,7 +23,7 @@ import java.util.Arrays;
/**
* @hide
*/
*/
@SystemApi
public class ContextHubInfo {
private int mId;
@@ -58,6 +58,8 @@ public class ContextHubInfo {
* 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 @@ public class ContextHubInfo {
/**
* 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 @@ public class ContextHubInfo {
/**
* 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 @@ public class ContextHubInfo {
/**
* 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 @@ public class ContextHubInfo {
* set platform version
*
* @param platformVersion - platform version number
*
* @hide
*/
public void setPlatformVersion(int platformVersion) {
mPlatformVersion = platformVersion;
@@ -148,6 +158,8 @@ public class ContextHubInfo {
* set platform software version
*
* @param staticSwVersion - platform static s/w version number
*
* @hide
*/
public void setStaticSwVersion(int staticSwVersion) {
mStaticSwVersion = staticSwVersion;
@@ -166,6 +178,8 @@ public class ContextHubInfo {
* set the tool chain version number
*
* @param toolchainVersion - tool chain version number
*
* @hide
*/
public void setToolchainVersion(int toolchainVersion) {
mToolchainVersion = toolchainVersion;
@@ -184,6 +198,8 @@ public class ContextHubInfo {
* 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 @@ public class ContextHubInfo {
* 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 @@ public class ContextHubInfo {
* 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 @@ public class ContextHubInfo {
*
* @param peakPowerDrawMw - peak power draw of the hub in
* milliwatts.
*
* @hide
*/
public void setPeakPowerDrawMw(float peakPowerDrawMw) {
mPeakPowerDrawMw = peakPowerDrawMw;
@@ -281,6 +303,8 @@ public class ContextHubInfo {
* 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 @@ public class ContextHubInfo {
* @param memoryRegions - memory regions information
*
* @see MemoryRegion
*
* @hide
*/
public void setMemoryRegions(MemoryRegion[] memoryRegions) {
mMemoryRegions = Arrays.copyOf(memoryRegions, memoryRegions.length);

View File

@@ -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 @@ public final class ContextHubManager {
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 final class ContextHubManager {
*/
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 @@ public final class ContextHubManager {
*
* @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 final class ContextHubManager {
*/
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 final class ContextHubManager {
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 final class ContextHubManager {
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 @@ public final class ContextHubManager {
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 @@ public final class ContextHubManager {
*
* @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;
}
}

View File

@@ -15,8 +15,8 @@
*/
package android.hardware.location;
/*
@hide
*/
/**
* @hide
*/
parcelable ContextHubMessage;

View File

@@ -29,175 +29,157 @@ import java.util.HashMap;
/**
* @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 final Context mContext;
private HashMap<Integer, ContextHubInfo> mHubHash;
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()));
}
};
}

View File

@@ -18,7 +18,9 @@ package android.hardware.location;
import android.hardware.location.ContextHubMessage;
/** @hide */
/**
* @hide
*/
oneway interface IContextHubCallback {
void onMessageReceipt(int hubId, int nanoAppId, in ContextHubMessage msg);
}

View File

@@ -24,11 +24,13 @@ import android.hardware.location.NanoAppInstanceInfo;
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();

View File

@@ -23,7 +23,6 @@ import android.os.Parcelable;
/**
* @hide
*/
@SystemApi
public class MemoryRegion implements Parcelable{

View File

@@ -15,7 +15,7 @@
*/
package android.hardware.location;
/*
@hide
*/
/**
* @hide
*/
parcelable NanoApp;

View File

@@ -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.

View File

@@ -15,7 +15,7 @@
*/
package android.hardware.location;
/*
@hide
*/
/**
* @hide
*/
parcelable NanoAppFilter;

View File

@@ -110,8 +110,9 @@ public class NanoAppFilter {
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
*/

View File

@@ -15,7 +15,7 @@
*/
package android.hardware.location;
/*
@hide
*/
parcelable NanoAppInstanceInfo;
/**
* @hide
*/
parcelable NanoAppInstanceInfo;

View File

@@ -161,6 +161,7 @@ LOCAL_SRC_FILES:= \
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 \

View File

@@ -95,6 +95,7 @@ extern int register_android_hardware_UsbDevice(JNIEnv *env);
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);
@@ -1357,6 +1358,7 @@ static const RegJNIRec gRegJNI[] = {
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),

View File

@@ -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;
}

View File

@@ -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);
}
}
}

View File

@@ -1032,6 +1032,7 @@ public final class SystemServer {
mSystemServiceManager.startService(GestureLauncherService.class);
}
mSystemServiceManager.startService(SensorNotificationService.class);
mSystemServiceManager.startService(ContextHubSystemService.class);
}
traceBeginAndSlog("StartDiskStatsService");