diff --git a/api/system-current.txt b/api/system-current.txt index bb48f7856db04..32fb87f3274f2 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -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 CREATOR; } public final class ContextHubManager { method public java.lang.Integer[] findNanoAppOnHub(int, android.hardware.location.NanoAppFilter); - method public int[] getContexthubHandles(); - method public android.hardware.location.ContextHubInfo getContexthubInfo(int); + method public int[] getContextHubHandles(); + method public android.hardware.location.ContextHubInfo getContextHubInfo(int); method public android.hardware.location.NanoAppInstanceInfo getNanoAppInstanceInfo(int); method public int loadNanoApp(int, android.hardware.location.NanoApp); + method public int registerContextHubCallback(android.hardware.location.ContextHubManager.ContextHubCallback); + method public int registerContextHubCallback(android.hardware.location.ContextHubManager.ContextHubCallback, android.os.Handler); method public int sendMessage(int, int, android.hardware.location.ContextHubMessage); method public int unloadNanoApp(int); + method public int unregisterContextHubCallback(android.hardware.location.ContextHubManager.ContextHubCallback); field public static final int ANY_HUB = -1; // 0xffffffff field public static final int MSG_DATA_SEND = 3; // 0x3 field public static final int MSG_LOAD_NANO_APP = 1; // 0x1 field public static final int MSG_UNLOAD_NANO_APP = 2; // 0x2 } + public abstract class ContextHubManager.ContextHubCallback { + ctor public ContextHubManager.ContextHubCallback(); + } + public class ContextHubMessage { ctor public ContextHubMessage(int, int, byte[]); method public int describeContents(); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 6c0b69c8afdb3..9d7f7246a25da 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -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() { + @Override + public ContextHubManager createService(ContextImpl ctx) { + return new ContextHubManager(ctx.getOuterContext(), + ctx.mMainThread.getHandler().getLooper()); + }}); } /** diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index ccb0552ae4829..c4dfdcf104051 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -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, diff --git a/core/java/android/hardware/location/ContextHubInfo.aidl b/core/java/android/hardware/location/ContextHubInfo.aidl index 1a9221a02cc3f..8de03daf203d0 100644 --- a/core/java/android/hardware/location/ContextHubInfo.aidl +++ b/core/java/android/hardware/location/ContextHubInfo.aidl @@ -15,7 +15,7 @@ */ package android.hardware.location; -/* -@hide -*/ +/** + * @hide + */ parcelable ContextHubInfo; diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java index e47c541ee62be..644e29fcaedfe 100644 --- a/core/java/android/hardware/location/ContextHubInfo.java +++ b/core/java/android/hardware/location/ContextHubInfo.java @@ -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); diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java index 301b2e49a19c6..38a760a065ddf 100644 --- a/core/java/android/hardware/location/ContextHubManager.java +++ b/core/java/android/hardware/location/ContextHubManager.java @@ -15,18 +15,24 @@ */ package android.hardware.location; +import android.Manifest; import android.annotation.SystemApi; -import android.hardware.location.NanoAppInstanceInfo; import android.content.ComponentName; import android.content.Context; import android.content.ServiceConnection; -import android.Manifest; +import android.hardware.location.ContextHubService; +import android.hardware.location.NanoAppInstanceInfo; +import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.RemoteException; +import android.os.ServiceManager; import android.util.Log; import java.util.ArrayList; import java.util.HashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; /** * A class that exposes the Context hubs on a device to @@ -48,9 +54,12 @@ 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; + } } diff --git a/core/java/android/hardware/location/ContextHubMessage.aidl b/core/java/android/hardware/location/ContextHubMessage.aidl index 915f1ec683c96..56704e70ba5f8 100644 --- a/core/java/android/hardware/location/ContextHubMessage.aidl +++ b/core/java/android/hardware/location/ContextHubMessage.aidl @@ -15,8 +15,8 @@ */ package android.hardware.location; -/* -@hide -*/ +/** + * @hide + */ parcelable ContextHubMessage; diff --git a/core/java/android/hardware/location/ContextHubService.java b/core/java/android/hardware/location/ContextHubService.java index a2a13c6f82896..658d90bae21e7 100644 --- a/core/java/android/hardware/location/ContextHubService.java +++ b/core/java/android/hardware/location/ContextHubService.java @@ -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 mHubHash; private HashMap 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(); - 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 foundInstances = new ArrayList(); + + 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 foundInstances = new ArrayList(); - - for(Integer nanoAppInstance : mNanoAppHash.keySet()) { - NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance); - - if(filter.testMatch(info)){ - foundInstances.add(nanoAppInstance); - } - } - - int[] retArray = new int[foundInstances.size()]; - for (int i = 0; i < foundInstances.size(); i++) { - retArray[i] = foundInstances.get(i).intValue(); - } - - return retArray; - } - - @Override - public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg) throws RemoteException { - int[] msgHeader = new int[8]; - msgHeader[0] = ContextHubManager.MSG_DATA_SEND; - msgHeader[1] = hubHandle; - msgHeader[2] = nanoAppHandle; - msgHeader[3] = msg.getMsgType(); - msgHeader[4] = msg.getVersion(); - - return (nativeSendMessage(msgHeader, msg.getData())); - } - }; } + diff --git a/core/java/android/hardware/location/IContextHubCallback.aidl b/core/java/android/hardware/location/IContextHubCallback.aidl index 45b1ef494ac26..141fcf6a598b5 100644 --- a/core/java/android/hardware/location/IContextHubCallback.aidl +++ b/core/java/android/hardware/location/IContextHubCallback.aidl @@ -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); } diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl index b2db0b2cdd236..ff8c1d07ce2c1 100644 --- a/core/java/android/hardware/location/IContextHubService.aidl +++ b/core/java/android/hardware/location/IContextHubService.aidl @@ -24,11 +24,13 @@ import android.hardware.location.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(); diff --git a/core/java/android/hardware/location/MemoryRegion.java b/core/java/android/hardware/location/MemoryRegion.java index e8c761527c2c0..d100de2575497 100644 --- a/core/java/android/hardware/location/MemoryRegion.java +++ b/core/java/android/hardware/location/MemoryRegion.java @@ -23,7 +23,6 @@ import android.os.Parcelable; /** * @hide */ - @SystemApi public class MemoryRegion implements Parcelable{ diff --git a/core/java/android/hardware/location/NanoApp.aidl b/core/java/android/hardware/location/NanoApp.aidl index d32c44a5c44a1..9df9a087afdc6 100644 --- a/core/java/android/hardware/location/NanoApp.aidl +++ b/core/java/android/hardware/location/NanoApp.aidl @@ -15,7 +15,7 @@ */ package android.hardware.location; -/* -@hide -*/ +/** + * @hide + */ parcelable NanoApp; diff --git a/core/java/android/hardware/location/NanoApp.java b/core/java/android/hardware/location/NanoApp.java index 36d181f91fba7..b447b62457122 100644 --- a/core/java/android/hardware/location/NanoApp.java +++ b/core/java/android/hardware/location/NanoApp.java @@ -13,16 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package android.hardware.location; - import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -/** - * A class describing nano apps. +/** A class describing nano apps. * A nano app is a piece of executable code that can be * downloaded onto a specific architecture. These are targtted * for low power compute domains on a device. diff --git a/core/java/android/hardware/location/NanoAppFilter.aidl b/core/java/android/hardware/location/NanoAppFilter.aidl index cc6d4755997ae..5f10201116139 100644 --- a/core/java/android/hardware/location/NanoAppFilter.aidl +++ b/core/java/android/hardware/location/NanoAppFilter.aidl @@ -15,7 +15,7 @@ */ package android.hardware.location; -/* -@hide -*/ +/** + * @hide + */ parcelable NanoAppFilter; diff --git a/core/java/android/hardware/location/NanoAppFilter.java b/core/java/android/hardware/location/NanoAppFilter.java index ac341e417b644..369f9e44e8d94 100644 --- a/core/java/android/hardware/location/NanoAppFilter.java +++ b/core/java/android/hardware/location/NanoAppFilter.java @@ -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 */ diff --git a/core/java/android/hardware/location/NanoAppInstanceInfo.aidl b/core/java/android/hardware/location/NanoAppInstanceInfo.aidl index c8c40d7be2339..2db5566a590dc 100644 --- a/core/java/android/hardware/location/NanoAppInstanceInfo.aidl +++ b/core/java/android/hardware/location/NanoAppInstanceInfo.aidl @@ -15,7 +15,7 @@ */ package android.hardware.location; -/* -@hide -*/ -parcelable NanoAppInstanceInfo; \ No newline at end of file +/** + * @hide + */ +parcelable NanoAppInstanceInfo; diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 623b603d8280e..8ef1a22aef765 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -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 \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 798a6deb92f96..95323f75706e1 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -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), diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp new file mode 100644 index 0000000000000..87247292a73b8 --- /dev/null +++ b/core/jni/android_hardware_location_ContextHubService.cpp @@ -0,0 +1,344 @@ +/* + * Copyright 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "context_hub.h" + +#include +#include +#include + +#include +#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 +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, "", "()V"); + db.jniInfo.contextHubInfoSetId = + env->GetMethodID(db.jniInfo.contextHubInfoClass, "setId", "(I)V"); + db.jniInfo.contextHubInfoSetName = + env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName", + "(Ljava/lang/String;)V"); + + db.jniInfo.contextHubInfoSetVendor = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setVendor", "(Ljava/lang/String;)V"); + db.jniInfo.contextHubInfoSetToolchain = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setToolchain", "(Ljava/lang/String;)V"); + db.jniInfo.contextHubInfoSetPlatformVersion = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setPlatformVersion", "(I)V"); + db.jniInfo.contextHubInfoSetStaticSwVersion = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setStaticSwVersion", "(I)V"); + db.jniInfo.contextHubInfoSetToolchainVersion = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setToolchainVersion", "(I)V"); + db.jniInfo.contextHubInfoSetPeakMips = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setPeakMips", "(F)V"); + db.jniInfo.contextHubInfoSetStoppedPowerDrawMw = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setStoppedPowerDrawMw", "(F)V"); + db.jniInfo.contextHubInfoSetSleepPowerDrawMw = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setSleepPowerDrawMw", "(F)V"); + db.jniInfo.contextHubInfoSetPeakPowerDrawMw = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setPeakPowerDrawMw", "(F)V"); + db.jniInfo.contextHubInfoSetSupportedSensors = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setSupportedSensors", "([I)V"); + db.jniInfo.contextHubInfoSetMemoryRegions = + env->GetMethodID(db.jniInfo.contextHubInfoClass, + "setMemoryRegions", "([Landroid/hardware/location/MemoryRegion;)V"); + + + db.jniInfo.contextHubServiceMsgReceiptCallback = + env->GetMethodID(db.jniInfo.contextHubServiceClass, "onMessageReceipt", + "([I[B)I"); + db.jniInfo.contextHubInfoSetName = + env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName", + "(Ljava/lang/String;)V"); + + + return 0; +} + +static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t *hub) { + jstring jstrBuf; + jintArray jintBuf; + jobjectArray jmemBuf; + + int dummyConnectedSensors[] = {1, 2, 3, 4, 5}; + + jobject jHub = env->NewObject(db.jniInfo.contextHubInfoClass, + db.jniInfo.contextHubInfoCtor); + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetId, hub->hub_id); + + jstrBuf = env->NewStringUTF(hub->name); + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetName, jstrBuf); + + jstrBuf = env->NewStringUTF(hub->vendor); + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetVendor, jstrBuf); + + jstrBuf = env->NewStringUTF(hub->toolchain); + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchain, jstrBuf); + + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPlatformVersion, hub->platform_version); + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchainVersion, hub->toolchain_version); + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakMips, hub->peak_mips); + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw, hub->stopped_power_draw_mw); + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw, hub->sleep_power_draw_mw); + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw, hub->peak_power_draw_mw); + + // TODO : jintBuf = env->NewIntArray(hub->num_connected_sensors); + // TODO : env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, hub->connected_sensors); + jintBuf = env->NewIntArray(array_length(dummyConnectedSensors)); + env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, dummyConnectedSensors); + + // We are not getting the memory regions from the CH Hal - change this when it is available + jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, NULL); + // Note the zero size above. We do not need to set any elements + env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf); + + return jHub; +} + +static jobjectArray nativeInitialize(JNIEnv *env, jobject instance) +{ + jobject hub; + jobjectArray retArray; + + initContextHubService(); + + if (init_jni(env, instance) < 0) { + return NULL; + } + + // Note : The service is clamping the number of hubs to 1 + db.hubInfo.numHubs = 1; + + initContextHubService(); + + retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, NULL); + + for(int i = 0; i < db.hubInfo.numHubs; i++) { + hub = constructJContextHubInfo(env, &db.hubInfo.hubs[i]); + env->SetObjectArrayElement(retArray, i, hub); + } + + return retArray; +} + +static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_, + jbyteArray data_) { + hub_message_t msg; + hub_app_name_t dest; + uint8_t os_name[8]; + + memset(os_name, 0, sizeof(os_name)); + + jint *header = env->GetIntArrayElements(header_, 0); + //int numHeaderElements = env->GetArrayLength(header_); + jbyte *data = env->GetByteArrayElements(data_, 0); + int dataBufferLength = env->GetArrayLength(data_); + + /* Assume an int - thats all we understand */ + dest.app_name_len = array_length(os_name); // TODO : Check this + //dest.app_name = &header[1]; + dest.app_name = os_name; + + msg.app = &dest; + + msg.message_type = header[3]; + msg.message_len = dataBufferLength; + msg.message = data; + + jint retVal = db.hubInfo.contextHubModule->send_message(header[0], &msg); + + env->ReleaseIntArrayElements(header_, header, 0); + env->ReleaseByteArrayElements(data_, data, 0); + + return retVal; +} + +//-------------------------------------------------------------------------------------------------- +// +static const JNINativeMethod gContextHubServiceMethods[] = { + {"nativeInitialize", + "()[Landroid/hardware/location/ContextHubInfo;", + (void*)nativeInitialize }, + {"nativeSendMessage", + "([I[B)I", + (void*)nativeSendMessage } +}; + +}//namespace android + +using namespace android; + +int register_android_hardware_location_ContextHubService(JNIEnv *env) +{ + RegisterMethodsOrDie(env, "android/hardware/location/ContextHubService", + gContextHubServiceMethods, NELEM(gContextHubServiceMethods)); + + return 0; +} diff --git a/services/core/java/com/android/server/ContextHubSystemService.java b/services/core/java/com/android/server/ContextHubSystemService.java new file mode 100644 index 0000000000000..1b85632b806c6 --- /dev/null +++ b/services/core/java/com/android/server/ContextHubSystemService.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.hardware.location.ContextHubService; +import android.content.Context; +import android.util.Log; + +class ContextHubSystemService extends SystemService { + private static final String TAG = "ContextHubSystemService"; + private final ContextHubService mContextHubService; + + public ContextHubSystemService(Context context) { + super(context); + mContextHubService = new ContextHubService(context); + } + + @Override + public void onStart() { + } + + @Override + public void onBootPhase(int phase) { + if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { + Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY"); + publishBinderService(ContextHubService.CONTEXTHUB_SERVICE, mContextHubService); + } + } +} diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index fc0ac0bbe84eb..19c073ccf4dca 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1032,6 +1032,7 @@ public final class SystemServer { mSystemServiceManager.startService(GestureLauncherService.class); } mSystemServiceManager.startService(SensorNotificationService.class); + mSystemServiceManager.startService(ContextHubSystemService.class); } traceBeginAndSlog("StartDiskStatsService");