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.notification.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 
51         if (serviceConnection != null) {
52             doAnswer((Answer<Void>) invocation -> {
53                 serviceConnection.onServiceConnected(null, null);
54                 return null;
55             }).when(sMockCar).connect();
56             doAnswer((Answer<Void>) invocation -> {
57                 serviceConnection.onServiceDisconnected(null);
58                 return null;
59             }).when(sMockCar).disconnect();
60         }
61         doReturn(sIsConnected).when(sMockCar).isConnected();
62         if (sServiceName != null) {
63             try {
64                 doReturn(sCarManager).when(sMockCar).getCarManager(sServiceName);
65             } catch (CarNotConnectedException e) {
66                 // do nothing, have to do this because compiler doesn't understand mock can't throw
67                 // exception.
68             }
69         }
70         return sMockCar;
71     }
72 
73     /**
74      * Sets the manager returned by {@link Car#getCarManager(String)}.
75      *
76      * @param serviceName the name for the service request that should return this car manager.
77      * @param carManager  the object returned by a call with this service.
78      */
setCarManager(String serviceName, Object carManager)79     public static void setCarManager(String serviceName, Object carManager) {
80         sServiceName = serviceName;
81         sCarManager = carManager;
82         try {
83             doReturn(carManager).when(sMockCar).getCarManager(serviceName);
84         } catch (CarNotConnectedException e) {
85             // do nothing, have to do this because compiler doesn't understand mock can't throw e.
86         }
87     }
88 
89     /**
90      * Resets the shadow state, note this will not remove stubbed behavior on references to older
91      * calls to {@link #createCar(Context, ServiceConnection)}.
92      */
93     @Resetter
reset()94     public static void reset() {
95         sMockCar = mock(Car.class);
96         sServiceName = null;
97         sCarManager = null;
98         sIsConnected = false;
99     }
100 }
101 
102