• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.fail;
20 
21 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerBootupReason;
22 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateConfigFlag;
23 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateReport;
24 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateReq;
25 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateReqIndex;
26 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateShutdownParam;
27 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
28 import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
29 import android.os.SystemClock;
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.systeminterface.DisplayInterface;
35 import com.android.car.systeminterface.SystemInterface;
36 import com.android.car.vehiclehal.VehiclePropValueBuilder;
37 import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
38 
39 import com.google.android.collect.Lists;
40 
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.util.ArrayList;
45 import java.util.LinkedList;
46 import java.util.concurrent.Semaphore;
47 import java.util.concurrent.TimeUnit;
48 
49 @RunWith(AndroidJUnit4.class)
50 @MediumTest
51 public class CarPowerManagementTest extends MockedCarTestBase {
52 
53     private final PowerStatePropertyHandler mPowerStateHandler = new PowerStatePropertyHandler();
54     private final MockDisplayInterface mMockDisplayInterface = new MockDisplayInterface();
55 
56     @Override
getSystemInterfaceBuilder()57     protected synchronized SystemInterface.Builder getSystemInterfaceBuilder() {
58         SystemInterface.Builder builder = super.getSystemInterfaceBuilder();
59         return builder.withDisplayInterface(mMockDisplayInterface);
60     }
61 
setupPowerPropertyAndStart(boolean allowSleep)62     private void setupPowerPropertyAndStart(boolean allowSleep) throws Exception {
63         addProperty(VehicleProperty.AP_POWER_STATE_REQ, mPowerStateHandler)
64                 .setConfigArray(Lists.newArrayList(
65                         allowSleep ? VehicleApPowerStateConfigFlag.ENABLE_DEEP_SLEEP_FLAG : 0));
66         addProperty(VehicleProperty.AP_POWER_STATE_REPORT, mPowerStateHandler);
67 
68         addStaticProperty(VehicleProperty.AP_POWER_BOOTUP_REASON,
69                 VehiclePropValueBuilder.newBuilder(VehicleProperty.AP_POWER_BOOTUP_REASON)
70                         .addIntValue(VehicleApPowerBootupReason.USER_POWER_ON)
71                         .build());
72 
73         reinitializeMockedHal();
74     }
75 
76     @Test
77     @UiThreadTest
testImmediateShutdown()78     public void testImmediateShutdown() throws Exception {
79         setupPowerPropertyAndStart(true);
80         assertBootComplete();
81         mPowerStateHandler.sendPowerState(
82                 VehicleApPowerStateReq.SHUTDOWN_PREPARE,
83                 VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY);
84         mPowerStateHandler.waitForStateSetAndGetAll(DEFAULT_WAIT_TIMEOUT_MS,
85                 VehicleApPowerStateReport.SHUTDOWN_START);
86         mPowerStateHandler.sendPowerState(VehicleApPowerStateReq.ON_FULL, 0);
87     }
88 
89     @Test
90     @UiThreadTest
testDisplayOnOff()91     public void testDisplayOnOff() throws Exception {
92         setupPowerPropertyAndStart(true);
93         assertBootComplete();
94         for (int i = 0; i < 2; i++) {
95             mPowerStateHandler.sendPowerState(VehicleApPowerStateReq.ON_DISP_OFF, 0);
96             mMockDisplayInterface.waitForDisplayState(false);
97             mPowerStateHandler.sendPowerState(VehicleApPowerStateReq.ON_FULL, 0);
98             mMockDisplayInterface.waitForDisplayState(true);
99         }
100     }
101 
102     /* TODO make deep sleep work to test this
103     @Test public void testSleepEntry() throws Exception {
104         assertBootComplete();
105         mPowerStateHandler.sendPowerState(
106                 VehicleApPowerState.SHUTDOWN_PREPARE,
107                 VehicleApPowerStateShutdownParam.CAN_SLEEP);
108         assertResponse(VehicleApPowerSetState.DEEP_SLEEP_ENTRY, 0);
109         assertResponse(VehicleApPowerSetState.DEEP_SLEEP_EXIT, 0);
110         mPowerStateHandler.sendPowerState(
111                 VehicleApPowerState.ON_FULL,
112                 0);
113     }*/
114 
assertResponse(int expectedResponseState, int expectedResponseParam)115     private void assertResponse(int expectedResponseState, int expectedResponseParam)
116             throws Exception {
117         LinkedList<int[]> setEvents = mPowerStateHandler.waitForStateSetAndGetAll(
118                 DEFAULT_WAIT_TIMEOUT_MS, expectedResponseState);
119         int[] last = setEvents.getLast();
120         assertEquals(expectedResponseState, last[0]);
121         assertEquals(expectedResponseParam, last[1]);
122     }
123 
assertBootComplete()124     private void assertBootComplete() throws Exception {
125         mPowerStateHandler.waitForSubscription(DEFAULT_WAIT_TIMEOUT_MS);
126         LinkedList<int[]> setEvents = mPowerStateHandler.waitForStateSetAndGetAll(
127                 DEFAULT_WAIT_TIMEOUT_MS, VehicleApPowerStateReport.BOOT_COMPLETE);
128         int[] first = setEvents.getFirst();
129         assertEquals(VehicleApPowerStateReport.BOOT_COMPLETE, first[0]);
130         assertEquals(0, first[1]);
131     }
132 
133     private final class MockDisplayInterface implements DisplayInterface {
134         private boolean mDisplayOn = true;
135         private final Semaphore mDisplayStateWait = new Semaphore(0);
136 
137         @Override
setDisplayBrightness(int brightness)138         public void setDisplayBrightness(int brightness) {}
139 
140         @Override
setDisplayState(boolean on)141         public synchronized void setDisplayState(boolean on) {
142             mDisplayOn = on;
143             mDisplayStateWait.release();
144         }
145 
waitForDisplayState(boolean expectedState)146         boolean waitForDisplayState(boolean expectedState)
147             throws Exception {
148             if (expectedState == mDisplayOn) {
149                 return true;
150             }
151             mDisplayStateWait.tryAcquire(MockedCarTestBase.SHORT_WAIT_TIMEOUT_MS,
152                     TimeUnit.MILLISECONDS);
153             return expectedState == mDisplayOn;
154         }
155 
156         @Override
startDisplayStateMonitoring(CarPowerManagementService service)157         public void startDisplayStateMonitoring(CarPowerManagementService service) {}
158 
159         @Override
stopDisplayStateMonitoring()160         public void stopDisplayStateMonitoring() {}
161     }
162 
163     private class PowerStatePropertyHandler implements VehicleHalPropertyHandler {
164 
165         private int mPowerState = VehicleApPowerStateReq.ON_FULL;
166         private int mPowerParam = 0;
167 
168         private final Semaphore mSubscriptionWaitSemaphore = new Semaphore(0);
169         private final Semaphore mSetWaitSemaphore = new Semaphore(0);
170         private LinkedList<int[]> mSetStates = new LinkedList<>();
171 
172         @Override
onPropertySet(VehiclePropValue value)173         public void onPropertySet(VehiclePropValue value) {
174             ArrayList<Integer> v = value.value.int32Values;
175             synchronized (this) {
176                 mSetStates.add(new int[] {
177                         v.get(VehicleApPowerStateReqIndex.STATE),
178                         v.get(VehicleApPowerStateReqIndex.ADDITIONAL)
179                 });
180             }
181             mSetWaitSemaphore.release();
182         }
183 
184         @Override
onPropertyGet(VehiclePropValue value)185         public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
186             return VehiclePropValueBuilder.newBuilder(VehicleProperty.AP_POWER_STATE_REQ)
187                     .setTimestamp(SystemClock.elapsedRealtimeNanos())
188                     .addIntValue(mPowerState, mPowerParam)
189                     .build();
190         }
191 
192         @Override
onPropertySubscribe(int property, float sampleRate)193         public void onPropertySubscribe(int property, float sampleRate) {
194             mSubscriptionWaitSemaphore.release();
195         }
196 
197         @Override
onPropertyUnsubscribe(int property)198         public void onPropertyUnsubscribe(int property) {
199             //ignore
200         }
201 
setCurrentState(int state, int param)202         private synchronized void setCurrentState(int state, int param) {
203             mPowerState = state;
204             mPowerParam = param;
205         }
206 
waitForSubscription(long timeoutMs)207         private void waitForSubscription(long timeoutMs) throws Exception {
208             if (!mSubscriptionWaitSemaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
209                 fail("waitForSubscription timeout");
210             }
211         }
212 
waitForStateSetAndGetAll(long timeoutMs, int expectedSet)213         private LinkedList<int[]> waitForStateSetAndGetAll(long timeoutMs, int expectedSet)
214                 throws Exception {
215             while (true) {
216                 if (!mSetWaitSemaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
217                     fail("waitForStateSetAndGetAll timeout");
218                 }
219                 synchronized (this) {
220                     boolean found = false;
221                     for (int[] state : mSetStates) {
222                         if (state[0] == expectedSet) {
223                             found = true;
224                         }
225                     }
226                     if (found) {
227                         LinkedList<int[]> res = mSetStates;
228                         mSetStates = new LinkedList<>();
229                         return res;
230                     }
231                 }
232             }
233         }
234 
sendPowerState(int state, int param)235         private void sendPowerState(int state, int param) {
236             getMockedVehicleHal().injectEvent(
237                     VehiclePropValueBuilder.newBuilder(VehicleProperty.AP_POWER_STATE_REQ)
238                             .setTimestamp(SystemClock.elapsedRealtimeNanos())
239                             .addIntValue(state, param)
240                             .build());
241         }
242     }
243 }
244