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.FrameworkStatsLog.HOTWORD_EVENT_EGRESS_SIZE__DETECTOR_TYPE__NORMAL_DETECTOR; 38 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_EVENT_EGRESS_SIZE__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP; 39 import static com.android.internal.util.FrameworkStatsLog.HOTWORD_EVENT_EGRESS_SIZE__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE; 40 import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERACTION; 41 42 import android.content.Context; 43 import android.service.voice.HotwordDetector; 44 45 import com.android.internal.util.FrameworkStatsLog; 46 import com.android.internal.util.LatencyTracker; 47 48 /** 49 * A utility class for logging hotword statistics event. 50 */ 51 public final class HotwordMetricsLogger { 52 53 private static final int METRICS_INIT_DETECTOR_SOFTWARE = 54 HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE; 55 private static final int METRICS_INIT_DETECTOR_DSP = 56 HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP; 57 private static final int METRICS_INIT_NORMAL_DETECTOR = 58 HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR; 59 private static final int AUDIO_EGRESS_DSP_DETECTOR = 60 HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP; 61 private static final int AUDIO_EGRESS_SOFTWARE_DETECTOR = 62 HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE; 63 private static final int AUDIO_EGRESS_NORMAL_DETECTOR = 64 HOTWORD_AUDIO_EGRESS_EVENT_REPORTED__DETECTOR_TYPE__NORMAL_DETECTOR; 65 HotwordMetricsLogger()66 private HotwordMetricsLogger() { 67 // Class only contains static utility functions, and should not be instantiated 68 } 69 70 /** 71 * Logs information related to create hotword detector. 72 */ writeDetectorCreateEvent(int detectorType, boolean isCreated, int uid)73 public static void writeDetectorCreateEvent(int detectorType, boolean isCreated, int uid) { 74 int metricsDetectorType = getCreateMetricsDetectorType(detectorType); 75 FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED, 76 metricsDetectorType, isCreated, uid); 77 } 78 79 /** 80 * Logs information related to hotword detection service init result. 81 */ writeServiceInitResultEvent(int detectorType, int result, int uid)82 public static void writeServiceInitResultEvent(int detectorType, int result, int uid) { 83 int metricsDetectorType = getInitMetricsDetectorType(detectorType); 84 FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED, 85 metricsDetectorType, result, uid); 86 } 87 88 /** 89 * Logs information related to hotword detection service restarting. 90 */ writeServiceRestartEvent(int detectorType, int reason, int uid)91 public static void writeServiceRestartEvent(int detectorType, int reason, int uid) { 92 int metricsDetectorType = getRestartMetricsDetectorType(detectorType); 93 FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED, 94 metricsDetectorType, reason, uid); 95 } 96 97 /** 98 * Logs information related to keyphrase trigger. 99 */ writeKeyphraseTriggerEvent(int detectorType, int result, int uid)100 public static void writeKeyphraseTriggerEvent(int detectorType, int result, int uid) { 101 int metricsDetectorType = getKeyphraseMetricsDetectorType(detectorType); 102 FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED, 103 metricsDetectorType, result, uid); 104 } 105 106 /** 107 * Logs information related to hotword detector events. 108 */ writeDetectorEvent(int detectorType, int event, int uid)109 public static void writeDetectorEvent(int detectorType, int event, int uid) { 110 int metricsDetectorType = getDetectorMetricsDetectorType(detectorType); 111 FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS, 112 metricsDetectorType, event, uid); 113 } 114 115 /** 116 * Logs information related to hotword audio egress events. 117 */ writeAudioEgressEvent(int detectorType, int event, int uid, int streamSizeBytes, int bundleSizeBytes, int streamCount)118 public static void writeAudioEgressEvent(int detectorType, int event, int uid, 119 int streamSizeBytes, int bundleSizeBytes, int streamCount) { 120 int metricsDetectorType = getAudioEgressDetectorType(detectorType); 121 FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_AUDIO_EGRESS_EVENT_REPORTED, 122 metricsDetectorType, event, uid, streamSizeBytes, bundleSizeBytes, streamCount); 123 } 124 125 /** 126 * Logs hotword event egress size metrics. 127 */ writeHotwordDataEgressSize(int eventType, long eventSize, int detectorType, int uid)128 public static void writeHotwordDataEgressSize(int eventType, long eventSize, int detectorType, 129 int uid) { 130 int metricsDetectorType = getHotwordEventEgressSizeDetectorType(detectorType); 131 FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_EGRESS_SIZE_ATOM_REPORTED, 132 eventType, eventSize, metricsDetectorType, uid); 133 } 134 135 /** 136 * Starts a {@link LatencyTracker} log for the time it takes to show the 137 * {@link android.service.voice.VoiceInteractionSession} system UI after a voice trigger. 138 * 139 * @see LatencyTracker 140 * 141 * @param tag Extra tag to separate different sessions from each other. 142 */ startHotwordTriggerToUiLatencySession(Context context, String tag)143 public static void startHotwordTriggerToUiLatencySession(Context context, String tag) { 144 LatencyTracker.getInstance(context).onActionStart(ACTION_SHOW_VOICE_INTERACTION, tag); 145 } 146 147 /** 148 * Completes a {@link LatencyTracker} log for the time it takes to show the 149 * {@link android.service.voice.VoiceInteractionSession} system UI after a voice trigger. 150 * 151 * <p>Completing this session will result in logging metric data.</p> 152 * 153 * @see LatencyTracker 154 */ stopHotwordTriggerToUiLatencySession(Context context)155 public static void stopHotwordTriggerToUiLatencySession(Context context) { 156 LatencyTracker.getInstance(context).onActionEnd(ACTION_SHOW_VOICE_INTERACTION); 157 } 158 159 /** 160 * Cancels a {@link LatencyTracker} log for the time it takes to show the 161 * {@link android.service.voice.VoiceInteractionSession} system UI after a voice trigger. 162 * 163 * <p>Cancels typically occur when the VoiceInteraction session UI is shown for reasons outside 164 * of a {@link android.hardware.soundtrigger.SoundTrigger.RecognitionEvent} such as an 165 * invocation from an external source or service.</p> 166 * 167 * <p>Canceling this session will not result in logging metric data. 168 * 169 * @see LatencyTracker 170 */ cancelHotwordTriggerToUiLatencySession(Context context)171 public static void cancelHotwordTriggerToUiLatencySession(Context context) { 172 LatencyTracker.getInstance(context).onActionCancel(ACTION_SHOW_VOICE_INTERACTION); 173 } 174 getCreateMetricsDetectorType(int detectorType)175 private static int getCreateMetricsDetectorType(int detectorType) { 176 switch (detectorType) { 177 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE: 178 return HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE; 179 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP: 180 return HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP; 181 default: 182 return HOTWORD_DETECTOR_CREATE_REQUESTED__DETECTOR_TYPE__NORMAL_DETECTOR; 183 } 184 } 185 getRestartMetricsDetectorType(int detectorType)186 private static int getRestartMetricsDetectorType(int detectorType) { 187 switch (detectorType) { 188 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE: 189 return HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE; 190 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP: 191 return HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP; 192 default: 193 return HOTWORD_DETECTION_SERVICE_RESTARTED__DETECTOR_TYPE__NORMAL_DETECTOR; 194 } 195 } 196 getInitMetricsDetectorType(int detectorType)197 private static int getInitMetricsDetectorType(int detectorType) { 198 switch (detectorType) { 199 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE: 200 return METRICS_INIT_DETECTOR_SOFTWARE; 201 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP: 202 return METRICS_INIT_DETECTOR_DSP; 203 default: 204 return METRICS_INIT_NORMAL_DETECTOR; 205 } 206 } 207 getKeyphraseMetricsDetectorType(int detectorType)208 private static int getKeyphraseMetricsDetectorType(int detectorType) { 209 switch (detectorType) { 210 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE: 211 return HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE; 212 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP: 213 return HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP; 214 default: 215 return HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR; 216 } 217 } 218 getDetectorMetricsDetectorType(int detectorType)219 private static int getDetectorMetricsDetectorType(int detectorType) { 220 switch (detectorType) { 221 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE: 222 return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE; 223 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP: 224 return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP; 225 default: 226 return HOTWORD_DETECTOR_EVENTS__DETECTOR_TYPE__NORMAL_DETECTOR; 227 } 228 } 229 getAudioEgressDetectorType(int detectorType)230 private static int getAudioEgressDetectorType(int detectorType) { 231 switch (detectorType) { 232 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE: 233 return AUDIO_EGRESS_SOFTWARE_DETECTOR; 234 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP: 235 return AUDIO_EGRESS_DSP_DETECTOR; 236 default: 237 return AUDIO_EGRESS_NORMAL_DETECTOR; 238 } 239 } 240 getHotwordEventEgressSizeDetectorType(int detectorType)241 private static int getHotwordEventEgressSizeDetectorType(int detectorType) { 242 switch (detectorType) { 243 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE: 244 return HOTWORD_EVENT_EGRESS_SIZE__DETECTOR_TYPE__TRUSTED_DETECTOR_SOFTWARE; 245 case HotwordDetector.DETECTOR_TYPE_TRUSTED_HOTWORD_DSP: 246 return HOTWORD_EVENT_EGRESS_SIZE__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP; 247 default: 248 return HOTWORD_EVENT_EGRESS_SIZE__DETECTOR_TYPE__NORMAL_DETECTOR; 249 } 250 } 251 } 252