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.media.AudioAttributes; 20 import android.media.AudioManager; 21 import android.media.AudioSystem; 22 import android.media.MediaMetrics; 23 24 import com.android.server.audio.AudioDeviceInventory.WiredDeviceConnectionState; 25 26 27 public class AudioServiceEvents { 28 29 final static class PhoneStateEvent extends AudioEventLogger.Event { 30 static final int MODE_SET = 0; 31 static final int MODE_IN_COMMUNICATION_TIMEOUT = 1; 32 33 final int mOp; 34 final String mPackage; 35 final int mOwnerPid; 36 final int mRequesterPid; 37 final int mRequestedMode; 38 final int mActualMode; 39 40 /** used for MODE_SET */ PhoneStateEvent(String callingPackage, int requesterPid, int requestedMode, int ownerPid, int actualMode)41 PhoneStateEvent(String callingPackage, int requesterPid, int requestedMode, 42 int ownerPid, int actualMode) { 43 mOp = MODE_SET; 44 mPackage = callingPackage; 45 mRequesterPid = requesterPid; 46 mRequestedMode = requestedMode; 47 mOwnerPid = ownerPid; 48 mActualMode = actualMode; 49 logMetricEvent(); 50 } 51 52 /** used for MODE_IN_COMMUNICATION_TIMEOUT */ PhoneStateEvent(String callingPackage, int ownerPid)53 PhoneStateEvent(String callingPackage, int ownerPid) { 54 mOp = MODE_IN_COMMUNICATION_TIMEOUT; 55 mPackage = callingPackage; 56 mOwnerPid = ownerPid; 57 mRequesterPid = 0; 58 mRequestedMode = 0; 59 mActualMode = 0; 60 logMetricEvent(); 61 } 62 63 @Override eventToString()64 public String eventToString() { 65 switch (mOp) { 66 case MODE_SET: 67 return new StringBuilder("setMode(") 68 .append(AudioSystem.modeToString(mRequestedMode)) 69 .append(") from package=").append(mPackage) 70 .append(" pid=").append(mRequesterPid) 71 .append(" selected mode=") 72 .append(AudioSystem.modeToString(mActualMode)) 73 .append(" by pid=").append(mOwnerPid).toString(); 74 case MODE_IN_COMMUNICATION_TIMEOUT: 75 return new StringBuilder("mode IN COMMUNICATION timeout") 76 .append(" for package=").append(mPackage) 77 .append(" pid=").append(mOwnerPid).toString(); 78 default: return new StringBuilder("FIXME invalid op:").append(mOp).toString(); 79 } 80 } 81 82 /** 83 * Audio Analytics unique Id. 84 */ 85 private static final String mMetricsId = MediaMetrics.Name.AUDIO_MODE; 86 logMetricEvent()87 private void logMetricEvent() { 88 switch (mOp) { 89 case MODE_SET: 90 new MediaMetrics.Item(mMetricsId) 91 .set(MediaMetrics.Property.EVENT, "set") 92 .set(MediaMetrics.Property.REQUESTED_MODE, 93 AudioSystem.modeToString(mRequestedMode)) 94 .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mActualMode)) 95 .set(MediaMetrics.Property.CALLING_PACKAGE, mPackage) 96 .record(); 97 return; 98 case MODE_IN_COMMUNICATION_TIMEOUT: 99 new MediaMetrics.Item(mMetricsId) 100 .set(MediaMetrics.Property.EVENT, "inCommunicationTimeout") 101 .set(MediaMetrics.Property.CALLING_PACKAGE, mPackage) 102 .record(); 103 return; 104 default: return; 105 } 106 } 107 } 108 109 final static class WiredDevConnectEvent extends AudioEventLogger.Event { 110 final WiredDeviceConnectionState mState; 111 WiredDevConnectEvent(WiredDeviceConnectionState state)112 WiredDevConnectEvent(WiredDeviceConnectionState state) { 113 mState = state; 114 } 115 116 @Override eventToString()117 public String eventToString() { 118 return new StringBuilder("setWiredDeviceConnectionState(") 119 .append(" type:").append(Integer.toHexString(mState.mType)) 120 .append(" state:").append(AudioSystem.deviceStateToString(mState.mState)) 121 .append(" addr:").append(mState.mAddress) 122 .append(" name:").append(mState.mName) 123 .append(") from ").append(mState.mCaller).toString(); 124 } 125 } 126 127 final static class ForceUseEvent extends AudioEventLogger.Event { 128 final int mUsage; 129 final int mConfig; 130 final String mReason; 131 ForceUseEvent(int usage, int config, String reason)132 ForceUseEvent(int usage, int config, String reason) { 133 mUsage = usage; 134 mConfig = config; 135 mReason = reason; 136 } 137 138 @Override eventToString()139 public String eventToString() { 140 return new StringBuilder("setForceUse(") 141 .append(AudioSystem.forceUseUsageToString(mUsage)) 142 .append(", ").append(AudioSystem.forceUseConfigToString(mConfig)) 143 .append(") due to ").append(mReason).toString(); 144 } 145 } 146 147 final static class VolumeEvent extends AudioEventLogger.Event { 148 static final int VOL_ADJUST_SUGG_VOL = 0; 149 static final int VOL_ADJUST_STREAM_VOL = 1; 150 static final int VOL_SET_STREAM_VOL = 2; 151 static final int VOL_SET_HEARING_AID_VOL = 3; 152 static final int VOL_SET_AVRCP_VOL = 4; 153 static final int VOL_ADJUST_VOL_UID = 5; 154 static final int VOL_VOICE_ACTIVITY_HEARING_AID = 6; 155 static final int VOL_MODE_CHANGE_HEARING_AID = 7; 156 static final int VOL_SET_GROUP_VOL = 8; 157 static final int VOL_MUTE_STREAM_INT = 9; 158 159 final int mOp; 160 final int mStream; 161 final int mVal1; 162 final int mVal2; 163 final String mCaller; 164 final String mGroupName; 165 final AudioAttributes mAudioAttributes; 166 167 /** used for VOL_ADJUST_VOL_UID, 168 * VOL_ADJUST_SUGG_VOL, 169 * VOL_ADJUST_STREAM_VOL, 170 * VOL_SET_STREAM_VOL */ VolumeEvent(int op, int stream, int val1, int val2, String caller)171 VolumeEvent(int op, int stream, int val1, int val2, String caller) { 172 mOp = op; 173 mStream = stream; 174 mVal1 = val1; 175 mVal2 = val2; 176 mCaller = caller; 177 mGroupName = null; 178 mAudioAttributes = null; 179 logMetricEvent(); 180 } 181 182 /** used for VOL_SET_HEARING_AID_VOL*/ VolumeEvent(int op, int index, int gainDb)183 VolumeEvent(int op, int index, int gainDb) { 184 mOp = op; 185 mVal1 = index; 186 mVal2 = gainDb; 187 // unused 188 mStream = -1; 189 mCaller = null; 190 mGroupName = null; 191 mAudioAttributes = null; 192 logMetricEvent(); 193 } 194 195 /** used for VOL_SET_AVRCP_VOL */ VolumeEvent(int op, int index)196 VolumeEvent(int op, int index) { 197 mOp = op; 198 mVal1 = index; 199 // unused 200 mVal2 = 0; 201 mStream = -1; 202 mCaller = null; 203 mGroupName = null; 204 mAudioAttributes = null; 205 logMetricEvent(); 206 } 207 208 /** used for VOL_VOICE_ACTIVITY_HEARING_AID */ VolumeEvent(int op, boolean voiceActive, int stream, int index)209 VolumeEvent(int op, boolean voiceActive, int stream, int index) { 210 mOp = op; 211 mStream = stream; 212 mVal1 = index; 213 mVal2 = voiceActive ? 1 : 0; 214 // unused 215 mCaller = null; 216 mGroupName = null; 217 mAudioAttributes = null; 218 logMetricEvent(); 219 } 220 221 /** used for VOL_MODE_CHANGE_HEARING_AID */ VolumeEvent(int op, int mode, int stream, int index)222 VolumeEvent(int op, int mode, int stream, int index) { 223 mOp = op; 224 mStream = stream; 225 mVal1 = index; 226 mVal2 = mode; 227 // unused 228 mCaller = null; 229 mGroupName = null; 230 mAudioAttributes = null; 231 logMetricEvent(); 232 } 233 234 /** used for VOL_SET_GROUP_VOL */ VolumeEvent(int op, AudioAttributes aa, String group, int index, int flags, String caller)235 VolumeEvent(int op, AudioAttributes aa, String group, int index, int flags, String caller) { 236 mOp = op; 237 mStream = -1; 238 mVal1 = index; 239 mVal2 = flags; 240 mCaller = caller; 241 mGroupName = group; 242 mAudioAttributes = aa; 243 logMetricEvent(); 244 } 245 246 /** used for VOL_MUTE_STREAM_INT */ VolumeEvent(int op, int stream, boolean state)247 VolumeEvent(int op, int stream, boolean state) { 248 mOp = op; 249 mStream = stream; 250 mVal1 = state ? 1 : 0; 251 mVal2 = 0; 252 mCaller = null; 253 mGroupName = null; 254 mAudioAttributes = null; 255 logMetricEvent(); 256 } 257 258 259 /** 260 * Audio Analytics unique Id. 261 */ 262 private static final String mMetricsId = MediaMetrics.Name.AUDIO_VOLUME_EVENT; 263 264 /** 265 * Log mediametrics event 266 */ logMetricEvent()267 private void logMetricEvent() { 268 switch (mOp) { 269 case VOL_ADJUST_SUGG_VOL: 270 case VOL_ADJUST_VOL_UID: 271 case VOL_ADJUST_STREAM_VOL: { 272 String eventName; 273 switch (mOp) { 274 case VOL_ADJUST_SUGG_VOL: 275 eventName = "adjustSuggestedStreamVolume"; 276 break; 277 case VOL_ADJUST_STREAM_VOL: 278 eventName = "adjustStreamVolume"; 279 break; 280 case VOL_ADJUST_VOL_UID: 281 eventName = "adjustStreamVolumeForUid"; 282 break; 283 default: 284 return; // not possible, just return here 285 } 286 new MediaMetrics.Item(mMetricsId) 287 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 288 .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down") 289 .set(MediaMetrics.Property.EVENT, eventName) 290 .set(MediaMetrics.Property.FLAGS, mVal2) 291 .set(MediaMetrics.Property.STREAM_TYPE, 292 AudioSystem.streamToString(mStream)) 293 .record(); 294 return; 295 } 296 case VOL_SET_STREAM_VOL: 297 new MediaMetrics.Item(mMetricsId) 298 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 299 .set(MediaMetrics.Property.EVENT, "setStreamVolume") 300 .set(MediaMetrics.Property.FLAGS, mVal2) 301 .set(MediaMetrics.Property.INDEX, mVal1) 302 .set(MediaMetrics.Property.STREAM_TYPE, 303 AudioSystem.streamToString(mStream)) 304 .record(); 305 return; 306 case VOL_SET_HEARING_AID_VOL: 307 new MediaMetrics.Item(mMetricsId) 308 .set(MediaMetrics.Property.EVENT, "setHearingAidVolume") 309 .set(MediaMetrics.Property.GAIN_DB, (double) mVal2) 310 .set(MediaMetrics.Property.INDEX, mVal1) 311 .record(); 312 return; 313 case VOL_SET_AVRCP_VOL: 314 new MediaMetrics.Item(mMetricsId) 315 .set(MediaMetrics.Property.EVENT, "setAvrcpVolume") 316 .set(MediaMetrics.Property.INDEX, mVal1) 317 .record(); 318 return; 319 case VOL_VOICE_ACTIVITY_HEARING_AID: 320 new MediaMetrics.Item(mMetricsId) 321 .set(MediaMetrics.Property.EVENT, "voiceActivityHearingAid") 322 .set(MediaMetrics.Property.INDEX, mVal1) 323 .set(MediaMetrics.Property.STATE, 324 mVal2 == 1 ? "active" : "inactive") 325 .set(MediaMetrics.Property.STREAM_TYPE, 326 AudioSystem.streamToString(mStream)) 327 .record(); 328 return; 329 case VOL_MODE_CHANGE_HEARING_AID: 330 new MediaMetrics.Item(mMetricsId) 331 .set(MediaMetrics.Property.EVENT, "modeChangeHearingAid") 332 .set(MediaMetrics.Property.INDEX, mVal1) 333 .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mVal2)) 334 .set(MediaMetrics.Property.STREAM_TYPE, 335 AudioSystem.streamToString(mStream)) 336 .record(); 337 return; 338 case VOL_SET_GROUP_VOL: 339 new MediaMetrics.Item(mMetricsId) 340 .set(MediaMetrics.Property.ATTRIBUTES, mAudioAttributes.toString()) 341 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 342 .set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes") 343 .set(MediaMetrics.Property.FLAGS, mVal2) 344 .set(MediaMetrics.Property.GROUP, mGroupName) 345 .set(MediaMetrics.Property.INDEX, mVal1) 346 .record(); 347 return; 348 case VOL_MUTE_STREAM_INT: 349 // No value in logging metrics for this internal event 350 return; 351 default: 352 return; 353 } 354 } 355 356 @Override eventToString()357 public String eventToString() { 358 switch (mOp) { 359 case VOL_ADJUST_SUGG_VOL: 360 return new StringBuilder("adjustSuggestedStreamVolume(sugg:") 361 .append(AudioSystem.streamToString(mStream)) 362 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 363 .append(" flags:0x").append(Integer.toHexString(mVal2)) 364 .append(") from ").append(mCaller) 365 .toString(); 366 case VOL_ADJUST_STREAM_VOL: 367 return new StringBuilder("adjustStreamVolume(stream:") 368 .append(AudioSystem.streamToString(mStream)) 369 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 370 .append(" flags:0x").append(Integer.toHexString(mVal2)) 371 .append(") from ").append(mCaller) 372 .toString(); 373 case VOL_SET_STREAM_VOL: 374 return new StringBuilder("setStreamVolume(stream:") 375 .append(AudioSystem.streamToString(mStream)) 376 .append(" index:").append(mVal1) 377 .append(" flags:0x").append(Integer.toHexString(mVal2)) 378 .append(") from ").append(mCaller) 379 .toString(); 380 case VOL_SET_HEARING_AID_VOL: 381 return new StringBuilder("setHearingAidVolume:") 382 .append(" index:").append(mVal1) 383 .append(" gain dB:").append(mVal2) 384 .toString(); 385 case VOL_SET_AVRCP_VOL: 386 return new StringBuilder("setAvrcpVolume:") 387 .append(" index:").append(mVal1) 388 .toString(); 389 case VOL_ADJUST_VOL_UID: 390 return new StringBuilder("adjustStreamVolumeForUid(stream:") 391 .append(AudioSystem.streamToString(mStream)) 392 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 393 .append(" flags:0x").append(Integer.toHexString(mVal2)) 394 .append(") from ").append(mCaller) 395 .toString(); 396 case VOL_VOICE_ACTIVITY_HEARING_AID: 397 return new StringBuilder("Voice activity change (") 398 .append(mVal2 == 1 ? "active" : "inactive") 399 .append(") causes setting HEARING_AID volume to idx:").append(mVal1) 400 .append(" stream:").append(AudioSystem.streamToString(mStream)) 401 .toString(); 402 case VOL_MODE_CHANGE_HEARING_AID: 403 return new StringBuilder("setMode(") 404 .append(AudioSystem.modeToString(mVal2)) 405 .append(") causes setting HEARING_AID volume to idx:").append(mVal1) 406 .append(" stream:").append(AudioSystem.streamToString(mStream)) 407 .toString(); 408 case VOL_SET_GROUP_VOL: 409 return new StringBuilder("setVolumeIndexForAttributes(attr:") 410 .append(mAudioAttributes.toString()) 411 .append(" group: ").append(mGroupName) 412 .append(" index:").append(mVal1) 413 .append(" flags:0x").append(Integer.toHexString(mVal2)) 414 .append(") from ").append(mCaller) 415 .toString(); 416 case VOL_MUTE_STREAM_INT: 417 return new StringBuilder("VolumeStreamState.muteInternally(stream:") 418 .append(AudioSystem.streamToString(mStream)) 419 .append(mVal1 == 1 ? ", muted)" : ", unmuted)") 420 .toString(); 421 default: return new StringBuilder("FIXME invalid op:").append(mOp).toString(); 422 } 423 } 424 } 425 } 426