Implements onNanoAppAborted callback

Bug: 67734082
Bug: 31049861
Test: Fake a handleAppAbort callback at the HAL implementation for
walleye, run a test app that registers a client callback, and verify
client receives the onNanoAppAborted callback.
Change-Id: Ic1ab3a1ef0f903a9aad04f732dac1a04f3fc5169
diff --git a/services/core/java/com/android/server/location/ContextHubClientBroker.java b/services/core/java/com/android/server/location/ContextHubClientBroker.java
index 41d9feb..9640e04 100644
--- a/services/core/java/com/android/server/location/ContextHubClientBroker.java
+++ b/services/core/java/com/android/server/location/ContextHubClientBroker.java
@@ -179,7 +179,7 @@
     }
 
     /**
-     * Handles a nanoapp load event.
+     * Notifies the client of a nanoapp load event if the connection is open.
      *
      * @param nanoAppId the ID of the nanoapp that was loaded.
      */
@@ -195,7 +195,7 @@
     }
 
     /**
-     * Handles a nanoapp unload event.
+     * Notifies the client of a nanoapp unload event if the connection is open.
      *
      * @param nanoAppId the ID of the nanoapp that was unloaded.
      */
@@ -211,7 +211,7 @@
     }
 
     /**
-     * Handles a hub reset for this client.
+     * Notifies the client of a hub reset event if the connection is open.
      */
     /* package */ void onHubReset() {
         if (mConnectionOpen.get()) {
@@ -223,4 +223,21 @@
             }
         }
     }
+
+    /**
+     * Notifies the client of a nanoapp abort event if the connection is open.
+     *
+     * @param nanoAppId the ID of the nanoapp that aborted
+     * @param abortCode the nanoapp specific abort code
+     */
+    /* package */ void onNanoAppAborted(long nanoAppId, int abortCode) {
+        if (mConnectionOpen.get()) {
+            try {
+                mCallbackInterface.onNanoAppAborted(nanoAppId, abortCode);
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException while calling onNanoAppAborted on client"
+                        + " (host endpoint ID = " + mHostEndPointId + ")", e);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/location/ContextHubClientManager.java b/services/core/java/com/android/server/location/ContextHubClientManager.java
index d58a746..60b5b1f 100644
--- a/services/core/java/com/android/server/location/ContextHubClientManager.java
+++ b/services/core/java/com/android/server/location/ContextHubClientManager.java
@@ -149,35 +149,38 @@
     }
 
     /**
-     * Handles a nanoapp load event.
-     *
-     * @param contextHubId the ID of the hub where the nanoapp was loaded.
-     * @param nanoAppId    the ID of the nanoapp that was loaded.
+     * @param contextHubId the ID of the hub where the nanoapp was loaded
+     * @param nanoAppId    the ID of the nanoapp that was loaded
      */
     /* package */ void onNanoAppLoaded(int contextHubId, long nanoAppId) {
         forEachClientOfHub(contextHubId, client -> client.onNanoAppLoaded(nanoAppId));
     }
 
     /**
-     * Handles a nanoapp unload event.
-     *
-     * @param contextHubId the ID of the hub where the nanoapp was unloaded.
-     * @param nanoAppId    the ID of the nanoapp that was unloaded.
+     * @param contextHubId the ID of the hub where the nanoapp was unloaded
+     * @param nanoAppId    the ID of the nanoapp that was unloaded
      */
     /* package */ void onNanoAppUnloaded(int contextHubId, long nanoAppId) {
         forEachClientOfHub(contextHubId, client -> client.onNanoAppUnloaded(nanoAppId));
     }
 
     /**
-     * Handles a hub reset.
-     *
-     * @param contextHubId the ID of the hub that has reset.
+     * @param contextHubId the ID of the hub that has reset
      */
     /* package */ void onHubReset(int contextHubId) {
         forEachClientOfHub(contextHubId, client -> client.onHubReset());
     }
 
     /**
+     * @param contextHubId the ID of the hub that contained the nanoapp that aborted
+     * @param nanoAppId the ID of the nanoapp that aborted
+     * @param abortCode the nanoapp specific abort code
+     */
+    /* package */ void onNanoAppAborted(int contextHubId, long nanoAppId, int abortCode) {
+        forEachClientOfHub(contextHubId, client -> client.onNanoAppAborted(nanoAppId, abortCode));
+    }
+
+    /**
      * Creates a new ContextHubClientBroker object for a client and registers it with the client
      * manager.
      *
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index 1ad0cf9..56bc19d 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -583,7 +583,7 @@
      * @param abortCode    the nanoapp-specific abort code
      */
     private void handleAppAbortCallback(int contextHubId, long nanoAppId, int abortCode) {
-        // TODO(b/31049861): Implement this
+        mClientManager.onNanoAppAborted(contextHubId, nanoAppId, abortCode);
     }
 
     /**