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 android.car.test;
17 
18 import android.annotation.SystemApi;
19 import android.car.CarManagerBase;
20 import android.os.IBinder;
21 import android.os.RemoteException;
22 
23 import com.android.car.vehiclenetwork.IVehicleNetworkHalMock;
24 import com.android.car.vehiclenetwork.VehicleNetwork.VehicleNetworkHalMock;
25 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfigs;
26 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
27 import com.android.car.vehiclenetwork.VehiclePropConfigsParcelable;
28 import com.android.car.vehiclenetwork.VehiclePropValueParcelable;
29 import com.android.internal.annotations.GuardedBy;
30 
31 import java.lang.ref.WeakReference;
32 
33 /**
34  * API for testing only. Allows mocking vehicle hal.
35  * @hide
36  */
37 @SystemApi
38 public class CarTestManager implements CarManagerBase {
39 
40     /**
41      * Flag for {@link #startMocking(VehicleNetworkHalMock, int)}.
42      * This is for passing no flag.
43      */
44     public static final int FLAG_MOCKING_NONE = 0x0;
45 
46     /**
47      * Flag for {@link #startMocking(VehicleNetworkHalMock, int)}.
48      * When this flag is set, shutdown request from mocked vehicle HAL will shutdown the system
49      * instead of avoiding shutdown, which is the default behavior.
50      * This can be used to test shutdown flow manually using mocking.
51      */
52     public static final int FLAG_MOCKING_REAL_SHUTDOWN = 0x1;
53 
54     private final ICarTest mService;
55 
56     @GuardedBy("this")
57     private VehicleNetworkHalMock mHalMock;
58     private IVehicleNetworkHalMockImpl mHalMockImpl;
59 
CarTestManager(CarTestManagerBinderWrapper wrapper)60     public CarTestManager(CarTestManagerBinderWrapper wrapper) {
61         mService = ICarTest.Stub.asInterface(wrapper.binder);
62     }
63 
64     @Override
onCarDisconnected()65     public void onCarDisconnected() {
66         // should not happen for embedded
67     }
68 
69     /**
70      * Inject vehicle prop value event.
71      * @param value
72      */
injectEvent(VehiclePropValue value)73     public void injectEvent(VehiclePropValue value) {
74         try {
75             mService.injectEvent(new VehiclePropValueParcelable(value));
76         } catch (RemoteException e) {
77             handleRemoteException(e);
78         }
79     }
80 
81     /**
82      * Check if given property is supported by vehicle hal.
83      * @param property
84      * @return
85      */
isPropertySupported(int property)86     public boolean isPropertySupported(int property) {
87         try {
88             return mService.isPropertySupported(property);
89         } catch (RemoteException e) {
90             handleRemoteException(e);
91         }
92         return false;
93     }
94     /**
95      * Start mocking vehicle HAL. It is somewhat strange to re-use interface in lower level
96      * API, but this is only for testing, and interface is exactly the same.
97      * @param mock
98      * @flags Combination of FLAG_MOCKING_*
99      */
startMocking(VehicleNetworkHalMock mock, int flags)100     public void startMocking(VehicleNetworkHalMock mock, int flags) {
101         IVehicleNetworkHalMockImpl halMockImpl = new IVehicleNetworkHalMockImpl(this);
102         synchronized (this) {
103             mHalMock = mock;
104             mHalMockImpl = halMockImpl;
105         }
106         try {
107             mService.startMocking(halMockImpl, flags);
108         } catch (RemoteException e) {
109             handleRemoteException(e);
110         }
111     }
112 
113     /**
114      * Stop previously started mocking.
115      */
stopMocking()116     public void stopMocking() {
117         IVehicleNetworkHalMockImpl halMockImpl;
118         synchronized (this) {
119             halMockImpl = mHalMockImpl;
120             mHalMock = null;
121             mHalMockImpl = null;
122         }
123         try {
124             mService.stopMocking(halMockImpl);
125         } catch (RemoteException e) {
126             handleRemoteException(e);
127         }
128     }
129 
getHalMock()130     private synchronized VehicleNetworkHalMock getHalMock() {
131         return mHalMock;
132     }
133 
handleRemoteException(RemoteException e)134     private void handleRemoteException(RemoteException e) {
135         //TODO
136     }
137 
138     private static class IVehicleNetworkHalMockImpl extends IVehicleNetworkHalMock.Stub {
139         private final WeakReference<CarTestManager> mTestManager;
140 
IVehicleNetworkHalMockImpl(CarTestManager testManager)141         private IVehicleNetworkHalMockImpl(CarTestManager testManager) {
142             mTestManager = new WeakReference<CarTestManager>(testManager);
143         }
144 
145         @Override
onListProperties()146         public VehiclePropConfigsParcelable onListProperties() {
147             CarTestManager testManager = mTestManager.get();
148             if (testManager == null) {
149                 return null;
150             }
151             VehiclePropConfigs configs = testManager.getHalMock().onListProperties();
152             return new VehiclePropConfigsParcelable(configs);
153         }
154 
155         @Override
onPropertySet(VehiclePropValueParcelable value)156         public void onPropertySet(VehiclePropValueParcelable value) {
157             CarTestManager testManager = mTestManager.get();
158             if (testManager == null) {
159                 return;
160             }
161             testManager.getHalMock().onPropertySet(value.value);
162         }
163 
164         @Override
onPropertyGet(VehiclePropValueParcelable value)165         public VehiclePropValueParcelable onPropertyGet(VehiclePropValueParcelable value) {
166             CarTestManager testManager = mTestManager.get();
167             if (testManager == null) {
168                 return null;
169             }
170             VehiclePropValue retValue = testManager.getHalMock().onPropertyGet(value.value);
171             return new VehiclePropValueParcelable(retValue);
172         }
173 
174         @Override
onPropertySubscribe(int property, float sampleRate, int zones)175         public void onPropertySubscribe(int property, float sampleRate, int zones) {
176             CarTestManager testManager = mTestManager.get();
177             if (testManager == null) {
178                 return;
179             }
180             testManager.getHalMock().onPropertySubscribe(property, sampleRate, zones);
181         }
182 
183         @Override
onPropertyUnsubscribe(int property)184         public void onPropertyUnsubscribe(int property) {
185             CarTestManager testManager = mTestManager.get();
186             if (testManager == null) {
187                 return;
188             }
189             testManager.getHalMock().onPropertyUnsubscribe(property);
190         }
191     }
192 }
193