1 /* 2 * Copyright (C) 2015 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.systemui.volume; 18 19 import android.media.AudioManager; 20 import android.media.AudioSystem; 21 import android.provider.Settings.Global; 22 import android.util.Log; 23 24 import com.android.internal.annotations.VisibleForTesting; 25 import com.android.internal.logging.MetricsLogger; 26 import com.android.internal.logging.UiEvent; 27 import com.android.internal.logging.UiEventLogger; 28 import com.android.internal.logging.UiEventLoggerImpl; 29 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 30 import com.android.systemui.plugins.VolumeDialogController.State; 31 32 import java.util.Arrays; 33 34 /** 35 * Interesting events related to the volume. 36 */ 37 public class Events { 38 private static final String TAG = Util.logTag(Events.class); 39 40 public static final int EVENT_SHOW_DIALOG = 0; // (reason|int) (keyguard|bool) 41 public static final int EVENT_DISMISS_DIALOG = 1; // (reason|int) 42 public static final int EVENT_ACTIVE_STREAM_CHANGED = 2; // (stream|int) 43 public static final int EVENT_EXPAND = 3; // (expand|bool) 44 public static final int EVENT_KEY = 4; // (stream|int) (lastAudibleStreamVolume) 45 public static final int EVENT_COLLECTION_STARTED = 5; 46 public static final int EVENT_COLLECTION_STOPPED = 6; 47 public static final int EVENT_ICON_CLICK = 7; // (stream|int) (icon_state|int) 48 public static final int EVENT_SETTINGS_CLICK = 8; 49 public static final int EVENT_TOUCH_LEVEL_CHANGED = 9; // (stream|int) (level|int) 50 public static final int EVENT_LEVEL_CHANGED = 10; // (stream|int) (level|int) 51 public static final int EVENT_INTERNAL_RINGER_MODE_CHANGED = 11; // (mode|int) 52 public static final int EVENT_EXTERNAL_RINGER_MODE_CHANGED = 12; // (mode|int) 53 public static final int EVENT_ZEN_MODE_CHANGED = 13; // (mode|int) 54 public static final int EVENT_SUPPRESSOR_CHANGED = 14; // (component|string) (name|string) 55 public static final int EVENT_MUTE_CHANGED = 15; // (stream|int) (muted|bool) 56 public static final int EVENT_TOUCH_LEVEL_DONE = 16; // (stream|int) (level|int) 57 public static final int EVENT_ZEN_CONFIG_CHANGED = 17; // (allow/disallow|string) 58 public static final int EVENT_RINGER_TOGGLE = 18; // (ringer_mode) 59 public static final int EVENT_SHOW_USB_OVERHEAT_ALARM = 19; // (reason|int) (keyguard|bool) 60 public static final int EVENT_DISMISS_USB_OVERHEAT_ALARM = 20; // (reason|int) (keyguard|bool) 61 public static final int EVENT_ODI_CAPTIONS_CLICK = 21; 62 public static final int EVENT_ODI_CAPTIONS_TOOLTIP_CLICK = 22; 63 64 private static final String[] EVENT_TAGS = { 65 "show_dialog", 66 "dismiss_dialog", 67 "active_stream_changed", 68 "expand", 69 "key", 70 "collection_started", 71 "collection_stopped", 72 "icon_click", 73 "settings_click", 74 "touch_level_changed", 75 "level_changed", 76 "internal_ringer_mode_changed", 77 "external_ringer_mode_changed", 78 "zen_mode_changed", 79 "suppressor_changed", 80 "mute_changed", 81 "touch_level_done", 82 "zen_mode_config_changed", 83 "ringer_toggle", 84 "show_usb_overheat_alarm", 85 "dismiss_usb_overheat_alarm", 86 "odi_captions_click", 87 "odi_captions_tooltip_click" 88 }; 89 90 public static final int DISMISS_REASON_UNKNOWN = 0; 91 public static final int DISMISS_REASON_TOUCH_OUTSIDE = 1; 92 public static final int DISMISS_REASON_VOLUME_CONTROLLER = 2; 93 public static final int DISMISS_REASON_TIMEOUT = 3; 94 public static final int DISMISS_REASON_SCREEN_OFF = 4; 95 public static final int DISMISS_REASON_SETTINGS_CLICKED = 5; 96 public static final int DISMISS_REASON_DONE_CLICKED = 6; 97 public static final int DISMISS_STREAM_GONE = 7; 98 public static final int DISMISS_REASON_OUTPUT_CHOOSER = 8; 99 public static final int DISMISS_REASON_USB_OVERHEAD_ALARM_CHANGED = 9; 100 public static final int DISMISS_REASON_CSD_WARNING_TIMEOUT = 10; 101 public static final int DISMISS_REASON_POSTURE_CHANGED = 11; 102 103 public static final String[] DISMISS_REASONS = { 104 "unknown", 105 "touch_outside", 106 "volume_controller", 107 "timeout", 108 "screen_off", 109 "settings_clicked", 110 "done_clicked", 111 "a11y_stream_changed", 112 "output_chooser", 113 "usb_temperature_below_threshold", 114 "csd_warning_timeout", 115 "posture_changed" 116 }; 117 118 public static final int SHOW_REASON_UNKNOWN = 0; 119 public static final int SHOW_REASON_VOLUME_CHANGED = 1; 120 public static final int SHOW_REASON_REMOTE_VOLUME_CHANGED = 2; 121 public static final int SHOW_REASON_USB_OVERHEAD_ALARM_CHANGED = 3; 122 public static final String[] SHOW_REASONS = { 123 "unknown", 124 "volume_changed", 125 "remote_volume_changed", 126 "usb_temperature_above_threshold" 127 }; 128 129 public static final int ICON_STATE_UNKNOWN = 0; 130 public static final int ICON_STATE_UNMUTE = 1; 131 public static final int ICON_STATE_MUTE = 2; 132 public static final int ICON_STATE_VIBRATE = 3; 133 134 @VisibleForTesting 135 public enum VolumeDialogOpenEvent implements UiEventLogger.UiEventEnum { 136 //TODO zap the lock/unlock distinction 137 INVALID(0), 138 @UiEvent(doc = "The volume dialog was shown because the volume changed") 139 VOLUME_DIALOG_SHOW_VOLUME_CHANGED(128), 140 @UiEvent(doc = "The volume dialog was shown because the volume changed remotely") 141 VOLUME_DIALOG_SHOW_REMOTE_VOLUME_CHANGED(129), 142 @UiEvent(doc = "The volume dialog was shown because the usb high temperature alarm changed") 143 VOLUME_DIALOG_SHOW_USB_TEMP_ALARM_CHANGED(130); 144 145 private final int mId; VolumeDialogOpenEvent(int id)146 VolumeDialogOpenEvent(int id) { 147 mId = id; 148 } getId()149 public int getId() { 150 return mId; 151 } fromReasons(int reason)152 static VolumeDialogOpenEvent fromReasons(int reason) { 153 switch (reason) { 154 case SHOW_REASON_VOLUME_CHANGED: 155 return VOLUME_DIALOG_SHOW_VOLUME_CHANGED; 156 case SHOW_REASON_REMOTE_VOLUME_CHANGED: 157 return VOLUME_DIALOG_SHOW_REMOTE_VOLUME_CHANGED; 158 case SHOW_REASON_USB_OVERHEAD_ALARM_CHANGED: 159 return VOLUME_DIALOG_SHOW_USB_TEMP_ALARM_CHANGED; 160 } 161 return INVALID; 162 } 163 } 164 165 @VisibleForTesting 166 public enum VolumeDialogCloseEvent implements UiEventLogger.UiEventEnum { 167 INVALID(0), 168 @UiEvent(doc = "The volume dialog was dismissed because of a touch outside the dialog") 169 VOLUME_DIALOG_DISMISS_TOUCH_OUTSIDE(134), 170 @UiEvent(doc = "The system asked the volume dialog to close, e.g. for a navigation bar " 171 + "touch, or ActivityManager ACTION_CLOSE_SYSTEM_DIALOGS broadcast.") 172 VOLUME_DIALOG_DISMISS_SYSTEM(135), 173 @UiEvent(doc = "The volume dialog was dismissed because it timed out") 174 VOLUME_DIALOG_DISMISS_TIMEOUT(136), 175 @UiEvent(doc = "The volume dialog was dismissed because the screen turned off") 176 VOLUME_DIALOG_DISMISS_SCREEN_OFF(137), 177 @UiEvent(doc = "The volume dialog was dismissed because the settings icon was clicked") 178 VOLUME_DIALOG_DISMISS_SETTINGS(138), 179 // reserving 139 for DISMISS_REASON_DONE_CLICKED which is currently unused 180 @UiEvent(doc = "The volume dialog was dismissed because the stream no longer exists") 181 VOLUME_DIALOG_DISMISS_STREAM_GONE(140), 182 // reserving 141 for DISMISS_REASON_OUTPUT_CHOOSER which is currently unused 183 @UiEvent(doc = "The volume dialog was dismissed because the usb high temperature alarm " 184 + "changed") 185 VOLUME_DIALOG_DISMISS_USB_TEMP_ALARM_CHANGED(142); 186 187 private final int mId; VolumeDialogCloseEvent(int id)188 VolumeDialogCloseEvent(int id) { 189 mId = id; 190 } getId()191 public int getId() { 192 return mId; 193 } 194 fromReason(int reason)195 static VolumeDialogCloseEvent fromReason(int reason) { 196 switch (reason) { 197 case DISMISS_REASON_TOUCH_OUTSIDE: 198 return VOLUME_DIALOG_DISMISS_TOUCH_OUTSIDE; 199 case DISMISS_REASON_VOLUME_CONTROLLER: 200 return VOLUME_DIALOG_DISMISS_SYSTEM; 201 case DISMISS_REASON_TIMEOUT: 202 return VOLUME_DIALOG_DISMISS_TIMEOUT; 203 case DISMISS_REASON_SCREEN_OFF: 204 return VOLUME_DIALOG_DISMISS_SCREEN_OFF; 205 case DISMISS_REASON_SETTINGS_CLICKED: 206 return VOLUME_DIALOG_DISMISS_SETTINGS; 207 case DISMISS_STREAM_GONE: 208 return VOLUME_DIALOG_DISMISS_STREAM_GONE; 209 case DISMISS_REASON_USB_OVERHEAD_ALARM_CHANGED: 210 return VOLUME_DIALOG_DISMISS_USB_TEMP_ALARM_CHANGED; 211 } 212 return INVALID; 213 } 214 } 215 216 @VisibleForTesting 217 public enum VolumeDialogEvent implements UiEventLogger.UiEventEnum { 218 INVALID(0), 219 @UiEvent(doc = "The volume dialog settings icon was clicked") 220 VOLUME_DIALOG_SETTINGS_CLICK(143), 221 @UiEvent(doc = "The volume dialog details were expanded") 222 VOLUME_DIALOG_EXPAND_DETAILS(144), 223 @UiEvent(doc = "The volume dialog details were collapsed") 224 VOLUME_DIALOG_COLLAPSE_DETAILS(145), 225 @UiEvent(doc = "The active audio stream changed") 226 VOLUME_DIALOG_ACTIVE_STREAM_CHANGED(146), 227 @UiEvent(doc = "The audio stream was muted via icon") 228 VOLUME_DIALOG_MUTE_STREAM(147), 229 @UiEvent(doc = "The audio stream was unmuted via icon") 230 VOLUME_DIALOG_UNMUTE_STREAM(148), 231 @UiEvent(doc = "The audio stream was set to vibrate via icon") 232 VOLUME_DIALOG_TO_VIBRATE_STREAM(149), 233 @UiEvent(doc = "The audio stream was set to non-silent via slider") 234 VOLUME_DIALOG_SLIDER(150), 235 @UiEvent(doc = "The audio stream was set to silent via slider") 236 VOLUME_DIALOG_SLIDER_TO_ZERO(151), 237 @UiEvent(doc = "The audio volume was adjusted to silent via key") 238 VOLUME_KEY_TO_ZERO(152), 239 @UiEvent(doc = "The audio volume was adjusted to non-silent via key") 240 VOLUME_KEY(153), 241 @UiEvent(doc = "The ringer mode was toggled to silent") 242 RINGER_MODE_SILENT(154), 243 @UiEvent(doc = "The ringer mode was toggled to vibrate") 244 RINGER_MODE_VIBRATE(155), 245 @UiEvent(doc = "The ringer mode was toggled to normal") 246 RINGER_MODE_NORMAL(334), 247 @UiEvent(doc = "USB Overheat alarm was raised") 248 USB_OVERHEAT_ALARM(160), 249 @UiEvent(doc = "USB Overheat alarm was dismissed") 250 USB_OVERHEAT_ALARM_DISMISSED(161); 251 252 private final int mId; 253 VolumeDialogEvent(int id)254 VolumeDialogEvent(int id) { 255 mId = id; 256 } 257 getId()258 public int getId() { 259 return mId; 260 } 261 fromIconState(int iconState)262 static VolumeDialogEvent fromIconState(int iconState) { 263 switch (iconState) { 264 case ICON_STATE_UNMUTE: 265 return VOLUME_DIALOG_UNMUTE_STREAM; 266 case ICON_STATE_MUTE: 267 return VOLUME_DIALOG_MUTE_STREAM; 268 case ICON_STATE_VIBRATE: 269 return VOLUME_DIALOG_TO_VIBRATE_STREAM; 270 default: 271 return INVALID; 272 } 273 } 274 fromSliderLevel(int level)275 static VolumeDialogEvent fromSliderLevel(int level) { 276 return level == 0 ? VOLUME_DIALOG_SLIDER_TO_ZERO : VOLUME_DIALOG_SLIDER; 277 } 278 fromKeyLevel(int level)279 static VolumeDialogEvent fromKeyLevel(int level) { 280 return level == 0 ? VOLUME_KEY_TO_ZERO : VOLUME_KEY; 281 } 282 fromRingerMode(int ringerMode)283 static VolumeDialogEvent fromRingerMode(int ringerMode) { 284 switch (ringerMode) { 285 case AudioManager.RINGER_MODE_SILENT: 286 return RINGER_MODE_SILENT; 287 case AudioManager.RINGER_MODE_VIBRATE: 288 return RINGER_MODE_VIBRATE; 289 case AudioManager.RINGER_MODE_NORMAL: 290 return RINGER_MODE_NORMAL; 291 default: 292 return INVALID; 293 } 294 } 295 } 296 297 @VisibleForTesting 298 public enum ZenModeEvent implements UiEventLogger.UiEventEnum { 299 INVALID(0), 300 @UiEvent(doc = "Zen (do not disturb) mode was toggled to off") 301 ZEN_MODE_OFF(335), 302 @UiEvent(doc = "Zen (do not disturb) mode was toggled to important interruptions only") 303 ZEN_MODE_IMPORTANT_ONLY(157), 304 @UiEvent(doc = "Zen (do not disturb) mode was toggled to alarms only") 305 ZEN_MODE_ALARMS_ONLY(158), 306 @UiEvent(doc = "Zen (do not disturb) mode was toggled to block all interruptions") 307 ZEN_MODE_NO_INTERRUPTIONS(159); 308 309 private final int mId; ZenModeEvent(int id)310 ZenModeEvent(int id) { 311 mId = id; 312 } getId()313 public int getId() { 314 return mId; 315 } 316 fromZenMode(int zenMode)317 static ZenModeEvent fromZenMode(int zenMode) { 318 switch (zenMode) { 319 case Global.ZEN_MODE_OFF: return ZEN_MODE_OFF; 320 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return ZEN_MODE_IMPORTANT_ONLY; 321 case Global.ZEN_MODE_ALARMS: return ZEN_MODE_ALARMS_ONLY; 322 case Global.ZEN_MODE_NO_INTERRUPTIONS: return ZEN_MODE_NO_INTERRUPTIONS; 323 default: return INVALID; 324 } 325 } 326 } 327 328 public static Callback sCallback; 329 @VisibleForTesting 330 static MetricsLogger sLegacyLogger = new MetricsLogger(); 331 @VisibleForTesting 332 static UiEventLogger sUiEventLogger = new UiEventLoggerImpl(); 333 334 /** 335 * Logs an event to the system log, to sCallback if present, and to the logEvent destinations. 336 * @param tag One of the EVENT_* codes above. 337 * @param list Any additional event-specific arguments, documented above. 338 */ writeEvent(int tag, Object... list)339 public static void writeEvent(int tag, Object... list) { 340 final long time = System.currentTimeMillis(); 341 Log.i(TAG, logEvent(tag, list)); 342 if (sCallback != null) { 343 sCallback.writeEvent(time, tag, list); 344 } 345 } 346 347 /** 348 * Logs an event to the event log and UiEvent (statsd) logging. Compare writeEvent, which 349 * adds more log destinations. 350 * @param tag One of the EVENT_* codes above. 351 * @param list Any additional event-specific arguments, documented above. 352 * @return String a readable description of the event. Begins "writeEvent <tag_description>" 353 * if the tag is valid. 354 */ logEvent(int tag, Object... list)355 public static String logEvent(int tag, Object... list) { 356 if (tag >= EVENT_TAGS.length) { 357 return ""; 358 } 359 final StringBuilder sb = new StringBuilder("writeEvent ").append(EVENT_TAGS[tag]); 360 // Handle events without extra data 361 if (list == null || list.length == 0) { 362 if (tag == EVENT_SETTINGS_CLICK) { 363 sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_SETTINGS); 364 sUiEventLogger.log(VolumeDialogEvent.VOLUME_DIALOG_SETTINGS_CLICK); 365 } 366 return sb.toString(); 367 } 368 // Handle events with extra data. We've established list[0] exists. 369 sb.append(" "); 370 switch (tag) { 371 case EVENT_SHOW_DIALOG: 372 sLegacyLogger.visible(MetricsEvent.VOLUME_DIALOG); 373 if (list.length > 1) { 374 final Integer reason = (Integer) list[0]; 375 final Boolean keyguard = (Boolean) list[1]; 376 sLegacyLogger.histogram("volume_from_keyguard", keyguard ? 1 : 0); 377 sUiEventLogger.log(VolumeDialogOpenEvent.fromReasons(reason)); 378 sb.append(SHOW_REASONS[reason]).append(" keyguard=").append(keyguard); 379 } 380 break; 381 case EVENT_EXPAND: { 382 final Boolean expand = (Boolean) list[0]; 383 sLegacyLogger.visibility(MetricsEvent.VOLUME_DIALOG_DETAILS, expand); 384 sUiEventLogger.log(expand ? VolumeDialogEvent.VOLUME_DIALOG_EXPAND_DETAILS 385 : VolumeDialogEvent.VOLUME_DIALOG_COLLAPSE_DETAILS); 386 sb.append(expand); 387 break; 388 } 389 case EVENT_DISMISS_DIALOG: { 390 sLegacyLogger.hidden(MetricsEvent.VOLUME_DIALOG); 391 final Integer reason = (Integer) list[0]; 392 sUiEventLogger.log(VolumeDialogCloseEvent.fromReason(reason)); 393 sb.append(DISMISS_REASONS[reason]); 394 break; 395 } 396 case EVENT_ACTIVE_STREAM_CHANGED: { 397 final Integer stream = (Integer) list[0]; 398 sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_STREAM, stream); 399 sUiEventLogger.log(VolumeDialogEvent.VOLUME_DIALOG_ACTIVE_STREAM_CHANGED); 400 sb.append(AudioSystem.streamToString(stream)); 401 break; 402 } 403 case EVENT_ICON_CLICK: 404 if (list.length > 1) { 405 final Integer stream = (Integer) list[0]; 406 sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_ICON, stream); 407 final Integer iconState = (Integer) list[1]; 408 sUiEventLogger.log(VolumeDialogEvent.fromIconState(iconState)); 409 sb.append(AudioSystem.streamToString(stream)).append(' ') 410 .append(iconStateToString(iconState)); 411 } 412 break; 413 case EVENT_TOUCH_LEVEL_DONE: // (stream|int) (level|int) 414 if (list.length > 1) { 415 final Integer level = (Integer) list[1]; 416 sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_SLIDER, level); 417 sUiEventLogger.log(VolumeDialogEvent.fromSliderLevel(level)); 418 } 419 // fall through 420 case EVENT_TOUCH_LEVEL_CHANGED: 421 case EVENT_LEVEL_CHANGED: 422 case EVENT_MUTE_CHANGED: // (stream|int) (level|int) 423 if (list.length > 1) { 424 sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ') 425 .append(list[1]); 426 } 427 break; 428 case EVENT_KEY: // (stream|int) (lastAudibleStreamVolume) 429 if (list.length > 1) { 430 final Integer stream = (Integer) list[0]; 431 sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_KEY, stream); 432 final Integer level = (Integer) list[1]; 433 sUiEventLogger.log(VolumeDialogEvent.fromKeyLevel(level)); 434 sb.append(AudioSystem.streamToString(stream)).append(' ').append(level); 435 } 436 break; 437 case EVENT_RINGER_TOGGLE: { 438 final Integer ringerMode = (Integer) list[0]; 439 sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_RINGER_TOGGLE, ringerMode); 440 sUiEventLogger.log(VolumeDialogEvent.fromRingerMode(ringerMode)); 441 sb.append(ringerModeToString(ringerMode)); 442 break; 443 } 444 case EVENT_EXTERNAL_RINGER_MODE_CHANGED: { 445 final Integer ringerMode = (Integer) list[0]; 446 sLegacyLogger.action(MetricsEvent.ACTION_RINGER_MODE, ringerMode); 447 } 448 // fall through 449 case EVENT_INTERNAL_RINGER_MODE_CHANGED: { 450 final Integer ringerMode = (Integer) list[0]; 451 sb.append(ringerModeToString(ringerMode)); 452 break; 453 } 454 case EVENT_ZEN_MODE_CHANGED: { 455 final Integer zenMode = (Integer) list[0]; 456 sb.append(zenModeToString(zenMode)); 457 sUiEventLogger.log(ZenModeEvent.fromZenMode(zenMode)); 458 break; 459 } 460 case EVENT_SUPPRESSOR_CHANGED: // (component|string) (name|string) 461 if (list.length > 1) { 462 sb.append(list[0]).append(' ').append(list[1]); 463 } 464 break; 465 case EVENT_SHOW_USB_OVERHEAT_ALARM: 466 sLegacyLogger.visible(MetricsEvent.POWER_OVERHEAT_ALARM); 467 sUiEventLogger.log(VolumeDialogEvent.USB_OVERHEAT_ALARM); 468 if (list.length > 1) { 469 final Boolean keyguard = (Boolean) list[1]; 470 sLegacyLogger.histogram("show_usb_overheat_alarm", keyguard ? 1 : 0); 471 final Integer reason = (Integer) list[0]; 472 sb.append(SHOW_REASONS[reason]).append(" keyguard=").append(keyguard); 473 } 474 break; 475 case EVENT_DISMISS_USB_OVERHEAT_ALARM: 476 sLegacyLogger.hidden(MetricsEvent.POWER_OVERHEAT_ALARM); 477 sUiEventLogger.log(VolumeDialogEvent.USB_OVERHEAT_ALARM_DISMISSED); 478 if (list.length > 1) { 479 final Boolean keyguard = (Boolean) list[1]; 480 sLegacyLogger.histogram("dismiss_usb_overheat_alarm", keyguard ? 1 : 0); 481 final Integer reason = (Integer) list[0]; 482 sb.append(DISMISS_REASONS[reason]) 483 .append(" keyguard=").append(keyguard); 484 } 485 break; 486 default: 487 sb.append(Arrays.asList(list)); 488 break; 489 } 490 return sb.toString(); 491 } 492 writeState(long time, State state)493 public static void writeState(long time, State state) { 494 if (sCallback != null) { 495 sCallback.writeState(time, state); 496 } 497 } 498 iconStateToString(int iconState)499 private static String iconStateToString(int iconState) { 500 switch (iconState) { 501 case ICON_STATE_UNMUTE: return "unmute"; 502 case ICON_STATE_MUTE: return "mute"; 503 case ICON_STATE_VIBRATE: return "vibrate"; 504 default: return "unknown_state_" + iconState; 505 } 506 } 507 ringerModeToString(int ringerMode)508 private static String ringerModeToString(int ringerMode) { 509 switch (ringerMode) { 510 case AudioManager.RINGER_MODE_SILENT: return "silent"; 511 case AudioManager.RINGER_MODE_VIBRATE: return "vibrate"; 512 case AudioManager.RINGER_MODE_NORMAL: return "normal"; 513 default: return "unknown"; 514 } 515 } 516 zenModeToString(int zenMode)517 private static String zenModeToString(int zenMode) { 518 switch (zenMode) { 519 case Global.ZEN_MODE_OFF: return "off"; 520 case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return "important_interruptions"; 521 case Global.ZEN_MODE_ALARMS: return "alarms"; 522 case Global.ZEN_MODE_NO_INTERRUPTIONS: return "no_interruptions"; 523 default: return "unknown"; 524 } 525 } 526 527 public interface Callback { writeEvent(long time, int tag, Object[] list)528 void writeEvent(long time, int tag, Object[] list); writeState(long time, State state)529 void writeState(long time, State state); 530 } 531 532 } 533