blob: 2553ac1e8fcba52c13e321d73f1a6e6ceab8b884 [file] [log] [blame]
Jason Monk0b80c4e2017-05-01 15:38:34 -04001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.systemui.statusbar.policy;
16
17import static org.junit.Assert.assertEquals;
18import static org.junit.Assert.assertNull;
19import static org.mockito.ArgumentMatchers.any;
20import static org.mockito.ArgumentMatchers.eq;
21import static org.mockito.Mockito.mock;
22import static org.mockito.Mockito.verify;
23import static org.mockito.Mockito.when;
24
25import android.content.res.Configuration;
Jason Monkfba8faf2017-05-23 10:42:59 -040026import android.support.test.filters.SmallTest;
Jason Monk0b80c4e2017-05-01 15:38:34 -040027import android.testing.AndroidTestingRunner;
28import android.testing.TestableLooper;
29import android.testing.TestableLooper.RunWithLooper;
Jason Monk0b80c4e2017-05-01 15:38:34 -040030
Jason Monk0b80c4e2017-05-01 15:38:34 -040031import com.android.systemui.SysuiTestCase;
32import com.android.systemui.plugins.OverlayPlugin;
33import com.android.systemui.plugins.Plugin;
34import com.android.systemui.plugins.PluginListener;
Tony Wickham023cb192018-09-13 15:23:04 -070035import com.android.systemui.shared.plugins.PluginManager;
Jason Monk0b80c4e2017-05-01 15:38:34 -040036import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
37import com.android.systemui.statusbar.policy.ExtensionController.Extension;
38import com.android.systemui.statusbar.policy.ExtensionController.TunerFactory;
39import com.android.systemui.tuner.TunerService;
40import com.android.systemui.tuner.TunerService.Tunable;
Jason Monk7fc1f9b2018-12-20 15:12:17 -050041import com.android.systemui.util.leak.LeakDetector;
Jason Monk0b80c4e2017-05-01 15:38:34 -040042
43import org.junit.Before;
44import org.junit.Test;
45import org.junit.runner.RunWith;
46import org.mockito.ArgumentCaptor;
47
48import java.util.Map;
49import java.util.function.Consumer;
50
51@RunWith(AndroidTestingRunner.class)
Jason Monkfba8faf2017-05-23 10:42:59 -040052@SmallTest
Jason Monk0b80c4e2017-05-01 15:38:34 -040053public class ExtensionControllerImplTest extends SysuiTestCase {
54
55 private PluginManager mPluginManager;
56 private TunerService mTunerService;
57 private ExtensionController mExtensionController;
58 private ConfigurationController mConfigurationController;
59
60 @Before
61 public void setup() {
62 mPluginManager = mDependency.injectMockDependency(PluginManager.class);
63 mTunerService = mDependency.injectMockDependency(TunerService.class);
64 mConfigurationController = mDependency.injectMockDependency(ConfigurationController.class);
Jason Monk7fc1f9b2018-12-20 15:12:17 -050065 mExtensionController = new ExtensionControllerImpl(mContext,
66 mock(LeakDetector.class), mPluginManager, mTunerService, mConfigurationController);
Jason Monk0b80c4e2017-05-01 15:38:34 -040067 }
68
69 @Test
70 public void testPlugin() {
71 OverlayPlugin plugin = mock(OverlayPlugin.class);
72
73 Extension ext = mExtensionController.newExtension(OverlayPlugin.class)
74 .withPlugin(OverlayPlugin.class)
75 .build();
76 ArgumentCaptor<PluginListener> listener = ArgumentCaptor.forClass(PluginListener.class);
77 verify(mPluginManager).addPluginListener(eq(OverlayPlugin.ACTION), listener.capture(),
78 eq(OverlayPlugin.class));
79
80 listener.getValue().onPluginConnected(plugin, null);
81 assertEquals(plugin, ext.get());
82
83 ext.destroy();
84 verify(mPluginManager).removePluginListener(any());
85 }
86
87 @Test
88 public void testTuner() {
89 String[] keys = new String[] { "key1", "key2" };
90 TunerFactory<Object> factory = new ExtensionController.TunerFactory() {
91 @Override
92 public String[] keys() {
93 return keys;
94 }
95
96 @Override
97 public Object create(Map settings) {
98 return null;
99 }
100 };
101 Extension ext = mExtensionController.newExtension(Object.class)
102 .withTunerFactory(factory)
103 .build();
104 verify(mTunerService).addTunable(any(), eq(keys[0]), eq(keys[1]));
105
106 ext.destroy();
107 verify(mTunerService).removeTunable(any());
108 }
109
110 @Test
111 @RunWithLooper
112 public void testUiMode() {
113 Object o = new Object();
114 Extension ext = mExtensionController.newExtension(Object.class)
115 .withUiMode(Configuration.UI_MODE_TYPE_CAR, () -> o)
116 .build();
117 ArgumentCaptor<ConfigurationListener> captor = ArgumentCaptor.forClass(
118 ConfigurationListener.class);
119 verify(mConfigurationController).addCallback(captor.capture());
120
121 Configuration c = new Configuration(mContext.getResources().getConfiguration());
122 c.uiMode = 0;
123 captor.getValue().onConfigChanged(c);
124 TestableLooper.get(this).processAllMessages();
125 assertNull(ext.get());
126
127 c.uiMode = Configuration.UI_MODE_TYPE_CAR;
128 captor.getValue().onConfigChanged(c);
129 TestableLooper.get(this).processAllMessages();
130 assertEquals(o, ext.get());
131
132 ext.destroy();
133 verify(mConfigurationController).removeCallback(eq(captor.getValue()));
134 }
135
136 @Test
137 public void testDefault() {
138 Object o = new Object();
139 Extension ext = mExtensionController.newExtension(Object.class)
140 .withDefault(() -> o)
141 .build();
142 assertEquals(o, ext.get());
143 }
144
145 @Test
146 @RunWithLooper
147 public void testSortOrder() {
Jason Monk0b80c4e2017-05-01 15:38:34 -0400148 Object def = new Object();
149 Object uiMode = new Object();
150 Object tuner = new Object();
151 Plugin plugin = mock(Plugin.class);
152 TunerFactory<Object> factory = mock(TunerFactory.class);
153 Extension ext = mExtensionController.newExtension(Object.class)
154 .withDefault(() -> def)
155 .withUiMode(Configuration.UI_MODE_TYPE_CAR, () -> uiMode)
156 .withTunerFactory(factory)
157 .withPlugin(Object.class, "some_action")
158 .build();
159
160 // Test default first.
161 assertEquals(def, ext.get());
162
163 // Enable a UI mode and check that.
164 ArgumentCaptor<ConfigurationListener> captor = ArgumentCaptor.forClass(
165 ConfigurationListener.class);
166 verify(mConfigurationController).addCallback(captor.capture());
167 Configuration c = new Configuration(mContext.getResources().getConfiguration());
168 c.uiMode |= Configuration.UI_MODE_TYPE_CAR;
169 captor.getValue().onConfigChanged(c);
170 TestableLooper.get(this).processAllMessages();
171 assertEquals(uiMode, ext.get());
172
173 // Turn on tuner item and check that.
174 when(factory.create(any())).thenReturn(tuner);
175 ArgumentCaptor<Tunable> tunable = ArgumentCaptor.forClass(Tunable.class);
176 verify(mTunerService).addTunable(tunable.capture(), any());
177 tunable.getValue().onTuningChanged(null, null);
178 assertEquals(tuner, ext.get());
179
180 // Lastly, check a plugin.
181 ArgumentCaptor<PluginListener> listener = ArgumentCaptor.forClass(PluginListener.class);
182 verify(mPluginManager).addPluginListener(any(), listener.capture(), any());
183 listener.getValue().onPluginConnected(plugin, null);
184 assertEquals(plugin, ext.get());
185 }
186
187 @Test
188 public void testCallback() {
189 Consumer<Object> callback = mock(Consumer.class);
190 final Object o = new Object();
191 mExtensionController.newExtension(Object.class)
192 .withDefault(() -> o)
193 .withCallback(callback)
194 .build();
195 verify(callback).accept(eq(o));
196 }
197
198}