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