blob: 4888fb284a35472cab589c08b5bd59dedc481d45 [file] [log] [blame]
Julia Reynolds561d3f42018-01-26 11:31:02 -05001/*
2 * Copyright (C) 2018 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
17package com.android.systemui.volume;
18
Julia Reynolds45d4ab02018-01-31 14:59:14 -050019import static android.media.AudioManager.RINGER_MODE_NORMAL;
20import static android.media.AudioManager.RINGER_MODE_SILENT;
21import static android.media.AudioManager.RINGER_MODE_VIBRATE;
22import static android.media.AudioManager.STREAM_RING;
23
Julia Reynolds561d3f42018-01-26 11:31:02 -050024import static com.android.systemui.volume.Events.DISMISS_REASON_UNKNOWN;
25import static com.android.systemui.volume.Events.SHOW_REASON_UNKNOWN;
26import static com.android.systemui.volume.VolumeDialogControllerImpl.STREAMS;
27
28import static junit.framework.Assert.assertTrue;
29
Julia Reynolds45d4ab02018-01-31 14:59:14 -050030import static org.mockito.Mockito.times;
31import static org.mockito.Mockito.verify;
32import static org.mockito.Mockito.when;
33
Julia Reynolds561d3f42018-01-26 11:31:02 -050034import android.app.KeyguardManager;
35import android.media.AudioManager;
36import android.support.test.filters.SmallTest;
37import android.testing.AndroidTestingRunner;
38import android.testing.TestableLooper;
39import android.text.TextUtils;
40import android.view.View;
41import android.view.ViewGroup;
42import android.widget.ImageView;
43
Julia Reynolds45d4ab02018-01-31 14:59:14 -050044import com.android.systemui.R;
Julia Reynolds561d3f42018-01-26 11:31:02 -050045import com.android.systemui.SysuiTestCase;
46import com.android.systemui.plugins.VolumeDialogController;
Julia Reynolds45d4ab02018-01-31 14:59:14 -050047import com.android.systemui.plugins.VolumeDialogController.State;
Julia Reynolds561d3f42018-01-26 11:31:02 -050048import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
49
50import org.junit.Before;
51import org.junit.Test;
52import org.junit.runner.RunWith;
53import org.mockito.Mock;
54import org.mockito.MockitoAnnotations;
55
56import java.util.function.Predicate;
57
58@SmallTest
59@RunWith(AndroidTestingRunner.class)
60@TestableLooper.RunWithLooper
61public class VolumeDialogImplTest extends SysuiTestCase {
62
63 VolumeDialogImpl mDialog;
64
65 @Mock
66 VolumeDialogController mController;
67
68 @Mock
69 KeyguardManager mKeyguard;
70
71 @Mock
72 AccessibilityManagerWrapper mAccessibilityMgr;
73
74 @Before
75 public void setup() throws Exception {
76 MockitoAnnotations.initMocks(this);
77
78 mController = mDependency.injectMockDependency(VolumeDialogController.class);
79 mAccessibilityMgr = mDependency.injectMockDependency(AccessibilityManagerWrapper.class);
80 getContext().addMockSystemService(KeyguardManager.class, mKeyguard);
81
82 mDialog = new VolumeDialogImpl(getContext());
83 mDialog.init(0, null);
Julia Reynolds45d4ab02018-01-31 14:59:14 -050084 State state = createShellState();
85 mDialog.onStateChangedH(state);
86 }
87
88 private State createShellState() {
89 State state = new VolumeDialogController.State();
Julia Reynolds561d3f42018-01-26 11:31:02 -050090 for (int i = AudioManager.STREAM_VOICE_CALL; i <= AudioManager.STREAM_ACCESSIBILITY; i++) {
91 VolumeDialogController.StreamState ss = new VolumeDialogController.StreamState();
92 ss.name = STREAMS.get(i);
Julia Reynolds45d4ab02018-01-31 14:59:14 -050093 ss.level = 1;
Julia Reynolds561d3f42018-01-26 11:31:02 -050094 state.states.append(i, ss);
95 }
Julia Reynolds45d4ab02018-01-31 14:59:14 -050096 return state;
Julia Reynolds561d3f42018-01-26 11:31:02 -050097 }
98
99 private void navigateViews(View view, Predicate<View> condition) {
100 if (view instanceof ViewGroup) {
101 ViewGroup viewGroup = (ViewGroup) view;
102 for (int i = 0; i < viewGroup.getChildCount(); i++) {
103 navigateViews(viewGroup.getChildAt(i), condition);
104 }
105 } else {
106 String resourceName = null;
107 try {
108 resourceName = getContext().getResources().getResourceName(view.getId());
109 } catch (Exception e) {}
110 assertTrue("View " + resourceName != null ? resourceName : view.getId()
111 + " failed test", condition.test(view));
112 }
113 }
114
115 @Test
116 public void testContentDescriptions() {
117 mDialog.show(SHOW_REASON_UNKNOWN);
118 ViewGroup dialog = mDialog.getDialogView();
119
120 navigateViews(dialog, view -> {
121 if (view instanceof ImageView) {
122 return !TextUtils.isEmpty(view.getContentDescription());
123 } else {
124 return true;
125 }
126 });
127
128 mDialog.dismiss(DISMISS_REASON_UNKNOWN);
129 }
130
Julia Reynolds45d4ab02018-01-31 14:59:14 -0500131 @Test
132 public void testNoDuplicationOfParentState() {
133 mDialog.show(SHOW_REASON_UNKNOWN);
134 ViewGroup dialog = mDialog.getDialogView();
135
136 navigateViews(dialog, view -> !view.isDuplicateParentStateEnabled());
137
138 mDialog.dismiss(DISMISS_REASON_UNKNOWN);
139 }
140
141 @Test
142 public void testNoClickableViewGroups() {
143 mDialog.show(SHOW_REASON_UNKNOWN);
144 ViewGroup dialog = mDialog.getDialogView();
145
146 navigateViews(dialog, view -> {
147 if (view instanceof ViewGroup) {
148 return !view.isClickable();
149 } else {
150 return true;
151 }
152 });
153
154 mDialog.dismiss(DISMISS_REASON_UNKNOWN);
155 }
156
157 @Test
158 public void testTristateToggle_withVibrator() {
159 when(mController.hasVibrator()).thenReturn(true);
160
161 State state = createShellState();
162 state.ringerModeInternal = RINGER_MODE_NORMAL;
163 mDialog.onStateChangedH(state);
164
165 mDialog.show(SHOW_REASON_UNKNOWN);
166 ViewGroup dialog = mDialog.getDialogView();
167
168 // click once, verify updates to vibrate
169 dialog.findViewById(R.id.ringer_icon).performClick();
170 verify(mController, times(1)).setRingerMode(RINGER_MODE_VIBRATE, false);
171
172 // fake the update back to the dialog with the new ringer mode
173 state = createShellState();
174 state.ringerModeInternal = RINGER_MODE_VIBRATE;
175 mDialog.onStateChangedH(state);
176
177 // click once, verify updates to silent
178 dialog.findViewById(R.id.ringer_icon).performClick();
179 verify(mController, times(1)).setRingerMode(RINGER_MODE_SILENT, false);
180 verify(mController, times(1)).setStreamVolume(STREAM_RING, 0);
181
182 // fake the update back to the dialog with the new ringer mode
183 state = createShellState();
184 state.states.get(STREAM_RING).level = 0;
185 state.ringerModeInternal = RINGER_MODE_SILENT;
186 mDialog.onStateChangedH(state);
187
188 // click once, verify updates to normal
189 dialog.findViewById(R.id.ringer_icon).performClick();
190 verify(mController, times(1)).setRingerMode(RINGER_MODE_NORMAL, false);
191 verify(mController, times(1)).setStreamVolume(STREAM_RING, 0);
192 }
193
194 @Test
195 public void testTristateToggle_withoutVibrator() {
196 when(mController.hasVibrator()).thenReturn(false);
197
198 State state = createShellState();
199 state.ringerModeInternal = RINGER_MODE_NORMAL;
200 mDialog.onStateChangedH(state);
201
202 mDialog.show(SHOW_REASON_UNKNOWN);
203 ViewGroup dialog = mDialog.getDialogView();
204
205 // click once, verify updates to silent
206 dialog.findViewById(R.id.ringer_icon).performClick();
207 verify(mController, times(1)).setRingerMode(RINGER_MODE_SILENT, false);
208 verify(mController, times(1)).setStreamVolume(STREAM_RING, 0);
209
210 // fake the update back to the dialog with the new ringer mode
211 state = createShellState();
212 state.states.get(STREAM_RING).level = 0;
213 state.ringerModeInternal = RINGER_MODE_SILENT;
214 mDialog.onStateChangedH(state);
215
216 // click once, verify updates to normal
217 dialog.findViewById(R.id.ringer_icon).performClick();
218 verify(mController, times(1)).setRingerMode(RINGER_MODE_NORMAL, false);
219 verify(mController, times(1)).setStreamVolume(STREAM_RING, 0);
220 }
Julia Reynolds561d3f42018-01-26 11:31:02 -0500221}