Car.java revision 150d8de43e71a624106e90bcc04067414c42ef18
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; 226e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.content.pm.CarPackageManager; 236e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.hardware.CarSensorManager; 2443c04a7c87404d078db60e09d2da0061d72357c2Steve Paikimport android.car.hardware.cabin.CarCabinManager; 25634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsevimport android.car.hardware.CarVendorExtensionManager; 266e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.hardware.camera.CarCameraManager; 276e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.hardware.hvac.CarHvacManager; 286e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.hardware.radio.CarRadioManager; 296e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.media.CarAudioManager; 303388e7848f3a30029935463afafe9b8280939127Keun-young Parkimport android.car.navigation.CarNavigationStatusManager; 316e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.test.CarTestManagerBinderWrapper; 32ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.content.ComponentName; 33ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.content.Context; 34e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.content.Intent; 35e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.content.ServiceConnection; 36ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.content.pm.PackageManager; 376b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoungimport android.os.Handler; 38ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.IBinder; 39ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.Looper; 40ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.RemoteException; 4144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Parkimport android.os.UserHandle; 42ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.util.Log; 43ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 44e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport com.android.internal.annotations.GuardedBy; 45e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 46ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport java.lang.annotation.Retention; 47ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport java.lang.annotation.RetentionPolicy; 48ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport java.util.HashMap; 496b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung 50ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung/** 51e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup * Top level car API for embedded Android Auto deployments. 52e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup * This API works only for devices with {@link PackageManager#FEATURE_AUTOMOTIVE} 53e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup * Calling this API on a device with no such feature will lead to an exception. 54ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 554cf6911619b9fe6ffeba7afeb05299aab165f184Keun-young Parkpublic final class Car { 56ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 57f521fd7b917a63c240802c7f841fc04c315573d0Keun-young Park /** 58f521fd7b917a63c240802c7f841fc04c315573d0Keun-young Park * Represent the version of Car API. 59f521fd7b917a63c240802c7f841fc04c315573d0Keun-young Park */ 60f521fd7b917a63c240802c7f841fc04c315573d0Keun-young Park public static final int VERSION = 1; 61f521fd7b917a63c240802c7f841fc04c315573d0Keun-young Park 62a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung /** Service name for {@link CarSensorManager}, to be used in {@link #getCarManager(String)}. */ 63ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public static final String SENSOR_SERVICE = "sensor"; 64ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 65a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung /** Service name for {@link CarInfoManager}, to be used in {@link #getCarManager(String)}. */ 66a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung public static final String INFO_SERVICE = "info"; 67a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung 683ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup /** Service name for {@link CarAppFocusManager}. */ 6946371473c416415fb6bcb8db85686669c3d65af6Vitalii Tomkiv public static final String APP_FOCUS_SERVICE = "app_focus"; 70a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung 717a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev /** Service name for {@link CarPackageManager} */ 7245fdcbaab5699d7d8153bfda058d0eea2049c8b8Keun-young Park public static final String PACKAGE_SERVICE = "package"; 7345fdcbaab5699d7d8153bfda058d0eea2049c8b8Keun-young Park 745672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Park /** Service name for {@link CarAudioManager} */ 755672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Park public static final String AUDIO_SERVICE = "audio"; 767a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev /** 773388e7848f3a30029935463afafe9b8280939127Keun-young Park * Service name for {@link CarNavigationStatusManager} 787a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev * @hide 797a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev */ 807a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev public static final String CAR_NAVIGATION_SERVICE = "car_navigation_service"; 817a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev 82280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 83280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 84280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 85e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 8643c04a7c87404d078db60e09d2da0061d72357c2Steve Paik public static final String CABIN_SERVICE = "cabin"; 8743c04a7c87404d078db60e09d2da0061d72357c2Steve Paik 8843c04a7c87404d078db60e09d2da0061d72357c2Steve Paik /** 8943c04a7c87404d078db60e09d2da0061d72357c2Steve Paik * @hide 9043c04a7c87404d078db60e09d2da0061d72357c2Steve Paik */ 9143c04a7c87404d078db60e09d2da0061d72357c2Steve Paik @SystemApi 92875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik public static final String CAMERA_SERVICE = "camera"; 93875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik 94280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 95280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 96280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 97875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik @SystemApi 98e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String RADIO_SERVICE = "radio"; 99ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 100280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 101280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 102280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 103e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 104e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String HVAC_SERVICE = "hvac"; 105e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 106280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 107280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 108280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 1096e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv @SystemApi 1106e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv public static final String PROJECTION_SERVICE = "projection"; 1116e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv 112e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** 113634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev * @hide 114634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev */ 115634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev @SystemApi 116634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev public static final String VENDOR_EXTENSION_SERVICE = "vendor_extension"; 117634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev 118634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev /** 119e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * Service for testing. This is system app only feature. 120e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}. 121e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * @hide 122e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park */ 123e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 124e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String TEST_SERVICE = "car-service-test"; 125ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 126ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** Permission necessary to access car's mileage information. */ 127e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_MILEAGE = "android.car.permission.CAR_MILEAGE"; 128e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 129ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** Permission necessary to access car's fuel level. */ 130e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_FUEL = "android.car.permission.CAR_FUEL"; 131e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 132ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** Permission necessary to access car's speed. */ 133e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_SPEED = "android.car.permission.CAR_SPEED"; 134e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 135ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** 136c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen * Permission necessary to change car audio volume through {@link CarAudioManager}. 137c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen */ 138c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen public static final String PERMISSION_CAR_CONTROL_AUDIO_VOLUME = 139c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen "android.car.permission.CAR_CONTROL_AUDIO_VOLUME"; 140c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen 141c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen /** 1423388e7848f3a30029935463afafe9b8280939127Keun-young Park * Permission necessary to use {@link CarNavigationStatusManager}. 143ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev * @hide 144ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev */ 145ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev public static final String PERMISSION_CAR_NAVIGATION_MANAGER = 146e31a8b24afe58bfc924fab7b66c9e48b9ef8e884Keun-young Park "android.car.permission.CAR_NAVIGATION_MANAGER"; 147ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev 148280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 149280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access car specific communication channel. 150280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 151280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 152e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 153ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public static final String PERMISSION_VENDOR_EXTENSION = 154e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park "android.car.permission.CAR_VENDOR_EXTENSION"; 155e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 156280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 157280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 158280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 159e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 1604aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park public static final String PERMISSION_CONTROL_APP_BLOCKING = 161e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park "android.car.permission.CONTROL_APP_BLOCKING"; 162ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 163280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 16443c04a7c87404d078db60e09d2da0061d72357c2Steve Paik * Permission necessary to access Car Cabin APIs. 16543c04a7c87404d078db60e09d2da0061d72357c2Steve Paik * @hide 16643c04a7c87404d078db60e09d2da0061d72357c2Steve Paik */ 16743c04a7c87404d078db60e09d2da0061d72357c2Steve Paik @SystemApi 16843c04a7c87404d078db60e09d2da0061d72357c2Steve Paik public static final String PERMISSION_CAR_CABIN = "android.car.permission.CAR_CABIN"; 16943c04a7c87404d078db60e09d2da0061d72357c2Steve Paik 17043c04a7c87404d078db60e09d2da0061d72357c2Steve Paik /** 171280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access Car Camera APIs. 172280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 173280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 174875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik @SystemApi 175875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik public static final String PERMISSION_CAR_CAMERA = "android.car.permission.CAR_CAMERA"; 176875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik 177280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 178280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access Car HVAC APIs. 179280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 180280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 181e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 182e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_CAR_HVAC = "android.car.permission.CAR_HVAC"; 183ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 184280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 185280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access Car RADIO system APIs. 186280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 187280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 188e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 189e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_CAR_RADIO = "android.car.permission.CAR_RADIO"; 190ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 191b13dbe470108846d1c04494c5c0d2bf3cd9b8054Jason Tholstrup 192280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 193b13dbe470108846d1c04494c5c0d2bf3cd9b8054Jason Tholstrup * Permission necessary to access Car PROJECTION system APIs. 194280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 195280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 1966e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv @SystemApi 1976e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv public static final String PERMISSION_CAR_PROJECTION = "android.car.permission.CAR_PROJECTION"; 1986e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv 199280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 200280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to mock vehicle hal for testing. 201280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 202280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 203e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 204e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_MOCK_VEHICLE_HAL = 205e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park "android.car.permission.CAR_MOCK_VEHICLE_HAL"; 206e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 207e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** Type of car connection: platform runs directly in car. */ 208e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final int CONNECTION_TYPE_EMBEDDED = 5; 2091ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev /** 2101ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev * Type of car connection: platform runs directly in car but with mocked vehicle hal. 2111ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev * This will only happen in testing environment. 2121ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev * @hide 2131ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev */ 2141ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev public static final int CONNECTION_TYPE_EMBEDDED_MOCKING = 6; 215e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 216e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup 217e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** @hide */ 2181ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev @IntDef({CONNECTION_TYPE_EMBEDDED, CONNECTION_TYPE_EMBEDDED_MOCKING}) 219e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @Retention(RetentionPolicy.SOURCE) 220e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public @interface ConnectionType {} 221ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 2223cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal /** 2233cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * CarXyzService throws IllegalStateException with this message is re-thrown as 2243cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * {@link CarNotConnectedException}. 2253cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 2263cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * @hide 2273cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal */ 2283cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public static final String CAR_NOT_CONNECTED_EXCEPTION_MSG = "CarNotConnected"; 2293cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 230e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** @hide */ 231e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String CAR_SERVICE_INTERFACE_NAME = "android.car.ICar"; 232e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 233e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private static final String CAR_SERVICE_PACKAGE = "com.android.car"; 234e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 23544241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private static final String CAR_SERVICE_CLASS = "com.android.car.CarService"; 23644241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park 237e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private static final String CAR_TEST_MANAGER_CLASS = "android.car.CarTestManager"; 238ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 23944241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private static final long CAR_SERVICE_BIND_RETRY_INTERVAL_MS = 500; 24044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private static final long CAR_SERVICE_BIND_MAX_RETRY = 20; 24144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park 242ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private final Context mContext; 243ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @GuardedBy("this") 244ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private ICar mService; 245ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private static final int STATE_DISCONNECTED = 0; 246ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private static final int STATE_CONNECTING = 1; 247ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private static final int STATE_CONNECTED = 2; 248ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @GuardedBy("this") 249ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private int mConnectionState; 25044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park @GuardedBy("this") 25144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private int mConnectionRetryCount; 25244241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park 25344241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private final Runnable mConnectionRetryRunnable = new Runnable() { 25444241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park @Override 25544241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park public void run() { 25644241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park startCarService(); 25744241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } 25844241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park }; 25944241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park 26044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park private final Runnable mConnectionRetryFailedRunnable = new Runnable() { 26144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park @Override 26244241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park public void run() { 26344241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mServiceConnectionListener.onServiceDisconnected(new ComponentName(CAR_SERVICE_PACKAGE, 26444241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park CAR_SERVICE_CLASS)); 26544241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } 26644241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park }; 267ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 268e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private final ServiceConnection mServiceConnectionListener = 269e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park new ServiceConnection () { 270ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void onServiceConnected(ComponentName name, IBinder service) { 2711ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung synchronized (Car.this) { 272ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = ICar.Stub.asInterface(service); 273ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_CONNECTED; 274ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 275ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient.onServiceConnected(name, service); 276ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 277ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 278ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void onServiceDisconnected(ComponentName name) { 2791ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung synchronized (Car.this) { 280ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = null; 281ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mConnectionState == STATE_DISCONNECTED) { 282ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return; 283ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 284cc449f7941456a0133ff8a4b2e49737f0936c1d0keunyoung mConnectionState = STATE_DISCONNECTED; 285ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 286e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park // unbind explicitly here. 287e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park disconnect(); 288ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient.onServiceDisconnected(name); 289ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 290ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung }; 291ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 292e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private final ServiceConnection mServiceConnectionListenerClient; 293ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private final Object mCarManagerLock = new Object(); 294ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @GuardedBy("mCarManagerLock") 295ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private final HashMap<String, CarManagerBase> mServiceMap = new HashMap<>(); 2966b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung 2976b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung /** Handler for generic event dispatching. */ 2986b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung private final Handler mEventHandler; 2996b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung 3003ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup private final Handler mMainThreadEventHandler; 30144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park 3021ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung /** 3038de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * A factory method that creates Car instance for all Car API access. 304ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @param context 305e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * @param serviceConnectionListener listener for monitoring service connection. 3063ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup * @param handler the handler on which the callback should execute, or null to execute on the 3073ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup * service's main thread. Note: the service connection listener will be always on the main 3083ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup * thread regardless of the handler given. 3098de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * @return Car instance if system is in car environment and returns {@code null} otherwise. 310ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 311e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static Car createCar(Context context, ServiceConnection serviceConnectionListener, 3123ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup @Nullable Handler handler) { 313e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 314e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park Log.e(CarLibLog.TAG_CAR, "FEATURE_AUTOMOTIVE not declared while android.car is used"); 315e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park return null; 316e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 3178de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev try { 3183ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup return new Car(context, serviceConnectionListener, handler); 3198de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } catch (IllegalArgumentException e) { 3208de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev // Expected when car service loader is not available. 3218de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } 3228de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev return null; 3238de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } 3248de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev 3258de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev /** 3268de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * A factory method that creates Car instance for all Car API access using main thread {@code 3278de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * Looper}. 3288de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * 3293ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup * @see #createCar(Context, ServiceConnection, Handler) 3308de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev */ 331e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static Car createCar(Context context, ServiceConnection serviceConnectionListener) { 3328de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev return createCar(context, serviceConnectionListener, null); 3338de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } 3348de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev 335e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private Car(Context context, ServiceConnection serviceConnectionListener, 3363ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup @Nullable Handler handler) { 337ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mContext = context; 3383ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup mEventHandler = determineEventHandler(handler); 339224220701b9c22ebcfc7dc532714839dca202bb3Yao Chen mMainThreadEventHandler = determineMainThreadEventHandler(mEventHandler); 3403ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup 3413ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup mService = null; 342ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient = serviceConnectionListener; 343ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 344ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 3453ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup 346ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 3471ac59caa6b1bc760aef0adb3c675b49bfa53af9fJason Tholstrup * Car constructor when ICar binder is already available. * 348ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @hide 349ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 3503ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup public Car(Context context, ICar service, @Nullable Handler handler) { 351ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mContext = context; 3523ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup mEventHandler = determineEventHandler(handler); 353f4f07bf04563b9ad25ff9cdfc96f40790f155e41Keun-young Park mMainThreadEventHandler = determineMainThreadEventHandler(mEventHandler); 3543ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup 355ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = service; 356ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_CONNECTED; 357ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient = null; 358ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 359ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 3603ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup private static Handler determineMainThreadEventHandler(Handler eventHandler) { 3613ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup Looper mainLooper = Looper.getMainLooper(); 3623ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup return (eventHandler.getLooper() == mainLooper) ? eventHandler : new Handler(mainLooper); 3633ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup } 3643ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup 3653ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup private static Handler determineEventHandler(@Nullable Handler handler) { 3663ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup if (handler == null) { 367f4f07bf04563b9ad25ff9cdfc96f40790f155e41Keun-young Park Looper looper = Looper.getMainLooper(); 3683ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup handler = new Handler(looper); 3693ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup } 3703ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup return handler; 3713ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup } 3723ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup 373ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 374ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Connect to car service. This can be called while it is disconnected. 375ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @throws IllegalStateException If connection is still on-going from previous 376ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * connect call or it is already connected 377ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 378ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void connect() throws IllegalStateException { 379ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 380ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mConnectionState != STATE_DISCONNECTED) { 381ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung throw new IllegalStateException("already connected or connecting"); 382ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 383ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_CONNECTING; 384e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park startCarService(); 385ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 386ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 387ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 388ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 389ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Disconnect from car service. This can be called while disconnected. Once disconnect is 390ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * called, all Car*Managers from this instance becomes invalid, and 391ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * {@link Car#getCarManager(String)} will return different instance if it is connected again. 392ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 393ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void disconnect() { 394ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 395ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mConnectionState == STATE_DISCONNECTED) { 396ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return; 397ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 39844241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mEventHandler.removeCallbacks(mConnectionRetryRunnable); 3993ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup mMainThreadEventHandler.removeCallbacks(mConnectionRetryFailedRunnable); 40044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mConnectionRetryCount = 0; 401ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung tearDownCarManagers(); 402ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = null; 403ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_DISCONNECTED; 404e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park mContext.unbindService(mServiceConnectionListener); 405ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 406ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 407ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 408ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 409ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Tells if it is connected to the service or not. This will return false if it is still 410ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * connecting. 411ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return 412ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 413ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public boolean isConnected() { 414ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 415ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return mService != null; 416ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 417ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 418ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 419ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 420ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Tells if this instance is already connecting to car service or not. 421ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return 422ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 423ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public boolean isConnecting() { 424ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 425ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return mConnectionState == STATE_CONNECTING; 426ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 427ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 428ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 429ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 430ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Get car specific service as in {@link Context#getSystemService(String)}. Returned 431ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * {@link Object} should be type-casted to the desired service. 432ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * For example, to get sensor service, 433ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * SensorManagerService sensorManagerService = car.getCarManager(Car.SENSOR_SERVICE); 434ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @param serviceName Name of service that should be created like {@link #SENSOR_SERVICE}. 435ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return Matching service manager or null if there is no such service. 436d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup * @throws CarNotConnectedException if the connection to the car service has been lost. 437ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 438235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv public Object getCarManager(String serviceName) throws CarNotConnectedException { 4390477e29bb17ee8ec99acfa5fa966889cd45ebf34Pavel Maltsev CarManagerBase manager; 4401ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung ICar service = getICarOrThrow(); 441ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (mCarManagerLock) { 442ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung manager = mServiceMap.get(serviceName); 443ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (manager == null) { 444ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung try { 4451ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung IBinder binder = service.getCarService(serviceName); 446ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (binder == null) { 447ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung Log.w(CarLibLog.TAG_CAR, "getCarManager could not get binder for service:" + 448ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung serviceName); 449ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return null; 450ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 451e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = createCarManager(serviceName, binder); 452ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (manager == null) { 453ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung Log.w(CarLibLog.TAG_CAR, 454ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung "getCarManager could not create manager for service:" + 4550477e29bb17ee8ec99acfa5fa966889cd45ebf34Pavel Maltsev serviceName); 456ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return null; 457ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 458ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceMap.put(serviceName, manager); 459ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } catch (RemoteException e) { 460e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park handleRemoteException(e); 461ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 462ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 463ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 464ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return manager; 465ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 466ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 467ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 468ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Return the type of currently connected car. 469ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return 470ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 471ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @ConnectionType 472e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public int getCarConnectionType() { 473e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park return CONNECTION_TYPE_EMBEDDED; 474ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 475ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 4763cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal /** 4773cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * IllegalStateException from XyzCarService with special message is re-thrown as a different 4783cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * exception. If the IllegalStateException is not understood then this message will throw the 4793cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * original exception. 4803cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 4813cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * @param e exception from XyzCarService. 482d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup * @throws CarNotConnectedException if the connection to the car service has been lost. 4833cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * @hide 4843cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal */ 4853cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public static void checkCarNotConnectedExceptionFromCarService( 4863cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal IllegalStateException e) throws CarNotConnectedException, IllegalStateException { 4873cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal String message = e.getMessage(); 48877ac6cf7366599d48d242205bcf5a67bcc633980Keun-young Park if (CAR_NOT_CONNECTED_EXCEPTION_MSG.equals(message)) { 4893cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal throw new CarNotConnectedException(); 4903cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } else { 4913cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal throw e; 4923cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 4933cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 4943cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 495150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park /** @hide */ 496150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park public static void hideCarNotConnectedExceptionFromCarService( 497150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park IllegalStateException e) throws IllegalStateException { 498150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park String message = e.getMessage(); 499150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park if (CAR_NOT_CONNECTED_EXCEPTION_MSG.equals(message)) { 500150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park return; //ignore 501150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park } else { 502150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park throw e; 503150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park } 504150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park } 505150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park 506235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv private CarManagerBase createCarManager(String serviceName, IBinder binder) 507235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv throws CarNotConnectedException { 508e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park CarManagerBase manager = null; 509e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park switch (serviceName) { 510e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case AUDIO_SERVICE: 5116f3f402a7469e300fbfe65d950204fef995d4d8dVitalii Tomkiv manager = new CarAudioManager(binder, mContext); 512e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 513e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case SENSOR_SERVICE: 5143ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarSensorManager(binder, mContext, mEventHandler); 515e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 516e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case INFO_SERVICE: 517e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarInfoManager(binder); 518e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 51946371473c416415fb6bcb8db85686669c3d65af6Vitalii Tomkiv case APP_FOCUS_SERVICE: 5203ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarAppFocusManager(binder, mEventHandler); 521e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 522e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case PACKAGE_SERVICE: 523e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarPackageManager(binder, mContext); 524e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 525e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case CAR_NAVIGATION_SERVICE: 5263388e7848f3a30029935463afafe9b8280939127Keun-young Park manager = new CarNavigationStatusManager(binder); 527e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 52843c04a7c87404d078db60e09d2da0061d72357c2Steve Paik case CABIN_SERVICE: 5293ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarCabinManager(binder, mContext, mEventHandler); 53043c04a7c87404d078db60e09d2da0061d72357c2Steve Paik break; 531875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik case CAMERA_SERVICE: 532875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik manager = new CarCameraManager(binder, mContext); 533875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik break; 534e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case HVAC_SERVICE: 5353ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarHvacManager(binder, mContext, mEventHandler); 536e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 5376e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv case PROJECTION_SERVICE: 5383ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarProjectionManager(binder, mEventHandler); 5396e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv break; 540e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case RADIO_SERVICE: 5413ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarRadioManager(binder, mEventHandler); 542e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 543634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev case VENDOR_EXTENSION_SERVICE: 5443ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup manager = new CarVendorExtensionManager(binder, mEventHandler); 545634e1ff49c62c32c8227ec5092743de3caca790cPavel Maltsev break; 546e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case TEST_SERVICE: 547e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /* CarTestManager exist in static library. So instead of constructing it here, 548e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * only pass binder wrapper so that CarTestManager can be constructed outside. */ 549e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarTestManagerBinderWrapper(binder); 550e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 551e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 552e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park return manager; 553e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 554e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 555e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private void startCarService() { 556e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park Intent intent = new Intent(); 557e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park intent.setPackage(CAR_SERVICE_PACKAGE); 558e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park intent.setAction(Car.CAR_SERVICE_INTERFACE_NAME); 55944241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park boolean bound = mContext.bindServiceAsUser(intent, mServiceConnectionListener, 56044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park Context.BIND_AUTO_CREATE, UserHandle.CURRENT_OR_SELF); 56144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park if (!bound) { 56244241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mConnectionRetryCount++; 56344241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park if (mConnectionRetryCount > CAR_SERVICE_BIND_MAX_RETRY) { 56444241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park Log.w(CarLibLog.TAG_CAR, "cannot bind to car service after max retry"); 5653ee334d8c220f631d2ea7fa225af148f41b43354Jason Tholstrup mMainThreadEventHandler.post(mConnectionRetryFailedRunnable); 56644241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } else { 56744241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mEventHandler.postDelayed(mConnectionRetryRunnable, 56844241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park CAR_SERVICE_BIND_RETRY_INTERVAL_MS); 56944241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } 57044241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } else { 57144241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park mConnectionRetryCount = 0; 57244241ffb0717f22650bbcef19c9b68c1f56cac10Keun-young Park } 573e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 574e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 575ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private synchronized ICar getICarOrThrow() throws IllegalStateException { 576ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mService == null) { 577ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung throw new IllegalStateException("not connected"); 578ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 579ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return mService; 580ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 581ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 582ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private void handleRemoteException(RemoteException e) { 583ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung Log.w(CarLibLog.TAG_CAR, "RemoteException", e); 584ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung disconnect(); 585ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 586ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 587ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private void tearDownCarManagers() { 588ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (mCarManagerLock) { 589ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung for (CarManagerBase manager: mServiceMap.values()) { 590ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung manager.onCarDisconnected(); 591ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 592ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceMap.clear(); 593ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 594ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 595ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung} 596