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 android.annotation.IntDef; 20 import android.annotation.Nullable; 21 import android.annotation.SdkConstant; 22 import android.annotation.SdkConstant.SdkConstantType; 23 import android.annotation.SystemApi; 24 import android.car.cluster.CarInstrumentClusterManager; 25 import android.car.cluster.ClusterActivityState; 26 import android.car.content.pm.CarPackageManager; 27 import android.car.diagnostic.CarDiagnosticManager; 28 import android.car.drivingstate.CarDrivingStateManager; 29 import android.car.drivingstate.CarUxRestrictionsManager; 30 import android.car.hardware.CarSensorManager; 31 import android.car.hardware.CarVendorExtensionManager; 32 import android.car.hardware.cabin.CarCabinManager; 33 import android.car.hardware.hvac.CarHvacManager; 34 import android.car.hardware.power.CarPowerManager; 35 import android.car.hardware.property.CarPropertyManager; 36 import android.car.hardware.property.ICarProperty; 37 import android.car.media.CarAudioManager; 38 import android.car.media.CarMediaManager; 39 import android.car.navigation.CarNavigationStatusManager; 40 import android.car.settings.CarConfigurationManager; 41 import android.car.storagemonitoring.CarStorageMonitoringManager; 42 import android.car.test.CarTestManagerBinderWrapper; 43 import android.car.trust.CarTrustAgentEnrollmentManager; 44 import android.car.vms.VmsSubscriberManager; 45 import android.content.ComponentName; 46 import android.content.Context; 47 import android.content.Intent; 48 import android.content.ServiceConnection; 49 import android.content.pm.PackageManager; 50 import android.os.Handler; 51 import android.os.IBinder; 52 import android.os.Looper; 53 import android.os.RemoteException; 54 import android.os.ServiceManager; 55 import android.os.UserHandle; 56 import android.util.Log; 57 58 import com.android.internal.annotations.GuardedBy; 59 60 import java.lang.annotation.Retention; 61 import java.lang.annotation.RetentionPolicy; 62 import java.util.HashMap; 63 64 /** 65 * Top level car API for embedded Android Auto deployments. 66 * This API works only for devices with {@link PackageManager#FEATURE_AUTOMOTIVE} 67 * Calling this API on a device with no such feature will lead to an exception. 68 */ 69 public final class Car { 70 /** 71 * Service name for {@link CarSensorManager}, to be used in {@link #getCarManager(String)}. 72 * 73 * @deprecated {@link CarSensorManager} is deprecated. Use {@link CarPropertyManager} instead. 74 */ 75 @Deprecated 76 public static final String SENSOR_SERVICE = "sensor"; 77 78 /** Service name for {@link CarInfoManager}, to be used in {@link #getCarManager(String)}. */ 79 public static final String INFO_SERVICE = "info"; 80 81 /** Service name for {@link CarAppFocusManager}. */ 82 public static final String APP_FOCUS_SERVICE = "app_focus"; 83 84 /** Service name for {@link CarPackageManager} */ 85 public static final String PACKAGE_SERVICE = "package"; 86 87 /** Service name for {@link CarAudioManager} */ 88 public static final String AUDIO_SERVICE = "audio"; 89 90 /** Service name for {@link CarNavigationStatusManager} */ 91 public static final String CAR_NAVIGATION_SERVICE = "car_navigation_service"; 92 93 /** 94 * Service name for {@link CarInstrumentClusterManager} 95 * 96 * @deprecated CarInstrumentClusterManager is being deprecated 97 * @hide 98 */ 99 @Deprecated 100 public static final String CAR_INSTRUMENT_CLUSTER_SERVICE = "cluster_service"; 101 102 /** 103 * Service name for {@link CarCabinManager}. 104 * 105 * @deprecated {@link CarCabinManager} is deprecated. Use {@link CarPropertyManager} instead. 106 * @hide 107 */ 108 @Deprecated 109 @SystemApi 110 public static final String CABIN_SERVICE = "cabin"; 111 112 /** 113 * @hide 114 */ 115 @SystemApi 116 public static final String DIAGNOSTIC_SERVICE = "diagnostic"; 117 118 /** 119 * Service name for {@link CarHvacManager} 120 * @deprecated {@link CarHvacManager} is deprecated. Use {@link CarPropertyManager} instead. 121 * @hide 122 */ 123 @Deprecated 124 @SystemApi 125 public static final String HVAC_SERVICE = "hvac"; 126 127 /** 128 * @hide 129 */ 130 @SystemApi 131 public static final String POWER_SERVICE = "power"; 132 133 /** 134 * @hide 135 */ 136 @SystemApi 137 public static final String PROJECTION_SERVICE = "projection"; 138 139 /** 140 * Service name for {@link CarPropertyManager} 141 */ 142 public static final String PROPERTY_SERVICE = "property"; 143 144 /** 145 * Service name for {@link CarVendorExtensionManager} 146 * 147 * @deprecated {@link CarVendorExtensionManager} is deprecated. 148 * Use {@link CarPropertyManager} instead. 149 * @hide 150 */ 151 @Deprecated 152 @SystemApi 153 public static final String VENDOR_EXTENSION_SERVICE = "vendor_extension"; 154 155 /** 156 * @hide 157 */ 158 public static final String BLUETOOTH_SERVICE = "car_bluetooth"; 159 160 /** 161 * @hide 162 */ 163 @SystemApi 164 public static final String VMS_SUBSCRIBER_SERVICE = "vehicle_map_subscriber_service"; 165 166 /** 167 * Service name for {@link CarDrivingStateManager} 168 * @hide 169 */ 170 @SystemApi 171 public static final String CAR_DRIVING_STATE_SERVICE = "drivingstate"; 172 173 /** 174 * Service name for {@link CarUxRestrictionsManager} 175 */ 176 public static final String CAR_UX_RESTRICTION_SERVICE = "uxrestriction"; 177 178 /** 179 * Service name for {@link android.car.settings.CarConfigurationManager} 180 */ 181 public static final String CAR_CONFIGURATION_SERVICE = "configuration"; 182 183 /** 184 * Service name for {@link android.car.media.CarMediaManager} 185 * @hide 186 */ 187 public static final String CAR_MEDIA_SERVICE = "car_media"; 188 189 /** 190 * 191 * Service name for {@link android.car.CarBugreportManager} 192 * @hide 193 */ 194 public static final String CAR_BUGREPORT_SERVICE = "car_bugreport"; 195 196 /** 197 * @hide 198 */ 199 @SystemApi 200 public static final String STORAGE_MONITORING_SERVICE = "storage_monitoring"; 201 202 /** 203 * Service name for {@link android.car.trust.CarTrustAgentEnrollmentManager} 204 * @hide 205 */ 206 @SystemApi 207 public static final String CAR_TRUST_AGENT_ENROLLMENT_SERVICE = "trust_enroll"; 208 209 /** 210 * Service for testing. This is system app only feature. 211 * Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}. 212 * @hide 213 */ 214 @SystemApi 215 public static final String TEST_SERVICE = "car-service-test"; 216 217 /** Permission necessary to access car's mileage information. 218 * @hide 219 */ 220 @SystemApi 221 public static final String PERMISSION_MILEAGE = "android.car.permission.CAR_MILEAGE"; 222 223 /** Permission necessary to access car's energy information. */ 224 public static final String PERMISSION_ENERGY = "android.car.permission.CAR_ENERGY"; 225 226 /** Permission necessary to access car's VIN information */ 227 public static final String PERMISSION_IDENTIFICATION = 228 "android.car.permission.CAR_IDENTIFICATION"; 229 230 /** Permission necessary to access car's speed. */ 231 public static final String PERMISSION_SPEED = "android.car.permission.CAR_SPEED"; 232 233 /** Permission necessary to access car's dynamics state. 234 * @hide 235 */ 236 @SystemApi 237 public static final String PERMISSION_CAR_DYNAMICS_STATE = 238 "android.car.permission.CAR_DYNAMICS_STATE"; 239 240 /** Permission necessary to access car's fuel door and ev charge port. */ 241 public static final String PERMISSION_ENERGY_PORTS = "android.car.permission.CAR_ENERGY_PORTS"; 242 243 /** Permission necessary to read car's exterior lights information. 244 * @hide 245 */ 246 @SystemApi 247 public static final String PERMISSION_EXTERIOR_LIGHTS = 248 "android.car.permission.CAR_EXTERIOR_LIGHTS"; 249 250 /** 251 * Permission necessary to read car's interior lights information. 252 */ 253 public static final String PERMISSION_READ_INTERIOR_LIGHTS = 254 "android.car.permission.READ_CAR_INTERIOR_LIGHTS"; 255 256 /** Permission necessary to control car's exterior lights. 257 * @hide 258 */ 259 @SystemApi 260 public static final String PERMISSION_CONTROL_EXTERIOR_LIGHTS = 261 "android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS"; 262 263 /** 264 * Permission necessary to control car's interior lights. 265 */ 266 public static final String PERMISSION_CONTROL_INTERIOR_LIGHTS = 267 "android.car.permission.CONTROL_CAR_INTERIOR_LIGHTS"; 268 269 /** Permission necessary to access car's powertrain information.*/ 270 public static final String PERMISSION_POWERTRAIN = "android.car.permission.CAR_POWERTRAIN"; 271 272 /** 273 * Permission necessary to change car audio volume through {@link CarAudioManager}. 274 */ 275 public static final String PERMISSION_CAR_CONTROL_AUDIO_VOLUME = 276 "android.car.permission.CAR_CONTROL_AUDIO_VOLUME"; 277 278 /** 279 * Permission necessary to change car audio settings through {@link CarAudioManager}. 280 */ 281 public static final String PERMISSION_CAR_CONTROL_AUDIO_SETTINGS = 282 "android.car.permission.CAR_CONTROL_AUDIO_SETTINGS"; 283 284 /** 285 * Permission necessary to receive full audio ducking events from car audio focus handler. 286 * 287 * @hide 288 */ 289 @SystemApi 290 public static final String PERMISSION_RECEIVE_CAR_AUDIO_DUCKING_EVENTS = 291 "android.car.permission.RECEIVE_CAR_AUDIO_DUCKING_EVENTS"; 292 293 /** 294 * Permission necessary to use {@link CarNavigationStatusManager}. 295 */ 296 public static final String PERMISSION_CAR_NAVIGATION_MANAGER = 297 "android.car.permission.CAR_NAVIGATION_MANAGER"; 298 299 /** 300 * Permission necessary to start activities in the instrument cluster through 301 * {@link CarInstrumentClusterManager} 302 * 303 * @hide 304 */ 305 @SystemApi 306 public static final String PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL = 307 "android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL"; 308 309 /** 310 * Application must have this permission in order to be launched in the instrument cluster 311 * display. 312 * 313 * @hide 314 */ 315 public static final String PERMISSION_CAR_DISPLAY_IN_CLUSTER = 316 "android.car.permission.CAR_DISPLAY_IN_CLUSTER"; 317 318 /** Permission necessary to use {@link CarInfoManager}. */ 319 public static final String PERMISSION_CAR_INFO = "android.car.permission.CAR_INFO"; 320 321 /** Permission necessary to read temperature of car's exterior environment. */ 322 public static final String PERMISSION_EXTERIOR_ENVIRONMENT = 323 "android.car.permission.CAR_EXTERIOR_ENVIRONMENT"; 324 325 /** 326 * Permission necessary to access car specific communication channel. 327 * @hide 328 */ 329 @SystemApi 330 public static final String PERMISSION_VENDOR_EXTENSION = 331 "android.car.permission.CAR_VENDOR_EXTENSION"; 332 333 /** 334 * @hide 335 */ 336 @SystemApi 337 public static final String PERMISSION_CONTROL_APP_BLOCKING = 338 "android.car.permission.CONTROL_APP_BLOCKING"; 339 340 /** 341 * Permission necessary to access car's engine information. 342 * @hide 343 */ 344 @SystemApi 345 public static final String PERMISSION_CAR_ENGINE_DETAILED = 346 "android.car.permission.CAR_ENGINE_DETAILED"; 347 348 /** 349 * Permission necessary to access car's tire pressure information. 350 * @hide 351 */ 352 @SystemApi 353 public static final String PERMISSION_TIRES = "android.car.permission.CAR_TIRES"; 354 355 /** 356 * Permission necessary to access car's steering angle information. 357 */ 358 public static final String PERMISSION_READ_STEERING_STATE = 359 "android.car.permission.READ_CAR_STEERING"; 360 361 /** 362 * Permission necessary to read and write display units for distance, fuel volume, tire pressure 363 * and ev battery. 364 */ 365 public static final String PERMISSION_READ_DISPLAY_UNITS = 366 "android.car.permission.READ_CAR_DISPLAY_UNITS"; 367 /** 368 * Permission necessary to control display units for distance, fuel volume, tire pressure 369 * and ev battery. 370 */ 371 public static final String PERMISSION_CONTROL_DISPLAY_UNITS = 372 "android.car.permission.CONTROL_CAR_DISPLAY_UNITS"; 373 374 /** 375 * Permission necessary to control car's door. 376 * @hide 377 */ 378 @SystemApi 379 public static final String PERMISSION_CONTROL_CAR_DOORS = 380 "android.car.permission.CONTROL_CAR_DOORS"; 381 382 /** 383 * Permission necessary to control car's windows. 384 * @hide 385 */ 386 @SystemApi 387 public static final String PERMISSION_CONTROL_CAR_WINDOWS = 388 "android.car.permission.CONTROL_CAR_WINDOWS"; 389 390 /** 391 * Permission necessary to control car's seats. 392 * @hide 393 */ 394 @SystemApi 395 public static final String PERMISSION_CONTROL_CAR_SEATS = 396 "android.car.permission.CONTROL_CAR_SEATS"; 397 398 /** 399 * Permission necessary to control car's mirrors. 400 * @hide 401 */ 402 @SystemApi 403 public static final String PERMISSION_CONTROL_CAR_MIRRORS = 404 "android.car.permission.CONTROL_CAR_MIRRORS"; 405 406 /** 407 * Permission necessary to access Car HVAC APIs. 408 * @hide 409 */ 410 @SystemApi 411 public static final String PERMISSION_CONTROL_CAR_CLIMATE = 412 "android.car.permission.CONTROL_CAR_CLIMATE"; 413 414 /** 415 * Permission necessary to access Car POWER APIs. 416 * @hide 417 */ 418 @SystemApi 419 public static final String PERMISSION_CAR_POWER = "android.car.permission.CAR_POWER"; 420 421 /** 422 * Permission necessary to access Car PROJECTION system APIs. 423 * @hide 424 */ 425 @SystemApi 426 public static final String PERMISSION_CAR_PROJECTION = "android.car.permission.CAR_PROJECTION"; 427 428 /** 429 * Permission necessary to access projection status. 430 * @hide 431 */ 432 @SystemApi 433 public static final String PERMISSION_CAR_PROJECTION_STATUS = 434 "android.car.permission.ACCESS_CAR_PROJECTION_STATUS"; 435 436 /** 437 * Permission necessary to mock vehicle hal for testing. 438 * @hide 439 * @deprecated mocking vehicle HAL in car service is no longer supported. 440 */ 441 @SystemApi 442 public static final String PERMISSION_MOCK_VEHICLE_HAL = 443 "android.car.permission.CAR_MOCK_VEHICLE_HAL"; 444 445 /** 446 * Permission necessary to access CarTestService. 447 * @hide 448 */ 449 @SystemApi 450 public static final String PERMISSION_CAR_TEST_SERVICE = 451 "android.car.permission.CAR_TEST_SERVICE"; 452 453 /** 454 * Permission necessary to access CarDrivingStateService to get a Car's driving state. 455 * @hide 456 */ 457 @SystemApi 458 public static final String PERMISSION_CAR_DRIVING_STATE = 459 "android.car.permission.CAR_DRIVING_STATE"; 460 461 /** 462 * Permission necessary to access VMS client service. 463 * 464 * @hide 465 */ 466 public static final String PERMISSION_BIND_VMS_CLIENT = 467 "android.car.permission.BIND_VMS_CLIENT"; 468 469 /** 470 * Permissions necessary to access VMS publisher APIs. 471 * 472 * @hide 473 */ 474 @SystemApi 475 public static final String PERMISSION_VMS_PUBLISHER = "android.car.permission.VMS_PUBLISHER"; 476 477 /** 478 * Permissions necessary to access VMS subscriber APIs. 479 * 480 * @hide 481 */ 482 @SystemApi 483 public static final String PERMISSION_VMS_SUBSCRIBER = "android.car.permission.VMS_SUBSCRIBER"; 484 485 /** 486 * Permissions necessary to read diagnostic information, including vendor-specific bits. 487 * 488 * @hide 489 */ 490 @SystemApi 491 public static final String PERMISSION_CAR_DIAGNOSTIC_READ_ALL = 492 "android.car.permission.CAR_DIAGNOSTICS"; 493 494 /** 495 * Permissions necessary to clear diagnostic information. 496 * 497 * @hide 498 */ 499 @SystemApi 500 public static final String PERMISSION_CAR_DIAGNOSTIC_CLEAR = 501 "android.car.permission.CLEAR_CAR_DIAGNOSTICS"; 502 503 /** 504 * Permission necessary to configure UX restrictions through {@link CarUxRestrictionsManager}. 505 * 506 * @hide 507 */ 508 public static final String PERMISSION_CAR_UX_RESTRICTIONS_CONFIGURATION = 509 "android.car.permission.CAR_UX_RESTRICTIONS_CONFIGURATION"; 510 511 /** 512 * Permissions necessary to clear diagnostic information. 513 * 514 * @hide 515 */ 516 @SystemApi 517 public static final String PERMISSION_STORAGE_MONITORING = 518 "android.car.permission.STORAGE_MONITORING"; 519 520 /** 521 * Permission necessary to enroll a device as a trusted authenticator device. 522 * 523 * @hide 524 */ 525 @SystemApi 526 public static final String PERMISSION_CAR_ENROLL_TRUST = 527 "android.car.permission.CAR_ENROLL_TRUST"; 528 529 /** Type of car connection: platform runs directly in car. */ 530 public static final int CONNECTION_TYPE_EMBEDDED = 5; 531 532 533 /** @hide */ 534 @IntDef({CONNECTION_TYPE_EMBEDDED}) 535 @Retention(RetentionPolicy.SOURCE) 536 public @interface ConnectionType {} 537 538 /** 539 * Activity Action: Provide media playing through a media template app. 540 * <p>Input: String extra mapped by {@link android.app.SearchManager#QUERY} is the query 541 * used to start the media. String extra mapped by {@link #CAR_EXTRA_MEDIA_PACKAGE} is the 542 * package name of the media app which user wants to play media on. 543 * <p>Output: nothing. 544 */ 545 @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) 546 public static final String CAR_INTENT_ACTION_MEDIA_TEMPLATE = 547 "android.car.intent.action.MEDIA_TEMPLATE"; 548 549 /** 550 * Used as a string extra field with {@link #CAR_INTENT_ACTION_MEDIA_TEMPLATE} to specify the 551 * media app that user wants to start the media on. Note: this is not the templated media app. 552 */ 553 public static final String CAR_EXTRA_MEDIA_PACKAGE = "android.car.intent.extra.MEDIA_PACKAGE"; 554 555 /** @hide */ 556 public static final String CAR_SERVICE_INTERFACE_NAME = "android.car.ICar"; 557 558 private static final String CAR_SERVICE_PACKAGE = "com.android.car"; 559 560 private static final String CAR_SERVICE_CLASS = "com.android.car.CarService"; 561 562 /** 563 * Category used by navigation applications to indicate which activity should be launched on 564 * the instrument cluster when such application holds 565 * {@link CarAppFocusManager#APP_FOCUS_TYPE_NAVIGATION} focus. 566 * 567 * @hide 568 */ 569 public static final String CAR_CATEGORY_NAVIGATION = "android.car.cluster.NAVIGATION"; 570 571 /** 572 * When an activity is launched in the cluster, it will receive {@link ClusterActivityState} in 573 * the intent's extra under this key, containing instrument cluster information such as 574 * unobscured area, visibility, etc. 575 * 576 * @hide 577 */ 578 @SystemApi 579 public static final String CAR_EXTRA_CLUSTER_ACTIVITY_STATE = 580 "android.car.cluster.ClusterActivityState"; 581 582 private static final long CAR_SERVICE_BIND_RETRY_INTERVAL_MS = 500; 583 private static final long CAR_SERVICE_BIND_MAX_RETRY = 20; 584 585 private final Context mContext; 586 @GuardedBy("this") 587 private ICar mService; 588 private final boolean mOwnsService; 589 private static final int STATE_DISCONNECTED = 0; 590 private static final int STATE_CONNECTING = 1; 591 private static final int STATE_CONNECTED = 2; 592 @GuardedBy("this") 593 private int mConnectionState; 594 @GuardedBy("this") 595 private int mConnectionRetryCount; 596 597 private final Runnable mConnectionRetryRunnable = new Runnable() { 598 @Override 599 public void run() { 600 startCarService(); 601 } 602 }; 603 604 private final Runnable mConnectionRetryFailedRunnable = new Runnable() { 605 @Override 606 public void run() { 607 mServiceConnectionListener.onServiceDisconnected(new ComponentName(CAR_SERVICE_PACKAGE, 608 CAR_SERVICE_CLASS)); 609 } 610 }; 611 612 private final ServiceConnection mServiceConnectionListener = 613 new ServiceConnection () { 614 public void onServiceConnected(ComponentName name, IBinder service) { 615 synchronized (Car.this) { 616 mService = ICar.Stub.asInterface(service); 617 mConnectionState = STATE_CONNECTED; 618 } 619 mServiceConnectionListenerClient.onServiceConnected(name, service); 620 } 621 622 public void onServiceDisconnected(ComponentName name) { 623 synchronized (Car.this) { 624 if (mConnectionState == STATE_DISCONNECTED) { 625 return; 626 } 627 } 628 // unbind explicitly and set connectionState to STATE_DISCONNECTED here. 629 disconnect(); 630 mServiceConnectionListenerClient.onServiceDisconnected(name); 631 } 632 }; 633 634 private final ServiceConnection mServiceConnectionListenerClient; 635 private final Object mCarManagerLock = new Object(); 636 @GuardedBy("mCarManagerLock") 637 private final HashMap<String, CarManagerBase> mServiceMap = new HashMap<>(); 638 639 /** Handler for generic event dispatching. */ 640 private final Handler mEventHandler; 641 642 private final Handler mMainThreadEventHandler; 643 644 /** 645 * A factory method that creates Car instance for all Car API access. 646 * @param context 647 * @param serviceConnectionListener listener for monitoring service connection. 648 * @param handler the handler on which the callback should execute, or null to execute on the 649 * service's main thread. Note: the service connection listener will be always on the main 650 * thread regardless of the handler given. 651 * @return Car instance if system is in car environment and returns {@code null} otherwise. 652 * 653 * @deprecated use {@link #createCar(Context, Handler)} instead. 654 */ 655 @Deprecated createCar(Context context, ServiceConnection serviceConnectionListener, @Nullable Handler handler)656 public static Car createCar(Context context, ServiceConnection serviceConnectionListener, 657 @Nullable Handler handler) { 658 if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 659 Log.e(CarLibLog.TAG_CAR, "FEATURE_AUTOMOTIVE not declared while android.car is used"); 660 return null; 661 } 662 try { 663 return new Car(context, serviceConnectionListener, handler); 664 } catch (IllegalArgumentException e) { 665 // Expected when car service loader is not available. 666 } 667 return null; 668 } 669 670 /** 671 * A factory method that creates Car instance for all Car API access using main thread {@code 672 * Looper}. 673 * 674 * @see #createCar(Context, ServiceConnection, Handler) 675 * 676 * @deprecated use {@link #createCar(Context, Handler)} instead. 677 */ 678 @Deprecated createCar(Context context, ServiceConnection serviceConnectionListener)679 public static Car createCar(Context context, ServiceConnection serviceConnectionListener) { 680 return createCar(context, serviceConnectionListener, null); 681 } 682 683 /** 684 * Creates new {@link Car} object which connected synchronously to Car Service and ready to use. 685 * 686 * @param context application's context 687 * 688 * @return Car object if operation succeeded, otherwise null. 689 */ 690 @Nullable createCar(Context context)691 public static Car createCar(Context context) { 692 return createCar(context, (Handler) null); 693 } 694 695 /** 696 * Creates new {@link Car} object which connected synchronously to Car Service and ready to use. 697 * 698 * @param context application's context 699 * @param handler the handler on which the manager's callbacks will be executed, or null to 700 * execute on the application's main thread. 701 * 702 * @return Car object if operation succeeded, otherwise null. 703 */ 704 @Nullable createCar(Context context, @Nullable Handler handler)705 public static Car createCar(Context context, @Nullable Handler handler) { 706 IBinder service = ServiceManager.getService("car_service"); 707 if (service == null) { 708 return null; 709 } 710 return new Car(context, ICar.Stub.asInterface(service), handler); 711 } 712 Car(Context context, ServiceConnection serviceConnectionListener, @Nullable Handler handler)713 private Car(Context context, ServiceConnection serviceConnectionListener, 714 @Nullable Handler handler) { 715 mContext = context; 716 mEventHandler = determineEventHandler(handler); 717 mMainThreadEventHandler = determineMainThreadEventHandler(mEventHandler); 718 719 mService = null; 720 mOwnsService = true; 721 mServiceConnectionListenerClient = serviceConnectionListener; 722 } 723 724 725 /** 726 * Car constructor when ICar binder is already available. 727 * @hide 728 */ Car(Context context, ICar service, @Nullable Handler handler)729 public Car(Context context, ICar service, @Nullable Handler handler) { 730 mContext = context; 731 mEventHandler = determineEventHandler(handler); 732 mMainThreadEventHandler = determineMainThreadEventHandler(mEventHandler); 733 734 mService = service; 735 mOwnsService = false; 736 mConnectionState = STATE_CONNECTED; 737 mServiceConnectionListenerClient = null; 738 } 739 determineMainThreadEventHandler(Handler eventHandler)740 private static Handler determineMainThreadEventHandler(Handler eventHandler) { 741 Looper mainLooper = Looper.getMainLooper(); 742 return (eventHandler.getLooper() == mainLooper) ? eventHandler : new Handler(mainLooper); 743 } 744 determineEventHandler(@ullable Handler handler)745 private static Handler determineEventHandler(@Nullable Handler handler) { 746 if (handler == null) { 747 Looper looper = Looper.getMainLooper(); 748 handler = new Handler(looper); 749 } 750 return handler; 751 } 752 753 /** 754 * Connect to car service. This can be called while it is disconnected. 755 * @throws IllegalStateException If connection is still on-going from previous 756 * connect call or it is already connected 757 * 758 * @deprecated this method is not need if this object is created via 759 * {@link #createCar(Context, Handler)}. 760 */ 761 @Deprecated connect()762 public void connect() throws IllegalStateException { 763 synchronized (this) { 764 if (mConnectionState != STATE_DISCONNECTED) { 765 throw new IllegalStateException("already connected or connecting"); 766 } 767 mConnectionState = STATE_CONNECTING; 768 startCarService(); 769 } 770 } 771 772 /** 773 * Disconnect from car service. This can be called while disconnected. Once disconnect is 774 * called, all Car*Managers from this instance becomes invalid, and 775 * {@link Car#getCarManager(String)} will return different instance if it is connected again. 776 */ disconnect()777 public void disconnect() { 778 synchronized (this) { 779 if (mConnectionState == STATE_DISCONNECTED) { 780 return; 781 } 782 mEventHandler.removeCallbacks(mConnectionRetryRunnable); 783 mMainThreadEventHandler.removeCallbacks(mConnectionRetryFailedRunnable); 784 mConnectionRetryCount = 0; 785 tearDownCarManagers(); 786 mService = null; 787 mConnectionState = STATE_DISCONNECTED; 788 789 if (mOwnsService) { 790 mContext.unbindService(mServiceConnectionListener); 791 } 792 } 793 } 794 795 /** 796 * Tells if it is connected to the service or not. This will return false if it is still 797 * connecting. 798 * @return 799 */ isConnected()800 public boolean isConnected() { 801 synchronized (this) { 802 return mService != null; 803 } 804 } 805 806 /** 807 * Tells if this instance is already connecting to car service or not. 808 * @return 809 */ isConnecting()810 public boolean isConnecting() { 811 synchronized (this) { 812 return mConnectionState == STATE_CONNECTING; 813 } 814 } 815 816 /** 817 * Get car specific service as in {@link Context#getSystemService(String)}. Returned 818 * {@link Object} should be type-casted to the desired service. 819 * For example, to get sensor service, 820 * SensorManagerService sensorManagerService = car.getCarManager(Car.SENSOR_SERVICE); 821 * @param serviceName Name of service that should be created like {@link #SENSOR_SERVICE}. 822 * @return Matching service manager or null if there is no such service. 823 */ 824 @Nullable getCarManager(String serviceName)825 public Object getCarManager(String serviceName) { 826 CarManagerBase manager; 827 ICar service = getICarOrThrow(); 828 synchronized (mCarManagerLock) { 829 manager = mServiceMap.get(serviceName); 830 if (manager == null) { 831 try { 832 IBinder binder = service.getCarService(serviceName); 833 if (binder == null) { 834 Log.w(CarLibLog.TAG_CAR, "getCarManager could not get binder for service:" + 835 serviceName); 836 return null; 837 } 838 manager = createCarManager(serviceName, binder); 839 if (manager == null) { 840 Log.w(CarLibLog.TAG_CAR, 841 "getCarManager could not create manager for service:" + 842 serviceName); 843 return null; 844 } 845 mServiceMap.put(serviceName, manager); 846 } catch (RemoteException e) { 847 throw e.rethrowFromSystemServer(); 848 } 849 } 850 } 851 return manager; 852 } 853 854 /** 855 * Return the type of currently connected car. 856 * @return 857 */ 858 @ConnectionType getCarConnectionType()859 public int getCarConnectionType() { 860 return CONNECTION_TYPE_EMBEDDED; 861 } 862 863 @Nullable createCarManager(String serviceName, IBinder binder)864 private CarManagerBase createCarManager(String serviceName, IBinder binder) { 865 CarManagerBase manager = null; 866 switch (serviceName) { 867 case AUDIO_SERVICE: 868 manager = new CarAudioManager(binder, mContext, mEventHandler); 869 break; 870 case SENSOR_SERVICE: 871 manager = new CarSensorManager(binder, mContext, mEventHandler); 872 break; 873 case INFO_SERVICE: 874 manager = new CarInfoManager(binder); 875 break; 876 case APP_FOCUS_SERVICE: 877 manager = new CarAppFocusManager(binder, mEventHandler); 878 break; 879 case PACKAGE_SERVICE: 880 manager = new CarPackageManager(binder, mContext); 881 break; 882 case CAR_NAVIGATION_SERVICE: 883 manager = new CarNavigationStatusManager(binder); 884 break; 885 case CABIN_SERVICE: 886 manager = new CarCabinManager(binder, mContext, mEventHandler); 887 break; 888 case DIAGNOSTIC_SERVICE: 889 manager = new CarDiagnosticManager(binder, mContext, mEventHandler); 890 break; 891 case HVAC_SERVICE: 892 manager = new CarHvacManager(binder, mContext, mEventHandler); 893 break; 894 case POWER_SERVICE: 895 manager = new CarPowerManager(binder, mContext, mEventHandler); 896 break; 897 case PROJECTION_SERVICE: 898 manager = new CarProjectionManager(binder, mEventHandler); 899 break; 900 case PROPERTY_SERVICE: 901 manager = new CarPropertyManager(ICarProperty.Stub.asInterface(binder), 902 mEventHandler); 903 break; 904 case VENDOR_EXTENSION_SERVICE: 905 manager = new CarVendorExtensionManager(binder, mEventHandler); 906 break; 907 case CAR_INSTRUMENT_CLUSTER_SERVICE: 908 manager = new CarInstrumentClusterManager(binder, mEventHandler); 909 break; 910 case TEST_SERVICE: 911 /* CarTestManager exist in static library. So instead of constructing it here, 912 * only pass binder wrapper so that CarTestManager can be constructed outside. */ 913 manager = new CarTestManagerBinderWrapper(binder); 914 break; 915 case VMS_SUBSCRIBER_SERVICE: 916 manager = new VmsSubscriberManager(binder); 917 break; 918 case BLUETOOTH_SERVICE: 919 manager = new CarBluetoothManager(binder, mContext); 920 break; 921 case STORAGE_MONITORING_SERVICE: 922 manager = new CarStorageMonitoringManager(binder, mEventHandler); 923 break; 924 case CAR_DRIVING_STATE_SERVICE: 925 manager = new CarDrivingStateManager(binder, mContext, mEventHandler); 926 break; 927 case CAR_UX_RESTRICTION_SERVICE: 928 manager = new CarUxRestrictionsManager(binder, mContext, mEventHandler); 929 break; 930 case CAR_CONFIGURATION_SERVICE: 931 manager = new CarConfigurationManager(binder); 932 break; 933 case CAR_TRUST_AGENT_ENROLLMENT_SERVICE: 934 manager = new CarTrustAgentEnrollmentManager(binder, mContext, mEventHandler); 935 break; 936 case CAR_MEDIA_SERVICE: 937 manager = new CarMediaManager(binder); 938 break; 939 case CAR_BUGREPORT_SERVICE: 940 manager = new CarBugreportManager(binder, mContext); 941 break; 942 default: 943 break; 944 } 945 return manager; 946 } 947 startCarService()948 private void startCarService() { 949 Intent intent = new Intent(); 950 intent.setPackage(CAR_SERVICE_PACKAGE); 951 intent.setAction(Car.CAR_SERVICE_INTERFACE_NAME); 952 boolean bound = mContext.bindServiceAsUser(intent, mServiceConnectionListener, 953 Context.BIND_AUTO_CREATE, UserHandle.CURRENT_OR_SELF); 954 if (!bound) { 955 mConnectionRetryCount++; 956 if (mConnectionRetryCount > CAR_SERVICE_BIND_MAX_RETRY) { 957 Log.w(CarLibLog.TAG_CAR, "cannot bind to car service after max retry"); 958 mMainThreadEventHandler.post(mConnectionRetryFailedRunnable); 959 } else { 960 mEventHandler.postDelayed(mConnectionRetryRunnable, 961 CAR_SERVICE_BIND_RETRY_INTERVAL_MS); 962 } 963 } else { 964 mConnectionRetryCount = 0; 965 } 966 } 967 getICarOrThrow()968 private synchronized ICar getICarOrThrow() throws IllegalStateException { 969 if (mService == null) { 970 throw new IllegalStateException("not connected"); 971 } 972 return mService; 973 } 974 tearDownCarManagers()975 private void tearDownCarManagers() { 976 synchronized (mCarManagerLock) { 977 for (CarManagerBase manager: mServiceMap.values()) { 978 manager.onCarDisconnected(); 979 } 980 mServiceMap.clear(); 981 } 982 } 983 } 984