Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51537e59 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Report onFailure when binding detection service failure" into udc-dev

parents d8f11772 8552262a
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -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;
@@ -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) {
+72 −16
Original line number Diff line number Diff line
@@ -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;
@@ -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();
@@ -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();
@@ -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);
@@ -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
@@ -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);
@@ -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");
@@ -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,
@@ -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);
@@ -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);
@@ -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);
@@ -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")