Merge "Make Trusted Hotword session permissions follow previous behavior" into sc-dev am: e81ea6bebd

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

Change-Id: Iea6b6643bda7f4d9395caf5d77aab0e8d09527e9
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 4137416..face870 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -783,6 +783,9 @@
      *         This may happen if another detector has been instantiated or the
      *         {@link VoiceInteractionService} hosting this detector has been shut down.
      */
+    // TODO: Remove this RequiresPermission since it isn't actually enforced. Also fix the javadoc
+    // about permissions enforcement (when it throws vs when it just returns false) for other
+    // methods in this class.
     @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
     @Override
     public boolean stopRecognition() {
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
index 02294e5..f7a3415 100644
--- a/core/java/android/service/voice/SoftwareHotwordDetector.java
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -82,6 +82,9 @@
         try {
             mManagerService.startListeningFromMic(
                     mAudioFormat, new BinderCallback(mHandler, mCallback));
+        } catch (SecurityException e) {
+            Slog.e(TAG, "startRecognition failed: " + e);
+            return false;
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
index 68b2e61..c0c3e6f 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerSessionPermissionsDecorator.java
@@ -60,7 +60,7 @@
 
     @Override
     public SoundTrigger.ModuleProperties getDspModuleProperties() throws RemoteException {
-        // No permission needed.
+        // No permission needed here (the app must have the Assistant Role to retrieve the session).
         return mDelegate.getDspModuleProperties();
     }
 
@@ -71,7 +71,9 @@
         if (DEBUG) {
             Slog.d(TAG, "startRecognition");
         }
-        enforcePermissions();
+        if (!isHoldingPermissions()) {
+            return SoundTrigger.STATUS_PERMISSION_DENIED;
+        }
         return mDelegate.startRecognition(i, s, iHotwordRecognitionStatusCallback,
                 recognitionConfig, b);
     }
@@ -80,25 +82,28 @@
     public int stopRecognition(int i,
             IHotwordRecognitionStatusCallback iHotwordRecognitionStatusCallback)
             throws RemoteException {
-        enforcePermissions();
+        // Stopping a model does not require special permissions. Having a handle to the session is
+        // sufficient.
         return mDelegate.stopRecognition(i, iHotwordRecognitionStatusCallback);
     }
 
     @Override
     public int setParameter(int i, int i1, int i2) throws RemoteException {
-        enforcePermissions();
+        if (!isHoldingPermissions()) {
+            return SoundTrigger.STATUS_PERMISSION_DENIED;
+        }
         return mDelegate.setParameter(i, i1, i2);
     }
 
     @Override
     public int getParameter(int i, int i1) throws RemoteException {
-        enforcePermissions();
+        // No permission needed here (the app must have the Assistant Role to retrieve the session).
         return mDelegate.getParameter(i, i1);
     }
 
     @Override
     public SoundTrigger.ModelParamRange queryParameter(int i, int i1) throws RemoteException {
-        enforcePermissions();
+        // No permission needed here (the app must have the Assistant Role to retrieve the session).
         return mDelegate.queryParameter(i, i1);
     }
 
@@ -109,9 +114,15 @@
     }
 
     // TODO: Share this code with SoundTriggerMiddlewarePermission.
-    private void enforcePermissions() {
-        enforcePermissionForPreflight(mContext, mOriginatorIdentity, RECORD_AUDIO);
-        enforcePermissionForPreflight(mContext, mOriginatorIdentity, CAPTURE_AUDIO_HOTWORD);
+    private boolean isHoldingPermissions() {
+        try {
+            enforcePermissionForPreflight(mContext, mOriginatorIdentity, RECORD_AUDIO);
+            enforcePermissionForPreflight(mContext, mOriginatorIdentity, CAPTURE_AUDIO_HOTWORD);
+            return true;
+        } catch (SecurityException e) {
+            Slog.e(TAG, e.toString());
+            return false;
+        }
     }
 
     /**