Ensure ST attach propagates exceptions

Currently, SoundTrigger#attach suppresses exceptions while attaching,
and can leave the STService session in an invalid state.

Call the STModule ctor directly so the exception is propagated.

Bug: 272147641
Fixes: 279178427
Test: SoundTriggerManagerTest
Change-Id: Ic609eadf4c60d27ce3e40d7fd88b456e3afa1508
This commit is contained in:
Atneya Nair
2023-04-21 09:53:40 -07:00
parent c2ce3fc785
commit 8b38e97193
3 changed files with 39 additions and 24 deletions

View File

@@ -61,36 +61,42 @@ public class SoundTriggerModule {
* 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

View File

@@ -1043,7 +1043,13 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
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;
}
}
}
}

View File

@@ -57,6 +57,7 @@ import android.hardware.soundtrigger.SoundTrigger.ModelParamRange;
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 @@ public class SoundTriggerService extends SystemService {
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 @@ public class SoundTriggerService extends SystemService {
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 @@ public class SoundTriggerService extends SystemService {
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)
);