• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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;
18 
19 import android.annotation.Nullable;
20 import android.car.builtin.os.BuildHelper;
21 import android.car.builtin.util.Slogf;
22 import android.car.hardware.CarPropertyValue;
23 import android.hardware.automotive.vehicle.RawPropValues;
24 import android.hardware.automotive.vehicle.SubscribeOptions;
25 import android.os.IBinder.DeathRecipient;
26 import android.os.RemoteException;
27 import android.os.ServiceSpecificException;
28 
29 import com.android.car.hal.HalAreaConfig;
30 import com.android.car.hal.HalPropConfig;
31 import com.android.car.hal.HalPropValue;
32 import com.android.car.hal.HalPropValueBuilder;
33 import com.android.car.hal.VehicleHalCallback;
34 import com.android.car.hal.fakevhal.FakeVehicleStub;
35 import com.android.car.internal.property.CarPropertyErrorCodes;
36 import com.android.car.internal.property.CarPropertyErrorCodes.CarPropMgrErrorCode;
37 import com.android.car.internal.property.PropIdAreaId;
38 
39 import java.io.FileDescriptor;
40 import java.util.List;
41 
42 /**
43  * VehicleStub represents an IVehicle service interface in either AIDL or legacy HIDL version. It
44  * exposes common interface so that the client does not need to care about which version the
45  * underlying IVehicle service is in.
46  */
47 public abstract class VehicleStub {
48 
49     /**
50      * SubscriptionClient represents a client that could subscribe/unsubscribe to properties.
51      */
52     public interface SubscriptionClient {
53         /**
54          * Subscribes to a property.
55          *
56          * @param options The list of subscribe options.
57          * @throws RemoteException if the remote operation fails.
58          * @throws ServiceSpecificException if VHAL returns service specific error.
59          */
subscribe(SubscribeOptions[] options)60         void subscribe(SubscribeOptions[] options) throws RemoteException, ServiceSpecificException;
61 
62         /**
63          * Unsubscribes from a property.
64          *
65          * @param prop The ID for the property to unsubscribe.
66          * @throws RemoteException if the remote operation fails.
67          * @throws ServiceSpecificException if VHAL returns service specific error.
68          */
unsubscribe(int prop)69         void unsubscribe(int prop) throws RemoteException, ServiceSpecificException;
70 
71         /**
72          * Registers the callback to be called when the min/max supported value or supportd values
73          * list change for the [propId, areaId]s.
74          *
75          * @throws ServiceSpecificException If VHAL returns error or VHAL connection fails.
76          */
registerSupportedValuesChange(List<PropIdAreaId> propIdAreaIds)77         void registerSupportedValuesChange(List<PropIdAreaId> propIdAreaIds);
78 
79         /**
80          * Unregisters the [propId, areaId]s previously registered with
81          * registerSupportedValuesChange.
82          *
83          * Do nothing if the [propId, areaId]s were not previously registered.
84          *
85          * This operation is always assumed succeeded.
86          */
unregisterSupportedValuesChange(List<PropIdAreaId> propIdAreaIds)87         void unregisterSupportedValuesChange(List<PropIdAreaId> propIdAreaIds);
88     }
89 
90     /**
91      * A request for {@link VehicleStub#getAsync} or {@link VehicleStub#setAsync}.
92      */
93     public static class AsyncGetSetRequest {
94         private final int mServiceRequestId;
95         private final HalPropValue mHalPropValue;
96         private final long mTimeoutUptimeMs;
97 
getServiceRequestId()98         public int getServiceRequestId() {
99             return mServiceRequestId;
100         }
101 
getHalPropValue()102         public HalPropValue getHalPropValue() {
103             return mHalPropValue;
104         }
105 
getTimeoutUptimeMs()106         public long getTimeoutUptimeMs() {
107             return mTimeoutUptimeMs;
108         }
109 
110         /**
111          * Get an instance for AsyncGetSetRequest.
112          */
AsyncGetSetRequest(int serviceRequestId, HalPropValue halPropValue, long timeoutUptimeMs)113         public AsyncGetSetRequest(int serviceRequestId, HalPropValue halPropValue,
114                 long timeoutUptimeMs) {
115             mServiceRequestId = serviceRequestId;
116             mHalPropValue = halPropValue;
117             mTimeoutUptimeMs = timeoutUptimeMs;
118         }
119     }
120 
121     /**
122      * A result for {@link VehicleStub#getAsync}.
123      */
124     public static final class GetVehicleStubAsyncResult {
125         private final int mServiceRequestId;
126         @Nullable
127         private final HalPropValue mHalPropValue;
128         private final CarPropertyErrorCodes mCarPropertyErrorCodes;
129 
getServiceRequestId()130         public int getServiceRequestId() {
131             return mServiceRequestId;
132         }
133 
134         @Nullable
getHalPropValue()135         public HalPropValue getHalPropValue() {
136             return mHalPropValue;
137         }
138 
getCarPropertyErrorCodes()139         public CarPropertyErrorCodes getCarPropertyErrorCodes() {
140             return mCarPropertyErrorCodes;
141         }
142 
143         /**
144          * Constructs an instance for GetVehicleStubAsyncResult when result returned successfully.
145          */
GetVehicleStubAsyncResult(int serviceRequestId, HalPropValue halPropValue)146         public GetVehicleStubAsyncResult(int serviceRequestId, HalPropValue halPropValue) {
147             mServiceRequestId = serviceRequestId;
148             mHalPropValue = halPropValue;
149             mCarPropertyErrorCodes = CarPropertyErrorCodes.STATUS_OK_NO_ERROR;
150         }
151 
152         /**
153          * Constructs an instance for GetVehicleStubAsyncResult when errors.
154          */
GetVehicleStubAsyncResult(int serviceRequestId, CarPropertyErrorCodes errorCodes)155         public GetVehicleStubAsyncResult(int serviceRequestId, CarPropertyErrorCodes errorCodes) {
156             mServiceRequestId = serviceRequestId;
157             mHalPropValue = null;
158             mCarPropertyErrorCodes = errorCodes;
159         }
160     }
161 
162     /**
163      * A result for {@link VehicleStub#setAsync}.
164      */
165     public static final class SetVehicleStubAsyncResult {
166         private final int mServiceRequestId;
167         @CarPropMgrErrorCode
168         private final CarPropertyErrorCodes mCarPropertyErrorCodes;
169 
getServiceRequestId()170         public int getServiceRequestId() {
171             return mServiceRequestId;
172         }
173 
getCarPropertyErrorCodes()174         public CarPropertyErrorCodes getCarPropertyErrorCodes() {
175             return mCarPropertyErrorCodes;
176         }
177 
178         /**
179          * Constructs an success result.
180          */
SetVehicleStubAsyncResult(int serviceRequestId)181         public SetVehicleStubAsyncResult(int serviceRequestId) {
182             mServiceRequestId = serviceRequestId;
183             mCarPropertyErrorCodes = CarPropertyErrorCodes.STATUS_OK_NO_ERROR;
184         }
185 
186         /**
187          * Constructs an instance for SetVehicleStubAsyncResult when errors.
188          */
SetVehicleStubAsyncResult(int serviceRequestId, CarPropertyErrorCodes errorCodes)189         public SetVehicleStubAsyncResult(int serviceRequestId, CarPropertyErrorCodes errorCodes) {
190             mServiceRequestId = serviceRequestId;
191             mCarPropertyErrorCodes = errorCodes;
192         }
193     }
194 
195     /**
196      * A callback for asynchronous operations.
197      */
198     public abstract static class VehicleStubCallbackInterface {
199         /**
200          * Method called when {@link getAsync} returns results.
201          */
onGetAsyncResults( List<GetVehicleStubAsyncResult> getVehicleStubAsyncResults)202         public abstract void onGetAsyncResults(
203                 List<GetVehicleStubAsyncResult> getVehicleStubAsyncResults);
204 
205         /**
206          * Method called when {@link setAsync} returns results.
207          */
onSetAsyncResults( List<SetVehicleStubAsyncResult> setVehicleStubAsyncResults)208         public abstract void onSetAsyncResults(
209                 List<SetVehicleStubAsyncResult> setVehicleStubAsyncResults);
210 
211         /**
212          * Register a callback that will be called when the callback binder died.
213          */
linkToDeath(DeathRecipient recipient)214         public abstract void linkToDeath(DeathRecipient recipient) throws RemoteException;
215 
216         /**
217          * Method called when async requests timed-out.
218          *
219          * If the callback's binder is already dead, this function will not be called.
220          */
onRequestsTimeout(List<Integer> serviceRequestIds)221         public abstract void onRequestsTimeout(List<Integer> serviceRequestIds);
222     }
223 
224     /**
225      * Gets a property asynchronously.
226      */
getAsync(List<AsyncGetSetRequest> getVehicleStubAsyncRequests, VehicleStubCallbackInterface getVehicleStubAsyncCallback)227     public abstract void getAsync(List<AsyncGetSetRequest> getVehicleStubAsyncRequests,
228             VehicleStubCallbackInterface getVehicleStubAsyncCallback);
229 
230     /**
231      * Sets a property asynchronously.
232      */
setAsync(List<AsyncGetSetRequest> setVehicleStubAsyncRequests, VehicleStubCallbackInterface setVehicleStubAsyncCallback)233     public abstract void setAsync(List<AsyncGetSetRequest> setVehicleStubAsyncRequests,
234             VehicleStubCallbackInterface setVehicleStubAsyncCallback);
235 
236     /**
237      * Checks whether we are connected to AIDL VHAL: {@code true} or HIDL VHAL: {@code false}.
238      */
isAidlVhal()239     public abstract boolean isAidlVhal();
240 
241     /**
242      * Creates a new VehicleStub to connect to Vehicle HAL.
243      *
244      * Create a new VehicleStub to connect to Vehicle HAL according to which backend (AIDL or HIDL)
245      * is available. This function will throw {@link IllegalStateException} if no vehicle HAL is
246      * available.
247      *
248      * @return a vehicle stub to connect to Vehicle HAL.
249      */
newVehicleStub()250     public static VehicleStub newVehicleStub() throws IllegalStateException {
251         VehicleStub stub = new AidlVehicleStub();
252         if (stub.isValid()) {
253             if ((BuildHelper.isUserDebugBuild() || BuildHelper.isEngBuild())
254                     && FakeVehicleStub.doesEnableFileExist()) {
255                 try {
256                     return new FakeVehicleStub(stub);
257                 } catch (Exception e) {
258                     Slogf.e(CarLog.TAG_SERVICE, e, "Failed to create FakeVehicleStub. "
259                             + "Fallback to using real VehicleStub.");
260                 }
261             }
262             return stub;
263         }
264 
265         Slogf.i(CarLog.TAG_SERVICE, "No AIDL vehicle HAL found, fall back to HIDL version");
266 
267         stub = new HidlVehicleStub();
268 
269         if (!stub.isValid()) {
270             throw new IllegalStateException("Vehicle HAL service is not available.");
271         }
272 
273         return stub;
274     }
275 
276     /**
277      * Gets a HalPropValueBuilder that could be used to build a HalPropValue.
278      *
279      * @return a builder to build HalPropValue.
280      */
getHalPropValueBuilder()281     public abstract HalPropValueBuilder getHalPropValueBuilder();
282 
283     /**
284      * Returns whether this vehicle stub is connecting to a valid vehicle HAL.
285      *
286      * @return Whether this vehicle stub is connecting to a valid vehicle HAL.
287      */
isValid()288     public abstract boolean isValid();
289 
290     /**
291      * Gets the interface descriptor for the connecting vehicle HAL.
292      *
293      * @return the interface descriptor.
294      * @throws IllegalStateException If unable to get the descriptor.
295      */
getInterfaceDescriptor()296     public abstract String getInterfaceDescriptor() throws IllegalStateException;
297 
298     /**
299      * Registers a death recipient that would be called when vehicle HAL died.
300      *
301      * @param recipient A death recipient.
302      * @throws IllegalStateException If unable to register the death recipient.
303      */
linkToDeath(IVehicleDeathRecipient recipient)304     public abstract void linkToDeath(IVehicleDeathRecipient recipient) throws IllegalStateException;
305 
306     /**
307      * Unlinks a previously linked death recipient.
308      *
309      * @param recipient A previously linked death recipient.
310      */
unlinkToDeath(IVehicleDeathRecipient recipient)311     public abstract void unlinkToDeath(IVehicleDeathRecipient recipient);
312 
313     /**
314      * Gets all property configs.
315      *
316      * @return All the property configs.
317      * @throws RemoteException if the remote operation fails.
318      * @throws ServiceSpecificException if VHAL returns service specific error.
319      */
getAllPropConfigs()320     public abstract HalPropConfig[] getAllPropConfigs()
321             throws RemoteException, ServiceSpecificException;
322 
323     /**
324      * Gets a new {@code SubscriptionClient} that could be used to subscribe/unsubscribe.
325      *
326      * Caller MUST unsubscribe all subscribed properties before discarding the client to prevent
327      * resource leak.
328      *
329      * @param callback A callback that could be used to receive events.
330      * @return a {@code SubscriptionClient} that could be used to subscribe/unsubscribe.
331      */
newSubscriptionClient(VehicleHalCallback callback)332     public abstract SubscriptionClient newSubscriptionClient(VehicleHalCallback callback);
333 
334     /**
335      * Gets a property.
336      *
337      * @param requestedPropValue The property to get.
338      * @return The vehicle property value.
339      * @throws RemoteException if the remote operation fails.
340      * @throws ServiceSpecificException if VHAL returns service specific error.
341      */
342     @Nullable
get(HalPropValue requestedPropValue)343     public abstract HalPropValue get(HalPropValue requestedPropValue)
344             throws RemoteException, ServiceSpecificException;
345 
346     /**
347      * Sets a property.
348      *
349      * @param propValue The property to set.
350      * @throws RemoteException if the remote operation fails.
351      * @throws ServiceSpecificException if VHAL returns service specific error.
352      */
set(HalPropValue propValue)353     public abstract void set(HalPropValue propValue)
354             throws RemoteException, ServiceSpecificException;
355 
356     /**
357      * Dumps VHAL debug information.
358      *
359      * Additional arguments could also be provided through {@link args} to debug VHAL.
360      *
361      * @param fd The file descriptor to print output.
362      * @param args Optional additional arguments for the debug command. Can be empty.
363      * @throws RemoteException if the remote operation fails.
364      * @throws ServiceSpecificException if VHAL returns service specific error.
365      */
dump(FileDescriptor fd, List<String> args)366     public abstract void dump(FileDescriptor fd, List<String> args)
367             throws RemoteException, ServiceSpecificException;
368 
369     /**
370      * Checks if fake VHAL is enabled.
371      *
372      * @return {@code true} if a FakeVehicleStub instance is created.
373      */
isFakeModeEnabled()374     public boolean isFakeModeEnabled() {
375         return false;
376     }
377 
378     /**
379      * Checks if simulated mode is enabled
380      */
isSimulatedModeEnabled()381     public boolean isSimulatedModeEnabled() {
382         return false;
383     }
384 
385     /**
386      * Cancels all the on-going async requests with the given request IDs.
387      *
388      * @param requestIds a list of async get/set request IDs.
389      */
cancelRequests(List<Integer> requestIds)390     public void cancelRequests(List<Integer> requestIds) {}
391 
392     /**
393      * Whether the area config supports dynamic supported values API.
394      *
395      * This is only supported if area config has non-null
396      * {@code hasSupportedValuesInfo}.
397      */
isSupportedValuesImplemented(HalAreaConfig halAreaConfig)398     public boolean isSupportedValuesImplemented(HalAreaConfig halAreaConfig) {
399         return false;
400     }
401 
MinMaxSupportedRawPropValues( @ullable RawPropValues minValue, @Nullable RawPropValues maxValue)402     public record MinMaxSupportedRawPropValues(
403             @Nullable RawPropValues minValue, @Nullable RawPropValues maxValue) {};
404 
405     /**
406      * Gets the min/max supported value.
407      *
408      * Caller should only call this if {@link #isSupportedValuesImplemented} is {@code true}.
409      *
410      * If no min/max supported value is specified, return an empty structure.
411      *
412      * @throws ServiceSpecificException if the operation fails.
413      */
getMinMaxSupportedValue(int propertyId, int areaId)414     public MinMaxSupportedRawPropValues getMinMaxSupportedValue(int propertyId, int areaId)
415             throws ServiceSpecificException {
416         throw new UnsupportedOperationException();
417     }
418 
419     /**
420      * Gets the supported values list.
421      *
422      * Caller should only call this if {@link #isSupportedValuesImplemented} is {@code true}.
423      *
424      * The returned list is not sorted.
425      *
426      * If no supported values list is specified, return {@code null}.
427      *
428      * @throws ServiceSpecificException if the operation fails.
429      */
getSupportedValuesList(int propertyId, int areaId)430     public @Nullable List<RawPropValues> getSupportedValuesList(int propertyId, int areaId)
431             throws ServiceSpecificException {
432         throw new UnsupportedOperationException();
433     }
434 
435     /**
436      * Returns the real vehicle stub if the vehicle stub is fake.
437      *
438      * @return The real vehicle stub other wise this.
439      */
getRealVehicleStub()440     public VehicleStub getRealVehicleStub() {
441         return this;
442     }
443 
444     /**
445      * Returns the start time of the simulation in nanos.
446      */
getSimulationStartTimestampNanos()447     public long getSimulationStartTimestampNanos() {
448         throw new UnsupportedOperationException("Not in simulated mode");
449     }
450 
451     /**
452      * Injects the CarPropertyValues.
453      * @param carPropertyValues The carPropertyValues to inject.
454      */
injectVehicleProperties(List<CarPropertyValue> carPropertyValues)455     public void injectVehicleProperties(List<CarPropertyValue> carPropertyValues) {
456         throw new UnsupportedOperationException("Not in simulated mode");
457     }
458 
459     /**
460      * Gets the last injected vehicle property for the propertyId.
461      *
462      * @param propertyId The propertyId that was last injected.
463      * @return The {@link CarPropertyValue} that was last injected.
464      */
getLastInjectedVehicleProperty(int propertyId)465     public CarPropertyValue getLastInjectedVehicleProperty(int propertyId) {
466         throw new UnsupportedOperationException("Not in simulated mode");
467     }
468 }
469