diff options
5 files changed, 200 insertions, 33 deletions
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java index b31c7bcdb31e..1d66dc6d939f 100644 --- a/core/java/android/hardware/location/ContextHubManager.java +++ b/core/java/android/hardware/location/ContextHubManager.java @@ -342,7 +342,17 @@ public final class ContextHubManager { @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public ContextHubTransaction<Void> loadNanoApp( ContextHubInfo hubInfo, NanoAppBinary appBinary) { - throw new UnsupportedOperationException("TODO: Implement this"); + ContextHubTransaction<Void> transaction = + new ContextHubTransaction<>(ContextHubTransaction.TYPE_LOAD_NANOAPP); + IContextHubTransactionCallback callback = createTransactionCallback(transaction); + + try { + mService.loadNanoAppOnHub(hubInfo.getId(), callback, appBinary); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + + return transaction; } /** @@ -357,7 +367,17 @@ public final class ContextHubManager { */ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public ContextHubTransaction<Void> unloadNanoApp(ContextHubInfo hubInfo, long nanoAppId) { - throw new UnsupportedOperationException("TODO: Implement this"); + ContextHubTransaction<Void> transaction = + new ContextHubTransaction<>(ContextHubTransaction.TYPE_UNLOAD_NANOAPP); + IContextHubTransactionCallback callback = createTransactionCallback(transaction); + + try { + mService.unloadNanoAppFromHub(hubInfo.getId(), callback, nanoAppId); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + + return transaction; } /** @@ -401,7 +421,17 @@ public final class ContextHubManager { */ @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public ContextHubTransaction<List<NanoAppState>> queryNanoApps(ContextHubInfo hubInfo) { - throw new UnsupportedOperationException("TODO: Implement this"); + ContextHubTransaction<List<NanoAppState>> transaction = + new ContextHubTransaction<>(ContextHubTransaction.TYPE_QUERY_NANOAPPS); + IContextHubTransactionCallback callback = createQueryCallback(transaction); + + try { + mService.queryNanoApps(hubInfo.getId(), callback); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + + return transaction; } /** diff --git a/core/java/android/hardware/location/ContextHubTransaction.java b/core/java/android/hardware/location/ContextHubTransaction.java index a8569ef479a1..b808de3a11d6 100644 --- a/core/java/android/hardware/location/ContextHubTransaction.java +++ b/core/java/android/hardware/location/ContextHubTransaction.java @@ -72,7 +72,8 @@ public class ContextHubTransaction<T> { TRANSACTION_FAILED_PENDING, TRANSACTION_FAILED_AT_HUB, TRANSACTION_FAILED_TIMEOUT, - TRANSACTION_FAILED_SERVICE_INTERNAL_FAILURE}) + TRANSACTION_FAILED_SERVICE_INTERNAL_FAILURE, + TRANSACTION_FAILED_HAL_UNAVAILABLE}) public @interface Result {} public static final int TRANSACTION_SUCCESS = 0; /** @@ -103,6 +104,10 @@ public class ContextHubTransaction<T> { * Failure mode when the transaction has failed internally at the service. */ public static final int TRANSACTION_FAILED_SERVICE_INTERNAL_FAILURE = 7; + /** + * Failure mode when the Context Hub HAL was not available. + */ + public static final int TRANSACTION_FAILED_HAL_UNAVAILABLE = 8; /** * A class describing the response for a ContextHubTransaction. @@ -189,6 +194,30 @@ public class ContextHubTransaction<T> { } /** + * Converts a transaction type to a human-readable string + * + * @param type the type of a transaction + * @param upperCase {@code true} if upper case the first letter, {@code false} otherwise + * @return a string describing the transaction + */ + public static String typeToString(@Type int type, boolean upperCase) { + switch (type) { + case ContextHubTransaction.TYPE_LOAD_NANOAPP: + return upperCase ? "Load" : "load"; + case ContextHubTransaction.TYPE_UNLOAD_NANOAPP: + return upperCase ? "Unload" : "unload"; + case ContextHubTransaction.TYPE_ENABLE_NANOAPP: + return upperCase ? "Enable" : "enable"; + case ContextHubTransaction.TYPE_DISABLE_NANOAPP: + return upperCase ? "Disable" : "disable"; + case ContextHubTransaction.TYPE_QUERY_NANOAPPS: + return upperCase ? "Query" : "query"; + default: + return upperCase ? "Unknown" : "unknown"; + } + } + + /** * @return the type of the transaction */ @Type @@ -239,7 +268,7 @@ public class ContextHubTransaction<T> { * A transaction can be invalidated if the process owning the transaction is no longer active * and the reference to this object is lost. * - * This method or {@link #setCallbackOnCompletecan(ContextHubTransaction.Callback)} can only be + * This method or {@link #setCallbackOnComplete(ContextHubTransaction.Callback)} can only be * invoked once, or an IllegalStateException will be thrown. * * @param callback the callback to be invoked upon completion diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl index 1bb7c8fbb6e7..628ebc7d4579 100644 --- a/core/java/android/hardware/location/IContextHubService.aidl +++ b/core/java/android/hardware/location/IContextHubService.aidl @@ -20,41 +20,56 @@ package android.hardware.location; import android.hardware.location.ContextHubInfo; import android.hardware.location.ContextHubMessage; import android.hardware.location.NanoApp; +import android.hardware.location.NanoAppBinary; import android.hardware.location.NanoAppFilter; import android.hardware.location.NanoAppInstanceInfo; import android.hardware.location.IContextHubCallback; import android.hardware.location.IContextHubClient; import android.hardware.location.IContextHubClientCallback; +import android.hardware.location.IContextHubTransactionCallback; /** * @hide */ interface IContextHubService { - // register a callback to receive messages + // Registers a callback to receive messages int registerCallback(in IContextHubCallback callback); // Gets a list of available context hub handles int[] getContextHubHandles(); - // Get the properties of a hub + // Gets the properties of a hub ContextHubInfo getContextHubInfo(int contextHubHandle); - // Load a nanoapp on a specified context hub + // Loads a nanoapp at the specified hub (old API) int loadNanoApp(int hubHandle, in NanoApp app); - // Unload a nanoapp instance + // Unloads a nanoapp given its instance ID (old API) int unloadNanoApp(int nanoAppInstanceHandle); - // get information about a nanoAppInstance + // Gets the NanoAppInstanceInfo of a nanoapp give its instance ID NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle); - // find all nanoApp instances matching some filter + // Finds all nanoApp instances matching some filter int[] findNanoAppOnHub(int hubHandle, in NanoAppFilter filter); - // send a message to a nanoApp + // Sends a message to a nanoApp int sendMessage(int hubHandle, int nanoAppHandle, in ContextHubMessage msg); // Creates a client to send and receive messages IContextHubClient createClient(in IContextHubClientCallback client, int contextHubId); + + // Loads a nanoapp at the specified hub (new API) + void loadNanoAppOnHub( + int contextHubId, in IContextHubTransactionCallback transactionCallback, + in NanoAppBinary nanoAppBinary); + + // Unloads a nanoapp on a specified context hub (new API) + void unloadNanoAppFromHub( + int contextHubId, in IContextHubTransactionCallback transactionCallback, + long nanoAppId); + + // Queries for a list of nanoapps + void queryNanoApps(int contextHubId, in IContextHubTransactionCallback transactionCallback); } diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java index 4525a4982d44..cd4bb14ee91f 100644 --- a/services/core/java/com/android/server/location/ContextHubService.java +++ b/services/core/java/com/android/server/location/ContextHubService.java @@ -742,6 +742,82 @@ public class ContextHubService extends IContextHubService.Stub { return mClientManager.registerClient(clientCallback, contextHubId); } + /** + * Loads a nanoapp binary at the specified Context hub. + * + * @param contextHubId the ID of the hub to load the binary + * @param transactionCallback the client-facing transaction callback interface + * @param nanoAppBinary the binary to load + * + * @throws RemoteException + */ + @Override + public void loadNanoAppOnHub( + int contextHubId, IContextHubTransactionCallback transactionCallback, + NanoAppBinary nanoAppBinary) throws RemoteException { + checkPermissions(); + if (!checkHalProxyAndContextHubId( + contextHubId, transactionCallback, ContextHubTransaction.TYPE_LOAD_NANOAPP)) { + return; + } + if (nanoAppBinary == null) { + Log.e(TAG, "NanoAppBinary cannot be null in loadNanoAppOnHub"); + transactionCallback.onTransactionComplete( + ContextHubTransaction.TRANSACTION_FAILED_BAD_PARAMS); + return; + } + + ContextHubServiceTransaction transaction = mTransactionManager.createLoadTransaction( + contextHubId, nanoAppBinary, transactionCallback); + addTransaction(transaction); + } + + /** + * Unloads a nanoapp from the specified Context Hub. + * + * @param contextHubId the ID of the hub to unload the nanoapp + * @param transactionCallback the client-facing transaction callback interface + * @param nanoAppId the ID of the nanoapp to unload + * + * @throws RemoteException + */ + @Override + public void unloadNanoAppFromHub( + int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId) + throws RemoteException { + checkPermissions(); + if (!checkHalProxyAndContextHubId( + contextHubId, transactionCallback, ContextHubTransaction.TYPE_UNLOAD_NANOAPP)) { + return; + } + + ContextHubServiceTransaction transaction = mTransactionManager.createUnloadTransaction( + contextHubId, nanoAppId, transactionCallback); + addTransaction(transaction); + } + + /** + * Queries for a list of nanoapps from the specified Context hub. + * + * @param contextHubId the ID of the hub to query + * @param transactionCallback the client-facing transaction callback interface + * + * @throws RemoteException + */ + @Override + public void queryNanoApps(int contextHubId, IContextHubTransactionCallback transactionCallback) + throws RemoteException { + checkPermissions(); + if (!checkHalProxyAndContextHubId( + contextHubId, transactionCallback, ContextHubTransaction.TYPE_QUERY_NANOAPPS)) { + return; + } + + ContextHubServiceTransaction transaction = + mTransactionManager.createQueryTransaction(contextHubId, transactionCallback); + addTransaction(transaction); + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; @@ -797,6 +873,42 @@ public class ContextHubService extends IContextHubService.Stub { return 0; } + /** + * Validates the HAL proxy state and context hub ID to see if we can start the transaction. + * + * @param contextHubId the ID of the hub to start the transaction + * @param callback the client transaction callback interface + * @param transactionType the type of the transaction + * + * @return {@code true} if mContextHubProxy and contextHubId is valid, {@code false} otherwise + */ + private boolean checkHalProxyAndContextHubId( + int contextHubId, IContextHubTransactionCallback callback, + @ContextHubTransaction.Type int transactionType) { + if (mContextHubProxy == null) { + try { + callback.onTransactionComplete( + ContextHubTransaction.TRANSACTION_FAILED_HAL_UNAVAILABLE); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException while calling onTransactionComplete", e); + } + return false; + } + if (!isValidContextHubId(contextHubId)) { + Log.e(TAG, "Cannot start " + + ContextHubTransaction.typeToString(transactionType, false /* upperCase */) + + " transaction for invalid hub ID " + contextHubId); + try { + callback.onTransactionComplete(ContextHubTransaction.TRANSACTION_FAILED_BAD_PARAMS); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException while calling onTransactionComplete", e); + } + return false; + } + + return true; + } + private int addAppInstance(int hubHandle, int appInstanceHandle, long appId, int appVersion) { // App Id encodes vendor & version NanoAppInstanceInfo appInfo = new NanoAppInstanceInfo(); diff --git a/services/core/java/com/android/server/location/ContextHubServiceTransaction.java b/services/core/java/com/android/server/location/ContextHubServiceTransaction.java index a543dafc1ed1..ce92f722e2d2 100644 --- a/services/core/java/com/android/server/location/ContextHubServiceTransaction.java +++ b/services/core/java/com/android/server/location/ContextHubServiceTransaction.java @@ -126,28 +126,9 @@ import java.util.concurrent.TimeUnit; return mIsComplete; } - /** - * @return the human-readable string of this transaction's type - */ - private String getTransactionTypeString() { - switch (mTransactionType) { - case ContextHubTransaction.TYPE_LOAD_NANOAPP: - return "Load"; - case ContextHubTransaction.TYPE_UNLOAD_NANOAPP: - return "Unload"; - case ContextHubTransaction.TYPE_ENABLE_NANOAPP: - return "Enable"; - case ContextHubTransaction.TYPE_DISABLE_NANOAPP: - return "Disable"; - case ContextHubTransaction.TYPE_QUERY_NANOAPPS: - return "Query"; - default: - return "Unknown"; - } - } - @Override public String toString() { - return getTransactionTypeString() + " transaction (ID = " + mTransactionId + ")"; + return ContextHubTransaction.typeToString(mTransactionType, true /* upperCase */) + + " transaction (ID = " + mTransactionId + ")"; } } |