1 /* 2 * Copyright (C) 2018 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 17 package com.android.car.settings.testutils; 18 19 import static org.mockito.Mockito.doAnswer; 20 import static org.mockito.Mockito.doReturn; 21 import static org.mockito.Mockito.mock; 22 23 import android.car.Car; 24 import android.car.CarNotConnectedException; 25 import android.content.Context; 26 import android.content.ServiceConnection; 27 28 import org.mockito.stubbing.Answer; 29 import org.robolectric.annotation.Implementation; 30 import org.robolectric.annotation.Implements; 31 import org.robolectric.annotation.Resetter; 32 33 /** 34 * Shadow class for {@link Car}. Components in car support library expects 35 * this class to be available at run time. 36 */ 37 @Implements(Car.class) 38 public class ShadowCar { 39 40 private static Car sMockCar = mock(Car.class); 41 private static boolean sIsConnected; 42 private static String sServiceName; 43 private static Object sCarManager; 44 45 /** 46 * Returns a mocked version of a {@link Car} object. 47 */ 48 @Implementation createCar(Context context, ServiceConnection serviceConnection)49 protected static Car createCar(Context context, ServiceConnection serviceConnection) { 50 if (serviceConnection != null) { 51 doAnswer((Answer<Void>) invocation -> { 52 serviceConnection.onServiceConnected(null, null); 53 return null; 54 }).when(sMockCar).connect(); 55 doAnswer((Answer<Void>) invocation -> { 56 serviceConnection.onServiceDisconnected(null); 57 return null; 58 }).when(sMockCar).disconnect(); 59 } 60 doReturn(sIsConnected).when(sMockCar).isConnected(); 61 if (sServiceName != null) { 62 try { 63 doReturn(sCarManager).when(sMockCar).getCarManager(sServiceName); 64 } catch (CarNotConnectedException e) { 65 // do nothing, have to do this because compiler doesn't understand mock can't throw 66 // exception. 67 } 68 } 69 return sMockCar; 70 } 71 72 /** 73 * Returns a mocked version of a {@link Car} object. 74 */ 75 @Implementation createCar(Context context)76 protected static Car createCar(Context context) { 77 doReturn(sIsConnected).when(sMockCar).isConnected(); 78 if (sServiceName != null) { 79 try { 80 doReturn(sCarManager).when(sMockCar).getCarManager(sServiceName); 81 } catch (CarNotConnectedException e) { 82 // do nothing, have to do this because compiler doesn't understand mock can't throw 83 // exception. 84 } 85 } 86 return sMockCar; 87 } 88 89 /** 90 * Sets the manager returned by {@link Car#getCarManager(String)}. 91 * 92 * @param serviceName the name for the service request that should return this car manager. 93 * @param carManager the object returned by a call with this service. 94 */ setCarManager(String serviceName, Object carManager)95 public static void setCarManager(String serviceName, Object carManager) { 96 sServiceName = serviceName; 97 sCarManager = carManager; 98 try { 99 doReturn(carManager).when(sMockCar).getCarManager(serviceName); 100 } catch (CarNotConnectedException e) { 101 // do nothing, have to do this because compiler doesn't understand mock can't throw e. 102 } 103 } 104 105 /** 106 * Resets the shadow state, note this will not remove stubbed behavior on references to older 107 * calls to {@link #createCar(Context, ServiceConnection)}. 108 */ 109 @Resetter reset()110 public static void reset() { 111 sMockCar = mock(Car.class); 112 sServiceName = null; 113 sCarManager = null; 114 sIsConnected = false; 115 } 116 } 117