summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ytai Ben-Tsvi <ytai@google.com> 2021-03-31 13:48:19 -0700
committer Ytai Ben-Tsvi <ytai@google.com> 2021-03-31 14:24:54 -0700
commitdef517ec0490530bc6a56b34318c5ee1a6f33e9e (patch)
tree39279960b78b6ed5825665bf2467421ef582f21b
parent2e6c469012aea6e414dcf446bb477de16d732a96 (diff)
Improve permission enforcement in SoundTriggerService
Use a session-based identity mechanism similar to SoundTriggerMiddleware. Clear identity context within service to allow internal calls to originate from this service. Fixes: 184021066 Test: Manual verification of OKG / Now Playing on Sargo Change-Id: Iccda9ef864f82eafbf3473e706bcffe695705953
-rw-r--r--services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java773
1 files changed, 404 insertions, 369 deletions
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 7a53f1e159a9..a9300f3d33ae 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -56,6 +56,7 @@ import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
+import android.media.permission.ClearCallingIdentityContext;
import android.media.permission.Identity;
import android.media.permission.IdentityContext;
import android.media.permission.PermissionUtil;
@@ -242,7 +243,7 @@ public class SoundTriggerService extends SystemService {
@NonNull IBinder client) {
try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
originatorIdentity)) {
- return new SoundTriggerSessionStub(newSoundTriggerHelper(), client);
+ return new SoundTriggerSessionStub(client);
}
}
@@ -253,7 +254,7 @@ public class SoundTriggerService extends SystemService {
try (SafeCloseable ignored = PermissionUtil.establishIdentityIndirect(mContext,
SOUNDTRIGGER_DELEGATE_IDENTITY, middlemanIdentity,
originatorIdentity)) {
- return new SoundTriggerSessionStub(newSoundTriggerHelper(), client);
+ return new SoundTriggerSessionStub(client);
}
}
}
@@ -262,14 +263,15 @@ public class SoundTriggerService extends SystemService {
private final SoundTriggerHelper mSoundTriggerHelper;
// Used to detect client death.
private final IBinder mClient;
+ private final Identity mOriginatorIdentity;
private final TreeMap<UUID, SoundModel> mLoadedModels = new TreeMap<>();
private final Object mCallbacksLock = new Object();
private final TreeMap<UUID, IRecognitionStatusCallback> mCallbacks = new TreeMap<>();
- SoundTriggerSessionStub(
- SoundTriggerHelper soundTriggerHelper, @NonNull IBinder client) {
- mSoundTriggerHelper = soundTriggerHelper;
+ SoundTriggerSessionStub(@NonNull IBinder client) {
+ mSoundTriggerHelper = newSoundTriggerHelper();
mClient = client;
+ mOriginatorIdentity = IdentityContext.getNonNull();
try {
mClient.linkToDeath(() -> {
clientDied();
@@ -297,464 +299,496 @@ public class SoundTriggerService extends SystemService {
@Override
public int startRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback,
RecognitionConfig config, boolean runInBatterySaverMode) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (runInBatterySaverMode) {
- enforceCallingPermission(Manifest.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER);
- }
- if (DEBUG) {
- Slog.i(TAG, "startRecognition(): Uuid : " + parcelUuid);
- }
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (runInBatterySaverMode) {
+ enforceCallingPermission(Manifest.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER);
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent("startRecognition(): Uuid : "
- + parcelUuid));
+ if (DEBUG) {
+ Slog.i(TAG, "startRecognition(): Uuid : " + parcelUuid);
+ }
- GenericSoundModel model = getSoundModel(parcelUuid);
- if (model == null) {
- Slog.e(TAG, "Null model in database for id: " + parcelUuid);
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("startRecognition(): Uuid : "
+ + parcelUuid));
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "startRecognition(): Null model in database for id: " + parcelUuid));
+ GenericSoundModel model = getSoundModel(parcelUuid);
+ if (model == null) {
+ Slog.e(TAG, "Null model in database for id: " + parcelUuid);
- return STATUS_ERROR;
- }
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "startRecognition(): Null model in database for id: " + parcelUuid));
- int ret = mSoundTriggerHelper.startGenericRecognition(parcelUuid.getUuid(), model,
- callback, config, runInBatterySaverMode);
- if (ret == STATUS_OK) {
- mSoundModelStatTracker.onStart(parcelUuid.getUuid());
+ return STATUS_ERROR;
+ }
+
+ int ret = mSoundTriggerHelper.startGenericRecognition(parcelUuid.getUuid(), model,
+ callback, config, runInBatterySaverMode);
+ if (ret == STATUS_OK) {
+ mSoundModelStatTracker.onStart(parcelUuid.getUuid());
+ }
+ return ret;
}
- return ret;
}
@Override
public int stopRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (DEBUG) {
- Slog.i(TAG, "stopRecognition(): Uuid : " + parcelUuid);
- }
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "stopRecognition(): Uuid : " + parcelUuid);
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent("stopRecognition(): Uuid : "
- + parcelUuid));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("stopRecognition(): Uuid : "
+ + parcelUuid));
- int ret = mSoundTriggerHelper.stopGenericRecognition(parcelUuid.getUuid(), callback);
- if (ret == STATUS_OK) {
- mSoundModelStatTracker.onStop(parcelUuid.getUuid());
+ int ret = mSoundTriggerHelper.stopGenericRecognition(parcelUuid.getUuid(),
+ callback);
+ if (ret == STATUS_OK) {
+ mSoundModelStatTracker.onStop(parcelUuid.getUuid());
+ }
+ return ret;
}
- return ret;
}
@Override
public SoundTrigger.GenericSoundModel getSoundModel(ParcelUuid soundModelId) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (DEBUG) {
- Slog.i(TAG, "getSoundModel(): id = " + soundModelId);
- }
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "getSoundModel(): id = " + soundModelId);
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent("getSoundModel(): id = "
- + soundModelId));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("getSoundModel(): id = "
+ + soundModelId));
- SoundTrigger.GenericSoundModel model = mDbHelper.getGenericSoundModel(
- soundModelId.getUuid());
- return model;
+ SoundTrigger.GenericSoundModel model = mDbHelper.getGenericSoundModel(
+ soundModelId.getUuid());
+ return model;
+ }
}
@Override
public void updateSoundModel(SoundTrigger.GenericSoundModel soundModel) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (DEBUG) {
- Slog.i(TAG, "updateSoundModel(): model = " + soundModel);
- }
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "updateSoundModel(): model = " + soundModel);
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent("updateSoundModel(): model = "
- + soundModel));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("updateSoundModel(): model = "
+ + soundModel));
- mDbHelper.updateGenericSoundModel(soundModel);
+ mDbHelper.updateGenericSoundModel(soundModel);
+ }
}
@Override
public void deleteSoundModel(ParcelUuid soundModelId) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (DEBUG) {
- Slog.i(TAG, "deleteSoundModel(): id = " + soundModelId);
- }
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "deleteSoundModel(): id = " + soundModelId);
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent("deleteSoundModel(): id = "
- + soundModelId));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("deleteSoundModel(): id = "
+ + soundModelId));
- // Unload the model if it is loaded.
- mSoundTriggerHelper.unloadGenericSoundModel(soundModelId.getUuid());
+ // Unload the model if it is loaded.
+ mSoundTriggerHelper.unloadGenericSoundModel(soundModelId.getUuid());
- // Stop tracking recognition if it is started.
- mSoundModelStatTracker.onStop(soundModelId.getUuid());
+ // Stop tracking recognition if it is started.
+ mSoundModelStatTracker.onStop(soundModelId.getUuid());
- mDbHelper.deleteGenericSoundModel(soundModelId.getUuid());
+ mDbHelper.deleteGenericSoundModel(soundModelId.getUuid());
+ }
}
@Override
public int loadGenericSoundModel(GenericSoundModel soundModel) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (soundModel == null || soundModel.getUuid() == null) {
- Slog.e(TAG, "Invalid sound model");
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (soundModel == null || soundModel.getUuid() == null) {
+ Slog.e(TAG, "Invalid sound model");
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "loadGenericSoundModel(): Invalid sound model"));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "loadGenericSoundModel(): Invalid sound model"));
- return STATUS_ERROR;
- }
- if (DEBUG) {
- Slog.i(TAG, "loadGenericSoundModel(): id = " + soundModel.getUuid());
- }
+ return STATUS_ERROR;
+ }
+ if (DEBUG) {
+ Slog.i(TAG, "loadGenericSoundModel(): id = " + soundModel.getUuid());
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent("loadGenericSoundModel(): id = "
- + soundModel.getUuid()));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("loadGenericSoundModel(): id = "
+ + soundModel.getUuid()));
- synchronized (mLock) {
- SoundModel oldModel = mLoadedModels.get(soundModel.getUuid());
- // If the model we're loading is actually different than what we had loaded, we
- // should unload that other model now. We don't care about return codes since we
- // don't know if the other model is loaded.
- if (oldModel != null && !oldModel.equals(soundModel)) {
- mSoundTriggerHelper.unloadGenericSoundModel(soundModel.getUuid());
- synchronized (mCallbacksLock) {
- mCallbacks.remove(soundModel.getUuid());
+ synchronized (mLock) {
+ SoundModel oldModel = mLoadedModels.get(soundModel.getUuid());
+ // If the model we're loading is actually different than what we had loaded, we
+ // should unload that other model now. We don't care about return codes since we
+ // don't know if the other model is loaded.
+ if (oldModel != null && !oldModel.equals(soundModel)) {
+ mSoundTriggerHelper.unloadGenericSoundModel(soundModel.getUuid());
+ synchronized (mCallbacksLock) {
+ mCallbacks.remove(soundModel.getUuid());
+ }
}
+ mLoadedModels.put(soundModel.getUuid(), soundModel);
}
- mLoadedModels.put(soundModel.getUuid(), soundModel);
+ return STATUS_OK;
}
- return STATUS_OK;
}
@Override
public int loadKeyphraseSoundModel(KeyphraseSoundModel soundModel) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (soundModel == null || soundModel.getUuid() == null) {
- Slog.e(TAG, "Invalid sound model");
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (soundModel == null || soundModel.getUuid() == null) {
+ Slog.e(TAG, "Invalid sound model");
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "loadKeyphraseSoundModel(): Invalid sound model"));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "loadKeyphraseSoundModel(): Invalid sound model"));
- return STATUS_ERROR;
- }
- if (soundModel.getKeyphrases() == null || soundModel.getKeyphrases().length != 1) {
- Slog.e(TAG, "Only one keyphrase per model is currently supported.");
+ return STATUS_ERROR;
+ }
+ if (soundModel.getKeyphrases() == null || soundModel.getKeyphrases().length != 1) {
+ Slog.e(TAG, "Only one keyphrase per model is currently supported.");
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "loadKeyphraseSoundModel(): Only one keyphrase per model"
- + " is currently supported."));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "loadKeyphraseSoundModel(): Only one keyphrase per model"
+ + " is currently supported."));
- return STATUS_ERROR;
- }
- if (DEBUG) {
- Slog.i(TAG, "loadKeyphraseSoundModel(): id = " + soundModel.getUuid());
- }
+ return STATUS_ERROR;
+ }
+ if (DEBUG) {
+ Slog.i(TAG, "loadKeyphraseSoundModel(): id = " + soundModel.getUuid());
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent("loadKeyphraseSoundModel(): id = "
- + soundModel.getUuid()));
+ sEventLogger.log(
+ new SoundTriggerLogger.StringEvent("loadKeyphraseSoundModel(): id = "
+ + soundModel.getUuid()));
- synchronized (mLock) {
- SoundModel oldModel = mLoadedModels.get(soundModel.getUuid());
- // If the model we're loading is actually different than what we had loaded, we
- // should unload that other model now. We don't care about return codes since we
- // don't know if the other model is loaded.
- if (oldModel != null && !oldModel.equals(soundModel)) {
- mSoundTriggerHelper.unloadKeyphraseSoundModel(
- soundModel.getKeyphrases()[0].getId());
- synchronized (mCallbacksLock) {
- mCallbacks.remove(soundModel.getUuid());
+ synchronized (mLock) {
+ SoundModel oldModel = mLoadedModels.get(soundModel.getUuid());
+ // If the model we're loading is actually different than what we had loaded, we
+ // should unload that other model now. We don't care about return codes since we
+ // don't know if the other model is loaded.
+ if (oldModel != null && !oldModel.equals(soundModel)) {
+ mSoundTriggerHelper.unloadKeyphraseSoundModel(
+ soundModel.getKeyphrases()[0].getId());
+ synchronized (mCallbacksLock) {
+ mCallbacks.remove(soundModel.getUuid());
+ }
}
+ mLoadedModels.put(soundModel.getUuid(), soundModel);
}
- mLoadedModels.put(soundModel.getUuid(), soundModel);
+ return STATUS_OK;
}
- return STATUS_OK;
}
@Override
public int startRecognitionForService(ParcelUuid soundModelId, Bundle params,
ComponentName detectionService, SoundTrigger.RecognitionConfig config) {
- Objects.requireNonNull(soundModelId);
- Objects.requireNonNull(detectionService);
- Objects.requireNonNull(config);
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ Objects.requireNonNull(soundModelId);
+ Objects.requireNonNull(detectionService);
+ Objects.requireNonNull(config);
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- enforceDetectionPermissions(detectionService);
+ enforceDetectionPermissions(detectionService);
- if (DEBUG) {
- Slog.i(TAG, "startRecognition(): id = " + soundModelId);
- }
+ if (DEBUG) {
+ Slog.i(TAG, "startRecognition(): id = " + soundModelId);
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "startRecognitionForService(): id = " + soundModelId));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "startRecognitionForService(): id = " + soundModelId));
- IRecognitionStatusCallback callback =
- new RemoteSoundTriggerDetectionService(soundModelId.getUuid(), params,
- detectionService, Binder.getCallingUserHandle(), config);
+ IRecognitionStatusCallback callback =
+ new RemoteSoundTriggerDetectionService(soundModelId.getUuid(), params,
+ detectionService, Binder.getCallingUserHandle(), config);
- synchronized (mLock) {
- SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
- if (soundModel == null) {
+ synchronized (mLock) {
+ SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+ if (soundModel == null) {
Slog.e(TAG, soundModelId + " is not loaded");
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "startRecognitionForService():" + soundModelId + " is not loaded"));
-
- return STATUS_ERROR;
- }
- IRecognitionStatusCallback existingCallback = null;
- synchronized (mCallbacksLock) {
- existingCallback = mCallbacks.get(soundModelId.getUuid());
- }
- if (existingCallback != null) {
- Slog.e(TAG, soundModelId + " is already running");
-
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "startRecognitionForService():"
- + soundModelId + " is already running"));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "startRecognitionForService():" + soundModelId + " is not loaded"));
- return STATUS_ERROR;
- }
- int ret;
- switch (soundModel.getType()) {
- case SoundModel.TYPE_GENERIC_SOUND:
- ret = mSoundTriggerHelper.startGenericRecognition(soundModel.getUuid(),
- (GenericSoundModel) soundModel, callback, config, false);
- break;
- default:
- Slog.e(TAG, "Unknown model type");
+ return STATUS_ERROR;
+ }
+ IRecognitionStatusCallback existingCallback = null;
+ synchronized (mCallbacksLock) {
+ existingCallback = mCallbacks.get(soundModelId.getUuid());
+ }
+ if (existingCallback != null) {
+ Slog.e(TAG, soundModelId + " is already running");
sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "startRecognitionForService(): Unknown model type"));
+ "startRecognitionForService():"
+ + soundModelId + " is already running"));
return STATUS_ERROR;
- }
+ }
+ int ret;
+ switch (soundModel.getType()) {
+ case SoundModel.TYPE_GENERIC_SOUND:
+ ret = mSoundTriggerHelper.startGenericRecognition(soundModel.getUuid(),
+ (GenericSoundModel) soundModel, callback, config, false);
+ break;
+ default:
+ Slog.e(TAG, "Unknown model type");
+
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "startRecognitionForService(): Unknown model type"));
+
+ return STATUS_ERROR;
+ }
- if (ret != STATUS_OK) {
- Slog.e(TAG, "Failed to start model: " + ret);
+ if (ret != STATUS_OK) {
+ Slog.e(TAG, "Failed to start model: " + ret);
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "startRecognitionForService(): Failed to start model:"));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "startRecognitionForService(): Failed to start model:"));
- return ret;
- }
- synchronized (mCallbacksLock) {
- mCallbacks.put(soundModelId.getUuid(), callback);
- }
+ return ret;
+ }
+ synchronized (mCallbacksLock) {
+ mCallbacks.put(soundModelId.getUuid(), callback);
+ }
- mSoundModelStatTracker.onStart(soundModelId.getUuid());
+ mSoundModelStatTracker.onStart(soundModelId.getUuid());
+ }
+ return STATUS_OK;
}
- return STATUS_OK;
}
@Override
public int stopRecognitionForService(ParcelUuid soundModelId) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (DEBUG) {
- Slog.i(TAG, "stopRecognition(): id = " + soundModelId);
- }
-
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "stopRecognitionForService(): id = " + soundModelId));
-
- synchronized (mLock) {
- SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
- if (soundModel == null) {
- Slog.e(TAG, soundModelId + " is not loaded");
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "stopRecognition(): id = " + soundModelId);
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "stopRecognitionForService(): " + soundModelId
- + " is not loaded"));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "stopRecognitionForService(): id = " + soundModelId));
- return STATUS_ERROR;
- }
- IRecognitionStatusCallback callback = null;
- synchronized (mCallbacksLock) {
- callback = mCallbacks.get(soundModelId.getUuid());
- }
- if (callback == null) {
- Slog.e(TAG, soundModelId + " is not running");
+ synchronized (mLock) {
+ SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+ if (soundModel == null) {
+ Slog.e(TAG, soundModelId + " is not loaded");
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "stopRecognitionForService(): " + soundModelId
- + " is not running"));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "stopRecognitionForService(): " + soundModelId
+ + " is not loaded"));
- return STATUS_ERROR;
- }
- int ret;
- switch (soundModel.getType()) {
- case SoundModel.TYPE_GENERIC_SOUND:
- ret = mSoundTriggerHelper.stopGenericRecognition(
- soundModel.getUuid(), callback);
- break;
- default:
- Slog.e(TAG, "Unknown model type");
+ return STATUS_ERROR;
+ }
+ IRecognitionStatusCallback callback = null;
+ synchronized (mCallbacksLock) {
+ callback = mCallbacks.get(soundModelId.getUuid());
+ }
+ if (callback == null) {
+ Slog.e(TAG, soundModelId + " is not running");
sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "stopRecognitionForService(): Unknown model type"));
+ "stopRecognitionForService(): " + soundModelId
+ + " is not running"));
return STATUS_ERROR;
- }
+ }
+ int ret;
+ switch (soundModel.getType()) {
+ case SoundModel.TYPE_GENERIC_SOUND:
+ ret = mSoundTriggerHelper.stopGenericRecognition(
+ soundModel.getUuid(), callback);
+ break;
+ default:
+ Slog.e(TAG, "Unknown model type");
+
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "stopRecognitionForService(): Unknown model type"));
+
+ return STATUS_ERROR;
+ }
- if (ret != STATUS_OK) {
- Slog.e(TAG, "Failed to stop model: " + ret);
+ if (ret != STATUS_OK) {
+ Slog.e(TAG, "Failed to stop model: " + ret);
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
"stopRecognitionForService(): Failed to stop model: " + ret));
- return ret;
- }
- synchronized (mCallbacksLock) {
- mCallbacks.remove(soundModelId.getUuid());
- }
+ return ret;
+ }
+ synchronized (mCallbacksLock) {
+ mCallbacks.remove(soundModelId.getUuid());
+ }
- mSoundModelStatTracker.onStop(soundModelId.getUuid());
+ mSoundModelStatTracker.onStop(soundModelId.getUuid());
+ }
+ return STATUS_OK;
}
- return STATUS_OK;
}
@Override
public int unloadSoundModel(ParcelUuid soundModelId) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (DEBUG) {
- Slog.i(TAG, "unloadSoundModel(): id = " + soundModelId);
- }
-
- sEventLogger.log(new SoundTriggerLogger.StringEvent("unloadSoundModel(): id = "
- + soundModelId));
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "unloadSoundModel(): id = " + soundModelId);
+ }
- synchronized (mLock) {
- SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
- if (soundModel == null) {
- Slog.e(TAG, soundModelId + " is not loaded");
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("unloadSoundModel(): id = "
+ + soundModelId));
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "unloadSoundModel(): " + soundModelId + " is not loaded"));
-
- return STATUS_ERROR;
- }
- int ret;
- switch (soundModel.getType()) {
- case SoundModel.TYPE_KEYPHRASE:
- ret = mSoundTriggerHelper.unloadKeyphraseSoundModel(
- ((KeyphraseSoundModel) soundModel).getKeyphrases()[0].getId());
- break;
- case SoundModel.TYPE_GENERIC_SOUND:
- ret = mSoundTriggerHelper.unloadGenericSoundModel(soundModel.getUuid());
- break;
- default:
- Slog.e(TAG, "Unknown model type");
+ synchronized (mLock) {
+ SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+ if (soundModel == null) {
+ Slog.e(TAG, soundModelId + " is not loaded");
sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "unloadSoundModel(): Unknown model type"));
+ "unloadSoundModel(): " + soundModelId + " is not loaded"));
return STATUS_ERROR;
- }
- if (ret != STATUS_OK) {
- Slog.e(TAG, "Failed to unload model");
+ }
+ int ret;
+ switch (soundModel.getType()) {
+ case SoundModel.TYPE_KEYPHRASE:
+ ret = mSoundTriggerHelper.unloadKeyphraseSoundModel(
+ ((KeyphraseSoundModel) soundModel).getKeyphrases()[0].getId());
+ break;
+ case SoundModel.TYPE_GENERIC_SOUND:
+ ret = mSoundTriggerHelper.unloadGenericSoundModel(soundModel.getUuid());
+ break;
+ default:
+ Slog.e(TAG, "Unknown model type");
+
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "unloadSoundModel(): Unknown model type"));
+
+ return STATUS_ERROR;
+ }
+ if (ret != STATUS_OK) {
+ Slog.e(TAG, "Failed to unload model");
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "unloadSoundModel(): Failed to unload model"));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "unloadSoundModel(): Failed to unload model"));
- return ret;
+ return ret;
+ }
+ mLoadedModels.remove(soundModelId.getUuid());
+ return STATUS_OK;
}
- mLoadedModels.remove(soundModelId.getUuid());
- return STATUS_OK;
}
}
@Override
public boolean isRecognitionActive(ParcelUuid parcelUuid) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- synchronized (mCallbacksLock) {
- IRecognitionStatusCallback callback = mCallbacks.get(parcelUuid.getUuid());
- if (callback == null) {
- return false;
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ synchronized (mCallbacksLock) {
+ IRecognitionStatusCallback callback = mCallbacks.get(parcelUuid.getUuid());
+ if (callback == null) {
+ return false;
+ }
}
+ return mSoundTriggerHelper.isRecognitionRequested(parcelUuid.getUuid());
}
- return mSoundTriggerHelper.isRecognitionRequested(parcelUuid.getUuid());
}
@Override
public int getModelState(ParcelUuid soundModelId) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- int ret = STATUS_ERROR;
- if (DEBUG) {
- Slog.i(TAG, "getModelState(): id = " + soundModelId);
- }
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ int ret = STATUS_ERROR;
+ if (DEBUG) {
+ Slog.i(TAG, "getModelState(): id = " + soundModelId);
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent("getModelState(): id = "
- + soundModelId));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("getModelState(): id = "
+ + soundModelId));
- synchronized (mLock) {
- SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
- if (soundModel == null) {
- Slog.e(TAG, soundModelId + " is not loaded");
+ synchronized (mLock) {
+ SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+ if (soundModel == null) {
+ Slog.e(TAG, soundModelId + " is not loaded");
+
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("getModelState(): "
+ + soundModelId + " is not loaded"));
- sEventLogger.log(new SoundTriggerLogger.StringEvent("getModelState(): "
- + soundModelId + " is not loaded"));
+ return ret;
+ }
+ switch (soundModel.getType()) {
+ case SoundModel.TYPE_GENERIC_SOUND:
+ ret = mSoundTriggerHelper.getGenericModelState(soundModel.getUuid());
+ break;
+ default:
+ // SoundModel.TYPE_KEYPHRASE is not supported to increase privacy.
+ Slog.e(TAG, "Unsupported model type, " + soundModel.getType());
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "getModelState(): Unsupported model type, "
+ + soundModel.getType()));
+ break;
+ }
return ret;
}
- switch (soundModel.getType()) {
- case SoundModel.TYPE_GENERIC_SOUND:
- ret = mSoundTriggerHelper.getGenericModelState(soundModel.getUuid());
- break;
- default:
- // SoundModel.TYPE_KEYPHRASE is not supported to increase privacy.
- Slog.e(TAG, "Unsupported model type, " + soundModel.getType());
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "getModelState(): Unsupported model type, "
- + soundModel.getType()));
- break;
- }
-
- return ret;
}
}
@Override
@Nullable
public ModuleProperties getModuleProperties() {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (DEBUG) {
- Slog.i(TAG, "getModuleProperties()");
- }
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.i(TAG, "getModuleProperties()");
+ }
- synchronized (mLock) {
- ModuleProperties properties = mSoundTriggerHelper.getModuleProperties();
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "getModuleProperties(): " + properties));
- return properties;
+ synchronized (mLock) {
+ ModuleProperties properties = mSoundTriggerHelper.getModuleProperties();
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "getModuleProperties(): " + properties));
+ return properties;
+ }
}
}
@Override
public int setParameter(ParcelUuid soundModelId,
@ModelParams int modelParam, int value) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (DEBUG) {
- Slog.d(TAG, "setParameter(): id=" + soundModelId
- + ", param=" + modelParam
- + ", value=" + value);
- }
-
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "setParameter(): id=" + soundModelId
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.d(TAG, "setParameter(): id=" + soundModelId
+ ", param=" + modelParam
- + ", value=" + value));
+ + ", value=" + value);
+ }
- synchronized (mLock) {
- SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
- if (soundModel == null) {
- Slog.e(TAG, soundModelId + " is not loaded. Loaded models: "
- + mLoadedModels.toString());
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "setParameter(): id=" + soundModelId
+ + ", param=" + modelParam
+ + ", value=" + value));
- sEventLogger.log(new SoundTriggerLogger.StringEvent("setParameter(): "
- + soundModelId + " is not loaded"));
+ synchronized (mLock) {
+ SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+ if (soundModel == null) {
+ Slog.e(TAG, soundModelId + " is not loaded. Loaded models: "
+ + mLoadedModels.toString());
- return STATUS_BAD_VALUE;
- }
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("setParameter(): "
+ + soundModelId + " is not loaded"));
- return mSoundTriggerHelper.setParameter(soundModel.getUuid(), modelParam, value);
+ return STATUS_BAD_VALUE;
+ }
+
+ return mSoundTriggerHelper.setParameter(soundModel.getUuid(), modelParam,
+ value);
+ }
}
}
@@ -762,28 +796,30 @@ public class SoundTriggerService extends SystemService {
public int getParameter(@NonNull ParcelUuid soundModelId,
@ModelParams int modelParam)
throws UnsupportedOperationException, IllegalArgumentException {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (DEBUG) {
- Slog.d(TAG, "getParameter(): id=" + soundModelId
- + ", param=" + modelParam);
- }
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.d(TAG, "getParameter(): id=" + soundModelId
+ + ", param=" + modelParam);
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "getParameter(): id=" + soundModelId
- + ", param=" + modelParam));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "getParameter(): id=" + soundModelId
+ + ", param=" + modelParam));
- synchronized (mLock) {
- SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
- if (soundModel == null) {
- Slog.e(TAG, soundModelId + " is not loaded");
+ synchronized (mLock) {
+ SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+ if (soundModel == null) {
+ Slog.e(TAG, soundModelId + " is not loaded");
- sEventLogger.log(new SoundTriggerLogger.StringEvent("getParameter(): "
- + soundModelId + " is not loaded"));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent("getParameter(): "
+ + soundModelId + " is not loaded"));
- throw new IllegalArgumentException("sound model is not loaded");
- }
+ throw new IllegalArgumentException("sound model is not loaded");
+ }
- return mSoundTriggerHelper.getParameter(soundModel.getUuid(), modelParam);
+ return mSoundTriggerHelper.getParameter(soundModel.getUuid(), modelParam);
+ }
}
}
@@ -791,29 +827,31 @@ public class SoundTriggerService extends SystemService {
@Nullable
public ModelParamRange queryParameter(@NonNull ParcelUuid soundModelId,
@ModelParams int modelParam) {
- enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (DEBUG) {
- Slog.d(TAG, "queryParameter(): id=" + soundModelId
- + ", param=" + modelParam);
- }
+ try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+ if (DEBUG) {
+ Slog.d(TAG, "queryParameter(): id=" + soundModelId
+ + ", param=" + modelParam);
+ }
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "queryParameter(): id=" + soundModelId
- + ", param=" + modelParam));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "queryParameter(): id=" + soundModelId
+ + ", param=" + modelParam));
- synchronized (mLock) {
- SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
- if (soundModel == null) {
- Slog.e(TAG, soundModelId + " is not loaded");
+ synchronized (mLock) {
+ SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+ if (soundModel == null) {
+ Slog.e(TAG, soundModelId + " is not loaded");
- sEventLogger.log(new SoundTriggerLogger.StringEvent(
- "queryParameter(): "
- + soundModelId + " is not loaded"));
+ sEventLogger.log(new SoundTriggerLogger.StringEvent(
+ "queryParameter(): "
+ + soundModelId + " is not loaded"));
- return null;
- }
+ return null;
+ }
- return mSoundTriggerHelper.queryParameter(soundModel.getUuid(), modelParam);
+ return mSoundTriggerHelper.queryParameter(soundModel.getUuid(), modelParam);
+ }
}
}
@@ -824,6 +862,20 @@ public class SoundTriggerService extends SystemService {
mSoundTriggerHelper.detach();
}
+ private void enforceCallingPermission(String permission) {
+ PermissionUtil.checkPermissionForPreflight(mContext, mOriginatorIdentity, permission);
+ }
+
+ private void enforceDetectionPermissions(ComponentName detectionService) {
+ PackageManager packageManager = mContext.getPackageManager();
+ String packageName = detectionService.getPackageName();
+ if (packageManager.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(detectionService.getPackageName() + " does not have"
+ + " permission " + Manifest.permission.CAPTURE_AUDIO_HOTWORD);
+ }
+ }
+
/**
* Local end for a {@link SoundTriggerDetectionService}. Operations are queued up and
* executed when the service connects.
@@ -1577,23 +1629,6 @@ public class SoundTriggerService extends SystemService {
}
}
- private void enforceCallingPermission(String permission) {
- if (mContext.checkCallingOrSelfPermission(permission)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Caller does not hold the permission " + permission);
- }
- }
-
- private void enforceDetectionPermissions(ComponentName detectionService) {
- PackageManager packageManager = mContext.getPackageManager();
- String packageName = detectionService.getPackageName();
- if (packageManager.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException(detectionService.getPackageName() + " does not have"
- + " permission " + Manifest.permission.CAPTURE_AUDIO_HOTWORD);
- }
- }
-
//=================================================================
// For logging