• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 package com.android.car;
17 
18 import static org.junit.Assert.assertArrayEquals;
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertNull;
22 import static org.junit.Assert.assertTrue;
23 
24 import android.car.settings.CarSettings;
25 import android.content.Context;
26 import android.content.SharedPreferences;
27 import android.os.HandlerThread;
28 import android.os.Looper;
29 import android.support.test.InstrumentationRegistry;
30 import android.support.test.annotation.UiThreadTest;
31 import android.support.test.filters.MediumTest;
32 import android.support.test.runner.AndroidJUnit4;
33 
34 import com.android.car.GarageModeService.GarageModePolicy;
35 import com.android.car.GarageModeService.WakeupTime;
36 
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 
40 @RunWith(AndroidJUnit4.class)
41 @MediumTest
42 public class GarageModeTest {
43     private static final int WAIT_FOR_COMPLETION_TIME = 3000;//ms
44 
45     @Test
46     @UiThreadTest
testMaintenanceActive()47     public void testMaintenanceActive() throws Exception {
48         MockCarPowerManagementService powerManagementService = new MockCarPowerManagementService();
49         MockDeviceIdleController controller = new MockDeviceIdleController(true);
50         GarageModeServiceForTest garageMode = new GarageModeServiceForTest(getContext(),
51                 powerManagementService,
52                 controller);
53         garageMode.init();
54         final int index1 = garageMode.getGarageModeIndex();
55         assertEquals(garageMode.getMaintenanceWindow(),
56                 powerManagementService.doNotifyPrepareShutdown(false));
57         assertEquals(true, garageMode.isInGarageMode());
58         assertEquals(true, garageMode.isMaintenanceActive());
59 
60         controller.setMaintenanceActivity(false);
61         assertEquals(false, garageMode.isInGarageMode());
62         assertEquals(false, garageMode.isMaintenanceActive());
63         final int index2 = garageMode.getGarageModeIndex();
64 
65         assertEquals(1, index2 - index1);
66     }
67 
68     @Test
69     @UiThreadTest
testMaintenanceInactive()70     public void testMaintenanceInactive() throws Exception {
71         MockCarPowerManagementService powerManagementService = new MockCarPowerManagementService();
72         MockDeviceIdleController controller = new MockDeviceIdleController(false);
73         GarageModeServiceForTest garageMode = new GarageModeServiceForTest(getContext(),
74                 powerManagementService,
75                 controller);
76         garageMode.init();
77         assertEquals(garageMode.getMaintenanceWindow(),
78                 powerManagementService.doNotifyPrepareShutdown(false));
79         assertEquals(true, garageMode.isInGarageMode());
80         assertEquals(false, garageMode.isMaintenanceActive());
81     }
82 
83     @Test
84     @UiThreadTest
testDisplayOn()85     public void testDisplayOn() throws Exception {
86         MockCarPowerManagementService powerManagementService = new MockCarPowerManagementService();
87         MockDeviceIdleController controller = new MockDeviceIdleController(true);
88         GarageModeServiceForTest garageMode = new GarageModeServiceForTest(getContext(),
89                 powerManagementService,
90                 controller);
91         garageMode.init();
92 
93         powerManagementService.doNotifyPrepareShutdown(false);
94         assertTrue(garageMode.getGarageModeIndex() > 0);
95         powerManagementService.doNotifyPowerOn(true);
96         assertEquals(0,garageMode.getGarageModeIndex());
97     }
98 
99     @Test
100     @UiThreadTest
testPolicyIndexing()101     public void testPolicyIndexing() throws Exception {
102         // Background processing of asynchronous messages.
103         HandlerThread thread = new HandlerThread("testPolicy");
104         thread.start();
105 
106         // Test that the index is saved in the prefs and that this index is used to determine the
107         // next wakeup time.
108         MockCarPowerManagementService powerManagementService = new MockCarPowerManagementService();
109         MockDeviceIdleController controller = new MockDeviceIdleController(true);
110         GarageModeServiceForTest garageMode = new GarageModeServiceForTest(getContext(),
111                 powerManagementService,
112                 controller,
113                 thread.getLooper());
114         String[] policy = {
115                 "15m,1",
116                 "6h,8",
117                 "1d,5",
118         };
119         SharedPreferences prefs =
120                 getContext().getSharedPreferences("testPolicy", Context.MODE_PRIVATE);
121         prefs.edit().putInt("garage_mode_index", 0).apply();
122         garageMode.init(policy, prefs);
123 
124         assertEquals(15 * 60, garageMode.getWakeupTime());
125         garageMode.onPrepareShutdown(false);
126         garageMode.onShutdown();
127         assertEquals(6 * 60 * 60, garageMode.getWakeupTime());
128         Thread.sleep(WAIT_FOR_COMPLETION_TIME);
129         assertEquals(1, prefs.getInt("garage_mode_index", 0));
130 
131         garageMode = new GarageModeServiceForTest(getContext(),
132                 powerManagementService,
133                 controller,
134                 thread.getLooper());
135         // Jump ahead 8 restarts.
136         prefs = getContext().getSharedPreferences("testPolicy", Context.MODE_PRIVATE);
137         prefs.edit().putInt("garage_mode_index", 8).apply();
138         garageMode.init(policy, prefs);
139 
140         assertEquals(6 * 60 * 60, garageMode.getWakeupTime());
141         garageMode.onPrepareShutdown(false);
142         garageMode.onShutdown();
143         assertEquals(24 * 60 * 60, garageMode.getWakeupTime());
144         Thread.sleep(WAIT_FOR_COMPLETION_TIME);
145         assertEquals(9, prefs.getInt("garage_mode_index", 0));
146     }
147 
148     @Test
testPolicyParserValid()149     public void testPolicyParserValid() throws Exception {
150         WakeupTime expected[] = new WakeupTime[]{
151                 new WakeupTime(15 * 60, 1),
152                 new WakeupTime(6 * 60 * 60, 8),
153                 new WakeupTime(24 * 60 * 60, 5),
154         };
155         WakeupTime received[] = new GarageModePolicy(new String[] {
156                 "15m,1",
157                 "6h,8",
158                 "1d,5",
159         }).mWakeupTime;
160 
161         assertEquals(expected.length, received.length);
162         for (int i = 0; i < expected.length; i++) {
163             assertEquals(expected[i].mWakeupTime, received[i].mWakeupTime);
164             assertEquals(expected[i].mNumAttempts, received[i].mNumAttempts);
165         }
166     }
167 
168     @Test(expected=RuntimeException.class)
testPolicyParserNull()169     public void testPolicyParserNull() {
170         new GarageModePolicy(null);
171     }
172     @Test(expected=RuntimeException.class)
testPolicyParserEmptyArray()173     public void testPolicyParserEmptyArray() {
174         new GarageModePolicy(new String[] {});
175     }
176     @Test(expected=RuntimeException.class)
testPolicyParserEmptyString()177     public void testPolicyParserEmptyString() {
178         new GarageModePolicy(new String[] {""});
179     }
180     @Test(expected=RuntimeException.class)
testPolicyParserMissingUnits()181     public void testPolicyParserMissingUnits() {
182         new GarageModePolicy(new String[] {"15,1"});
183     }
184     @Test(expected=RuntimeException.class)
testPolicyParserInvalidUnits()185     public void testPolicyParserInvalidUnits() {
186         new GarageModePolicy(new String[] {"15y,1"});
187     }
188     @Test(expected=RuntimeException.class)
testPolicyParserNoCount()189     public void testPolicyParserNoCount() {
190         new GarageModePolicy(new String[] {"15m"});
191     }
192     @Test(expected=RuntimeException.class)
testPolicyParserBadCount()193     public void testPolicyParserBadCount() {
194         new GarageModePolicy(new String[] {"15m,Q"});
195     }
196     @Test(expected=RuntimeException.class)
testPolicyParserNegativeCount()197     public void testPolicyParserNegativeCount() {
198         new GarageModePolicy(new String[] {"15m,-1"});
199     }
200     @Test(expected=RuntimeException.class)
testPolicyParserNoTime()201     public void testPolicyParserNoTime() {
202         new GarageModePolicy(new String[] {",1"});
203     }
204     @Test(expected=RuntimeException.class)
testPolicyParserNoTimeValue()205     public void testPolicyParserNoTimeValue() {
206         new GarageModePolicy(new String[] {"m,1"});
207     }
208     @Test(expected=RuntimeException.class)
testPolicyParserBadTime()209     public void testPolicyParserBadTime() {
210         new GarageModePolicy(new String[] {"Qm,1"});
211     }
212     @Test(expected=RuntimeException.class)
testPolicyParserNegativeTime()213     public void testPolicyParserNegativeTime() {
214         new GarageModePolicy(new String[] {"-10m,1"});
215     }
216 
217     @Test
testPolicyInResource()218     public void testPolicyInResource() throws Exception {
219         // Test that the policy in the resource file parses fine.
220         assertNotNull(new GarageModePolicy(getContext().getResources().getStringArray(
221                 R.array.config_garageModeCadence)).mWakeupTime);
222     }
223 
224     private static class MockCarPowerManagementService extends CarPowerManagementService {
doNotifyPrepareShutdown(boolean shuttingdown)225         public long doNotifyPrepareShutdown(boolean shuttingdown) {
226             return notifyPrepareShutdown(shuttingdown);
227         }
228 
doNotifyPowerOn(boolean displayOn)229         public void doNotifyPowerOn(boolean displayOn) {
230             notifyPowerOn(displayOn);
231         }
232     }
233 
234     private static class GarageModeServiceForTest extends GarageModeService {
GarageModeServiceForTest(Context context, CarPowerManagementService powerManagementService, DeviceIdleControllerWrapper controllerWrapper, Looper looper)235         public GarageModeServiceForTest(Context context,
236                 CarPowerManagementService powerManagementService,
237                 DeviceIdleControllerWrapper controllerWrapper,
238                 Looper looper) {
239             super(context, powerManagementService, controllerWrapper, looper);
240         }
241 
GarageModeServiceForTest(Context context, CarPowerManagementService powerManagementService, DeviceIdleControllerWrapper controllerWrapper)242         public GarageModeServiceForTest(Context context,
243                 CarPowerManagementService powerManagementService,
244                 DeviceIdleControllerWrapper controllerWrapper) {
245             super(context, powerManagementService, controllerWrapper, Looper.myLooper());
246         }
247 
getMaintenanceWindow()248         public long getMaintenanceWindow() {
249             return CarSettings.DEFAULT_GARAGE_MODE_MAINTENANCE_WINDOW;
250         }
251 
isInGarageMode()252         public boolean isInGarageMode() {
253             synchronized (this) {
254                 return mInGarageMode;
255             }
256         }
257 
isMaintenanceActive()258         public boolean isMaintenanceActive() {
259             synchronized (this) {
260                 return mMaintenanceActive;
261             }
262         }
263 
getGarageModeIndex()264         public int getGarageModeIndex() {
265             synchronized (this) {
266                 return mGarageModeIndex;
267             }
268         }
269     }
270 
getContext()271     private Context getContext() {
272         return InstrumentationRegistry.getTargetContext();
273     }
274 
275     private static class MockDeviceIdleController extends DeviceIdleControllerWrapper {
276 
277         private final boolean mInitialActive;
278 
MockDeviceIdleController(boolean active)279         MockDeviceIdleController(boolean active) {
280             super();
281             mInitialActive = active;
282         }
283 
284         @Override
startLocked()285         protected boolean startLocked() {
286             return mInitialActive;
287         }
288 
289         @Override
stopTracking()290         public void stopTracking() {
291             // nothing to clean up
292         }
293 
294         @Override
reportActiveLocked(final boolean active)295         protected void reportActiveLocked(final boolean active) {
296             // directly calling the callback instead of posting to handler, to make testing easier.
297             if (mListener.get() != null) {
298                 mListener.get().onMaintenanceActivityChanged(active);
299             }
300         }
301 
setMaintenanceActivity(boolean active)302         public void setMaintenanceActivity(boolean active) {
303             super.setMaintenanceActivity(active);
304         }
305     }
306 }
307