Loading services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java +3 −4 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.SharedMemory; import android.service.voice.DetectorFailure; import android.service.voice.HotwordDetectedResult; import android.service.voice.HotwordDetectionService; import android.service.voice.HotwordDetectionServiceFailure; Loading Loading @@ -623,11 +624,9 @@ abstract class DetectorSession { mRemoteDetectionService = remoteDetectionService; } void reportErrorLocked(int errorCode, @NonNull String errorMessage) { void reportErrorLocked(@NonNull DetectorFailure detectorFailure) { try { // TODO: Use instanceof(this) to get different detector to set the right error source. mCallback.onDetectionFailure( new HotwordDetectionServiceFailure(errorCode, errorMessage)); mCallback.onDetectionFailure(detectorFailure); } catch (RemoteException e) { Slog.w(TAG, "Failed to report onError status: " + e); if (getDetectorType() != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { Loading services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +72 −16 Original line number Diff line number Diff line Loading @@ -51,11 +51,14 @@ import android.os.ServiceManager; import android.os.SharedMemory; import android.provider.DeviceConfig; import android.service.voice.HotwordDetectionService; import android.service.voice.HotwordDetectionServiceFailure; import android.service.voice.HotwordDetector; import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback; import android.service.voice.ISandboxedDetectionService; import android.service.voice.IVisualQueryDetectionVoiceInteractionCallback; import android.service.voice.UnknownFailure; import android.service.voice.VisualQueryDetectionService; import android.service.voice.VisualQueryDetectionServiceFailure; import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity; import android.speech.IRecognitionServiceManager; import android.util.Slog; Loading Loading @@ -109,6 +112,16 @@ 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; /** * Indicates the {@link HotwordDetectionService} is created. */ private static final int DETECTION_SERVICE_TYPE_HOTWORD = 1; /** * Indicates the {@link VisualQueryDetectionService} is created. */ private static final int DETECTION_SERVICE_TYPE_VISUAL_QUERY = 2; // TODO: This may need to be a Handler(looper) private final ScheduledExecutorService mScheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); Loading Loading @@ -186,11 +199,11 @@ final class HotwordDetectionConnection { mHotwordDetectionServiceConnectionFactory = new ServiceConnectionFactory(hotwordDetectionServiceIntent, bindInstantServiceAllowed); bindInstantServiceAllowed, DETECTION_SERVICE_TYPE_HOTWORD); mVisualQueryDetectionServiceConnectionFactory = new ServiceConnectionFactory(visualQueryDetectionServiceIntent, bindInstantServiceAllowed); bindInstantServiceAllowed, DETECTION_SERVICE_TYPE_VISUAL_QUERY); mLastRestartInstant = Instant.now(); Loading Loading @@ -604,17 +617,20 @@ final class HotwordDetectionConnection { private class ServiceConnectionFactory { private final Intent mIntent; private final int mBindingFlags; private final int mDetectionServiceType; ServiceConnectionFactory(@NonNull Intent intent, boolean bindInstantServiceAllowed) { ServiceConnectionFactory(@NonNull Intent intent, boolean bindInstantServiceAllowed, int detectionServiceType) { mIntent = intent; mBindingFlags = bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0; mDetectionServiceType = detectionServiceType; } ServiceConnection createLocked() { ServiceConnection connection = new ServiceConnection(mContext, mIntent, mBindingFlags, mUser, ISandboxedDetectionService.Stub::asInterface, mRestartCount % MAX_ISOLATED_PROCESS_NUMBER); mRestartCount % MAX_ISOLATED_PROCESS_NUMBER, mDetectionServiceType); connection.connect(); updateAudioFlinger(connection, mAudioFlinger); Loading @@ -635,15 +651,17 @@ final class HotwordDetectionConnection { private boolean mRespectServiceConnectionStatusChanged = true; private boolean mIsBound = false; private boolean mIsLoggedFirstConnect = false; private final int mDetectionServiceType; ServiceConnection(@NonNull Context context, @NonNull Intent serviceIntent, int bindingFlags, int userId, @Nullable Function<IBinder, ISandboxedDetectionService> binderAsInterface, int instanceNumber) { int instanceNumber, int detectionServiceType) { super(context, serviceIntent, bindingFlags, userId, binderAsInterface); this.mIntent = serviceIntent; this.mBindingFlags = bindingFlags; this.mInstanceNumber = instanceNumber; this.mDetectionServiceType = detectionServiceType; } @Override // from ServiceConnector.Impl Loading @@ -660,14 +678,14 @@ final class HotwordDetectionConnection { mIsBound = connected; if (!connected) { if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeDetectorEvent(mDetectorType, HOTWORD_DETECTOR_EVENTS__EVENT__ON_DISCONNECTED, mVoiceInteractionServiceUid); } } else if (!mIsLoggedFirstConnect) { mIsLoggedFirstConnect = true; if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeDetectorEvent(mDetectorType, HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED, mVoiceInteractionServiceUid); Loading @@ -684,7 +702,7 @@ final class HotwordDetectionConnection { @Override public void binderDied() { super.binderDied(); Slog.w(TAG, "binderDied"); Slog.w(TAG, "binderDied mDetectionServiceType = " + mDetectionServiceType); synchronized (mLock) { if (!mRespectServiceConnectionStatusChanged) { Slog.v(TAG, "Ignored #binderDied event"); Loading @@ -693,13 +711,10 @@ final class HotwordDetectionConnection { } //TODO(b265535257): report error to either service only. synchronized (HotwordDetectionConnection.this.mLock) { runForEachDetectorSessionLocked((session) -> { session.reportErrorLocked(DetectorSession.HOTWORD_DETECTION_SERVICE_DIED, "Detection service is dead."); }); runForEachDetectorSessionLocked(this::reportBinderDiedLocked); } // Can improve to log exit reason if needed if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeKeyphraseTriggerEvent( mDetectorType, HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH, Loading @@ -711,7 +726,7 @@ final class HotwordDetectionConnection { protected boolean bindService( @NonNull android.content.ServiceConnection serviceConnection) { try { if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeDetectorEvent(mDetectorType, HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE, mVoiceInteractionServiceUid); Loading @@ -723,7 +738,12 @@ final class HotwordDetectionConnection { mExecutor, serviceConnection); if (!bindResult) { if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { Slog.w(TAG, "bindService failure mDetectionServiceType = " + mDetectionServiceType); synchronized (HotwordDetectionConnection.this.mLock) { runForEachDetectorSessionLocked(this::reportBindServiceFailureLocked); } if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeDetectorEvent(mDetectorType, HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL, mVoiceInteractionServiceUid); Loading @@ -731,7 +751,7 @@ final class HotwordDetectionConnection { } return bindResult; } catch (IllegalArgumentException e) { if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeDetectorEvent(mDetectorType, HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL, mVoiceInteractionServiceUid); Loading @@ -752,6 +772,42 @@ final class HotwordDetectionConnection { mRespectServiceConnectionStatusChanged = false; } } private void reportBinderDiedLocked(DetectorSession detectorSession) { if (mDetectionServiceType == DETECTION_SERVICE_TYPE_HOTWORD && ( detectorSession instanceof DspTrustedHotwordDetectorSession || detectorSession instanceof SoftwareTrustedHotwordDetectorSession)) { detectorSession.reportErrorLocked(new HotwordDetectionServiceFailure( HotwordDetectionServiceFailure.ERROR_CODE_BINDING_DIED, "Detection service is dead.")); } else if (mDetectionServiceType == DETECTION_SERVICE_TYPE_VISUAL_QUERY && detectorSession instanceof VisualQueryDetectorSession) { detectorSession.reportErrorLocked(new VisualQueryDetectionServiceFailure( VisualQueryDetectionServiceFailure.ERROR_CODE_BINDING_DIED, "Detection service is dead.")); } else { detectorSession.reportErrorLocked(new UnknownFailure( "Detection service is dead with unknown detection service type.")); } } private void reportBindServiceFailureLocked(DetectorSession detectorSession) { if (mDetectionServiceType == DETECTION_SERVICE_TYPE_HOTWORD && ( detectorSession instanceof DspTrustedHotwordDetectorSession || detectorSession instanceof SoftwareTrustedHotwordDetectorSession)) { detectorSession.reportErrorLocked(new HotwordDetectionServiceFailure( HotwordDetectionServiceFailure.ERROR_CODE_BIND_FAILURE, "Bind detection service failure.")); } else if (mDetectionServiceType == DETECTION_SERVICE_TYPE_VISUAL_QUERY && detectorSession instanceof VisualQueryDetectorSession) { detectorSession.reportErrorLocked(new VisualQueryDetectionServiceFailure( VisualQueryDetectionServiceFailure.ERROR_CODE_BIND_FAILURE, "Bind detection service failure.")); } else { detectorSession.reportErrorLocked(new UnknownFailure( "Bind detection service failure with unknown detection service type.")); } } } @SuppressWarnings("GuardedBy") Loading Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java +3 −4 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.SharedMemory; import android.service.voice.DetectorFailure; import android.service.voice.HotwordDetectedResult; import android.service.voice.HotwordDetectionService; import android.service.voice.HotwordDetectionServiceFailure; Loading Loading @@ -623,11 +624,9 @@ abstract class DetectorSession { mRemoteDetectionService = remoteDetectionService; } void reportErrorLocked(int errorCode, @NonNull String errorMessage) { void reportErrorLocked(@NonNull DetectorFailure detectorFailure) { try { // TODO: Use instanceof(this) to get different detector to set the right error source. mCallback.onDetectionFailure( new HotwordDetectionServiceFailure(errorCode, errorMessage)); mCallback.onDetectionFailure(detectorFailure); } catch (RemoteException e) { Slog.w(TAG, "Failed to report onError status: " + e); if (getDetectorType() != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +72 −16 Original line number Diff line number Diff line Loading @@ -51,11 +51,14 @@ import android.os.ServiceManager; import android.os.SharedMemory; import android.provider.DeviceConfig; import android.service.voice.HotwordDetectionService; import android.service.voice.HotwordDetectionServiceFailure; import android.service.voice.HotwordDetector; import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback; import android.service.voice.ISandboxedDetectionService; import android.service.voice.IVisualQueryDetectionVoiceInteractionCallback; import android.service.voice.UnknownFailure; import android.service.voice.VisualQueryDetectionService; import android.service.voice.VisualQueryDetectionServiceFailure; import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity; import android.speech.IRecognitionServiceManager; import android.util.Slog; Loading Loading @@ -109,6 +112,16 @@ 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; /** * Indicates the {@link HotwordDetectionService} is created. */ private static final int DETECTION_SERVICE_TYPE_HOTWORD = 1; /** * Indicates the {@link VisualQueryDetectionService} is created. */ private static final int DETECTION_SERVICE_TYPE_VISUAL_QUERY = 2; // TODO: This may need to be a Handler(looper) private final ScheduledExecutorService mScheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); Loading Loading @@ -186,11 +199,11 @@ final class HotwordDetectionConnection { mHotwordDetectionServiceConnectionFactory = new ServiceConnectionFactory(hotwordDetectionServiceIntent, bindInstantServiceAllowed); bindInstantServiceAllowed, DETECTION_SERVICE_TYPE_HOTWORD); mVisualQueryDetectionServiceConnectionFactory = new ServiceConnectionFactory(visualQueryDetectionServiceIntent, bindInstantServiceAllowed); bindInstantServiceAllowed, DETECTION_SERVICE_TYPE_VISUAL_QUERY); mLastRestartInstant = Instant.now(); Loading Loading @@ -604,17 +617,20 @@ final class HotwordDetectionConnection { private class ServiceConnectionFactory { private final Intent mIntent; private final int mBindingFlags; private final int mDetectionServiceType; ServiceConnectionFactory(@NonNull Intent intent, boolean bindInstantServiceAllowed) { ServiceConnectionFactory(@NonNull Intent intent, boolean bindInstantServiceAllowed, int detectionServiceType) { mIntent = intent; mBindingFlags = bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0; mDetectionServiceType = detectionServiceType; } ServiceConnection createLocked() { ServiceConnection connection = new ServiceConnection(mContext, mIntent, mBindingFlags, mUser, ISandboxedDetectionService.Stub::asInterface, mRestartCount % MAX_ISOLATED_PROCESS_NUMBER); mRestartCount % MAX_ISOLATED_PROCESS_NUMBER, mDetectionServiceType); connection.connect(); updateAudioFlinger(connection, mAudioFlinger); Loading @@ -635,15 +651,17 @@ final class HotwordDetectionConnection { private boolean mRespectServiceConnectionStatusChanged = true; private boolean mIsBound = false; private boolean mIsLoggedFirstConnect = false; private final int mDetectionServiceType; ServiceConnection(@NonNull Context context, @NonNull Intent serviceIntent, int bindingFlags, int userId, @Nullable Function<IBinder, ISandboxedDetectionService> binderAsInterface, int instanceNumber) { int instanceNumber, int detectionServiceType) { super(context, serviceIntent, bindingFlags, userId, binderAsInterface); this.mIntent = serviceIntent; this.mBindingFlags = bindingFlags; this.mInstanceNumber = instanceNumber; this.mDetectionServiceType = detectionServiceType; } @Override // from ServiceConnector.Impl Loading @@ -660,14 +678,14 @@ final class HotwordDetectionConnection { mIsBound = connected; if (!connected) { if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeDetectorEvent(mDetectorType, HOTWORD_DETECTOR_EVENTS__EVENT__ON_DISCONNECTED, mVoiceInteractionServiceUid); } } else if (!mIsLoggedFirstConnect) { mIsLoggedFirstConnect = true; if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeDetectorEvent(mDetectorType, HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED, mVoiceInteractionServiceUid); Loading @@ -684,7 +702,7 @@ final class HotwordDetectionConnection { @Override public void binderDied() { super.binderDied(); Slog.w(TAG, "binderDied"); Slog.w(TAG, "binderDied mDetectionServiceType = " + mDetectionServiceType); synchronized (mLock) { if (!mRespectServiceConnectionStatusChanged) { Slog.v(TAG, "Ignored #binderDied event"); Loading @@ -693,13 +711,10 @@ final class HotwordDetectionConnection { } //TODO(b265535257): report error to either service only. synchronized (HotwordDetectionConnection.this.mLock) { runForEachDetectorSessionLocked((session) -> { session.reportErrorLocked(DetectorSession.HOTWORD_DETECTION_SERVICE_DIED, "Detection service is dead."); }); runForEachDetectorSessionLocked(this::reportBinderDiedLocked); } // Can improve to log exit reason if needed if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeKeyphraseTriggerEvent( mDetectorType, HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH, Loading @@ -711,7 +726,7 @@ final class HotwordDetectionConnection { protected boolean bindService( @NonNull android.content.ServiceConnection serviceConnection) { try { if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeDetectorEvent(mDetectorType, HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE, mVoiceInteractionServiceUid); Loading @@ -723,7 +738,12 @@ final class HotwordDetectionConnection { mExecutor, serviceConnection); if (!bindResult) { if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { Slog.w(TAG, "bindService failure mDetectionServiceType = " + mDetectionServiceType); synchronized (HotwordDetectionConnection.this.mLock) { runForEachDetectorSessionLocked(this::reportBindServiceFailureLocked); } if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeDetectorEvent(mDetectorType, HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL, mVoiceInteractionServiceUid); Loading @@ -731,7 +751,7 @@ final class HotwordDetectionConnection { } return bindResult; } catch (IllegalArgumentException e) { if (mDetectorType != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) { if (mDetectionServiceType != DETECTION_SERVICE_TYPE_VISUAL_QUERY) { HotwordMetricsLogger.writeDetectorEvent(mDetectorType, HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL, mVoiceInteractionServiceUid); Loading @@ -752,6 +772,42 @@ final class HotwordDetectionConnection { mRespectServiceConnectionStatusChanged = false; } } private void reportBinderDiedLocked(DetectorSession detectorSession) { if (mDetectionServiceType == DETECTION_SERVICE_TYPE_HOTWORD && ( detectorSession instanceof DspTrustedHotwordDetectorSession || detectorSession instanceof SoftwareTrustedHotwordDetectorSession)) { detectorSession.reportErrorLocked(new HotwordDetectionServiceFailure( HotwordDetectionServiceFailure.ERROR_CODE_BINDING_DIED, "Detection service is dead.")); } else if (mDetectionServiceType == DETECTION_SERVICE_TYPE_VISUAL_QUERY && detectorSession instanceof VisualQueryDetectorSession) { detectorSession.reportErrorLocked(new VisualQueryDetectionServiceFailure( VisualQueryDetectionServiceFailure.ERROR_CODE_BINDING_DIED, "Detection service is dead.")); } else { detectorSession.reportErrorLocked(new UnknownFailure( "Detection service is dead with unknown detection service type.")); } } private void reportBindServiceFailureLocked(DetectorSession detectorSession) { if (mDetectionServiceType == DETECTION_SERVICE_TYPE_HOTWORD && ( detectorSession instanceof DspTrustedHotwordDetectorSession || detectorSession instanceof SoftwareTrustedHotwordDetectorSession)) { detectorSession.reportErrorLocked(new HotwordDetectionServiceFailure( HotwordDetectionServiceFailure.ERROR_CODE_BIND_FAILURE, "Bind detection service failure.")); } else if (mDetectionServiceType == DETECTION_SERVICE_TYPE_VISUAL_QUERY && detectorSession instanceof VisualQueryDetectorSession) { detectorSession.reportErrorLocked(new VisualQueryDetectionServiceFailure( VisualQueryDetectionServiceFailure.ERROR_CODE_BIND_FAILURE, "Bind detection service failure.")); } else { detectorSession.reportErrorLocked(new UnknownFailure( "Bind detection service failure with unknown detection service type.")); } } } @SuppressWarnings("GuardedBy") Loading