Plumb trusted config through soundtrigger stack am: 31316ca79d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22690713

Change-Id: Ib1bf9a37a5a8dc72bc5d66533ede73a1d2a36623
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Atneya Nair
2023-05-05 17:00:52 +00:00
committed by Automerger Merge Worker
14 changed files with 86 additions and 54 deletions

View File

@@ -2306,7 +2306,7 @@ public class SoundTrigger {
Looper looper = handler != null ? handler.getLooper() : Looper.getMainLooper();
try {
return new SoundTriggerModule(getService(), moduleId, listener, looper,
middlemanIdentity, originatorIdentity);
middlemanIdentity, originatorIdentity, false);
} catch (Exception e) {
Log.e(TAG, "", e);
return null;

View File

@@ -83,7 +83,8 @@ public class SoundTriggerModule {
*/
public SoundTriggerModule(@NonNull ISoundTriggerMiddlewareService service,
int moduleId, @NonNull SoundTrigger.StatusListener listener, @NonNull Looper looper,
@NonNull Identity middlemanIdentity, @NonNull Identity originatorIdentity) {
@NonNull Identity middlemanIdentity, @NonNull Identity originatorIdentity,
boolean isTrusted) {
mId = moduleId;
mEventHandlerDelegate = new EventHandlerDelegate(listener, looper);
@@ -91,7 +92,8 @@ public class SoundTriggerModule {
try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
mService = service.attachAsMiddleman(moduleId, middlemanIdentity,
originatorIdentity,
mEventHandlerDelegate);
mEventHandlerDelegate,
isTrusted);
}
mService.asBinder().linkToDeath(mEventHandlerDelegate, 0);
} catch (RemoteException e) {

View File

@@ -80,14 +80,16 @@ interface ISoundTriggerMiddlewareService {
* This implies that the caller must clear its caller identity to protect from the case where
* it resides in the same process as the callee.
* - The identity of the entity on behalf of which module operations are to be performed.
*
* @param isTrusted - {@code true} if the middleware should not audit data delivery, since the
* callback is being delivered to another trusted component which will audit access.
* listModules() must be called prior to calling this method and the provided handle must be
* one of the handles from the returned list.
*/
ISoundTriggerModule attachAsMiddleman(int handle,
in Identity middlemanIdentity,
in Identity originatorIdentity,
ISoundTriggerCallback callback);
ISoundTriggerCallback callback,
boolean isTrusted);
/**
* Attach an injection interface interface to the ST mock HAL.

View File

@@ -47,7 +47,14 @@ public interface SoundTriggerInternal {
int STATUS_OK = SoundTrigger.STATUS_OK;
// Attach to a specific underlying STModule
Session attach(@NonNull IBinder client, ModuleProperties underlyingModule);
/**
* Attach to a specific underlying STModule.
* @param client - Binder token representing the app client for death notifications
* @param underlyingModule - Properties of the underlying STModule to attach to
* @param isTrusted - {@code true} if callbacks will be appropriately AppOps attributed by
* a trusted component prior to delivery to the ultimate client.
*/
Session attach(@NonNull IBinder client, ModuleProperties underlyingModule, boolean isTrusted);
// Enumerate possible STModules to attach to
List<ModuleProperties> listModuleProperties(Identity originatorIdentity);

View File

@@ -164,7 +164,7 @@ public class SoundTriggerMiddlewareImplTest {
public void testAttachDetach() throws Exception {
// Normal attachment / detachment.
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
assertNotNull(module);
module.detach();
}
@@ -172,7 +172,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testLoadUnloadModel() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
final int hwHandle = 7;
int handle = loadGenericModel(module, hwHandle).first;
@@ -183,7 +183,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testLoadPreemptModel() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
final int hwHandle = 7;
Pair<Integer, SoundTriggerHwCallback> loadResult = loadGenericModel(module, hwHandle);
@@ -202,7 +202,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testLoadUnloadPhraseModel() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
final int hwHandle = 73;
int handle = loadPhraseModel(module, hwHandle).first;
@@ -213,7 +213,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testStartStopRecognition() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 7;
@@ -233,7 +233,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testStartRecognitionBusy() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 7;
@@ -257,7 +257,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testStartStopPhraseRecognition() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 67;
@@ -277,7 +277,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testRecognition() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 7;
@@ -322,7 +322,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testPhraseRecognition() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 7;
@@ -352,7 +352,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testForceRecognition() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 17;
@@ -389,7 +389,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testForceRecognitionNotSupported() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 17;
@@ -420,7 +420,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testForcePhraseRecognition() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 17;
@@ -457,7 +457,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testForcePhraseRecognitionNotSupported() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 17;
@@ -489,7 +489,7 @@ public class SoundTriggerMiddlewareImplTest {
public void testAbortRecognition() throws Exception {
// Make sure the HAL doesn't support concurrent capture.
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 11;
@@ -521,7 +521,7 @@ public class SoundTriggerMiddlewareImplTest {
public void testAbortPhraseRecognition() throws Exception {
// Make sure the HAL doesn't support concurrent capture.
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
// Load the model.
final int hwHandle = 11;
@@ -552,7 +552,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testParameterSupported() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
final int hwHandle = 12;
int modelHandle = loadGenericModel(module, hwHandle).first;
@@ -574,7 +574,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testParameterNotSupported() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
final int hwHandle = 13;
int modelHandle = loadGenericModel(module, hwHandle).first;
@@ -592,7 +592,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testGetParameter() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
final int hwHandle = 14;
int modelHandle = loadGenericModel(module, hwHandle).first;
@@ -609,7 +609,7 @@ public class SoundTriggerMiddlewareImplTest {
@Test
public void testSetParameter() throws Exception {
ISoundTriggerCallback callback = createCallbackMock();
ISoundTriggerModule module = mService.attach(0, callback);
ISoundTriggerModule module = mService.attach(0, callback, false);
final int hwHandle = 17;
int modelHandle = loadGenericModel(module, hwHandle).first;

View File

@@ -20,6 +20,7 @@ import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERAC
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.verify;
@@ -101,8 +102,9 @@ public class SoundTriggerMiddlewareLoggingLatencyTest {
throws RemoteException {
ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
ISoundTriggerCallback.class);
mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback, false);
verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture(),
anyBoolean());
triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
RecognitionStatus.SUCCESS, 100 /* keyphraseId */);
@@ -116,8 +118,9 @@ public class SoundTriggerMiddlewareLoggingLatencyTest {
public void testOnPhraseRecognitionRestartsActiveSession() throws RemoteException {
ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
ISoundTriggerCallback.class);
mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback, false);
verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture(),
anyBoolean());
triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
RecognitionStatus.SUCCESS, 100 /* keyphraseId */);
@@ -137,8 +140,9 @@ public class SoundTriggerMiddlewareLoggingLatencyTest {
throws RemoteException {
ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
ISoundTriggerCallback.class);
mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback, false);
verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture(),
anyBoolean());
triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
RecognitionStatus.ABORTED, 100 /* keyphraseId */);
@@ -154,8 +158,9 @@ public class SoundTriggerMiddlewareLoggingLatencyTest {
throws RemoteException {
ArgumentCaptor<ISoundTriggerCallback> soundTriggerCallbackCaptor = ArgumentCaptor.forClass(
ISoundTriggerCallback.class);
mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback);
verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture());
mSoundTriggerMiddlewareLogging.attach(0, mISoundTriggerCallback, false);
verify(mDelegateMiddleware).attach(anyInt(), soundTriggerCallbackCaptor.capture(),
anyBoolean());
triggerPhraseRecognitionEvent(soundTriggerCallbackCaptor.getValue(),
RecognitionStatus.SUCCESS);

View File

@@ -303,6 +303,10 @@ public class SoundTriggerService extends SystemService {
private SoundTriggerHelper newSoundTriggerHelper(
ModuleProperties moduleProperties, EventLogger eventLogger) {
return newSoundTriggerHelper(moduleProperties, eventLogger, false);
}
private SoundTriggerHelper newSoundTriggerHelper(
ModuleProperties moduleProperties, EventLogger eventLogger, boolean isTrusted) {
Identity middlemanIdentity = new Identity();
middlemanIdentity.packageName = ActivityThread.currentOpPackageName();
@@ -325,7 +329,7 @@ public class SoundTriggerService extends SystemService {
eventLogger,
(SoundTrigger.StatusListener statusListener) -> new SoundTriggerModule(
mMiddlewareService, moduleId, statusListener,
Looper.getMainLooper(), middlemanIdentity, originatorIdentity),
Looper.getMainLooper(), middlemanIdentity, originatorIdentity, isTrusted),
moduleId,
() -> listUnderlyingModuleProperties(originatorIdentity)
);
@@ -1724,7 +1728,8 @@ public class SoundTriggerService extends SystemService {
}
@Override
public Session attach(@NonNull IBinder client, ModuleProperties underlyingModule) {
public Session attach(@NonNull IBinder client, ModuleProperties underlyingModule,
boolean isTrusted) {
var identity = IdentityContext.getNonNull();
int sessionId = mSessionIdCounter.getAndIncrement();
mServiceEventLogger.enqueue(new ServiceEvent(
@@ -1733,7 +1738,7 @@ public class SoundTriggerService extends SystemService {
"LocalSoundTriggerEventLogger for package: " +
identity.packageName + "#" + sessionId);
return new SessionImpl(newSoundTriggerHelper(underlyingModule, eventLogger),
return new SessionImpl(newSoundTriggerHelper(underlyingModule, eventLogger, isTrusted),
client, eventLogger, identity);
}

View File

@@ -38,7 +38,10 @@ public interface ISoundTriggerMiddlewareInternal {
*
* listModules() must be called prior to calling this method and the provided handle must be
* one of the handles from the returned list.
* @param isTrusted - {@code true} if this service should not note AppOps for recognitions,
* and should delegate these checks to the **trusted** client.
*/
public ISoundTriggerModule attach(int handle,
ISoundTriggerCallback callback);
ISoundTriggerCallback callback,
boolean isTrusted);
}

View File

@@ -116,7 +116,8 @@ public class SoundTriggerMiddlewareImpl implements ISoundTriggerMiddlewareIntern
@Override
public @NonNull
ISoundTriggerModule attach(int handle, @NonNull ISoundTriggerCallback callback) {
ISoundTriggerModule attach(int handle, @NonNull ISoundTriggerCallback callback,
boolean isTrusted) {
return mModules[handle].attach(callback);
}
}

View File

@@ -149,22 +149,22 @@ public class SoundTriggerMiddlewareLogging implements ISoundTriggerMiddlewareInt
@Override
public @NonNull
ISoundTriggerModule attach(int handle, ISoundTriggerCallback callback) {
ISoundTriggerModule attach(int handle, ISoundTriggerCallback callback, boolean isTrusted) {
try {
var originatorIdentity = IdentityContext.getNonNull();
String packageIdentification = originatorIdentity.packageName
+ mSessionCount.getAndIncrement();
+ mSessionCount.getAndIncrement() + (isTrusted ? "trusted" : "");
ModuleLogging result = new ModuleLogging();
var eventLogger = new EventLogger(SESSION_MAX_EVENT_SIZE,
"Session logger for: " + packageIdentification);
var callbackWrapper = new CallbackLogging(callback, eventLogger, originatorIdentity);
result.attach(mDelegate.attach(handle, callbackWrapper), eventLogger);
result.attach(mDelegate.attach(handle, callbackWrapper, isTrusted), eventLogger);
mServiceEventLogger.enqueue(ServiceEvent.createForReturn(
ServiceEvent.Type.ATTACH,
packageIdentification, result, handle, callback)
packageIdentification, result, handle, callback, isTrusted)
.printLog(ALOGI, TAG));
mSessionEventLoggers.add(eventLogger);

View File

@@ -85,11 +85,11 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware
@Override
public @NonNull
ISoundTriggerModule attach(int handle,
@NonNull ISoundTriggerCallback callback) {
@NonNull ISoundTriggerCallback callback, boolean isTrusted) {
Identity identity = getIdentity();
enforcePermissionsForPreflight(identity);
ModuleWrapper wrapper = new ModuleWrapper(identity, callback);
return wrapper.attach(mDelegate.attach(handle, wrapper.getCallbackWrapper()));
ModuleWrapper wrapper = new ModuleWrapper(identity, callback, isTrusted);
return wrapper.attach(mDelegate.attach(handle, wrapper.getCallbackWrapper(), isTrusted));
}
// Override toString() in order to have the delegate's ID in it.
@@ -204,11 +204,14 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware
private ISoundTriggerModule mDelegate;
private final @NonNull Identity mOriginatorIdentity;
private final @NonNull CallbackWrapper mCallbackWrapper;
private final boolean mIsTrusted;
ModuleWrapper(@NonNull Identity originatorIdentity,
@NonNull ISoundTriggerCallback callback) {
@NonNull ISoundTriggerCallback callback,
boolean isTrusted) {
mOriginatorIdentity = originatorIdentity;
mCallbackWrapper = new CallbackWrapper(callback);
mIsTrusted = isTrusted;
}
ModuleWrapper attach(@NonNull ISoundTriggerModule delegate) {
@@ -347,7 +350,11 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware
}
private void enforcePermissions(String reason) {
enforcePermissionsForDataDelivery(mOriginatorIdentity, reason);
if (mIsTrusted) {
enforcePermissionsForPreflight(mOriginatorIdentity);
} else {
enforcePermissionsForDataDelivery(mOriginatorIdentity, reason);
}
}
}
}

View File

@@ -105,17 +105,17 @@ public class SoundTriggerMiddlewareService extends ISoundTriggerMiddlewareServic
public ISoundTriggerModule attachAsOriginator(int handle, Identity identity,
ISoundTriggerCallback callback) {
try (SafeCloseable ignored = establishIdentityDirect(Objects.requireNonNull(identity))) {
return new ModuleService(mDelegate.attach(handle, callback));
return new ModuleService(mDelegate.attach(handle, callback, /* isTrusted= */ false));
}
}
@Override
public ISoundTriggerModule attachAsMiddleman(int handle, Identity middlemanIdentity,
Identity originatorIdentity, ISoundTriggerCallback callback) {
Identity originatorIdentity, ISoundTriggerCallback callback, boolean isTrusted) {
try (SafeCloseable ignored = establishIdentityIndirect(
Objects.requireNonNull(middlemanIdentity),
Objects.requireNonNull(originatorIdentity))) {
return new ModuleService(mDelegate.attach(handle, callback));
return new ModuleService(mDelegate.attach(handle, callback, isTrusted));
}
}

View File

@@ -191,7 +191,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware
@Override
public @NonNull ISoundTriggerModule attach(int handle,
@NonNull ISoundTriggerCallback callback) {
@NonNull ISoundTriggerCallback callback, boolean isTrusted) {
// Input validation.
Objects.requireNonNull(callback);
Objects.requireNonNull(callback.asBinder());
@@ -209,7 +209,7 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware
// From here on, every exception isn't client's fault.
try {
Session session = new Session(handle, callback);
session.attach(mDelegate.attach(handle, session.getCallbackWrapper()));
session.attach(mDelegate.attach(handle, session.getCallbackWrapper(), isTrusted));
return session;
} catch (Exception e) {
throw handleException(e);

View File

@@ -408,7 +408,7 @@ public class VoiceInteractionManagerService extends SystemService {
try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
originatorIdentity)) {
session = new SoundTriggerSession(mSoundTriggerInternal.attach(client,
moduleProperties));
moduleProperties, false));
}
}
return new SoundTriggerSessionBinderProxy(session);
@@ -423,7 +423,7 @@ public class VoiceInteractionManagerService extends SystemService {
return Binder.withCleanCallingIdentity(() -> {
try (SafeCloseable ignored = IdentityContext.create(identity)) {
return new SoundTriggerSession(
mSoundTriggerInternal.attach(client, moduleProperties));
mSoundTriggerInternal.attach(client, moduleProperties, false));
}
});
}