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_HEARING_AID = 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 238 final int mOp; 239 final int mStream; 240 final int mVal1; 241 final int mVal2; 242 final int mVal3; 243 final String mCaller; 244 final String mGroupName; 245 246 /** used for VOL_SET_STREAM_VOL */ VolumeEvent(int op, int stream, int val1, int val2, int val3, String caller)247 VolumeEvent(int op, int stream, int val1, int val2, int val3, String caller) { 248 mOp = op; 249 mStream = stream; 250 mVal1 = val1; 251 mVal2 = val2; 252 mVal3 = val3; 253 mCaller = caller; 254 // unused 255 mGroupName = null; 256 logMetricEvent(); 257 } 258 259 /** used for VOL_ADJUST_VOL_UID, 260 * VOL_ADJUST_SUGG_VOL, 261 * VOL_ADJUST_STREAM_VOL, 262 * VOL_SET_LE_AUDIO_VOL 263 */ VolumeEvent(int op, int stream, int val1, int val2, String caller)264 VolumeEvent(int op, int stream, int val1, int val2, String caller) { 265 mOp = op; 266 mStream = stream; 267 mVal1 = val1; 268 mVal2 = val2; 269 mCaller = caller; 270 // unused 271 mVal3 = -1; 272 mGroupName = null; 273 logMetricEvent(); 274 } 275 276 /** used for VOL_SET_HEARING_AID_VOL*/ VolumeEvent(int op, int index, int gainDb)277 VolumeEvent(int op, int index, int gainDb) { 278 mOp = op; 279 mVal1 = index; 280 mVal2 = gainDb; 281 // unused 282 mVal3 = -1; 283 mStream = -1; 284 mCaller = null; 285 mGroupName = null; 286 logMetricEvent(); 287 } 288 289 /** used for VOL_SET_AVRCP_VOL */ VolumeEvent(int op, int index)290 VolumeEvent(int op, int index) { 291 mOp = op; 292 mVal1 = index; 293 // unused 294 mVal2 = 0; 295 mVal3 = -1; 296 mStream = -1; 297 mCaller = null; 298 mGroupName = null; 299 logMetricEvent(); 300 } 301 302 /** used for VOL_VOICE_ACTIVITY_HEARING_AID */ VolumeEvent(int op, boolean voiceActive, int stream, int index)303 VolumeEvent(int op, boolean voiceActive, int stream, int index) { 304 mOp = op; 305 mStream = stream; 306 mVal1 = index; 307 mVal2 = voiceActive ? 1 : 0; 308 // unused 309 mVal3 = -1; 310 mCaller = null; 311 mGroupName = null; 312 logMetricEvent(); 313 } 314 315 /** used for VOL_MODE_CHANGE_HEARING_AID */ VolumeEvent(int op, int mode, int stream, int index)316 VolumeEvent(int op, int mode, int stream, int index) { 317 mOp = op; 318 mStream = stream; 319 mVal1 = index; 320 mVal2 = mode; 321 // unused 322 mVal3 = -1; 323 mCaller = null; 324 mGroupName = null; 325 logMetricEvent(); 326 } 327 328 /** used for VOL_SET_GROUP_VOL, 329 * VOL_ADJUST_GROUP_VOL */ VolumeEvent(int op, String group, int index, int flags, String caller)330 VolumeEvent(int op, String group, int index, int flags, String caller) { 331 mOp = op; 332 mStream = -1; 333 mVal1 = index; 334 mVal2 = flags; 335 mCaller = caller; 336 mGroupName = group; 337 // unused 338 mVal3 = -1; 339 logMetricEvent(); 340 } 341 342 /** used for VOL_MUTE_STREAM_INT */ VolumeEvent(int op, int stream, boolean state)343 VolumeEvent(int op, int stream, boolean state) { 344 mOp = op; 345 mStream = stream; 346 mVal1 = state ? 1 : 0; 347 mVal2 = 0; 348 // unused 349 mCaller = null; 350 mGroupName = null; 351 mVal3 = -1; 352 logMetricEvent(); 353 } 354 355 /** used for VOL_MASTER_MUTE */ VolumeEvent(int op, boolean state)356 VolumeEvent(int op, boolean state) { 357 mOp = op; 358 mStream = -1; 359 mVal1 = state ? 1 : 0; 360 mVal2 = 0; 361 // unused 362 mVal3 = -1; 363 mCaller = null; 364 mGroupName = null; 365 logMetricEvent(); 366 } 367 368 369 /** 370 * Audio Analytics unique Id. 371 */ 372 private static final String mMetricsId = MediaMetrics.Name.AUDIO_VOLUME_EVENT; 373 374 /** 375 * Log mediametrics event 376 */ logMetricEvent()377 private void logMetricEvent() { 378 switch (mOp) { 379 case VOL_ADJUST_SUGG_VOL: 380 case VOL_ADJUST_VOL_UID: 381 case VOL_ADJUST_STREAM_VOL: { 382 String eventName; 383 switch (mOp) { 384 case VOL_ADJUST_SUGG_VOL: 385 eventName = "adjustSuggestedStreamVolume"; 386 break; 387 case VOL_ADJUST_STREAM_VOL: 388 eventName = "adjustStreamVolume"; 389 break; 390 case VOL_ADJUST_VOL_UID: 391 eventName = "adjustStreamVolumeForUid"; 392 break; 393 default: 394 return; // not possible, just return here 395 } 396 new MediaMetrics.Item(mMetricsId) 397 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 398 .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down") 399 .set(MediaMetrics.Property.EVENT, eventName) 400 .set(MediaMetrics.Property.FLAGS, mVal2) 401 .set(MediaMetrics.Property.STREAM_TYPE, 402 AudioSystem.streamToString(mStream)) 403 .record(); 404 return; 405 } 406 case VOL_ADJUST_GROUP_VOL: 407 new MediaMetrics.Item(mMetricsId) 408 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 409 .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down") 410 .set(MediaMetrics.Property.EVENT, "adjustVolumeGroupVolume") 411 .set(MediaMetrics.Property.FLAGS, mVal2) 412 .set(MediaMetrics.Property.GROUP, mGroupName) 413 .record(); 414 return; 415 case VOL_SET_STREAM_VOL: 416 new MediaMetrics.Item(mMetricsId) 417 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 418 .set(MediaMetrics.Property.EVENT, "setStreamVolume") 419 .set(MediaMetrics.Property.FLAGS, mVal2) 420 .set(MediaMetrics.Property.INDEX, mVal1) 421 .set(MediaMetrics.Property.OLD_INDEX, mVal3) 422 .set(MediaMetrics.Property.STREAM_TYPE, 423 AudioSystem.streamToString(mStream)) 424 .record(); 425 return; 426 case VOL_SET_HEARING_AID_VOL: 427 new MediaMetrics.Item(mMetricsId) 428 .set(MediaMetrics.Property.EVENT, "setHearingAidVolume") 429 .set(MediaMetrics.Property.GAIN_DB, (double) mVal2) 430 .set(MediaMetrics.Property.INDEX, mVal1) 431 .record(); 432 return; 433 case VOL_SET_LE_AUDIO_VOL: 434 new MediaMetrics.Item(mMetricsId) 435 .set(MediaMetrics.Property.EVENT, "setLeAudioVolume") 436 .set(MediaMetrics.Property.INDEX, mVal1) 437 .set(MediaMetrics.Property.MAX_INDEX, mVal2) 438 .set(MediaMetrics.Property.STREAM_TYPE, 439 AudioSystem.streamToString(mStream)) 440 .record(); 441 return; 442 case VOL_SET_AVRCP_VOL: 443 new MediaMetrics.Item(mMetricsId) 444 .set(MediaMetrics.Property.EVENT, "setAvrcpVolume") 445 .set(MediaMetrics.Property.INDEX, mVal1) 446 .record(); 447 return; 448 case VOL_VOICE_ACTIVITY_HEARING_AID: 449 new MediaMetrics.Item(mMetricsId) 450 .set(MediaMetrics.Property.EVENT, "voiceActivityHearingAid") 451 .set(MediaMetrics.Property.INDEX, mVal1) 452 .set(MediaMetrics.Property.STATE, 453 mVal2 == 1 ? "active" : "inactive") 454 .set(MediaMetrics.Property.STREAM_TYPE, 455 AudioSystem.streamToString(mStream)) 456 .record(); 457 return; 458 case VOL_MODE_CHANGE_HEARING_AID: 459 new MediaMetrics.Item(mMetricsId) 460 .set(MediaMetrics.Property.EVENT, "modeChangeHearingAid") 461 .set(MediaMetrics.Property.INDEX, mVal1) 462 .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mVal2)) 463 .set(MediaMetrics.Property.STREAM_TYPE, 464 AudioSystem.streamToString(mStream)) 465 .record(); 466 return; 467 case VOL_SET_GROUP_VOL: 468 new MediaMetrics.Item(mMetricsId) 469 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 470 .set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes") 471 .set(MediaMetrics.Property.FLAGS, mVal2) 472 .set(MediaMetrics.Property.GROUP, mGroupName) 473 .set(MediaMetrics.Property.INDEX, mVal1) 474 .record(); 475 return; 476 case VOL_MUTE_STREAM_INT: 477 // No value in logging metrics for this internal event 478 return; 479 case VOL_MASTER_MUTE: 480 // No value in logging metrics for this internal event 481 return; 482 default: 483 return; 484 } 485 } 486 487 @Override eventToString()488 public String eventToString() { 489 switch (mOp) { 490 case VOL_ADJUST_SUGG_VOL: 491 return new StringBuilder("adjustSuggestedStreamVolume(sugg:") 492 .append(AudioSystem.streamToString(mStream)) 493 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 494 .append(" flags:0x").append(Integer.toHexString(mVal2)) 495 .append(") from ").append(mCaller) 496 .toString(); 497 case VOL_ADJUST_GROUP_VOL: 498 return new StringBuilder("adjustVolumeGroupVolume(group:") 499 .append(mGroupName) 500 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 501 .append(" flags:0x").append(Integer.toHexString(mVal2)) 502 .append(") from ").append(mCaller) 503 .toString(); 504 case VOL_ADJUST_STREAM_VOL: 505 return new StringBuilder("adjustStreamVolume(stream:") 506 .append(AudioSystem.streamToString(mStream)) 507 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 508 .append(" flags:0x").append(Integer.toHexString(mVal2)) 509 .append(") from ").append(mCaller) 510 .toString(); 511 case VOL_SET_STREAM_VOL: 512 return new StringBuilder("setStreamVolume(stream:") 513 .append(AudioSystem.streamToString(mStream)) 514 .append(" index:").append(mVal1) 515 .append(" flags:0x").append(Integer.toHexString(mVal2)) 516 .append(" oldIndex:").append(mVal3) 517 .append(") from ").append(mCaller) 518 .toString(); 519 case VOL_SET_HEARING_AID_VOL: 520 return new StringBuilder("setHearingAidVolume:") 521 .append(" index:").append(mVal1) 522 .append(" gain dB:").append(mVal2) 523 .toString(); 524 case VOL_SET_LE_AUDIO_VOL: 525 return new StringBuilder("setLeAudioVolume(stream:") 526 .append(AudioSystem.streamToString(mStream)) 527 .append(" index:").append(mVal1) 528 .append(" maxIndex:").append(mVal2) 529 .toString(); 530 case VOL_SET_AVRCP_VOL: 531 return new StringBuilder("setAvrcpVolume:") 532 .append(" index:").append(mVal1) 533 .toString(); 534 case VOL_ADJUST_VOL_UID: 535 return new StringBuilder("adjustStreamVolumeForUid(stream:") 536 .append(AudioSystem.streamToString(mStream)) 537 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 538 .append(" flags:0x").append(Integer.toHexString(mVal2)) 539 .append(") from ").append(mCaller) 540 .toString(); 541 case VOL_VOICE_ACTIVITY_HEARING_AID: 542 return new StringBuilder("Voice activity change (") 543 .append(mVal2 == 1 ? "active" : "inactive") 544 .append(") causes setting HEARING_AID volume to idx:").append(mVal1) 545 .append(" stream:").append(AudioSystem.streamToString(mStream)) 546 .toString(); 547 case VOL_MODE_CHANGE_HEARING_AID: 548 return new StringBuilder("setMode(") 549 .append(AudioSystem.modeToString(mVal2)) 550 .append(") causes setting HEARING_AID volume to idx:").append(mVal1) 551 .append(" stream:").append(AudioSystem.streamToString(mStream)) 552 .toString(); 553 case VOL_SET_GROUP_VOL: 554 return new StringBuilder("setVolumeIndexForAttributes(group:") 555 .append(" group: ").append(mGroupName) 556 .append(" index:").append(mVal1) 557 .append(" flags:0x").append(Integer.toHexString(mVal2)) 558 .append(") from ").append(mCaller) 559 .toString(); 560 case VOL_MUTE_STREAM_INT: 561 return new StringBuilder("VolumeStreamState.muteInternally(stream:") 562 .append(AudioSystem.streamToString(mStream)) 563 .append(mVal1 == 1 ? ", muted)" : ", unmuted)") 564 .toString(); 565 case VOL_MASTER_MUTE: 566 return new StringBuilder("Master mute:") 567 .append(mVal1 == 1 ? " muted)" : " unmuted)") 568 .toString(); 569 default: return new StringBuilder("FIXME invalid op:").append(mOp).toString(); 570 } 571 } 572 } 573 574 static final class SoundDoseEvent extends EventLogger.Event { 575 static final int MOMENTARY_EXPOSURE = 0; 576 static final int DOSE_UPDATE = 1; 577 static final int DOSE_REPEAT_5X = 2; 578 static final int DOSE_ACCUMULATION_START = 3; 579 static final int LOWER_VOLUME_TO_RS1 = 4; 580 581 final int mEventType; 582 final float mFloatValue; 583 final long mLongValue; 584 SoundDoseEvent(int event, float f, long l)585 private SoundDoseEvent(int event, float f, long l) { 586 mEventType = event; 587 mFloatValue = f; 588 mLongValue = l; 589 } 590 getMomentaryExposureEvent(float mel)591 static SoundDoseEvent getMomentaryExposureEvent(float mel) { 592 return new SoundDoseEvent(MOMENTARY_EXPOSURE, mel, 0 /*ignored*/); 593 } 594 getDoseUpdateEvent(float csd, long totalDuration)595 static SoundDoseEvent getDoseUpdateEvent(float csd, long totalDuration) { 596 return new SoundDoseEvent(DOSE_UPDATE, csd, totalDuration); 597 } 598 getDoseRepeat5xEvent()599 static SoundDoseEvent getDoseRepeat5xEvent() { 600 return new SoundDoseEvent(DOSE_REPEAT_5X, 0 /*ignored*/, 0 /*ignored*/); 601 } 602 getDoseAccumulationStartEvent()603 static SoundDoseEvent getDoseAccumulationStartEvent() { 604 return new SoundDoseEvent(DOSE_ACCUMULATION_START, 0 /*ignored*/, 0 /*ignored*/); 605 } 606 getLowerVolumeToRs1Event()607 static SoundDoseEvent getLowerVolumeToRs1Event() { 608 return new SoundDoseEvent(LOWER_VOLUME_TO_RS1, 0 /*ignored*/, 0 /*ignored*/); 609 } 610 611 @Override eventToString()612 public String eventToString() { 613 switch (mEventType) { 614 case MOMENTARY_EXPOSURE: 615 return String.format("momentary exposure MEL=%.2f", mFloatValue); 616 case DOSE_UPDATE: 617 return String.format(java.util.Locale.US, 618 "dose update CSD=%.1f%% total duration=%d", 619 mFloatValue * 100.0f, mLongValue); 620 case DOSE_REPEAT_5X: 621 return "CSD reached 500%"; 622 case DOSE_ACCUMULATION_START: 623 return "CSD accumulating: RS2 entered"; 624 case LOWER_VOLUME_TO_RS1: 625 return "CSD lowering volume to RS1"; 626 } 627 return new StringBuilder("FIXME invalid event type:").append(mEventType).toString(); 628 } 629 } 630 631 static final class LoudnessEvent extends EventLogger.Event { 632 static final int START_PIID = 0; 633 634 static final int STOP_PIID = 1; 635 636 static final int CLIENT_DIED = 2; 637 638 final int mEventType; 639 final int mIntValue1; 640 final int mIntValue2; 641 LoudnessEvent(int event, int i1, int i2)642 private LoudnessEvent(int event, int i1, int i2) { 643 mEventType = event; 644 mIntValue1 = i1; 645 mIntValue2 = i2; 646 } 647 getStartPiid(int piid, int pid)648 static LoudnessEvent getStartPiid(int piid, int pid) { 649 return new LoudnessEvent(START_PIID, piid, pid); 650 } 651 getStopPiid(int piid, int pid)652 static LoudnessEvent getStopPiid(int piid, int pid) { 653 return new LoudnessEvent(STOP_PIID, piid, pid); 654 } 655 getClientDied(int pid)656 static LoudnessEvent getClientDied(int pid) { 657 return new LoudnessEvent(CLIENT_DIED, 0 /* ignored */, pid); 658 } 659 660 661 @Override eventToString()662 public String eventToString() { 663 switch (mEventType) { 664 case START_PIID: 665 return String.format( 666 "Start loudness updates for piid %d for client pid %d", 667 mIntValue1, mIntValue2); 668 case STOP_PIID: 669 return String.format( 670 "Stop loudness updates for piid %d for client pid %d", 671 mIntValue1, mIntValue2); 672 case CLIENT_DIED: 673 return String.format("Loudness client with pid %d died", mIntValue2); 674 675 } 676 return new StringBuilder("FIXME invalid event type:").append(mEventType).toString(); 677 } 678 } 679 680 /** 681 * Class to log stream type mute/unmute events 682 */ 683 static final class StreamMuteEvent extends EventLogger.Event { 684 final int mStreamType; 685 final boolean mMuted; 686 final String mSource; 687 StreamMuteEvent(int streamType, boolean muted, String source)688 StreamMuteEvent(int streamType, boolean muted, String source) { 689 mStreamType = streamType; 690 mMuted = muted; 691 mSource = source; 692 } 693 694 @Override eventToString()695 public String eventToString() { 696 final String streamName = 697 (mStreamType <= AudioSystem.getNumStreamTypes() && mStreamType >= 0) 698 ? AudioSystem.STREAM_NAMES[mStreamType] 699 : ("stream " + mStreamType); 700 return new StringBuilder(streamName) 701 .append(mMuted ? " muting by " : " unmuting by ") 702 .append(mSource) 703 .toString(); 704 } 705 } 706 707 /** 708 * Class to log unmute errors that contradict the ringer/zen mode muted streams 709 */ 710 static final class StreamUnmuteErrorEvent extends EventLogger.Event { 711 final int mStreamType; 712 final int mRingerZenMutedStreams; 713 StreamUnmuteErrorEvent(int streamType, int ringerZenMutedStreams)714 StreamUnmuteErrorEvent(int streamType, int ringerZenMutedStreams) { 715 mStreamType = streamType; 716 mRingerZenMutedStreams = ringerZenMutedStreams; 717 } 718 719 @Override eventToString()720 public String eventToString() { 721 final String streamName = 722 (mStreamType <= AudioSystem.getNumStreamTypes() && mStreamType >= 0) 723 ? AudioSystem.STREAM_NAMES[mStreamType] 724 : ("stream " + mStreamType); 725 return new StringBuilder("Invalid call to unmute ") 726 .append(streamName) 727 .append(" despite muted streams 0x") 728 .append(Integer.toHexString(mRingerZenMutedStreams)) 729 .toString(); 730 } 731 } 732 733 static final class RingerZenMutedStreamsEvent extends EventLogger.Event { 734 final int mRingerZenMutedStreams; 735 final String mSource; 736 RingerZenMutedStreamsEvent(int ringerZenMutedStreams, String source)737 RingerZenMutedStreamsEvent(int ringerZenMutedStreams, String source) { 738 mRingerZenMutedStreams = ringerZenMutedStreams; 739 mSource = source; 740 } 741 742 @Override eventToString()743 public String eventToString() { 744 return new StringBuilder("RingerZenMutedStreams 0x") 745 .append(Integer.toHexString(mRingerZenMutedStreams)) 746 .append(" from ").append(mSource) 747 .toString(); 748 } 749 } 750 } 751