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.test.hal; 17 18 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DEBUGGING_CODE; 19 20 import static org.mockito.Mockito.mock; 21 import static org.mockito.Mockito.when; 22 23 import android.car.feature.FeatureFlagsImpl; 24 import android.car.test.mocks.JavaMockitoHelper; 25 import android.content.Context; 26 import android.hardware.automotive.vehicle.VehicleApPowerStateReq; 27 import android.util.Log; 28 import android.util.SparseIntArray; 29 import android.view.Display; 30 31 import com.android.car.CarServiceUtils; 32 import com.android.car.VehicleStub; 33 import com.android.car.hal.ClusterHalService; 34 import com.android.car.hal.DiagnosticHalService; 35 import com.android.car.hal.HalPropValueBuilder; 36 import com.android.car.hal.InputHalService; 37 import com.android.car.hal.PowerHalService; 38 import com.android.car.hal.PropertyHalService; 39 import com.android.car.hal.TimeHalService; 40 import com.android.car.hal.UserHalService; 41 import com.android.car.hal.VehicleHal; 42 import com.android.car.hal.VmsHalService; 43 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport; 44 import com.android.car.systeminterface.DisplayHelperInterface; 45 import com.android.internal.annotations.GuardedBy; 46 47 import java.util.LinkedList; 48 import java.util.concurrent.CountDownLatch; 49 import java.util.concurrent.TimeoutException; 50 51 @ExcludeFromCodeCoverageGeneratedReport(reason = DEBUGGING_CODE) 52 public class MockedPowerHalService extends PowerHalService { 53 private static final String TAG = MockedPowerHalService.class.getSimpleName(); 54 55 private final boolean mIsPowerStateSupported; 56 private final boolean mIsTimedWakeupAllowed; 57 58 private final Object mLock = new Object(); 59 private final CountDownLatch mBrightnessSendLatch = new CountDownLatch(1); 60 61 @GuardedBy("mLock") 62 private PowerState mCurrentPowerState = new PowerState(VehicleApPowerStateReq.ON, 0); 63 64 @GuardedBy("mLock") 65 private PowerEventListener mListener; 66 67 @GuardedBy("mLock") 68 private SignalListener mSignalListener; 69 70 @GuardedBy("mLock") 71 private final LinkedList<int[]> mSentStates = new LinkedList<>(); 72 73 @GuardedBy("mLock") 74 private final SparseIntArray mDisplayBrightnessSet = new SparseIntArray(); 75 76 private boolean mIsDeepSleepAllowed; 77 private boolean mIsHibernationAllowed; 78 @PowerState.ShutdownType 79 private int mRequestedShutdownPowerState = PowerState.SHUTDOWN_TYPE_UNDEFINED; 80 81 public interface SignalListener { 82 /** 83 * Sends signals 84 * @param signal The signal to send 85 */ sendingSignal(int signal)86 void sendingSignal(int signal); 87 } 88 createVehicleHalWithMockedServices()89 private static VehicleHal createVehicleHalWithMockedServices() { 90 HalPropValueBuilder propValueBuilder = new HalPropValueBuilder(/*isAidl=*/true); 91 VehicleStub vehicleStub = mock(VehicleStub.class); 92 when(vehicleStub.getHalPropValueBuilder()).thenReturn(propValueBuilder); 93 VehicleHal mockedVehicleHal = new VehicleHal( 94 mock(Context.class), 95 mock(PowerHalService.class), 96 mock(PropertyHalService.class), 97 mock(InputHalService.class), 98 mock(VmsHalService.class), 99 mock(UserHalService.class), 100 mock(DiagnosticHalService.class), 101 mock(ClusterHalService.class), 102 mock(TimeHalService.class), 103 CarServiceUtils.getHandlerThread(VehicleHal.class.getSimpleName()), 104 vehicleStub); 105 106 return mockedVehicleHal; 107 } 108 MockedPowerHalService(boolean isPowerStateSupported, boolean isDeepSleepAllowed, boolean isHibernationAllowed, boolean isTimedWakeupAllowed)109 public MockedPowerHalService(boolean isPowerStateSupported, boolean isDeepSleepAllowed, 110 boolean isHibernationAllowed, boolean isTimedWakeupAllowed) { 111 super(mock(Context.class), new FeatureFlagsImpl(), 112 createVehicleHalWithMockedServices(), new DisplayHelperInterface.DefaultImpl()); 113 mIsPowerStateSupported = isPowerStateSupported; 114 mIsDeepSleepAllowed = isDeepSleepAllowed; 115 mIsHibernationAllowed = isHibernationAllowed; 116 mIsTimedWakeupAllowed = isTimedWakeupAllowed; 117 } 118 119 @Override setListener(PowerEventListener listener)120 public void setListener(PowerEventListener listener) { 121 synchronized (mLock) { 122 mListener = listener; 123 } 124 } 125 126 /** 127 * Sets the signalListener 128 * @param listener The listener to set 129 */ setSignalListener(SignalListener listener)130 public void setSignalListener(SignalListener listener) { 131 synchronized (mLock) { 132 mSignalListener = listener; 133 } 134 } 135 136 @Override sendOn()137 public void sendOn() { 138 Log.i(TAG, "sendOn"); 139 doSendState(SET_ON, 0); 140 } 141 142 @Override sendWaitForVhal()143 public void sendWaitForVhal() { 144 Log.i(TAG, "sendWaitForVhal"); 145 doSendState(SET_WAIT_FOR_VHAL, 0); 146 } 147 148 @Override sendSleepEntry(int wakeupTimeSec)149 public void sendSleepEntry(int wakeupTimeSec) { 150 Log.i(TAG, "sendSleepEntry"); 151 doSendState(SET_DEEP_SLEEP_ENTRY, wakeupTimeSec); 152 } 153 154 @Override sendSleepExit()155 public void sendSleepExit() { 156 Log.i(TAG, "sendSleepExit"); 157 doSendState(SET_DEEP_SLEEP_EXIT, 0); 158 } 159 160 @Override sendShutdownPostpone(int postponeTimeMs)161 public void sendShutdownPostpone(int postponeTimeMs) { 162 Log.i(TAG, "sendShutdownPostpone"); 163 doSendState(SET_SHUTDOWN_POSTPONE, postponeTimeMs); 164 } 165 166 @Override sendShutdownStart(int wakeupTimeSec)167 public void sendShutdownStart(int wakeupTimeSec) { 168 Log.i(TAG, "sendShutdownStart"); 169 doSendState(SET_SHUTDOWN_START, wakeupTimeSec); 170 } 171 172 @Override sendShutdownCancel()173 public void sendShutdownCancel() { 174 Log.i(TAG, "sendShutdownCancel"); 175 doSendState(SET_SHUTDOWN_CANCELLED, 0); 176 } 177 178 @Override sendShutdownPrepare()179 public void sendShutdownPrepare() { 180 Log.i(TAG, "sendShutdownPrepare"); 181 super.sendShutdownPrepare(); 182 } 183 184 @Override sendHibernationEntry(int wakeupTimeSec)185 public void sendHibernationEntry(int wakeupTimeSec) { 186 Log.i(TAG, "sendHibernationEntry"); 187 doSendState(SET_HIBERNATION_ENTRY, wakeupTimeSec); 188 } 189 190 @Override sendHibernationExit()191 public void sendHibernationExit() { 192 Log.i(TAG, "sendHibernationExit"); 193 doSendState(SET_HIBERNATION_EXIT, 0); 194 } 195 196 @Override sendDisplayBrightnessLegacy(int brightness)197 public void sendDisplayBrightnessLegacy(int brightness) { 198 sendDisplayBrightness(Display.DEFAULT_DISPLAY, brightness); 199 } 200 201 @Override sendDisplayBrightness(int displayId, int brightness)202 public void sendDisplayBrightness(int displayId, int brightness) { 203 synchronized (mLock) { 204 mDisplayBrightnessSet.put(displayId, brightness); 205 } 206 mBrightnessSendLatch.countDown(); 207 } 208 209 /** 210 * Gets the display brightness 211 * 212 * @param displayId DisplayId to check brightness 213 * @return brightness of the displayId 214 */ getDisplayBrightness(int displayId)215 public int getDisplayBrightness(int displayId) { 216 synchronized (mLock) { 217 return mDisplayBrightnessSet.get(displayId, -1); 218 } 219 } 220 221 /** 222 * Waits for the brightness to be sent 223 * 224 * @param displayId The displayId of the brightness 225 * @param brightness the brightness to set 226 * @param timeoutMs Amount of ms to wait before timeout. 227 * @throws Exception If the brightness is not sent by timeout. 228 */ waitForBrightnessSent(int displayId, int brightness, long timeoutMs)229 public void waitForBrightnessSent(int displayId, int brightness, long timeoutMs) 230 throws Exception { 231 if (getDisplayBrightness(displayId) == brightness) { 232 return; 233 } 234 JavaMockitoHelper.await(mBrightnessSendLatch, timeoutMs); 235 } 236 237 @Override requestShutdownAp(@owerState.ShutdownType int powerState, boolean runGarageMode)238 public void requestShutdownAp(@PowerState.ShutdownType int powerState, boolean runGarageMode) { 239 mRequestedShutdownPowerState = powerState; 240 } 241 getRequestedShutdownPowerState()242 public int getRequestedShutdownPowerState() { 243 return mRequestedShutdownPowerState; 244 } 245 246 /** 247 * Wait for sent events to be finished 248 * 249 * @param timeoutMs Timeout when events are not all sent by this time 250 * @return All the events that were sent 251 * @throws TimeoutException SentState is empty 252 */ waitForSend(long timeoutMs)253 public int[] waitForSend(long timeoutMs) throws Exception { 254 long now = System.currentTimeMillis(); 255 long deadline = now + timeoutMs; 256 synchronized (mLock) { 257 while (mSentStates.isEmpty() && now < deadline) { 258 mLock.wait(deadline - now); 259 now = System.currentTimeMillis(); 260 } 261 if (mSentStates.isEmpty()) { 262 throw new TimeoutException("mSentStates is still empty " 263 + "(monitor was not notified in " + timeoutMs + " ms)"); 264 } 265 return mSentStates.removeFirst(); 266 } 267 } 268 doSendState(int state, int param)269 private void doSendState(int state, int param) { 270 int[] toSend = new int[] {state, param}; 271 SignalListener listener; 272 synchronized (mLock) { 273 listener = mSignalListener; 274 mSentStates.addLast(toSend); 275 mLock.notifyAll(); 276 } 277 if (listener != null) { 278 listener.sendingSignal(state); 279 } 280 } 281 282 @Override isPowerStateSupported()283 public boolean isPowerStateSupported() { 284 return mIsPowerStateSupported; 285 } 286 287 @Override isDeepSleepAllowed()288 public boolean isDeepSleepAllowed() { 289 return mIsDeepSleepAllowed; 290 } 291 292 @Override isHibernationAllowed()293 public boolean isHibernationAllowed() { 294 return mIsHibernationAllowed; 295 } 296 297 @Override isTimedWakeupAllowed()298 public boolean isTimedWakeupAllowed() { 299 return mIsTimedWakeupAllowed; 300 } 301 302 @Override getCurrentPowerState()303 public PowerState getCurrentPowerState() { 304 synchronized (mLock) { 305 return mCurrentPowerState; 306 } 307 } 308 setDeepSleepEnabled(boolean enabled)309 public void setDeepSleepEnabled(boolean enabled) { 310 mIsDeepSleepAllowed = enabled; 311 } 312 setHibernationEnabled(boolean enabled)313 public void setHibernationEnabled(boolean enabled) { 314 mIsHibernationAllowed = enabled; 315 } 316 317 /** 318 * Sets the current power state to the state that is given. 319 * @param state The power state to set 320 */ setCurrentPowerState(PowerState state)321 public void setCurrentPowerState(PowerState state) { 322 setCurrentPowerState(state, true); 323 } 324 325 /** 326 * Sets the current power state 327 * @param state The state to set 328 * @param notify If to notify listeners 329 */ setCurrentPowerState(PowerState state, boolean notify)330 public void setCurrentPowerState(PowerState state, boolean notify) { 331 PowerEventListener listener; 332 synchronized (mLock) { 333 mCurrentPowerState = state; 334 listener = mListener; 335 } 336 if (listener != null && notify) { 337 listener.onApPowerStateChange(state); 338 } 339 } 340 } 341