Merge "Increased test coverage for garagemode" into sc-v2-dev
diff --git a/service/src/com/android/car/garagemode/Controller.java b/service/src/com/android/car/garagemode/Controller.java
index 81c8c10..fdf0c05 100644
--- a/service/src/com/android/car/garagemode/Controller.java
+++ b/service/src/com/android/car/garagemode/Controller.java
@@ -16,6 +16,8 @@
package com.android.car.garagemode;
+import static com.android.car.internal.testing.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO;
+
import android.app.job.JobScheduler;
import android.car.hardware.power.CarPowerManager;
import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
@@ -28,6 +30,7 @@
import com.android.car.CarLocalServices;
import com.android.car.CarLog;
+import com.android.car.internal.testing.ExcludeFromCodeCoverageGeneratedReport;
import com.android.car.systeminterface.SystemInterface;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.utils.Slogf;
@@ -116,6 +119,7 @@
/**
* Prints Garage Mode's status, including what jobs it is waiting for
*/
+ @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO)
void dump(PrintWriter writer) {
mGarageMode.dump(writer);
}
diff --git a/service/src/com/android/car/garagemode/GarageMode.java b/service/src/com/android/car/garagemode/GarageMode.java
index f315dca..5936391 100644
--- a/service/src/com/android/car/garagemode/GarageMode.java
+++ b/service/src/com/android/car/garagemode/GarageMode.java
@@ -16,6 +16,8 @@
package com.android.car.garagemode;
+import static com.android.car.internal.testing.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO;
+
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.app.job.JobSnapshot;
@@ -30,6 +32,7 @@
import com.android.car.CarLocalServices;
import com.android.car.CarLog;
import com.android.car.CarStatsLogHelper;
+import com.android.car.internal.testing.ExcludeFromCodeCoverageGeneratedReport;
import com.android.car.power.CarPowerManagementService;
import com.android.car.user.CarUserService;
import com.android.internal.annotations.GuardedBy;
@@ -242,6 +245,7 @@
}
}
+ @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO)
void dump(PrintWriter writer) {
if (!mGarageModeActive) {
return;
diff --git a/tests/carservice_test/src/com/android/car/garagemode/ControllerTest.java b/tests/carservice_test/src/com/android/car/garagemode/ControllerTest.java
index ca3598a..36e4361 100644
--- a/tests/carservice_test/src/com/android/car/garagemode/ControllerTest.java
+++ b/tests/carservice_test/src/com/android/car/garagemode/ControllerTest.java
@@ -24,16 +24,21 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.car.Car;
import android.car.hardware.power.CarPowerManager;
import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
@@ -42,6 +47,8 @@
import androidx.test.filters.SmallTest;
import com.android.car.CarLocalServices;
+import com.android.car.R;
+import com.android.car.power.CarPowerManagementService;
import com.android.car.systeminterface.SystemInterface;
import com.android.car.user.CarUserService;
@@ -219,4 +226,87 @@
// Verify that worker that polls running jobs from JobScheduler is scheduled.
verify(mHandlerMock).postDelayed(any(), eq(JOB_SNAPSHOT_INITIAL_UPDATE_MS));
}
+
+ @Test
+ public void testInitAndRelease() {
+ CarPowerManagementService mockCarPowerManagementService =
+ mock(CarPowerManagementService.class);
+
+ GarageMode garageMode = mock(GarageMode.class);
+ Controller controller = new Controller(mContextMock, mLooperMock, mWakeupPolicy,
+ mHandlerMock, garageMode);
+ CarLocalServices.addService(CarPowerManagementService.class, mockCarPowerManagementService);
+
+ controller.init();
+ controller.release();
+
+ verify(garageMode).init();
+ verify(garageMode).release();
+ }
+
+ @Test
+ public void testConstructor() {
+ Resources resourcesMock = mock(Resources.class);
+ when(mContextMock.getResources()).thenReturn(resourcesMock);
+ when(resourcesMock.getStringArray(R.array.config_garageModeCadence))
+ .thenReturn(sTemplateWakeupSchedule);
+ Controller controller = new Controller(mContextMock, mLooperMock);
+
+ assertThat(controller).isNotNull();
+ }
+
+ @Test
+ public void testScheduleNextWakeup() {
+ GarageMode garageMode = mock(GarageMode.class);
+
+ // Enter GarageMode only 1 time, no wake up after that
+ WakeupPolicy wakeUpPolicy = new WakeupPolicy(new String[] { "15m,1" });
+
+ Controller controller = new Controller(mContextMock, mLooperMock, wakeUpPolicy,
+ mHandlerMock, garageMode);
+ controller.setCarPowerManager(mCarPowerManagerMock);
+
+ // Imitate entering and leavimg GarageMode
+ controller.initiateGarageMode(/* future= */ null);
+
+ controller.scheduleNextWakeup();
+
+ verify(mCarPowerManagerMock).scheduleNextWakeupTime(900);
+
+ // Imitate entering Garage mode after sleep
+ controller.initiateGarageMode(/* future= */ null);
+
+ // Should be no more calls to scheduleNextWakeupTime
+ controller.scheduleNextWakeup();
+
+ Mockito.verifyNoMoreInteractions(mCarPowerManagerMock);
+ }
+
+ @Test
+ public void testOnStateChanged() {
+ GarageMode garageMode = mock(GarageMode.class);
+
+ Controller controller = Mockito.spy(new Controller(mContextMock, mLooperMock, mWakeupPolicy,
+ mHandlerMock, garageMode));
+
+ controller.onStateChanged(CarPowerStateListener.SHUTDOWN_CANCELLED, null);
+ verify(controller).resetGarageMode();
+
+ clearInvocations(controller);
+ controller.onStateChanged(CarPowerStateListener.SHUTDOWN_ENTER, null);
+ verify(controller).resetGarageMode();
+
+ clearInvocations(controller);
+ controller.onStateChanged(CarPowerStateListener.SUSPEND_ENTER, null);
+ verify(controller).resetGarageMode();
+
+ clearInvocations(controller);
+ controller.onStateChanged(CarPowerStateListener.SUSPEND_EXIT, null);
+ verify(controller).resetGarageMode();
+
+ clearInvocations(controller);
+ controller.onStateChanged(CarPowerStateListener.INVALID , null);
+ verify(controller, never()).resetGarageMode();
+ }
+
}
diff --git a/tests/carservice_test/src/com/android/car/garagemode/GarageModeTest.java b/tests/carservice_test/src/com/android/car/garagemode/GarageModeTest.java
index 6133baf..6183549 100644
--- a/tests/carservice_test/src/com/android/car/garagemode/GarageModeTest.java
+++ b/tests/carservice_test/src/com/android/car/garagemode/GarageModeTest.java
@@ -22,6 +22,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -36,6 +37,7 @@
import androidx.test.filters.SmallTest;
import com.android.car.CarLocalServices;
+import com.android.car.power.CarPowerManagementService;
import com.android.car.user.CarUserService;
import org.junit.After;
@@ -50,6 +52,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -131,6 +134,42 @@
105);
}
+ @Test
+ public void garageModeTestExitImmediately() throws Exception {
+ CarPowerManagementService mockCarPowerManagementService =
+ mock(CarPowerManagementService.class);
+
+ // Mock CPMS to force Garage Mode early exit
+ CarLocalServices.removeServiceForTest(CarPowerManagementService.class);
+ CarLocalServices.addService(CarPowerManagementService.class, mockCarPowerManagementService);
+ when(mockCarPowerManagementService.garageModeShouldExitImmediately()).thenReturn(true);
+
+ // Check exit immediately without future
+ GarageMode garageMode = new GarageMode(mController);
+ garageMode.init();
+ garageMode.enterGarageMode(/* future= */ null);
+ assertThat(garageMode.isGarageModeActive()).isFalse();
+
+ // Create new instance of GarageMode
+ garageMode = new GarageMode(mController);
+ garageMode.init();
+ // Check exit immediately with future
+ CompletableFuture<Void> future = new CompletableFuture<>();
+ garageMode.enterGarageMode(future);
+ assertThat(garageMode.isGarageModeActive()).isFalse();
+ assertThat(future.isDone()).isTrue();
+
+ // Create new instance of GarageMode
+ garageMode = new GarageMode(mController);
+ garageMode.init();
+ // Check exit immediately with completed future
+ garageMode.enterGarageMode(future);
+ assertThat(garageMode.isGarageModeActive()).isFalse();
+ assertThat(future.isDone()).isTrue();
+
+ CarLocalServices.removeServiceForTest(CarPowerManagementService.class);
+ }
+
private void waitForHandlerThreadToFinish(CountDownLatch latch) throws Exception {
assertWithMessage("Latch has timed out.")
.that(latch.await(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();