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.SdkConstant;
25 import android.annotation.SdkConstant.SdkConstantType;
26 import android.annotation.SystemApi;
27 import android.app.Activity;
28 import android.app.Service;
29 import android.car.cluster.CarInstrumentClusterManager;
30 import android.car.cluster.ClusterActivityState;
31 import android.car.content.pm.CarPackageManager;
32 import android.car.diagnostic.CarDiagnosticManager;
33 import android.car.drivingstate.CarDrivingStateManager;
34 import android.car.drivingstate.CarUxRestrictionsManager;
35 import android.car.hardware.CarSensorManager;
36 import android.car.hardware.CarVendorExtensionManager;
37 import android.car.hardware.cabin.CarCabinManager;
38 import android.car.hardware.hvac.CarHvacManager;
39 import android.car.hardware.power.CarPowerManager;
40 import android.car.hardware.property.CarPropertyManager;
41 import android.car.hardware.property.ICarProperty;
42 import android.car.media.CarAudioManager;
43 import android.car.media.CarMediaManager;
44 import android.car.navigation.CarNavigationStatusManager;
45 import android.car.settings.CarConfigurationManager;
46 import android.car.storagemonitoring.CarStorageMonitoringManager;
47 import android.car.test.CarTestManagerBinderWrapper;
48 import android.car.trust.CarTrustAgentEnrollmentManager;
49 import android.car.vms.VmsSubscriberManager;
50 import android.content.ComponentName;
51 import android.content.Context;
52 import android.content.ContextWrapper;
53 import android.content.Intent;
54 import android.content.ServiceConnection;
55 import android.content.pm.PackageManager;
56 import android.os.Handler;
57 import android.os.IBinder;
58 import android.os.Looper;
59 import android.os.Process;
60 import android.os.RemoteException;
61 import android.os.ServiceManager;
62 import android.os.TransactionTooLargeException;
63 import android.os.UserHandle;
64 import android.util.Log;
65 
66 import com.android.internal.annotations.GuardedBy;
67 import com.android.internal.annotations.VisibleForTesting;
68 import com.android.internal.util.Preconditions;
69 
70 import java.lang.annotation.ElementType;
71 import java.lang.annotation.Retention;
72 import java.lang.annotation.RetentionPolicy;
73 import java.lang.annotation.Target;
74 import java.util.HashMap;
75 
76 /**
77  *   Top level car API for embedded Android Auto deployments.
78  *   This API works only for devices with {@link PackageManager#FEATURE_AUTOMOTIVE}
79  *   Calling this API on a device with no such feature will lead to an exception.
80  */
81 public final class Car {
82 
83     /**
84      * Binder service name of car service registered to service manager.
85      *
86      * @hide
87      */
88     public static final String CAR_SERVICE_BINDER_SERVICE_NAME = "car_service";
89     /**
90      * Service name for {@link CarSensorManager}, to be used in {@link #getCarManager(String)}.
91      *
92      * @deprecated  {@link CarSensorManager} is deprecated. Use {@link CarPropertyManager} instead.
93      */
94     @Deprecated
95     public static final String SENSOR_SERVICE = "sensor";
96 
97     /** Service name for {@link CarInfoManager}, to be used in {@link #getCarManager(String)}. */
98     public static final String INFO_SERVICE = "info";
99 
100     /** Service name for {@link CarAppFocusManager}. */
101     public static final String APP_FOCUS_SERVICE = "app_focus";
102 
103     /** Service name for {@link CarPackageManager} */
104     public static final String PACKAGE_SERVICE = "package";
105 
106     /** Service name for {@link CarAudioManager} */
107     public static final String AUDIO_SERVICE = "audio";
108 
109     /** Service name for {@link CarNavigationStatusManager} */
110     public static final String CAR_NAVIGATION_SERVICE = "car_navigation_service";
111 
112     /**
113      * Service name for {@link CarInstrumentClusterManager}
114      *
115      * @deprecated CarInstrumentClusterManager is being deprecated
116      * @hide
117      */
118     @Deprecated
119     public static final String CAR_INSTRUMENT_CLUSTER_SERVICE = "cluster_service";
120 
121     /**
122      * Service name for {@link CarCabinManager}.
123      *
124      * @deprecated {@link CarCabinManager} is deprecated. Use {@link CarPropertyManager} instead.
125      * @hide
126      */
127     @Deprecated
128     @SystemApi
129     public static final String CABIN_SERVICE = "cabin";
130 
131     /**
132      * @hide
133      */
134     @SystemApi
135     public static final String DIAGNOSTIC_SERVICE = "diagnostic";
136 
137     /**
138      * Service name for {@link CarHvacManager}
139      * @deprecated {@link CarHvacManager} is deprecated. Use {@link CarPropertyManager} instead.
140      * @hide
141      */
142     @Deprecated
143     @SystemApi
144     public static final String HVAC_SERVICE = "hvac";
145 
146     /**
147      * @hide
148      */
149     @SystemApi
150     public static final String POWER_SERVICE = "power";
151 
152     /**
153      * @hide
154      */
155     @SystemApi
156     public static final String PROJECTION_SERVICE = "projection";
157 
158     /**
159      * Service name for {@link CarPropertyManager}
160      */
161     public static final String PROPERTY_SERVICE = "property";
162 
163     /**
164      * Service name for {@link CarVendorExtensionManager}
165      *
166      * @deprecated {@link CarVendorExtensionManager} is deprecated.
167      * Use {@link CarPropertyManager} instead.
168      * @hide
169      */
170     @Deprecated
171     @SystemApi
172     public static final String VENDOR_EXTENSION_SERVICE = "vendor_extension";
173 
174     /**
175      * @hide
176      */
177     public static final String BLUETOOTH_SERVICE = "car_bluetooth";
178 
179     /**
180      * @hide
181      */
182     @SystemApi
183     public static final String VMS_SUBSCRIBER_SERVICE = "vehicle_map_subscriber_service";
184 
185     /**
186      * Service name for {@link CarDrivingStateManager}
187      * @hide
188      */
189     @SystemApi
190     public static final String CAR_DRIVING_STATE_SERVICE = "drivingstate";
191 
192     /**
193      * Service name for {@link CarUxRestrictionsManager}
194      */
195     public static final String CAR_UX_RESTRICTION_SERVICE = "uxrestriction";
196 
197     /**
198      * Service name for {@link android.car.settings.CarConfigurationManager}
199      */
200     public static final String CAR_CONFIGURATION_SERVICE = "configuration";
201 
202     /**
203      * Service name for {@link android.car.media.CarMediaManager}
204      * @hide
205      */
206     public static final String CAR_MEDIA_SERVICE = "car_media";
207 
208     /**
209      *
210      * Service name for {@link android.car.CarBugreportManager}
211      * @hide
212      */
213     public static final String CAR_BUGREPORT_SERVICE = "car_bugreport";
214 
215     /**
216      * @hide
217      */
218     @SystemApi
219     public static final String STORAGE_MONITORING_SERVICE = "storage_monitoring";
220 
221     /**
222      * Service name for {@link android.car.trust.CarTrustAgentEnrollmentManager}
223      * @hide
224      */
225     @SystemApi
226     public static final String CAR_TRUST_AGENT_ENROLLMENT_SERVICE = "trust_enroll";
227 
228     /**
229      * Service for testing. This is system app only feature.
230      * Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}.
231      * @hide
232      */
233     @SystemApi
234     public static final String TEST_SERVICE = "car-service-test";
235 
236     /** Permission necessary to access car's mileage information.
237      *  @hide
238      */
239     @SystemApi
240     public static final String PERMISSION_MILEAGE = "android.car.permission.CAR_MILEAGE";
241 
242     /** Permission necessary to access car's energy information. */
243     public static final String PERMISSION_ENERGY = "android.car.permission.CAR_ENERGY";
244 
245     /** Permission necessary to access car's VIN information */
246     public static final String PERMISSION_IDENTIFICATION =
247             "android.car.permission.CAR_IDENTIFICATION";
248 
249     /** Permission necessary to access car's speed. */
250     public static final String PERMISSION_SPEED = "android.car.permission.CAR_SPEED";
251 
252     /** Permission necessary to access car's dynamics state.
253      *  @hide
254      */
255     @SystemApi
256     public static final String PERMISSION_CAR_DYNAMICS_STATE =
257             "android.car.permission.CAR_DYNAMICS_STATE";
258 
259     /** Permission necessary to access car's fuel door and ev charge port. */
260     public static final String PERMISSION_ENERGY_PORTS = "android.car.permission.CAR_ENERGY_PORTS";
261 
262     /** Permission necessary to read car's exterior lights information.
263      *  @hide
264      */
265     @SystemApi
266     public static final String PERMISSION_EXTERIOR_LIGHTS =
267             "android.car.permission.CAR_EXTERIOR_LIGHTS";
268 
269     /**
270      * Permission necessary to read car's interior lights information.
271      */
272     public static final String PERMISSION_READ_INTERIOR_LIGHTS =
273             "android.car.permission.READ_CAR_INTERIOR_LIGHTS";
274 
275     /** Permission necessary to control car's exterior lights.
276      *  @hide
277      */
278     @SystemApi
279     public static final String PERMISSION_CONTROL_EXTERIOR_LIGHTS =
280             "android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS";
281 
282     /**
283      * Permission necessary to control car's interior lights.
284      */
285     public static final String PERMISSION_CONTROL_INTERIOR_LIGHTS =
286             "android.car.permission.CONTROL_CAR_INTERIOR_LIGHTS";
287 
288     /** Permission necessary to access car's powertrain information.*/
289     public static final String PERMISSION_POWERTRAIN = "android.car.permission.CAR_POWERTRAIN";
290 
291     /**
292      * Permission necessary to change car audio volume through {@link CarAudioManager}.
293      */
294     public static final String PERMISSION_CAR_CONTROL_AUDIO_VOLUME =
295             "android.car.permission.CAR_CONTROL_AUDIO_VOLUME";
296 
297     /**
298      * Permission necessary to change car audio settings through {@link CarAudioManager}.
299      */
300     public static final String PERMISSION_CAR_CONTROL_AUDIO_SETTINGS =
301             "android.car.permission.CAR_CONTROL_AUDIO_SETTINGS";
302 
303     /**
304      * Permission necessary to receive full audio ducking events from car audio focus handler.
305      *
306      * @hide
307      */
308     @SystemApi
309     public static final String PERMISSION_RECEIVE_CAR_AUDIO_DUCKING_EVENTS =
310             "android.car.permission.RECEIVE_CAR_AUDIO_DUCKING_EVENTS";
311 
312     /**
313      * Permission necessary to use {@link CarNavigationStatusManager}.
314      */
315     public static final String PERMISSION_CAR_NAVIGATION_MANAGER =
316             "android.car.permission.CAR_NAVIGATION_MANAGER";
317 
318     /**
319      * Permission necessary to start activities in the instrument cluster through
320      * {@link CarInstrumentClusterManager}
321      *
322      * @hide
323      */
324     @SystemApi
325     public static final String PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL =
326             "android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL";
327 
328     /**
329      * Application must have this permission in order to be launched in the instrument cluster
330      * display.
331      *
332      * @hide
333      */
334     public static final String PERMISSION_CAR_DISPLAY_IN_CLUSTER =
335             "android.car.permission.CAR_DISPLAY_IN_CLUSTER";
336 
337     /** Permission necessary to use {@link CarInfoManager}. */
338     public static final String PERMISSION_CAR_INFO = "android.car.permission.CAR_INFO";
339 
340     /** Permission necessary to read temperature of car's exterior environment. */
341     public static final String PERMISSION_EXTERIOR_ENVIRONMENT =
342             "android.car.permission.CAR_EXTERIOR_ENVIRONMENT";
343 
344     /**
345      * Permission necessary to access car specific communication channel.
346      * @hide
347      */
348     @SystemApi
349     public static final String PERMISSION_VENDOR_EXTENSION =
350             "android.car.permission.CAR_VENDOR_EXTENSION";
351 
352     /**
353      * @hide
354      */
355     @SystemApi
356     public static final String PERMISSION_CONTROL_APP_BLOCKING =
357             "android.car.permission.CONTROL_APP_BLOCKING";
358 
359     /**
360      * Permission necessary to access car's engine information.
361      * @hide
362      */
363     @SystemApi
364     public static final String PERMISSION_CAR_ENGINE_DETAILED =
365             "android.car.permission.CAR_ENGINE_DETAILED";
366 
367     /**
368      * Permission necessary to access car's tire pressure information.
369      * @hide
370      */
371     @SystemApi
372     public static final String PERMISSION_TIRES = "android.car.permission.CAR_TIRES";
373 
374     /**
375      * Permission necessary to access car's steering angle information.
376      */
377     public static final String PERMISSION_READ_STEERING_STATE =
378             "android.car.permission.READ_CAR_STEERING";
379 
380     /**
381      * Permission necessary to read and write display units for distance, fuel volume, tire pressure
382      * and ev battery.
383      */
384     public static final String PERMISSION_READ_DISPLAY_UNITS =
385             "android.car.permission.READ_CAR_DISPLAY_UNITS";
386     /**
387      * Permission necessary to control display units for distance, fuel volume, tire pressure
388      * and ev battery.
389      */
390     public static final String PERMISSION_CONTROL_DISPLAY_UNITS =
391             "android.car.permission.CONTROL_CAR_DISPLAY_UNITS";
392 
393     /**
394      * Permission necessary to control car's door.
395      * @hide
396      */
397     @SystemApi
398     public static final String PERMISSION_CONTROL_CAR_DOORS =
399             "android.car.permission.CONTROL_CAR_DOORS";
400 
401     /**
402      * Permission necessary to control car's windows.
403      * @hide
404      */
405     @SystemApi
406     public static final String PERMISSION_CONTROL_CAR_WINDOWS =
407             "android.car.permission.CONTROL_CAR_WINDOWS";
408 
409     /**
410      * Permission necessary to control car's seats.
411      * @hide
412      */
413     @SystemApi
414     public static final String PERMISSION_CONTROL_CAR_SEATS =
415             "android.car.permission.CONTROL_CAR_SEATS";
416 
417     /**
418      * Permission necessary to control car's mirrors.
419      * @hide
420      */
421     @SystemApi
422     public static final String PERMISSION_CONTROL_CAR_MIRRORS =
423             "android.car.permission.CONTROL_CAR_MIRRORS";
424 
425     /**
426      * Permission necessary to access Car HVAC APIs.
427      * @hide
428      */
429     @SystemApi
430     public static final String PERMISSION_CONTROL_CAR_CLIMATE =
431             "android.car.permission.CONTROL_CAR_CLIMATE";
432 
433     /**
434      * Permission necessary to access Car POWER APIs.
435      * @hide
436      */
437     @SystemApi
438     public static final String PERMISSION_CAR_POWER = "android.car.permission.CAR_POWER";
439 
440     /**
441      * Permission necessary to access Car PROJECTION system APIs.
442      * @hide
443      */
444     @SystemApi
445     public static final String PERMISSION_CAR_PROJECTION = "android.car.permission.CAR_PROJECTION";
446 
447     /**
448      * Permission necessary to access projection status.
449      * @hide
450      */
451     @SystemApi
452     public static final String PERMISSION_CAR_PROJECTION_STATUS =
453             "android.car.permission.ACCESS_CAR_PROJECTION_STATUS";
454 
455     /**
456      * Permission necessary to mock vehicle hal for testing.
457      * @hide
458      * @deprecated mocking vehicle HAL in car service is no longer supported.
459      */
460     @SystemApi
461     public static final String PERMISSION_MOCK_VEHICLE_HAL =
462             "android.car.permission.CAR_MOCK_VEHICLE_HAL";
463 
464     /**
465      * Permission necessary to access CarTestService.
466      * @hide
467      */
468     @SystemApi
469     public static final String PERMISSION_CAR_TEST_SERVICE =
470             "android.car.permission.CAR_TEST_SERVICE";
471 
472     /**
473      * Permission necessary to access CarDrivingStateService to get a Car's driving state.
474      * @hide
475      */
476     @SystemApi
477     public static final String PERMISSION_CAR_DRIVING_STATE =
478             "android.car.permission.CAR_DRIVING_STATE";
479 
480     /**
481      * Permission necessary to access VMS client service.
482      *
483      * @hide
484      */
485     public static final String PERMISSION_BIND_VMS_CLIENT =
486             "android.car.permission.BIND_VMS_CLIENT";
487 
488     /**
489      * Permissions necessary to access VMS publisher APIs.
490      *
491      * @hide
492      */
493     @SystemApi
494     public static final String PERMISSION_VMS_PUBLISHER = "android.car.permission.VMS_PUBLISHER";
495 
496     /**
497      * Permissions necessary to access VMS subscriber APIs.
498      *
499      * @hide
500      */
501     @SystemApi
502     public static final String PERMISSION_VMS_SUBSCRIBER = "android.car.permission.VMS_SUBSCRIBER";
503 
504     /**
505      * Permissions necessary to read diagnostic information, including vendor-specific bits.
506      *
507      * @hide
508      */
509     @SystemApi
510     public static final String PERMISSION_CAR_DIAGNOSTIC_READ_ALL =
511         "android.car.permission.CAR_DIAGNOSTICS";
512 
513     /**
514      * Permissions necessary to clear diagnostic information.
515      *
516      * @hide
517      */
518     @SystemApi
519     public static final String PERMISSION_CAR_DIAGNOSTIC_CLEAR =
520             "android.car.permission.CLEAR_CAR_DIAGNOSTICS";
521 
522     /**
523      * Permission necessary to configure UX restrictions through {@link CarUxRestrictionsManager}.
524      *
525      * @hide
526      */
527     public static final String PERMISSION_CAR_UX_RESTRICTIONS_CONFIGURATION =
528             "android.car.permission.CAR_UX_RESTRICTIONS_CONFIGURATION";
529 
530     /**
531      * Permissions necessary to clear diagnostic information.
532      *
533      * @hide
534      */
535     @SystemApi
536     public static final String PERMISSION_STORAGE_MONITORING =
537             "android.car.permission.STORAGE_MONITORING";
538 
539     /**
540      * Permission necessary to enroll a device as a trusted authenticator device.
541      *
542      * @hide
543      */
544     @SystemApi
545     public static final String PERMISSION_CAR_ENROLL_TRUST =
546             "android.car.permission.CAR_ENROLL_TRUST";
547 
548     /** Type of car connection: platform runs directly in car. */
549     public static final int CONNECTION_TYPE_EMBEDDED = 5;
550 
551 
552     /** @hide */
553     @IntDef({CONNECTION_TYPE_EMBEDDED})
554     @Retention(RetentionPolicy.SOURCE)
555     public @interface ConnectionType {}
556 
557     /**
558      * Activity Action: Provide media playing through a media template app.
559      * <p>Input: String extra mapped by {@link android.app.SearchManager#QUERY} is the query
560      * used to start the media. String extra mapped by {@link #CAR_EXTRA_MEDIA_COMPONENT} is the
561      * component name of the media app which user wants to play media on.
562      * <p>Output: nothing.
563      */
564     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
565     public static final String CAR_INTENT_ACTION_MEDIA_TEMPLATE =
566             "android.car.intent.action.MEDIA_TEMPLATE";
567 
568     /**
569      * Used as a string extra field with {@link #CAR_INTENT_ACTION_MEDIA_TEMPLATE} to specify the
570      * MediaBrowserService that user wants to start the media on.
571      *
572      * @hide
573      */
574     public static final String CAR_EXTRA_MEDIA_COMPONENT =
575             "android.car.intent.extra.MEDIA_COMPONENT";
576 
577     /**
578      * Used as a string extra field with {@link #CAR_INTENT_ACTION_MEDIA_TEMPLATE} to specify the
579      * media app that user wants to start the media on. Note: this is not the templated media app.
580      *
581      * This is being deprecated. Use {@link #CAR_EXTRA_MEDIA_COMPONENT} instead.
582      */
583     public static final String CAR_EXTRA_MEDIA_PACKAGE = "android.car.intent.extra.MEDIA_PACKAGE";
584 
585     /**
586      * Used as a string extra field of media session to specify the service corresponding to the
587      * session.
588      *
589      * @hide
590      */
591     public static final String CAR_EXTRA_BROWSE_SERVICE_FOR_SESSION =
592             "android.media.session.BROWSE_SERVICE";
593 
594     /** @hide */
595     public static final String CAR_SERVICE_INTERFACE_NAME = "android.car.ICar";
596 
597     private static final String CAR_SERVICE_PACKAGE = "com.android.car";
598 
599     private static final String CAR_SERVICE_CLASS = "com.android.car.CarService";
600 
601     /**
602      * Category used by navigation applications to indicate which activity should be launched on
603      * the instrument cluster when such application holds
604      * {@link CarAppFocusManager#APP_FOCUS_TYPE_NAVIGATION} focus.
605      *
606      * @hide
607      */
608     public static final String CAR_CATEGORY_NAVIGATION = "android.car.cluster.NAVIGATION";
609 
610     /**
611      * When an activity is launched in the cluster, it will receive {@link ClusterActivityState} in
612      * the intent's extra under this key, containing instrument cluster information such as
613      * unobscured area, visibility, etc.
614      *
615      * @hide
616      */
617     @SystemApi
618     public static final String CAR_EXTRA_CLUSTER_ACTIVITY_STATE =
619             "android.car.cluster.ClusterActivityState";
620 
621 
622     /**
623      * Callback to notify the Lifecycle of car service.
624      *
625      * <p>Access to car service should happen
626      * after {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} call with
627      * {@code ready} set {@code true}.</p>
628      *
629      * <p>When {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} is
630      * called with ready set to false, access to car service should stop until car service is ready
631      * again from {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} call
632      * with {@code ready} set to {@code true}.</p>
633      * @hide
634      */
635     public interface CarServiceLifecycleListener {
636         /**
637          * Car service has gone through status change.
638          *
639          * <p>This is always called in the main thread context.</p>
640          *
641          * @param car {@code Car} object that was originally associated with this lister from
642          *            {@link #createCar(Context, Handler, long, Car.CarServiceLifecycleListener)}
643          *            call.
644          * @param ready When {@code true, car service is ready and all accesses are ok.
645          *              Otherwise car service has crashed or killed and will be restarted.
646          */
onLifecycleChanged(@onNull Car car, boolean ready)647         void onLifecycleChanged(@NonNull Car car, boolean ready);
648     }
649 
650     /**
651      * {@link #createCar(Context, Handler, long, CarServiceLifecycleListener)}'s
652      * waitTimeoutMs value to use to wait forever inside the call until car service is ready.
653      * @hide
654      */
655     public static final long CAR_WAIT_TIMEOUT_WAIT_FOREVER = -1;
656 
657     /**
658      * {@link #createCar(Context, Handler, long, CarServiceLifecycleListener)}'s
659      * waitTimeoutMs value to use to skip any waiting inside the call.
660      * @hide
661      */
662     public static final long CAR_WAIT_TIMEOUT_DO_NOT_WAIT = 0;
663 
664     private static final long CAR_SERVICE_BIND_RETRY_INTERVAL_MS = 500;
665     private static final long CAR_SERVICE_BIND_MAX_RETRY = 20;
666 
667     private static final long CAR_SERVICE_BINDER_POLLING_INTERVAL_MS = 50;
668     private static final long CAR_SERVICE_BINDER_POLLING_MAX_RETRY = 100;
669 
670     private static final int STATE_DISCONNECTED = 0;
671     private static final int STATE_CONNECTING = 1;
672     private static final int STATE_CONNECTED = 2;
673 
674     /** @hide */
675     @Retention(RetentionPolicy.SOURCE)
676     @IntDef(prefix = "STATE_", value = {
677             STATE_DISCONNECTED,
678             STATE_CONNECTING,
679             STATE_CONNECTED,
680     })
681     @Target({ElementType.TYPE_USE})
682     public @interface StateTypeEnum {}
683 
684     private static final boolean DBG = false;
685 
686     private final Context mContext;
687 
688     private final Exception mConstructionStack;
689 
690     private final Object mLock = new Object();
691 
692     @GuardedBy("mLock")
693     private ICar mService;
694     @GuardedBy("mLock")
695     private boolean mServiceBound;
696 
697     @GuardedBy("mLock")
698     @StateTypeEnum
699     private int mConnectionState;
700     @GuardedBy("mLock")
701     private int mConnectionRetryCount;
702 
703     private final Runnable mConnectionRetryRunnable = new Runnable() {
704         @Override
705         public void run() {
706             startCarService();
707         }
708     };
709 
710     private final Runnable mConnectionRetryFailedRunnable = new Runnable() {
711         @Override
712         public void run() {
713             mServiceConnectionListener.onServiceDisconnected(new ComponentName(CAR_SERVICE_PACKAGE,
714                     CAR_SERVICE_CLASS));
715         }
716     };
717 
718     private final ServiceConnection mServiceConnectionListener =
719             new ServiceConnection () {
720         @Override
721         public void onServiceConnected(ComponentName name, IBinder service) {
722             synchronized (mLock) {
723                 ICar newService = ICar.Stub.asInterface(service);
724                 if (newService == null) {
725                     Log.wtf(TAG_CAR, "null binder service", new RuntimeException());
726                     return;  // should not happen.
727                 }
728                 if (mService != null && mService.asBinder().equals(newService.asBinder())) {
729                     // already connected.
730                     return;
731                 }
732                 mConnectionState = STATE_CONNECTED;
733                 mService = newService;
734             }
735             if (mStatusChangeCallback != null) {
736                 mStatusChangeCallback.onLifecycleChanged(Car.this, true);
737             } else if (mServiceConnectionListenerClient != null) {
738                 mServiceConnectionListenerClient.onServiceConnected(name, service);
739             }
740         }
741 
742         @Override
743         public void onServiceDisconnected(ComponentName name) {
744             synchronized (mLock) {
745                 if (mConnectionState  == STATE_DISCONNECTED) {
746                     // can happen when client calls disconnect before onServiceDisconnected call.
747                     return;
748                 }
749                 handleCarDisconnectLocked();
750             }
751             if (mStatusChangeCallback != null) {
752                 mStatusChangeCallback.onLifecycleChanged(Car.this, false);
753             } else if (mServiceConnectionListenerClient != null) {
754                 mServiceConnectionListenerClient.onServiceDisconnected(name);
755             } else {
756                 // This client does not handle car service restart, so should be terminated.
757                 finishClient();
758             }
759         }
760     };
761 
762     @Nullable
763     private final ServiceConnection mServiceConnectionListenerClient;
764 
765     /** Can be added after ServiceManager.getService call */
766     @Nullable
767     private final CarServiceLifecycleListener mStatusChangeCallback;
768 
769     @GuardedBy("mLock")
770     private final HashMap<String, CarManagerBase> mServiceMap = new HashMap<>();
771 
772     /** Handler for generic event dispatching. */
773     private final Handler mEventHandler;
774 
775     private final Handler mMainThreadEventHandler;
776 
777     /**
778      * A factory method that creates Car instance for all Car API access.
779      * @param context App's Context. This should not be null. If you are passing
780      *                {@link ContextWrapper}, make sure that its base Context is non-null as well.
781      *                Otherwise it will throw {@link java.lang.NullPointerException}.
782      * @param serviceConnectionListener listener for monitoring service connection.
783      * @param handler the handler on which the callback should execute, or null to execute on the
784      * service's main thread. Note: the service connection listener will be always on the main
785      * thread regardless of the handler given.
786      * @return Car instance if system is in car environment and returns {@code null} otherwise.
787      *
788      * @deprecated use {@link #createCar(Context, Handler)} instead.
789      */
790     @Deprecated
createCar(Context context, ServiceConnection serviceConnectionListener, @Nullable Handler handler)791     public static Car createCar(Context context, ServiceConnection serviceConnectionListener,
792             @Nullable Handler handler) {
793         assertNonNullContext(context);
794         if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
795             Log.e(TAG_CAR, "FEATURE_AUTOMOTIVE not declared while android.car is used");
796             return null;
797         }
798         try {
799             return new Car(context, /* service= */ null , serviceConnectionListener,
800                     /* statusChangeListener= */ null, handler);
801         } catch (IllegalArgumentException e) {
802             // Expected when car service loader is not available.
803         }
804         return null;
805     }
806 
807     /**
808      * A factory method that creates Car instance for all Car API access using main thread {@code
809      * Looper}.
810      *
811      * @see #createCar(Context, ServiceConnection, Handler)
812      *
813      * @deprecated use {@link #createCar(Context, Handler)} instead.
814      */
815     @Deprecated
createCar(Context context, ServiceConnection serviceConnectionListener)816     public static Car createCar(Context context, ServiceConnection serviceConnectionListener) {
817       return createCar(context, serviceConnectionListener, null);
818     }
819 
820     /**
821      * Creates new {@link Car} object which connected synchronously to Car Service and ready to use.
822      *
823      * @param context application's context
824      *
825      * @return Car object if operation succeeded, otherwise null.
826      */
827     @Nullable
createCar(Context context)828     public static Car createCar(Context context) {
829         return createCar(context, (Handler) null);
830     }
831 
832     /**
833      * Creates new {@link Car} object which connected synchronously to Car Service and ready to use.
834      *
835      * @param context App's Context. This should not be null. If you are passing
836      *                {@link ContextWrapper}, make sure that its base Context is non-null as well.
837      *                Otherwise it will throw {@link java.lang.NullPointerException}.
838      * @param handler the handler on which the manager's callbacks will be executed, or null to
839      * execute on the application's main thread.
840      *
841      * @return Car object if operation succeeded, otherwise null.
842      */
843     @Nullable
createCar(Context context, @Nullable Handler handler)844     public static Car createCar(Context context, @Nullable Handler handler) {
845         assertNonNullContext(context);
846         Car car = null;
847         IBinder service = null;
848         boolean started = false;
849         int retryCount = 0;
850         while (true) {
851             service = ServiceManager.getService(CAR_SERVICE_BINDER_SERVICE_NAME);
852             if (car == null) {
853                 // service can be still null. The constructor is safe for null service.
854                 car = new Car(context, ICar.Stub.asInterface(service),
855                         null /*serviceConnectionListener*/, null /*statusChangeListener*/, handler);
856             }
857             if (service != null) {
858                 if (!started) {  // specialization for most common case.
859                     // Do this to crash client when car service crashes.
860                     car.startCarService();
861                     return car;
862                 }
863                 break;
864             }
865             if (!started) {
866                 car.startCarService();
867                 started = true;
868             }
869             retryCount++;
870             if (retryCount > CAR_SERVICE_BINDER_POLLING_MAX_RETRY) {
871                 Log.e(TAG_CAR, "cannot get car_service, waited for car service (ms):"
872                                 + CAR_SERVICE_BINDER_POLLING_INTERVAL_MS
873                                 * CAR_SERVICE_BINDER_POLLING_MAX_RETRY,
874                         new RuntimeException());
875                 return null;
876             }
877             try {
878                 Thread.sleep(CAR_SERVICE_BINDER_POLLING_INTERVAL_MS);
879             } catch (InterruptedException e) {
880                 Log.e(CarLibLog.TAG_CAR, "interrupted while waiting for car_service",
881                         new RuntimeException());
882                 return null;
883             }
884         }
885         // Can be accessed from mServiceConnectionListener in main thread.
886         synchronized (car) {
887             if (car.mService == null) {
888                 car.mService = ICar.Stub.asInterface(service);
889                 Log.w(TAG_CAR,
890                         "waited for car_service (ms):"
891                                 + CAR_SERVICE_BINDER_POLLING_INTERVAL_MS * retryCount,
892                         new RuntimeException());
893             }
894             car.mConnectionState = STATE_CONNECTED;
895         }
896         return car;
897     }
898 
899     /**
900      * Creates new {@link Car} object with {@link CarServiceLifecycleListener}.
901      *
902      * <p> If car service is ready inside this call and if the caller is running in the main thread,
903      * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} will be called
904      * with ready set to be true. Otherwise,
905      * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} will be called
906      * from the main thread later. </p>
907      *
908      * <p>This call can block up to specified waitTimeoutMs to wait for car service to be ready.
909      * If car service is not ready within the given time, it will return a Car instance in
910      * disconnected state. Blocking main thread forever can lead into getting ANR (Application Not
911      * Responding) killing from system and should not be used if the app is supposed to survive
912      * across the crash / restart of car service. It can be still useful in case the app cannot do
913      * anything without car service being ready. In any waiting, if the thread is getting
914      * interrupted, it will return immediately.
915      * </p>
916      *
917      * <p>Note that returned {@link Car} object is not guaranteed to be connected when there is
918      * a limited timeout. Regardless of returned car being connected or not, it is recommended to
919      * implement all car related initialization inside
920      * {@link CarServiceLifecycleListener#onLifecycleChanged(Car, boolean)} and avoid the
921      * needs to check if returned {@link Car} is connected or not from returned {@link Car}.</p>
922      *
923      * @param context App's Context. This should not be null. If you are passing
924      *                {@link ContextWrapper}, make sure that its base Context is non-null as well.
925      *                Otherwise it will throw {@link java.lang.NullPointerException}.
926      * @param handler dispatches all Car*Manager events to this Handler. Exception is
927      *                {@link CarServiceLifecycleListener} which will be always dispatched to main
928      *                thread. Passing null leads into dispatching all Car*Manager callbacks to main
929      *                thread as well.
930      * @param waitTimeoutMs Setting this to {@link #CAR_WAIT_TIMEOUT_DO_NOT_WAIT} will guarantee
931      *                      that the API does not wait for the car service at all. Setting this to
932      *                      to {@link #CAR_WAIT_TIMEOUT_WAIT_FOREVER} will block the call forever
933      *                      until the car service is ready. Setting any positive value will be
934      *                      interpreted as timeout value.
935      *
936      * @hide
937      */
938     @NonNull
createCar(@onNull Context context, @Nullable Handler handler, long waitTimeoutMs, @NonNull CarServiceLifecycleListener statusChangeListener)939     public static Car createCar(@NonNull Context context,
940             @Nullable Handler handler, long waitTimeoutMs,
941             @NonNull CarServiceLifecycleListener statusChangeListener) {
942         assertNonNullContext(context);
943         Preconditions.checkNotNull(statusChangeListener);
944         Car car = null;
945         IBinder service = null;
946         boolean started = false;
947         int retryCount = 0;
948         long maxRetryCount = 0;
949         if (waitTimeoutMs > 0) {
950             maxRetryCount = waitTimeoutMs / CAR_SERVICE_BINDER_POLLING_INTERVAL_MS;
951             // at least wait once if it is positive value.
952             if (maxRetryCount == 0) {
953                 maxRetryCount = 1;
954             }
955         }
956         boolean isMainThread = Looper.myLooper() == Looper.getMainLooper();
957         while (true) {
958             service = ServiceManager.getService(CAR_SERVICE_BINDER_SERVICE_NAME);
959             if (car == null) {
960                 // service can be still null. The constructor is safe for null service.
961                 car = new Car(context, ICar.Stub.asInterface(service), null, statusChangeListener,
962                         handler);
963             }
964             if (service != null) {
965                 if (!started) {  // specialization for most common case : car service already ready
966                     car.dispatchCarReadyToMainThread(isMainThread);
967                     // Needs this for CarServiceLifecycleListener. Note that ServiceConnection
968                     // will skip the callback as valid mService is set already.
969                     car.startCarService();
970                     return car;
971                 }
972                 // service available after starting.
973                 break;
974             }
975             if (!started) {
976                 car.startCarService();
977                 started = true;
978             }
979             retryCount++;
980             if (waitTimeoutMs < 0 && retryCount >= CAR_SERVICE_BINDER_POLLING_MAX_RETRY
981                     && retryCount % CAR_SERVICE_BINDER_POLLING_MAX_RETRY == 0) {
982                 // Log warning if car service is not alive even for waiting forever case.
983                 Log.w(TAG_CAR, "car_service not ready, waited for car service (ms):"
984                                 + retryCount * CAR_SERVICE_BINDER_POLLING_INTERVAL_MS,
985                         new RuntimeException());
986             } else if (waitTimeoutMs >= 0 && retryCount > maxRetryCount) {
987                 if (waitTimeoutMs > 0) {
988                     Log.w(TAG_CAR, "car_service not ready, waited for car service (ms):"
989                                     + waitTimeoutMs,
990                             new RuntimeException());
991                 }
992                 return car;
993             }
994 
995             try {
996                 Thread.sleep(CAR_SERVICE_BINDER_POLLING_INTERVAL_MS);
997             } catch (InterruptedException e) {
998                 Thread.currentThread().interrupt();
999                 Log.w(TAG_CAR, "interrupted", new RuntimeException());
1000                 return car;
1001             }
1002         }
1003         // Can be accessed from mServiceConnectionListener in main thread.
1004         synchronized (car.mLock) {
1005             Log.w(TAG_CAR,
1006                     "waited for car_service (ms):"
1007                             + retryCount * CAR_SERVICE_BINDER_POLLING_INTERVAL_MS,
1008                     new RuntimeException());
1009             // ServiceConnection has handled everything.
1010             if (car.mService != null) {
1011                 return car;
1012             }
1013             // mService check in ServiceConnection prevents calling
1014             // onLifecycleChanged. So onLifecycleChanged should be called explicitly
1015             // but do it outside lock.
1016             car.mService = ICar.Stub.asInterface(service);
1017             car.mConnectionState = STATE_CONNECTED;
1018         }
1019         car.dispatchCarReadyToMainThread(isMainThread);
1020         return car;
1021     }
1022 
assertNonNullContext(Context context)1023     private static void assertNonNullContext(Context context) {
1024         Preconditions.checkNotNull(context);
1025         if (context instanceof ContextWrapper
1026                 && ((ContextWrapper) context).getBaseContext() == null) {
1027             throw new NullPointerException(
1028                     "ContextWrapper with null base passed as Context, forgot to set base Context?");
1029         }
1030     }
1031 
dispatchCarReadyToMainThread(boolean isMainThread)1032     private void dispatchCarReadyToMainThread(boolean isMainThread) {
1033         if (isMainThread) {
1034             mStatusChangeCallback.onLifecycleChanged(this, true);
1035         } else {
1036             // should dispatch to main thread.
1037             mMainThreadEventHandler.post(
1038                     () -> mStatusChangeCallback.onLifecycleChanged(this, true));
1039         }
1040     }
1041 
Car(Context context, @Nullable ICar service, @Nullable ServiceConnection serviceConnectionListener, @Nullable CarServiceLifecycleListener statusChangeListener, @Nullable Handler handler)1042     private Car(Context context, @Nullable ICar service,
1043             @Nullable ServiceConnection serviceConnectionListener,
1044             @Nullable CarServiceLifecycleListener statusChangeListener,
1045             @Nullable Handler handler) {
1046         mContext = context;
1047         mEventHandler = determineEventHandler(handler);
1048         mMainThreadEventHandler = determineMainThreadEventHandler(mEventHandler);
1049 
1050         mService = service;
1051         if (service != null) {
1052             mConnectionState = STATE_CONNECTED;
1053         } else {
1054             mConnectionState = STATE_DISCONNECTED;
1055         }
1056         mServiceConnectionListenerClient = serviceConnectionListener;
1057         mStatusChangeCallback = statusChangeListener;
1058         // Store construction stack so that client can get help when it crashes when car service
1059         // crashes.
1060         if (serviceConnectionListener == null && statusChangeListener == null) {
1061             mConstructionStack = new RuntimeException();
1062         } else {
1063             mConstructionStack = null;
1064         }
1065     }
1066 
1067     /**
1068      * Car constructor when ICar binder is already available. The binder can be null.
1069      * @hide
1070      */
Car(Context context, @Nullable ICar service, @Nullable Handler handler)1071     public Car(Context context, @Nullable ICar service, @Nullable Handler handler) {
1072         this(context, service, null /*serviceConnectionListener*/, null /*statusChangeListener*/,
1073                 handler);
1074     }
1075 
determineMainThreadEventHandler(Handler eventHandler)1076     private static Handler determineMainThreadEventHandler(Handler eventHandler) {
1077         Looper mainLooper = Looper.getMainLooper();
1078         return (eventHandler.getLooper() == mainLooper) ? eventHandler : new Handler(mainLooper);
1079     }
1080 
determineEventHandler(@ullable Handler handler)1081     private static Handler determineEventHandler(@Nullable Handler handler) {
1082         if (handler == null) {
1083             Looper looper = Looper.getMainLooper();
1084             handler = new Handler(looper);
1085         }
1086         return handler;
1087     }
1088 
1089     /**
1090      * Connect to car service. This can be called while it is disconnected.
1091      * @throws IllegalStateException If connection is still on-going from previous
1092      *         connect call or it is already connected
1093      *
1094      * @deprecated this method is not need if this object is created via
1095      * {@link #createCar(Context, Handler)}.
1096      */
1097     @Deprecated
connect()1098     public void connect() throws IllegalStateException {
1099         synchronized (mLock) {
1100             if (mConnectionState != STATE_DISCONNECTED) {
1101                 throw new IllegalStateException("already connected or connecting");
1102             }
1103             mConnectionState = STATE_CONNECTING;
1104             startCarService();
1105         }
1106     }
1107 
handleCarDisconnectLocked()1108     private void handleCarDisconnectLocked() {
1109         if (mConnectionState == STATE_DISCONNECTED) {
1110             // can happen when client calls disconnect with onServiceDisconnected already called.
1111             return;
1112         }
1113         mEventHandler.removeCallbacks(mConnectionRetryRunnable);
1114         mMainThreadEventHandler.removeCallbacks(mConnectionRetryFailedRunnable);
1115         mConnectionRetryCount = 0;
1116         tearDownCarManagersLocked();
1117         mService = null;
1118         mConnectionState = STATE_DISCONNECTED;
1119     }
1120 
1121     /**
1122      * Disconnect from car service. This can be called while disconnected. Once disconnect is
1123      * called, all Car*Managers from this instance becomes invalid, and
1124      * {@link Car#getCarManager(String)} will return different instance if it is connected again.
1125      */
disconnect()1126     public void disconnect() {
1127         synchronized (mLock) {
1128             handleCarDisconnectLocked();
1129             if (mServiceBound) {
1130                 mContext.unbindService(mServiceConnectionListener);
1131                 mServiceBound = false;
1132             }
1133         }
1134     }
1135 
1136     /**
1137      * Tells if it is connected to the service or not. This will return false if it is still
1138      * connecting.
1139      * @return
1140      */
isConnected()1141     public boolean isConnected() {
1142         synchronized (mLock) {
1143             return mService != null;
1144         }
1145     }
1146 
1147     /**
1148      * Tells if this instance is already connecting to car service or not.
1149      * @return
1150      */
isConnecting()1151     public boolean isConnecting() {
1152         synchronized (mLock) {
1153             return mConnectionState == STATE_CONNECTING;
1154         }
1155     }
1156 
1157     /** @hide */
1158     @VisibleForTesting
getServiceConnectionListener()1159     public ServiceConnection getServiceConnectionListener() {
1160         return mServiceConnectionListener;
1161     }
1162 
1163     /**
1164      * Get car specific service as in {@link Context#getSystemService(String)}. Returned
1165      * {@link Object} should be type-casted to the desired service.
1166      * For example, to get sensor service,
1167      * SensorManagerService sensorManagerService = car.getCarManager(Car.SENSOR_SERVICE);
1168      * @param serviceName Name of service that should be created like {@link #SENSOR_SERVICE}.
1169      * @return Matching service manager or null if there is no such service.
1170      */
1171     @Nullable
getCarManager(String serviceName)1172     public Object getCarManager(String serviceName) {
1173         CarManagerBase manager;
1174         synchronized (mLock) {
1175             if (mService == null) {
1176                 Log.w(TAG_CAR, "getCarManager not working while car service not ready");
1177                 return null;
1178             }
1179             manager = mServiceMap.get(serviceName);
1180             if (manager == null) {
1181                 try {
1182                     IBinder binder = mService.getCarService(serviceName);
1183                     if (binder == null) {
1184                         Log.w(TAG_CAR, "getCarManager could not get binder for service:"
1185                                 + serviceName);
1186                         return null;
1187                     }
1188                     manager = createCarManager(serviceName, binder);
1189                     if (manager == null) {
1190                         Log.w(TAG_CAR, "getCarManager could not create manager for service:"
1191                                         + serviceName);
1192                         return null;
1193                     }
1194                     mServiceMap.put(serviceName, manager);
1195                 } catch (RemoteException e) {
1196                     handleRemoteExceptionFromCarService(e);
1197                 }
1198             }
1199         }
1200         return manager;
1201     }
1202 
1203     /**
1204      * Return the type of currently connected car.
1205      * @return
1206      */
1207     @ConnectionType
getCarConnectionType()1208     public int getCarConnectionType() {
1209         return CONNECTION_TYPE_EMBEDDED;
1210     }
1211 
1212     /** @hide */
getContext()1213     Context getContext() {
1214         return mContext;
1215     }
1216 
1217     /** @hide */
getEventHandler()1218     Handler getEventHandler() {
1219         return mEventHandler;
1220     }
1221 
1222     /** @hide */
handleRemoteExceptionFromCarService(RemoteException e, T returnValue)1223     <T> T handleRemoteExceptionFromCarService(RemoteException e, T returnValue) {
1224         handleRemoteExceptionFromCarService(e);
1225         return returnValue;
1226     }
1227 
1228     /** @hide */
handleRemoteExceptionFromCarService(RemoteException e)1229     void handleRemoteExceptionFromCarService(RemoteException e) {
1230         if (e instanceof TransactionTooLargeException) {
1231             Log.w(TAG_CAR, "Car service threw TransactionTooLargeException", e);
1232             throw new CarTransactionException(e, "Car service threw TransactionTooLargException");
1233         } else {
1234             Log.w(TAG_CAR, "Car service has crashed", e);
1235         }
1236     }
1237 
1238 
finishClient()1239     private void finishClient() {
1240         if (mContext == null) {
1241             throw new IllegalStateException("Car service has crashed, null Context");
1242         }
1243         if (mContext instanceof Activity) {
1244             Activity activity = (Activity) mContext;
1245             if (!activity.isFinishing()) {
1246                 Log.w(TAG_CAR,
1247                         "Car service crashed, client not handling it, finish Activity, created "
1248                                 + "from " + mConstructionStack);
1249                 activity.finish();
1250             }
1251             return;
1252         } else if (mContext instanceof Service) {
1253             Service service = (Service) mContext;
1254             killClient(service.getPackageName() + "," + service.getClass().getSimpleName());
1255         } else {
1256             killClient(/* clientInfo= */ null);
1257         }
1258     }
1259 
killClient(@ullable String clientInfo)1260     private void killClient(@Nullable String clientInfo) {
1261         Log.w(TAG_CAR, "**Car service has crashed. Client(" + clientInfo + ") is not handling it."
1262                         + " Client should use Car.createCar(..., CarServiceLifecycleListener, .."
1263                         + ".) to handle it properly. Check pritned callstack to check where other "
1264                         + "version of Car.createCar() was called. Killing the client process**",
1265                 mConstructionStack);
1266         Process.killProcess(Process.myPid());
1267     }
1268 
1269     /** @hide */
handleRemoteExceptionFromCarService(Service service, RemoteException e, T returnValue)1270     public static <T> T handleRemoteExceptionFromCarService(Service service, RemoteException e,
1271             T returnValue) {
1272         handleRemoteExceptionFromCarService(service, e);
1273         return returnValue;
1274     }
1275 
1276     /** @hide */
handleRemoteExceptionFromCarService(Service service, RemoteException e)1277     public static  void handleRemoteExceptionFromCarService(Service service, RemoteException e) {
1278         if (e instanceof TransactionTooLargeException) {
1279             Log.w(TAG_CAR, "Car service threw TransactionTooLargeException, client:"
1280                     + service.getPackageName() + ","
1281                     + service.getClass().getSimpleName(), e);
1282             throw new CarTransactionException(e, "Car service threw TransactionTooLargeException, "
1283                 + "client: %s, %s", service.getPackageName(), service.getClass().getSimpleName());
1284         } else {
1285             Log.w(TAG_CAR, "Car service has crashed, client:"
1286                     + service.getPackageName() + ","
1287                     + service.getClass().getSimpleName(), e);
1288             service.stopSelf();
1289         }
1290     }
1291 
1292     @Nullable
createCarManager(String serviceName, IBinder binder)1293     private CarManagerBase createCarManager(String serviceName, IBinder binder) {
1294         CarManagerBase manager = null;
1295         switch (serviceName) {
1296             case AUDIO_SERVICE:
1297                 manager = new CarAudioManager(this, binder);
1298                 break;
1299             case SENSOR_SERVICE:
1300                 manager = new CarSensorManager(this, binder);
1301                 break;
1302             case INFO_SERVICE:
1303                 manager = new CarInfoManager(this, binder);
1304                 break;
1305             case APP_FOCUS_SERVICE:
1306                 manager = new CarAppFocusManager(this, binder);
1307                 break;
1308             case PACKAGE_SERVICE:
1309                 manager = new CarPackageManager(this, binder);
1310                 break;
1311             case CAR_NAVIGATION_SERVICE:
1312                 manager = new CarNavigationStatusManager(this, binder);
1313                 break;
1314             case CABIN_SERVICE:
1315                 manager = new CarCabinManager(this, binder);
1316                 break;
1317             case DIAGNOSTIC_SERVICE:
1318                 manager = new CarDiagnosticManager(this, binder);
1319                 break;
1320             case HVAC_SERVICE:
1321                 manager = new CarHvacManager(this, binder);
1322                 break;
1323             case POWER_SERVICE:
1324                 manager = new CarPowerManager(this, binder);
1325                 break;
1326             case PROJECTION_SERVICE:
1327                 manager = new CarProjectionManager(this, binder);
1328                 break;
1329             case PROPERTY_SERVICE:
1330                 manager = new CarPropertyManager(this, ICarProperty.Stub.asInterface(binder));
1331                 break;
1332             case VENDOR_EXTENSION_SERVICE:
1333                 manager = new CarVendorExtensionManager(this, binder);
1334                 break;
1335             case CAR_INSTRUMENT_CLUSTER_SERVICE:
1336                 manager = new CarInstrumentClusterManager(this, binder);
1337                 break;
1338             case TEST_SERVICE:
1339                 /* CarTestManager exist in static library. So instead of constructing it here,
1340                  * only pass binder wrapper so that CarTestManager can be constructed outside. */
1341                 manager = new CarTestManagerBinderWrapper(this, binder);
1342                 break;
1343             case VMS_SUBSCRIBER_SERVICE:
1344                 manager = new VmsSubscriberManager(this, binder);
1345                 break;
1346             case BLUETOOTH_SERVICE:
1347                 manager = new CarBluetoothManager(this, binder);
1348                 break;
1349             case STORAGE_MONITORING_SERVICE:
1350                 manager = new CarStorageMonitoringManager(this, binder);
1351                 break;
1352             case CAR_DRIVING_STATE_SERVICE:
1353                 manager = new CarDrivingStateManager(this, binder);
1354                 break;
1355             case CAR_UX_RESTRICTION_SERVICE:
1356                 manager = new CarUxRestrictionsManager(this, binder);
1357                 break;
1358             case CAR_CONFIGURATION_SERVICE:
1359                 manager = new CarConfigurationManager(this, binder);
1360                 break;
1361             case CAR_TRUST_AGENT_ENROLLMENT_SERVICE:
1362                 manager = new CarTrustAgentEnrollmentManager(this, binder);
1363                 break;
1364             case CAR_MEDIA_SERVICE:
1365                 manager = new CarMediaManager(this, binder);
1366                 break;
1367             case CAR_BUGREPORT_SERVICE:
1368                 manager = new CarBugreportManager(this, binder);
1369                 break;
1370             default:
1371                 break;
1372         }
1373         return manager;
1374     }
1375 
startCarService()1376     private void startCarService() {
1377         Intent intent = new Intent();
1378         intent.setPackage(CAR_SERVICE_PACKAGE);
1379         intent.setAction(Car.CAR_SERVICE_INTERFACE_NAME);
1380         boolean bound = mContext.bindServiceAsUser(intent, mServiceConnectionListener,
1381                 Context.BIND_AUTO_CREATE, UserHandle.CURRENT_OR_SELF);
1382         synchronized (mLock) {
1383             if (!bound) {
1384                 mConnectionRetryCount++;
1385                 if (mConnectionRetryCount > CAR_SERVICE_BIND_MAX_RETRY) {
1386                     Log.w(TAG_CAR, "cannot bind to car service after max retry");
1387                     mMainThreadEventHandler.post(mConnectionRetryFailedRunnable);
1388                 } else {
1389                     mEventHandler.postDelayed(mConnectionRetryRunnable,
1390                             CAR_SERVICE_BIND_RETRY_INTERVAL_MS);
1391                 }
1392             } else {
1393                 mEventHandler.removeCallbacks(mConnectionRetryRunnable);
1394                 mMainThreadEventHandler.removeCallbacks(mConnectionRetryFailedRunnable);
1395                 mConnectionRetryCount = 0;
1396                 mServiceBound = true;
1397             }
1398         }
1399     }
1400 
tearDownCarManagersLocked()1401     private void tearDownCarManagersLocked() {
1402         // All disconnected handling should be only doing its internal cleanup.
1403         for (CarManagerBase manager: mServiceMap.values()) {
1404             manager.onCarDisconnected();
1405         }
1406         mServiceMap.clear();
1407     }
1408 }
1409