1 /*
2  * Copyright (C) 2016 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 android.car.hardware.cabin;
18 
19 import android.annotation.IntDef;
20 import android.annotation.SystemApi;
21 import android.car.Car;
22 import android.car.CarManagerBase;
23 import android.car.hardware.CarPropertyConfig;
24 import android.car.hardware.CarPropertyValue;
25 import android.car.hardware.property.CarPropertyManager;
26 import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
27 import android.car.hardware.property.ICarProperty;
28 import android.os.IBinder;
29 import android.util.ArraySet;
30 
31 import com.android.internal.annotations.GuardedBy;
32 
33 import java.lang.annotation.Retention;
34 import java.lang.annotation.RetentionPolicy;
35 import java.lang.ref.WeakReference;
36 import java.util.Arrays;
37 import java.util.Collection;
38 import java.util.List;
39 
40 /**
41  * API for controlling Cabin system in cars.
42  * Most Car Cabin properties have both a MOVE and POSITION parameter associated with them.
43  *
44  * The MOVE parameter will start moving the device in the indicated direction.  Magnitude
45  * indicates relative speed.  For instance, setting the WINDOW_MOVE parameter to +1 rolls
46  * the window down.  Setting it to +2 (if available) will roll it down faster.
47  *
48  * POSITION parameter will move the device to the desired position.  For instance, if the
49  * WINDOW_POS has a range of 0-100, setting this parameter to 50 will open the window
50  * halfway.  Depending upon the initial position, the window may move up or down to the
51  * 50% value.
52  *
53  * One or both of the MOVE/POSITION parameters may be implemented depending upon the
54  * capability of the hardware.
55  * @hide
56  * @deprecated Use {@link CarPropertyManager} instead.
57  */
58 @Deprecated
59 @SystemApi
60 public final class CarCabinManager extends CarManagerBase {
61     private final Object mLock = new Object();
62     private final CarPropertyManager mCarPropertyMgr;
63     @GuardedBy("mLock")
64     private final ArraySet<CarCabinEventCallback> mCallbacks = new ArraySet<>();
65     @GuardedBy("mLock")
66     private CarPropertyEventListenerToBase mListenerToBase = null;
67 
68     /** Door properties are zoned by VehicleAreaDoor */
69     /**
70      * door position, int type
71      * Max value indicates fully open, min value (0) indicates fully closed.
72      *
73      * Some vehicles (minivans) can open the door electronically.  Hence, the ability
74      * to write this property.
75      */
76     public static final int ID_DOOR_POS = 0x16400b00;
77     /** door move, int type
78      * Positive values open the door, negative values close it.
79      */
80     public static final int ID_DOOR_MOVE = 0x16400b01;
81     /** door lock, bool type
82      * 'true' indicates door is locked.
83      */
84     public static final int ID_DOOR_LOCK = 0x16200b02;
85 
86     /** Mirror properties are zoned by VehicleAreaMirror */
87     /**
88      * mirror z position, int type
89      * Positive value indicates tilt upwards, negative value tilt downwards.
90      */
91     public static final int ID_MIRROR_Z_POS = 0x14400b40;
92     /** mirror z move, int type
93      * Positive value tilts the mirror upwards, negative value tilts downwards.
94      */
95     public static final int ID_MIRROR_Z_MOVE = 0x14400b41;
96     /**
97      * mirror y position, int type
98      * Positive value indicates tilt right, negative value tilt left
99      */
100     public static final int ID_MIRROR_Y_POS = 0x14400b42;
101     /** mirror y move, int type
102      * Positive value tilts the mirror right, negative value tilts left.
103      */
104     public static final int ID_MIRROR_Y_MOVE = 0x14400b43;
105     /**
106      * mirror lock, bool type
107      * True indicates mirror positions are locked and not changeable.
108      */
109     public static final int ID_MIRROR_LOCK = 0x11200b44;
110     /**
111      * mirror fold, bool type
112      * True indicates mirrors are folded.
113      */
114     public static final int ID_MIRROR_FOLD = 0x11200b45;
115 
116     /** Seat properties are zoned by VehicleAreaSeat */
117     /**
118      * seat memory select, int type
119      * This parameter selects the memory preset to use to select the seat position.
120      * The minValue is always 1, and the maxValue determines the number of seat
121      * positions available.
122      *
123      * For instance, if the driver's seat has 3 memory presets, the maxValue will be 3.
124      * When the user wants to select a preset, the desired preset number (1, 2, or 3)
125      * is set.
126      */
127     public static final int ID_SEAT_MEMORY_SELECT = 0x15400b80;
128     /**
129      * seat memory set, int type
130      * This setting allows the user to save the current seat position settings into
131      * the selected preset slot.  The maxValue for each seat position shall match
132      * the maxValue for VEHICLE_PROPERTY_SEAT_MEMORY_SELECT.
133      */
134     public static final int ID_SEAT_MEMORY_SET = 0x15400b81;
135     /**
136      * seat belt buckled, bool type
137      * True indicates belt is buckled.
138      */
139     public static final int ID_SEAT_BELT_BUCKLED = 0x15200b82;
140     /**
141      * seat belt height position, int type
142      * Adjusts the shoulder belt anchor point.
143      * Max value indicates highest position.
144      * Min value indicates lowest position.
145      */
146     public static final int ID_SEAT_BELT_HEIGHT_POS = 0x15400b83;
147     /** seat belt height move, int type
148      * Adjusts the shoulder belt anchor point.
149      * Positive value moves towards highest point.
150      * Negative value moves towards lowest point.
151      */
152     public static final int ID_SEAT_BELT_HEIGHT_MOVE = 0x15400b84;
153     /**
154      * seat fore/aft position, int type
155      * Sets the seat position forward (closer to steering wheel) and backwards.
156      * Max value indicates closest to wheel, min value indicates most rearward position.
157      */
158     public static final int ID_SEAT_FORE_AFT_POS = 0x15400b85;
159     /**
160      * seat fore/aft move, int type
161      * Positive value moves seat forward (closer to steering wheel).
162      * Negative value moves seat rearward.
163      */
164     public static final int ID_SEAT_FORE_AFT_MOVE = 0x15400b86;
165     /**
166      * seat backrest angle #1 position, int type
167      * Backrest angle 1 is the actuator closest to the bottom of the seat.
168      * Max value indicates angling forward towards the steering wheel.
169      * Min value indicates full recline.
170      */
171     public static final int ID_SEAT_BACKREST_ANGLE_1_POS = 0x15400b87;
172     /** seat backrest angle #1 move, int type
173      * Backrest angle 1 is the actuator closest to the bottom of the seat.
174      * Positive value angles seat towards the steering wheel.
175      * Negatie value angles away from steering wheel.
176      */
177     public static final int ID_SEAT_BACKREST_ANGLE_1_MOVE = 0x15400b88;
178     /**
179      * seat backrest angle #2 position, int type
180      * Backrest angle 2 is the next actuator up from the bottom of the seat.
181      * Max value indicates angling forward towards the steering wheel.
182      * Min value indicates full recline.
183      */
184     public static final int ID_SEAT_BACKREST_ANGLE_2_POS = 0x15400b89;
185     /** seat backrest angle #2 move, int type
186      * Backrest angle 2 is the next actuator up from the bottom of the seat.
187      * Positive value tilts forward towards the steering wheel.
188      * Negative value tilts backwards.
189      */
190     public static final int ID_SEAT_BACKREST_ANGLE_2_MOVE = 0x15400b8a;
191     /**
192      * seat height position, int type
193      * Sets the seat height.
194      * Max value indicates highest position.
195      * Min value indicates lowest position.
196      */
197     public static final int ID_SEAT_HEIGHT_POS = 0x15400b8b;
198     /** seat height move, int type
199      * Sets the seat height.
200      * Positive value raises the seat.
201      * Negative value lowers the seat.
202      * */
203     public static final int ID_SEAT_HEIGHT_MOVE = 0x15400b8c;
204     /**
205      * seat depth position, int type
206      * Sets the seat depth, distance from back rest to front edge of seat.
207      * Max value indicates longest depth position.
208      * Min value indicates shortest position.
209      */
210     public static final int ID_SEAT_DEPTH_POS = 0x15400b8d;
211     /** seat depth move, int type
212      * Adjusts the seat depth, distance from back rest to front edge of seat.
213      * Positive value increases the distance from back rest to front edge of seat.
214      * Negative value decreases this distance.
215      */
216     public static final int ID_SEAT_DEPTH_MOVE = 0x15400b8e;
217     /**
218      * seat tilt position, int type
219      * Sets the seat tilt.
220      * Max value indicates front edge of seat higher than back edge.
221      * Min value indicates front edge of seat lower than back edge.
222      */
223     public static final int ID_SEAT_TILT_POS = 0x15400b8f;
224     /** seat tilt move, int type
225      * Adjusts the seat tilt.
226      * Positive value lifts front edge of seat higher than back edge.
227      * Negative value lowers front edge of seat in relation to back edge.
228      */
229     public static final int ID_SEAT_TILT_MOVE = 0x15400b90;
230     /**
231      * seat lumbar fore/aft position, int type
232      * Pushes the lumbar support forward and backwards.
233      * Max value indicates most forward position.
234      * Min value indicates most rearward position.
235      */
236     public static final int ID_SEAT_LUMBAR_FORE_AFT_POS = 0x15400b91;
237     /** seat lumbar fore/aft move, int type
238      * Adjusts the lumbar support forwards and backwards.
239      * Positive value moves lumbar support forward.
240      * Negative value moves lumbar support rearward.
241      */
242     public static final int ID_SEAT_LUMBAR_FORE_AFT_MOVE = 0x15400b92;
243     /**
244      * seat lumbar side support position, int type
245      * Sets the amount of lateral lumbar support.
246      * Max value indicates widest lumbar setting (i.e. least support)
247      * Min value indicates thinnest lumbar setting.
248      */
249     public static final int ID_SEAT_LUMBAR_SIDE_SUPPORT_POS = 0x15400b93;
250     /** seat lumbar side support move, int type
251      * Adjusts the amount of lateral lumbar support.
252      * Positive value widens the lumbar area.
253      * Negative value makes the lumbar area thinner.
254      */
255     public static final int ID_SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 0x15400b94;
256     /**
257      * seat headrest height position, int type
258      * Sets the headrest height.
259      * Max value indicates tallest setting.
260      * Min value indicates shortest setting.
261      */
262     public static final int ID_SEAT_HEADREST_HEIGHT_POS = 0x15400b95;
263     /** seat headrest height move, int type
264      * Postive value moves the headrest higher.
265      * Negative value moves the headrest lower.
266      */
267     public static final int ID_SEAT_HEADREST_HEIGHT_MOVE = 0x15400b96;
268     /**
269      * seat headrest angle position, int type
270      * Sets the angle of the headrest.
271      * Max value indicates most upright angle.
272      * Min value indicates shallowest headrest angle.
273      */
274     public static final int ID_SEAT_HEADREST_ANGLE_POS = 0x15400b97;
275     /** seat headrest angle move, int type
276      * Adjusts the angle of the headrest.
277      * Positive value angles headrest towards most upright angle.
278      * Negative value angles headrest towards shallowest headrest angle.
279      */
280     public static final int ID_SEAT_HEADREST_ANGLE_MOVE = 0x15400b98;
281     /**
282      * seat headrest fore/aft position, int type
283      * Sets the headrest forwards and backwards.
284      * Max value indicates position closest to front of car.
285      * Min value indicates position closest to rear of car.
286      */
287     public static final int ID_SEAT_HEADREST_FORE_AFT_POS = 0x15400b99;
288     /** seat headrest fore/aft move, int type
289      * Adjsuts the headrest forwards and backwards.
290      * Positive value moves the headrest closer to front of car.
291      * Negative value moves the headrest closer to rear of car.
292      */
293     public static final int ID_SEAT_HEADREST_FORE_AFT_MOVE = 0x15400b9a;
294 
295     /** Window properties are zoned by VehicleAreaWindow */
296     /**
297      * window position, int type
298      * Max = window down / open.
299      * Min = window up / closed.
300      */
301     public static final int ID_WINDOW_POS = 0x13400bc0;
302     /** window move, int type
303      * Positive value moves window down / opens window.
304      * Negative value moves window up / closes window.
305      */
306     public static final int ID_WINDOW_MOVE = 0x13400bc1;
307     /**
308      * window lock, bool type
309      * True indicates windows are locked and can't be moved.
310      */
311     public static final int ID_WINDOW_LOCK = 0x13400bc4;
312 
313     /** @hide */
314     @IntDef({
315             ID_DOOR_POS,
316             ID_DOOR_MOVE,
317             ID_DOOR_LOCK,
318             ID_MIRROR_Z_POS,
319             ID_MIRROR_Z_MOVE,
320             ID_MIRROR_Y_POS,
321             ID_MIRROR_Y_MOVE,
322             ID_MIRROR_LOCK,
323             ID_MIRROR_FOLD,
324             ID_SEAT_MEMORY_SELECT,
325             ID_SEAT_MEMORY_SET,
326             ID_SEAT_BELT_BUCKLED,
327             ID_SEAT_BELT_HEIGHT_POS,
328             ID_SEAT_BELT_HEIGHT_MOVE,
329             ID_SEAT_FORE_AFT_POS,
330             ID_SEAT_FORE_AFT_MOVE,
331             ID_SEAT_BACKREST_ANGLE_1_POS,
332             ID_SEAT_BACKREST_ANGLE_1_MOVE,
333             ID_SEAT_BACKREST_ANGLE_2_POS,
334             ID_SEAT_BACKREST_ANGLE_2_MOVE,
335             ID_SEAT_HEIGHT_POS,
336             ID_SEAT_HEIGHT_MOVE,
337             ID_SEAT_DEPTH_POS,
338             ID_SEAT_DEPTH_MOVE,
339             ID_SEAT_TILT_POS,
340             ID_SEAT_TILT_MOVE,
341             ID_SEAT_LUMBAR_FORE_AFT_POS,
342             ID_SEAT_LUMBAR_FORE_AFT_MOVE,
343             ID_SEAT_LUMBAR_SIDE_SUPPORT_POS,
344             ID_SEAT_LUMBAR_SIDE_SUPPORT_MOVE,
345             ID_SEAT_HEADREST_HEIGHT_POS,
346             ID_SEAT_HEADREST_HEIGHT_MOVE,
347             ID_SEAT_HEADREST_ANGLE_POS,
348             ID_SEAT_HEADREST_ANGLE_MOVE,
349             ID_SEAT_HEADREST_FORE_AFT_POS,
350             ID_SEAT_HEADREST_FORE_AFT_MOVE,
351             ID_WINDOW_POS,
352             ID_WINDOW_MOVE,
353             ID_WINDOW_LOCK
354     })
355     @Retention(RetentionPolicy.SOURCE)
356     public @interface PropertyId {}
357     private final ArraySet<Integer> mCabinPropertyIds = new ArraySet<>(Arrays.asList(new Integer[]{
358             ID_DOOR_POS,
359             ID_DOOR_MOVE,
360             ID_DOOR_LOCK,
361             ID_MIRROR_Z_POS,
362             ID_MIRROR_Z_MOVE,
363             ID_MIRROR_Y_POS,
364             ID_MIRROR_Y_MOVE,
365             ID_MIRROR_LOCK,
366             ID_MIRROR_FOLD,
367             ID_SEAT_MEMORY_SELECT,
368             ID_SEAT_MEMORY_SET,
369             ID_SEAT_BELT_BUCKLED,
370             ID_SEAT_BELT_HEIGHT_POS,
371             ID_SEAT_BELT_HEIGHT_MOVE,
372             ID_SEAT_FORE_AFT_POS,
373             ID_SEAT_FORE_AFT_MOVE,
374             ID_SEAT_BACKREST_ANGLE_1_POS,
375             ID_SEAT_BACKREST_ANGLE_1_MOVE,
376             ID_SEAT_BACKREST_ANGLE_2_POS,
377             ID_SEAT_BACKREST_ANGLE_2_MOVE,
378             ID_SEAT_HEIGHT_POS,
379             ID_SEAT_HEIGHT_MOVE,
380             ID_SEAT_DEPTH_POS,
381             ID_SEAT_DEPTH_MOVE,
382             ID_SEAT_TILT_POS,
383             ID_SEAT_TILT_MOVE,
384             ID_SEAT_LUMBAR_FORE_AFT_POS,
385             ID_SEAT_LUMBAR_FORE_AFT_MOVE,
386             ID_SEAT_LUMBAR_SIDE_SUPPORT_POS,
387             ID_SEAT_LUMBAR_SIDE_SUPPORT_MOVE,
388             ID_SEAT_HEADREST_HEIGHT_POS,
389             ID_SEAT_HEADREST_HEIGHT_MOVE,
390             ID_SEAT_HEADREST_ANGLE_POS,
391             ID_SEAT_HEADREST_ANGLE_MOVE,
392             ID_SEAT_HEADREST_FORE_AFT_POS,
393             ID_SEAT_HEADREST_FORE_AFT_MOVE,
394             ID_WINDOW_POS,
395             ID_WINDOW_MOVE,
396             ID_WINDOW_LOCK
397     }));
398 
399     /**
400      * Application registers CarCabinEventCallback object to receive updates and changes to
401      * subscribed Car Cabin properties.
402      */
403     public interface CarCabinEventCallback {
404         /**
405          * Called when a property is updated
406          * @param value Property that has been updated.
407          */
onChangeEvent(CarPropertyValue value)408         void onChangeEvent(CarPropertyValue value);
409 
410         /**
411          * Called when an error is detected with a property
412          * @param propertyId
413          * @param zone
414          */
onErrorEvent(@ropertyId int propertyId, int zone)415         void onErrorEvent(@PropertyId int propertyId, int zone);
416     }
417 
418     private static class CarPropertyEventListenerToBase implements CarPropertyEventCallback {
419         private final WeakReference<CarCabinManager> mManager;
420 
CarPropertyEventListenerToBase(CarCabinManager manager)421         CarPropertyEventListenerToBase(CarCabinManager manager) {
422             mManager = new WeakReference<>(manager);
423         }
424 
425         @Override
onChangeEvent(CarPropertyValue value)426         public void onChangeEvent(CarPropertyValue value) {
427             CarCabinManager manager = mManager.get();
428             if (manager != null) {
429                 manager.handleOnChangeEvent(value);
430             }
431         }
432 
433         @Override
onErrorEvent(int propertyId, int zone)434         public void onErrorEvent(int propertyId, int zone) {
435             CarCabinManager manager = mManager.get();
436             if (manager != null) {
437                 manager.handleOnErrorEvent(propertyId, zone);
438             }
439         }
440     }
441 
handleOnChangeEvent(CarPropertyValue value)442     private void handleOnChangeEvent(CarPropertyValue value) {
443         Collection<CarCabinEventCallback> callbacks;
444         synchronized (mLock) {
445             callbacks = new ArraySet<>(mCallbacks);
446         }
447         for (CarCabinEventCallback l: callbacks) {
448             l.onChangeEvent(value);
449         }
450     }
451 
handleOnErrorEvent(int propertyId, int zone)452     private void handleOnErrorEvent(int propertyId, int zone) {
453         Collection<CarCabinEventCallback> listeners;
454         synchronized (mLock) {
455             listeners = new ArraySet<>(mCallbacks);
456         }
457         if (!listeners.isEmpty()) {
458             for (CarCabinEventCallback l: listeners) {
459                 l.onErrorEvent(propertyId, zone);
460             }
461         }
462     }
463 
464     /**
465      * Get an instance of CarCabinManager
466      *
467      * Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead.
468      * @param service
469      * @param context
470      * @param handler
471      * @hide
472      */
CarCabinManager(Car car, IBinder service)473     public CarCabinManager(Car car, IBinder service) {
474         super(car);
475         ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service);
476         mCarPropertyMgr = new CarPropertyManager(car, mCarPropertyService);
477     }
478 
479     /**
480      * All properties in CarCabinManager are zoned.
481      * @param propertyId
482      * @return true if property is a zoned type
483      */
isZonedProperty(@ropertyId int propertyId)484     public static boolean isZonedProperty(@PropertyId int propertyId) {
485         return true;
486     }
487 
488     /**
489      * Implement wrappers for contained CarPropertyManagerBase object
490      * @param callback
491      */
registerCallback(CarCabinEventCallback callback)492     public void registerCallback(CarCabinEventCallback callback) {
493         List<CarPropertyConfig> configs = getPropertyList();
494         synchronized (mLock) {
495             if (mListenerToBase == null) {
496                 mListenerToBase = new CarPropertyEventListenerToBase(this);
497             }
498             for (CarPropertyConfig c : configs) {
499                 // Register each individual propertyId
500                 mCarPropertyMgr.registerCallback(mListenerToBase, c.getPropertyId(), 0);
501             }
502             mCallbacks.add(callback);
503         }
504     }
505 
506     /**
507      * Stop getting property updates for the given callback. If there are multiple registrations for
508      * this listener, all listening will be stopped.
509      * @param callback
510      */
unregisterCallback(CarCabinEventCallback callback)511     public void unregisterCallback(CarCabinEventCallback callback) {
512         synchronized (mLock) {
513             mCallbacks.remove(callback);
514             List<CarPropertyConfig> configs = getPropertyList();
515             for (CarPropertyConfig c : configs) {
516                     // Register each individual propertyId
517                 mCarPropertyMgr.unregisterCallback(mListenerToBase, c.getPropertyId());
518             }
519             if (mCallbacks.isEmpty()) {
520                 mListenerToBase = null;
521             }
522         }
523     }
524 
525     /**
526      * Get list of properties represented by CarCabinManager for this car.
527      * @return List of CarPropertyConfig objects available via Car Cabin Manager.
528      */
getPropertyList()529     public List<CarPropertyConfig> getPropertyList() {
530         return mCarPropertyMgr.getPropertyList(mCabinPropertyIds);
531     }
532 
533     /**
534      * Get value of boolean property
535      * @param propertyId
536      * @param area
537      * @return value of requested boolean property
538      */
getBooleanProperty(@ropertyId int propertyId, int area)539     public boolean getBooleanProperty(@PropertyId int propertyId, int area) {
540         return mCarPropertyMgr.getBooleanProperty(propertyId, area);
541     }
542 
543     /**
544      * Get value of float property
545      * @param propertyId
546      * @param area
547      * @return value of requested float property
548      */
getFloatProperty(@ropertyId int propertyId, int area)549     public float getFloatProperty(@PropertyId int propertyId, int area) {
550         return mCarPropertyMgr.getFloatProperty(propertyId, area);
551     }
552 
553     /**
554      * Get value of integer property
555      * @param propertyId
556      * @param area
557      * @return value of requested integer property
558      */
getIntProperty(@ropertyId int propertyId, int area)559     public int getIntProperty(@PropertyId int propertyId, int area) {
560         return mCarPropertyMgr.getIntProperty(propertyId, area);
561     }
562 
563     /**
564      * Set the value of a boolean property
565      * @param propertyId
566      * @param area
567      * @param val
568      */
setBooleanProperty(@ropertyId int propertyId, int area, boolean val)569     public void setBooleanProperty(@PropertyId int propertyId, int area, boolean val) {
570         if (mCabinPropertyIds.contains(propertyId)) {
571             mCarPropertyMgr.setBooleanProperty(propertyId, area, val);
572         }
573     }
574 
575     /**
576      * Set the value of a float property
577      * @param propertyId
578      * @param area
579      * @param val
580      */
setFloatProperty(@ropertyId int propertyId, int area, float val)581     public void setFloatProperty(@PropertyId int propertyId, int area, float val) {
582         if (mCabinPropertyIds.contains(propertyId)) {
583             mCarPropertyMgr.setFloatProperty(propertyId, area, val);
584         }
585     }
586 
587     /**
588      * Set the value of an integer property
589      * @param propertyId
590      * @param area
591      * @param val
592      */
setIntProperty(@ropertyId int propertyId, int area, int val)593     public void setIntProperty(@PropertyId int propertyId, int area, int val) {
594         if (mCabinPropertyIds.contains(propertyId)) {
595             mCarPropertyMgr.setIntProperty(propertyId, area, val);
596         }
597     }
598 
599     /** @hide */
600     @Override
onCarDisconnected()601     public void onCarDisconnected() {
602         synchronized (mLock) {
603             mCallbacks.clear();
604         }
605         mCarPropertyMgr.onCarDisconnected();
606     }
607 }
608