• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.qs.tiles;
18 
19 import static junit.framework.TestCase.assertEquals;
20 import static junit.framework.TestCase.assertFalse;
21 import static junit.framework.TestCase.assertTrue;
22 
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.spy;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28 
29 import android.content.BroadcastReceiver;
30 import android.content.ComponentName;
31 import android.content.Intent;
32 import android.os.Handler;
33 import android.os.RemoteException;
34 import android.os.UserHandle;
35 import android.provider.Settings;
36 import android.service.dreams.IDreamManager;
37 import android.service.quicksettings.Tile;
38 import android.testing.AndroidTestingRunner;
39 import android.testing.TestableLooper;
40 
41 import androidx.test.filters.SmallTest;
42 
43 import com.android.internal.logging.MetricsLogger;
44 import com.android.systemui.R;
45 import com.android.systemui.SysuiTestCase;
46 import com.android.systemui.broadcast.BroadcastDispatcher;
47 import com.android.systemui.classifier.FalsingManagerFake;
48 import com.android.systemui.plugins.ActivityStarter;
49 import com.android.systemui.plugins.statusbar.StatusBarStateController;
50 import com.android.systemui.qs.QSHost;
51 import com.android.systemui.qs.logging.QSLogger;
52 import com.android.systemui.qs.tileimpl.QSTileImpl;
53 import com.android.systemui.settings.UserTracker;
54 import com.android.systemui.util.settings.FakeSettings;
55 import com.android.systemui.util.settings.SecureSettings;
56 
57 import org.junit.After;
58 import org.junit.Before;
59 import org.junit.Test;
60 import org.junit.runner.RunWith;
61 import org.mockito.ArgumentCaptor;
62 import org.mockito.Mock;
63 import org.mockito.MockitoAnnotations;
64 
65 @RunWith(AndroidTestingRunner.class)
66 @TestableLooper.RunWithLooper(setAsMainLooper = true)
67 @SmallTest
68 public class DreamTileTest extends SysuiTestCase {
69 
70     @Mock
71     private ActivityStarter mActivityStarter;
72     @Mock
73     private QSHost mHost;
74     @Mock
75     private MetricsLogger mMetricsLogger;
76     @Mock
77     private QSLogger mQSLogger;
78     @Mock
79     private StatusBarStateController mStatusBarStateController;
80     @Mock
81     private IDreamManager mDreamManager;
82     @Mock
83     private BroadcastDispatcher mBroadcastDispatcher;
84     @Mock
85     private UserTracker mUserTracker;
86 
87     private TestableLooper mTestableLooper;
88 
89     private DreamTile mTile;
90 
91     private SecureSettings mSecureSettings;
92 
93     private static final ComponentName COLORS_DREAM_COMPONENT_NAME = new ComponentName(
94             "com.android.dreams", ".Colors");
95 
96     private static final int DEFAULT_USER = 0;
97 
98     private final String mExpectedTileLabel = mContext.getResources().getString(
99             R.string.quick_settings_screensaver_label);
100 
101     @Before
setUp()102     public void setUp() throws Exception {
103         MockitoAnnotations.initMocks(this);
104         mSecureSettings = new FakeSettings();
105         mTestableLooper = TestableLooper.get(this);
106 
107         when(mHost.getUserId()).thenReturn(DEFAULT_USER);
108         when(mHost.getContext()).thenReturn(mContext);
109 
110         mTile = spy(constructTileForTest(true, false));
111 
112         mTestableLooper.processAllMessages();
113         mTile.initialize();
114     }
115 
116     @After
tearDown()117     public void tearDown() {
118         mTile.destroy();
119         mTestableLooper.processAllMessages();
120     }
121 
122     @Test
testNotAvailable()123     public void testNotAvailable() throws RemoteException {
124         // Should not be available if screensaver is disabled
125         setScreensaverEnabled(false);
126 
127         mTile.refreshState();
128         mTestableLooper.processAllMessages();
129         assertEquals(Tile.STATE_UNAVAILABLE, mTile.getState().state);
130 
131         // Should not be available if component is not set
132         mSecureSettings.putInt(Settings.Secure.SCREENSAVER_ENABLED, 1);
133         when(mDreamManager.getDreamComponents()).thenReturn(null);
134 
135         mTestableLooper.processAllMessages();
136         assertEquals(Tile.STATE_UNAVAILABLE, mTile.getState().state);
137         assertEquals(mExpectedTileLabel, mTile.getState().contentDescription);
138     }
139 
140     @Test
testInactiveWhenDreaming()141     public void testInactiveWhenDreaming() throws RemoteException {
142         setScreensaverEnabled(true);
143 
144         when(mDreamManager.getDreamComponents()).thenReturn(new ComponentName[]{
145                 COLORS_DREAM_COMPONENT_NAME
146         });
147         when(mDreamManager.isDreaming()).thenReturn(false);
148 
149         mTile.refreshState();
150         mTestableLooper.processAllMessages();
151         assertEquals(Tile.STATE_INACTIVE, mTile.getState().state);
152     }
153 
154     @Test
testActive()155     public void testActive() throws RemoteException {
156         setScreensaverEnabled(true);
157 
158         when(mDreamManager.getDreamComponents()).thenReturn(new ComponentName[]{
159                 COLORS_DREAM_COMPONENT_NAME
160         });
161         when(mDreamManager.isDreaming()).thenReturn(true);
162 
163         mTile.refreshState();
164         mTestableLooper.processAllMessages();
165         assertEquals(Tile.STATE_ACTIVE, mTile.getState().state);
166     }
167 
168     @Test
testClick()169     public void testClick() throws RemoteException {
170         // Set the AOSP dream enabled as the base setup.
171         setScreensaverEnabled(true);
172         when(mDreamManager.getDreamComponents()).thenReturn(new ComponentName[]{
173                 COLORS_DREAM_COMPONENT_NAME
174         });
175         when(mDreamManager.isDreaming()).thenReturn(false);
176 
177         mTile.refreshState();
178         mTestableLooper.processAllMessages();
179         assertEquals(Tile.STATE_INACTIVE, mTile.getState().state);
180 
181         // Now click
182         mTile.handleClick(null /* view */);
183 
184         verify(mDreamManager).dream();
185 
186         when(mDreamManager.isDreaming()).thenReturn(true);
187         mTile.refreshState();
188         mTestableLooper.processAllMessages();
189         assertEquals(Tile.STATE_ACTIVE, mTile.getState().state);
190 
191         // Click again to see that other method is called
192         mTile.handleClick(null /* view */);
193 
194         verify(mDreamManager).awaken();
195     }
196 
197     @Test
testContentDescription()198     public void testContentDescription() {
199         assertEquals(mExpectedTileLabel, mTile.getContentDescription(null));
200 
201         final String testDreamName = "MyDream";
202         assertEquals(mExpectedTileLabel + ", " + testDreamName,
203                 mTile.getContentDescription(testDreamName));
204     }
205 
206     @Test
testUserAvailability()207     public void testUserAvailability() {
208         DreamTile unsupportedTile = constructTileForTest(false, true);
209         assertFalse(unsupportedTile.isAvailable());
210 
211         DreamTile supportedTileAllUsers = constructTileForTest(true, false);
212 
213         UserHandle systemUserHandle = mock(UserHandle.class);
214         when(systemUserHandle.isSystem()).thenReturn(true);
215 
216         UserHandle nonSystemUserHandle = mock(UserHandle.class);
217         when(nonSystemUserHandle.isSystem()).thenReturn(false);
218 
219         when(mUserTracker.getUserHandle()).thenReturn(systemUserHandle);
220         assertTrue(supportedTileAllUsers.isAvailable());
221         when(mUserTracker.getUserHandle()).thenReturn(nonSystemUserHandle);
222         assertTrue(supportedTileAllUsers.isAvailable());
223 
224         DreamTile supportedTileOnlySystemUser = constructTileForTest(true, true);
225         when(mUserTracker.getUserHandle()).thenReturn(systemUserHandle);
226         assertTrue(supportedTileOnlySystemUser.isAvailable());
227         when(mUserTracker.getUserHandle()).thenReturn(nonSystemUserHandle);
228         assertFalse(supportedTileOnlySystemUser.isAvailable());
229     }
230 
231     @Test
testIconDockState()232     public void testIconDockState() {
233         final DreamTile dockedTile = constructTileForTest(true, false);
234 
235         final ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
236                 BroadcastReceiver.class);
237         dockedTile.handleSetListening(true);
238         verify(mBroadcastDispatcher).registerReceiver(receiverCaptor.capture(), any());
239         final BroadcastReceiver receiver = receiverCaptor.getValue();
240 
241         Intent dockIntent = new Intent(Intent.ACTION_DOCK_EVENT);
242         dockIntent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_DESK);
243         receiver.onReceive(mContext, dockIntent);
244         mTestableLooper.processAllMessages();
245         assertEquals(QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_screen_saver),
246                 dockedTile.getState().icon);
247 
248         dockIntent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
249         receiver.onReceive(mContext, dockIntent);
250         mTestableLooper.processAllMessages();
251         assertEquals(QSTileImpl.ResourceIcon.get(R.drawable.ic_qs_screen_saver_undocked),
252                 dockedTile.getState().icon);
253     }
254 
setScreensaverEnabled(boolean enabled)255     private void setScreensaverEnabled(boolean enabled) {
256         mSecureSettings.putIntForUser(Settings.Secure.SCREENSAVER_ENABLED, enabled ? 1 : 0,
257                 DEFAULT_USER);
258     }
259 
constructTileForTest(boolean dreamSupported, boolean dreamOnlyEnabledForSystemUser)260     private DreamTile constructTileForTest(boolean dreamSupported,
261             boolean dreamOnlyEnabledForSystemUser) {
262         return new DreamTile(
263                 mHost,
264                 mTestableLooper.getLooper(),
265                 new Handler(mTestableLooper.getLooper()),
266                 new FalsingManagerFake(),
267                 mMetricsLogger,
268                 mStatusBarStateController,
269                 mActivityStarter,
270                 mQSLogger,
271                 mDreamManager,
272                 mSecureSettings,
273                 mBroadcastDispatcher,
274                 mUserTracker,
275                 dreamSupported, dreamOnlyEnabledForSystemUser);
276     }
277 }
278