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(" state:").append(AudioSystem.deviceStateToString(mState.mState)) 124 .append(" addr:").append(mState.mAttributes.getAddress()) 125 .append(" name:").append(mState.mAttributes.getName()) 126 .append(") from ").append(mState.mCaller).toString(); 127 } 128 } 129 130 final static class ForceUseEvent extends EventLogger.Event { 131 final int mUsage; 132 final int mConfig; 133 final String mReason; 134 ForceUseEvent(int usage, int config, String reason)135 ForceUseEvent(int usage, int config, String reason) { 136 mUsage = usage; 137 mConfig = config; 138 mReason = reason; 139 } 140 141 @Override eventToString()142 public String eventToString() { 143 return new StringBuilder("setForceUse(") 144 .append(AudioSystem.forceUseUsageToString(mUsage)) 145 .append(", ").append(AudioSystem.forceUseConfigToString(mConfig)) 146 .append(") due to ").append(mReason).toString(); 147 } 148 } 149 150 static final class VolChangedBroadcastEvent extends EventLogger.Event { 151 final int mStreamType; 152 final int mAliasStreamType; 153 final int mIndex; 154 VolChangedBroadcastEvent(int stream, int alias, int index)155 VolChangedBroadcastEvent(int stream, int alias, int index) { 156 mStreamType = stream; 157 mAliasStreamType = alias; 158 mIndex = index; 159 } 160 161 @Override eventToString()162 public String eventToString() { 163 return new StringBuilder("sending VOLUME_CHANGED stream:") 164 .append(AudioSystem.streamToString(mStreamType)) 165 .append(" index:").append(mIndex) 166 .append(" alias:").append(AudioSystem.streamToString(mAliasStreamType)) 167 .toString(); 168 } 169 } 170 171 static final class DeviceVolumeEvent extends EventLogger.Event { 172 final int mStream; 173 final int mVolIndex; 174 final String mDeviceNativeType; 175 final String mDeviceAddress; 176 final String mCaller; 177 final int mDeviceForStream; 178 final boolean mSkipped; 179 DeviceVolumeEvent(int streamType, int index, @NonNull AudioDeviceAttributes device, int deviceForStream, String callingPackage, boolean skipped)180 DeviceVolumeEvent(int streamType, int index, @NonNull AudioDeviceAttributes device, 181 int deviceForStream, String callingPackage, boolean skipped) { 182 mStream = streamType; 183 mVolIndex = index; 184 mDeviceNativeType = "0x" + Integer.toHexString(device.getInternalType()); 185 mDeviceAddress = device.getAddress(); 186 mDeviceForStream = deviceForStream; 187 mCaller = callingPackage; 188 mSkipped = skipped; 189 // log metrics 190 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME_EVENT) 191 .set(MediaMetrics.Property.EVENT, "setDeviceVolume") 192 .set(MediaMetrics.Property.STREAM_TYPE, 193 AudioSystem.streamToString(mStream)) 194 .set(MediaMetrics.Property.INDEX, mVolIndex) 195 .set(MediaMetrics.Property.DEVICE, mDeviceNativeType) 196 .set(MediaMetrics.Property.ADDRESS, mDeviceAddress) 197 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 198 .record(); 199 } 200 201 @Override eventToString()202 public String eventToString() { 203 final StringBuilder sb = new StringBuilder("setDeviceVolume(stream:") 204 .append(AudioSystem.streamToString(mStream)) 205 .append(" index:").append(mVolIndex) 206 .append(" device:").append(mDeviceNativeType) 207 .append(" addr:").append(mDeviceAddress) 208 .append(") from ").append(mCaller); 209 if (mSkipped) { 210 sb.append(" skipped [device in use]"); 211 } else { 212 sb.append(" currDevForStream:Ox").append(Integer.toHexString(mDeviceForStream)); 213 } 214 return sb.toString(); 215 } 216 } 217 218 final static class VolumeEvent extends EventLogger.Event { 219 static final int VOL_ADJUST_SUGG_VOL = 0; 220 static final int VOL_ADJUST_STREAM_VOL = 1; 221 static final int VOL_SET_STREAM_VOL = 2; 222 static final int VOL_SET_HEARING_AID_VOL = 3; 223 static final int VOL_SET_AVRCP_VOL = 4; 224 static final int VOL_ADJUST_VOL_UID = 5; 225 static final int VOL_VOICE_ACTIVITY_HEARING_AID = 6; 226 static final int VOL_MODE_CHANGE_HEARING_AID = 7; 227 static final int VOL_SET_GROUP_VOL = 8; 228 static final int VOL_MUTE_STREAM_INT = 9; 229 static final int VOL_SET_LE_AUDIO_VOL = 10; 230 static final int VOL_ADJUST_GROUP_VOL = 11; 231 232 final int mOp; 233 final int mStream; 234 final int mVal1; 235 final int mVal2; 236 final String mCaller; 237 final String mGroupName; 238 239 /** used for VOL_ADJUST_VOL_UID, 240 * VOL_ADJUST_SUGG_VOL, 241 * VOL_ADJUST_STREAM_VOL, 242 * VOL_SET_STREAM_VOL */ VolumeEvent(int op, int stream, int val1, int val2, String caller)243 VolumeEvent(int op, int stream, int val1, int val2, String caller) { 244 mOp = op; 245 mStream = stream; 246 mVal1 = val1; 247 mVal2 = val2; 248 mCaller = caller; 249 mGroupName = null; 250 logMetricEvent(); 251 } 252 253 /** used for VOL_SET_HEARING_AID_VOL*/ VolumeEvent(int op, int index, int gainDb)254 VolumeEvent(int op, int index, int gainDb) { 255 mOp = op; 256 mVal1 = index; 257 mVal2 = gainDb; 258 // unused 259 mStream = -1; 260 mCaller = null; 261 mGroupName = null; 262 logMetricEvent(); 263 } 264 265 /** used for VOL_SET_AVRCP_VOL */ VolumeEvent(int op, int index)266 VolumeEvent(int op, int index) { 267 mOp = op; 268 mVal1 = index; 269 // unused 270 mVal2 = 0; 271 mStream = -1; 272 mCaller = null; 273 mGroupName = null; 274 logMetricEvent(); 275 } 276 277 /** used for VOL_VOICE_ACTIVITY_HEARING_AID */ VolumeEvent(int op, boolean voiceActive, int stream, int index)278 VolumeEvent(int op, boolean voiceActive, int stream, int index) { 279 mOp = op; 280 mStream = stream; 281 mVal1 = index; 282 mVal2 = voiceActive ? 1 : 0; 283 // unused 284 mCaller = null; 285 mGroupName = null; 286 logMetricEvent(); 287 } 288 289 /** used for VOL_MODE_CHANGE_HEARING_AID */ VolumeEvent(int op, int mode, int stream, int index)290 VolumeEvent(int op, int mode, int stream, int index) { 291 mOp = op; 292 mStream = stream; 293 mVal1 = index; 294 mVal2 = mode; 295 // unused 296 mCaller = null; 297 mGroupName = null; 298 logMetricEvent(); 299 } 300 301 /** used for VOL_SET_GROUP_VOL, 302 * VOL_ADJUST_GROUP_VOL */ VolumeEvent(int op, String group, int index, int flags, String caller)303 VolumeEvent(int op, String group, int index, int flags, String caller) { 304 mOp = op; 305 mStream = -1; 306 mVal1 = index; 307 mVal2 = flags; 308 mCaller = caller; 309 mGroupName = group; 310 logMetricEvent(); 311 } 312 313 /** used for VOL_MUTE_STREAM_INT */ VolumeEvent(int op, int stream, boolean state)314 VolumeEvent(int op, int stream, boolean state) { 315 mOp = op; 316 mStream = stream; 317 mVal1 = state ? 1 : 0; 318 mVal2 = 0; 319 mCaller = null; 320 mGroupName = null; 321 logMetricEvent(); 322 } 323 324 325 /** 326 * Audio Analytics unique Id. 327 */ 328 private static final String mMetricsId = MediaMetrics.Name.AUDIO_VOLUME_EVENT; 329 330 /** 331 * Log mediametrics event 332 */ logMetricEvent()333 private void logMetricEvent() { 334 switch (mOp) { 335 case VOL_ADJUST_SUGG_VOL: 336 case VOL_ADJUST_VOL_UID: 337 case VOL_ADJUST_STREAM_VOL: { 338 String eventName; 339 switch (mOp) { 340 case VOL_ADJUST_SUGG_VOL: 341 eventName = "adjustSuggestedStreamVolume"; 342 break; 343 case VOL_ADJUST_STREAM_VOL: 344 eventName = "adjustStreamVolume"; 345 break; 346 case VOL_ADJUST_VOL_UID: 347 eventName = "adjustStreamVolumeForUid"; 348 break; 349 default: 350 return; // not possible, just return here 351 } 352 new MediaMetrics.Item(mMetricsId) 353 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 354 .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down") 355 .set(MediaMetrics.Property.EVENT, eventName) 356 .set(MediaMetrics.Property.FLAGS, mVal2) 357 .set(MediaMetrics.Property.STREAM_TYPE, 358 AudioSystem.streamToString(mStream)) 359 .record(); 360 return; 361 } 362 case VOL_ADJUST_GROUP_VOL: 363 new MediaMetrics.Item(mMetricsId) 364 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 365 .set(MediaMetrics.Property.DIRECTION, mVal1 > 0 ? "up" : "down") 366 .set(MediaMetrics.Property.EVENT, "adjustVolumeGroupVolume") 367 .set(MediaMetrics.Property.FLAGS, mVal2) 368 .set(MediaMetrics.Property.GROUP, mGroupName) 369 .record(); 370 return; 371 case VOL_SET_STREAM_VOL: 372 new MediaMetrics.Item(mMetricsId) 373 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 374 .set(MediaMetrics.Property.EVENT, "setStreamVolume") 375 .set(MediaMetrics.Property.FLAGS, mVal2) 376 .set(MediaMetrics.Property.INDEX, mVal1) 377 .set(MediaMetrics.Property.STREAM_TYPE, 378 AudioSystem.streamToString(mStream)) 379 .record(); 380 return; 381 case VOL_SET_HEARING_AID_VOL: 382 new MediaMetrics.Item(mMetricsId) 383 .set(MediaMetrics.Property.EVENT, "setHearingAidVolume") 384 .set(MediaMetrics.Property.GAIN_DB, (double) mVal2) 385 .set(MediaMetrics.Property.INDEX, mVal1) 386 .record(); 387 return; 388 case VOL_SET_LE_AUDIO_VOL: 389 new MediaMetrics.Item(mMetricsId) 390 .set(MediaMetrics.Property.EVENT, "setLeAudioVolume") 391 .set(MediaMetrics.Property.INDEX, mVal1) 392 .set(MediaMetrics.Property.MAX_INDEX, mVal2) 393 .record(); 394 return; 395 case VOL_SET_AVRCP_VOL: 396 new MediaMetrics.Item(mMetricsId) 397 .set(MediaMetrics.Property.EVENT, "setAvrcpVolume") 398 .set(MediaMetrics.Property.INDEX, mVal1) 399 .record(); 400 return; 401 case VOL_VOICE_ACTIVITY_HEARING_AID: 402 new MediaMetrics.Item(mMetricsId) 403 .set(MediaMetrics.Property.EVENT, "voiceActivityHearingAid") 404 .set(MediaMetrics.Property.INDEX, mVal1) 405 .set(MediaMetrics.Property.STATE, 406 mVal2 == 1 ? "active" : "inactive") 407 .set(MediaMetrics.Property.STREAM_TYPE, 408 AudioSystem.streamToString(mStream)) 409 .record(); 410 return; 411 case VOL_MODE_CHANGE_HEARING_AID: 412 new MediaMetrics.Item(mMetricsId) 413 .set(MediaMetrics.Property.EVENT, "modeChangeHearingAid") 414 .set(MediaMetrics.Property.INDEX, mVal1) 415 .set(MediaMetrics.Property.MODE, AudioSystem.modeToString(mVal2)) 416 .set(MediaMetrics.Property.STREAM_TYPE, 417 AudioSystem.streamToString(mStream)) 418 .record(); 419 return; 420 case VOL_SET_GROUP_VOL: 421 new MediaMetrics.Item(mMetricsId) 422 .set(MediaMetrics.Property.CALLING_PACKAGE, mCaller) 423 .set(MediaMetrics.Property.EVENT, "setVolumeIndexForAttributes") 424 .set(MediaMetrics.Property.FLAGS, mVal2) 425 .set(MediaMetrics.Property.GROUP, mGroupName) 426 .set(MediaMetrics.Property.INDEX, mVal1) 427 .record(); 428 return; 429 case VOL_MUTE_STREAM_INT: 430 // No value in logging metrics for this internal event 431 return; 432 default: 433 return; 434 } 435 } 436 437 @Override eventToString()438 public String eventToString() { 439 switch (mOp) { 440 case VOL_ADJUST_SUGG_VOL: 441 return new StringBuilder("adjustSuggestedStreamVolume(sugg:") 442 .append(AudioSystem.streamToString(mStream)) 443 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 444 .append(" flags:0x").append(Integer.toHexString(mVal2)) 445 .append(") from ").append(mCaller) 446 .toString(); 447 case VOL_ADJUST_GROUP_VOL: 448 return new StringBuilder("adjustVolumeGroupVolume(group:") 449 .append(mGroupName) 450 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 451 .append(" flags:0x").append(Integer.toHexString(mVal2)) 452 .append(") from ").append(mCaller) 453 .toString(); 454 case VOL_ADJUST_STREAM_VOL: 455 return new StringBuilder("adjustStreamVolume(stream:") 456 .append(AudioSystem.streamToString(mStream)) 457 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 458 .append(" flags:0x").append(Integer.toHexString(mVal2)) 459 .append(") from ").append(mCaller) 460 .toString(); 461 case VOL_SET_STREAM_VOL: 462 return new StringBuilder("setStreamVolume(stream:") 463 .append(AudioSystem.streamToString(mStream)) 464 .append(" index:").append(mVal1) 465 .append(" flags:0x").append(Integer.toHexString(mVal2)) 466 .append(") from ").append(mCaller) 467 .toString(); 468 case VOL_SET_HEARING_AID_VOL: 469 return new StringBuilder("setHearingAidVolume:") 470 .append(" index:").append(mVal1) 471 .append(" gain dB:").append(mVal2) 472 .toString(); 473 case VOL_SET_LE_AUDIO_VOL: 474 return new StringBuilder("setLeAudioVolume:") 475 .append(" index:").append(mVal1) 476 .append(" maxIndex:").append(mVal2) 477 .toString(); 478 case VOL_SET_AVRCP_VOL: 479 return new StringBuilder("setAvrcpVolume:") 480 .append(" index:").append(mVal1) 481 .toString(); 482 case VOL_ADJUST_VOL_UID: 483 return new StringBuilder("adjustStreamVolumeForUid(stream:") 484 .append(AudioSystem.streamToString(mStream)) 485 .append(" dir:").append(AudioManager.adjustToString(mVal1)) 486 .append(" flags:0x").append(Integer.toHexString(mVal2)) 487 .append(") from ").append(mCaller) 488 .toString(); 489 case VOL_VOICE_ACTIVITY_HEARING_AID: 490 return new StringBuilder("Voice activity change (") 491 .append(mVal2 == 1 ? "active" : "inactive") 492 .append(") causes setting HEARING_AID volume to idx:").append(mVal1) 493 .append(" stream:").append(AudioSystem.streamToString(mStream)) 494 .toString(); 495 case VOL_MODE_CHANGE_HEARING_AID: 496 return new StringBuilder("setMode(") 497 .append(AudioSystem.modeToString(mVal2)) 498 .append(") causes setting HEARING_AID volume to idx:").append(mVal1) 499 .append(" stream:").append(AudioSystem.streamToString(mStream)) 500 .toString(); 501 case VOL_SET_GROUP_VOL: 502 return new StringBuilder("setVolumeIndexForAttributes(group:") 503 .append(" group: ").append(mGroupName) 504 .append(" index:").append(mVal1) 505 .append(" flags:0x").append(Integer.toHexString(mVal2)) 506 .append(") from ").append(mCaller) 507 .toString(); 508 case VOL_MUTE_STREAM_INT: 509 return new StringBuilder("VolumeStreamState.muteInternally(stream:") 510 .append(AudioSystem.streamToString(mStream)) 511 .append(mVal1 == 1 ? ", muted)" : ", unmuted)") 512 .toString(); 513 default: return new StringBuilder("FIXME invalid op:").append(mOp).toString(); 514 } 515 } 516 } 517 518 static final class SoundDoseEvent extends EventLogger.Event { 519 static final int MOMENTARY_EXPOSURE = 0; 520 static final int DOSE_UPDATE = 1; 521 static final int DOSE_REPEAT_5X = 2; 522 static final int DOSE_ACCUMULATION_START = 3; 523 final int mEventType; 524 final float mFloatValue; 525 final long mLongValue; 526 SoundDoseEvent(int event, float f, long l)527 private SoundDoseEvent(int event, float f, long l) { 528 mEventType = event; 529 mFloatValue = f; 530 mLongValue = l; 531 } 532 getMomentaryExposureEvent(float mel)533 static SoundDoseEvent getMomentaryExposureEvent(float mel) { 534 return new SoundDoseEvent(MOMENTARY_EXPOSURE, mel, 0 /*ignored*/); 535 } 536 getDoseUpdateEvent(float csd, long totalDuration)537 static SoundDoseEvent getDoseUpdateEvent(float csd, long totalDuration) { 538 return new SoundDoseEvent(DOSE_UPDATE, csd, totalDuration); 539 } 540 getDoseRepeat5xEvent()541 static SoundDoseEvent getDoseRepeat5xEvent() { 542 return new SoundDoseEvent(DOSE_REPEAT_5X, 0 /*ignored*/, 0 /*ignored*/); 543 } 544 getDoseAccumulationStartEvent()545 static SoundDoseEvent getDoseAccumulationStartEvent() { 546 return new SoundDoseEvent(DOSE_ACCUMULATION_START, 0 /*ignored*/, 0 /*ignored*/); 547 } 548 549 @Override eventToString()550 public String eventToString() { 551 switch (mEventType) { 552 case MOMENTARY_EXPOSURE: 553 return String.format("momentary exposure MEL=%.2f", mFloatValue); 554 case DOSE_UPDATE: 555 return String.format(java.util.Locale.US, 556 "dose update CSD=%.1f%% total duration=%d", 557 mFloatValue * 100.0f, mLongValue); 558 case DOSE_REPEAT_5X: 559 return "CSD reached 500%"; 560 case DOSE_ACCUMULATION_START: 561 return "CSD accumulating: RS2 entered"; 562 } 563 return new StringBuilder("FIXME invalid event type:").append(mEventType).toString(); 564 } 565 } 566 567 /** 568 * Class to log stream type mute/unmute events 569 */ 570 static final class StreamMuteEvent extends EventLogger.Event { 571 final int mStreamType; 572 final boolean mMuted; 573 final String mSource; 574 StreamMuteEvent(int streamType, boolean muted, String source)575 StreamMuteEvent(int streamType, boolean muted, String source) { 576 mStreamType = streamType; 577 mMuted = muted; 578 mSource = source; 579 } 580 581 @Override eventToString()582 public String eventToString() { 583 final String streamName = 584 (mStreamType <= AudioSystem.getNumStreamTypes() && mStreamType >= 0) 585 ? AudioSystem.STREAM_NAMES[mStreamType] 586 : ("stream " + mStreamType); 587 return new StringBuilder(streamName) 588 .append(mMuted ? " muting by " : " unmuting by ") 589 .append(mSource) 590 .toString(); 591 } 592 } 593 594 /** 595 * Class to log unmute errors that contradict the ringer/zen mode muted streams 596 */ 597 static final class StreamUnmuteErrorEvent extends EventLogger.Event { 598 final int mStreamType; 599 final int mRingerZenMutedStreams; 600 StreamUnmuteErrorEvent(int streamType, int ringerZenMutedStreams)601 StreamUnmuteErrorEvent(int streamType, int ringerZenMutedStreams) { 602 mStreamType = streamType; 603 mRingerZenMutedStreams = ringerZenMutedStreams; 604 } 605 606 @Override eventToString()607 public String eventToString() { 608 final String streamName = 609 (mStreamType <= AudioSystem.getNumStreamTypes() && mStreamType >= 0) 610 ? AudioSystem.STREAM_NAMES[mStreamType] 611 : ("stream " + mStreamType); 612 return new StringBuilder("Invalid call to unmute ") 613 .append(streamName) 614 .append(" despite muted streams 0x") 615 .append(Integer.toHexString(mRingerZenMutedStreams)) 616 .toString(); 617 } 618 } 619 620 static final class RingerZenMutedStreamsEvent extends EventLogger.Event { 621 final int mRingerZenMutedStreams; 622 final String mSource; 623 RingerZenMutedStreamsEvent(int ringerZenMutedStreams, String source)624 RingerZenMutedStreamsEvent(int ringerZenMutedStreams, String source) { 625 mRingerZenMutedStreams = ringerZenMutedStreams; 626 mSource = source; 627 } 628 629 @Override eventToString()630 public String eventToString() { 631 return new StringBuilder("RingerZenMutedStreams 0x") 632 .append(Integer.toHexString(mRingerZenMutedStreams)) 633 .append(" from ").append(mSource) 634 .toString(); 635 } 636 } 637 } 638