1 /*
2  * Copyright (C) 2019 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 static org.junit.Assert.assertEquals;
20 
21 import android.media.AudioManager;
22 import android.media.AudioSystem;
23 import android.metrics.LogMaker;
24 import android.provider.Settings;
25 
26 import androidx.test.filters.SmallTest;
27 
28 import com.android.internal.logging.UiEventLogger;
29 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
30 import com.android.internal.logging.testing.FakeMetricsLogger;
31 import com.android.internal.logging.testing.UiEventLoggerFake;
32 import com.android.systemui.SysuiTestCase;
33 
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.junit.runners.Parameterized;
38 
39 import java.util.Arrays;
40 import java.util.Collection;
41 import java.util.Queue;
42 
43 /**
44  * Parameterized unit test for Events.logEvent.
45  *
46  * This test captures a translation table between the Event class tags, the debugging logs,
47  * the event-buffer logs, and the statsd logs.
48  *
49  * This test works as a straight JUnit4 test, but is declared as a SysuiTestCase because
50  * AAAPlusPlusVerifySysuiRequiredTestPropertiesTest requires all tests in SystemUiTest extend
51  * either SysuiTestCase or SysUiBaseFragmentTest.
52  *
53  */
54 @RunWith(Parameterized.class)
55 @SmallTest
56 public class EventsTest extends SysuiTestCase {
57     private FakeMetricsLogger mLegacyLogger;
58     private UiEventLoggerFake mUiEventLogger;
59 
60     @Before
setFakeLoggers()61     public void setFakeLoggers() {
62         mLegacyLogger = new FakeMetricsLogger();
63         Events.sLegacyLogger = mLegacyLogger;
64         mUiEventLogger = new UiEventLoggerFake();
65         Events.sUiEventLogger = mUiEventLogger;
66     }
67 
68     // Parameters for calling writeEvent with arbitrary args.
69     @Parameterized.Parameter
70     public int mTag;
71 
72     @Parameterized.Parameter(1)
73     public Object[] mArgs;
74 
75     // Expect returned string exactly matches.
76     @Parameterized.Parameter(2)
77     public String mExpectedMessage;
78 
79     // Expect these MetricsLogger calls.
80 
81     @Parameterized.Parameter(3)
82     public int[] mExpectedMetrics;
83 
84     // Expect this UiEvent (use null if there isn't one).
85     @Parameterized.Parameter(4)
86     public UiEventLogger.UiEventEnum mUiEvent;
87 
88     @Test
testLogEvent()89     public void testLogEvent() {
90         String result = Events.logEvent(mTag, mArgs);
91         assertEquals("Show Dialog", mExpectedMessage, result);
92 
93         Queue<LogMaker> logs = mLegacyLogger.getLogs();
94         if (mExpectedMetrics == null) {
95             assertEquals(0, logs.size());
96         } else {
97             assertEquals(mExpectedMetrics.length, logs.size());
98             if (mExpectedMetrics.length > 0) {
99                 assertEquals(mExpectedMetrics[0], logs.remove().getCategory());
100             }
101             if (mExpectedMetrics.length > 1) {
102                 assertEquals(mExpectedMetrics[1], logs.remove().getCategory());
103             }
104         }
105         if (mUiEvent != null) {
106             assertEquals(1, mUiEventLogger.numLogs());
107             assertEquals(mUiEvent.getId(), mUiEventLogger.eventId(0));
108         }
109     }
110 
111     @Parameterized.Parameters(name = "{index}: {2}")
data()112     public static Collection<Object[]> data() {
113         return Arrays.asList(new Object[][]{
114                 {Events.EVENT_SETTINGS_CLICK, null,
115                         "writeEvent settings_click",
116                         new int[]{MetricsEvent.ACTION_VOLUME_SETTINGS},
117                         Events.VolumeDialogEvent.VOLUME_DIALOG_SETTINGS_CLICK},
118                 {Events.EVENT_SHOW_DIALOG, new Object[]{Events.SHOW_REASON_VOLUME_CHANGED, false},
119                         "writeEvent show_dialog volume_changed keyguard=false",
120                         new int[]{MetricsEvent.VOLUME_DIALOG,
121                                 MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM},
122                         Events.VolumeDialogOpenEvent.VOLUME_DIALOG_SHOW_VOLUME_CHANGED},
123                 {Events.EVENT_EXPAND, new Object[]{true},
124                         "writeEvent expand true",
125                         new int[]{MetricsEvent.VOLUME_DIALOG_DETAILS},
126                         Events.VolumeDialogEvent.VOLUME_DIALOG_EXPAND_DETAILS},
127                 {Events.EVENT_DISMISS_DIALOG,
128                         new Object[]{Events.DISMISS_REASON_TOUCH_OUTSIDE, true},
129                         "writeEvent dismiss_dialog touch_outside",
130                         new int[]{MetricsEvent.VOLUME_DIALOG},
131                         Events.VolumeDialogCloseEvent.VOLUME_DIALOG_DISMISS_TOUCH_OUTSIDE},
132                 {Events.EVENT_ACTIVE_STREAM_CHANGED, new Object[]{AudioSystem.STREAM_ACCESSIBILITY},
133                         "writeEvent active_stream_changed STREAM_ACCESSIBILITY",
134                         new int[]{MetricsEvent.ACTION_VOLUME_STREAM},
135                         Events.VolumeDialogEvent.VOLUME_DIALOG_ACTIVE_STREAM_CHANGED},
136                 {Events.EVENT_ICON_CLICK,
137                         new Object[]{AudioSystem.STREAM_MUSIC, Events.ICON_STATE_MUTE},
138                         "writeEvent icon_click STREAM_MUSIC mute",
139                         new int[]{MetricsEvent.ACTION_VOLUME_ICON},
140                         Events.VolumeDialogEvent.VOLUME_DIALOG_MUTE_STREAM},
141                 {Events.EVENT_TOUCH_LEVEL_DONE,
142                         new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 0},
143                         "writeEvent touch_level_done STREAM_MUSIC 0",
144                         new int[]{MetricsEvent.ACTION_VOLUME_SLIDER},
145                         Events.VolumeDialogEvent.VOLUME_DIALOG_SLIDER_TO_ZERO},
146                 {Events.EVENT_TOUCH_LEVEL_DONE,
147                         new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 1},
148                         "writeEvent touch_level_done STREAM_MUSIC 1",
149                         new int[]{MetricsEvent.ACTION_VOLUME_SLIDER},
150                         Events.VolumeDialogEvent.VOLUME_DIALOG_SLIDER},
151                 {Events.EVENT_TOUCH_LEVEL_CHANGED,
152                         new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 0},
153                         "writeEvent touch_level_changed STREAM_MUSIC 0",
154                         null, null},
155                 {Events.EVENT_LEVEL_CHANGED,
156                         new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 0},
157                         "writeEvent level_changed STREAM_MUSIC 0",
158                         null, null},
159                 {Events.EVENT_MUTE_CHANGED,
160                         new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 0},
161                         "writeEvent mute_changed STREAM_MUSIC 0",
162                         null, null},
163                 {Events.EVENT_KEY,
164                         new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 0},
165                         "writeEvent key STREAM_MUSIC 0",
166                         new int[]{MetricsEvent.ACTION_VOLUME_KEY},
167                         Events.VolumeDialogEvent.VOLUME_KEY_TO_ZERO},
168                 {Events.EVENT_KEY,
169                         new Object[]{AudioSystem.STREAM_MUSIC, /* volume */ 1},
170                         "writeEvent key STREAM_MUSIC 1",
171                         new int[]{MetricsEvent.ACTION_VOLUME_KEY},
172                         Events.VolumeDialogEvent.VOLUME_KEY},
173                 {Events.EVENT_RINGER_TOGGLE, new Object[]{AudioManager.RINGER_MODE_NORMAL},
174                         "writeEvent ringer_toggle normal",
175                         new int[]{MetricsEvent.ACTION_VOLUME_RINGER_TOGGLE},
176                         Events.VolumeDialogEvent.RINGER_MODE_NORMAL},
177                 {Events.EVENT_EXTERNAL_RINGER_MODE_CHANGED,
178                         new Object[]{AudioManager.RINGER_MODE_NORMAL},
179                         "writeEvent external_ringer_mode_changed normal",
180                         new int[]{MetricsEvent.ACTION_RINGER_MODE},
181                         null},
182                 {Events.EVENT_INTERNAL_RINGER_MODE_CHANGED,
183                         new Object[]{AudioManager.RINGER_MODE_NORMAL},
184                         "writeEvent internal_ringer_mode_changed normal",
185                         null, null},
186                 {Events.EVENT_ZEN_MODE_CHANGED,
187                         new Object[]{Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS},
188                         "writeEvent zen_mode_changed important_interruptions",
189                         null, Events.ZenModeEvent.ZEN_MODE_IMPORTANT_ONLY},
190                 {Events.EVENT_ZEN_MODE_CHANGED,
191                         new Object[]{Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS},
192                         "writeEvent zen_mode_changed important_interruptions",
193                         null, Events.ZenModeEvent.ZEN_MODE_IMPORTANT_ONLY},
194                 {Events.EVENT_SUPPRESSOR_CHANGED,
195                         new Object[]{"component", "name"},
196                         "writeEvent suppressor_changed component name",
197                         null, null},
198                 {Events.EVENT_SHOW_USB_OVERHEAT_ALARM,
199                         new Object[]{Events.SHOW_REASON_USB_OVERHEAD_ALARM_CHANGED, true},
200                         "writeEvent show_usb_overheat_alarm usb_temperature_above_threshold "
201                                 + "keyguard=true",
202                         new int[]{MetricsEvent.POWER_OVERHEAT_ALARM,
203                                 MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM},
204                         Events.VolumeDialogEvent.USB_OVERHEAT_ALARM},
205                 {Events.EVENT_DISMISS_USB_OVERHEAT_ALARM,
206                         new Object[]{Events.DISMISS_REASON_USB_OVERHEAD_ALARM_CHANGED, true},
207                         "writeEvent dismiss_usb_overheat_alarm usb_temperature_below_threshold "
208                                 + "keyguard=true",
209                         new int[]{MetricsEvent.POWER_OVERHEAT_ALARM,
210                                 MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM},
211                         Events.VolumeDialogEvent.USB_OVERHEAT_ALARM_DISMISSED},
212         });
213     }
214 }
215 
216