1ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung/* 2ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Copyright (C) 2015 The Android Open Source Project 3ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * 4ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Licensed under the Apache License, Version 2.0 (the "License"); 5ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * you may not use this file except in compliance with the License. 6ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * You may obtain a copy of the License at 7ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * 8ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * http://www.apache.org/licenses/LICENSE-2.0 9ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * 10ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Unless required by applicable law or agreed to in writing, software 11ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * distributed under the License is distributed on an "AS IS" BASIS, 12ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * See the License for the specific language governing permissions and 14ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * limitations under the License. 15ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 16ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 17e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkpackage android.car; 18ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 19e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.annotation.IntDef; 20e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.annotation.Nullable; 21e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.annotation.SystemApi; 22e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortesimport android.car.annotation.FutureFeature; 236e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.content.pm.CarPackageManager; 245c56d2a3a5bc4ef5b46a58fa56b7f4a657b0827eEnrico Granataimport android.car.hardware.CarDiagnosticManager; 256e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.hardware.CarSensorManager; 26634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsevimport android.car.hardware.CarVendorExtensionManager; 270d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsevimport android.car.hardware.cabin.CarCabinManager; 286e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.hardware.hvac.CarHvacManager; 296e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.hardware.radio.CarRadioManager; 306e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.media.CarAudioManager; 313388e7848f3a30029935463afafe9b8280939127Keun-young Parkimport android.car.navigation.CarNavigationStatusManager; 326e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.test.CarTestManagerBinderWrapper; 33a7d8ed1681d297bdda8345c1598c7b9a388599beAntonio Cortesimport android.car.vms.VmsSubscriberManager; 34ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.content.ComponentName; 35ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.content.Context; 36e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.content.Intent; 37e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.content.ServiceConnection; 38ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.content.pm.PackageManager; 396b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoungimport android.os.Handler; 40ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.IBinder; 41ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.Looper; 42ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.RemoteException; 4344241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Parkimport android.os.UserHandle; 44ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.util.Log; 45ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 46c52d5f9f6190cf9a44dd6dfd3bc92386fbf023b3Antonio Cortesimport com.android.car.internal.FeatureConfiguration; 47c52d5f9f6190cf9a44dd6dfd3bc92386fbf023b3Antonio Cortesimport com.android.car.internal.FeatureUtil; 48e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport com.android.internal.annotations.GuardedBy; 49e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 50ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport java.lang.annotation.Retention; 51ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport java.lang.annotation.RetentionPolicy; 52ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport java.util.HashMap; 536b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung 54ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung/** 55e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup * Top level car API for embedded Android Auto deployments. 56e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup * This API works only for devices with {@link PackageManager#FEATURE_AUTOMOTIVE} 57e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup * Calling this API on a device with no such feature will lead to an exception. 58ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 594cf6911619b9fe6ffeba7afeb05299aab165f184Keun-young Parkpublic final class Car { 60ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 61f521fd7b917a63c240802c7f841fc04c315573d0Keun-young Park /** 6212cfa0d0d909df96c501546eec83bfa09515e3f8Keun-young Park * Represent the version of Car API. This is only updated when there is API change. 6312cfa0d0d909df96c501546eec83bfa09515e3f8Keun-young Park * 1 : N 6412cfa0d0d909df96c501546eec83bfa09515e3f8Keun-young Park * 2 : O 65f521fd7b917a63c240802c7f841fc04c315573d0Keun-young Park */ 6612cfa0d0d909df96c501546eec83bfa09515e3f8Keun-young Park public static final int VERSION = 2; 67f521fd7b917a63c240802c7f841fc04c315573d0Keun-young Park 68a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung /** Service name for {@link CarSensorManager}, to be used in {@link #getCarManager(String)}. */ 69ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public static final String SENSOR_SERVICE = "sensor"; 70ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 71a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung /** Service name for {@link CarInfoManager}, to be used in {@link #getCarManager(String)}. */ 72a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung public static final String INFO_SERVICE = "info"; 73a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung 743ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup /** Service name for {@link CarAppFocusManager}. */ 7546371473c416415fb6bcb8db85686669c3d65af6Vitalii Tomkiv public static final String APP_FOCUS_SERVICE = "app_focus"; 76a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung 777a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev /** Service name for {@link CarPackageManager} */ 7845fdcbaab5699d7d8153bfda058d0eea2049c8b8Keun-young Park public static final String PACKAGE_SERVICE = "package"; 7945fdcbaab5699d7d8153bfda058d0eea2049c8b8Keun-young Park 805672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Park /** Service name for {@link CarAudioManager} */ 815672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Park public static final String AUDIO_SERVICE = "audio"; 827a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev /** 833388e7848f3a30029935463afafe9b8280939127Keun-young Park * Service name for {@link CarNavigationStatusManager} 847a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev * @hide 857a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev */ 867a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev public static final String CAR_NAVIGATION_SERVICE = "car_navigation_service"; 877a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev 88280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 89280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 90280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 91e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 9243c04a7c87404d078db60e09d2da0061d72357c2Steve Paik public static final String CABIN_SERVICE = "cabin"; 9343c04a7c87404d078db60e09d2da0061d72357c2Steve Paik 9443c04a7c87404d078db60e09d2da0061d72357c2Steve Paik /** 9543c04a7c87404d078db60e09d2da0061d72357c2Steve Paik * @hide 9643c04a7c87404d078db60e09d2da0061d72357c2Steve Paik */ 975c56d2a3a5bc4ef5b46a58fa56b7f4a657b0827eEnrico Granata public static final String DIAGNOSTIC_SERVICE = "diagnostic"; 985c56d2a3a5bc4ef5b46a58fa56b7f4a657b0827eEnrico Granata 995c56d2a3a5bc4ef5b46a58fa56b7f4a657b0827eEnrico Granata /** 1005c56d2a3a5bc4ef5b46a58fa56b7f4a657b0827eEnrico Granata * @hide 1015c56d2a3a5bc4ef5b46a58fa56b7f4a657b0827eEnrico Granata */ 1025c56d2a3a5bc4ef5b46a58fa56b7f4a657b0827eEnrico Granata @SystemApi 103e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String RADIO_SERVICE = "radio"; 104ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 105280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 106280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 107280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 108e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 109e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String HVAC_SERVICE = "hvac"; 110e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 111280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 112280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 113280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 1146e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv @SystemApi 1156e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv public static final String PROJECTION_SERVICE = "projection"; 1166e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv 117e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** 118634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev * @hide 119634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev */ 120634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev @SystemApi 121634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev public static final String VENDOR_EXTENSION_SERVICE = "vendor_extension"; 122634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev 123634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev /** 124e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes * @FutureFeature Cannot drop due to usage in non-flag protected place. 125e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes * @hide 126e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes */ 127e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes @SystemApi 128e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes public static final String VMS_SUBSCRIBER_SERVICE = "vehicle_map_subscriber_service"; 129e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes 130e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes /** 131e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * Service for testing. This is system app only feature. 132e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}. 133e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * @hide 134e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park */ 135e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 136e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String TEST_SERVICE = "car-service-test"; 137ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 138ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** Permission necessary to access car's mileage information. */ 139e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_MILEAGE = "android.car.permission.CAR_MILEAGE"; 140e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 141ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** Permission necessary to access car's fuel level. */ 142e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_FUEL = "android.car.permission.CAR_FUEL"; 143e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 144ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** Permission necessary to access car's speed. */ 145e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_SPEED = "android.car.permission.CAR_SPEED"; 146e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 147ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** 148c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen * Permission necessary to change car audio volume through {@link CarAudioManager}. 149c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen */ 150c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen public static final String PERMISSION_CAR_CONTROL_AUDIO_VOLUME = 151c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen "android.car.permission.CAR_CONTROL_AUDIO_VOLUME"; 152c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen 153c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen /** 154fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * Permission necessary to change car audio settings through {@link CarAudioManager}. 155fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * @hide 156fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park */ 157fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public static final String PERMISSION_CAR_CONTROL_AUDIO_SETTINGS = 158fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park "android.car.permission.CAR_CONTROL_AUDIO_SETTINGS"; 159fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 160fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park /** 1613388e7848f3a30029935463afafe9b8280939127Keun-young Park * Permission necessary to use {@link CarNavigationStatusManager}. 162ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev * @hide 163ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev */ 164ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev public static final String PERMISSION_CAR_NAVIGATION_MANAGER = 165e31a8b24afe58bfc924fab7b66c9e48b9ef8e884Keun-young Park "android.car.permission.CAR_NAVIGATION_MANAGER"; 166ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev 167280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 168280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access car specific communication channel. 169280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 170280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 171e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 172ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public static final String PERMISSION_VENDOR_EXTENSION = 173e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park "android.car.permission.CAR_VENDOR_EXTENSION"; 174e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 175280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 176280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 177280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 178e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 1794aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park public static final String PERMISSION_CONTROL_APP_BLOCKING = 180e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park "android.car.permission.CONTROL_APP_BLOCKING"; 181ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 182280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 18343c04a7c87404d078db60e09d2da0061d72357c2Steve Paik * Permission necessary to access Car Cabin APIs. 18443c04a7c87404d078db60e09d2da0061d72357c2Steve Paik * @hide 18543c04a7c87404d078db60e09d2da0061d72357c2Steve Paik */ 18643c04a7c87404d078db60e09d2da0061d72357c2Steve Paik @SystemApi 18743c04a7c87404d078db60e09d2da0061d72357c2Steve Paik public static final String PERMISSION_CAR_CABIN = "android.car.permission.CAR_CABIN"; 18843c04a7c87404d078db60e09d2da0061d72357c2Steve Paik 18943c04a7c87404d078db60e09d2da0061d72357c2Steve Paik /** 190280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access Car HVAC APIs. 191280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 192280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 193e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 194e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_CAR_HVAC = "android.car.permission.CAR_HVAC"; 195ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 196280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 197280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access Car RADIO system APIs. 198280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 199280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 200e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 201e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_CAR_RADIO = "android.car.permission.CAR_RADIO"; 202ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 203b13dbe470108846d1c04494c5c0d2bf3cd9b8054Jason Tholstrup 204280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 205b13dbe470108846d1c04494c5c0d2bf3cd9b8054Jason Tholstrup * Permission necessary to access Car PROJECTION system APIs. 206280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 207280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 2086e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv @SystemApi 2096e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv public static final String PERMISSION_CAR_PROJECTION = "android.car.permission.CAR_PROJECTION"; 2106e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv 211280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 212280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to mock vehicle hal for testing. 213280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 2140d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev * @deprecated mocking vehicle HAL in car service is no longer supported. 215280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 216e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 217e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_MOCK_VEHICLE_HAL = 218e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park "android.car.permission.CAR_MOCK_VEHICLE_HAL"; 219e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 2201ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev /** 2210d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev * Permission necessary to access CarTestService. 2221ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev * @hide 2231ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev */ 2240d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev @SystemApi 2250d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev public static final String PERMISSION_CAR_TEST_SERVICE = 2260d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev "android.car.permission.CAR_TEST_SERVICE"; 2270d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev 228e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes /** 2296b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes * Permissions necessary to access VMS publisher APIs. 2306b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes * 2316b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes * @hide 2326b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes */ 2336b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes @FutureFeature 2346b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes @SystemApi 2356b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes public static final String PERMISSION_VMS_PUBLISHER = "android.car.permission.VMS_PUBLISHER"; 2366b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes 2376b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes /** 2386b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes * Permissions necessary to access VMS subscriber APIs. 2396b3544cf13ee99d6704216c96d40f89aff9bdc2bAntonio Cortes * 240e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes * @hide 241e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes */ 242e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes @FutureFeature 243e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes @SystemApi 244e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes public static final String PERMISSION_VMS_SUBSCRIBER = "android.car.permission.VMS_SUBSCRIBER"; 245e4619c7bdd549833cb795b74e438a7d1f3caa1b5Antonio Cortes 2463c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata /** 2473c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata * Permissions necessary to read diagnostic information. 2483c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata * 2493c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata * @hide 2503c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata */ 2513c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata @FutureFeature 2523c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata public static final String PERMISSION_CAR_DIAGNOSTIC_READ = "android.car.permission.DIAGNOSTIC_READ"; 2533c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata 2543c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata /** 2553c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata * Permissions necessary to clear diagnostic information. 2563c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata * 2573c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata * @hide 2583c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata */ 2593c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata @FutureFeature 2603c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata public static final String PERMISSION_CAR_DIAGNOSTIC_CLEAR = "android.car.permission.DIAGNOSTIC_CLEAR"; 2613c7a66693e28acaa82d3c9ff2ed99712270c889fEnrico Granata 2620d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev /** Type of car connection: platform runs directly in car. */ 2630d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev public static final int CONNECTION_TYPE_EMBEDDED = 5; 264e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 265e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup 266e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** @hide */ 2670d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev @IntDef({CONNECTION_TYPE_EMBEDDED}) 268e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @Retention(RetentionPolicy.SOURCE) 269e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public @interface ConnectionType {} 270ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 2713cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal /** 2723cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * CarXyzService throws IllegalStateException with this message is re-thrown as 2733cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * {@link CarNotConnectedException}. 2743cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 2753cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * @hide 2763cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal */ 2773cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public static final String CAR_NOT_CONNECTED_EXCEPTION_MSG = "CarNotConnected"; 2783cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 279e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** @hide */ 280e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String CAR_SERVICE_INTERFACE_NAME = "android.car.ICar"; 281e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 282e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private static final String CAR_SERVICE_PACKAGE = "com.android.car"; 283e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 28444241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private static final String CAR_SERVICE_CLASS = "com.android.car.CarService"; 28544241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park 28644241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private static final long CAR_SERVICE_BIND_RETRY_INTERVAL_MS = 500; 28744241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private static final long CAR_SERVICE_BIND_MAX_RETRY = 20; 28844241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park 289ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private final Context mContext; 290ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @GuardedBy("this") 291ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private ICar mService; 2920d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev private final boolean mOwnsService; 293ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private static final int STATE_DISCONNECTED = 0; 294ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private static final int STATE_CONNECTING = 1; 295ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private static final int STATE_CONNECTED = 2; 296ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @GuardedBy("this") 297ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private int mConnectionState; 29844241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park @GuardedBy("this") 29944241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private int mConnectionRetryCount; 30044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park 30144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private final Runnable mConnectionRetryRunnable = new Runnable() { 30244241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park @Override 30344241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park public void run() { 30444241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park startCarService(); 30544241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } 30644241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park }; 30744241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park 30844241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private final Runnable mConnectionRetryFailedRunnable = new Runnable() { 30944241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park @Override 31044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park public void run() { 31144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mServiceConnectionListener.onServiceDisconnected(new ComponentName(CAR_SERVICE_PACKAGE, 31244241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park CAR_SERVICE_CLASS)); 31344241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } 31444241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park }; 315ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 316e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private final ServiceConnection mServiceConnectionListener = 317e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park new ServiceConnection () { 318ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void onServiceConnected(ComponentName name, IBinder service) { 3191ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung synchronized (Car.this) { 320ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = ICar.Stub.asInterface(service); 321ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_CONNECTED; 322ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 323ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient.onServiceConnected(name, service); 324ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 325ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 326ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void onServiceDisconnected(ComponentName name) { 3271ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung synchronized (Car.this) { 328ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = null; 329ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mConnectionState == STATE_DISCONNECTED) { 330ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return; 331ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 332cc449f7941456a0133ff8a4b2e49737f0936c1d0keunyoung mConnectionState = STATE_DISCONNECTED; 333ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 334e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park // unbind explicitly here. 335e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park disconnect(); 336ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient.onServiceDisconnected(name); 337ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 338ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung }; 339ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 340e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private final ServiceConnection mServiceConnectionListenerClient; 341ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private final Object mCarManagerLock = new Object(); 342ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @GuardedBy("mCarManagerLock") 343ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private final HashMap<String, CarManagerBase> mServiceMap = new HashMap<>(); 3446b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung 3456b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung /** Handler for generic event dispatching. */ 3466b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung private final Handler mEventHandler; 3476b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung 3483ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup private final Handler mMainThreadEventHandler; 34944241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park 3501ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung /** 3518de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * A factory method that creates Car instance for all Car API access. 352ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @param context 353e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * @param serviceConnectionListener listener for monitoring service connection. 3543ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup * @param handler the handler on which the callback should execute, or null to execute on the 3553ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup * service's main thread. Note: the service connection listener will be always on the main 3563ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup * thread regardless of the handler given. 3578de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * @return Car instance if system is in car environment and returns {@code null} otherwise. 358ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 359e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static Car createCar(Context context, ServiceConnection serviceConnectionListener, 3603ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup @Nullable Handler handler) { 361e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 362e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park Log.e(CarLibLog.TAG_CAR, "FEATURE_AUTOMOTIVE not declared while android.car is used"); 363e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park return null; 364e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 3658de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev try { 3663ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup return new Car(context, serviceConnectionListener, handler); 3678de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } catch (IllegalArgumentException e) { 3688de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev // Expected when car service loader is not available. 3698de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } 3708de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev return null; 3718de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } 3728de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev 3738de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev /** 3748de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * A factory method that creates Car instance for all Car API access using main thread {@code 3758de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * Looper}. 3768de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * 3773ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup * @see #createCar(Context, ServiceConnection, Handler) 3788de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev */ 379e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static Car createCar(Context context, ServiceConnection serviceConnectionListener) { 3808de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev return createCar(context, serviceConnectionListener, null); 3818de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } 3828de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev 383e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private Car(Context context, ServiceConnection serviceConnectionListener, 3843ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup @Nullable Handler handler) { 385ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mContext = context; 3863ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup mEventHandler = determineEventHandler(handler); 387224220701b9c22ebcfc7dc532714839dca202bb3Yao Chen mMainThreadEventHandler = determineMainThreadEventHandler(mEventHandler); 3883ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup 3893ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup mService = null; 3900d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev mOwnsService = true; 391ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient = serviceConnectionListener; 392ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 393ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 3943ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup 395ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 3960d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev * Car constructor when ICar binder is already available. 397ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @hide 398ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 3993ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup public Car(Context context, ICar service, @Nullable Handler handler) { 400ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mContext = context; 4013ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup mEventHandler = determineEventHandler(handler); 402f4f07bf04563b9ad25ff9cdfc96f40790f155e41Keun-young Park mMainThreadEventHandler = determineMainThreadEventHandler(mEventHandler); 4033ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup 404ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = service; 4050d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev mOwnsService = false; 406ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_CONNECTED; 407ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient = null; 408ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 409ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 4103ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup private static Handler determineMainThreadEventHandler(Handler eventHandler) { 4113ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup Looper mainLooper = Looper.getMainLooper(); 4123ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup return (eventHandler.getLooper() == mainLooper) ? eventHandler : new Handler(mainLooper); 4133ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup } 4143ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup 4153ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup private static Handler determineEventHandler(@Nullable Handler handler) { 4163ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup if (handler == null) { 417f4f07bf04563b9ad25ff9cdfc96f40790f155e41Keun-young Park Looper looper = Looper.getMainLooper(); 4183ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup handler = new Handler(looper); 4193ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup } 4203ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup return handler; 4213ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup } 4223ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup 423ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 424ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Connect to car service. This can be called while it is disconnected. 425ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @throws IllegalStateException If connection is still on-going from previous 426ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * connect call or it is already connected 427ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 428ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void connect() throws IllegalStateException { 429ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 430ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mConnectionState != STATE_DISCONNECTED) { 431ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung throw new IllegalStateException("already connected or connecting"); 432ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 433ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_CONNECTING; 434e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park startCarService(); 435ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 436ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 437ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 438ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 439ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Disconnect from car service. This can be called while disconnected. Once disconnect is 440ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * called, all Car*Managers from this instance becomes invalid, and 441ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * {@link Car#getCarManager(String)} will return different instance if it is connected again. 442ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 443ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void disconnect() { 444ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 445ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mConnectionState == STATE_DISCONNECTED) { 446ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return; 447ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 44844241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mEventHandler.removeCallbacks(mConnectionRetryRunnable); 4493ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup mMainThreadEventHandler.removeCallbacks(mConnectionRetryFailedRunnable); 45044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mConnectionRetryCount = 0; 451ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung tearDownCarManagers(); 452ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = null; 453ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_DISCONNECTED; 4540d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev 4550d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev if (mOwnsService) { 4560d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev mContext.unbindService(mServiceConnectionListener); 4570d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev } 458ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 459ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 460ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 461ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 462ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Tells if it is connected to the service or not. This will return false if it is still 463ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * connecting. 464ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return 465ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 466ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public boolean isConnected() { 467ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 468ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return mService != null; 469ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 470ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 471ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 472ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 473ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Tells if this instance is already connecting to car service or not. 474ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return 475ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 476ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public boolean isConnecting() { 477ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 478ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return mConnectionState == STATE_CONNECTING; 479ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 480ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 481ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 482ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 483ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Get car specific service as in {@link Context#getSystemService(String)}. Returned 484ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * {@link Object} should be type-casted to the desired service. 485ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * For example, to get sensor service, 486ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * SensorManagerService sensorManagerService = car.getCarManager(Car.SENSOR_SERVICE); 487ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @param serviceName Name of service that should be created like {@link #SENSOR_SERVICE}. 488ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return Matching service manager or null if there is no such service. 489d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup * @throws CarNotConnectedException if the connection to the car service has been lost. 490ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 491235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv public Object getCarManager(String serviceName) throws CarNotConnectedException { 4920477e29bb17ee8ec99acfa5fa966889cd45ebf34Pavel Maltsev CarManagerBase manager; 4931ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung ICar service = getICarOrThrow(); 494ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (mCarManagerLock) { 495ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung manager = mServiceMap.get(serviceName); 496ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (manager == null) { 497ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung try { 4981ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung IBinder binder = service.getCarService(serviceName); 499ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (binder == null) { 500ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung Log.w(CarLibLog.TAG_CAR, "getCarManager could not get binder for service:" + 501ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung serviceName); 502ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return null; 503ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 504e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = createCarManager(serviceName, binder); 505ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (manager == null) { 506ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung Log.w(CarLibLog.TAG_CAR, 507ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung "getCarManager could not create manager for service:" + 5080477e29bb17ee8ec99acfa5fa966889cd45ebf34Pavel Maltsev serviceName); 509ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return null; 510ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 511ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceMap.put(serviceName, manager); 512ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } catch (RemoteException e) { 513e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park handleRemoteException(e); 514ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 515ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 516ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 517ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return manager; 518ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 519ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 520ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 521ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Return the type of currently connected car. 522ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return 523ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 524ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @ConnectionType 525e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public int getCarConnectionType() { 526e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park return CONNECTION_TYPE_EMBEDDED; 527ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 528ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 5293cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal /** 5303cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * IllegalStateException from XyzCarService with special message is re-thrown as a different 5313cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * exception. If the IllegalStateException is not understood then this message will throw the 5323cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * original exception. 5333cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 5343cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * @param e exception from XyzCarService. 535d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup * @throws CarNotConnectedException if the connection to the car service has been lost. 5363cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * @hide 5373cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal */ 5383cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public static void checkCarNotConnectedExceptionFromCarService( 5393cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal IllegalStateException e) throws CarNotConnectedException, IllegalStateException { 5403cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal String message = e.getMessage(); 54177ac6cf7366599d48d242205bcf5a67bcc633980Keun-young Park if (CAR_NOT_CONNECTED_EXCEPTION_MSG.equals(message)) { 5423cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal throw new CarNotConnectedException(); 5433cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } else { 5443cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal throw e; 5453cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 5463cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 5473cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 548150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park /** @hide */ 549150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park public static void hideCarNotConnectedExceptionFromCarService( 550150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park IllegalStateException e) throws IllegalStateException { 551150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park String message = e.getMessage(); 552150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park if (CAR_NOT_CONNECTED_EXCEPTION_MSG.equals(message)) { 553150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park return; //ignore 554150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park } else { 555150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park throw e; 556150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park } 557150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park } 558150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park 559235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv private CarManagerBase createCarManager(String serviceName, IBinder binder) 560235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv throws CarNotConnectedException { 561e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park CarManagerBase manager = null; 562e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park switch (serviceName) { 563e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case AUDIO_SERVICE: 564fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park manager = new CarAudioManager(binder, mContext, mEventHandler); 565e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 566e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case SENSOR_SERVICE: 5673ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarSensorManager(binder, mContext, mEventHandler); 568e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 569e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case INFO_SERVICE: 570e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarInfoManager(binder); 571e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 57246371473c416415fb6bcb8db85686669c3d65af6Vitalii Tomkiv case APP_FOCUS_SERVICE: 5733ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarAppFocusManager(binder, mEventHandler); 574e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 575e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case PACKAGE_SERVICE: 576e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarPackageManager(binder, mContext); 577e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 578e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case CAR_NAVIGATION_SERVICE: 5793388e7848f3a30029935463afafe9b8280939127Keun-young Park manager = new CarNavigationStatusManager(binder); 580e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 58143c04a7c87404d078db60e09d2da0061d72357c2Steve Paik case CABIN_SERVICE: 5823ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarCabinManager(binder, mContext, mEventHandler); 58343c04a7c87404d078db60e09d2da0061d72357c2Steve Paik break; 5845c56d2a3a5bc4ef5b46a58fa56b7f4a657b0827eEnrico Granata case DIAGNOSTIC_SERVICE: 58534010edbc8e13794307564c63b45226a8bf39e7aEnrico Granata if (FeatureConfiguration.ENABLE_DIAGNOSTIC) { 58634010edbc8e13794307564c63b45226a8bf39e7aEnrico Granata manager = new CarDiagnosticManager(binder, mContext, mEventHandler); 58734010edbc8e13794307564c63b45226a8bf39e7aEnrico Granata } 5885c56d2a3a5bc4ef5b46a58fa56b7f4a657b0827eEnrico Granata break; 589e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case HVAC_SERVICE: 5903ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarHvacManager(binder, mContext, mEventHandler); 591e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 5926e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv case PROJECTION_SERVICE: 5933ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarProjectionManager(binder, mEventHandler); 5946e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv break; 595e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case RADIO_SERVICE: 5963ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarRadioManager(binder, mEventHandler); 597e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 598634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev case VENDOR_EXTENSION_SERVICE: 5993ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarVendorExtensionManager(binder, mEventHandler); 600634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev break; 601e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case TEST_SERVICE: 602e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /* CarTestManager exist in static library. So instead of constructing it here, 603e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * only pass binder wrapper so that CarTestManager can be constructed outside. */ 604e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarTestManagerBinderWrapper(binder); 605e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 606a7d8ed1681d297bdda8345c1598c7b9a388599beAntonio Cortes case VMS_SUBSCRIBER_SERVICE: 607c52d5f9f6190cf9a44dd6dfd3bc92386fbf023b3Antonio Cortes if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) { 608c52d5f9f6190cf9a44dd6dfd3bc92386fbf023b3Antonio Cortes manager = new VmsSubscriberManager(binder, mEventHandler); 609c52d5f9f6190cf9a44dd6dfd3bc92386fbf023b3Antonio Cortes } 610a7d8ed1681d297bdda8345c1598c7b9a388599beAntonio Cortes break; 611e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 612e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park return manager; 613e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 614e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 615e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private void startCarService() { 616e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park Intent intent = new Intent(); 617e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park intent.setPackage(CAR_SERVICE_PACKAGE); 618e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park intent.setAction(Car.CAR_SERVICE_INTERFACE_NAME); 61944241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park boolean bound = mContext.bindServiceAsUser(intent, mServiceConnectionListener, 62044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park Context.BIND_AUTO_CREATE, UserHandle.CURRENT_OR_SELF); 62144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park if (!bound) { 62244241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mConnectionRetryCount++; 62344241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park if (mConnectionRetryCount > CAR_SERVICE_BIND_MAX_RETRY) { 62444241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park Log.w(CarLibLog.TAG_CAR, "cannot bind to car service after max retry"); 6253ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup mMainThreadEventHandler.post(mConnectionRetryFailedRunnable); 62644241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } else { 62744241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mEventHandler.postDelayed(mConnectionRetryRunnable, 62844241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park CAR_SERVICE_BIND_RETRY_INTERVAL_MS); 62944241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } 63044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } else { 63144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mConnectionRetryCount = 0; 63244241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } 633e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 634e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 635ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private synchronized ICar getICarOrThrow() throws IllegalStateException { 636ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mService == null) { 637ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung throw new IllegalStateException("not connected"); 638ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 639ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return mService; 640ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 641ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 642ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private void handleRemoteException(RemoteException e) { 643ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung Log.w(CarLibLog.TAG_CAR, "RemoteException", e); 644ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung disconnect(); 645ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 646ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 647ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private void tearDownCarManagers() { 648ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (mCarManagerLock) { 649ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung for (CarManagerBase manager: mServiceMap.values()) { 650ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung manager.onCarDisconnected(); 651ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 652ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceMap.clear(); 653ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 654ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 655ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung} 656