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