• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.setupwizardlib.shadows;
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.invocation.InvocationOnMock;
29 import org.mockito.stubbing.Answer;
30 import org.robolectric.annotation.Implementation;
31 import org.robolectric.annotation.Implements;
32 import org.robolectric.annotation.Resetter;
33 
34 /**
35  * Shadow class for {@link Car}. Allows tests to control the return values and behavior of the
36  * object.
37  */
38 @Implements(Car.class)
39 public class ShadowCar {
40 
41     private static Car sMockCar = mock(Car.class);
42     private static boolean sIsConnected;
43     private static String sServiceName;
44     private static Object sCarManager;
45     private static boolean sHasConnected;
46     private static boolean sHasDisconnected;
47 
48     /**
49      * Returns a mocked version of a {@link Car} object. Will reset
50      */
51     @Implementation
createCar(Context context, ServiceConnection serviceConnection)52     public static Car createCar(Context context, ServiceConnection serviceConnection) {
53         if (serviceConnection != null) {
54             doAnswer(new Answer<Void>() {
55                 @Override
56                 public Void answer(InvocationOnMock invocation) {
57                     serviceConnection.onServiceConnected(null, null);
58                     sHasConnected = true;
59                     return null;
60                 }
61             }).when(sMockCar).connect();
62             doAnswer(new Answer<Void>() {
63                 @Override
64                 public Void answer(InvocationOnMock invocation) {
65                     sHasDisconnected = true;
66                     serviceConnection.onServiceDisconnected(null);
67                     return null;
68                 }
69             }).when(sMockCar).disconnect();
70         }
71         doReturn(sIsConnected).when(sMockCar).isConnected();
72         if (sServiceName != null) {
73             try {
74                 doReturn(sCarManager).when(sMockCar).getCarManager(sServiceName);
75             } catch (CarNotConnectedException e) {
76                 // do nothing, have to do this because compiler doesn't understand mock can't throw
77                 // exception.
78             }
79         }
80         return sMockCar;
81     }
82 
83     /**
84      * Sets the isConnected state for the car returned by the {@link #createCar(Context,
85      * ServiceConnection)} method.
86      */
setIsConnected(boolean connected)87     public static void setIsConnected(boolean connected) {
88         sIsConnected = connected;
89         doReturn(connected).when(sMockCar).isConnected();
90     }
91 
92     /**
93      * Sets the manager returned by {@link Car#getCarManager(String)}.
94      *
95      * @param serviceName the name for the service request that should return this car manager.
96      * @param carManager  the object returned by a call with this service.
97      */
setCarManager(String serviceName, Object carManager)98     public static void setCarManager(String serviceName, Object carManager) {
99         sServiceName = serviceName;
100         sCarManager = carManager;
101         try {
102             doReturn(carManager).when(sMockCar).getCarManager(serviceName);
103         } catch (CarNotConnectedException e) {
104             // do nothing, have to do this because compiler doesn't understand mock can't throw e.
105         }
106     }
107 
108     /**
109      * Returns whether the mock has received a call to connect.
110      */
hasConnected()111     public static boolean hasConnected() {
112         return sHasConnected;
113     }
114 
115     /**
116      * Returns whether the mock has received a call to disconnect.
117      */
hasDisconnected()118     public static boolean hasDisconnected() {
119         return sHasDisconnected;
120     }
121 
122     /**
123      * Triggers a disconnect on the mock object being held.
124      */
triggerDisconnect()125     public static void triggerDisconnect() {
126         sMockCar.disconnect();
127     }
128 
129     /**
130      * Resets the shadow state, note this will not remove stubbed behavior on references to older
131      * calls to {@link #createCar(Context, ServiceConnection)}.
132      */
133     @Resetter
reset()134     public static void reset() {
135         sMockCar = mock(Car.class);
136         sServiceName = null;
137         sCarManager = null;
138         sIsConnected = false;
139         sHasConnected = false;
140         sHasDisconnected = false;
141     }
142 }
143