Implements enableNanoApp

Bug: 67734082
Test: Run a test app to issue an enable request, verify HAL code is
executed via logs and client receives an error response.
Change-Id: Ie4ec660a094082887eaefbdfc2e1fd8d1ee7c0e3
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 1d66dc6d..8a0d2e6 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -271,7 +271,7 @@
         throw new UnsupportedOperationException("TODO: Implement this");
     }
 
-    /*
+    /**
      * Helper function to generate a stub for a non-query transaction callback.
      *
      * @param transaction the transaction to unblock when complete
@@ -297,7 +297,7 @@
         };
     }
 
-   /*
+   /**
     * Helper function to generate a stub for a query transaction callback.
     *
     * @param transaction the transaction to unblock when complete
@@ -392,7 +392,17 @@
      */
     @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
     public ContextHubTransaction<Void> enableNanoApp(ContextHubInfo hubInfo, long nanoAppId) {
-        throw new UnsupportedOperationException("TODO: Implement this");
+        ContextHubTransaction<Void> transaction =
+                new ContextHubTransaction<>(ContextHubTransaction.TYPE_ENABLE_NANOAPP);
+        IContextHubTransactionCallback callback = createTransactionCallback(transaction);
+
+        try {
+            mService.enableNanoApp(hubInfo.getId(), callback, nanoAppId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
+        return transaction;
     }
 
     /**
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
index 628ebc7..471c639 100644
--- a/core/java/android/hardware/location/IContextHubService.aidl
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -70,6 +70,11 @@
             int contextHubId, in IContextHubTransactionCallback transactionCallback,
             long nanoAppId);
 
+    // Enables a nanoapp at the specified hub
+    void enableNanoApp(
+            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 90c912a..694dd26 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -642,11 +642,10 @@
     /**
      * Loads a nanoapp binary at the specified Context hub.
      *
-     * @param contextHubId the ID of the hub to load the binary
+     * @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
+     * @param nanoAppBinary       the binary to load
      *
-     * @throws RemoteException
      * @throws IllegalStateException if the transaction queue is full
      */
     @Override
@@ -673,11 +672,10 @@
     /**
      * Unloads a nanoapp from the specified Context Hub.
      *
-     * @param contextHubId the ID of the hub to unload the nanoapp
+     * @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
+     * @param nanoAppId           the ID of the nanoapp to unload
      *
-     * @throws RemoteException
      * @throws IllegalStateException if the transaction queue is full
      */
     @Override
@@ -696,12 +694,35 @@
     }
 
     /**
+     * Enables a nanoapp at the specified Context Hub.
+     *
+     * @param contextHubId        the ID of the hub to enable the nanoapp
+     * @param transactionCallback the client-facing transaction callback interface
+     * @param nanoAppId           the ID of the nanoapp to enable
+     *
+     * @throws IllegalStateException if the transaction queue is full
+     */
+    @Override
+    public void enableNanoApp(
+            int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
+            throws RemoteException {
+        checkPermissions();
+        if (!checkHalProxyAndContextHubId(
+                contextHubId, transactionCallback, ContextHubTransaction.TYPE_ENABLE_NANOAPP)) {
+            return;
+        }
+
+        ContextHubServiceTransaction transaction = mTransactionManager.createEnableTransaction(
+                contextHubId, nanoAppId, transactionCallback);
+        mTransactionManager.addTransaction(transaction);
+    }
+
+    /**
      * Queries for a list of nanoapps from the specified Context hub.
      *
-     * @param contextHubId the ID of the hub to query
+     * @param contextHubId        the ID of the hub to query
      * @param transactionCallback the client-facing transaction callback interface
      *
-     * @throws RemoteException
      * @throws IllegalStateException if the transaction queue is full
      */
     @Override
@@ -713,8 +734,8 @@
             return;
         }
 
-        ContextHubServiceTransaction transaction =
-                mTransactionManager.createQueryTransaction(contextHubId, transactionCallback);
+        ContextHubServiceTransaction transaction = mTransactionManager.createQueryTransaction(
+                contextHubId, transactionCallback);
         mTransactionManager.addTransaction(transaction);
     }
 
diff --git a/services/core/java/com/android/server/location/ContextHubTransactionManager.java b/services/core/java/com/android/server/location/ContextHubTransactionManager.java
index 00252bc..30468bf 100644
--- a/services/core/java/com/android/server/location/ContextHubTransactionManager.java
+++ b/services/core/java/com/android/server/location/ContextHubTransactionManager.java
@@ -143,7 +143,7 @@
     /**
      * Creates a transaction for unloading a nanoapp.
      *
-     * @param contextHubId       the ID of the hub to load the nanoapp to
+     * @param contextHubId       the ID of the hub to unload the nanoapp from
      * @param nanoAppId          the ID of the nanoapp to unload
      * @param onCompleteCallback the client on complete callback
      * @return the generated transaction
@@ -182,6 +182,41 @@
     }
 
     /**
+     * Creates a transaction for enabling a nanoapp.
+     *
+     * @param contextHubId       the ID of the hub to enable the nanoapp on
+     * @param nanoAppId          the ID of the nanoapp to enable
+     * @param onCompleteCallback the client on complete callback
+     * @return the generated transaction
+     */
+    /* package */ ContextHubServiceTransaction createEnableTransaction(
+            int contextHubId, long nanoAppId, IContextHubTransactionCallback onCompleteCallback) {
+        return new ContextHubServiceTransaction(
+                mNextAvailableId.getAndIncrement(), ContextHubTransaction.TYPE_ENABLE_NANOAPP) {
+            @Override
+            /* package */ int onTransact() {
+                try {
+                    return mContextHubProxy.enableNanoApp(
+                            contextHubId, nanoAppId, this.getTransactionId());
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException while trying to enable nanoapp with ID 0x" +
+                            Long.toHexString(nanoAppId), e);
+                    return Result.UNKNOWN_FAILURE;
+                }
+            }
+
+            @Override
+            /* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
+                try {
+                    onCompleteCallback.onTransactionComplete(result);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException while calling client onTransactionComplete", e);
+                }
+            }
+        };
+    }
+
+    /**
      * Creates a transaction for querying for a list of nanoapps.
      *
      * @param contextHubId       the ID of the hub to query