• 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 
27 
28 public class AudioServiceEvents {
29 
30     final static class PhoneStateEvent extends AudioEventLogger.Event {
31         static final int MODE_SET = 0;
32         static final int MODE_IN_COMMUNICATION_TIMEOUT = 1;
33 
34         final int mOp;
35         final String mPackage;
36         final int mOwnerPid;
37         final int mRequesterPid;
38         final int mRequestedMode;
39         final int mActualMode;
40 
41         /** used for MODE_SET */
PhoneStateEvent(String callingPackage, int requesterPid, int requestedMode, int ownerPid, int actualMode)42         PhoneStateEvent(String callingPackage, int requesterPid, int requestedMode,
43                         int ownerPid, int actualMode) {
44             mOp = MODE_SET;
45             mPackage = callingPackage;
46             mRequesterPid = requesterPid;
47             mRequestedMode = requestedMode;
48             mOwnerPid = ownerPid;
49             mActualMode = actualMode;
50             logMetricEvent();
51         }
52 
53         /** used for MODE_IN_COMMUNICATION_TIMEOUT */
PhoneStateEvent(String callingPackage, int ownerPid)54         PhoneStateEvent(String callingPackage, int ownerPid) {
55             mOp = MODE_IN_COMMUNICATION_TIMEOUT;
56             mPackage = callingPackage;
57             mOwnerPid = ownerPid;
58             mRequesterPid = 0;
59             mRequestedMode = 0;
60             mActualMode = 0;
61             logMetricEvent();
62         }
63 
64         @Override
eventToString()65         public String eventToString() {
66             switch (mOp) {
67                 case MODE_SET:
68                     return new StringBuilder("setMode(")
69                             .append(AudioSystem.modeToString(mRequestedMode))
70                             .append(") from package=").append(mPackage)
71                             .append(" pid=").append(mRequesterPid)
72                             .append(" selected mode=")
73                             .append(AudioSystem.modeToString(mActualMode))
74                             .append(" by pid=").append(mOwnerPid).toString();
75                 case MODE_IN_COMMUNICATION_TIMEOUT:
76                     return new StringBuilder("mode IN COMMUNICATION timeout")
77                             .append(" for package=").append(mPackage)
78                             .append(" pid=").append(mOwnerPid).toString();
79                 default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
80             }
81         }
82 
83         /**
84          * Audio Analytics unique Id.
85          */
86         private static final String mMetricsId = MediaMetrics.Name.AUDIO_MODE;
87 
logMetricEvent()88         private void logMetricEvent() {
89             switch (mOp) {
90                 case MODE_SET:
91                     new MediaMetrics.Item(mMetricsId)
92                             .set(MediaMetrics.Property.EVENT, "set")
93                             .set(MediaMetrics.Property.REQUESTED_MODE,
94                                     AudioSystem.modeToString(mRequestedMode))
95                             .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mActualMode))
96                             .set(MediaMetrics.Property.CALLING_PACKAGE, mPackage)
97                             .record();
98                     return;
99                 case MODE_IN_COMMUNICATION_TIMEOUT:
100                     new MediaMetrics.Item(mMetricsId)
101                             .set(MediaMetrics.Property.EVENT, "inCommunicationTimeout")
102                             .set(MediaMetrics.Property.CALLING_PACKAGE, mPackage)
103                             .record();
104                     return;
105                 default: return;
106             }
107         }
108     }
109 
110     final static class WiredDevConnectEvent extends AudioEventLogger.Event {
111         final WiredDeviceConnectionState mState;
112 
WiredDevConnectEvent(WiredDeviceConnectionState state)113         WiredDevConnectEvent(WiredDeviceConnectionState state) {
114             mState = state;
115         }
116 
117         @Override
eventToString()118         public String eventToString() {
119             return new StringBuilder("setWiredDeviceConnectionState(")
120                     .append(" type:").append(
121                             Integer.toHexString(mState.mAttributes.getInternalType()))
122                     .append(" state:").append(AudioSystem.deviceStateToString(mState.mState))
123                     .append(" addr:").append(mState.mAttributes.getAddress())
124                     .append(" name:").append(mState.mAttributes.getName())
125                     .append(") from ").append(mState.mCaller).toString();
126         }
127     }
128 
129     final static class ForceUseEvent extends AudioEventLogger.Event {
130         final int mUsage;
131         final int mConfig;
132         final String mReason;
133 
ForceUseEvent(int usage, int config, String reason)134         ForceUseEvent(int usage, int config, String reason) {
135             mUsage = usage;
136             mConfig = config;
137             mReason = reason;
138         }
139 
140         @Override
eventToString()141         public String eventToString() {
142             return new StringBuilder("setForceUse(")
143                     .append(AudioSystem.forceUseUsageToString(mUsage))
144                     .append(", ").append(AudioSystem.forceUseConfigToString(mConfig))
145                     .append(") due to ").append(mReason).toString();
146         }
147     }
148 
149     static final class VolChangedBroadcastEvent extends AudioEventLogger.Event {
150         final int mStreamType;
151         final int mAliasStreamType;
152         final int mIndex;
153 
VolChangedBroadcastEvent(int stream, int alias, int index)154         VolChangedBroadcastEvent(int stream, int alias, int index) {
155             mStreamType = stream;
156             mAliasStreamType = alias;
157             mIndex = index;
158         }
159 
160         @Override
eventToString()161         public String eventToString() {
162             return new StringBuilder("sending VOLUME_CHANGED stream:")
163                     .append(AudioSystem.streamToString(mStreamType))
164                     .append(" index:").append(mIndex)
165                     .append(" alias:").append(AudioSystem.streamToString(mAliasStreamType))
166                     .toString();
167         }
168     }
169 
170     static final class DeviceVolumeEvent extends AudioEventLogger.Event {
171         final int mStream;
172         final int mVolIndex;
173         final String mDeviceNativeType;
174         final String mDeviceAddress;
175         final String mCaller;
176         final int mDeviceForStream;
177         final boolean mSkipped;
178 
DeviceVolumeEvent(int streamType, int index, @NonNull AudioDeviceAttributes device, int deviceForStream, String callingPackage, boolean skipped)179         DeviceVolumeEvent(int streamType, int index, @NonNull AudioDeviceAttributes device,
180                 int deviceForStream, String callingPackage, boolean skipped) {
181             mStream = streamType;
182             mVolIndex = index;
183             mDeviceNativeType = "0x" + Integer.toHexString(device.getInternalType());
184             mDeviceAddress = device.getAddress();
185             mDeviceForStream = deviceForStream;
186             mCaller = callingPackage;
187             mSkipped = skipped;
188             // log metrics
189             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME_EVENT)
190                     .set(MediaMetrics.Property.EVENT, "setDeviceVolume")
191                     .set(MediaMetrics.Property.STREAM_TYPE,
192                             AudioSystem.streamToString(mStream))
193                     .set(MediaMetrics.Property.INDEX, mVolIndex)
194                     .set(MediaMetrics.Property.DEVICE, mDeviceNativeType)
195                     .set(MediaMetrics.Property.ADDRESS, mDeviceAddress)
196                     .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
197                     .record();
198         }
199 
200         @Override
eventToString()201         public String eventToString() {
202             final StringBuilder sb = new StringBuilder("setDeviceVolume(stream:")
203                     .append(AudioSystem.streamToString(mStream))
204                     .append(" index:").append(mVolIndex)
205                     .append(" device:").append(mDeviceNativeType)
206                     .append(" addr:").append(mDeviceAddress)
207                     .append(") from ").append(mCaller);
208             if (mSkipped) {
209                 sb.append(" skipped [device in use]");
210             } else {
211                 sb.append(" currDevForStream:Ox").append(Integer.toHexString(mDeviceForStream));
212             }
213             return sb.toString();
214         }
215     }
216 
217     final static class VolumeEvent extends AudioEventLogger.Event {
218         static final int VOL_ADJUST_SUGG_VOL = 0;
219         static final int VOL_ADJUST_STREAM_VOL = 1;
220         static final int VOL_SET_STREAM_VOL = 2;
221         static final int VOL_SET_HEARING_AID_VOL = 3;
222         static final int VOL_SET_AVRCP_VOL = 4;
223         static final int VOL_ADJUST_VOL_UID = 5;
224         static final int VOL_VOICE_ACTIVITY_HEARING_AID = 6;
225         static final int VOL_MODE_CHANGE_HEARING_AID = 7;
226         static final int VOL_SET_GROUP_VOL = 8;
227         static final int VOL_MUTE_STREAM_INT = 9;
228         static final int VOL_SET_LE_AUDIO_VOL = 10;
229         static final int VOL_ADJUST_GROUP_VOL = 11;
230 
231         final int mOp;
232         final int mStream;
233         final int mVal1;
234         final int mVal2;
235         final String mCaller;
236         final String mGroupName;
237 
238         /** used for VOL_ADJUST_VOL_UID,
239          *           VOL_ADJUST_SUGG_VOL,
240          *           VOL_ADJUST_STREAM_VOL,
241          *           VOL_SET_STREAM_VOL */
VolumeEvent(int op, int stream, int val1, int val2, String caller)242         VolumeEvent(int op, int stream, int val1, int val2, String caller) {
243             mOp = op;
244             mStream = stream;
245             mVal1 = val1;
246             mVal2 = val2;
247             mCaller = caller;
248             mGroupName = null;
249             logMetricEvent();
250         }
251 
252         /** used for VOL_SET_HEARING_AID_VOL*/
VolumeEvent(int op, int index, int gainDb)253         VolumeEvent(int op, int index, int gainDb) {
254             mOp = op;
255             mVal1 = index;
256             mVal2 = gainDb;
257             // unused
258             mStream = -1;
259             mCaller = null;
260             mGroupName = null;
261             logMetricEvent();
262         }
263 
264         /** used for VOL_SET_AVRCP_VOL */
VolumeEvent(int op, int index)265         VolumeEvent(int op, int index) {
266             mOp = op;
267             mVal1 = index;
268             // unused
269             mVal2 = 0;
270             mStream = -1;
271             mCaller = null;
272             mGroupName = null;
273             logMetricEvent();
274         }
275 
276         /** used for VOL_VOICE_ACTIVITY_HEARING_AID */
VolumeEvent(int op, boolean voiceActive, int stream, int index)277         VolumeEvent(int op, boolean voiceActive, int stream, int index) {
278             mOp = op;
279             mStream = stream;
280             mVal1 = index;
281             mVal2 = voiceActive ? 1 : 0;
282             // unused
283             mCaller = null;
284             mGroupName = null;
285             logMetricEvent();
286         }
287 
288         /** used for VOL_MODE_CHANGE_HEARING_AID */
VolumeEvent(int op, int mode, int stream, int index)289         VolumeEvent(int op, int mode, int stream, int index) {
290             mOp = op;
291             mStream = stream;
292             mVal1 = index;
293             mVal2 = mode;
294             // unused
295             mCaller = null;
296             mGroupName = null;
297             logMetricEvent();
298         }
299 
300         /** used for VOL_SET_GROUP_VOL,
301          *           VOL_ADJUST_GROUP_VOL */
VolumeEvent(int op, String group, int index, int flags, String caller)302         VolumeEvent(int op, String group, int index, int flags, String caller) {
303             mOp = op;
304             mStream = -1;
305             mVal1 = index;
306             mVal2 = flags;
307             mCaller = caller;
308             mGroupName = group;
309             logMetricEvent();
310         }
311 
312         /** used for VOL_MUTE_STREAM_INT */
VolumeEvent(int op, int stream, boolean state)313         VolumeEvent(int op, int stream, boolean state) {
314             mOp = op;
315             mStream = stream;
316             mVal1 = state ? 1 : 0;
317             mVal2 = 0;
318             mCaller = null;
319             mGroupName = null;
320             logMetricEvent();
321         }
322 
323 
324         /**
325          * Audio Analytics unique Id.
326          */
327         private static final String mMetricsId = MediaMetrics.Name.AUDIO_VOLUME_EVENT;
328 
329         /**
330          * Log mediametrics event
331          */
logMetricEvent()332         private void logMetricEvent() {
333             switch (mOp) {
334                 case VOL_ADJUST_SUGG_VOL:
335                 case VOL_ADJUST_VOL_UID:
336                 case VOL_ADJUST_STREAM_VOL: {
337                     String eventName;
338                     switch (mOp) {
339                         case VOL_ADJUST_SUGG_VOL:
340                             eventName = "adjustSuggestedStreamVolume";
341                             break;
342                         case VOL_ADJUST_STREAM_VOL:
343                             eventName = "adjustStreamVolume";
344                             break;
345                         case VOL_ADJUST_VOL_UID:
346                             eventName = "adjustStreamVolumeForUid";
347                             break;
348                         default:
349                             return; // not possible, just return here
350                     }
351                     new MediaMetrics.Item(mMetricsId)
352                             .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
353                             .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down")
354                             .set(MediaMetrics.Property.EVENT, eventName)
355                             .set(MediaMetrics.Property.FLAGS, mVal2)
356                             .set(MediaMetrics.Property.STREAM_TYPE,
357                                     AudioSystem.streamToString(mStream))
358                             .record();
359                     return;
360                 }
361                 case VOL_ADJUST_GROUP_VOL:
362                     new MediaMetrics.Item(mMetricsId)
363                             .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
364                             .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down")
365                             .set(MediaMetrics.Property.EVENT, "adjustVolumeGroupVolume")
366                             .set(MediaMetrics.Property.FLAGS, mVal2)
367                             .set(MediaMetrics.Property.GROUP, mGroupName)
368                             .record();
369                     return;
370                 case VOL_SET_STREAM_VOL:
371                     new MediaMetrics.Item(mMetricsId)
372                             .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
373                             .set(MediaMetrics.Property.EVENT, "setStreamVolume")
374                             .set(MediaMetrics.Property.FLAGS, mVal2)
375                             .set(MediaMetrics.Property.INDEX, mVal1)
376                             .set(MediaMetrics.Property.STREAM_TYPE,
377                                     AudioSystem.streamToString(mStream))
378                             .record();
379                     return;
380                 case VOL_SET_HEARING_AID_VOL:
381                     new MediaMetrics.Item(mMetricsId)
382                             .set(MediaMetrics.Property.EVENT, "setHearingAidVolume")
383                             .set(MediaMetrics.Property.GAIN_DB, (double) mVal2)
384                             .set(MediaMetrics.Property.INDEX, mVal1)
385                             .record();
386                     return;
387                 case VOL_SET_LE_AUDIO_VOL:
388                     new MediaMetrics.Item(mMetricsId)
389                             .set(MediaMetrics.Property.EVENT, "setLeAudioVolume")
390                             .set(MediaMetrics.Property.INDEX, mVal1)
391                             .set(MediaMetrics.Property.MAX_INDEX, mVal2)
392                             .record();
393                     return;
394                 case VOL_SET_AVRCP_VOL:
395                     new MediaMetrics.Item(mMetricsId)
396                             .set(MediaMetrics.Property.EVENT, "setAvrcpVolume")
397                             .set(MediaMetrics.Property.INDEX, mVal1)
398                             .record();
399                     return;
400                 case VOL_VOICE_ACTIVITY_HEARING_AID:
401                     new MediaMetrics.Item(mMetricsId)
402                             .set(MediaMetrics.Property.EVENT, "voiceActivityHearingAid")
403                             .set(MediaMetrics.Property.INDEX, mVal1)
404                             .set(MediaMetrics.Property.STATE,
405                                     mVal2 == 1 ? "active" : "inactive")
406                             .set(MediaMetrics.Property.STREAM_TYPE,
407                                     AudioSystem.streamToString(mStream))
408                             .record();
409                     return;
410                 case VOL_MODE_CHANGE_HEARING_AID:
411                     new MediaMetrics.Item(mMetricsId)
412                             .set(MediaMetrics.Property.EVENT, "modeChangeHearingAid")
413                             .set(MediaMetrics.Property.INDEX, mVal1)
414                             .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mVal2))
415                             .set(MediaMetrics.Property.STREAM_TYPE,
416                                     AudioSystem.streamToString(mStream))
417                             .record();
418                     return;
419                 case VOL_SET_GROUP_VOL:
420                     new MediaMetrics.Item(mMetricsId)
421                             .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller)
422                             .set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes")
423                             .set(MediaMetrics.Property.FLAGS, mVal2)
424                             .set(MediaMetrics.Property.GROUP, mGroupName)
425                             .set(MediaMetrics.Property.INDEX, mVal1)
426                             .record();
427                     return;
428                 case VOL_MUTE_STREAM_INT:
429                     // No value in logging metrics for this internal event
430                     return;
431                 default:
432                     return;
433             }
434         }
435 
436         @Override
eventToString()437         public String eventToString() {
438             switch (mOp) {
439                 case VOL_ADJUST_SUGG_VOL:
440                     return new StringBuilder("adjustSuggestedStreamVolume(sugg:")
441                             .append(AudioSystem.streamToString(mStream))
442                             .append(" dir:").append(AudioManager.adjustToString(mVal1))
443                             .append(" flags:0x").append(Integer.toHexString(mVal2))
444                             .append(") from ").append(mCaller)
445                             .toString();
446                 case VOL_ADJUST_GROUP_VOL:
447                     return new StringBuilder("adjustVolumeGroupVolume(group:")
448                             .append(mGroupName)
449                             .append(" dir:").append(AudioManager.adjustToString(mVal1))
450                             .append(" flags:0x").append(Integer.toHexString(mVal2))
451                             .append(") from ").append(mCaller)
452                             .toString();
453                 case VOL_ADJUST_STREAM_VOL:
454                     return new StringBuilder("adjustStreamVolume(stream:")
455                             .append(AudioSystem.streamToString(mStream))
456                             .append(" dir:").append(AudioManager.adjustToString(mVal1))
457                             .append(" flags:0x").append(Integer.toHexString(mVal2))
458                             .append(") from ").append(mCaller)
459                             .toString();
460                 case VOL_SET_STREAM_VOL:
461                     return new StringBuilder("setStreamVolume(stream:")
462                             .append(AudioSystem.streamToString(mStream))
463                             .append(" index:").append(mVal1)
464                             .append(" flags:0x").append(Integer.toHexString(mVal2))
465                             .append(") from ").append(mCaller)
466                             .toString();
467                 case VOL_SET_HEARING_AID_VOL:
468                     return new StringBuilder("setHearingAidVolume:")
469                             .append(" index:").append(mVal1)
470                             .append(" gain dB:").append(mVal2)
471                             .toString();
472                 case VOL_SET_LE_AUDIO_VOL:
473                     return new StringBuilder("setLeAudioVolume:")
474                             .append(" index:").append(mVal1)
475                             .append(" maxIndex:").append(mVal2)
476                             .toString();
477                 case VOL_SET_AVRCP_VOL:
478                     return new StringBuilder("setAvrcpVolume:")
479                             .append(" index:").append(mVal1)
480                             .toString();
481                 case VOL_ADJUST_VOL_UID:
482                     return new StringBuilder("adjustStreamVolumeForUid(stream:")
483                             .append(AudioSystem.streamToString(mStream))
484                             .append(" dir:").append(AudioManager.adjustToString(mVal1))
485                             .append(" flags:0x").append(Integer.toHexString(mVal2))
486                             .append(") from ").append(mCaller)
487                             .toString();
488                 case VOL_VOICE_ACTIVITY_HEARING_AID:
489                     return new StringBuilder("Voice activity change (")
490                             .append(mVal2 == 1 ? "active" : "inactive")
491                             .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
492                             .append(" stream:").append(AudioSystem.streamToString(mStream))
493                             .toString();
494                 case VOL_MODE_CHANGE_HEARING_AID:
495                     return new StringBuilder("setMode(")
496                             .append(AudioSystem.modeToString(mVal2))
497                             .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
498                             .append(" stream:").append(AudioSystem.streamToString(mStream))
499                             .toString();
500                 case VOL_SET_GROUP_VOL:
501                     return new StringBuilder("setVolumeIndexForAttributes(group:")
502                             .append(" group: ").append(mGroupName)
503                             .append(" index:").append(mVal1)
504                             .append(" flags:0x").append(Integer.toHexString(mVal2))
505                             .append(") from ").append(mCaller)
506                             .toString();
507                 case VOL_MUTE_STREAM_INT:
508                     return new StringBuilder("VolumeStreamState.muteInternally(stream:")
509                             .append(AudioSystem.streamToString(mStream))
510                             .append(mVal1 == 1 ? ", muted)" : ", unmuted)")
511                             .toString();
512                 default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
513             }
514         }
515     }
516 }
517