Merge "Ensure ST attach propagates exceptions" into udc-dev
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
index a1d74df..37c5213 100644
--- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
@@ -61,36 +61,42 @@
      * This variant is intended for use when the caller is acting an originator, rather than on
      * behalf of a different entity, as far as authorization goes.
      */
-    SoundTriggerModule(@NonNull ISoundTriggerMiddlewareService service,
+    public SoundTriggerModule(@NonNull ISoundTriggerMiddlewareService service,
             int moduleId, @NonNull SoundTrigger.StatusListener listener, @NonNull Looper looper,
-            @NonNull Identity originatorIdentity)
-            throws RemoteException {
+            @NonNull Identity originatorIdentity) {
         mId = moduleId;
         mEventHandlerDelegate = new EventHandlerDelegate(listener, looper);
-
-        try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
-            mService = service.attachAsOriginator(moduleId, originatorIdentity,
-                    mEventHandlerDelegate);
+        try {
+            try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+                mService = service.attachAsOriginator(moduleId, originatorIdentity,
+                        mEventHandlerDelegate);
+            }
+            mService.asBinder().linkToDeath(mEventHandlerDelegate, 0);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
-        mService.asBinder().linkToDeath(mEventHandlerDelegate, 0);
     }
 
     /**
      * This variant is intended for use when the caller is acting as a middleman, i.e. on behalf of
      * a different entity, as far as authorization goes.
      */
-    SoundTriggerModule(@NonNull ISoundTriggerMiddlewareService service,
+    public SoundTriggerModule(@NonNull ISoundTriggerMiddlewareService service,
             int moduleId, @NonNull SoundTrigger.StatusListener listener, @NonNull Looper looper,
-            @NonNull Identity middlemanIdentity, @NonNull Identity originatorIdentity)
-            throws RemoteException {
+            @NonNull Identity middlemanIdentity, @NonNull Identity originatorIdentity) {
         mId = moduleId;
         mEventHandlerDelegate = new EventHandlerDelegate(listener, looper);
 
-        try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
-            mService = service.attachAsMiddleman(moduleId, middlemanIdentity, originatorIdentity,
-                    mEventHandlerDelegate);
+        try {
+            try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+                mService = service.attachAsMiddleman(moduleId, middlemanIdentity,
+                        originatorIdentity,
+                        mEventHandlerDelegate);
+            }
+            mService.asBinder().linkToDeath(mEventHandlerDelegate, 0);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
-        mService.asBinder().linkToDeath(mEventHandlerDelegate, 0);
     }
 
     @Override
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index bee75df..255db1e 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -1043,7 +1043,13 @@
             internalClearGlobalStateLocked();
             if (mModule != null) {
                 mModule.detach();
-                mModule = mModuleProvider.apply(this);
+                try {
+                    // This is best effort
+                    // TODO (b/279507851)
+                    mModule = mModuleProvider.apply(this);
+                } catch (Exception e) {
+                    mModule = null;
+                }
             }
         }
     }
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 77e5317..b062e6b 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -57,6 +57,7 @@
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
 import android.hardware.soundtrigger.SoundTrigger.SoundModel;
+import android.hardware.soundtrigger.SoundTriggerModule;
 import android.media.AudioAttributes;
 import android.media.AudioFormat;
 import android.media.AudioRecord;
@@ -134,6 +135,8 @@
     private Object mLock;
     private final SoundTriggerServiceStub mServiceStub;
     private final LocalSoundTriggerService mLocalSoundTriggerService;
+
+    private ISoundTriggerMiddlewareService mMiddlewareService;
     private SoundTriggerDbHelper mDbHelper;
 
     private final EventLogger mServiceEventLogger = new EventLogger(256, "Service");
@@ -241,17 +244,18 @@
         if (PHASE_THIRD_PARTY_APPS_CAN_START == phase) {
             mDbHelper = new SoundTriggerDbHelper(mContext);
         }
+        mMiddlewareService = ISoundTriggerMiddlewareService.Stub.asInterface(
+                ServiceManager.waitForService(Context.SOUND_TRIGGER_MIDDLEWARE_SERVICE));
+
     }
 
     // Must be called with cleared binder context.
-    private static List<ModuleProperties> listUnderlyingModuleProperties(
+    private List<ModuleProperties> listUnderlyingModuleProperties(
             Identity originatorIdentity) {
         Identity middlemanIdentity = new Identity();
         middlemanIdentity.packageName = ActivityThread.currentOpPackageName();
-        var service = ISoundTriggerMiddlewareService.Stub.asInterface(
-                ServiceManager.waitForService(Context.SOUND_TRIGGER_MIDDLEWARE_SERVICE));
         try {
-            return Arrays.stream(service.listModulesAsMiddleman(middlemanIdentity,
+            return Arrays.stream(mMiddlewareService.listModulesAsMiddleman(middlemanIdentity,
                                                                 originatorIdentity))
                     .map(desc -> ConversionUtil.aidl2apiModuleDescriptor(desc))
                     .collect(Collectors.toList());
@@ -282,10 +286,9 @@
         return new SoundTriggerHelper(
                 mContext,
                 eventLogger,
-                (SoundTrigger.StatusListener statusListener) ->
-                                        SoundTrigger.attachModuleAsMiddleman(
-                                        moduleId, statusListener, null /* handler */,
-                                        middlemanIdentity, originatorIdentity),
+                (SoundTrigger.StatusListener statusListener) -> new SoundTriggerModule(
+                        mMiddlewareService, moduleId, statusListener,
+                        Looper.getMainLooper(), middlemanIdentity, originatorIdentity),
                 moduleId,
                 () -> listUnderlyingModuleProperties(originatorIdentity)
                 );