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