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