From 33694beb374e065f8dfa91c0a5bf50fb089244f6 Mon Sep 17 00:00:00 2001 From: lpeter Date: Tue, 14 Jun 2022 17:25:12 +0800 Subject: [PATCH] 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 (cherry picked from commit 37f8b3ec2b8a11fd07832e024da187d6b0f5fd35) --- .../HotwordDetectionConnection.java | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index 434663bd81672..25db81fa2667c 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -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; @@ -146,6 +153,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 = @@ -382,6 +396,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() @@ -422,14 +440,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; } @@ -449,6 +476,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. } }; @@ -460,6 +490,9 @@ final class HotwordDetectionConnection { null, null, internalCallback)); + HotwordMetricsLogger.writeDetectorEvent(mDetectorType, + HOTWORD_DETECTOR_EVENTS__EVENT__START_SOFTWARE_DETECTION, + mVoiceInteractionServiceUid); } public void startListeningFromExternalSource( @@ -891,6 +924,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); @@ -912,6 +948,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); @@ -922,6 +961,9 @@ final class HotwordDetectionConnection { try { enforcePermissionsForDataDelivery(); } catch (SecurityException e) { + HotwordMetricsLogger.writeDetectorEvent(mDetectorType, + METRICS_EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION, + mVoiceInteractionServiceUid); callback.onError(); return; } @@ -942,6 +984,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 { @@ -1002,7 +1047,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,