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

Commit 37f8b3ec authored by lpeter's avatar lpeter
Browse files

Add metrics for software and external source detections.

We add more metrics for software detection and
external source detection.

Android Metrics Design Review : eldar/276723226

Verify the metrics logs manually as below:

Step 1: m statsd_testdrive
Step 2: statsd_testdrive 434
Step 3: run the test
Step 4: We can see the log as below after 1 minutes from Step 2.

hotword_detector_events {
    event: EXTERNAL_SOURCE_DETECTED
}

hotword_detector_events {
    event: ON_DISCONNECTED
}

hotword_detector_events {
    event: START_EXTERNAL_SOURCE_DETECTION
}

Bug: 207717787
Bug: 233704035
Test: build pass
Test: manual. The logs are expected after following test steps
Change-Id: Ib268902d63c580cec9cbd65a3816fd5ba003eaff
parent bab5b292
Loading
Loading
Loading
Loading
+51 −1
Original line number Diff line number Diff line
@@ -31,11 +31,18 @@ import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERV
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_UNKNOWN_TIMEOUT;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__AUDIO_SERVICE_DIED;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__REASON__SCHEDULE;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__APP_REQUEST_UPDATE_STATE;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_UPDATE_STATE_AFTER_TIMEOUT;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECTED;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_REJECTED;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__ON_DISCONNECTED;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_BIND_SERVICE_FAIL;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__REQUEST_UPDATE_STATE;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__START_EXTERNAL_SOURCE_DETECTION;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__START_SOFTWARE_DETECTION;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED;
@@ -149,6 +156,13 @@ final class HotwordDetectionConnection {
    private static final int METRICS_KEYPHRASE_TRIGGERED_REJECT_UNEXPECTED_CALLBACK =
            HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECT_UNEXPECTED_CALLBACK;

    private static final int METRICS_EXTERNAL_SOURCE_DETECTED =
            HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECTED;
    private static final int METRICS_EXTERNAL_SOURCE_REJECTED =
            HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_REJECTED;
    private static final int METRICS_EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION =
            HOTWORD_DETECTOR_EVENTS__EVENT__EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION;

    private final Executor mAudioCopyExecutor = Executors.newCachedThreadPool();
    // TODO: This may need to be a Handler(looper)
    private final ScheduledExecutorService mScheduledExecutorService =
@@ -385,6 +399,10 @@ final class HotwordDetectionConnection {
    }

    void updateStateLocked(PersistableBundle options, SharedMemory sharedMemory) {
        HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
                HOTWORD_DETECTOR_EVENTS__EVENT__APP_REQUEST_UPDATE_STATE,
                mVoiceInteractionServiceUid);

        // Prevent doing the init late, so restart is handled equally to a clean process start.
        // TODO(b/191742511): this logic needs a test
        if (!mUpdateStateAfterStartFinished.get()
@@ -425,14 +443,23 @@ final class HotwordDetectionConnection {
                    Slog.d(TAG, "onDetected");
                }
                synchronized (mLock) {
                    HotwordMetricsLogger.writeKeyphraseTriggerEvent(
                            mDetectorType,
                            HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECTED);
                    if (!mPerformingSoftwareHotwordDetection) {
                        Slog.i(TAG, "Hotword detection has already completed");
                        HotwordMetricsLogger.writeKeyphraseTriggerEvent(
                                mDetectorType,
                                METRICS_KEYPHRASE_TRIGGERED_DETECT_UNEXPECTED_CALLBACK);
                        return;
                    }
                    mPerformingSoftwareHotwordDetection = false;
                    try {
                        enforcePermissionsForDataDelivery();
                    } catch (SecurityException e) {
                        HotwordMetricsLogger.writeKeyphraseTriggerEvent(
                                mDetectorType,
                                METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION);
                        mSoftwareCallback.onError();
                        return;
                    }
@@ -452,6 +479,9 @@ final class HotwordDetectionConnection {
                if (DEBUG) {
                    Slog.wtf(TAG, "onRejected");
                }
                HotwordMetricsLogger.writeKeyphraseTriggerEvent(
                        mDetectorType,
                        HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__REJECTED);
                // onRejected isn't allowed here, and we are not expecting it.
            }
        };
@@ -463,6 +493,9 @@ final class HotwordDetectionConnection {
                        null,
                        null,
                        internalCallback));
        HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
                HOTWORD_DETECTOR_EVENTS__EVENT__START_SOFTWARE_DETECTION,
                mVoiceInteractionServiceUid);
    }

    public void startListeningFromExternalSource(
@@ -896,6 +929,9 @@ final class HotwordDetectionConnection {
                                @Override
                                public void onRejected(HotwordRejectedResult result)
                                        throws RemoteException {
                                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
                                            METRICS_EXTERNAL_SOURCE_REJECTED,
                                            mVoiceInteractionServiceUid);
                                    mScheduledExecutorService.schedule(
                                            () -> {
                                                bestEffortClose(serviceAudioSink, audioSource);
@@ -917,6 +953,9 @@ final class HotwordDetectionConnection {
                                @Override
                                public void onDetected(HotwordDetectedResult triggerResult)
                                        throws RemoteException {
                                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
                                            METRICS_EXTERNAL_SOURCE_DETECTED,
                                            mVoiceInteractionServiceUid);
                                    mScheduledExecutorService.schedule(
                                            () -> {
                                                bestEffortClose(serviceAudioSink, audioSource);
@@ -927,6 +966,9 @@ final class HotwordDetectionConnection {
                                    try {
                                        enforcePermissionsForDataDelivery();
                                    } catch (SecurityException e) {
                                        HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
                                                METRICS_EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION,
                                                mVoiceInteractionServiceUid);
                                        callback.onError();
                                        return;
                                    }
@@ -947,6 +989,9 @@ final class HotwordDetectionConnection {
                    // A copy of this has been created and passed to the hotword validator
                    bestEffortClose(serviceAudioSource);
                });
        HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
                HOTWORD_DETECTOR_EVENTS__EVENT__START_EXTERNAL_SOURCE_DETECTION,
                mVoiceInteractionServiceUid);
    }

    private class ServiceConnectionFactory {
@@ -1008,7 +1053,12 @@ final class HotwordDetectionConnection {
                    return;
                }
                mIsBound = connected;
                if (connected && !mIsLoggedFirstConnect) {

                if (!connected) {
                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
                            HOTWORD_DETECTOR_EVENTS__EVENT__ON_DISCONNECTED,
                            mVoiceInteractionServiceUid);
                } else if (!mIsLoggedFirstConnect) {
                    mIsLoggedFirstConnect = true;
                    HotwordMetricsLogger.writeDetectorEvent(mDetectorType,
                            HOTWORD_DETECTOR_EVENTS__EVENT__ON_CONNECTED,