summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2017-10-27 15:29:57 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-10-27 15:29:57 +0000
commit584429921f98ad293f56bf72fa6d0780ee06a43f (patch)
treee649c8b04b639db87722cf47f049032124fdcf6a
parent7a78665016562f1e0677aea0fc82ecf747bafd10 (diff)
parentb9ae7bd8389deeb4abbe034dc97f151c60c13044 (diff)
Merge "Creates framework for new ContextHubService APIs"
-rw-r--r--core/java/android/hardware/location/ContextHubClient.java95
-rw-r--r--core/java/android/hardware/location/ContextHubClientCallback.java85
-rw-r--r--core/java/android/hardware/location/ContextHubManager.java121
-rw-r--r--core/java/android/hardware/location/ContextHubTransaction.java229
-rw-r--r--core/java/android/hardware/location/NanoAppBinary.aidl22
-rw-r--r--core/java/android/hardware/location/NanoAppBinary.java198
-rw-r--r--core/java/android/hardware/location/NanoAppMessage.aidl22
-rw-r--r--core/java/android/hardware/location/NanoAppMessage.java143
-rw-r--r--core/java/android/hardware/location/NanoAppState.aidl22
-rw-r--r--core/java/android/hardware/location/NanoAppState.java88
10 files changed, 1024 insertions, 1 deletions
diff --git a/core/java/android/hardware/location/ContextHubClient.java b/core/java/android/hardware/location/ContextHubClient.java
new file mode 100644
index 000000000000..b7e353a4860c
--- /dev/null
+++ b/core/java/android/hardware/location/ContextHubClient.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2017 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 android.hardware.location;
+
+import android.annotation.RequiresPermission;
+import android.os.Handler;
+
+import java.io.Closeable;
+
+/**
+ * A class describing a client of the Context Hub Service.
+ *
+ * Clients can send messages to nanoapps at a Context Hub through this object.
+ *
+ * @hide
+ */
+public class ContextHubClient implements Closeable {
+ /*
+ * The ContextHubClient interface associated with this client.
+ */
+ // TODO: Implement this interface and associate with ContextHubClient object
+ // private final IContextHubClient mClientInterface;
+
+ /*
+ * The listening callback associated with this client.
+ */
+ private ContextHubClientCallback mCallback;
+
+ /*
+ * The Context Hub that this client is attached to.
+ */
+ private ContextHubInfo mAttachedHub;
+
+ /*
+ * The handler to invoke mCallback.
+ */
+ private Handler mCallbackHandler;
+
+ ContextHubClient(ContextHubClientCallback callback, Handler handler, ContextHubInfo hubInfo) {
+ mCallback = callback;
+ mCallbackHandler = handler;
+ mAttachedHub = hubInfo;
+ }
+
+ /**
+ * Returns the hub that this client is attached to.
+ *
+ * @return the ContextHubInfo of the attached hub
+ */
+ public ContextHubInfo getAttachedHub() {
+ return mAttachedHub;
+ }
+
+ /**
+ * Closes the connection for this client and the Context Hub Service.
+ *
+ * When this function is invoked, the messaging associated with this client is invalidated.
+ * All futures messages targeted for this client are dropped at the service.
+ */
+ public void close() {
+ throw new UnsupportedOperationException("TODO: Implement this");
+ }
+
+ /**
+ * Sends a message to a nanoapp through the Context Hub Service.
+ *
+ * This function returns TRANSACTION_SUCCESS if the message has reached the HAL, but
+ * does not guarantee delivery of the message to the target nanoapp.
+ *
+ * @param message the message object to send
+ *
+ * @return the result of sending the message defined as in ContextHubTransaction.Result
+ *
+ * @see NanoAppMessage
+ * @see ContextHubTransaction.Result
+ */
+ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ @ContextHubTransaction.Result
+ public int sendMessageToNanoApp(NanoAppMessage message) {
+ throw new UnsupportedOperationException("TODO: Implement this");
+ }
+}
diff --git a/core/java/android/hardware/location/ContextHubClientCallback.java b/core/java/android/hardware/location/ContextHubClientCallback.java
new file mode 100644
index 000000000000..ab19d547025d
--- /dev/null
+++ b/core/java/android/hardware/location/ContextHubClientCallback.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2017 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 android.hardware.location;
+
+/**
+ * A class for {@link android.hardware.location.ContextHubClient ContextHubClient} to
+ * receive messages and life-cycle events from nanoapps in the Context Hub at which the client is
+ * attached to.
+ *
+ * This callback is registered through the
+ * {@link android.hardware.location.ContextHubManager#createClient() creation} of
+ * {@link android.hardware.location.ContextHubClient ContextHubClient}. Callbacks are
+ * invoked in the following ways:
+ * 1) Messages from nanoapps delivered through onMessageFromNanoApp may either be broadcasted
+ * or targeted to a specific client.
+ * 2) Nanoapp or Context Hub events (the remaining callbacks) are broadcasted to all clients, and
+ * the client can choose to ignore the event by filtering through the parameters.
+ *
+ * @hide
+ */
+public class ContextHubClientCallback {
+ /**
+ * Callback invoked when receiving a message from a nanoapp.
+ *
+ * The message contents of this callback may either be broadcasted or targeted to the
+ * client receiving the invocation.
+ *
+ * @param message the message sent by the nanoapp
+ */
+ public void onMessageFromNanoApp(NanoAppMessage message) {}
+
+ /**
+ * Callback invoked when the attached Context Hub has reset.
+ */
+ public void onHubReset() {}
+
+ /**
+ * Callback invoked when a nanoapp aborts at the attached Context Hub.
+ *
+ * @param nanoAppId the ID of the nanoapp that had aborted
+ * @param abortCode the reason for nanoapp's abort, specific to each nanoapp
+ */
+ public void onNanoAppAborted(long nanoAppId, int abortCode) {}
+
+ /**
+ * Callback invoked when a nanoapp is loaded at the attached Context Hub.
+ *
+ * @param nanoAppId the ID of the nanoapp that had been loaded
+ */
+ public void onNanoAppLoaded(long nanoAppId) {}
+
+ /**
+ * Callback invoked when a nanoapp is unloaded from the attached Context Hub.
+ *
+ * @param nanoAppId the ID of the nanoapp that had been unloaded
+ */
+ public void onNanoAppUnloaded(long nanoAppId) {}
+
+ /**
+ * Callback invoked when a nanoapp is enabled at the attached Context Hub.
+ *
+ * @param nanoAppId the ID of the nanoapp that had been enabled
+ */
+ public void onNanoAppEnabled(long nanoAppId) {}
+
+ /**
+ * Callback invoked when a nanoapp is disabled at the attached Context Hub.
+ *
+ * @param nanoAppId the ID of the nanoapp that had been disabled
+ */
+ public void onNanoAppDisabled(long nanoAppId) {}
+}
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 60500463d82e..7cbb436c84ee 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -15,6 +15,7 @@
*/
package android.hardware.location;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
@@ -27,6 +28,8 @@ import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.util.Log;
+import java.util.List;
+
/**
* A class that exposes the Context hubs on a device to applications.
*
@@ -38,7 +41,6 @@ import android.util.Log;
@SystemApi
@SystemService(Context.CONTEXTHUB_SERVICE)
public final class ContextHubManager {
-
private static final String TAG = "ContextHubManager";
private final Looper mMainLooper;
@@ -256,6 +258,100 @@ public final class ContextHubManager {
}
/**
+ * Returns the list of context hubs in the system.
+ *
+ * @return the list of context hub informations
+ *
+ * @see ContextHubInfo
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ public List<ContextHubInfo> getContextHubs() {
+ throw new UnsupportedOperationException("TODO: Implement this");
+ }
+
+ /**
+ * Loads a nanoapp at the specified Context Hub.
+ *
+ * After the nanoapp binary is successfully loaded at the specified hub, the nanoapp will be in
+ * the enabled state.
+ *
+ * @param hubInfo the hub to load the nanoapp on
+ * @param appBinary The app binary to load
+ *
+ * @return the ContextHubTransaction of the request
+ *
+ * @see NanoAppBinary
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ public ContextHubTransaction<Void> loadNanoApp(
+ ContextHubInfo hubInfo, NanoAppBinary appBinary) {
+ throw new UnsupportedOperationException("TODO: Implement this");
+ }
+
+ /**
+ * Unloads a nanoapp at the specified Context Hub.
+ *
+ * @param hubInfo the hub to unload the nanoapp from
+ * @param nanoAppId the app to unload
+ *
+ * @return the ContextHubTransaction of the request
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ public ContextHubTransaction<Void> unloadNanoApp(ContextHubInfo hubInfo, long nanoAppId) {
+ throw new UnsupportedOperationException("TODO: Implement this");
+ }
+
+ /**
+ * Enables a nanoapp at the specified Context Hub.
+ *
+ * @param hubInfo the hub to enable the nanoapp on
+ * @param nanoAppId the app to enable
+ *
+ * @return the ContextHubTransaction of the request
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ public ContextHubTransaction<Void> enableNanoApp(ContextHubInfo hubInfo, long nanoAppId) {
+ throw new UnsupportedOperationException("TODO: Implement this");
+ }
+
+ /**
+ * Disables a nanoapp at the specified Context Hub.
+ *
+ * @param hubInfo the hub to disable the nanoapp on
+ * @param nanoAppId the app to disable
+ *
+ * @return the ContextHubTransaction of the request
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ public ContextHubTransaction<Void> disableNanoApp(ContextHubInfo hubInfo, long nanoAppId) {
+ throw new UnsupportedOperationException("TODO: Implement this");
+ }
+
+ /**
+ * Requests a query for nanoapps loaded at the specified Context Hub.
+ *
+ * @param hubInfo the hub to query a list of nanoapps from
+ *
+ * @return the ContextHubTransaction of the request
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ public ContextHubTransaction<List<NanoAppState>> queryNanoApps(ContextHubInfo hubInfo) {
+ throw new UnsupportedOperationException("TODO: Implement this");
+ }
+
+ /**
* Set a callback to receive messages from the context hub
*
* @param callback Callback object
@@ -307,6 +403,29 @@ public final class ContextHubManager {
}
/**
+ * Creates and registers a client and its callback with the Context Hub Service.
+ *
+ * A client is registered with the Context Hub Service for a specified Context Hub. When the
+ * registration succeeds, the client can send messages to nanoapps through the returned
+ * {@link ContextHubClient} object, and receive notifications through the provided callback.
+ *
+ * @param callback the notification callback to register
+ * @param hubInfo the hub to attach this client to
+ * @param handler the handler to invoke the callback, if null uses the current thread Looper
+ *
+ * @return the registered client object
+ *
+ * @see ContextHubClientCallback
+ *
+ * @hide
+ */
+ public ContextHubClient createClient(
+ ContextHubClientCallback callback, ContextHubInfo hubInfo, @Nullable Handler handler) {
+ throw new UnsupportedOperationException(
+ "TODO: Implement this, and throw an exception on error");
+ }
+
+ /**
* Unregister a callback for receive messages from the context hub.
*
* @see Callback
diff --git a/core/java/android/hardware/location/ContextHubTransaction.java b/core/java/android/hardware/location/ContextHubTransaction.java
new file mode 100644
index 000000000000..4877d38b37e0
--- /dev/null
+++ b/core/java/android/hardware/location/ContextHubTransaction.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2017 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 android.hardware.location;
+
+import android.annotation.IntDef;
+import android.os.Handler;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A class describing a request sent to the Context Hub Service.
+ *
+ * This object is generated as a result of an asynchronous request sent to the Context Hub
+ * through the ContextHubManager APIs. The caller can either retrieve the result
+ * synchronously through a blocking call ({@link #waitForResponse(long, TimeUnit)}) or
+ * asynchronously through a user-defined callback
+ * ({@link #onComplete(ContextHubTransaction.Callback<T>, Handler)}).
+ *
+ * A transaction can be invalidated if the caller of the transaction is no longer active
+ * and the reference to this object is lost, or if timeout period has passed in
+ * {@link #waitForResponse(long, TimeUnit)}.
+ *
+ * @param <T> the type of the contents in the transaction response
+ *
+ * @hide
+ */
+public class ContextHubTransaction<T> {
+ /**
+ * Constants describing the type of a transaction through the Context Hub Service.
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ TYPE_LOAD_NANOAPP,
+ TYPE_UNLOAD_NANOAPP,
+ TYPE_ENABLE_NANOAPP,
+ TYPE_DISABLE_NANOAPP,
+ TYPE_QUERY_NANOAPPS})
+ public @interface Type {}
+ public static final int TYPE_LOAD_NANOAPP = 0;
+ public static final int TYPE_UNLOAD_NANOAPP = 1;
+ public static final int TYPE_ENABLE_NANOAPP = 2;
+ public static final int TYPE_DISABLE_NANOAPP = 3;
+ public static final int TYPE_QUERY_NANOAPPS = 4;
+
+ /**
+ * Constants describing the result of a transaction or request through the Context Hub Service.
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ TRANSACTION_SUCCESS,
+ TRANSACTION_FAILED_UNKNOWN,
+ TRANSACTION_FAILED_BAD_PARAMS,
+ TRANSACTION_FAILED_UNINITIALIZED,
+ TRANSACTION_FAILED_PENDING,
+ TRANSACTION_FAILED_AT_HUB,
+ TRANSACTION_FAILED_TIMEOUT})
+ public @interface Result {}
+ public static final int TRANSACTION_SUCCESS = 0;
+ /**
+ * Generic failure mode.
+ */
+ public static final int TRANSACTION_FAILED_UNKNOWN = 1;
+ /**
+ * Failure mode when the request parameters were not valid.
+ */
+ public static final int TRANSACTION_FAILED_BAD_PARAMS = 2;
+ /**
+ * Failure mode when the Context Hub is not initialized.
+ */
+ public static final int TRANSACTION_FAILED_UNINITIALIZED = 3;
+ /**
+ * Failure mode when there are too many transactions pending.
+ */
+ public static final int TRANSACTION_FAILED_PENDING = 4;
+ /**
+ * Failure mode when the request went through, but failed asynchronously at the hub.
+ */
+ public static final int TRANSACTION_FAILED_AT_HUB = 5;
+ /**
+ * Failure mode when the transaction has timed out.
+ */
+ public static final int TRANSACTION_FAILED_TIMEOUT = 6;
+
+ /**
+ * A class describing the response for a ContextHubTransaction.
+ *
+ * @param <R> the type of the contents in the response
+ */
+ public static class Response<R> {
+ /*
+ * The result of the transaction.
+ */
+ @ContextHubTransaction.Result
+ private int mResult;
+
+ /*
+ * The contents of the response from the Context Hub.
+ */
+ private R mContents;
+
+ Response(@ContextHubTransaction.Result int result, R contents) {
+ mResult = result;
+ mContents = contents;
+ }
+
+ @ContextHubTransaction.Result
+ public int getResult() {
+ return mResult;
+ }
+
+ public R getContents() {
+ return mContents;
+ }
+ }
+
+ /**
+ * An interface describing the callback to be invoked when a transaction completes.
+ *
+ * @param <C> the type of the contents in the transaction response
+ */
+ @FunctionalInterface
+ public interface Callback<C> {
+ /**
+ * The callback to invoke when the transaction completes.
+ *
+ * @param transaction the transaction that this callback was attached to.
+ * @param response the response of the transaction.
+ */
+ void onComplete(
+ ContextHubTransaction<C> transaction, ContextHubTransaction.Response<C> response);
+ }
+
+ /*
+ * The unique identifier representing the transaction.
+ */
+ private int mTransactionId;
+
+ /*
+ * The type of the transaction.
+ */
+ @Type
+ private int mTransactionType;
+
+ /*
+ * The response of the transaction.
+ */
+ private ContextHubTransaction.Response<T> mResponse;
+
+ /*
+ * The handler to invoke the aynsc response supplied by onComplete.
+ */
+ private Handler mHandler = null;
+
+ /*
+ * The callback to invoke when the transaction completes.
+ */
+ private ContextHubTransaction.Callback<T> mCallback = null;
+
+ ContextHubTransaction(int id, @Type int type) {
+ mTransactionId = id;
+ mTransactionType = type;
+ }
+
+ /**
+ * @return the type of the transaction
+ */
+ @Type
+ public int getType() {
+ return mTransactionType;
+ }
+
+ /**
+ * Waits to receive the asynchronous transaction result.
+ *
+ * This function blocks until the Context Hub Service has received a response
+ * for the transaction represented by this object by the Context Hub, or a
+ * specified timeout period has elapsed.
+ *
+ * If the specified timeout has passed, the transaction represented by this object
+ * is invalidated by the Context Hub Service (resulting in a timeout failure in the
+ * response).
+ *
+ * @param timeout the timeout duration
+ * @param unit the unit of the timeout
+ *
+ * @return the transaction response
+ */
+ public ContextHubTransaction.Response<T> waitForResponse(long timeout, TimeUnit unit) {
+ throw new UnsupportedOperationException("TODO: Implement this");
+ }
+
+ /**
+ * Sets a callback to be invoked when the transaction completes.
+ *
+ * This function provides an asynchronous approach to retrieve the result of the
+ * transaction. When the transaction response has been provided by the Context Hub,
+ * the given callback will be posted by the provided handler.
+ *
+ * If the transaction has already completed at the time of invocation, the callback
+ * will be immediately posted by the handler. If the transaction has been invalidated,
+ * the callback will never be invoked.
+ *
+ * @param callback the callback to be invoked upon completion
+ * @param handler the handler to post the callback
+ */
+ public void onComplete(ContextHubTransaction.Callback<T> callback, Handler handler) {
+ throw new UnsupportedOperationException("TODO: Implement this");
+ }
+
+ private void setResponse(ContextHubTransaction.Response<T> response) {
+ mResponse = response;
+ throw new UnsupportedOperationException("TODO: Unblock waitForResponse");
+ }
+}
diff --git a/core/java/android/hardware/location/NanoAppBinary.aidl b/core/java/android/hardware/location/NanoAppBinary.aidl
new file mode 100644
index 000000000000..ff50c93e1e44
--- /dev/null
+++ b/core/java/android/hardware/location/NanoAppBinary.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2017 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 android.hardware.location;
+
+/**
+ * @hide
+ */
+parcelable NanoAppBinary;
diff --git a/core/java/android/hardware/location/NanoAppBinary.java b/core/java/android/hardware/location/NanoAppBinary.java
new file mode 100644
index 000000000000..545422773aed
--- /dev/null
+++ b/core/java/android/hardware/location/NanoAppBinary.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2017 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 android.hardware.location;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * @hide
+ */
+public final class NanoAppBinary implements Parcelable {
+ private static final String TAG = "NanoAppBinary";
+
+ /*
+ * The contents of the app binary.
+ */
+ private byte[] mNanoAppBinary;
+
+ /*
+ * Contents of the nanoapp binary header.
+ *
+ * Only valid if mHasValidHeader is true.
+ * See nano_app_binary_t in context_hub.h for details.
+ */
+ private int mHeaderVersion;
+ private int mMagic;
+ private long mNanoAppId;
+ private int mNanoAppVersion;
+ private int mFlags;
+ private long mHwHubType;
+ private byte mTargetChreApiMajorVersion;
+ private byte mTargetChreApiMinorVersion;
+
+ private boolean mHasValidHeader = false;
+
+ /*
+ * The header version used to parse the binary in parseBinaryHeader().
+ */
+ private static final int EXPECTED_HEADER_VERSION = 1;
+
+ /*
+ * The magic value expected in the header.
+ */
+ private static final int EXPECTED_MAGIC_VALUE =
+ (((int) 'N' << 0) | ((int) 'A' << 8) | ((int) 'N' << 16) | ((int) 'O' << 24));
+
+ /*
+ * Byte order established in context_hub.h
+ */
+ private static final ByteOrder HEADER_ORDER = ByteOrder.LITTLE_ENDIAN;
+
+ public NanoAppBinary(byte[] appBinary) {
+ mNanoAppBinary = appBinary;
+ parseBinaryHeader();
+ }
+
+ /*
+ * Parses the binary header and populates its field using mNanoAppBinary.
+ */
+ private void parseBinaryHeader() {
+ ByteBuffer buf = ByteBuffer.wrap(mNanoAppBinary).order(HEADER_ORDER);
+
+ mHasValidHeader = false;
+ try {
+ mHeaderVersion = buf.getInt();
+ if (mHeaderVersion != EXPECTED_HEADER_VERSION) {
+ Log.e(TAG, "Unexpected header version " + mHeaderVersion + " while parsing header"
+ + " (expected " + EXPECTED_HEADER_VERSION + ")");
+ return;
+ }
+
+ mMagic = buf.getInt();
+ mNanoAppId = buf.getLong();
+ mNanoAppVersion = buf.getInt();
+ mFlags = buf.getInt();
+ mHwHubType = buf.getLong();
+ mTargetChreApiMajorVersion = buf.get();
+ mTargetChreApiMinorVersion = buf.get();
+ } catch (BufferUnderflowException e) {
+ Log.e(TAG, "Not enough contents in nanoapp header");
+ return;
+ }
+
+ if (mMagic != EXPECTED_MAGIC_VALUE) {
+ Log.e(TAG, "Unexpected magic value " + String.format("0x%08X", mMagic)
+ + "while parsing header (expected "
+ + String.format("0x%08X", EXPECTED_MAGIC_VALUE) + ")");
+ } else {
+ mHasValidHeader = true;
+ }
+ }
+
+ /**
+ * @return the app binary byte array
+ */
+ public byte[] getNanoAppBinary() {
+ return mNanoAppBinary;
+ }
+
+ /**
+ * @return {@code true} if the header is valid, {@code false} otherwise
+ */
+ public boolean hasValidHeader() {
+ return mHasValidHeader;
+ }
+
+ /**
+ * @return the header version
+ */
+ public int getHeaderVersion() {
+ return mHeaderVersion;
+ }
+
+ /**
+ * @return the app ID parsed from the nanoapp header
+ */
+ public long getNanoAppId() {
+ return mNanoAppId;
+ }
+
+ /**
+ * @return the app version parsed from the nanoapp header
+ */
+ public int getNanoAppVersion() {
+ return mNanoAppVersion;
+ }
+
+ /**
+ * @return the compile target hub type parsed from the nanoapp header
+ */
+ public long getHwHubType() {
+ return mHwHubType;
+ }
+
+ /**
+ * @return the target CHRE API major version parsed from the nanoapp header
+ */
+ public byte getTargetChreApiMajorVersion() {
+ return mTargetChreApiMajorVersion;
+ }
+
+ /**
+ * @return the target CHRE API minor version parsed from the nanoapp header
+ */
+ public byte getTargetChreApiMinorVersion() {
+ return mTargetChreApiMinorVersion;
+ }
+
+ private NanoAppBinary(Parcel in) {
+ int binaryLength = in.readInt();
+ mNanoAppBinary = new byte[binaryLength];
+ in.readByteArray(mNanoAppBinary);
+
+ parseBinaryHeader();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mNanoAppBinary.length);
+ out.writeByteArray(mNanoAppBinary);
+ }
+
+ public static final Creator<NanoAppBinary> CREATOR =
+ new Creator<NanoAppBinary>() {
+ @Override
+ public NanoAppBinary createFromParcel(Parcel in) {
+ return new NanoAppBinary(in);
+ }
+
+ @Override
+ public NanoAppBinary[] newArray(int size) {
+ return new NanoAppBinary[size];
+ }
+ };
+}
diff --git a/core/java/android/hardware/location/NanoAppMessage.aidl b/core/java/android/hardware/location/NanoAppMessage.aidl
new file mode 100644
index 000000000000..f1f4ff69b7af
--- /dev/null
+++ b/core/java/android/hardware/location/NanoAppMessage.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2017 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 android.hardware.location;
+
+/**
+ * @hide
+ */
+parcelable NanoAppMessage;
diff --git a/core/java/android/hardware/location/NanoAppMessage.java b/core/java/android/hardware/location/NanoAppMessage.java
new file mode 100644
index 000000000000..202867490fb9
--- /dev/null
+++ b/core/java/android/hardware/location/NanoAppMessage.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2017 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 android.hardware.location;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class describing messages send to or from nanoapps through the Context Hub Service.
+ *
+ * The basis of the class is in the IContextHub.hal ContextHubMsg definition.
+ *
+ * @hide
+ */
+public final class NanoAppMessage implements Parcelable {
+ private long mNanoAppId;
+ private int mMessageType;
+ private byte[] mMessageBody;
+ private boolean mIsBroadcasted;
+
+ private NanoAppMessage(
+ long nanoAppId, int messageType, byte[] messageBody, boolean broadcasted) {
+ mNanoAppId = nanoAppId;
+ mMessageType = messageType;
+ mMessageBody = messageBody;
+ mIsBroadcasted = broadcasted;
+ }
+
+ /**
+ * Creates a NanoAppMessage object to send to a nanoapp.
+ *
+ * This factory method can be used to generate a NanoAppMessage object to be used in
+ * the ContextHubClient.sendMessageToNanoApp API.
+ *
+ * @param targetNanoAppId the ID of the nanoapp to send the message to
+ * @param messageType the nanoapp-dependent message type
+ * @param messageBody the byte array message contents
+ *
+ * @return the NanoAppMessage object
+ */
+ public static NanoAppMessage createMessageToNanoApp(
+ long targetNanoAppId, int messageType, byte[] messageBody) {
+ return new NanoAppMessage(
+ targetNanoAppId, messageType, messageBody, false /* broadcasted */);
+ }
+
+ /**
+ * Creates a NanoAppMessage object sent from a nanoapp.
+ *
+ * This factory method is intended only to be used by the Context Hub Service when delivering
+ * messages from a nanoapp to clients.
+ *
+ * @param sourceNanoAppId the ID of the nanoapp that the message was sent from
+ * @param messageType the nanoapp-dependent message type
+ * @param messageBody the byte array message contents
+ * @param broadcasted {@code true} if the message was broadcasted, {@code false} otherwise
+ *
+ * @return the NanoAppMessage object
+ */
+ public static NanoAppMessage createMessageFromNanoApp(
+ long sourceNanoAppId, int messageType, byte[] messageBody, boolean broadcasted) {
+ return new NanoAppMessage(sourceNanoAppId, messageType, messageBody, broadcasted);
+ }
+
+ /**
+ * @return the ID of the source or destination nanoapp
+ */
+ public long getNanoAppId() {
+ return mNanoAppId;
+ }
+
+ /**
+ * @return the type of the message that is nanoapp-dependent
+ */
+ public int getMessageType() {
+ return mMessageType;
+ }
+
+ /**
+ * @return the byte array contents of the message
+ */
+ public byte[] getMessageBody() {
+ return mMessageBody;
+ }
+
+ /**
+ * @return {@code true} if the message is broadcasted, {@code false} otherwise
+ */
+ public boolean isBroadcastMessage() {
+ return mIsBroadcasted;
+ }
+
+ private NanoAppMessage(Parcel in) {
+ mNanoAppId = in.readLong();
+ mIsBroadcasted = (in.readInt() == 1);
+ mMessageType = in.readInt();
+
+ int msgSize = in.readInt();
+ mMessageBody = new byte[msgSize];
+ in.readByteArray(mMessageBody);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeLong(mNanoAppId);
+ out.writeInt(mIsBroadcasted ? 1 : 0);
+ out.writeInt(mMessageType);
+
+ out.writeInt(mMessageBody.length);
+ out.writeByteArray(mMessageBody);
+ }
+
+ public static final Creator<NanoAppMessage> CREATOR =
+ new Creator<NanoAppMessage>() {
+ @Override
+ public NanoAppMessage createFromParcel(Parcel in) {
+ return new NanoAppMessage(in);
+ }
+
+ @Override
+ public NanoAppMessage[] newArray(int size) {
+ return new NanoAppMessage[size];
+ }
+ };
+}
diff --git a/core/java/android/hardware/location/NanoAppState.aidl b/core/java/android/hardware/location/NanoAppState.aidl
new file mode 100644
index 000000000000..f80f4356ba55
--- /dev/null
+++ b/core/java/android/hardware/location/NanoAppState.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2017 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 android.hardware.location;
+
+/**
+ * @hide
+ */
+parcelable NanoAppState;
diff --git a/core/java/android/hardware/location/NanoAppState.java b/core/java/android/hardware/location/NanoAppState.java
new file mode 100644
index 000000000000..644031b034d5
--- /dev/null
+++ b/core/java/android/hardware/location/NanoAppState.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2017 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 android.hardware.location;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class describing the nanoapp state information resulting from a query to a Context Hub.
+ *
+ * @hide
+ */
+public final class NanoAppState implements Parcelable {
+ private long mNanoAppId;
+ private int mNanoAppVersion;
+ private boolean mIsEnabled;
+
+ public NanoAppState(long nanoAppId, int appVersion, boolean enabled) {
+ mNanoAppId = nanoAppId;
+ mNanoAppVersion = appVersion;
+ mIsEnabled = enabled;
+ }
+
+ /**
+ * @return the NanoAppInfo for this app
+ */
+ public long getNanoAppId() {
+ return mNanoAppId;
+ }
+
+ /**
+ * @return the app version
+ */
+ public long getNanoAppVersion() {
+ return mNanoAppVersion;
+ }
+
+ /**
+ * @return {@code true} if the app is enabled at the Context Hub, {@code false} otherwise
+ */
+ public boolean isEnabled() {
+ return mIsEnabled;
+ }
+
+ private NanoAppState(Parcel in) {
+ mNanoAppId = in.readLong();
+ mNanoAppVersion = in.readInt();
+ mIsEnabled = (in.readInt() == 1);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeLong(mNanoAppId);
+ out.writeInt(mNanoAppVersion);
+ out.writeInt(mIsEnabled ? 1 : 0);
+ }
+
+ public static final Creator<NanoAppState> CREATOR =
+ new Creator<NanoAppState>() {
+ @Override
+ public NanoAppState createFromParcel(Parcel in) {
+ return new NanoAppState(in);
+ }
+
+ @Override
+ public NanoAppState[] newArray(int size) {
+ return new NanoAppState[size];
+ }
+ };
+}