Correctly handle HAL death

In the presence of multiple sessions, we would modify the
mActiveSessions list while iterating it, causing a runtime exception.
This has not been observed before, since we never had more than one
session.

In addition, unified the exception used to convey a dead module.

Test: Killed STHAL process and observed recovery.
Bug: 163865561
Change-Id: Ib5c5f81463d51e0f1bacae3a689fd9c8515cecc9
This commit is contained in:
Ytai Ben-Tsvi
2020-08-13 16:25:45 -07:00
parent 82bc48af03
commit 2c344c0fec
2 changed files with 7 additions and 5 deletions

View File

@@ -21,6 +21,7 @@ import android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback;
import android.hardware.soundtrigger.V2_3.ModelParameterRange;
import android.hardware.soundtrigger.V2_3.Properties;
import android.hardware.soundtrigger.V2_3.RecognitionConfig;
import android.media.soundtrigger_middleware.Status;
import android.os.DeadObjectException;
import android.os.IHwBinder;
import android.os.RemoteException;
@@ -195,10 +196,10 @@ public class SoundTriggerHw2Enforcer implements ISoundTriggerHw2 {
if (e.getCause() instanceof DeadObjectException) {
// Server is dead, no need to reboot.
Log.e(TAG, "HAL died");
} else {
Log.e(TAG, "Exception caught from HAL, rebooting HAL");
rebootHal();
throw new RecoverableException(Status.DEAD_OBJECT);
}
Log.e(TAG, "Exception caught from HAL, rebooting HAL");
rebootHal();
throw e;
}

View File

@@ -184,11 +184,13 @@ class SoundTriggerModule implements IHwBinder.DeathRecipient {
@Override
public void serviceDied(long cookie) {
Log.w(TAG, String.format("Underlying HAL driver died."));
List<ISoundTriggerCallback> callbacks = new ArrayList<>(mActiveSessions.size());
List<ISoundTriggerCallback> callbacks;
synchronized (this) {
callbacks = new ArrayList<>(mActiveSessions.size());
for (Session session : mActiveSessions) {
callbacks.add(session.moduleDied());
}
mActiveSessions.clear();
reset();
}
// Trigger the callbacks outside of the lock to avoid deadlocks.
@@ -431,7 +433,6 @@ class SoundTriggerModule implements IHwBinder.DeathRecipient {
*/
private ISoundTriggerCallback moduleDied() {
ISoundTriggerCallback callback = mCallback;
removeSession(this);
mCallback = null;
return callback;
}