• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.audio;
18 
19 import android.annotation.NonNull;
20 import android.media.AudioDeviceAttributes;
21 import android.media.AudioManager;
22 import android.media.AudioSystem;
23 import android.media.MediaMetrics;
24 
25 import com.android.server.audio.AudioDeviceInventory.WiredDeviceConnectionState;
26 import com.android.server.utils.EventLogger;
27 
28 
29 public class AudioServiceEvents {
30 
31     final static class PhoneStateEvent extends EventLogger.Event {
32         static final int MODE_SET = 0;
33         static final int MODE_IN_COMMUNICATION_TIMEOUT = 1;
34 
35         final int mOp;
36         final String mPackage;
37         final int mOwnerPid;
38         final int mRequesterPid;
39         final int mRequestedMode;
40         final int mActualMode;
41 
42         /** used for MODE_SET */
PhoneStateEvent(String callingPackage, int requesterPid, int requestedMode, int ownerPid, int actualMode)43         PhoneStateEvent(String callingPackage, int requesterPid, int requestedMode,
44                         int ownerPid, int actualMode) {
45             mOp = MODE_SET;
46             mPackage = callingPackage;
47             mRequesterPid = requesterPid;
48             mRequestedMode = requestedMode;
49             mOwnerPid = ownerPid;
50             mActualMode = actualMode;
51             logMetricEvent();
52         }
53 
54         /** used for MODE_IN_COMMUNICATION_TIMEOUT */
PhoneStateEvent(String callingPackage, int ownerPid)55         PhoneStateEvent(String callingPackage, int ownerPid) {
56             mOp = MODE_IN_COMMUNICATION_TIMEOUT;
57             mPackage = callingPackage;
58             mOwnerPid = ownerPid;
59             mRequesterPid = 0;
60             mRequestedMode = 0;
61             mActualMode = 0;
62             logMetricEvent();
63         }
64 
65         @Override
eventToString()66         public String eventToString() {
67             switch (mOp) {
68                 case MODE_SET:
69                     return new StringBuilder("setMode(")
70                             .append(AudioSystem.modeToString(mRequestedMode))
71                             .append(") from package=").append(mPackage)
72                             .append(" pid=").append(mRequesterPid)
73                             .append(" selected mode=")
74                             .append(AudioSystem.modeToString(mActualMode))
75                             .append(" by pid=").append(mOwnerPid).toString();
76                 case MODE_IN_COMMUNICATION_TIMEOUT:
77                     return new StringBuilder("mode IN COMMUNICATION timeout")
78                             .append(" for package=").append(mPackage)
79                             .append(" pid=").append(mOwnerPid).toString();
80                 default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
81             }
82         }
83 
84         /**
85          * Audio Analytics unique Id.
86          */
87         private static final String mMetricsId = MediaMetrics.Name.AUDIO_MODE;
88 
logMetricEvent()89         private void logMetricEvent() {
90             switch (mOp) {
91                 case MODE_SET:
92                     new MediaMetrics.Item(mMetricsId)
93                             .set(MediaMetrics.Property.EVENT, "set")
94                             .set(MediaMetrics.Property.REQUESTED_MODE,
95                                     AudioSystem.modeToString(mRequestedMode))
96                             .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mActualMode))
97                             .set(MediaMetrics.Property.CALLING_PACKAGE, mPackage)
98                             .record();
99                     return;
100                 case MODE_IN_COMMUNICATION_TIMEOUT:
101                     new MediaMetrics.Item(mMetricsId)
102                             .set(MediaMetrics.Property.EVENT, "inCommunicationTimeout")
103                             .set(MediaMetrics.Property.CALLING_PACKAGE, mPackage)
104                             .record();
105                     return;
106                 default: return;
107             }
108         }
109     }
110 
111     final static class WiredDevConnectEvent extends EventLogger.Event {
112         final WiredDeviceConnectionState mState;
113 
WiredDevConnectEvent(WiredDeviceConnectionState state)114         WiredDevConnectEvent(WiredDeviceConnectionState state) {
115             mState = state;
116         }
117 
118         @Override
eventToString()119         public String eventToString() {
120             return new StringBuilder("setWiredDeviceConnectionState(")
121                     .append(" type:").append(
122                             Integer.toHexString(mState.mAttributes.getInternalType()))
123                     .append(" (").append(AudioSystem.isInputDevice(
124                             mState.mAttributes.getInternalType()) ? "source" : "sink").append(") ")
125                     .append(" state:").append(AudioSystem.deviceStateToString(mState.mState))
126                     .append(" addr:").append(mState.mAttributes.getAddress())
127                     .append(" name:").append(mState.mAttributes.getName())
128                     .append(") from ").append(mState.mCaller).toString();
129         }
130     }
131 
132     final static class ForceUseEvent extends EventLogger.Event {
133         final int mUsage;
134         final int mConfig;
135         final String mReason;
136 
ForceUseEvent(int usage, int config, String reason)137         ForceUseEvent(int usage, int config, String reason) {
138             mUsage = usage;
139             mConfig = config;
140             mReason = reason;
141         }
142 
143         @Override
eventToString()144         public String eventToString() {
145             return new StringBuilder("setForceUse(")
146                     .append(AudioSystem.forceUseUsageToString(mUsage))
147                     .append(", ").append(AudioSystem.forceUseConfigToString(mConfig))
148                     .append(") due to ").append(mReason).toString();
149         }
150     }
151 
152     static final class VolChangedBroadcastEvent extends EventLogger.Event {
153         final int mStreamType;
154         final String mAliasStreamIndexes;
155         final int mIndex;
156         final int mOldIndex;
157 
VolChangedBroadcastEvent(int stream, String aliasIndexes, int index, int oldIndex)158         VolChangedBroadcastEvent(int stream, String aliasIndexes, int index, int oldIndex) {
159             mStreamType = stream;
160             mAliasStreamIndexes = aliasIndexes;
161             mIndex = index;
162             mOldIndex = oldIndex;
163         }
164 
165         @Override
eventToString()166         public String eventToString() {
167             return new StringBuilder("sending VOLUME_CHANGED stream:")
168                     .append(AudioSystem.streamToString(mStreamType))
169                     .append(" index:").append(mIndex)
170                     .append(" (was:").append(mOldIndex).append(")")
171                     .append(mAliasStreamIndexes)
172                     .toString();
173         }
174     }
175 
176     static final class DeviceVolumeEvent extends EventLogger.Event {
177         final int mStream;
178         final int mVolIndex;
179         final String mDeviceNativeType;
180         final String mDeviceAddress;
181         final String mCaller;
182         final int mDeviceForStream;
183         final boolean mSkipped;
184 
DeviceVolumeEvent(int streamType, int index, @NonNull AudioDeviceAttributes device, int deviceForStream, String callingPackage, boolean skipped)185         DeviceVolumeEvent(int streamType, int index, @NonNull AudioDeviceAttributes device,
186                 int deviceForStream, String callingPackage, boolean skipped) {
187             mStream = streamType;
188             mVolIndex = index;
189             mDeviceNativeType = "0x" + Integer.toHexString(device.getInternalType());
190             mDeviceAddress = device.getAddress();
191             mDeviceForStream = deviceForStream;
192             mCaller = callingPackage;
193             mSkipped = skipped;
194             // log metrics
195             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME_EVENT)
196                     .set(MediaMetrics.Property.EVENT, "setDeviceVolume")
197                     .set(MediaMetrics.Property.STREAM_TYPE,
198                             AudioSystem.streamToString(mStream))
199                     .set(MediaMetrics.Property.INDEX, mVolIndex)
200                     .set(MediaMetrics.Property.DEVICE, mDeviceNativeType)
201                     .set(MediaMetrics.Property.ADDRESS, mDeviceAddress)
202                     .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
203                     .record();
204         }
205 
206         @Override
eventToString()207         public String eventToString() {
208             final StringBuilder sb = new StringBuilder("setDeviceVolume(stream:")
209                     .append(AudioSystem.streamToString(mStream))
210                     .append(" index:").append(mVolIndex)
211                     .append(" device:").append(mDeviceNativeType)
212                     .append(" addr:").append(mDeviceAddress)
213                     .append(") from ").append(mCaller);
214             if (mSkipped) {
215                 sb.append(" skipped [device in use]");
216             } else {
217                 sb.append(" currDevForStream:Ox").append(Integer.toHexString(mDeviceForStream));
218             }
219             return sb.toString();
220         }
221     }
222 
223     final static class VolumeEvent extends EventLogger.Event {
224         static final int VOL_ADJUST_SUGG_VOL = 0;
225         static final int VOL_ADJUST_STREAM_VOL = 1;
226         static final int VOL_SET_STREAM_VOL = 2;
227         static final int VOL_SET_HEARING_AID_VOL = 3;
228         static final int VOL_SET_AVRCP_VOL = 4;
229         static final int VOL_ADJUST_VOL_UID = 5;
230         static final int VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME = 6;
231         static final int VOL_MODE_CHANGE_HEARING_AID = 7;
232         static final int VOL_SET_GROUP_VOL = 8;
233         static final int VOL_MUTE_STREAM_INT = 9;
234         static final int VOL_SET_LE_AUDIO_VOL = 10;
235         static final int VOL_ADJUST_GROUP_VOL = 11;
236         static final int VOL_MASTER_MUTE = 12;
237         static final int VOL_ABS_DEVICE_ENABLED_ERROR = 13;
238 
239         final int mOp;
240         final int mStream;
241         final int mVal1;
242         final int mVal2;
243         final int mVal3;
244         final String mCaller;
245         final String mGroupName;
246 
247         /** used for VOL_SET_STREAM_VOL */
VolumeEvent(int op, int stream, int val1, int val2, int val3, String caller)248         VolumeEvent(int op, int stream, int val1, int val2, int val3, String caller) {
249             mOp = op;
250             mStream = stream;
251             mVal1 = val1;
252             mVal2 = val2;
253             mVal3 = val3;
254             mCaller = caller;
255             // unused
256             mGroupName = null;
257             logMetricEvent();
258         }
259 
260         /** used for VOL_ADJUST_VOL_UID,
261          *           VOL_ADJUST_SUGG_VOL,
262          *           VOL_ADJUST_STREAM_VOL,
263          *           VOL_SET_LE_AUDIO_VOL
264          */
VolumeEvent(int op, int stream, int val1, int val2, String caller)265         VolumeEvent(int op, int stream, int val1, int val2, String caller) {
266             mOp = op;
267             mStream = stream;
268             mVal1 = val1;
269             mVal2 = val2;
270             mCaller = caller;
271             // unused
272             mVal3 = -1;
273             mGroupName = null;
274             logMetricEvent();
275         }
276 
277         /** used for VOL_SET_HEARING_AID_VOL*/
VolumeEvent(int op, int index, int gainDb)278         VolumeEvent(int op, int index, int gainDb) {
279             mOp = op;
280             mVal1 = index;
281             mVal2 = gainDb;
282             // unused
283             mVal3 = -1;
284             mStream = -1;
285             mCaller = null;
286             mGroupName = null;
287             logMetricEvent();
288         }
289 
290         /** used for VOL_SET_AVRCP_VOL */
VolumeEvent(int op, int index)291         VolumeEvent(int op, int index) {
292             mOp = op;
293             mVal1 = index;
294             // unused
295             mVal2 = 0;
296             mVal3 = -1;
297             mStream = -1;
298             mCaller = null;
299             mGroupName = null;
300             logMetricEvent();
301         }
302 
303         /** used for VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME */
VolumeEvent(int op, boolean voiceActive, int stream, int index, int device)304         VolumeEvent(int op, boolean voiceActive, int stream, int index, int device) {
305             mOp = op;
306             mStream = stream;
307             mVal1 = index;
308             mVal2 = voiceActive ? 1 : 0;
309             // unused
310             mVal3 = device;
311             mCaller = null;
312             mGroupName = null;
313             logMetricEvent();
314         }
315 
316         /** used for VOL_MODE_CHANGE_HEARING_AID */
VolumeEvent(int op, int mode, int stream, int index)317         VolumeEvent(int op, int mode, int stream, int index) {
318             mOp = op;
319             mStream = stream;
320             mVal1 = index;
321             mVal2 = mode;
322             // unused
323             mVal3 = -1;
324             mCaller = null;
325             mGroupName = null;
326             logMetricEvent();
327         }
328 
329         /** used for VOL_SET_GROUP_VOL,
330          *           VOL_ADJUST_GROUP_VOL */
VolumeEvent(int op, String group, int index, int flags, String caller)331         VolumeEvent(int op, String group, int index, int flags, String caller) {
332             mOp = op;
333             mStream = -1;
334             mVal1 = index;
335             mVal2 = flags;
336             mCaller = caller;
337             mGroupName = group;
338             // unused
339             mVal3 = -1;
340             logMetricEvent();
341         }
342 
343         /** used for VOL_MUTE_STREAM_INT */
VolumeEvent(int op, int stream, boolean state)344         VolumeEvent(int op, int stream, boolean state) {
345             mOp = op;
346             mStream = stream;
347             mVal1 = state ? 1 : 0;
348             mVal2 = 0;
349             // unused
350             mCaller = null;
351             mGroupName = null;
352             mVal3 = -1;
353             logMetricEvent();
354         }
355 
356         /** used for VOL_MASTER_MUTE */
VolumeEvent(int op, boolean state)357         VolumeEvent(int op, boolean state) {
358             mOp = op;
359             mStream = -1;
360             mVal1 = state ? 1 : 0;
361             mVal2 = 0;
362             // unused
363             mVal3 = -1;
364             mCaller = null;
365             mGroupName = null;
366             logMetricEvent();
367         }
368 
369         /** used for VOL_ABS_DEVICE_ENABLED_ERROR */
VolumeEvent(int op, int result, int device, boolean enabled, int streamType)370         VolumeEvent(int op, int result, int device, boolean enabled, int streamType) {
371             mOp = op;
372             mStream = streamType;
373             mVal1 = device;
374             mVal2 = enabled ? 1 : 0;
375             mVal3 = result;
376             // unused
377             mCaller = null;
378             mGroupName = null;
379             logMetricEvent();
380         }
381 
382 
383         /**
384          * Audio Analytics unique Id.
385          */
386         private static final String mMetricsId = MediaMetrics.Name.AUDIO_VOLUME_EVENT;
387 
388         /**
389          * Log mediametrics event
390          */
logMetricEvent()391         private void logMetricEvent() {
392             switch (mOp) {
393                 case VOL_ADJUST_SUGG_VOL:
394                 case VOL_ADJUST_VOL_UID:
395                 case VOL_ADJUST_STREAM_VOL: {
396                     String eventName;
397                     switch (mOp) {
398                         case VOL_ADJUST_SUGG_VOL:
399                             eventName = "adjustSuggestedStreamVolume";
400                             break;
401                         case VOL_ADJUST_STREAM_VOL:
402                             eventName = "adjustStreamVolume";
403                             break;
404                         case VOL_ADJUST_VOL_UID:
405                             eventName = "adjustStreamVolumeForUid";
406                             break;
407                         default:
408                             return; // not possible, just return here
409                     }
410                     new MediaMetrics.Item(mMetricsId)
411                             .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
412                             .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down")
413                             .set(MediaMetrics.Property.EVENT, eventName)
414                             .set(MediaMetrics.Property.FLAGS, mVal2)
415                             .set(MediaMetrics.Property.STREAM_TYPE,
416                                     AudioSystem.streamToString(mStream))
417                             .record();
418                     return;
419                 }
420                 case VOL_ADJUST_GROUP_VOL:
421                     new MediaMetrics.Item(mMetricsId)
422                             .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
423                             .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down")
424                             .set(MediaMetrics.Property.EVENT, "adjustVolumeGroupVolume")
425                             .set(MediaMetrics.Property.FLAGS, mVal2)
426                             .set(MediaMetrics.Property.GROUP, mGroupName)
427                             .record();
428                     return;
429                 case VOL_SET_STREAM_VOL:
430                     new MediaMetrics.Item(mMetricsId)
431                             .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
432                             .set(MediaMetrics.Property.EVENT, "setStreamVolume")
433                             .set(MediaMetrics.Property.FLAGS, mVal2)
434                             .set(MediaMetrics.Property.INDEX, mVal1)
435                             .set(MediaMetrics.Property.OLD_INDEX, mVal3)
436                             .set(MediaMetrics.Property.STREAM_TYPE,
437                                     AudioSystem.streamToString(mStream))
438                             .record();
439                     return;
440                 case VOL_SET_HEARING_AID_VOL:
441                     new MediaMetrics.Item(mMetricsId)
442                             .set(MediaMetrics.Property.EVENT, "setHearingAidVolume")
443                             .set(MediaMetrics.Property.GAIN_DB, (double) mVal2)
444                             .set(MediaMetrics.Property.INDEX, mVal1)
445                             .record();
446                     return;
447                 case VOL_SET_LE_AUDIO_VOL:
448                     new MediaMetrics.Item(mMetricsId)
449                             .set(MediaMetrics.Property.EVENT, "setLeAudioVolume")
450                             .set(MediaMetrics.Property.INDEX, mVal1)
451                             .set(MediaMetrics.Property.MAX_INDEX, mVal2)
452                             .set(MediaMetrics.Property.STREAM_TYPE,
453                                     AudioSystem.streamToString(mStream))
454                             .record();
455                     return;
456                 case VOL_SET_AVRCP_VOL:
457                     new MediaMetrics.Item(mMetricsId)
458                             .set(MediaMetrics.Property.EVENT, "setAvrcpVolume")
459                             .set(MediaMetrics.Property.INDEX, mVal1)
460                             .record();
461                     return;
462                 case VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME:
463                     new MediaMetrics.Item(mMetricsId)
464                             .set(MediaMetrics.Property.EVENT, "voiceActivityContextualVolume")
465                             .set(MediaMetrics.Property.INDEX, mVal1)
466                             .set(MediaMetrics.Property.STATE,
467                                     mVal2 == 1 ? "active" : "inactive")
468                             .set(MediaMetrics.Property.STREAM_TYPE,
469                                     AudioSystem.streamToString(mStream))
470                             .set(MediaMetrics.Property.DEVICE,
471                                     AudioSystem.getOutputDeviceName(mVal3))
472                             .record();
473                     return;
474                 case VOL_MODE_CHANGE_HEARING_AID:
475                     new MediaMetrics.Item(mMetricsId)
476                             .set(MediaMetrics.Property.EVENT, "modeChangeHearingAid")
477                             .set(MediaMetrics.Property.INDEX, mVal1)
478                             .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mVal2))
479                             .set(MediaMetrics.Property.STREAM_TYPE,
480                                     AudioSystem.streamToString(mStream))
481                             .record();
482                     return;
483                 case VOL_SET_GROUP_VOL:
484                     new MediaMetrics.Item(mMetricsId)
485                             .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
486                             .set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes")
487                             .set(MediaMetrics.Property.FLAGS, mVal2)
488                             .set(MediaMetrics.Property.GROUP, mGroupName)
489                             .set(MediaMetrics.Property.INDEX, mVal1)
490                             .record();
491                     return;
492                 case VOL_MUTE_STREAM_INT:
493                     // No value in logging metrics for this internal event
494                     return;
495                 case VOL_MASTER_MUTE:
496                     // No value in logging metrics for this internal event
497                     return;
498                 case VOL_ABS_DEVICE_ENABLED_ERROR:
499                     // No value in logging metrics for this internal event
500                     return;
501                 default:
502                     return;
503             }
504         }
505 
506         @Override
eventToString()507         public String eventToString() {
508             switch (mOp) {
509                 case VOL_ADJUST_SUGG_VOL:
510                     return new StringBuilder("adjustSuggestedStreamVolume(sugg:")
511                             .append(AudioSystem.streamToString(mStream))
512                             .append(" dir:").append(AudioManager.adjustToString(mVal1))
513                             .append(" flags:0x").append(Integer.toHexString(mVal2))
514                             .append(") from ").append(mCaller)
515                             .toString();
516                 case VOL_ADJUST_GROUP_VOL:
517                     return new StringBuilder("adjustVolumeGroupVolume(group:")
518                             .append(mGroupName)
519                             .append(" dir:").append(AudioManager.adjustToString(mVal1))
520                             .append(" flags:0x").append(Integer.toHexString(mVal2))
521                             .append(") from ").append(mCaller)
522                             .toString();
523                 case VOL_ADJUST_STREAM_VOL:
524                     return new StringBuilder("adjustStreamVolume(stream:")
525                             .append(AudioSystem.streamToString(mStream))
526                             .append(" dir:").append(AudioManager.adjustToString(mVal1))
527                             .append(" flags:0x").append(Integer.toHexString(mVal2))
528                             .append(") from ").append(mCaller)
529                             .toString();
530                 case VOL_SET_STREAM_VOL:
531                     return new StringBuilder("setStreamVolume(stream:")
532                             .append(AudioSystem.streamToString(mStream))
533                             .append(" index:").append(mVal1)
534                             .append(" flags:0x").append(Integer.toHexString(mVal2))
535                             .append(" oldIndex:").append(mVal3)
536                             .append(") from ").append(mCaller)
537                             .toString();
538                 case VOL_SET_HEARING_AID_VOL:
539                     return new StringBuilder("setHearingAidVolume:")
540                             .append(" index:").append(mVal1)
541                             .append(" gain dB:").append(mVal2)
542                             .toString();
543                 case VOL_SET_LE_AUDIO_VOL:
544                     return new StringBuilder("setLeAudioVolume(stream:")
545                             .append(AudioSystem.streamToString(mStream))
546                             .append(" index:").append(mVal1)
547                             .append(" maxIndex:").append(mVal2)
548                             .toString();
549                 case VOL_SET_AVRCP_VOL:
550                     return new StringBuilder("setAvrcpVolume:")
551                             .append(" index:").append(mVal1)
552                             .toString();
553                 case VOL_ADJUST_VOL_UID:
554                     return new StringBuilder("adjustStreamVolumeForUid(stream:")
555                             .append(AudioSystem.streamToString(mStream))
556                             .append(" dir:").append(AudioManager.adjustToString(mVal1))
557                             .append(" flags:0x").append(Integer.toHexString(mVal2))
558                             .append(") from ").append(mCaller)
559                             .toString();
560                 case VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME:
561                     return new StringBuilder("Voice activity change (")
562                             .append(mVal2 == 1 ? "active" : "inactive")
563                             .append(") causes setting volume to idx:").append(mVal1)
564                             .append(" stream:").append(AudioSystem.streamToString(mStream))
565                             .append(" device:").append(AudioSystem.getOutputDeviceName(mVal3))
566                             .toString();
567                 case VOL_MODE_CHANGE_HEARING_AID:
568                     return new StringBuilder("setMode(")
569                             .append(AudioSystem.modeToString(mVal2))
570                             .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
571                             .append(" stream:").append(AudioSystem.streamToString(mStream))
572                             .toString();
573                 case VOL_SET_GROUP_VOL:
574                     return new StringBuilder("setVolumeIndexForAttributes(group:")
575                             .append(" group: ").append(mGroupName)
576                             .append(" index:").append(mVal1)
577                             .append(" flags:0x").append(Integer.toHexString(mVal2))
578                             .append(") from ").append(mCaller)
579                             .toString();
580                 case VOL_MUTE_STREAM_INT:
581                     return new StringBuilder("VolumeStreamState.muteInternally(stream:")
582                             .append(AudioSystem.streamToString(mStream))
583                             .append(mVal1 == 1 ? ", muted)" : ", unmuted)")
584                             .toString();
585                 case VOL_MASTER_MUTE:
586                     return new StringBuilder("Master mute:")
587                             .append(mVal1 == 1 ? " muted)" : " unmuted)")
588                             .toString();
589                 case VOL_ABS_DEVICE_ENABLED_ERROR:
590                     return new StringBuilder("setDeviceAbsoluteVolumeEnabled failed with ")
591                             .append(mVal3)
592                             .append(" for dev: 0x").append(Integer.toHexString(mVal1))
593                             .append(" enabled: ").append(mVal2)
594                             .append(" streamType: ").append(mStream)
595                             .toString();
596                 default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
597             }
598         }
599     }
600 
601     static final class SoundDoseEvent extends EventLogger.Event {
602         static final int MOMENTARY_EXPOSURE = 0;
603         static final int DOSE_UPDATE = 1;
604         static final int DOSE_REPEAT_5X = 2;
605         static final int DOSE_ACCUMULATION_START = 3;
606         static final int LOWER_VOLUME_TO_RS1 = 4;
607         static final int UPDATE_ABS_VOLUME_ATTENUATION = 5;
608 
609         final int mEventType;
610         final float mFloatValue;
611         final long mLongValue;
612 
SoundDoseEvent(int event, float f, long l)613         private SoundDoseEvent(int event, float f, long l) {
614             mEventType = event;
615             mFloatValue = f;
616             mLongValue = l;
617         }
618 
getMomentaryExposureEvent(float mel)619         static SoundDoseEvent getMomentaryExposureEvent(float mel) {
620             return new SoundDoseEvent(MOMENTARY_EXPOSURE, mel, 0 /*ignored*/);
621         }
622 
getDoseUpdateEvent(float csd, long totalDuration)623         static SoundDoseEvent getDoseUpdateEvent(float csd, long totalDuration) {
624             return new SoundDoseEvent(DOSE_UPDATE, csd, totalDuration);
625         }
626 
getDoseRepeat5xEvent()627         static SoundDoseEvent getDoseRepeat5xEvent() {
628             return new SoundDoseEvent(DOSE_REPEAT_5X, 0 /*ignored*/, 0 /*ignored*/);
629         }
630 
getDoseAccumulationStartEvent()631         static SoundDoseEvent getDoseAccumulationStartEvent() {
632             return new SoundDoseEvent(DOSE_ACCUMULATION_START, 0 /*ignored*/, 0 /*ignored*/);
633         }
634 
getLowerVolumeToRs1Event()635         static SoundDoseEvent getLowerVolumeToRs1Event() {
636             return new SoundDoseEvent(LOWER_VOLUME_TO_RS1, 0 /*ignored*/, 0 /*ignored*/);
637         }
638 
getAbsVolumeAttenuationEvent(float attenuation, int device)639         static SoundDoseEvent getAbsVolumeAttenuationEvent(float attenuation, int device) {
640             return new SoundDoseEvent(UPDATE_ABS_VOLUME_ATTENUATION, attenuation, device);
641         }
642 
643         @Override
eventToString()644         public String eventToString() {
645             switch (mEventType) {
646                 case MOMENTARY_EXPOSURE:
647                     return String.format("momentary exposure MEL=%.2f", mFloatValue);
648                 case DOSE_UPDATE:
649                     return String.format(java.util.Locale.US,
650                             "dose update CSD=%.1f%% total duration=%d",
651                             mFloatValue * 100.0f, mLongValue);
652                 case DOSE_REPEAT_5X:
653                     return "CSD reached 500%";
654                 case DOSE_ACCUMULATION_START:
655                     return "CSD accumulating: RS2 entered";
656                 case LOWER_VOLUME_TO_RS1:
657                     return "CSD lowering volume to RS1";
658                 case UPDATE_ABS_VOLUME_ATTENUATION:
659                     return String.format(java.util.Locale.US,
660                             "Updating CSD absolute volume attenuation on device 0x%s with %.2f dB ",
661                             Long.toHexString(mLongValue), mFloatValue);
662             }
663             return new StringBuilder("FIXME invalid event type:").append(mEventType).toString();
664         }
665     }
666 
667     static final class LoudnessEvent extends EventLogger.Event {
668         static final int START_PIID = 0;
669 
670         static final int STOP_PIID = 1;
671 
672         static final int CLIENT_DIED = 2;
673 
674         final int mEventType;
675         final int mIntValue1;
676         final int mIntValue2;
677 
LoudnessEvent(int event, int i1, int i2)678         private LoudnessEvent(int event, int i1, int i2) {
679             mEventType = event;
680             mIntValue1 = i1;
681             mIntValue2 = i2;
682         }
683 
getStartPiid(int piid, int pid)684         static LoudnessEvent getStartPiid(int piid, int pid) {
685             return new LoudnessEvent(START_PIID, piid, pid);
686         }
687 
getStopPiid(int piid, int pid)688         static LoudnessEvent getStopPiid(int piid, int pid) {
689             return new LoudnessEvent(STOP_PIID, piid, pid);
690         }
691 
getClientDied(int pid)692         static LoudnessEvent getClientDied(int pid) {
693             return new LoudnessEvent(CLIENT_DIED, 0 /* ignored */, pid);
694         }
695 
696 
697         @Override
eventToString()698         public String eventToString() {
699             switch (mEventType) {
700                 case START_PIID:
701                     return String.format(
702                             "Start loudness updates for piid %d for client pid %d",
703                             mIntValue1, mIntValue2);
704                 case STOP_PIID:
705                     return String.format(
706                             "Stop loudness updates for piid %d for client pid %d",
707                             mIntValue1, mIntValue2);
708                 case CLIENT_DIED:
709                     return String.format("Loudness client with pid %d died", mIntValue2);
710 
711             }
712             return new StringBuilder("FIXME invalid event type:").append(mEventType).toString();
713         }
714     }
715 
716     /**
717      * Class to log stream type mute/unmute events
718      */
719     static final class StreamMuteEvent extends EventLogger.Event {
720         final int mStreamType;
721         final boolean mMuted;
722         final String mSource;
723 
StreamMuteEvent(int streamType, boolean muted, String source)724         StreamMuteEvent(int streamType, boolean muted, String source) {
725             mStreamType = streamType;
726             mMuted = muted;
727             mSource = source;
728         }
729 
730         @Override
eventToString()731         public String eventToString() {
732             final String streamName =
733                     (mStreamType <= AudioSystem.getNumStreamTypes() && mStreamType >= 0)
734                     ? AudioSystem.STREAM_NAMES[mStreamType]
735                     : ("stream " + mStreamType);
736             return new StringBuilder(streamName)
737                     .append(mMuted ? " muting by " : " unmuting by ")
738                     .append(mSource)
739                     .toString();
740         }
741     }
742 
743     /**
744      * Class to log unmute errors that contradict the ringer/zen mode muted streams
745      */
746     static final class StreamUnmuteErrorEvent extends EventLogger.Event {
747         final int mStreamType;
748         final int mRingerZenMutedStreams;
749 
StreamUnmuteErrorEvent(int streamType, int ringerZenMutedStreams)750         StreamUnmuteErrorEvent(int streamType, int ringerZenMutedStreams) {
751             mStreamType = streamType;
752             mRingerZenMutedStreams = ringerZenMutedStreams;
753         }
754 
755         @Override
eventToString()756         public String eventToString() {
757             final String streamName =
758                     (mStreamType <= AudioSystem.getNumStreamTypes() && mStreamType >= 0)
759                             ? AudioSystem.STREAM_NAMES[mStreamType]
760                             : ("stream " + mStreamType);
761             return new StringBuilder("Invalid call to unmute ")
762                     .append(streamName)
763                     .append(" despite muted streams 0x")
764                     .append(Integer.toHexString(mRingerZenMutedStreams))
765                     .toString();
766         }
767     }
768 
769     static final class RingerZenMutedStreamsEvent extends EventLogger.Event {
770         final int mRingerZenMutedStreams;
771         final String mSource;
772 
RingerZenMutedStreamsEvent(int ringerZenMutedStreams, String source)773         RingerZenMutedStreamsEvent(int ringerZenMutedStreams, String source) {
774             mRingerZenMutedStreams = ringerZenMutedStreams;
775             mSource = source;
776         }
777 
778         @Override
eventToString()779         public String eventToString() {
780             return new StringBuilder("RingerZenMutedStreams 0x")
781                     .append(Integer.toHexString(mRingerZenMutedStreams))
782                     .append(" from ").append(mSource)
783                     .toString();
784         }
785     }
786 }
787