blob: 1240a4815b98532aca44265b95c3d0ceba8d76b1 [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;
26import android.testing.AndroidTestingRunner;
27import android.testing.TestableLooper;
28import android.testing.TestableLooper.RunWithLooper;
Jason Monk0b80c4e2017-05-01 15:38:34 -040029
Brett Chabot84151d92019-02-27 15:37:59 -080030import androidx.test.filters.SmallTest;
31
Jason Monk0b80c4e2017-05-01 15:38:34 -040032import com.android.systemui.SysuiTestCase;
33import com.android.systemui.plugins.OverlayPlugin;
34import com.android.systemui.plugins.Plugin;
35import com.android.systemui.plugins.PluginListener;
Tony Wickham023cb192018-09-13 15:23:04 -070036import com.android.systemui.shared.plugins.PluginManager;
Jason Monk0b80c4e2017-05-01 15:38:34 -040037import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
38import com.android.systemui.statusbar.policy.ExtensionController.Extension;
39import com.android.systemui.statusbar.policy.ExtensionController.TunerFactory;
40import com.android.systemui.tuner.TunerService;
41import com.android.systemui.tuner.TunerService.Tunable;
Jason Monk7fc1f9b2018-12-20 15:12:17 -050042import com.android.systemui.util.leak.LeakDetector;
Jason Monk0b80c4e2017-05-01 15:38:34 -040043
44import org.junit.Before;
45import org.junit.Test;
46import org.junit.runner.RunWith;
47import org.mockito.ArgumentCaptor;
48
49import java.util.Map;
50import java.util.function.Consumer;
51
52@RunWith(AndroidTestingRunner.class)
Jason Monkfba8faf2017-05-23 10:42:59 -040053@SmallTest
Jason Monk0b80c4e2017-05-01 15:38:34 -040054public class ExtensionControllerImplTest extends SysuiTestCase {
55
56 private PluginManager mPluginManager;
57 private TunerService mTunerService;
58 private ExtensionController mExtensionController;
59 private ConfigurationController mConfigurationController;
60
61 @Before
62 public void setup() {
63 mPluginManager = mDependency.injectMockDependency(PluginManager.class);
64 mTunerService = mDependency.injectMockDependency(TunerService.class);
65 mConfigurationController = mDependency.injectMockDependency(ConfigurationController.class);
Jason Monk7fc1f9b2018-12-20 15:12:17 -050066 mExtensionController = new ExtensionControllerImpl(mContext,
67 mock(LeakDetector.class), mPluginManager, mTunerService, mConfigurationController);
Jason Monk0b80c4e2017-05-01 15:38:34 -040068 }
69
70 @Test
71 public void testPlugin() {
72 OverlayPlugin plugin = mock(OverlayPlugin.class);
73
74 Extension ext = mExtensionController.newExtension(OverlayPlugin.class)
75 .withPlugin(OverlayPlugin.class)
76 .build();
77 ArgumentCaptor<PluginListener> listener = ArgumentCaptor.forClass(PluginListener.class);
78 verify(mPluginManager).addPluginListener(eq(OverlayPlugin.ACTION), listener.capture(),
79 eq(OverlayPlugin.class));
80
81 listener.getValue().onPluginConnected(plugin, null);
82 assertEquals(plugin, ext.get());
83
84 ext.destroy();
85 verify(mPluginManager).removePluginListener(any());
86 }
87
88 @Test
89 public void testTuner() {
90 String[] keys = new String[] { "key1", "key2" };
91 TunerFactory<Object> factory = new ExtensionController.TunerFactory() {
92 @Override
93 public String[] keys() {
94 return keys;
95 }
96
97 @Override
98 public Object create(Map settings) {
99 return null;
100 }
101 };
102 Extension ext = mExtensionController.newExtension(Object.class)
103 .withTunerFactory(factory)
104 .build();
105 verify(mTunerService).addTunable(any(), eq(keys[0]), eq(keys[1]));
106
107 ext.destroy();
108 verify(mTunerService).removeTunable(any());
109 }
110
111 @Test
112 @RunWithLooper
113 public void testUiMode() {
114 Object o = new Object();
115 Extension ext = mExtensionController.newExtension(Object.class)
116 .withUiMode(Configuration.UI_MODE_TYPE_CAR, () -> o)
117 .build();
118 ArgumentCaptor<ConfigurationListener> captor = ArgumentCaptor.forClass(
119 ConfigurationListener.class);
120 verify(mConfigurationController).addCallback(captor.capture());
121
122 Configuration c = new Configuration(mContext.getResources().getConfiguration());
123 c.uiMode = 0;
124 captor.getValue().onConfigChanged(c);
125 TestableLooper.get(this).processAllMessages();
126 assertNull(ext.get());
127
128 c.uiMode = Configuration.UI_MODE_TYPE_CAR;
129 captor.getValue().onConfigChanged(c);
130 TestableLooper.get(this).processAllMessages();
131 assertEquals(o, ext.get());
132
133 ext.destroy();
134 verify(mConfigurationController).removeCallback(eq(captor.getValue()));
135 }
136
137 @Test
138 public void testDefault() {
139 Object o = new Object();
140 Extension ext = mExtensionController.newExtension(Object.class)
141 .withDefault(() -> o)
142 .build();
143 assertEquals(o, ext.get());
144 }
145
146 @Test
147 @RunWithLooper
148 public void testSortOrder() {
Jason Monk0b80c4e2017-05-01 15:38:34 -0400149 Object def = new Object();
150 Object uiMode = new Object();
151 Object tuner = new Object();
152 Plugin plugin = mock(Plugin.class);
153 TunerFactory<Object> factory = mock(TunerFactory.class);
154 Extension ext = mExtensionController.newExtension(Object.class)
155 .withDefault(() -> def)
156 .withUiMode(Configuration.UI_MODE_TYPE_CAR, () -> uiMode)
157 .withTunerFactory(factory)
158 .withPlugin(Object.class, "some_action")
159 .build();
160
161 // Test default first.
162 assertEquals(def, ext.get());
163
164 // Enable a UI mode and check that.
165 ArgumentCaptor<ConfigurationListener> captor = ArgumentCaptor.forClass(
166 ConfigurationListener.class);
167 verify(mConfigurationController).addCallback(captor.capture());
168 Configuration c = new Configuration(mContext.getResources().getConfiguration());
169 c.uiMode |= Configuration.UI_MODE_TYPE_CAR;
170 captor.getValue().onConfigChanged(c);
171 TestableLooper.get(this).processAllMessages();
172 assertEquals(uiMode, ext.get());
173
174 // Turn on tuner item and check that.
175 when(factory.create(any())).thenReturn(tuner);
176 ArgumentCaptor<Tunable> tunable = ArgumentCaptor.forClass(Tunable.class);
177 verify(mTunerService).addTunable(tunable.capture(), any());
178 tunable.getValue().onTuningChanged(null, null);
179 assertEquals(tuner, ext.get());
180
181 // Lastly, check a plugin.
182 ArgumentCaptor<PluginListener> listener = ArgumentCaptor.forClass(PluginListener.class);
183 verify(mPluginManager).addPluginListener(any(), listener.capture(), any());
184 listener.getValue().onPluginConnected(plugin, null);
185 assertEquals(plugin, ext.get());
186 }
187
188 @Test
189 public void testCallback() {
190 Consumer<Object> callback = mock(Consumer.class);
191 final Object o = new Object();
192 mExtensionController.newExtension(Object.class)
193 .withDefault(() -> o)
194 .withCallback(callback)
195 .build();
196 verify(callback).accept(eq(o));
197 }
198
199}