Loading services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +28 −10 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPH import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER; import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH; import android.app.AppOpsManager; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.ChangeId; Loading Loading @@ -548,13 +549,15 @@ final class HotwordDetectionConnection { static final class SoundTriggerCallback extends IRecognitionStatusCallback.Stub { private final HotwordDetectionConnection mHotwordDetectionConnection; private final IHotwordRecognitionStatusCallback mExternalCallback; private final int mVoiceInteractionServiceUid; private final Identity mVoiceInteractorIdentity; private final Context mContext; SoundTriggerCallback(IHotwordRecognitionStatusCallback callback, HotwordDetectionConnection connection, int uid) { SoundTriggerCallback(Context context, IHotwordRecognitionStatusCallback callback, HotwordDetectionConnection connection, Identity voiceInteractorIdentity) { mContext = context; mHotwordDetectionConnection = connection; mExternalCallback = callback; mVoiceInteractionServiceUid = uid; mVoiceInteractorIdentity = voiceInteractorIdentity; } @Override Loading @@ -568,17 +571,32 @@ final class HotwordDetectionConnection { HotwordMetricsLogger.writeKeyphraseTriggerEvent( HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP, HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER, mVoiceInteractionServiceUid); mVoiceInteractorIdentity.uid); mHotwordDetectionConnection.detectFromDspSource( recognitionEvent, mExternalCallback); } else { // We have to attribute ops here, since we configure all st clients as trusted to // enable a partial exemption. // TODO (b/292012931) remove once trusted uniformly required. int result = mContext.getSystemService(AppOpsManager.class) .noteOpNoThrow(AppOpsManager.OP_RECORD_AUDIO_HOTWORD, mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName, mVoiceInteractorIdentity.attributionTag, "Non-HDS keyphrase recognition to VoiceInteractionService"); if (result != AppOpsManager.MODE_ALLOWED) { Slog.w(TAG, "onKeyphraseDetected suppressed, permission check returned: " + result); mExternalCallback.onRecognitionPaused(); } else { HotwordMetricsLogger.writeKeyphraseTriggerEvent( HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR, HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER, mVoiceInteractionServiceUid); mVoiceInteractorIdentity.uid); mExternalCallback.onKeyphraseDetected(recognitionEvent, null); } } } @Override public void onGenericSoundTriggerDetected( Loading services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +24 −6 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ import com.android.server.SystemService; import com.android.server.UiThread; import com.android.server.pm.UserManagerInternal; import com.android.server.pm.permission.LegacyPermissionManagerInternal; import com.android.server.policy.AppOpsPolicy; import com.android.server.utils.Slogf; import com.android.server.utils.TimingsTraceAndSlog; import com.android.server.wm.ActivityTaskManagerInternal; Loading Loading @@ -336,6 +337,9 @@ public class VoiceInteractionManagerService extends SystemService { /** The start value of showSessionId */ private static final int SHOW_SESSION_START_ID = 0; private final boolean IS_HDS_REQUIRED = AppOpsPolicy.isHotwordDetectionServiceRequired( mContext.getPackageManager()); @GuardedBy("this") private int mShowSessionId = SHOW_SESSION_START_ID; Loading Loading @@ -393,8 +397,14 @@ public class VoiceInteractionManagerService extends SystemService { } try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect( originatorIdentity)) { if (!IS_HDS_REQUIRED) { // For devices which still have hotword exemption, any client (not just HDS // clients) are trusted. // TODO (b/292012931) remove once trusted uniformly required. forHotwordDetectionService = true; } return new SoundTriggerSession(mSoundTriggerInternal.attach(client, moduleProperties, forHotwordDetectionService)); moduleProperties, forHotwordDetectionService), originatorIdentity); } } Loading Loading @@ -1674,10 +1684,13 @@ public class VoiceInteractionManagerService extends SystemService { final SoundTriggerInternal.Session mSession; private IHotwordRecognitionStatusCallback mSessionExternalCallback; private IRecognitionStatusCallback mSessionInternalCallback; private final Identity mVoiceInteractorIdentity; SoundTriggerSession( SoundTriggerInternal.Session session) { SoundTriggerInternal.Session session, Identity voiceInteractorIdentity) { mSession = session; mVoiceInteractorIdentity = voiceInteractorIdentity; } @Override Loading Loading @@ -1731,7 +1744,8 @@ public class VoiceInteractionManagerService extends SystemService { if (mSessionExternalCallback == null || mSessionInternalCallback == null || callback.asBinder() != mSessionExternalCallback.asBinder()) { mSessionInternalCallback = createSoundTriggerCallbackLocked(callback); mSessionInternalCallback = createSoundTriggerCallbackLocked(callback, mVoiceInteractorIdentity); mSessionExternalCallback = callback; } } Loading @@ -1752,7 +1766,8 @@ public class VoiceInteractionManagerService extends SystemService { if (mSessionExternalCallback == null || mSessionInternalCallback == null || callback.asBinder() != mSessionExternalCallback.asBinder()) { soundTriggerCallback = createSoundTriggerCallbackLocked(callback); soundTriggerCallback = createSoundTriggerCallbackLocked(callback, mVoiceInteractorIdentity); Slog.w(TAG, "stopRecognition() called with a different callback than" + "startRecognition()"); } else { Loading Loading @@ -2090,6 +2105,7 @@ public class VoiceInteractionManagerService extends SystemService { pw.println(" mTemporarilyDisabled: " + mTemporarilyDisabled); pw.println(" mCurUser: " + mCurUser); pw.println(" mCurUserSupported: " + mCurUserSupported); pw.println(" mIsHdsRequired: " + IS_HDS_REQUIRED); dumpSupportedUsers(pw, " "); mDbHelper.dump(pw); if (mImpl == null) { Loading Loading @@ -2165,11 +2181,13 @@ public class VoiceInteractionManagerService extends SystemService { } private IRecognitionStatusCallback createSoundTriggerCallbackLocked( IHotwordRecognitionStatusCallback callback) { IHotwordRecognitionStatusCallback callback, Identity voiceInteractorIdentity) { if (mImpl == null) { return null; } return mImpl.createSoundTriggerCallbackLocked(callback); return mImpl.createSoundTriggerCallbackLocked(mContext, callback, voiceInteractorIdentity); } class RoleObserver implements OnRoleHoldersChangedListener { Loading services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java +4 −3 Original line number Diff line number Diff line Loading @@ -877,12 +877,13 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne } public IRecognitionStatusCallback createSoundTriggerCallbackLocked( IHotwordRecognitionStatusCallback callback) { Context context, IHotwordRecognitionStatusCallback callback, Identity voiceInteractorIdentity) { if (DEBUG) { Slog.d(TAG, "createSoundTriggerCallbackLocked"); } return new HotwordDetectionConnection.SoundTriggerCallback(callback, mHotwordDetectionConnection, mInfo.getServiceInfo().applicationInfo.uid); return new HotwordDetectionConnection.SoundTriggerCallback(context, callback, mHotwordDetectionConnection, voiceInteractorIdentity); } private static ServiceInfo getServiceInfoLocked(@NonNull ComponentName componentName, Loading Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +28 −10 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPH import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER; import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH; import android.app.AppOpsManager; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.ChangeId; Loading Loading @@ -548,13 +549,15 @@ final class HotwordDetectionConnection { static final class SoundTriggerCallback extends IRecognitionStatusCallback.Stub { private final HotwordDetectionConnection mHotwordDetectionConnection; private final IHotwordRecognitionStatusCallback mExternalCallback; private final int mVoiceInteractionServiceUid; private final Identity mVoiceInteractorIdentity; private final Context mContext; SoundTriggerCallback(IHotwordRecognitionStatusCallback callback, HotwordDetectionConnection connection, int uid) { SoundTriggerCallback(Context context, IHotwordRecognitionStatusCallback callback, HotwordDetectionConnection connection, Identity voiceInteractorIdentity) { mContext = context; mHotwordDetectionConnection = connection; mExternalCallback = callback; mVoiceInteractionServiceUid = uid; mVoiceInteractorIdentity = voiceInteractorIdentity; } @Override Loading @@ -568,17 +571,32 @@ final class HotwordDetectionConnection { HotwordMetricsLogger.writeKeyphraseTriggerEvent( HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP, HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER, mVoiceInteractionServiceUid); mVoiceInteractorIdentity.uid); mHotwordDetectionConnection.detectFromDspSource( recognitionEvent, mExternalCallback); } else { // We have to attribute ops here, since we configure all st clients as trusted to // enable a partial exemption. // TODO (b/292012931) remove once trusted uniformly required. int result = mContext.getSystemService(AppOpsManager.class) .noteOpNoThrow(AppOpsManager.OP_RECORD_AUDIO_HOTWORD, mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName, mVoiceInteractorIdentity.attributionTag, "Non-HDS keyphrase recognition to VoiceInteractionService"); if (result != AppOpsManager.MODE_ALLOWED) { Slog.w(TAG, "onKeyphraseDetected suppressed, permission check returned: " + result); mExternalCallback.onRecognitionPaused(); } else { HotwordMetricsLogger.writeKeyphraseTriggerEvent( HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR, HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER, mVoiceInteractionServiceUid); mVoiceInteractorIdentity.uid); mExternalCallback.onKeyphraseDetected(recognitionEvent, null); } } } @Override public void onGenericSoundTriggerDetected( Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +24 −6 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ import com.android.server.SystemService; import com.android.server.UiThread; import com.android.server.pm.UserManagerInternal; import com.android.server.pm.permission.LegacyPermissionManagerInternal; import com.android.server.policy.AppOpsPolicy; import com.android.server.utils.Slogf; import com.android.server.utils.TimingsTraceAndSlog; import com.android.server.wm.ActivityTaskManagerInternal; Loading Loading @@ -336,6 +337,9 @@ public class VoiceInteractionManagerService extends SystemService { /** The start value of showSessionId */ private static final int SHOW_SESSION_START_ID = 0; private final boolean IS_HDS_REQUIRED = AppOpsPolicy.isHotwordDetectionServiceRequired( mContext.getPackageManager()); @GuardedBy("this") private int mShowSessionId = SHOW_SESSION_START_ID; Loading Loading @@ -393,8 +397,14 @@ public class VoiceInteractionManagerService extends SystemService { } try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect( originatorIdentity)) { if (!IS_HDS_REQUIRED) { // For devices which still have hotword exemption, any client (not just HDS // clients) are trusted. // TODO (b/292012931) remove once trusted uniformly required. forHotwordDetectionService = true; } return new SoundTriggerSession(mSoundTriggerInternal.attach(client, moduleProperties, forHotwordDetectionService)); moduleProperties, forHotwordDetectionService), originatorIdentity); } } Loading Loading @@ -1674,10 +1684,13 @@ public class VoiceInteractionManagerService extends SystemService { final SoundTriggerInternal.Session mSession; private IHotwordRecognitionStatusCallback mSessionExternalCallback; private IRecognitionStatusCallback mSessionInternalCallback; private final Identity mVoiceInteractorIdentity; SoundTriggerSession( SoundTriggerInternal.Session session) { SoundTriggerInternal.Session session, Identity voiceInteractorIdentity) { mSession = session; mVoiceInteractorIdentity = voiceInteractorIdentity; } @Override Loading Loading @@ -1731,7 +1744,8 @@ public class VoiceInteractionManagerService extends SystemService { if (mSessionExternalCallback == null || mSessionInternalCallback == null || callback.asBinder() != mSessionExternalCallback.asBinder()) { mSessionInternalCallback = createSoundTriggerCallbackLocked(callback); mSessionInternalCallback = createSoundTriggerCallbackLocked(callback, mVoiceInteractorIdentity); mSessionExternalCallback = callback; } } Loading @@ -1752,7 +1766,8 @@ public class VoiceInteractionManagerService extends SystemService { if (mSessionExternalCallback == null || mSessionInternalCallback == null || callback.asBinder() != mSessionExternalCallback.asBinder()) { soundTriggerCallback = createSoundTriggerCallbackLocked(callback); soundTriggerCallback = createSoundTriggerCallbackLocked(callback, mVoiceInteractorIdentity); Slog.w(TAG, "stopRecognition() called with a different callback than" + "startRecognition()"); } else { Loading Loading @@ -2090,6 +2105,7 @@ public class VoiceInteractionManagerService extends SystemService { pw.println(" mTemporarilyDisabled: " + mTemporarilyDisabled); pw.println(" mCurUser: " + mCurUser); pw.println(" mCurUserSupported: " + mCurUserSupported); pw.println(" mIsHdsRequired: " + IS_HDS_REQUIRED); dumpSupportedUsers(pw, " "); mDbHelper.dump(pw); if (mImpl == null) { Loading Loading @@ -2165,11 +2181,13 @@ public class VoiceInteractionManagerService extends SystemService { } private IRecognitionStatusCallback createSoundTriggerCallbackLocked( IHotwordRecognitionStatusCallback callback) { IHotwordRecognitionStatusCallback callback, Identity voiceInteractorIdentity) { if (mImpl == null) { return null; } return mImpl.createSoundTriggerCallbackLocked(callback); return mImpl.createSoundTriggerCallbackLocked(mContext, callback, voiceInteractorIdentity); } class RoleObserver implements OnRoleHoldersChangedListener { Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java +4 −3 Original line number Diff line number Diff line Loading @@ -877,12 +877,13 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne } public IRecognitionStatusCallback createSoundTriggerCallbackLocked( IHotwordRecognitionStatusCallback callback) { Context context, IHotwordRecognitionStatusCallback callback, Identity voiceInteractorIdentity) { if (DEBUG) { Slog.d(TAG, "createSoundTriggerCallbackLocked"); } return new HotwordDetectionConnection.SoundTriggerCallback(callback, mHotwordDetectionConnection, mInfo.getServiceInfo().applicationInfo.uid); return new HotwordDetectionConnection.SoundTriggerCallback(context, callback, mHotwordDetectionConnection, voiceInteractorIdentity); } private static ServiceInfo getServiceInfoLocked(@NonNull ComponentName componentName, Loading