summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/Events.java436
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/volume/EventsTest.java215
2 files changed, 565 insertions, 86 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java
index 5ed8b8f9e362..e1210011c7a4 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Events.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java
@@ -21,7 +21,11 @@ import android.media.AudioSystem;
import android.provider.Settings.Global;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.plugins.VolumeDialogController.State;
@@ -37,7 +41,7 @@ public class Events {
public static final int EVENT_DISMISS_DIALOG = 1; // (reason|int)
public static final int EVENT_ACTIVE_STREAM_CHANGED = 2; // (stream|int)
public static final int EVENT_EXPAND = 3; // (expand|bool)
- public static final int EVENT_KEY = 4;
+ public static final int EVENT_KEY = 4; // (stream|int) (lastAudibleStreamVolume)
public static final int EVENT_COLLECTION_STARTED = 5;
public static final int EVENT_COLLECTION_STOPPED = 6;
public static final int EVENT_ICON_CLICK = 7; // (stream|int) (icon_state|int)
@@ -49,7 +53,7 @@ public class Events {
public static final int EVENT_ZEN_MODE_CHANGED = 13; // (mode|int)
public static final int EVENT_SUPPRESSOR_CHANGED = 14; // (component|string) (name|string)
public static final int EVENT_MUTE_CHANGED = 15; // (stream|int) (muted|bool)
- public static final int EVENT_TOUCH_LEVEL_DONE = 16; // (stream|int) (level|bool)
+ public static final int EVENT_TOUCH_LEVEL_DONE = 16; // (stream|int) (level|int)
public static final int EVENT_ZEN_CONFIG_CHANGED = 17; // (allow/disallow|string)
public static final int EVENT_RINGER_TOGGLE = 18; // (ringer_mode)
public static final int EVENT_SHOW_USB_OVERHEAT_ALARM = 19; // (reason|int) (keyguard|bool)
@@ -122,103 +126,363 @@ public class Events {
public static final int ICON_STATE_MUTE = 2;
public static final int ICON_STATE_VIBRATE = 3;
+ @VisibleForTesting
+ public enum VolumeDialogOpenEvent implements UiEventLogger.UiEventEnum {
+ //TODO zap the lock/unlock distinction
+ INVALID(0),
+ @UiEvent(doc = "The volume dialog was shown because the volume changed")
+ VOLUME_DIALOG_SHOW_VOLUME_CHANGED(128),
+ @UiEvent(doc = "The volume dialog was shown because the volume changed remotely")
+ VOLUME_DIALOG_SHOW_REMOTE_VOLUME_CHANGED(129),
+ @UiEvent(doc = "The volume dialog was shown because the usb high temperature alarm changed")
+ VOLUME_DIALOG_SHOW_USB_TEMP_ALARM_CHANGED(130);
+
+ private final int mId;
+ VolumeDialogOpenEvent(int id) {
+ mId = id;
+ }
+ public int getId() {
+ return mId;
+ }
+ static VolumeDialogOpenEvent fromReasons(int reason) {
+ switch (reason) {
+ case SHOW_REASON_VOLUME_CHANGED:
+ return VOLUME_DIALOG_SHOW_VOLUME_CHANGED;
+ case SHOW_REASON_REMOTE_VOLUME_CHANGED:
+ return VOLUME_DIALOG_SHOW_REMOTE_VOLUME_CHANGED;
+ case SHOW_REASON_USB_OVERHEAD_ALARM_CHANGED:
+ return VOLUME_DIALOG_SHOW_USB_TEMP_ALARM_CHANGED;
+ }
+ return INVALID;
+ }
+ }
+
+ @VisibleForTesting
+ public enum VolumeDialogCloseEvent implements UiEventLogger.UiEventEnum {
+ INVALID(0),
+ @UiEvent(doc = "The volume dialog was dismissed because of a touch outside the dialog")
+ VOLUME_DIALOG_DISMISS_TOUCH_OUTSIDE(134),
+ @UiEvent(doc = "The system asked the volume dialog to close, e.g. for a navigation bar "
+ + "touch, or ActivityManager ACTION_CLOSE_SYSTEM_DIALOGS broadcast.")
+ VOLUME_DIALOG_DISMISS_SYSTEM(135),
+ @UiEvent(doc = "The volume dialog was dismissed because it timed out")
+ VOLUME_DIALOG_DISMISS_TIMEOUT(136),
+ @UiEvent(doc = "The volume dialog was dismissed because the screen turned off")
+ VOLUME_DIALOG_DISMISS_SCREEN_OFF(137),
+ @UiEvent(doc = "The volume dialog was dismissed because the settings icon was clicked")
+ VOLUME_DIALOG_DISMISS_SETTINGS(138),
+ // reserving 139 for DISMISS_REASON_DONE_CLICKED which is currently unused
+ @UiEvent(doc = "The volume dialog was dismissed because the stream no longer exists")
+ VOLUME_DIALOG_DISMISS_STREAM_GONE(140),
+ // reserving 141 for DISMISS_REASON_OUTPUT_CHOOSER which is currently unused
+ @UiEvent(doc = "The volume dialog was dismissed because the usb high temperature alarm "
+ + "changed")
+ VOLUME_DIALOG_DISMISS_USB_TEMP_ALARM_CHANGED(142);
+
+ private final int mId;
+ VolumeDialogCloseEvent(int id) {
+ mId = id;
+ }
+ public int getId() {
+ return mId;
+ }
+
+ static VolumeDialogCloseEvent fromReason(int reason) {
+ switch (reason) {
+ case DISMISS_REASON_TOUCH_OUTSIDE:
+ return VOLUME_DIALOG_DISMISS_TOUCH_OUTSIDE;
+ case DISMISS_REASON_VOLUME_CONTROLLER:
+ return VOLUME_DIALOG_DISMISS_SYSTEM;
+ case DISMISS_REASON_TIMEOUT:
+ return VOLUME_DIALOG_DISMISS_TIMEOUT;
+ case DISMISS_REASON_SCREEN_OFF:
+ return VOLUME_DIALOG_DISMISS_SCREEN_OFF;
+ case DISMISS_REASON_SETTINGS_CLICKED:
+ return VOLUME_DIALOG_DISMISS_SETTINGS;
+ case DISMISS_STREAM_GONE:
+ return VOLUME_DIALOG_DISMISS_STREAM_GONE;
+ case DISMISS_REASON_USB_OVERHEAD_ALARM_CHANGED:
+ return VOLUME_DIALOG_DISMISS_USB_TEMP_ALARM_CHANGED;
+ }
+ return INVALID;
+ }
+ }
+
+ @VisibleForTesting
+ public enum VolumeDialogEvent implements UiEventLogger.UiEventEnum {
+ INVALID(0),
+ @UiEvent(doc = "The volume dialog settings icon was clicked")
+ VOLUME_DIALOG_SETTINGS_CLICK(143),
+ @UiEvent(doc = "The volume dialog details were expanded")
+ VOLUME_DIALOG_EXPAND_DETAILS(144),
+ @UiEvent(doc = "The volume dialog details were collapsed")
+ VOLUME_DIALOG_COLLAPSE_DETAILS(145),
+ @UiEvent(doc = "The active audio stream changed")
+ VOLUME_DIALOG_ACTIVE_STREAM_CHANGED(146),
+ @UiEvent(doc = "The audio stream was muted via icon")
+ VOLUME_DIALOG_MUTE_STREAM(147),
+ @UiEvent(doc = "The audio stream was unmuted via icon")
+ VOLUME_DIALOG_UNMUTE_STREAM(148),
+ @UiEvent(doc = "The audio stream was set to vibrate via icon")
+ VOLUME_DIALOG_TO_VIBRATE_STREAM(149),
+ @UiEvent(doc = "The audio stream was set to non-silent via slider")
+ VOLUME_DIALOG_SLIDER(150),
+ @UiEvent(doc = "The audio stream was set to silent via slider")
+ VOLUME_DIALOG_SLIDER_TO_ZERO(151),
+ @UiEvent(doc = "The audio volume was adjusted to silent via key")
+ VOLUME_KEY_TO_ZERO(152),
+ @UiEvent(doc = "The audio volume was adjusted to non-silent via key")
+ VOLUME_KEY(153),
+ @UiEvent(doc = "The ringer mode was toggled to silent")
+ RINGER_MODE_SILENT(154),
+ @UiEvent(doc = "The ringer mode was toggled to vibrate")
+ RINGER_MODE_VIBRATE(155),
+ @UiEvent(doc = "The ringer mode was toggled to normal")
+ RINGER_MODE_NORMAL(156),
+ @UiEvent(doc = "USB Overheat alarm was raised")
+ USB_OVERHEAT_ALARM(160),
+ @UiEvent(doc = "USB Overheat alarm was dismissed")
+ USB_OVERHEAT_ALARM_DISMISSED(161);
+
+ private final int mId;
+
+ VolumeDialogEvent(int id) {
+ mId = id;
+ }
+
+ public int getId() {
+ return mId;
+ }
+
+ static VolumeDialogEvent fromIconState(int iconState) {
+ switch (iconState) {
+ case ICON_STATE_UNMUTE:
+ return VOLUME_DIALOG_UNMUTE_STREAM;
+ case ICON_STATE_MUTE:
+ return VOLUME_DIALOG_MUTE_STREAM;
+ case ICON_STATE_VIBRATE:
+ return VOLUME_DIALOG_TO_VIBRATE_STREAM;
+ default:
+ return INVALID;
+ }
+ }
+
+ static VolumeDialogEvent fromSliderLevel(int level) {
+ return level == 0 ? VOLUME_DIALOG_SLIDER_TO_ZERO : VOLUME_DIALOG_SLIDER;
+ }
+
+ static VolumeDialogEvent fromKeyLevel(int level) {
+ return level == 0 ? VOLUME_KEY_TO_ZERO : VOLUME_KEY;
+ }
+
+ static VolumeDialogEvent fromRingerMode(int ringerMode) {
+ switch (ringerMode) {
+ case AudioManager.RINGER_MODE_SILENT:
+ return RINGER_MODE_SILENT;
+ case AudioManager.RINGER_MODE_VIBRATE:
+ return RINGER_MODE_VIBRATE;
+ case AudioManager.RINGER_MODE_NORMAL:
+ return RINGER_MODE_NORMAL;
+ default:
+ return INVALID;
+ }
+ }
+ }
+
+ @VisibleForTesting
+ public enum ZenModeEvent implements UiEventLogger.UiEventEnum {
+ INVALID(0),
+ @UiEvent(doc = "Zen (do not disturb) mode was toggled to off")
+ ZEN_MODE_OFF(156),
+ @UiEvent(doc = "Zen (do not disturb) mode was toggled to important interruptions only")
+ ZEN_MODE_IMPORTANT_ONLY(157),
+ @UiEvent(doc = "Zen (do not disturb) mode was toggled to alarms only")
+ ZEN_MODE_ALARMS_ONLY(158),
+ @UiEvent(doc = "Zen (do not disturb) mode was toggled to block all interruptions")
+ ZEN_MODE_NO_INTERRUPTIONS(159);
+
+ private final int mId;
+ ZenModeEvent(int id) {
+ mId = id;
+ }
+ public int getId() {
+ return mId;
+ }
+
+ static ZenModeEvent fromZenMode(int zenMode) {
+ switch (zenMode) {
+ case Global.ZEN_MODE_OFF: return ZEN_MODE_OFF;
+ case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return ZEN_MODE_IMPORTANT_ONLY;
+ case Global.ZEN_MODE_ALARMS: return ZEN_MODE_ALARMS_ONLY;
+ case Global.ZEN_MODE_NO_INTERRUPTIONS: return ZEN_MODE_NO_INTERRUPTIONS;
+ default: return INVALID;
+ }
+ }
+ }
+
public static Callback sCallback;
+ @VisibleForTesting
+ static MetricsLogger sLegacyLogger = new MetricsLogger();
+ @VisibleForTesting
+ static UiEventLogger sUiEventLogger = new UiEventLoggerImpl();
/**
- * Logs an event to the system log and the event log.
+ * Logs an event to the system log, to sCallback if present, and to the logEvent destinations.
* @param tag One of the EVENT_* codes above.
* @param list Any additional event-specific arguments, documented above.
*/
public static void writeEvent(int tag, Object... list) {
- MetricsLogger logger = new MetricsLogger();
final long time = System.currentTimeMillis();
+ Log.i(TAG, logEvent(tag, list));
+ if (sCallback != null) {
+ sCallback.writeEvent(time, tag, list);
+ }
+ }
+
+ /**
+ * Logs an event to the event log and UiEvent (Westworld) logging. Compare writeEvent, which
+ * adds more log destinations.
+ * @param tag One of the EVENT_* codes above.
+ * @param list Any additional event-specific arguments, documented above.
+ * @return String a readable description of the event. Begins "writeEvent <tag_description>"
+ * if the tag is valid.
+ */
+ public static String logEvent(int tag, Object... list) {
+ if (tag >= EVENT_TAGS.length) {
+ return "";
+ }
final StringBuilder sb = new StringBuilder("writeEvent ").append(EVENT_TAGS[tag]);
- if (list != null && list.length > 0) {
- sb.append(" ");
- switch (tag) {
- case EVENT_SHOW_DIALOG:
- logger.visible(MetricsEvent.VOLUME_DIALOG);
- logger.histogram("volume_from_keyguard",
- (Boolean) list[1] ? 1 : 0);
- sb.append(SHOW_REASONS[(Integer) list[0]]).append(" keyguard=").append(list[1]);
- break;
- case EVENT_EXPAND:
- logger.visibility(MetricsEvent.VOLUME_DIALOG_DETAILS,
- (Boolean) list[0]);
- sb.append(list[0]);
- break;
- case EVENT_DISMISS_DIALOG:
- logger.hidden(MetricsEvent.VOLUME_DIALOG);
- sb.append(DISMISS_REASONS[(Integer) list[0]]);
- break;
- case EVENT_ACTIVE_STREAM_CHANGED:
- logger.action(MetricsEvent.ACTION_VOLUME_STREAM,
- (Integer) list[0]);
- sb.append(AudioSystem.streamToString((Integer) list[0]));
- break;
- case EVENT_ICON_CLICK:
- logger.action(MetricsEvent.ACTION_VOLUME_ICON,
- (Integer) list[0]);
- sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ')
- .append(iconStateToString((Integer) list[1]));
- break;
- case EVENT_TOUCH_LEVEL_DONE:
- logger.action(MetricsEvent.ACTION_VOLUME_SLIDER,
- (Integer) list[1]);
- // fall through
- case EVENT_TOUCH_LEVEL_CHANGED:
- case EVENT_LEVEL_CHANGED:
- case EVENT_MUTE_CHANGED:
- sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ')
- .append(list[1]);
- break;
- case EVENT_KEY:
- logger.action(MetricsEvent.ACTION_VOLUME_KEY,
- (Integer) list[0]);
+ // Handle events without extra data
+ if (list == null || list.length == 0) {
+ if (tag == EVENT_SETTINGS_CLICK) {
+ sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_SETTINGS);
+ sUiEventLogger.log(VolumeDialogEvent.VOLUME_DIALOG_SETTINGS_CLICK);
+ }
+ return sb.toString();
+ }
+ // Handle events with extra data. We've established list[0] exists.
+ sb.append(" ");
+ switch (tag) {
+ case EVENT_SHOW_DIALOG:
+ sLegacyLogger.visible(MetricsEvent.VOLUME_DIALOG);
+ if (list.length > 1) {
+ final Integer reason = (Integer) list[0];
+ final Boolean keyguard = (Boolean) list[1];
+ sLegacyLogger.histogram("volume_from_keyguard", keyguard ? 1 : 0);
+ sUiEventLogger.log(VolumeDialogOpenEvent.fromReasons(reason));
+ sb.append(SHOW_REASONS[reason]).append(" keyguard=").append(keyguard);
+ }
+ break;
+ case EVENT_EXPAND: {
+ final Boolean expand = (Boolean) list[0];
+ sLegacyLogger.visibility(MetricsEvent.VOLUME_DIALOG_DETAILS, expand);
+ sUiEventLogger.log(expand ? VolumeDialogEvent.VOLUME_DIALOG_EXPAND_DETAILS
+ : VolumeDialogEvent.VOLUME_DIALOG_COLLAPSE_DETAILS);
+ sb.append(expand);
+ break;
+ }
+ case EVENT_DISMISS_DIALOG: {
+ sLegacyLogger.hidden(MetricsEvent.VOLUME_DIALOG);
+ final Integer reason = (Integer) list[0];
+ sUiEventLogger.log(VolumeDialogCloseEvent.fromReason(reason));
+ sb.append(DISMISS_REASONS[reason]);
+ break;
+ }
+ case EVENT_ACTIVE_STREAM_CHANGED: {
+ final Integer stream = (Integer) list[0];
+ sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_STREAM, stream);
+ sUiEventLogger.log(VolumeDialogEvent.VOLUME_DIALOG_ACTIVE_STREAM_CHANGED);
+ sb.append(AudioSystem.streamToString(stream));
+ break;
+ }
+ case EVENT_ICON_CLICK:
+ if (list.length > 1) {
+ final Integer stream = (Integer) list[0];
+ sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_ICON, stream);
+ final Integer iconState = (Integer) list[1];
+ sUiEventLogger.log(VolumeDialogEvent.fromIconState(iconState));
+ sb.append(AudioSystem.streamToString(stream)).append(' ')
+ .append(iconStateToString(iconState));
+ }
+ break;
+ case EVENT_TOUCH_LEVEL_DONE: // (stream|int) (level|int)
+ if (list.length > 1) {
+ final Integer level = (Integer) list[1];
+ sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_SLIDER, level);
+ sUiEventLogger.log(VolumeDialogEvent.fromSliderLevel(level));
+ }
+ // fall through
+ case EVENT_TOUCH_LEVEL_CHANGED:
+ case EVENT_LEVEL_CHANGED:
+ case EVENT_MUTE_CHANGED: // (stream|int) (level|int)
+ if (list.length > 1) {
sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ')
.append(list[1]);
- break;
- case EVENT_RINGER_TOGGLE:
- logger.action(MetricsEvent.ACTION_VOLUME_RINGER_TOGGLE, (Integer) list[0]);
- break;
- case EVENT_SETTINGS_CLICK:
- logger.action(MetricsEvent.ACTION_VOLUME_SETTINGS);
- break;
- case EVENT_EXTERNAL_RINGER_MODE_CHANGED:
- logger.action(MetricsEvent.ACTION_RINGER_MODE,
- (Integer) list[0]);
- // fall through
- case EVENT_INTERNAL_RINGER_MODE_CHANGED:
- sb.append(ringerModeToString((Integer) list[0]));
- break;
- case EVENT_ZEN_MODE_CHANGED:
- sb.append(zenModeToString((Integer) list[0]));
- break;
- case EVENT_SUPPRESSOR_CHANGED:
- sb.append(list[0]).append(' ').append(list[1]);
- break;
- case EVENT_SHOW_USB_OVERHEAT_ALARM:
- logger.visible(MetricsEvent.POWER_OVERHEAT_ALARM);
- logger.histogram("show_usb_overheat_alarm",
- (Boolean) list[1] ? 1 : 0);
- sb.append(SHOW_REASONS[(Integer) list[0]]).append(" keyguard=").append(list[1]);
- break;
- case EVENT_DISMISS_USB_OVERHEAT_ALARM:
- logger.hidden(MetricsEvent.POWER_OVERHEAT_ALARM);
- logger.histogram("dismiss_usb_overheat_alarm",
- (Boolean) list[1] ? 1 : 0);
- sb.append(DISMISS_REASONS[(Integer) list[0]])
- .append(" keyguard=").append(list[1]);
- break;
- default:
- sb.append(Arrays.asList(list));
- break;
+ }
+ break;
+ case EVENT_KEY: // (stream|int) (lastAudibleStreamVolume)
+ if (list.length > 1) {
+ final Integer stream = (Integer) list[0];
+ sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_KEY, stream);
+ final Integer level = (Integer) list[1];
+ sUiEventLogger.log(VolumeDialogEvent.fromKeyLevel(level));
+ sb.append(AudioSystem.streamToString(stream)).append(' ').append(level);
+ }
+ break;
+ case EVENT_RINGER_TOGGLE: {
+ final Integer ringerMode = (Integer) list[0];
+ sLegacyLogger.action(MetricsEvent.ACTION_VOLUME_RINGER_TOGGLE, ringerMode);
+ sUiEventLogger.log(VolumeDialogEvent.fromRingerMode(ringerMode));
+ sb.append(ringerModeToString(ringerMode));
+ break;
}
+ case EVENT_EXTERNAL_RINGER_MODE_CHANGED: {
+ final Integer ringerMode = (Integer) list[0];
+ sLegacyLogger.action(MetricsEvent.ACTION_RINGER_MODE, ringerMode);
+ }
+ // fall through
+ case EVENT_INTERNAL_RINGER_MODE_CHANGED: {
+ final Integer ringerMode = (Integer) list[0];
+ sb.append(ringerModeToString(ringerMode));
+ break;
+ }
+ case EVENT_ZEN_MODE_CHANGED: {
+ final Integer zenMode = (Integer) list[0];
+ sb.append(zenModeToString(zenMode));
+ sUiEventLogger.log(ZenModeEvent.fromZenMode(zenMode));
+ break;
+ }
+ case EVENT_SUPPRESSOR_CHANGED: // (component|string) (name|string)
+ if (list.length > 1) {
+ sb.append(list[0]).append(' ').append(list[1]);
+ }
+ break;
+ case EVENT_SHOW_USB_OVERHEAT_ALARM:
+ sLegacyLogger.visible(MetricsEvent.POWER_OVERHEAT_ALARM);
+ sUiEventLogger.log(VolumeDialogEvent.USB_OVERHEAT_ALARM);
+ if (list.length > 1) {
+ final Boolean keyguard = (Boolean) list[1];
+ sLegacyLogger.histogram("show_usb_overheat_alarm", keyguard ? 1 : 0);
+ final Integer reason = (Integer) list[0];
+ sb.append(SHOW_REASONS[reason]).append(" keyguard=").append(keyguard);
+ }
+ break;
+ case EVENT_DISMISS_USB_OVERHEAT_ALARM:
+ sLegacyLogger.hidden(MetricsEvent.POWER_OVERHEAT_ALARM);
+ sUiEventLogger.log(VolumeDialogEvent.USB_OVERHEAT_ALARM_DISMISSED);
+ if (list.length > 1) {
+ final Boolean keyguard = (Boolean) list[1];
+ sLegacyLogger.histogram("dismiss_usb_overheat_alarm", keyguard ? 1 : 0);
+ final Integer reason = (Integer) list[0];
+ sb.append(DISMISS_REASONS[reason])
+ .append(" keyguard=").append(keyguard);
+ }
+ break;
+ default:
+ sb.append(Arrays.asList(list));
+ break;
}
- Log.i(TAG, sb.toString());
- if (sCallback != null) {
- sCallback.writeEvent(time, tag, list);
- }
+ return sb.toString();
}
public static void writeState(long time, State state) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/EventsTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/EventsTest.java
new file mode 100644
index 000000000000..701b2fab5f85
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/EventsTest.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume;
+
+import static org.junit.Assert.assertEquals;
+
+import android.media.AudioManager;
+import android.media.AudioSystem;
+import android.metrics.LogMaker;
+import android.provider.Settings;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.logging.testing.FakeMetricsLogger;
+import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Queue;
+
+/**
+ * Parameterized unit test for Events.logEvent.
+ *
+ * This test captures a translation table between the Event class tags, the debugging logs,
+ * the event-buffer logs, and the statsd logs.
+ *
+ * This test works as a straight JUnit4 test, but is declared as a SysuiTestCase because
+ * AAAPlusPlusVerifySysuiRequiredTestPropertiesTest requires all tests in SystemUiTest extend
+ * either SysuiTestCase or SysUiBaseFragmentTest.
+ *
+ */
+@RunWith(Parameterized.class)
+@SmallTest
+public class EventsTest extends SysuiTestCase {
+ private FakeMetricsLogger mLegacyLogger;
+ private UiEventLoggerFake mUiEventLogger;
+
+ @Before
+ public void setFakeLoggers() {
+ mLegacyLogger = new FakeMetricsLogger();
+ Events.sLegacyLogger = mLegacyLogger;
+ mUiEventLogger = new UiEventLoggerFake();
+ Events.sUiEventLogger = mUiEventLogger;
+ }
+
+ // Parameters for calling writeEvent with arbitrary args.
+ @Parameterized.Parameter
+ public int mTag;
+
+ @Parameterized.Parameter(1)
+ public Object[] mArgs;
+
+ // Expect returned string exactly matches.
+ @Parameterized.Parameter(2)
+ public String mExpectedMessage;
+
+ // Expect these MetricsLogger calls.
+
+ @Parameterized.Parameter(3)
+ public int[] mExpectedMetrics;
+
+ // Expect this UiEvent (use null if there isn't one).
+ @Parameterized.Parameter(4)
+ public UiEventLogger.UiEventEnum mUiEvent;
+
+ @Test
+ public void testLogEvent() {
+ String result = Events.logEvent(mTag, mArgs);
+ assertEquals("Show Dialog", mExpectedMessage, result);
+
+ Queue<LogMaker> logs = mLegacyLogger.getLogs();
+ if (mExpectedMetrics == null) {
+ assertEquals(0, logs.size());
+ } else {
+ assertEquals(mExpectedMetrics.length, logs.size());
+ if (mExpectedMetrics.length > 0) {
+ assertEquals(mExpectedMetrics[0], logs.remove().getCategory());
+ }
+ if (mExpectedMetrics.length > 1) {
+ assertEquals(mExpectedMetrics[1], logs.remove().getCategory());
+ }
+ }
+ Queue<UiEventLoggerFake.FakeUiEvent> events = mUiEventLogger.getLogs();
+ if (mUiEvent != null) {
+ assertEquals(mUiEvent.getId(), events.remove().eventId);
+ }
+ }
+
+ @Parameterized.Parameters(name = "{index}: {2}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {Events.EVENT_SETTINGS_CLICK, null,
+ "writeEvent settings_click",
+ new int[]{MetricsEvent.ACTION_VOLUME_SETTINGS},
+ Events.VolumeDialogEvent.VOLUME_DIALOG_SETTINGS_CLICK},
+ {Events.EVENT_SHOW_DIALOG, new Object[]{Events.SHOW_REASON_VOLUME_CHANGED, false},
+ "writeEvent show_dialog volume_changed keyguard=false",
+ new int[]{MetricsEvent.VOLUME_DIALOG,
+ MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM},
+ Events.VolumeDialogOpenEvent.VOLUME_DIALOG_SHOW_VOLUME_CHANGED},
+ {Events.EVENT_EXPAND, new Object[]{true},
+ "writeEvent expand true",
+ new int[]{MetricsEvent.VOLUME_DIALOG_DETAILS},
+ Events.VolumeDialogEvent.VOLUME_DIALOG_EXPAND_DETAILS},
+ {Events.EVENT_DISMISS_DIALOG,
+ new Object[]{Events.DISMISS_REASON_TOUCH_OUTSIDE, true},
+ "writeEvent dismiss_dialog touch_outside",
+ new int[]{MetricsEvent.VOLUME_DIALOG},
+ Events.VolumeDialogCloseEvent.VOLUME_DIALOG_DISMISS_TOUCH_OUTSIDE},
+ {Events.EVENT_ACTIVE_STREAM_CHANGED, new Object[]{AudioSystem.STREAM_ACCESSIBILITY},
+ "writeEvent active_stream_changed STREAM_ACCESSIBILITY",
+ new int[]{MetricsEvent.ACTION_VOLUME_STREAM},
+ Events.VolumeDialogEvent.VOLUME_DIALOG_ACTIVE_STREAM_CHANGED},
+ {Events.EVENT_ICON_CLICK,
+ new Object[]{AudioSystem.STREAM_MUSIC, Events.ICON_STATE_MUTE},
+ "writeEvent icon_click STREAM_MUSIC mute",
+ new int[]{MetricsEvent.ACTION_VOLUME_ICON},
+ Events.VolumeDialogEvent.VOLUME_DIALOG_MUTE_STREAM},
+ {Events.EVENT_TOUCH_LEVEL_DONE,
+ new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 0},
+ "writeEvent touch_level_done STREAM_MUSIC 0",
+ new int[]{MetricsEvent.ACTION_VOLUME_SLIDER},
+ Events.VolumeDialogEvent.VOLUME_DIALOG_SLIDER_TO_ZERO},
+ {Events.EVENT_TOUCH_LEVEL_DONE,
+ new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 1},
+ "writeEvent touch_level_done STREAM_MUSIC 1",
+ new int[]{MetricsEvent.ACTION_VOLUME_SLIDER},
+ Events.VolumeDialogEvent.VOLUME_DIALOG_SLIDER},
+ {Events.EVENT_TOUCH_LEVEL_CHANGED,
+ new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 0},
+ "writeEvent touch_level_changed STREAM_MUSIC 0",
+ null, null},
+ {Events.EVENT_LEVEL_CHANGED,
+ new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 0},
+ "writeEvent level_changed STREAM_MUSIC 0",
+ null, null},
+ {Events.EVENT_MUTE_CHANGED,
+ new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 0},
+ "writeEvent mute_changed STREAM_MUSIC 0",
+ null, null},
+ {Events.EVENT_KEY,
+ new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 0},
+ "writeEvent key STREAM_MUSIC 0",
+ new int[]{MetricsEvent.ACTION_VOLUME_KEY},
+ Events.VolumeDialogEvent.VOLUME_KEY_TO_ZERO},
+ {Events.EVENT_KEY,
+ new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 1},
+ "writeEvent key STREAM_MUSIC 1",
+ new int[]{MetricsEvent.ACTION_VOLUME_KEY},
+ Events.VolumeDialogEvent.VOLUME_KEY},
+ {Events.EVENT_RINGER_TOGGLE, new Object[]{AudioManager.RINGER_MODE_NORMAL},
+ "writeEvent ringer_toggle normal",
+ new int[]{MetricsEvent.ACTION_VOLUME_RINGER_TOGGLE},
+ Events.VolumeDialogEvent.RINGER_MODE_NORMAL},
+ {Events.EVENT_EXTERNAL_RINGER_MODE_CHANGED,
+ new Object[]{AudioManager.RINGER_MODE_NORMAL},
+ "writeEvent external_ringer_mode_changed normal",
+ new int[]{MetricsEvent.ACTION_RINGER_MODE},
+ null},
+ {Events.EVENT_INTERNAL_RINGER_MODE_CHANGED,
+ new Object[]{AudioManager.RINGER_MODE_NORMAL},
+ "writeEvent internal_ringer_mode_changed normal",
+ null, null},
+ {Events.EVENT_ZEN_MODE_CHANGED,
+ new Object[]{Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS},
+ "writeEvent zen_mode_changed important_interruptions",
+ null, Events.ZenModeEvent.ZEN_MODE_IMPORTANT_ONLY},
+ {Events.EVENT_ZEN_MODE_CHANGED,
+ new Object[]{Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS},
+ "writeEvent zen_mode_changed important_interruptions",
+ null, Events.ZenModeEvent.ZEN_MODE_IMPORTANT_ONLY},
+ {Events.EVENT_SUPPRESSOR_CHANGED,
+ new Object[]{"component", "name"},
+ "writeEvent suppressor_changed component name",
+ null, null},
+ {Events.EVENT_SHOW_USB_OVERHEAT_ALARM,
+ new Object[]{Events.SHOW_REASON_USB_OVERHEAD_ALARM_CHANGED, true},
+ "writeEvent show_usb_overheat_alarm usb_temperature_above_threshold "
+ + "keyguard=true",
+ new int[]{MetricsEvent.POWER_OVERHEAT_ALARM,
+ MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM},
+ Events.VolumeDialogEvent.USB_OVERHEAT_ALARM},
+ {Events.EVENT_DISMISS_USB_OVERHEAT_ALARM,
+ new Object[]{Events.DISMISS_REASON_USB_OVERHEAD_ALARM_CHANGED, true},
+ "writeEvent dismiss_usb_overheat_alarm usb_temperature_below_threshold "
+ + "keyguard=true",
+ new int[]{MetricsEvent.POWER_OVERHEAT_ALARM,
+ MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM},
+ Events.VolumeDialogEvent.USB_OVERHEAT_ALARM_DISMISSED},
+ });
+ }
+}
+