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