1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.voiceinteraction;
18 
19 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
20 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
21 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
22 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
23 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
24 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
25 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__NORMAL_DETECTOR;
26 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
27 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
28 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__NORMAL_DETECTOR;
29 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
30 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
31 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__NORMAL_DETECTOR;
32 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
33 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
34 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR;
35 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
36 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
37 import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
38 
39 import android.content.Context;
40 import android.service.voice.HotwordDetector;
41 
42 import com.android.internal.util.FrameworkStatsLog;
43 import com.android.internal.util.LatencyTracker;
44 
45 /**
46  * A utility class for logging hotword statistics event.
47  */
48 public final class HotwordMetricsLogger {
49 
50     private static final int METRICS_INIT_DETECTOR_SOFTWARE =
51             HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
52     private static final int METRICS_INIT_DETECTOR_DSP =
53             HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
54     private static final int METRICS_INIT_NORMAL_DETECTOR =
55             HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
56     private static final int AUDIO_EGRESS_DSP_DETECTOR =
57             HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
58     private static final int AUDIO_EGRESS_SOFTWARE_DETECTOR =
59             HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
60     private static final int AUDIO_EGRESS_NORMAL_DETECTOR =
61             HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR;
62 
HotwordMetricsLogger()63     private HotwordMetricsLogger() {
64         // Class only contains static utility functions, and should not be instantiated
65     }
66 
67     /**
68      * Logs information related to create hotword detector.
69      */
writeDetectorCreateEvent(int detectorType, boolean isCreated, int uid)70     public static void writeDetectorCreateEvent(int detectorType, boolean isCreated, int uid) {
71         int metricsDetectorType = getCreateMetricsDetectorType(detectorType);
72         FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED,
73                 metricsDetectorType, isCreated, uid);
74     }
75 
76     /**
77      * Logs information related to hotword detection service init result.
78      */
writeServiceInitResultEvent(int detectorType, int result, int uid)79     public static void writeServiceInitResultEvent(int detectorType, int result, int uid) {
80         int metricsDetectorType = getInitMetricsDetectorType(detectorType);
81         FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED,
82                 metricsDetectorType, result, uid);
83     }
84 
85     /**
86      * Logs information related to hotword detection service restarting.
87      */
writeServiceRestartEvent(int detectorType, int reason, int uid)88     public static void writeServiceRestartEvent(int detectorType, int reason, int uid) {
89         int metricsDetectorType = getRestartMetricsDetectorType(detectorType);
90         FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED,
91                 metricsDetectorType, reason, uid);
92     }
93 
94     /**
95      * Logs information related to keyphrase trigger.
96      */
writeKeyphraseTriggerEvent(int detectorType, int result, int uid)97     public static void writeKeyphraseTriggerEvent(int detectorType, int result, int uid) {
98         int metricsDetectorType = getKeyphraseMetricsDetectorType(detectorType);
99         FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED,
100                 metricsDetectorType, result, uid);
101     }
102 
103     /**
104      * Logs information related to hotword detector events.
105      */
writeDetectorEvent(int detectorType, int event, int uid)106     public static void writeDetectorEvent(int detectorType, int event, int uid) {
107         int metricsDetectorType = getDetectorMetricsDetectorType(detectorType);
108         FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS,
109                 metricsDetectorType, event, uid);
110     }
111 
112     /**
113      * Logs information related to hotword audio egress events.
114      */
writeAudioEgressEvent(int detectorType, int event, int uid, int streamSizeBytes, int bundleSizeBytes, int streamCount)115     public static void writeAudioEgressEvent(int detectorType, int event, int uid,
116             int streamSizeBytes, int bundleSizeBytes, int streamCount) {
117         int metricsDetectorType = getAudioEgressDetectorType(detectorType);
118         FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED,
119                 metricsDetectorType, event, uid, streamSizeBytes, bundleSizeBytes, streamCount);
120     }
121 
122     /**
123      * Starts a {@link LatencyTracker} log for the time it takes to show the
124      * {@link android.service.voice.VoiceInteractionSession} system UI after a voice trigger.
125      *
126      * @see LatencyTracker
127      *
128      * @param tag Extra tag to separate different sessions from each other.
129      */
startHotwordTriggerToUiLatencySession(Context context, String tag)130     public static void startHotwordTriggerToUiLatencySession(Context context, String tag) {
131         LatencyTracker.getInstance(context).onActionStart(ACTION_SHOW_VOICE_INTERACTION, tag);
132     }
133 
134     /**
135      * Completes a {@link LatencyTracker} log for the time it takes to show the
136      * {@link android.service.voice.VoiceInteractionSession} system UI after a voice trigger.
137      *
138      * <p>Completing this session will result in logging metric data.</p>
139      *
140      * @see LatencyTracker
141      */
stopHotwordTriggerToUiLatencySession(Context context)142     public static void stopHotwordTriggerToUiLatencySession(Context context) {
143         LatencyTracker.getInstance(context).onActionEnd(ACTION_SHOW_VOICE_INTERACTION);
144     }
145 
146     /**
147      * Cancels a {@link LatencyTracker} log for the time it takes to show the
148      * {@link android.service.voice.VoiceInteractionSession} system UI after a voice trigger.
149      *
150      * <p>Cancels typically occur when the VoiceInteraction session UI is shown for reasons outside
151      * of a {@link android.hardware.soundtrigger.SoundTrigger.RecognitionEvent} such as an
152      * invocation from an external source or service.</p>
153      *
154      * <p>Canceling this session will not result in logging metric data.
155      *
156      * @see LatencyTracker
157      */
cancelHotwordTriggerToUiLatencySession(Context context)158     public static void cancelHotwordTriggerToUiLatencySession(Context context) {
159         LatencyTracker.getInstance(context).onActionCancel(ACTION_SHOW_VOICE_INTERACTION);
160     }
161 
getCreateMetricsDetectorType(int detectorType)162     private static int getCreateMetricsDetectorType(int detectorType) {
163         switch (detectorType) {
164             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
165                 return HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
166             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
167                 return HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
168             default:
169                 return HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__NORMAL_DETECTOR;
170         }
171     }
172 
getRestartMetricsDetectorType(int detectorType)173     private static int getRestartMetricsDetectorType(int detectorType) {
174         switch (detectorType) {
175             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
176                 return HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
177             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
178                 return HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
179             default:
180                 return HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__NORMAL_DETECTOR;
181         }
182     }
183 
getInitMetricsDetectorType(int detectorType)184     private static int getInitMetricsDetectorType(int detectorType) {
185         switch (detectorType) {
186             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
187                 return METRICS_INIT_DETECTOR_SOFTWARE;
188             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
189                 return METRICS_INIT_DETECTOR_DSP;
190             default:
191                 return METRICS_INIT_NORMAL_DETECTOR;
192         }
193     }
194 
getKeyphraseMetricsDetectorType(int detectorType)195     private static int getKeyphraseMetricsDetectorType(int detectorType) {
196         switch (detectorType) {
197             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
198                 return HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
199             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
200                 return HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
201             default:
202                 return HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR;
203         }
204     }
205 
getDetectorMetricsDetectorType(int detectorType)206     private static int getDetectorMetricsDetectorType(int detectorType) {
207         switch (detectorType) {
208             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
209                 return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE;
210             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
211                 return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP;
212             default:
213                 return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__NORMAL_DETECTOR;
214         }
215     }
216 
getAudioEgressDetectorType(int detectorType)217     private static int getAudioEgressDetectorType(int detectorType) {
218         switch (detectorType) {
219             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE:
220                 return AUDIO_EGRESS_SOFTWARE_DETECTOR;
221             case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP:
222                 return AUDIO_EGRESS_DSP_DETECTOR;
223             default:
224                 return AUDIO_EGRESS_NORMAL_DETECTOR;
225         }
226     }
227 }
228