1 /* 2 * Copyright (C) 2015 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.test; 17 18 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerBootupReason; 19 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerSetState; 20 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerState; 21 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateConfigFlag; 22 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateIndex; 23 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateShutdownParam; 24 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; 25 import android.hardware.automotive.vehicle.V2_0.VehicleProperty; 26 import android.os.SystemClock; 27 import android.test.suitebuilder.annotation.MediumTest; 28 29 import com.google.android.collect.Lists; 30 31 import com.android.car.vehiclehal.VehiclePropValueBuilder; 32 import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler; 33 34 import java.util.ArrayList; 35 import java.util.LinkedList; 36 import java.util.concurrent.Semaphore; 37 import java.util.concurrent.TimeUnit; 38 39 @MediumTest 40 public class CarPowerManagementTest extends MockedCarTestBase { 41 42 private final PowerStatePropertyHandler mPowerStateHandler = new PowerStatePropertyHandler(); 43 44 private void setupPowerPropertyAndStart(boolean allowSleep) { 45 addProperty(VehicleProperty.AP_POWER_STATE, mPowerStateHandler) 46 .setConfigArray(Lists.newArrayList( 47 allowSleep ? VehicleApPowerStateConfigFlag.ENABLE_DEEP_SLEEP_FLAG : 0)); 48 49 addStaticProperty(VehicleProperty.AP_POWER_BOOTUP_REASON, 50 VehiclePropValueBuilder.newBuilder(VehicleProperty.AP_POWER_BOOTUP_REASON) 51 .addIntValue(VehicleApPowerBootupReason.USER_POWER_ON) 52 .build()); 53 54 reinitializeMockedHal(); 55 } 56 57 public void testImmediateShutdown() throws Exception { 58 setupPowerPropertyAndStart(true); 59 assertBootComplete(); 60 mPowerStateHandler.sendPowerState( 61 VehicleApPowerState.SHUTDOWN_PREPARE, 62 VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY); 63 mPowerStateHandler.waitForStateSetAndGetAll(DEFAULT_WAIT_TIMEOUT_MS, 64 VehicleApPowerSetState.SHUTDOWN_START); 65 mPowerStateHandler.sendPowerState(VehicleApPowerState.ON_FULL, 0); 66 } 67 68 public void testDisplayOnOff() throws Exception { 69 setupPowerPropertyAndStart(true); 70 assertBootComplete(); 71 for (int i = 0; i < 2; i++) { 72 mPowerStateHandler.sendPowerState(VehicleApPowerState.ON_DISP_OFF, 0); 73 waitForFakeDisplayState(false); 74 mPowerStateHandler.sendPowerState(VehicleApPowerState.ON_FULL, 0); 75 waitForFakeDisplayState(true); 76 } 77 } 78 79 /* TODO make deep sleep work to test this 80 public void testSleepEntry() throws Exception { 81 assertBootComplete(); 82 mPowerStateHandler.sendPowerState( 83 VehicleApPowerState.SHUTDOWN_PREPARE, 84 VehicleApPowerStateShutdownParam.CAN_SLEEP); 85 assertResponse(VehicleApPowerSetState.DEEP_SLEEP_ENTRY, 0); 86 assertResponse(VehicleApPowerSetState.DEEP_SLEEP_EXIT, 0); 87 mPowerStateHandler.sendPowerState( 88 VehicleApPowerState.ON_FULL, 89 0); 90 }*/ 91 92 private void assertResponse(int expectedResponseState, int expectedResponseParam) 93 throws Exception { 94 LinkedList<int[]> setEvents = mPowerStateHandler.waitForStateSetAndGetAll( 95 DEFAULT_WAIT_TIMEOUT_MS, expectedResponseState); 96 int[] last = setEvents.getLast(); 97 assertEquals(expectedResponseState, last[0]); 98 assertEquals(expectedResponseParam, last[1]); 99 } 100 101 private void assertBootComplete() throws Exception { 102 mPowerStateHandler.waitForSubscription(DEFAULT_WAIT_TIMEOUT_MS); 103 LinkedList<int[]> setEvents = mPowerStateHandler.waitForStateSetAndGetAll( 104 DEFAULT_WAIT_TIMEOUT_MS, VehicleApPowerSetState.BOOT_COMPLETE); 105 int[] first = setEvents.getFirst(); 106 assertEquals(VehicleApPowerSetState.BOOT_COMPLETE, first[0]); 107 assertEquals(0, first[1]); 108 } 109 110 private class PowerStatePropertyHandler implements VehicleHalPropertyHandler { 111 112 private int mPowerState = VehicleApPowerState.ON_FULL; 113 private int mPowerParam = 0; 114 115 private final Semaphore mSubscriptionWaitSemaphore = new Semaphore(0); 116 private final Semaphore mSetWaitSemaphore = new Semaphore(0); 117 private LinkedList<int[]> mSetStates = new LinkedList<>(); 118 119 @Override 120 public void onPropertySet(VehiclePropValue value) { 121 ArrayList<Integer> v = value.value.int32Values; 122 synchronized (this) { 123 mSetStates.add(new int[] { 124 v.get(VehicleApPowerStateIndex.STATE), 125 v.get(VehicleApPowerStateIndex.ADDITIONAL) 126 }); 127 } 128 mSetWaitSemaphore.release(); 129 } 130 131 @Override 132 public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) { 133 return VehiclePropValueBuilder.newBuilder(VehicleProperty.AP_POWER_STATE) 134 .setTimestamp(SystemClock.elapsedRealtimeNanos()) 135 .addIntValue(mPowerState, mPowerParam) 136 .build(); 137 } 138 139 @Override 140 public void onPropertySubscribe(int property, int zones, float sampleRate) { 141 mSubscriptionWaitSemaphore.release(); 142 } 143 144 @Override 145 public void onPropertyUnsubscribe(int property) { 146 //ignore 147 } 148 149 private synchronized void setCurrentState(int state, int param) { 150 mPowerState = state; 151 mPowerParam = param; 152 } 153 154 private void waitForSubscription(long timeoutMs) throws Exception { 155 if (!mSubscriptionWaitSemaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) { 156 fail("waitForSubscription timeout"); 157 } 158 } 159 160 private LinkedList<int[]> waitForStateSetAndGetAll(long timeoutMs, int expectedSet) 161 throws Exception { 162 while (true) { 163 if (!mSetWaitSemaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) { 164 fail("waitForStateSetAndGetAll timeout"); 165 } 166 synchronized (this) { 167 boolean found = false; 168 for (int[] state : mSetStates) { 169 if (state[0] == expectedSet) { 170 found = true; 171 } 172 } 173 if (found) { 174 LinkedList<int[]> res = mSetStates; 175 mSetStates = new LinkedList<>(); 176 return res; 177 } 178 } 179 } 180 } 181 182 private void sendPowerState(int state, int param) { 183 getMockedVehicleHal().injectEvent( 184 VehiclePropValueBuilder.newBuilder(VehicleProperty.AP_POWER_STATE) 185 .setTimestamp(SystemClock.elapsedRealtimeNanos()) 186 .addIntValue(state, param) 187 .build()); 188 } 189 } 190 } 191