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 
17 package android.car;
18 
19 import static android.car.CarLibLog.TAG_CAR;
20 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.RequiresPermission;
25 import android.annotation.SdkConstant;
26 import android.annotation.SdkConstant.SdkConstantType;
27 import android.annotation.SuppressLint;
28 import android.annotation.SystemApi;
29 import android.annotation.TestApi;
30 import android.app.Activity;
31 import android.app.Service;
32 import android.car.admin.CarDevicePolicyManager;
33 import android.car.annotation.MandatoryFeature;
34 import android.car.annotation.OptionalFeature;
35 import android.car.app.CarActivityManager;
36 import android.car.cluster.CarInstrumentClusterManager;
37 import android.car.cluster.ClusterActivityState;
38 import android.car.cluster.ClusterHomeManager;
39 import android.car.content.pm.CarPackageManager;
40 import android.car.diagnostic.CarDiagnosticManager;
41 import android.car.drivingstate.CarDrivingStateManager;
42 import android.car.drivingstate.CarUxRestrictionsManager;
43 import android.car.evs.CarEvsManager;
44 import android.car.hardware.CarSensorManager;
45 import android.car.hardware.CarVendorExtensionManager;
46 import android.car.hardware.cabin.CarCabinManager;
47 import android.car.hardware.hvac.CarHvacManager;
48 import android.car.hardware.power.CarPowerManager;
49 import android.car.hardware.property.CarPropertyManager;
50 import android.car.hardware.property.ICarProperty;
51 import android.car.input.CarInputManager;
52 import android.car.media.CarAudioManager;
53 import android.car.media.CarMediaIntents;
54 import android.car.media.CarMediaManager;
55 import android.car.navigation.CarNavigationStatusManager;
56 import android.car.occupantawareness.OccupantAwarenessManager;
57 import android.car.storagemonitoring.CarStorageMonitoringManager;
58 import android.car.telemetry.CarTelemetryManager;
59 import android.car.test.CarTestManagerBinderWrapper;
60 import android.car.user.CarUserManager;
61 import android.car.vms.VmsClientManager;
62 import android.car.vms.VmsSubscriberManager;
63 import android.car.watchdog.CarWatchdogManager;
64 import android.content.ComponentName;
65 import android.content.Context;
66 import android.content.ContextWrapper;
67 import android.content.Intent;
68 import android.content.ServiceConnection;
69 import android.content.pm.PackageManager;
70 import android.os.Handler;
71 import android.os.IBinder;
72 import android.os.Looper;
73 import android.os.Process;
74 import android.os.RemoteException;
75 import android.os.ServiceManager;
76 import android.os.TransactionTooLargeException;
77 import android.os.UserHandle;
78 import android.util.Log;
79 
80 import com.android.car.internal.common.CommonConstants;
81 import com.android.internal.annotations.GuardedBy;
82 import com.android.internal.annotations.VisibleForTesting;
83 
84 import java.lang.annotation.ElementType;
85 import java.lang.annotation.Retention;
86 import java.lang.annotation.RetentionPolicy;
87 import java.lang.annotation.Target;
88 import java.lang.reflect.Constructor;
89 import java.lang.reflect.InvocationTargetException;
90 import java.util.Collections;
91 import java.util.HashMap;
92 import java.util.List;
93 import java.util.Objects;
94 
95 /**
96  *   Top level car API for embedded Android Auto deployments.
97  *   This API works only for devices with {@link PackageManager#FEATURE_AUTOMOTIVE}
98  *   Calling this API on a device with no such feature will lead to an exception.
99  */
100 public final class Car {
101 
102     /**
103      * Binder service name of car service registered to service manager.
104      *
105      * @hide
106      */
107     public static final String CAR_SERVICE_BINDER_SERVICE_NAME = "car_service";
108 
109     /**
110      * This represents AndroidManifest meta-data to tell that {@code Activity} is optimized for
111      * driving distraction.
112      *
113      * <p>Activities without this meta-data can be blocked while car is in moving / driving state.
114      *
115      * <p>Note that having this flag does not guarantee that the {@code Activity} will be always
116      * allowed for all driving states.
117      *
118      * <p>For this meta-data, android:value can be {@code true} (=optimized) or {@code false}.
119      *
120      * <p>Example usage:
121      * <xml><meta-data android:name="distractionOptimized" android:value="true"/></xml>
122      */
123     @SuppressLint("IntentName")
124     public static final String META_DATA_DISTRACTION_OPTIMIZED = "distractionOptimized";
125 
126     /**
127      * This represents AndroidManifest meta-data to tell that {@code Application} requires specific
128      * car features to work.
129      *
130      * <p>Apps like launcher or installer app can use this information to filter out apps
131      * not usable in a specific car. This meta-data is not necessary for mandatory features.
132      *
133      * <p>For this meta-data, android:value should contain the feature name string defined by
134      * (@link android.car.annotation.OptionalFeature} or
135      * {@link android.car.annotation.ExperimentalFeature} annotations.
136      *
137      * <p>Example usage:
138      * <xml><meta-data android:name="requires-car-feature" android:value="diagnostic"/></xml>
139      */
140     @SuppressLint("IntentName")
141     public static final String META_DATA_REQUIRES_CAR_FEATURE = "requires-car-feature";
142 
143     /**
144      * Service name for {@link CarSensorManager}, to be used in {@link #getCarManager(String)}.
145      *
146      * @deprecated  {@link CarSensorManager} is deprecated. Use {@link CarPropertyManager} instead.
147      */
148     @MandatoryFeature
149     @Deprecated
150     public static final String SENSOR_SERVICE = "sensor";
151 
152     /** Service name for {@link CarInfoManager}, to be used in {@link #getCarManager(String)}. */
153     @MandatoryFeature
154     public static final String INFO_SERVICE = "info";
155 
156     /** Service name for {@link CarAppFocusManager}. */
157     @MandatoryFeature
158     public static final String APP_FOCUS_SERVICE = "app_focus";
159 
160     /** Service name for {@link CarPackageManager} */
161     @MandatoryFeature
162     public static final String PACKAGE_SERVICE = "package";
163 
164     /** Service name for {@link CarAudioManager} */
165     @MandatoryFeature
166     public static final String AUDIO_SERVICE = "audio";
167 
168     /** Service name for {@link CarNavigationStatusManager} */
169     @OptionalFeature
170     public static final String CAR_NAVIGATION_SERVICE = "car_navigation_service";
171 
172     /** Service name for {@link CarOccupantZoneManager} */
173     @MandatoryFeature
174     public static final String CAR_OCCUPANT_ZONE_SERVICE = "car_occupant_zone_service";
175 
176     /**
177      * Service name for {@link CarUserManager}
178      *
179      * @hide
180      */
181     @MandatoryFeature
182     @SystemApi
183     @TestApi
184     public static final String CAR_USER_SERVICE = "car_user_service";
185 
186     /**
187      * Service name for {@link CarDevicePolicyManager}
188      *
189      * @hide
190      */
191     @MandatoryFeature
192     @SystemApi
193     @TestApi
194     public static final String CAR_DEVICE_POLICY_SERVICE = "car_device_policy_service";
195 
196     /**
197      * Service name for {@link CarInstrumentClusterManager}
198      *
199      * @deprecated CarInstrumentClusterManager is being deprecated
200      * @hide
201      */
202     @OptionalFeature
203     @Deprecated
204     public static final String CAR_INSTRUMENT_CLUSTER_SERVICE = "cluster_service";
205 
206     /**
207      * Service name for {@link CarCabinManager}.
208      *
209      * @deprecated {@link CarCabinManager} is deprecated. Use {@link CarPropertyManager} instead.
210      * @hide
211      */
212     @MandatoryFeature
213     @Deprecated
214     @SystemApi
215     public static final String CABIN_SERVICE = "cabin";
216 
217     /**
218      * @hide
219      */
220     @OptionalFeature
221     @SystemApi
222     public static final String DIAGNOSTIC_SERVICE = "diagnostic";
223 
224     /**
225      * Service name for {@link CarHvacManager}
226      * @deprecated {@link CarHvacManager} is deprecated. Use {@link CarPropertyManager} instead.
227      * @hide
228      */
229     @MandatoryFeature
230     @Deprecated
231     @SystemApi
232     public static final String HVAC_SERVICE = "hvac";
233 
234     /**
235      * Service name for {@link CarPowerManager}
236      */
237     @MandatoryFeature
238     public static final String POWER_SERVICE = "power";
239 
240     /**
241      * @hide
242      */
243     @MandatoryFeature
244     @SystemApi
245     public static final String PROJECTION_SERVICE = "projection";
246 
247     /**
248      * Service name for {@link CarPropertyManager}
249      */
250     @MandatoryFeature
251     public static final String PROPERTY_SERVICE = "property";
252 
253     /**
254      * Service name for {@link CarVendorExtensionManager}
255      *
256      * @deprecated {@link CarVendorExtensionManager} is deprecated.
257      * Use {@link CarPropertyManager} instead.
258      * @hide
259      */
260     @MandatoryFeature
261     @Deprecated
262     @SystemApi
263     public static final String VENDOR_EXTENSION_SERVICE = "vendor_extension";
264 
265     /**
266      * @hide
267      */
268     @MandatoryFeature
269     public static final String BLUETOOTH_SERVICE = "car_bluetooth";
270 
271     /**
272      * Service name for {@link VmsClientManager}
273      *
274      * @hide
275      */
276     @OptionalFeature
277     @SystemApi
278     public static final String VEHICLE_MAP_SERVICE = "vehicle_map_service";
279 
280     /**
281      * Service name for {@link VmsSubscriberManager}
282      *
283      * @deprecated {@link VmsSubscriberManager} is deprecated. Use {@link VmsClientManager} instead.
284      * @hide
285      */
286     @OptionalFeature
287     @Deprecated
288     @SystemApi
289     public static final String VMS_SUBSCRIBER_SERVICE = "vehicle_map_subscriber_service";
290 
291     /**
292      * Service name for {@link CarDrivingStateManager}
293      * @hide
294      */
295     @MandatoryFeature
296     @SystemApi
297     public static final String CAR_DRIVING_STATE_SERVICE = "drivingstate";
298 
299     /**
300      * Service name for {@link CarUxRestrictionsManager}
301      */
302     public static final String CAR_UX_RESTRICTION_SERVICE = "uxrestriction";
303 
304     /** @hide */
305     @OptionalFeature
306     @SystemApi
307     public static final String OCCUPANT_AWARENESS_SERVICE = "occupant_awareness";
308 
309     /**
310      * Service name for {@link android.car.media.CarMediaManager}
311      * @hide
312      */
313     @MandatoryFeature
314     @SystemApi
315     public static final String CAR_MEDIA_SERVICE = "car_media";
316 
317     /**
318      *
319      * Service name for {@link android.car.CarBugreportManager}
320      * @hide
321      */
322     @MandatoryFeature
323     public static final String CAR_BUGREPORT_SERVICE = "car_bugreport";
324 
325     /**
326      * @hide
327      */
328     @OptionalFeature
329     @SystemApi
330     public static final String STORAGE_MONITORING_SERVICE = "storage_monitoring";
331 
332     /**
333      * Service name for {@link android.car.watchdog.CarWatchdogManager}
334      */
335     @MandatoryFeature
336     public static final String CAR_WATCHDOG_SERVICE = "car_watchdog";
337 
338     /**
339      * @hide
340      */
341     @MandatoryFeature
342     @SystemApi
343     public static final String CAR_INPUT_SERVICE = "android.car.input";
344 
345     /**
346      * @hide
347      */
348     @OptionalFeature
349     public static final String CLUSTER_HOME_SERVICE = "cluster_home_service";
350 
351     /**
352      * Service for testing. This is system app only feature.
353      * Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}.
354      * @hide
355      */
356     @MandatoryFeature
357     @SystemApi
358     public static final String TEST_SERVICE = "car-service-test";
359 
360     /**
361      * Service name for {@link android.car.evs.CarEvsManager}
362      *
363      * @hide
364      */
365     @OptionalFeature
366     @SystemApi
367     public static final String CAR_EVS_SERVICE = "car_evs_service";
368 
369     /**
370      * Service name for {@link android.car.telemetry.CarTelemetryManager}
371      *
372      * @hide
373      */
374     @OptionalFeature
375     public static final String CAR_TELEMETRY_SERVICE = "car_telemetry_service";
376 
377     /**
378      * Service name for {@link android.car.app.CarActivityManager}
379      *
380      * @hide
381      */
382     @MandatoryFeature
383     public static final String CAR_ACTIVITY_SERVICE = "car_activity_service";
384 
385     /** Permission necessary to access car's mileage information.
386      *  @hide
387      */
388     @SystemApi
389     public static final String PERMISSION_MILEAGE = "android.car.permission.CAR_MILEAGE";
390 
391     /** Permission necessary to access car's energy information. */
392     public static final String PERMISSION_ENERGY = "android.car.permission.CAR_ENERGY";
393 
394     /**
395      * Permission necessary to change value of car's range remaining.
396      * @hide
397      */
398     @SystemApi
399     public static final String PERMISSION_ADJUST_RANGE_REMAINING =
400             "android.car.permission.ADJUST_RANGE_REMAINING";
401 
402     /** Permission necessary to access car's VIN information */
403     public static final String PERMISSION_IDENTIFICATION =
404             "android.car.permission.CAR_IDENTIFICATION";
405 
406     /** Permission necessary to access car's speed. */
407     public static final String PERMISSION_SPEED = "android.car.permission.CAR_SPEED";
408 
409     /** Permission necessary to access car's dynamics state.
410      *  @hide
411      */
412     @SystemApi
413     public static final String PERMISSION_CAR_DYNAMICS_STATE =
414             "android.car.permission.CAR_DYNAMICS_STATE";
415 
416     /** Permission necessary to access car's fuel door and ev charge port. */
417     public static final String PERMISSION_ENERGY_PORTS = "android.car.permission.CAR_ENERGY_PORTS";
418 
419     /**
420      * Permission necessary to control car's fuel door and ev charge port.
421      * @hide
422      */
423     @SystemApi
424     public static final String PERMISSION_CONTROL_ENERGY_PORTS =
425             "android.car.permission.CONTROL_CAR_ENERGY_PORTS";
426 
427     /**
428      * Permission necessary to read car's exterior lights information.
429      *  @hide
430      */
431     @SystemApi
432     public static final String PERMISSION_EXTERIOR_LIGHTS =
433             "android.car.permission.CAR_EXTERIOR_LIGHTS";
434 
435     /**
436      * Permission necessary to read car's interior lights information.
437      */
438     public static final String PERMISSION_READ_INTERIOR_LIGHTS =
439             "android.car.permission.READ_CAR_INTERIOR_LIGHTS";
440 
441     /** Permission necessary to control car's exterior lights.
442      *  @hide
443      */
444     @SystemApi
445     public static final String PERMISSION_CONTROL_EXTERIOR_LIGHTS =
446             "android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS";
447 
448     /**
449      * Permission necessary to control car's interior lights.
450      */
451     public static final String PERMISSION_CONTROL_INTERIOR_LIGHTS =
452             "android.car.permission.CONTROL_CAR_INTERIOR_LIGHTS";
453 
454     /** Permission necessary to access car's powertrain information.*/
455     public static final String PERMISSION_POWERTRAIN = "android.car.permission.CAR_POWERTRAIN";
456 
457     /**
458      * Permission necessary to change car audio volume through {@link CarAudioManager}.
459      */
460     public static final String PERMISSION_CAR_CONTROL_AUDIO_VOLUME =
461             "android.car.permission.CAR_CONTROL_AUDIO_VOLUME";
462 
463     /**
464      * Permission necessary to change car audio settings through {@link CarAudioManager}.
465      */
466     public static final String PERMISSION_CAR_CONTROL_AUDIO_SETTINGS =
467             "android.car.permission.CAR_CONTROL_AUDIO_SETTINGS";
468 
469     /**
470      * Permission necessary to receive full audio ducking events from car audio focus handler.
471      *
472      * @hide
473      */
474     @SystemApi
475     public static final String PERMISSION_RECEIVE_CAR_AUDIO_DUCKING_EVENTS =
476             "android.car.permission.RECEIVE_CAR_AUDIO_DUCKING_EVENTS";
477 
478     /**
479      * Permission necessary to use {@link CarNavigationStatusManager}.
480      */
481     public static final String PERMISSION_CAR_NAVIGATION_MANAGER =
482             "android.car.permission.CAR_NAVIGATION_MANAGER";
483 
484     /**
485      * Permission necessary to start activities in the instrument cluster through
486      * {@link CarInstrumentClusterManager}
487      *
488      * @hide
489      */
490     @SystemApi
491     public static final String PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL =
492             "android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL";
493 
494     /**
495      * Permission necessary to listen for the instrument cluster's navigation state changes.
496      *
497      * @hide
498      */
499     public static final String PERMISSION_CAR_MONITOR_CLUSTER_NAVIGATION_STATE =
500             "android.car.permission.CAR_MONITOR_CLUSTER_NAVIGATION_STATE";
501 
502 
503     /**
504      * Application must have this permission in order to be launched in the instrument cluster
505      * display.
506      *
507      * @hide
508      */
509     public static final String PERMISSION_CAR_DISPLAY_IN_CLUSTER =
510             "android.car.permission.CAR_DISPLAY_IN_CLUSTER";
511 
512     /** Permission necessary to use {@link CarInfoManager}. */
513     public static final String PERMISSION_CAR_INFO = "android.car.permission.CAR_INFO";
514 
515     /**
516      * Permission necessary to read information of vendor properties' permissions.
517      * @hide
518      */
519     @SystemApi
520     public static final String PERMISSION_READ_CAR_VENDOR_PERMISSION_INFO =
521             "android.car.permission.READ_CAR_VENDOR_PERMISSION_INFO";
522 
523     /** Permission necessary to read temperature of car's exterior environment. */
524     public static final String PERMISSION_EXTERIOR_ENVIRONMENT =
525             "android.car.permission.CAR_EXTERIOR_ENVIRONMENT";
526 
527     /**
528      * Permission necessary to access car specific communication channel.
529      * @hide
530      */
531     @SystemApi
532     public static final String PERMISSION_VENDOR_EXTENSION =
533             "android.car.permission.CAR_VENDOR_EXTENSION";
534 
535     /**
536      * @hide
537      */
538     @SystemApi
539     public static final String PERMISSION_CONTROL_APP_BLOCKING =
540             "android.car.permission.CONTROL_APP_BLOCKING";
541 
542     /**
543      * Permission necessary to access car's engine information.
544      * @hide
545      */
546     @SystemApi
547     public static final String PERMISSION_CAR_ENGINE_DETAILED =
548             "android.car.permission.CAR_ENGINE_DETAILED";
549 
550     /**
551      * Permission necessary to access car's tire pressure information.
552      * @hide
553      */
554     @SystemApi
555     public static final String PERMISSION_TIRES = "android.car.permission.CAR_TIRES";
556 
557     /**
558      * Permission necessary to access car's property {@link VehiclePropertyIds#EPOCH_TIME}.
559      * @hide
560      */
561     @SystemApi
562     public static final String PERMISSION_CAR_EPOCH_TIME = "android.car.permission.CAR_EPOCH_TIME";
563 
564     /**
565      * Permission necessary to access car's property
566      * {@link VehiclePropertyIds#STORAGE_ENCRYPTION_BINDING_SEED}.
567      * @hide
568      */
569     @SystemApi
570     public static final String PERMISSION_STORAGE_ENCRYPTION_BINDING_SEED =
571             "android.car.permission.STORAGE_ENCRYPTION_BINDING_SEED";
572 
573     /**
574      * Permission necessary to access car's steering angle information.
575      */
576     public static final String PERMISSION_READ_STEERING_STATE =
577             "android.car.permission.READ_CAR_STEERING";
578 
579     /**
580      * Permission necessary to read and write display units for distance, fuel volume, tire pressure
581      * and ev battery.
582      */
583     public static final String PERMISSION_READ_DISPLAY_UNITS =
584             "android.car.permission.READ_CAR_DISPLAY_UNITS";
585 
586     /**
587      * Permission necessary to control display units for distance, fuel volume, tire pressure
588      * and ev battery.
589      */
590     public static final String PERMISSION_CONTROL_DISPLAY_UNITS =
591             "android.car.permission.CONTROL_CAR_DISPLAY_UNITS";
592 
593     /**
594      * Permission necessary to control car's door.
595      * @hide
596      */
597     @SystemApi
598     public static final String PERMISSION_CONTROL_CAR_DOORS =
599             "android.car.permission.CONTROL_CAR_DOORS";
600 
601     /**
602      * Permission necessary to control car's windows.
603      * @hide
604      */
605     @SystemApi
606     public static final String PERMISSION_CONTROL_CAR_WINDOWS =
607             "android.car.permission.CONTROL_CAR_WINDOWS";
608 
609     /**
610      * Permission necessary to control car's seats.
611      * @hide
612      */
613     @SystemApi
614     public static final String PERMISSION_CONTROL_CAR_SEATS =
615             "android.car.permission.CONTROL_CAR_SEATS";
616 
617     /**
618      * Permission necessary to control car's mirrors.
619      * @hide
620      */
621     @SystemApi
622     public static final String PERMISSION_CONTROL_CAR_MIRRORS =
623             "android.car.permission.CONTROL_CAR_MIRRORS";
624 
625     /**
626      * Permission necessary to access Car HVAC APIs.
627      * @hide
628      */
629     @SystemApi
630     public static final String PERMISSION_CONTROL_CAR_CLIMATE =
631             "android.car.permission.CONTROL_CAR_CLIMATE";
632 
633     /**
634      * Permission necessary to access restrictive car power management APIs.
635      * @hide
636      */
637     @SystemApi
638     public static final String PERMISSION_CAR_POWER = "android.car.permission.CAR_POWER";
639 
640     /**
641      * Permission necessary to read the current power policy or be notified of power policy change.
642      */
643     public static final String PERMISSION_READ_CAR_POWER_POLICY =
644             "android.car.permission.READ_CAR_POWER_POLICY";
645 
646     /**
647      * Permission necessary to apply a new power policy.
648      * @hide
649      */
650     @SystemApi
651     public static final String PERMISSION_CONTROL_CAR_POWER_POLICY =
652             "android.car.permission.CONTROL_CAR_POWER_POLICY";
653 
654     /**
655      * Permission necessary to access Car PROJECTION system APIs.
656      * @hide
657      */
658     @SystemApi
659     public static final String PERMISSION_CAR_PROJECTION = "android.car.permission.CAR_PROJECTION";
660 
661     /**
662      * Permission necessary to access projection status.
663      * @hide
664      */
665     @SystemApi
666     public static final String PERMISSION_CAR_PROJECTION_STATUS =
667             "android.car.permission.ACCESS_CAR_PROJECTION_STATUS";
668 
669     /**
670      * Permission necessary to mock vehicle hal for testing.
671      * @hide
672      * @deprecated mocking vehicle HAL in car service is no longer supported.
673      */
674     @Deprecated
675     @SystemApi
676     public static final String PERMISSION_MOCK_VEHICLE_HAL =
677             "android.car.permission.CAR_MOCK_VEHICLE_HAL";
678 
679     /**
680      * Permission necessary to access CarTestService.
681      * @hide
682      */
683     @SystemApi
684     public static final String PERMISSION_CAR_TEST_SERVICE =
685             "android.car.permission.CAR_TEST_SERVICE";
686 
687     /**
688      * Permission necessary to access CarDrivingStateService to get a Car's driving state.
689      * @hide
690      */
691     @SystemApi
692     public static final String PERMISSION_CAR_DRIVING_STATE =
693             "android.car.permission.CAR_DRIVING_STATE";
694 
695     /**
696      * Permission necessary to access VMS client service.
697      *
698      * @hide
699      */
700     public static final String PERMISSION_BIND_VMS_CLIENT =
701             "android.car.permission.BIND_VMS_CLIENT";
702 
703     /**
704      * Permissions necessary to access VMS publisher APIs.
705      *
706      * @hide
707      */
708     @SystemApi
709     public static final String PERMISSION_VMS_PUBLISHER = "android.car.permission.VMS_PUBLISHER";
710 
711     /**
712      * Permissions necessary to access VMS subscriber APIs.
713      *
714      * @hide
715      */
716     @SystemApi
717     public static final String PERMISSION_VMS_SUBSCRIBER = "android.car.permission.VMS_SUBSCRIBER";
718 
719     /**
720      * Permissions necessary to read diagnostic information, including vendor-specific bits.
721      *
722      * @hide
723      */
724     @SystemApi
725     public static final String PERMISSION_CAR_DIAGNOSTIC_READ_ALL =
726             "android.car.permission.CAR_DIAGNOSTICS";
727 
728     /**
729      * Permissions necessary to clear diagnostic information.
730      *
731      * @hide
732      */
733     @SystemApi
734     public static final String PERMISSION_CAR_DIAGNOSTIC_CLEAR =
735             "android.car.permission.CLEAR_CAR_DIAGNOSTICS";
736 
737     /**
738      * Permission necessary to configure UX restrictions through {@link CarUxRestrictionsManager}.
739      *
740      * @hide
741      */
742     public static final String PERMISSION_CAR_UX_RESTRICTIONS_CONFIGURATION =
743             "android.car.permission.CAR_UX_RESTRICTIONS_CONFIGURATION";
744 
745     /**
746      * Permission necessary to listen to occupant awareness state {@link OccupantAwarenessManager}.
747      *
748      * @hide
749      */
750     @SystemApi
751     public static final String PERMISSION_READ_CAR_OCCUPANT_AWARENESS_STATE =
752             "android.car.permission.READ_CAR_OCCUPANT_AWARENESS_STATE";
753 
754     /**
755      * Permission necessary to access private display id.
756      *
757      * @hide
758      */
759     @SystemApi
760     public static final String ACCESS_PRIVATE_DISPLAY_ID =
761             "android.car.permission.ACCESS_PRIVATE_DISPLAY_ID";
762 
763     /**
764      * @deprecated This permission is not used by any service.
765      *
766      * @hide
767      */
768     @SystemApi
769     public static final String PERMISSION_CONTROL_CAR_OCCUPANT_AWARENESS_SYSTEM =
770             "android.car.permission.CONTROL_CAR_OCCUPANT_AWARENESS_SYSTEM";
771 
772     /**
773      * Permissions necessary to clear diagnostic information.
774      *
775      * @hide
776      */
777     @SystemApi
778     public static final String PERMISSION_STORAGE_MONITORING =
779             "android.car.permission.STORAGE_MONITORING";
780 
781     /**
782      * Permission necessary to dynamically enable / disable optional car features.
783      *
784      * @hide
785      */
786     @SystemApi
787     public static final String PERMISSION_CONTROL_CAR_FEATURES =
788             "android.car.permission.CONTROL_CAR_FEATURES";
789 
790     /**
791      * Permission necessary to be car watchdog clients.
792      *
793      * @hide
794      */
795     @SystemApi
796     public static final String PERMISSION_USE_CAR_WATCHDOG =
797             "android.car.permission.USE_CAR_WATCHDOG";
798 
799     /**
800      * Permission necessary to monitor Car input events.
801      *
802      * @hide
803      */
804     @SystemApi
805     public static final String PERMISSION_CAR_MONITOR_INPUT =
806             "android.car.permission.CAR_MONITOR_INPUT";
807 
808     /**
809      * Permission necessary to request CarEvsService to launch the special activity to show the
810      * camera preview.
811      *
812      * @hide
813      */
814     @SystemApi
815     public static final String PERMISSION_REQUEST_CAR_EVS_ACTIVITY =
816             "android.car.permission.REQUEST_CAR_EVS_ACTIVITY";
817 
818     /**
819      * Permission necessary to control the special activity to show the camera preview.
820      *
821      * @hide
822      */
823     @SystemApi
824     public static final String PERMISSION_CONTROL_CAR_EVS_ACTIVITY =
825             "android.car.permission.CONTROL_CAR_EVS_ACTIVITY";
826 
827     /**
828      * Permission necessary to use the camera streams via CarEvsService.
829      *
830      * @hide
831      */
832     @SystemApi
833     public static final String PERMISSION_USE_CAR_EVS_CAMERA =
834             "android.car.permission.USE_CAR_EVS_CAMERA";
835 
836     /**
837      * Permission necessary to monitor the status of CarEvsService.
838      *
839      * @hide
840      */
841     @SystemApi
842     public static final String PERMISSION_MONITOR_CAR_EVS_STATUS =
843             "android.car.permission.MONITOR_CAR_EVS_STATUS";
844 
845     /**
846      * Permission necessary to use the CarTelemetryService.
847      *
848      * @hide
849      */
850     public static final String PERMISSION_USE_CAR_TELEMETRY_SERVICE =
851             "android.car.permission.USE_CAR_TELEMETRY_SERVICE";
852 
853     /**
854      * Type of car connection: platform runs directly in car.
855      *
856      * @deprecated connection type constants are no longer used
857      */
858     @Deprecated
859     public static final int CONNECTION_TYPE_EMBEDDED = 5;
860 
861     /**
862      * Permission necessary to be able to render template-based UI metadata on behalf of another
863      * application.
864      *
865      * @hide
866      */
867     @SystemApi
868     public static final String PERMISSION_TEMPLATE_RENDERER =
869             "android.car.permission.TEMPLATE_RENDERER";
870 
871     /**
872      * Permission necessary to set or retrieve car watchdog configurations.
873      *
874      * @hide
875      */
876     @SystemApi
877     public static final String PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG =
878             "android.car.permission.CONTROL_CAR_WATCHDOG_CONFIG";
879 
880     /**
881      * Permission necessary to collect metrics from car watchdog.
882      *
883      * @hide
884      */
885     @SystemApi
886     public static final String PERMISSION_COLLECT_CAR_WATCHDOG_METRICS =
887             "android.car.permission.COLLECT_CAR_WATCHDOG_METRICS";
888 
889     /**
890      * Permission necessary to control launching applications in Car.
891      *
892      * @hide
893      */
894     public static final String PERMISSION_CONTROL_CAR_APP_LAUNCH =
895             "android.car.permission.CONTROL_CAR_APP_LAUNCH";
896 
897     /** @hide */
898     @IntDef({CONNECTION_TYPE_EMBEDDED})
899     @Retention(RetentionPolicy.SOURCE)
900     public @interface ConnectionType {}
901 
902     /**
903      * @deprecated Use {@link CarMediaIntents#ACTION_MEDIA_TEMPLATE} instead.
904      */
905     @Deprecated
906     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
907     public static final String CAR_INTENT_ACTION_MEDIA_TEMPLATE =
908             "android.car.intent.action.MEDIA_TEMPLATE";
909 
910     /**
911      * @deprecated Use {@link CarMediaIntents#EXTRA_MEDIA_COMPONENT} instead.
912      */
913     @Deprecated
914     public static final String CAR_EXTRA_MEDIA_COMPONENT =
915             "android.car.intent.extra.MEDIA_COMPONENT";
916 
917     /**
918      *
919      * @deprecated Use {@link #CAR_EXTRA_MEDIA_COMPONENT} instead.
920      * @removed Using this for specifying MediaBrowserService was not supported since API level 29
921      * and above. Apps must use {@link #CAR_EXTRA_MEDIA_COMPONENT} instead.
922      */
923     @Deprecated
924     public static final String CAR_EXTRA_MEDIA_PACKAGE = "android.car.intent.extra.MEDIA_PACKAGE";
925 
926     /**
927      * Used as a string extra field of media session to specify the service corresponding to the
928      * session.
929      */
930     public static final String CAR_EXTRA_BROWSE_SERVICE_FOR_SESSION =
931             "android.media.session.BROWSE_SERVICE";
932 
933     /** @hide */
934     public static final String CAR_SERVICE_INTERFACE_NAME = CommonConstants.CAR_SERVICE_INTERFACE;
935 
936     private static final String CAR_SERVICE_PACKAGE = "com.android.car";
937 
938     private static final String CAR_SERVICE_CLASS = "com.android.car.CarService";
939 
940     /**
941      * Category used by navigation applications to indicate which activity should be launched on
942      * the instrument cluster when such application holds
943      * {@link CarAppFocusManager#APP_FOCUS_TYPE_NAVIGATION} focus.
944      *
945      * @hide
946      */
947     public static final String CAR_CATEGORY_NAVIGATION = "android.car.cluster.NAVIGATION";
948 
949     /**
950      * When an activity is launched in the cluster, it will receive {@link ClusterActivityState} in
951      * the intent's extra under this key, containing instrument cluster information such as
952      * unobscured area, visibility, etc.
953      *
954      * @hide
955      */
956     @SystemApi
957     public static final String CAR_EXTRA_CLUSTER_ACTIVITY_STATE =
958             "android.car.cluster.ClusterActivityState";
959 
960 
961     /**
962      * Callback to notify the Lifecycle of car service.
963      *
964      * <p>Access to car service should happen
965      * after {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} call with
966      * {@code ready} set {@code true}.</p>
967      *
968      * <p>When {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} is
969      * called with ready set to false, access to car service should stop until car service is ready
970      * again from {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} call
971      * with {@code ready} set to {@code true}.</p>
972      */
973     public interface CarServiceLifecycleListener {
974         /**
975          * Car service has gone through status change.
976          *
977          * <p>This is always called in the main thread context.</p>
978          *
979          * @param car {@code Car} object that was originally associated with this lister from
980          *            {@link #createCar(Context, Handler, long, Car.CarServiceLifecycleListener)}
981          *            call.
982          * @param ready When {@code true, car service is ready and all accesses are ok.
983          *              Otherwise car service has crashed or killed and will be restarted.
984          */
onLifecycleChanged(@onNull Car car, boolean ready)985         void onLifecycleChanged(@NonNull Car car, boolean ready);
986     }
987 
988     /**
989      * {@link #createCar(Context, Handler, long, CarServiceLifecycleListener)}'s
990      * waitTimeoutMs value to use to wait forever inside the call until car service is ready.
991      */
992     public static final long CAR_WAIT_TIMEOUT_WAIT_FOREVER = -1;
993 
994     /**
995      * {@link #createCar(Context, Handler, long, CarServiceLifecycleListener)}'s
996      * waitTimeoutMs value to use to skip any waiting inside the call.
997      */
998     public static final long CAR_WAIT_TIMEOUT_DO_NOT_WAIT = 0;
999 
1000     private static final long CAR_SERVICE_BIND_RETRY_INTERVAL_MS = 500;
1001     private static final long CAR_SERVICE_BIND_MAX_RETRY = 20;
1002 
1003     private static final long CAR_SERVICE_BINDER_POLLING_INTERVAL_MS = 50;
1004     private static final long CAR_SERVICE_BINDER_POLLING_MAX_RETRY = 100;
1005 
1006     private static final int STATE_DISCONNECTED = 0;
1007     private static final int STATE_CONNECTING = 1;
1008     private static final int STATE_CONNECTED = 2;
1009 
1010     /** @hide */
1011     @Retention(RetentionPolicy.SOURCE)
1012     @IntDef(prefix = "STATE_", value = {
1013             STATE_DISCONNECTED,
1014             STATE_CONNECTING,
1015             STATE_CONNECTED,
1016     })
1017     @Target({ElementType.TYPE_USE})
1018     public @interface StateTypeEnum {}
1019 
1020     /**
1021      * The enabling request was successful and requires reboot to take effect.
1022      * @hide
1023      */
1024     @SystemApi
1025     public static final int FEATURE_REQUEST_SUCCESS = 0;
1026     /**
1027      * The requested feature is already enabled or disabled as requested. No need to reboot the
1028      * system.
1029      * @hide
1030      */
1031     @SystemApi
1032     public static final int FEATURE_REQUEST_ALREADY_IN_THE_STATE = 1;
1033     /**
1034      * The requested feature is mandatory cannot be enabled or disabled. It is always enabled.
1035      * @hide
1036      */
1037     @SystemApi
1038     public static final int FEATURE_REQUEST_MANDATORY = 2;
1039     /**
1040      * The requested feature is not available and cannot be enabled or disabled.
1041      * @hide
1042      */
1043     @SystemApi
1044     public static final int FEATURE_REQUEST_NOT_EXISTING = 3;
1045 
1046     /** @hide */
1047     @Retention(RetentionPolicy.SOURCE)
1048     @IntDef(prefix = "FEATURE_REQUEST_", value = {
1049             FEATURE_REQUEST_SUCCESS,
1050             FEATURE_REQUEST_ALREADY_IN_THE_STATE,
1051             FEATURE_REQUEST_MANDATORY,
1052             FEATURE_REQUEST_NOT_EXISTING,
1053     })
1054     @Target({ElementType.TYPE_USE})
1055     public @interface FeaturerRequestEnum {}
1056 
1057     private static final boolean DBG = false;
1058 
1059     private final Context mContext;
1060 
1061     private final Exception mConstructionStack;
1062 
1063     private final Object mLock = new Object();
1064 
1065     @GuardedBy("mLock")
1066     private ICar mService;
1067     @GuardedBy("mLock")
1068     private boolean mServiceBound;
1069 
1070     @GuardedBy("mLock")
1071     @StateTypeEnum
1072     private int mConnectionState;
1073     @GuardedBy("mLock")
1074     private int mConnectionRetryCount;
1075 
1076     private final Runnable mConnectionRetryRunnable = new Runnable() {
1077         @Override
1078         public void run() {
1079             startCarService();
1080         }
1081     };
1082 
1083     private final Runnable mConnectionRetryFailedRunnable = new Runnable() {
1084         @Override
1085         public void run() {
1086             mServiceConnectionListener.onServiceDisconnected(new ComponentName(CAR_SERVICE_PACKAGE,
1087                     CAR_SERVICE_CLASS));
1088         }
1089     };
1090 
1091     private final ServiceConnection mServiceConnectionListener =
1092             new ServiceConnection() {
1093         @Override
1094         public void onServiceConnected(ComponentName name, IBinder service) {
1095             synchronized (mLock) {
1096                 ICar newService = ICar.Stub.asInterface(service);
1097                 if (newService == null) {
1098                     Log.wtf(TAG_CAR, "null binder service", new RuntimeException());
1099                     return;  // should not happen.
1100                 }
1101                 if (mService != null && mService.asBinder().equals(newService.asBinder())) {
1102                     // already connected.
1103                     return;
1104                 }
1105                 mConnectionState = STATE_CONNECTED;
1106                 mService = newService;
1107             }
1108             if (mStatusChangeCallback != null) {
1109                 mStatusChangeCallback.onLifecycleChanged(Car.this, true);
1110             } else if (mServiceConnectionListenerClient != null) {
1111                 mServiceConnectionListenerClient.onServiceConnected(name, service);
1112             }
1113         }
1114 
1115         @Override
1116         public void onServiceDisconnected(ComponentName name) {
1117             // Car service can pick up feature changes after restart.
1118             mFeatures.resetCache();
1119             synchronized (mLock) {
1120                 if (mConnectionState  == STATE_DISCONNECTED) {
1121                     // can happen when client calls disconnect before onServiceDisconnected call.
1122                     return;
1123                 }
1124                 handleCarDisconnectLocked();
1125             }
1126             if (mStatusChangeCallback != null) {
1127                 mStatusChangeCallback.onLifecycleChanged(Car.this, false);
1128             } else if (mServiceConnectionListenerClient != null) {
1129                 mServiceConnectionListenerClient.onServiceDisconnected(name);
1130             } else {
1131                 // This client does not handle car service restart, so should be terminated.
1132                 finishClient();
1133             }
1134         }
1135     };
1136 
1137     @Nullable
1138     private final ServiceConnection mServiceConnectionListenerClient;
1139 
1140     /** Can be added after ServiceManager.getService call */
1141     @Nullable
1142     private final CarServiceLifecycleListener mStatusChangeCallback;
1143 
1144     @GuardedBy("mLock")
1145     private final HashMap<String, CarManagerBase> mServiceMap = new HashMap<>();
1146 
1147     /** Handler for generic event dispatching. */
1148     private final Handler mEventHandler;
1149 
1150     private final Handler mMainThreadEventHandler;
1151 
1152     private final CarFeatures mFeatures = new CarFeatures();
1153 
1154     /**
1155      * A factory method that creates Car instance for all Car API access.
1156      *
1157      * <p>Instance created with this should be disconnected from car service by calling
1158      * {@link #disconnect()} before the passed {code Context} is released.
1159      *
1160      * @param context App's Context. This should not be null. If you are passing
1161      *                {@link ContextWrapper}, make sure that its base Context is non-null as well.
1162      *                Otherwise it will throw {@link java.lang.NullPointerException}.
1163      * @param serviceConnectionListener listener for monitoring service connection.
1164      * @param handler the handler on which the callback should execute, or null to execute on the
1165      * service's main thread. Note: the service connection listener will be always on the main
1166      * thread regardless of the handler given.
1167      * @return Car instance if system is in car environment and returns {@code null} otherwise.
1168      *
1169      * @deprecated use {@link #createCar(Context, Handler)} instead.
1170      */
1171     @Deprecated
createCar(Context context, ServiceConnection serviceConnectionListener, @Nullable Handler handler)1172     public static Car createCar(Context context, ServiceConnection serviceConnectionListener,
1173             @Nullable Handler handler) {
1174         assertNonNullContext(context);
1175         if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
1176             Log.e(TAG_CAR, "FEATURE_AUTOMOTIVE not declared while android.car is used");
1177             return null;
1178         }
1179         try {
1180             return new Car(context, /* service= */ null , serviceConnectionListener,
1181                     /* statusChangeListener= */ null, handler);
1182         } catch (IllegalArgumentException e) {
1183             // Expected when car service loader is not available.
1184         }
1185         return null;
1186     }
1187 
1188     /**
1189      * A factory method that creates Car instance for all Car API access using main thread {@code
1190      * Looper}.
1191      *
1192      * <p>Instance created with this should be disconnected from car service by calling
1193      * {@link #disconnect()} before the passed {code Context} is released.
1194      *
1195      * @see #createCar(Context, ServiceConnection, Handler)
1196      *
1197      * @deprecated use {@link #createCar(Context, Handler)} instead.
1198      */
1199     @Deprecated
createCar(Context context, ServiceConnection serviceConnectionListener)1200     public static Car createCar(Context context, ServiceConnection serviceConnectionListener) {
1201         return createCar(context, serviceConnectionListener, null);
1202     }
1203 
1204     /**
1205      * Creates new {@link Car} object which connected synchronously to Car Service and ready to use.
1206      *
1207      * <p>Instance created with this should be disconnected from car service by calling
1208      * {@link #disconnect()} before the passed {code Context} is released.
1209      *
1210      * @param context application's context
1211      *
1212      * @return Car object if operation succeeded, otherwise null.
1213      */
1214     @Nullable
createCar(Context context)1215     public static Car createCar(Context context) {
1216         return createCar(context, (Handler) null);
1217     }
1218 
1219     /**
1220      * Creates new {@link Car} object which connected synchronously to Car Service and ready to use.
1221      *
1222      * <p>Instance created with this should be disconnected from car service by calling
1223      * {@link #disconnect()} before the passed {code Context} is released.
1224      *
1225      * @param context App's Context. This should not be null. If you are passing
1226      *                {@link ContextWrapper}, make sure that its base Context is non-null as well.
1227      *                Otherwise it will throw {@link java.lang.NullPointerException}.
1228      * @param handler the handler on which the manager's callbacks will be executed, or null to
1229      * execute on the application's main thread.
1230      *
1231      * @return Car object if operation succeeded, otherwise null.
1232      */
1233     @Nullable
createCar(Context context, @Nullable Handler handler)1234     public static Car createCar(Context context, @Nullable Handler handler) {
1235         assertNonNullContext(context);
1236         Car car = null;
1237         IBinder service = null;
1238         boolean started = false;
1239         int retryCount = 0;
1240         while (true) {
1241             service = ServiceManager.getService(CAR_SERVICE_BINDER_SERVICE_NAME);
1242             if (car == null) {
1243                 // service can be still null. The constructor is safe for null service.
1244                 car = new Car(context, ICar.Stub.asInterface(service),
1245                         null /*serviceConnectionListener*/, null /*statusChangeListener*/, handler);
1246             }
1247             if (service != null) {
1248                 if (!started) {  // specialization for most common case.
1249                     // Do this to crash client when car service crashes.
1250                     car.startCarService();
1251                     return car;
1252                 }
1253                 break;
1254             }
1255             if (!started) {
1256                 car.startCarService();
1257                 started = true;
1258             }
1259             retryCount++;
1260             if (retryCount > CAR_SERVICE_BINDER_POLLING_MAX_RETRY) {
1261                 Log.e(TAG_CAR, "cannot get car_service, waited for car service (ms):"
1262                                 + CAR_SERVICE_BINDER_POLLING_INTERVAL_MS
1263                                 * CAR_SERVICE_BINDER_POLLING_MAX_RETRY,
1264                         new RuntimeException());
1265                 return null;
1266             }
1267             try {
1268                 Thread.sleep(CAR_SERVICE_BINDER_POLLING_INTERVAL_MS);
1269             } catch (InterruptedException e) {
1270                 Log.e(CarLibLog.TAG_CAR, "interrupted while waiting for car_service",
1271                         new RuntimeException());
1272                 return null;
1273             }
1274         }
1275         // Can be accessed from mServiceConnectionListener in main thread.
1276         synchronized (car) {
1277             if (car.mService == null) {
1278                 car.mService = ICar.Stub.asInterface(service);
1279                 Log.w(TAG_CAR,
1280                         "waited for car_service (ms):"
1281                                 + CAR_SERVICE_BINDER_POLLING_INTERVAL_MS * retryCount,
1282                         new RuntimeException());
1283             }
1284             car.mConnectionState = STATE_CONNECTED;
1285         }
1286         return car;
1287     }
1288 
1289     /**
1290      * Creates new {@link Car} object with {@link CarServiceLifecycleListener}.
1291      *
1292      * <p>Instance created with this should be disconnected from car service by calling
1293      * {@link #disconnect()} before the passed {code Context} is released.
1294      *
1295      * <p> If car service is ready inside this call and if the caller is running in the main thread,
1296      * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} will be called
1297      * with ready set to be true. Otherwise,
1298      * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} will be called
1299      * from the main thread later. </p>
1300      *
1301      * <p>This call can block up to specified waitTimeoutMs to wait for car service to be ready.
1302      * If car service is not ready within the given time, it will return a Car instance in
1303      * disconnected state. Blocking main thread forever can lead into getting ANR (Application Not
1304      * Responding) killing from system and should not be used if the app is supposed to survive
1305      * across the crash / restart of car service. It can be still useful in case the app cannot do
1306      * anything without car service being ready. In any waiting, if the thread is getting
1307      * interrupted, it will return immediately.
1308      * </p>
1309      *
1310      * <p>Note that returned {@link Car} object is not guaranteed to be connected when there is
1311      * a limited timeout. Regardless of returned car being connected or not, it is recommended to
1312      * implement all car related initialization inside
1313      * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} and avoid the
1314      * needs to check if returned {@link Car} is connected or not from returned {@link Car}.</p>
1315      *
1316      * @param context App's Context. This should not be null. If you are passing
1317      *                {@link ContextWrapper}, make sure that its base Context is non-null as well.
1318      *                Otherwise it will throw {@link java.lang.NullPointerException}.
1319      * @param handler dispatches all Car*Manager events to this Handler. Exception is
1320      *                {@link CarServiceLifecycleListener} which will be always dispatched to main
1321      *                thread. Passing null leads into dispatching all Car*Manager callbacks to main
1322      *                thread as well.
1323      * @param waitTimeoutMs Setting this to {@link #CAR_WAIT_TIMEOUT_DO_NOT_WAIT} will guarantee
1324      *                      that the API does not wait for the car service at all. Setting this to
1325      *                      to {@link #CAR_WAIT_TIMEOUT_WAIT_FOREVER} will block the call forever
1326      *                      until the car service is ready. Setting any positive value will be
1327      *                      interpreted as timeout value.
1328      */
1329     @NonNull
createCar(@onNull Context context, @Nullable Handler handler, long waitTimeoutMs, @NonNull CarServiceLifecycleListener statusChangeListener)1330     public static Car createCar(@NonNull Context context,
1331             @Nullable Handler handler, long waitTimeoutMs,
1332             @NonNull CarServiceLifecycleListener statusChangeListener) {
1333         assertNonNullContext(context);
1334         Objects.requireNonNull(statusChangeListener);
1335         Car car = null;
1336         IBinder service = null;
1337         boolean started = false;
1338         int retryCount = 0;
1339         long maxRetryCount = 0;
1340         if (waitTimeoutMs > 0) {
1341             maxRetryCount = waitTimeoutMs / CAR_SERVICE_BINDER_POLLING_INTERVAL_MS;
1342             // at least wait once if it is positive value.
1343             if (maxRetryCount == 0) {
1344                 maxRetryCount = 1;
1345             }
1346         }
1347         boolean isMainThread = Looper.myLooper() == Looper.getMainLooper();
1348         while (true) {
1349             service = ServiceManager.getService(CAR_SERVICE_BINDER_SERVICE_NAME);
1350             if (car == null) {
1351                 // service can be still null. The constructor is safe for null service.
1352                 car = new Car(context, ICar.Stub.asInterface(service), null, statusChangeListener,
1353                         handler);
1354             }
1355             if (service != null) {
1356                 if (!started) {  // specialization for most common case : car service already ready
1357                     car.dispatchCarReadyToMainThread(isMainThread);
1358                     // Needs this for CarServiceLifecycleListener. Note that ServiceConnection
1359                     // will skip the callback as valid mService is set already.
1360                     car.startCarService();
1361                     return car;
1362                 }
1363                 // service available after starting.
1364                 break;
1365             }
1366             if (!started) {
1367                 car.startCarService();
1368                 started = true;
1369             }
1370             retryCount++;
1371             if (waitTimeoutMs < 0 && retryCount >= CAR_SERVICE_BINDER_POLLING_MAX_RETRY
1372                     && retryCount % CAR_SERVICE_BINDER_POLLING_MAX_RETRY == 0) {
1373                 // Log warning if car service is not alive even for waiting forever case.
1374                 Log.w(TAG_CAR, "car_service not ready, waited for car service (ms):"
1375                                 + retryCount * CAR_SERVICE_BINDER_POLLING_INTERVAL_MS,
1376                         new RuntimeException());
1377             } else if (waitTimeoutMs >= 0 && retryCount > maxRetryCount) {
1378                 if (waitTimeoutMs > 0) {
1379                     Log.w(TAG_CAR, "car_service not ready, waited for car service (ms):"
1380                                     + waitTimeoutMs,
1381                             new RuntimeException());
1382                 }
1383                 return car;
1384             }
1385 
1386             try {
1387                 Thread.sleep(CAR_SERVICE_BINDER_POLLING_INTERVAL_MS);
1388             } catch (InterruptedException e) {
1389                 Thread.currentThread().interrupt();
1390                 Log.w(TAG_CAR, "interrupted", new RuntimeException());
1391                 return car;
1392             }
1393         }
1394         // Can be accessed from mServiceConnectionListener in main thread.
1395         synchronized (car.mLock) {
1396             Log.w(TAG_CAR,
1397                     "waited for car_service (ms):"
1398                             + retryCount * CAR_SERVICE_BINDER_POLLING_INTERVAL_MS,
1399                     new RuntimeException());
1400             // ServiceConnection has handled everything.
1401             if (car.mService != null) {
1402                 return car;
1403             }
1404             // mService check in ServiceConnection prevents calling
1405             // onLifecycleChanged. So onLifecycleChanged should be called explicitly
1406             // but do it outside lock.
1407             car.mService = ICar.Stub.asInterface(service);
1408             car.mConnectionState = STATE_CONNECTED;
1409         }
1410         car.dispatchCarReadyToMainThread(isMainThread);
1411         return car;
1412     }
1413 
assertNonNullContext(Context context)1414     private static void assertNonNullContext(Context context) {
1415         Objects.requireNonNull(context);
1416         if (context instanceof ContextWrapper
1417                 && ((ContextWrapper) context).getBaseContext() == null) {
1418             throw new NullPointerException(
1419                     "ContextWrapper with null base passed as Context, forgot to set base Context?");
1420         }
1421     }
1422 
dispatchCarReadyToMainThread(boolean isMainThread)1423     private void dispatchCarReadyToMainThread(boolean isMainThread) {
1424         if (isMainThread) {
1425             mStatusChangeCallback.onLifecycleChanged(this, true);
1426         } else {
1427             // should dispatch to main thread.
1428             mMainThreadEventHandler.post(
1429                     () -> mStatusChangeCallback.onLifecycleChanged(this, true));
1430         }
1431     }
1432 
Car(Context context, @Nullable ICar service, @Nullable ServiceConnection serviceConnectionListener, @Nullable CarServiceLifecycleListener statusChangeListener, @Nullable Handler handler)1433     private Car(Context context, @Nullable ICar service,
1434             @Nullable ServiceConnection serviceConnectionListener,
1435             @Nullable CarServiceLifecycleListener statusChangeListener,
1436             @Nullable Handler handler) {
1437         mContext = context;
1438         mEventHandler = determineEventHandler(handler);
1439         mMainThreadEventHandler = determineMainThreadEventHandler(mEventHandler);
1440 
1441         mService = service;
1442         if (service != null) {
1443             mConnectionState = STATE_CONNECTED;
1444         } else {
1445             mConnectionState = STATE_DISCONNECTED;
1446         }
1447         mServiceConnectionListenerClient = serviceConnectionListener;
1448         mStatusChangeCallback = statusChangeListener;
1449         // Store construction stack so that client can get help when it crashes when car service
1450         // crashes.
1451         if (serviceConnectionListener == null && statusChangeListener == null) {
1452             mConstructionStack = new RuntimeException();
1453         } else {
1454             mConstructionStack = null;
1455         }
1456     }
1457 
1458     /**
1459      * Car constructor when ICar binder is already available. The binder can be null.
1460      * @hide
1461      */
Car(Context context, @Nullable ICar service, @Nullable Handler handler)1462     public Car(Context context, @Nullable ICar service, @Nullable Handler handler) {
1463         this(context, service, null /*serviceConnectionListener*/, null /*statusChangeListener*/,
1464                 handler);
1465     }
1466 
determineMainThreadEventHandler(Handler eventHandler)1467     private static Handler determineMainThreadEventHandler(Handler eventHandler) {
1468         Looper mainLooper = Looper.getMainLooper();
1469         return (eventHandler.getLooper() == mainLooper) ? eventHandler : new Handler(mainLooper);
1470     }
1471 
determineEventHandler(@ullable Handler handler)1472     private static Handler determineEventHandler(@Nullable Handler handler) {
1473         if (handler == null) {
1474             Looper looper = Looper.getMainLooper();
1475             handler = new Handler(looper);
1476         }
1477         return handler;
1478     }
1479 
1480     /**
1481      * Connect to car service. This can be called while it is disconnected.
1482      * @throws IllegalStateException If connection is still on-going from previous
1483      *         connect call or it is already connected
1484      *
1485      * @deprecated this method is not need if this object is created via
1486      * {@link #createCar(Context, Handler)}.
1487      */
1488     @Deprecated
connect()1489     public void connect() throws IllegalStateException {
1490         synchronized (mLock) {
1491             if (mConnectionState != STATE_DISCONNECTED) {
1492                 throw new IllegalStateException("already connected or connecting");
1493             }
1494             mConnectionState = STATE_CONNECTING;
1495             startCarService();
1496         }
1497     }
1498 
handleCarDisconnectLocked()1499     private void handleCarDisconnectLocked() {
1500         if (mConnectionState == STATE_DISCONNECTED) {
1501             // can happen when client calls disconnect with onServiceDisconnected already called.
1502             return;
1503         }
1504         mEventHandler.removeCallbacks(mConnectionRetryRunnable);
1505         mMainThreadEventHandler.removeCallbacks(mConnectionRetryFailedRunnable);
1506         mConnectionRetryCount = 0;
1507         tearDownCarManagersLocked();
1508         mService = null;
1509         mConnectionState = STATE_DISCONNECTED;
1510     }
1511 
1512     /**
1513      * Disconnect from car service. This can be called while disconnected. Once disconnect is
1514      * called, all Car*Managers from this instance becomes invalid, and
1515      * {@link Car#getCarManager(String)} will return different instance if it is connected again.
1516      */
disconnect()1517     public void disconnect() {
1518         synchronized (mLock) {
1519             handleCarDisconnectLocked();
1520             if (mServiceBound) {
1521                 mContext.unbindService(mServiceConnectionListener);
1522                 mServiceBound = false;
1523             }
1524         }
1525     }
1526 
1527     /**
1528      * Tells if it is connected to the service or not. This will return false if it is still
1529      * connecting.
1530      * @return
1531      */
isConnected()1532     public boolean isConnected() {
1533         synchronized (mLock) {
1534             return mService != null;
1535         }
1536     }
1537 
1538     /**
1539      * Tells if this instance is already connecting to car service or not.
1540      * @return
1541      */
isConnecting()1542     public boolean isConnecting() {
1543         synchronized (mLock) {
1544             return mConnectionState == STATE_CONNECTING;
1545         }
1546     }
1547 
1548     /** @hide */
1549     @VisibleForTesting
getServiceConnectionListener()1550     public ServiceConnection getServiceConnectionListener() {
1551         return mServiceConnectionListener;
1552     }
1553 
1554     /**
1555      * Get car specific service as in {@link Context#getSystemService(String)}. Returned
1556      * {@link Object} should be type-casted to the desired service.
1557      * For example, to get sensor service,
1558      * SensorManagerService sensorManagerService = car.getCarManager(Car.SENSOR_SERVICE);
1559      * @param serviceName Name of service that should be created like {@link #SENSOR_SERVICE}.
1560      * @return Matching service manager or null if there is no such service.
1561      */
1562     @Nullable
getCarManager(String serviceName)1563     public Object getCarManager(String serviceName) {
1564         CarManagerBase manager;
1565         synchronized (mLock) {
1566             if (mService == null) {
1567                 Log.w(TAG_CAR, "getCarManager not working while car service not ready");
1568                 return null;
1569             }
1570             manager = mServiceMap.get(serviceName);
1571             if (manager == null) {
1572                 try {
1573                     IBinder binder = mService.getCarService(serviceName);
1574                     if (binder == null) {
1575                         Log.w(TAG_CAR, "getCarManager could not get binder for service:"
1576                                 + serviceName);
1577                         return null;
1578                     }
1579                     manager = createCarManagerLocked(serviceName, binder);
1580                     if (manager == null) {
1581                         Log.w(TAG_CAR, "getCarManager could not create manager for service:"
1582                                         + serviceName);
1583                         return null;
1584                     }
1585                     mServiceMap.put(serviceName, manager);
1586                 } catch (RemoteException e) {
1587                     handleRemoteExceptionFromCarService(e);
1588                 }
1589             }
1590         }
1591         return manager;
1592     }
1593 
1594     /**
1595      * @return the type of currently connected car.
1596      *
1597      * @deprecated connection type will be always {@link CONNECTION_TYPE_EMBEDDED}
1598      */
1599     @ConnectionType
1600     @Deprecated
getCarConnectionType()1601     public int getCarConnectionType() {
1602         return CONNECTION_TYPE_EMBEDDED;
1603     }
1604 
1605     /**
1606      * Checks if {code featureName} is enabled in this car.
1607      *
1608      * <p>For optional features, this can return false if the car cannot support it. Optional
1609      * features should be used only when they are supported.</p>
1610      *
1611      * <p>For mandatory features, this will always return true.
1612      */
isFeatureEnabled(@onNull String featureName)1613     public boolean isFeatureEnabled(@NonNull String featureName) {
1614         ICar service;
1615         synchronized (mLock) {
1616             if (mService == null) {
1617                 return false;
1618             }
1619             service = mService;
1620         }
1621         return mFeatures.isFeatureEnabled(service, featureName);
1622     }
1623 
1624     /**
1625      * Enables the requested car feature. It becomes no-op if the feature is already enabled. The
1626      * change take effects after reboot.
1627      *
1628      * @return true if the feature is enabled or was enabled before.
1629      *
1630      * @hide
1631      */
1632     @SystemApi
1633     @RequiresPermission(PERMISSION_CONTROL_CAR_FEATURES)
1634     @FeaturerRequestEnum
enableFeature(@onNull String featureName)1635     public int enableFeature(@NonNull String featureName) {
1636         ICar service;
1637         synchronized (mLock) {
1638             if (mService == null) {
1639                 return FEATURE_REQUEST_NOT_EXISTING;
1640             }
1641             service = mService;
1642         }
1643         try {
1644             return service.enableFeature(featureName);
1645         } catch (RemoteException e) {
1646             return handleRemoteExceptionFromCarService(e, FEATURE_REQUEST_NOT_EXISTING);
1647         }
1648     }
1649 
1650     /**
1651      * Disables the requested car feature. It becomes no-op if the feature is already disabled. The
1652      * change take effects after reboot.
1653      *
1654      * @return true if the request succeeds or if it was already disabled.
1655      *
1656      * @hide
1657      */
1658     @SystemApi
1659     @RequiresPermission(PERMISSION_CONTROL_CAR_FEATURES)
1660     @FeaturerRequestEnum
disableFeature(@onNull String featureName)1661     public int disableFeature(@NonNull String featureName) {
1662         ICar service;
1663         synchronized (mLock) {
1664             if (mService == null) {
1665                 return FEATURE_REQUEST_NOT_EXISTING;
1666             }
1667             service = mService;
1668         }
1669         try {
1670             return service.disableFeature(featureName);
1671         } catch (RemoteException e) {
1672             return handleRemoteExceptionFromCarService(e, FEATURE_REQUEST_NOT_EXISTING);
1673         }
1674     }
1675 
1676     /**
1677      * Returns all =enabled features at the moment including mandatory, optional, and
1678      * experimental features.
1679      *
1680      * @hide
1681      */
1682     @SystemApi
1683     @RequiresPermission(PERMISSION_CONTROL_CAR_FEATURES)
getAllEnabledFeatures()1684     @NonNull public List<String> getAllEnabledFeatures() {
1685         ICar service;
1686         synchronized (mLock) {
1687             if (mService == null) {
1688                 return Collections.EMPTY_LIST;
1689             }
1690             service = mService;
1691         }
1692         try {
1693             return service.getAllEnabledFeatures();
1694         } catch (RemoteException e) {
1695             return handleRemoteExceptionFromCarService(e, Collections.EMPTY_LIST);
1696         }
1697     }
1698 
1699     /**
1700      * Returns the list of disabled features which are not effective yet. Those features will be
1701      * disabled when system restarts later.
1702      *
1703      * @hide
1704      */
1705     @SystemApi
1706     @RequiresPermission(PERMISSION_CONTROL_CAR_FEATURES)
getAllPendingDisabledFeatures()1707     @NonNull public List<String> getAllPendingDisabledFeatures() {
1708         ICar service;
1709         synchronized (mLock) {
1710             if (mService == null) {
1711                 return Collections.EMPTY_LIST;
1712             }
1713             service = mService;
1714         }
1715         try {
1716             return service.getAllPendingDisabledFeatures();
1717         } catch (RemoteException e) {
1718             return handleRemoteExceptionFromCarService(e, Collections.EMPTY_LIST);
1719         }
1720     }
1721 
1722     /**
1723      * Returns the list of enabled features which are not effective yet. Those features will be
1724      * enabled when system restarts later.
1725      *
1726      * @hide
1727      */
1728     @SystemApi
1729     @RequiresPermission(PERMISSION_CONTROL_CAR_FEATURES)
getAllPendingEnabledFeatures()1730     @NonNull public List<String> getAllPendingEnabledFeatures() {
1731         ICar service;
1732         synchronized (mLock) {
1733             if (mService == null) {
1734                 return Collections.EMPTY_LIST;
1735             }
1736             service = mService;
1737         }
1738         try {
1739             return service.getAllPendingEnabledFeatures();
1740         } catch (RemoteException e) {
1741             return handleRemoteExceptionFromCarService(e, Collections.EMPTY_LIST);
1742         }
1743     }
1744 
1745     /** @hide */
getContext()1746     public Context getContext() {
1747         return mContext;
1748     }
1749 
1750     /** @hide */
1751     @VisibleForTesting
getEventHandler()1752     public Handler getEventHandler() {
1753         return mEventHandler;
1754     }
1755 
1756     /** @hide */
1757     @VisibleForTesting
handleRemoteExceptionFromCarService(RemoteException e, T returnValue)1758     public <T> T handleRemoteExceptionFromCarService(RemoteException e, T returnValue) {
1759         handleRemoteExceptionFromCarService(e);
1760         return returnValue;
1761     }
1762 
1763     /** @hide */
handleRemoteExceptionFromCarService(RemoteException e)1764     void handleRemoteExceptionFromCarService(RemoteException e) {
1765         if (e instanceof TransactionTooLargeException) {
1766             Log.w(TAG_CAR, "Car service threw TransactionTooLargeException", e);
1767             throw new CarTransactionException(e, "Car service threw TransactionTooLargException");
1768         } else {
1769             Log.w(TAG_CAR, "Car service has crashed", e);
1770         }
1771     }
1772 
finishClient()1773     private void finishClient() {
1774         if (mContext == null) {
1775             throw new IllegalStateException("Car service has crashed, null Context");
1776         }
1777         if (mContext instanceof Activity) {
1778             Activity activity = (Activity) mContext;
1779             if (!activity.isFinishing()) {
1780                 Log.w(TAG_CAR,
1781                         "Car service crashed, client not handling it, finish Activity, created "
1782                                 + "from " + mConstructionStack);
1783                 activity.finish();
1784             }
1785             return;
1786         } else if (mContext instanceof Service) {
1787             Service service = (Service) mContext;
1788             killClient(service.getPackageName() + "," + service.getClass().getSimpleName());
1789         } else {
1790             killClient(/* clientInfo= */ null);
1791         }
1792     }
1793 
killClient(@ullable String clientInfo)1794     private void killClient(@Nullable String clientInfo) {
1795         Log.w(TAG_CAR, "**Car service has crashed. Client(" + clientInfo + ") is not handling it."
1796                         + " Client should use Car.createCar(..., CarServiceLifecycleListener, .."
1797                         + ".) to handle it properly. Check pritned callstack to check where other "
1798                         + "version of Car.createCar() was called. Killing the client process**",
1799                 mConstructionStack);
1800         Process.killProcess(Process.myPid());
1801     }
1802 
1803     /** @hide */
handleRemoteExceptionFromCarService(Service service, RemoteException e, T returnValue)1804     public static <T> T handleRemoteExceptionFromCarService(Service service, RemoteException e,
1805             T returnValue) {
1806         handleRemoteExceptionFromCarService(service, e);
1807         return returnValue;
1808     }
1809 
1810     /** @hide */
handleRemoteExceptionFromCarService(Service service, RemoteException e)1811     public static  void handleRemoteExceptionFromCarService(Service service, RemoteException e) {
1812         if (e instanceof TransactionTooLargeException) {
1813             Log.w(TAG_CAR, "Car service threw TransactionTooLargeException, client:"
1814                     + service.getPackageName() + ","
1815                     + service.getClass().getSimpleName(), e);
1816             throw new CarTransactionException(e, "Car service threw TransactionTooLargeException, "
1817                 + "client: %s, %s", service.getPackageName(), service.getClass().getSimpleName());
1818         } else {
1819             Log.w(TAG_CAR, "Car service has crashed, client:"
1820                     + service.getPackageName() + ","
1821                     + service.getClass().getSimpleName(), e);
1822             service.stopSelf();
1823         }
1824     }
1825 
1826     @Nullable
createCarManagerLocked(String serviceName, IBinder binder)1827     private CarManagerBase createCarManagerLocked(String serviceName, IBinder binder) {
1828         CarManagerBase manager = null;
1829         switch (serviceName) {
1830             case AUDIO_SERVICE:
1831                 manager = new CarAudioManager(this, binder);
1832                 break;
1833             case SENSOR_SERVICE:
1834                 manager = new CarSensorManager(this, binder);
1835                 break;
1836             case INFO_SERVICE:
1837                 manager = new CarInfoManager(this, binder);
1838                 break;
1839             case APP_FOCUS_SERVICE:
1840                 manager = new CarAppFocusManager(this, binder);
1841                 break;
1842             case PACKAGE_SERVICE:
1843                 manager = new CarPackageManager(this, binder);
1844                 break;
1845             case CAR_OCCUPANT_ZONE_SERVICE:
1846                 manager = new CarOccupantZoneManager(this, binder);
1847                 break;
1848             case CAR_NAVIGATION_SERVICE:
1849                 manager = new CarNavigationStatusManager(this, binder);
1850                 break;
1851             case CABIN_SERVICE:
1852                 manager = new CarCabinManager(this, binder);
1853                 break;
1854             case DIAGNOSTIC_SERVICE:
1855                 manager = new CarDiagnosticManager(this, binder);
1856                 break;
1857             case HVAC_SERVICE:
1858                 manager = new CarHvacManager(this, binder);
1859                 break;
1860             case POWER_SERVICE:
1861                 manager = new CarPowerManager(this, binder);
1862                 break;
1863             case PROJECTION_SERVICE:
1864                 manager = new CarProjectionManager(this, binder);
1865                 break;
1866             case PROPERTY_SERVICE:
1867                 manager = new CarPropertyManager(this, ICarProperty.Stub.asInterface(binder));
1868                 break;
1869             case VENDOR_EXTENSION_SERVICE:
1870                 manager = new CarVendorExtensionManager(this, binder);
1871                 break;
1872             case CAR_INSTRUMENT_CLUSTER_SERVICE:
1873                 manager = new CarInstrumentClusterManager(this, binder);
1874                 break;
1875             case TEST_SERVICE:
1876                 /* CarTestManager exist in static library. So instead of constructing it here,
1877                  * only pass binder wrapper so that CarTestManager can be constructed outside. */
1878                 manager = new CarTestManagerBinderWrapper(this, binder);
1879                 break;
1880             case VEHICLE_MAP_SERVICE:
1881                 manager = new VmsClientManager(this, binder);
1882                 break;
1883             case VMS_SUBSCRIBER_SERVICE:
1884                 manager = VmsSubscriberManager.wrap(this,
1885                         (VmsClientManager) getCarManager(VEHICLE_MAP_SERVICE));
1886                 break;
1887             case BLUETOOTH_SERVICE:
1888                 manager = new CarBluetoothManager(this, binder);
1889                 break;
1890             case STORAGE_MONITORING_SERVICE:
1891                 manager = new CarStorageMonitoringManager(this, binder);
1892                 break;
1893             case CAR_DRIVING_STATE_SERVICE:
1894                 manager = new CarDrivingStateManager(this, binder);
1895                 break;
1896             case CAR_UX_RESTRICTION_SERVICE:
1897                 manager = new CarUxRestrictionsManager(this, binder);
1898                 break;
1899             case OCCUPANT_AWARENESS_SERVICE:
1900                 manager = new OccupantAwarenessManager(this, binder);
1901                 break;
1902             case CAR_MEDIA_SERVICE:
1903                 manager = new CarMediaManager(this, binder);
1904                 break;
1905             case CAR_BUGREPORT_SERVICE:
1906                 manager = new CarBugreportManager(this, binder);
1907                 break;
1908             case CAR_USER_SERVICE:
1909                 manager = new CarUserManager(this, binder);
1910                 break;
1911             case CAR_WATCHDOG_SERVICE:
1912                 manager = new CarWatchdogManager(this, binder);
1913                 break;
1914             case CAR_INPUT_SERVICE:
1915                 manager = new CarInputManager(this, binder);
1916                 break;
1917             case CAR_DEVICE_POLICY_SERVICE:
1918                 manager = new CarDevicePolicyManager(this, binder);
1919                 break;
1920             case CLUSTER_HOME_SERVICE:
1921                 manager = new ClusterHomeManager(this, binder);
1922                 break;
1923             case CAR_EVS_SERVICE:
1924                 manager = new CarEvsManager(this, binder);
1925                 break;
1926             case CAR_TELEMETRY_SERVICE:
1927                 manager = new CarTelemetryManager(this, binder);
1928                 break;
1929             case CAR_ACTIVITY_SERVICE:
1930                 manager = new CarActivityManager(this, binder);
1931                 break;
1932             default:
1933                 // Experimental or non-existing
1934                 String className = null;
1935                 try {
1936                     className = mService.getCarManagerClassForFeature(serviceName);
1937                 } catch (RemoteException e) {
1938                     handleRemoteExceptionFromCarService(e);
1939                     return null;
1940                 }
1941                 if (className == null) {
1942                     Log.e(TAG_CAR, "Cannot construct CarManager for service:" + serviceName
1943                             + " : no class defined");
1944                     return null;
1945                 }
1946                 manager = constructCarManager(className, binder);
1947                 break;
1948         }
1949         return manager;
1950     }
1951 
constructCarManager(String className, IBinder binder)1952     private CarManagerBase constructCarManager(String className, IBinder binder) {
1953         try {
1954             // Should use class loader for the Context as class loader for car api does not
1955             // see the class.
1956             ClassLoader loader = mContext.getClassLoader();
1957             Class managerClass = loader.loadClass(className);
1958             Constructor constructor = managerClass.getConstructor(Car.class, IBinder.class);
1959             CarManagerBase manager = (CarManagerBase) constructor.newInstance(this, binder);
1960             return manager;
1961         } catch (ClassNotFoundException | IllegalAccessException | NoSuchMethodException
1962                 | InstantiationException | InvocationTargetException e) {
1963             Log.e(TAG_CAR, "Cannot construct CarManager, class:" + className, e);
1964             return null;
1965         }
1966     }
1967 
startCarService()1968     private void startCarService() {
1969         Intent intent = new Intent();
1970         intent.setPackage(CAR_SERVICE_PACKAGE);
1971         intent.setAction(Car.CAR_SERVICE_INTERFACE_NAME);
1972         boolean bound = mContext.bindServiceAsUser(intent, mServiceConnectionListener,
1973                 Context.BIND_AUTO_CREATE, UserHandle.CURRENT_OR_SELF);
1974         synchronized (mLock) {
1975             if (!bound) {
1976                 mConnectionRetryCount++;
1977                 if (mConnectionRetryCount > CAR_SERVICE_BIND_MAX_RETRY) {
1978                     Log.w(TAG_CAR, "cannot bind to car service after max retry");
1979                     mMainThreadEventHandler.post(mConnectionRetryFailedRunnable);
1980                 } else {
1981                     mEventHandler.postDelayed(mConnectionRetryRunnable,
1982                             CAR_SERVICE_BIND_RETRY_INTERVAL_MS);
1983                 }
1984             } else {
1985                 mEventHandler.removeCallbacks(mConnectionRetryRunnable);
1986                 mMainThreadEventHandler.removeCallbacks(mConnectionRetryFailedRunnable);
1987                 mConnectionRetryCount = 0;
1988                 mServiceBound = true;
1989             }
1990         }
1991     }
1992 
tearDownCarManagersLocked()1993     private void tearDownCarManagersLocked() {
1994         // All disconnected handling should be only doing its internal cleanup.
1995         for (CarManagerBase manager: mServiceMap.values()) {
1996             manager.onCarDisconnected();
1997         }
1998         mServiceMap.clear();
1999     }
2000 }
2001