blob: 23153fc7a4075dc7d244202a0898cff00ff02448 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.car;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.car.settings.CarSettings;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.HandlerThread;
import android.os.Looper;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import com.android.car.GarageModeService.GarageModePolicy;
import com.android.car.GarageModeService.WakeupTime;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class GarageModeTest {
private static final int WAIT_FOR_COMPLETION_TIME = 3000;//ms
@Test
@UiThreadTest
public void testMaintenanceActive() throws Exception {
MockCarPowerManagementService powerManagementService = new MockCarPowerManagementService();
MockDeviceIdleController controller = new MockDeviceIdleController(true);
GarageModeServiceForTest garageMode = new GarageModeServiceForTest(getContext(),
powerManagementService,
controller);
garageMode.init();
final int index1 = garageMode.getGarageModeIndex();
assertEquals(garageMode.getMaintenanceWindow(),
powerManagementService.doNotifyPrepareShutdown(false));
assertEquals(true, garageMode.isInGarageMode());
assertEquals(true, garageMode.isMaintenanceActive());
controller.setMaintenanceActivity(false);
assertEquals(false, garageMode.isInGarageMode());
assertEquals(false, garageMode.isMaintenanceActive());
final int index2 = garageMode.getGarageModeIndex();
assertEquals(1, index2 - index1);
}
@Test
@UiThreadTest
public void testMaintenanceInactive() throws Exception {
MockCarPowerManagementService powerManagementService = new MockCarPowerManagementService();
MockDeviceIdleController controller = new MockDeviceIdleController(false);
GarageModeServiceForTest garageMode = new GarageModeServiceForTest(getContext(),
powerManagementService,
controller);
garageMode.init();
assertEquals(garageMode.getMaintenanceWindow(),
powerManagementService.doNotifyPrepareShutdown(false));
assertEquals(true, garageMode.isInGarageMode());
assertEquals(false, garageMode.isMaintenanceActive());
}
@Test
@UiThreadTest
public void testDisplayOn() throws Exception {
MockCarPowerManagementService powerManagementService = new MockCarPowerManagementService();
MockDeviceIdleController controller = new MockDeviceIdleController(true);
GarageModeServiceForTest garageMode = new GarageModeServiceForTest(getContext(),
powerManagementService,
controller);
garageMode.init();
powerManagementService.doNotifyPrepareShutdown(false);
assertTrue(garageMode.getGarageModeIndex() > 0);
powerManagementService.doNotifyPowerOn(true);
assertEquals(0,garageMode.getGarageModeIndex());
}
@Test
@UiThreadTest
public void testPolicyIndexing() throws Exception {
// Background processing of asynchronous messages.
HandlerThread thread = new HandlerThread("testPolicy");
thread.start();
// Test that the index is saved in the prefs and that this index is used to determine the
// next wakeup time.
MockCarPowerManagementService powerManagementService = new MockCarPowerManagementService();
MockDeviceIdleController controller = new MockDeviceIdleController(true);
GarageModeServiceForTest garageMode = new GarageModeServiceForTest(getContext(),
powerManagementService,
controller,
thread.getLooper());
String[] policy = {
"15m,1",
"6h,8",
"1d,5",
};
SharedPreferences prefs =
getContext().getSharedPreferences("testPolicy", Context.MODE_PRIVATE);
prefs.edit().putInt("garage_mode_index", 0).apply();
garageMode.init(policy, prefs);
assertEquals(15 * 60, garageMode.getWakeupTime());
garageMode.onPrepareShutdown(false);
garageMode.onShutdown();
assertEquals(6 * 60 * 60, garageMode.getWakeupTime());
Thread.sleep(WAIT_FOR_COMPLETION_TIME);
assertEquals(1, prefs.getInt("garage_mode_index", 0));
garageMode = new GarageModeServiceForTest(getContext(),
powerManagementService,
controller,
thread.getLooper());
// Jump ahead 8 restarts.
prefs = getContext().getSharedPreferences("testPolicy", Context.MODE_PRIVATE);
prefs.edit().putInt("garage_mode_index", 8).apply();
garageMode.init(policy, prefs);
assertEquals(6 * 60 * 60, garageMode.getWakeupTime());
garageMode.onPrepareShutdown(false);
garageMode.onShutdown();
assertEquals(24 * 60 * 60, garageMode.getWakeupTime());
Thread.sleep(WAIT_FOR_COMPLETION_TIME);
assertEquals(9, prefs.getInt("garage_mode_index", 0));
}
@Test
public void testPolicyParserValid() throws Exception {
WakeupTime expected[] = new WakeupTime[]{
new WakeupTime(15 * 60, 1),
new WakeupTime(6 * 60 * 60, 8),
new WakeupTime(24 * 60 * 60, 5),
};
WakeupTime received[] = new GarageModePolicy(new String[] {
"15m,1",
"6h,8",
"1d,5",
}).mWakeupTime;
assertEquals(expected.length, received.length);
for (int i = 0; i < expected.length; i++) {
assertEquals(expected[i].mWakeupTime, received[i].mWakeupTime);
assertEquals(expected[i].mNumAttempts, received[i].mNumAttempts);
}
}
@Test(expected=RuntimeException.class)
public void testPolicyParserNull() {
new GarageModePolicy(null);
}
@Test(expected=RuntimeException.class)
public void testPolicyParserEmptyArray() {
new GarageModePolicy(new String[] {});
}
@Test(expected=RuntimeException.class)
public void testPolicyParserEmptyString() {
new GarageModePolicy(new String[] {""});
}
@Test(expected=RuntimeException.class)
public void testPolicyParserMissingUnits() {
new GarageModePolicy(new String[] {"15,1"});
}
@Test(expected=RuntimeException.class)
public void testPolicyParserInvalidUnits() {
new GarageModePolicy(new String[] {"15y,1"});
}
@Test(expected=RuntimeException.class)
public void testPolicyParserNoCount() {
new GarageModePolicy(new String[] {"15m"});
}
@Test(expected=RuntimeException.class)
public void testPolicyParserBadCount() {
new GarageModePolicy(new String[] {"15m,Q"});
}
@Test(expected=RuntimeException.class)
public void testPolicyParserNegativeCount() {
new GarageModePolicy(new String[] {"15m,-1"});
}
@Test(expected=RuntimeException.class)
public void testPolicyParserNoTime() {
new GarageModePolicy(new String[] {",1"});
}
@Test(expected=RuntimeException.class)
public void testPolicyParserNoTimeValue() {
new GarageModePolicy(new String[] {"m,1"});
}
@Test(expected=RuntimeException.class)
public void testPolicyParserBadTime() {
new GarageModePolicy(new String[] {"Qm,1"});
}
@Test(expected=RuntimeException.class)
public void testPolicyParserNegativeTime() {
new GarageModePolicy(new String[] {"-10m,1"});
}
@Test
public void testPolicyInResource() throws Exception {
// Test that the policy in the resource file parses fine.
assertNotNull(new GarageModePolicy(getContext().getResources().getStringArray(
R.array.config_garageModeCadence)).mWakeupTime);
}
private static class MockCarPowerManagementService extends CarPowerManagementService {
public long doNotifyPrepareShutdown(boolean shuttingdown) {
return notifyPrepareShutdown(shuttingdown);
}
public void doNotifyPowerOn(boolean displayOn) {
notifyPowerOn(displayOn);
}
}
private static class GarageModeServiceForTest extends GarageModeService {
public GarageModeServiceForTest(Context context,
CarPowerManagementService powerManagementService,
DeviceIdleControllerWrapper controllerWrapper,
Looper looper) {
super(context, powerManagementService, controllerWrapper, looper);
}
public GarageModeServiceForTest(Context context,
CarPowerManagementService powerManagementService,
DeviceIdleControllerWrapper controllerWrapper) {
super(context, powerManagementService, controllerWrapper, Looper.myLooper());
}
public long getMaintenanceWindow() {
return CarSettings.DEFAULT_GARAGE_MODE_MAINTENANCE_WINDOW;
}
public boolean isInGarageMode() {
synchronized (this) {
return mInGarageMode;
}
}
public boolean isMaintenanceActive() {
synchronized (this) {
return mMaintenanceActive;
}
}
public int getGarageModeIndex() {
synchronized (this) {
return mGarageModeIndex;
}
}
}
private Context getContext() {
return InstrumentationRegistry.getTargetContext();
}
private static class MockDeviceIdleController extends DeviceIdleControllerWrapper {
private final boolean mInitialActive;
MockDeviceIdleController(boolean active) {
super();
mInitialActive = active;
}
@Override
protected boolean startLocked() {
return mInitialActive;
}
@Override
public void stopTracking() {
// nothing to clean up
}
@Override
protected void reportActiveLocked(final boolean active) {
// directly calling the callback instead of posting to handler, to make testing easier.
if (mListener.get() != null) {
mListener.get().onMaintenanceActivityChanged(active);
}
}
public void setMaintenanceActivity(boolean active) {
super.setMaintenanceActivity(active);
}
}
}