Loading core/java/android/service/voice/AbstractHotwordDetector.java +9 −0 Original line number Diff line number Diff line Loading @@ -204,5 +204,14 @@ abstract class AbstractHotwordDetector implements HotwordDetector { .setHotwordDetectedResult(hotwordDetectedResult) .build())); } /** Called when the detection fails due to an error. */ @Override public void onError() { Slog.v(TAG, "BinderCallback#onError"); mHandler.sendMessage(obtainMessage( HotwordDetector.Callback::onError, mCallback)); } } } core/java/android/service/voice/IMicrophoneHotwordDetectionVoiceInteractionCallback.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -33,4 +33,9 @@ oneway interface IMicrophoneHotwordDetectionVoiceInteractionCallback { in HotwordDetectedResult hotwordDetectedResult, in AudioFormat audioFormat, in ParcelFileDescriptor audioStream); /** * Called when the detection fails due to an error. */ void onError(); } core/java/android/service/voice/SoftwareHotwordDetector.java +9 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,15 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector { .setHotwordDetectedResult(hotwordDetectedResult) .build())); } /** Called when the detection fails due to an error. */ @Override public void onError() { Slog.v(TAG, "BinderCallback#onError"); mHandler.sendMessage(obtainMessage( HotwordDetector.Callback::onError, mCallback)); } } private static class InitializationStateListener Loading services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +46 −25 Original line number Diff line number Diff line Loading @@ -125,6 +125,10 @@ final class HotwordDetectionConnection { private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour private static final int MAX_ISOLATED_PROCESS_NUMBER = 10; // The error codes are used for onError callback private static final int HOTWORD_DETECTION_SERVICE_DIED = -1; private static final int CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION = -2; // Hotword metrics private static final int METRICS_INIT_UNKNOWN_TIMEOUT = HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_TIMEOUT; Loading Loading @@ -421,10 +425,18 @@ final class HotwordDetectionConnection { Slog.d(TAG, "onDetected"); } synchronized (mLock) { if (mPerformingSoftwareHotwordDetection) { if (!mPerformingSoftwareHotwordDetection) { Slog.i(TAG, "Hotword detection has already completed"); return; } mPerformingSoftwareHotwordDetection = false; try { enforcePermissionsForDataDelivery(); } catch (SecurityException e) { mSoftwareCallback.onError(); return; } mSoftwareCallback.onDetected(result, null, null); mPerformingSoftwareHotwordDetection = false; if (result != null) { Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result) + " bits from hotword trusted process"); Loading @@ -432,9 +444,6 @@ final class HotwordDetectionConnection { Slog.i(TAG, "Egressed detected result: " + result); } } } else { Slog.i(TAG, "Hotword detection has already completed"); } } } Loading Loading @@ -514,10 +523,18 @@ final class HotwordDetectionConnection { public void onDetected(HotwordDetectedResult result) throws RemoteException { Slog.v(TAG, "onDetected"); synchronized (mLock) { if (mValidatingDspTrigger) { if (!mValidatingDspTrigger) { Slog.i(TAG, "Ignored hotword detected since trigger has been handled"); return; } mValidatingDspTrigger = false; try { enforcePermissionsForDataDelivery(); enforceExtraKeyphraseIdNotLeaked(result, recognitionEvent); } catch (SecurityException e) { externalCallback.onError(CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION); return; } externalCallback.onKeyphraseDetected(recognitionEvent, result); if (result != null) { Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result) Loading @@ -526,9 +543,6 @@ final class HotwordDetectionConnection { Slog.i(TAG, "Egressed detected result: " + result); } } } else { Slog.i(TAG, "Ignored hotword detected since trigger has been handled"); } } } Loading Loading @@ -598,7 +612,8 @@ final class HotwordDetectionConnection { HotwordMetricsLogger.writeKeyphraseTriggerEvent( mDetectorType, METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION); throw e; externalCallback.onError(CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION); return; } externalCallback.onKeyphraseDetected(recognitionEvent, result); if (result != null) { Loading Loading @@ -888,7 +903,13 @@ final class HotwordDetectionConnection { throws RemoteException { bestEffortClose(serviceAudioSink); bestEffortClose(serviceAudioSource); try { enforcePermissionsForDataDelivery(); } catch (SecurityException e) { bestEffortClose(audioSource); callback.onError(); return; } callback.onDetected(triggerResult, null /* audioFormat */, null /* audioStream */); if (triggerResult != null) { Loading Loading @@ -988,7 +1009,7 @@ final class HotwordDetectionConnection { Slog.w(TAG, "binderDied"); try { mCallback.onError(-1); mCallback.onError(HOTWORD_DETECTION_SERVICE_DIED); } catch (RemoteException e) { Slog.w(TAG, "Failed to report onError status: " + e); } Loading Loading
core/java/android/service/voice/AbstractHotwordDetector.java +9 −0 Original line number Diff line number Diff line Loading @@ -204,5 +204,14 @@ abstract class AbstractHotwordDetector implements HotwordDetector { .setHotwordDetectedResult(hotwordDetectedResult) .build())); } /** Called when the detection fails due to an error. */ @Override public void onError() { Slog.v(TAG, "BinderCallback#onError"); mHandler.sendMessage(obtainMessage( HotwordDetector.Callback::onError, mCallback)); } } }
core/java/android/service/voice/IMicrophoneHotwordDetectionVoiceInteractionCallback.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -33,4 +33,9 @@ oneway interface IMicrophoneHotwordDetectionVoiceInteractionCallback { in HotwordDetectedResult hotwordDetectedResult, in AudioFormat audioFormat, in ParcelFileDescriptor audioStream); /** * Called when the detection fails due to an error. */ void onError(); }
core/java/android/service/voice/SoftwareHotwordDetector.java +9 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,15 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector { .setHotwordDetectedResult(hotwordDetectedResult) .build())); } /** Called when the detection fails due to an error. */ @Override public void onError() { Slog.v(TAG, "BinderCallback#onError"); mHandler.sendMessage(obtainMessage( HotwordDetector.Callback::onError, mCallback)); } } private static class InitializationStateListener Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +46 −25 Original line number Diff line number Diff line Loading @@ -125,6 +125,10 @@ final class HotwordDetectionConnection { private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour private static final int MAX_ISOLATED_PROCESS_NUMBER = 10; // The error codes are used for onError callback private static final int HOTWORD_DETECTION_SERVICE_DIED = -1; private static final int CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION = -2; // Hotword metrics private static final int METRICS_INIT_UNKNOWN_TIMEOUT = HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_TIMEOUT; Loading Loading @@ -421,10 +425,18 @@ final class HotwordDetectionConnection { Slog.d(TAG, "onDetected"); } synchronized (mLock) { if (mPerformingSoftwareHotwordDetection) { if (!mPerformingSoftwareHotwordDetection) { Slog.i(TAG, "Hotword detection has already completed"); return; } mPerformingSoftwareHotwordDetection = false; try { enforcePermissionsForDataDelivery(); } catch (SecurityException e) { mSoftwareCallback.onError(); return; } mSoftwareCallback.onDetected(result, null, null); mPerformingSoftwareHotwordDetection = false; if (result != null) { Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result) + " bits from hotword trusted process"); Loading @@ -432,9 +444,6 @@ final class HotwordDetectionConnection { Slog.i(TAG, "Egressed detected result: " + result); } } } else { Slog.i(TAG, "Hotword detection has already completed"); } } } Loading Loading @@ -514,10 +523,18 @@ final class HotwordDetectionConnection { public void onDetected(HotwordDetectedResult result) throws RemoteException { Slog.v(TAG, "onDetected"); synchronized (mLock) { if (mValidatingDspTrigger) { if (!mValidatingDspTrigger) { Slog.i(TAG, "Ignored hotword detected since trigger has been handled"); return; } mValidatingDspTrigger = false; try { enforcePermissionsForDataDelivery(); enforceExtraKeyphraseIdNotLeaked(result, recognitionEvent); } catch (SecurityException e) { externalCallback.onError(CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION); return; } externalCallback.onKeyphraseDetected(recognitionEvent, result); if (result != null) { Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result) Loading @@ -526,9 +543,6 @@ final class HotwordDetectionConnection { Slog.i(TAG, "Egressed detected result: " + result); } } } else { Slog.i(TAG, "Ignored hotword detected since trigger has been handled"); } } } Loading Loading @@ -598,7 +612,8 @@ final class HotwordDetectionConnection { HotwordMetricsLogger.writeKeyphraseTriggerEvent( mDetectorType, METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION); throw e; externalCallback.onError(CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION); return; } externalCallback.onKeyphraseDetected(recognitionEvent, result); if (result != null) { Loading Loading @@ -888,7 +903,13 @@ final class HotwordDetectionConnection { throws RemoteException { bestEffortClose(serviceAudioSink); bestEffortClose(serviceAudioSource); try { enforcePermissionsForDataDelivery(); } catch (SecurityException e) { bestEffortClose(audioSource); callback.onError(); return; } callback.onDetected(triggerResult, null /* audioFormat */, null /* audioStream */); if (triggerResult != null) { Loading Loading @@ -988,7 +1009,7 @@ final class HotwordDetectionConnection { Slog.w(TAG, "binderDied"); try { mCallback.onError(-1); mCallback.onError(HOTWORD_DETECTION_SERVICE_DIED); } catch (RemoteException e) { Slog.w(TAG, "Failed to report onError status: " + e); } Loading