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