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