Car.java revision c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193f
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; 246e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.hardware.camera.CarCameraManager; 256e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.hardware.hvac.CarHvacManager; 266e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.hardware.radio.CarRadioManager; 276e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.media.CarAudioManager; 286e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.navigation.CarNavigationManager; 296e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkivimport android.car.test.CarTestManagerBinderWrapper; 30ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.content.ComponentName; 31ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.content.Context; 32e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.content.Intent; 33e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.content.ServiceConnection; 34ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.content.pm.PackageManager; 356b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoungimport android.os.Handler; 36ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.IBinder; 37ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.Looper; 38ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.RemoteException; 39ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.util.Log; 40ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 41e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport com.android.internal.annotations.GuardedBy; 42e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 43ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport java.lang.annotation.Retention; 44ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport java.lang.annotation.RetentionPolicy; 45ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport java.util.HashMap; 466b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung 47ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung/** 48e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup * Top level car API for embedded Android Auto deployments. 49e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup * This API works only for devices with {@link PackageManager#FEATURE_AUTOMOTIVE} 50e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup * Calling this API on a device with no such feature will lead to an exception. 51ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 52ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungpublic class Car { 53ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 54a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung /** Service name for {@link CarSensorManager}, to be used in {@link #getCarManager(String)}. */ 55ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public static final String SENSOR_SERVICE = "sensor"; 56ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 57a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung /** Service name for {@link CarInfoManager}, to be used in {@link #getCarManager(String)}. */ 58a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung public static final String INFO_SERVICE = "info"; 59a3b28d81e0c8df531ac704f9e649e38ea90483d2keunyoung 6045fdcbaab5699d7d8153bfda058d0eea2049c8b8Keun-young Park /** Service name for {@link CarAppContextManager}. */ 61a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung public static final String APP_CONTEXT_SERVICE = "app_context"; 62a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung 637a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev /** Service name for {@link CarPackageManager} */ 6445fdcbaab5699d7d8153bfda058d0eea2049c8b8Keun-young Park public static final String PACKAGE_SERVICE = "package"; 6545fdcbaab5699d7d8153bfda058d0eea2049c8b8Keun-young Park 665672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Park /** Service name for {@link CarAudioManager} */ 675672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Park public static final String AUDIO_SERVICE = "audio"; 687a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev /** 69e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * Service name for {@link CarNavigationManager} 707a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev * @hide 717a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev */ 727a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev public static final String CAR_NAVIGATION_SERVICE = "car_navigation_service"; 737a948e54331cccf96f178ab426cb7810472c2dc8Pavel Maltsev 74280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 75280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 76280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 77e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 78875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik public static final String CAMERA_SERVICE = "camera"; 79875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik 80280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 81280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 82280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 83875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik @SystemApi 84e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String RADIO_SERVICE = "radio"; 85ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 86280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 87280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 88280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 89e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 90e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String HVAC_SERVICE = "hvac"; 91e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 92280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 93280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 94280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 956e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv @SystemApi 966e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv public static final String PROJECTION_SERVICE = "projection"; 976e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv 98e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** 99e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * Service for testing. This is system app only feature. 100e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}. 101e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * @hide 102e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park */ 103e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 104e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String TEST_SERVICE = "car-service-test"; 105ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 106ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** Permission necessary to access car's mileage information. */ 107e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_MILEAGE = "android.car.permission.CAR_MILEAGE"; 108e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 109ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** Permission necessary to access car's fuel level. */ 110e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_FUEL = "android.car.permission.CAR_FUEL"; 111e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 112ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** Permission necessary to access car's speed. */ 113e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_SPEED = "android.car.permission.CAR_SPEED"; 114e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 115ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev /** 116c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen * Permission necessary to change car audio volume through {@link CarAudioManager}. 117c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen */ 118c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen public static final String PERMISSION_CAR_CONTROL_AUDIO_VOLUME = 119c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen "android.car.permission.CAR_CONTROL_AUDIO_VOLUME"; 120c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen 121c4d442f4a0d3acf90b1c7a1dd7c222a8f32a193fYao Chen /** 122ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev * Permission necessary to use {@link CarNavigationManager}. 123ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev * @hide 124ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev */ 125ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev public static final String PERMISSION_CAR_NAVIGATION_MANAGER = 126e31a8b24afe58bfc924fab7b66c9e48b9ef8e884Keun-young Park "android.car.permission.CAR_NAVIGATION_MANAGER"; 127ce4ffd95d6883b28756e5b02ae45a06013bd6c38Pavel Maltsev 128280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 129280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access car specific communication channel. 130280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 131280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 132e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 133ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public static final String PERMISSION_VENDOR_EXTENSION = 134e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park "android.car.permission.CAR_VENDOR_EXTENSION"; 135e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 136280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 137280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 138280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 139e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 1404aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park public static final String PERMISSION_CONTROL_APP_BLOCKING = 141e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park "android.car.permission.CONTROL_APP_BLOCKING"; 142ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 143280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 144280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access Car Camera APIs. 145280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 146280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 147875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik @SystemApi 148875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik public static final String PERMISSION_CAR_CAMERA = "android.car.permission.CAR_CAMERA"; 149875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik 150280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 151280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access Car HVAC APIs. 152280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 153280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 154e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 155e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_CAR_HVAC = "android.car.permission.CAR_HVAC"; 156ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 157280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 158280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to access Car RADIO system APIs. 159280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 160280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 161e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 162e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_CAR_RADIO = "android.car.permission.CAR_RADIO"; 163ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 164b13dbe470108846d1c04494c5c0d2bf3cd9b8054Jason Tholstrup 165280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 166b13dbe470108846d1c04494c5c0d2bf3cd9b8054Jason Tholstrup * Permission necessary to access Car PROJECTION system APIs. 167280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 168280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 1696e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv @SystemApi 1706e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv public static final String PERMISSION_CAR_PROJECTION = "android.car.permission.CAR_PROJECTION"; 1716e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv 172280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv /** 173280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * Permission necessary to mock vehicle hal for testing. 174280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide 175280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv */ 176e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @SystemApi 177e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String PERMISSION_MOCK_VEHICLE_HAL = 178e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park "android.car.permission.CAR_MOCK_VEHICLE_HAL"; 179e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 180e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** Type of car connection: platform runs directly in car. */ 181e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final int CONNECTION_TYPE_EMBEDDED = 5; 1821ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev /** 1831ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev * Type of car connection: platform runs directly in car but with mocked vehicle hal. 1841ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev * This will only happen in testing environment. 1851ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev * @hide 1861ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev */ 1871ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev public static final int CONNECTION_TYPE_EMBEDDED_MOCKING = 6; 188e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 189e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup 190e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** @hide */ 1911ecdd6ca75fdf8ff62105630664de5125e29676bPavel Maltsev @IntDef({CONNECTION_TYPE_EMBEDDED, CONNECTION_TYPE_EMBEDDED_MOCKING}) 192e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park @Retention(RetentionPolicy.SOURCE) 193e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public @interface ConnectionType {} 194ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 1953cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal /** 1963cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * CarXyzService throws IllegalStateException with this message is re-thrown as 1973cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * {@link CarNotConnectedException}. 1983cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 1993cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * @hide 2003cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal */ 2013cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public static final String CAR_NOT_CONNECTED_EXCEPTION_MSG = "CarNotConnected"; 2023cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 203e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /** @hide */ 204e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static final String CAR_SERVICE_INTERFACE_NAME = "android.car.ICar"; 205e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 206e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private static final String CAR_SERVICE_PACKAGE = "com.android.car"; 207e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 208e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private static final String CAR_TEST_MANAGER_CLASS = "android.car.CarTestManager"; 209ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 210ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private final Context mContext; 211ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private final Looper mLooper; 212ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @GuardedBy("this") 213ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private ICar mService; 214ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private static final int STATE_DISCONNECTED = 0; 215ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private static final int STATE_CONNECTING = 1; 216ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private static final int STATE_CONNECTED = 2; 217ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @GuardedBy("this") 218ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private int mConnectionState; 219ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 220e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private final ServiceConnection mServiceConnectionListener = 221e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park new ServiceConnection () { 222ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void onServiceConnected(ComponentName name, IBinder service) { 2231ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung synchronized (Car.this) { 224ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = ICar.Stub.asInterface(service); 225ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_CONNECTED; 226ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 227ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient.onServiceConnected(name, service); 228ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 229ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 230ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void onServiceDisconnected(ComponentName name) { 2311ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung synchronized (Car.this) { 232ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = null; 233ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mConnectionState == STATE_DISCONNECTED) { 234ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return; 235ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 236cc449f7941456a0133ff8a4b2e49737f0936c1d0keunyoung mConnectionState = STATE_DISCONNECTED; 237ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 238e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park // unbind explicitly here. 239e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park disconnect(); 240ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient.onServiceDisconnected(name); 241ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 242ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung }; 243ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 244e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private final ServiceConnection mServiceConnectionListenerClient; 245ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private final Object mCarManagerLock = new Object(); 246ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @GuardedBy("mCarManagerLock") 247ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private final HashMap<String, CarManagerBase> mServiceMap = new HashMap<>(); 2486b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung 2496b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung /** Handler for generic event dispatching. */ 2506b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung private final Handler mEventHandler; 2516b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung 2521ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung /** 2538de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * A factory method that creates Car instance for all Car API access. 254ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @param context 255e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * @param serviceConnectionListener listener for monitoring service connection. 256ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @param looper Looper to dispatch all listeners. If null, it will use main thread. Note that 257ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * service connection listener will be always in main thread regardless of this Looper. 2588de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * @return Car instance if system is in car environment and returns {@code null} otherwise. 259ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 260e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static Car createCar(Context context, ServiceConnection serviceConnectionListener, 2618de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev @Nullable Looper looper) { 262e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 263e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park Log.e(CarLibLog.TAG_CAR, "FEATURE_AUTOMOTIVE not declared while android.car is used"); 264e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park return null; 265e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 2668de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev try { 2678de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev return new Car(context, serviceConnectionListener, looper); 2688de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } catch (IllegalArgumentException e) { 2698de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev // Expected when car service loader is not available. 2708de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } 2718de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev return null; 2728de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } 2738de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev 2748de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev /** 2758de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * A factory method that creates Car instance for all Car API access using main thread {@code 2768de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * Looper}. 2778de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev * 278e4c731ea3ed22615783efb02818b0b3d184bba33Jason Tholstrup * @see #createCar(Context, ServiceConnection, Looper) 2798de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev */ 280e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public static Car createCar(Context context, ServiceConnection serviceConnectionListener) { 2818de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev return createCar(context, serviceConnectionListener, null); 2828de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev } 2838de993354f1a8c30880b535cf8b80fee10c4e882Pavel Maltsev 284e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private Car(Context context, ServiceConnection serviceConnectionListener, 285ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @Nullable Looper looper) { 286ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mContext = context; 287ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient = serviceConnectionListener; 288ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (looper == null) { 289ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mLooper = Looper.getMainLooper(); 290ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } else { 291ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mLooper = looper; 292ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 2936b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung mEventHandler = new Handler(mLooper); 294ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 295ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 296ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 297ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Car constructor when ICar binder is already available. 298ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @param context 299ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @param service 300ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @param looper 301ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * 302ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @hide 303ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 304ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public Car(Context context, ICar service, @Nullable Looper looper) { 305ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mContext = context; 306ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (looper == null) { 307ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mLooper = Looper.getMainLooper(); 308ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } else { 309ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mLooper = looper; 310ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 3116b19769ee8cfbe0960d05ecfc01f73d08040784fkeunyoung mEventHandler = new Handler(mLooper); 312ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = service; 313ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_CONNECTED; 314ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceConnectionListenerClient = null; 315ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 316ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 317ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 318ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Connect to car service. This can be called while it is disconnected. 319ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @throws IllegalStateException If connection is still on-going from previous 320ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * connect call or it is already connected 321ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 322ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void connect() throws IllegalStateException { 323ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 324ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mConnectionState != STATE_DISCONNECTED) { 325ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung throw new IllegalStateException("already connected or connecting"); 326ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 327ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_CONNECTING; 328e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park startCarService(); 329ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 330ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 331ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 332ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 333ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Disconnect from car service. This can be called while disconnected. Once disconnect is 334ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * called, all Car*Managers from this instance becomes invalid, and 335ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * {@link Car#getCarManager(String)} will return different instance if it is connected again. 336ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 337ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public void disconnect() { 338ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 339ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mConnectionState == STATE_DISCONNECTED) { 340ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return; 341ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 342ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung tearDownCarManagers(); 343ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mService = null; 344ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mConnectionState = STATE_DISCONNECTED; 345e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park mContext.unbindService(mServiceConnectionListener); 346ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 347ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 348ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 349ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 350ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Tells if it is connected to the service or not. This will return false if it is still 351ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * connecting. 352ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return 353ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 354ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public boolean isConnected() { 355ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 356ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return mService != null; 357ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 358ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 359ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 360ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 361ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Tells if this instance is already connecting to car service or not. 362ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return 363ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 364ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung public boolean isConnecting() { 365ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (this) { 366ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return mConnectionState == STATE_CONNECTING; 367ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 368ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 369ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 370ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 371ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Get car specific service as in {@link Context#getSystemService(String)}. Returned 372ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * {@link Object} should be type-casted to the desired service. 373ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * For example, to get sensor service, 374ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * SensorManagerService sensorManagerService = car.getCarManager(Car.SENSOR_SERVICE); 375ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @param serviceName Name of service that should be created like {@link #SENSOR_SERVICE}. 376ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return Matching service manager or null if there is no such service. 377235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv * @throws CarNotConnectedException 378ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 379235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv public Object getCarManager(String serviceName) throws CarNotConnectedException { 380ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung CarManagerBase manager = null; 3811ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung ICar service = getICarOrThrow(); 382ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (mCarManagerLock) { 383ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung manager = mServiceMap.get(serviceName); 384ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (manager == null) { 385ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung try { 3861ab8e18e01d8063821bee0bf641a365224c7e1eekeunyoung IBinder binder = service.getCarService(serviceName); 387ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (binder == null) { 388ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung Log.w(CarLibLog.TAG_CAR, "getCarManager could not get binder for service:" + 389ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung serviceName); 390ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return null; 391ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 392e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = createCarManager(serviceName, binder); 393ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (manager == null) { 394ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung Log.w(CarLibLog.TAG_CAR, 395ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung "getCarManager could not create manager for service:" + 396ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung serviceName); 397ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return null; 398ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 399ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceMap.put(serviceName, manager); 400ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } catch (RemoteException e) { 401e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park handleRemoteException(e); 402ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 403ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 404ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 405ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return manager; 406ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 407ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 408ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung /** 409ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Return the type of currently connected car. 410ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * @return 411ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */ 412ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung @ConnectionType 413e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park public int getCarConnectionType() { 414e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park return CONNECTION_TYPE_EMBEDDED; 415ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 416ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 4173cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal /** 4183cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * IllegalStateException from XyzCarService with special message is re-thrown as a different 4193cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * exception. If the IllegalStateException is not understood then this message will throw the 4203cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * original exception. 4213cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 4223cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * @param e exception from XyzCarService. 4233cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * @throws CarNotConnectedException 4243cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * @hide 4253cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal */ 4263cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public static void checkCarNotConnectedExceptionFromCarService( 4273cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal IllegalStateException e) throws CarNotConnectedException, IllegalStateException { 4283cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal String message = e.getMessage(); 4293cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (message.equals(CAR_NOT_CONNECTED_EXCEPTION_MSG)) { 4303cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal throw new CarNotConnectedException(); 4313cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } else { 4323cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal throw e; 4333cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 4343cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 4353cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 436235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv private CarManagerBase createCarManager(String serviceName, IBinder binder) 437235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv throws CarNotConnectedException { 438e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park CarManagerBase manager = null; 439e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park switch (serviceName) { 440e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case AUDIO_SERVICE: 4416f3f402a7469e300fbfe65d950204fef995d4d8dVitalii Tomkiv manager = new CarAudioManager(binder, mContext); 442e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 443e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case SENSOR_SERVICE: 444e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarSensorManager(binder, mContext, mLooper); 445e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 446e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case INFO_SERVICE: 447e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarInfoManager(binder); 448e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 449e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case APP_CONTEXT_SERVICE: 450e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarAppContextManager(binder, mLooper); 451e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 452e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case PACKAGE_SERVICE: 453e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarPackageManager(binder, mContext); 454e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 455e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case CAR_NAVIGATION_SERVICE: 456e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarNavigationManager(binder, mLooper); 457e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 458875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik case CAMERA_SERVICE: 459875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik manager = new CarCameraManager(binder, mContext); 460875616c52be0a5a4d3aa348e9dcfd90e54789912Steve Paik break; 461e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case HVAC_SERVICE: 462e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarHvacManager(binder, mContext, mLooper); 463e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 4646e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv case PROJECTION_SERVICE: 4656e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv manager = new CarProjectionManager(binder, mLooper); 4666e5ee61be4c24ae4d647d687901b7c9670c25899Vitalii Tomkiv break; 467e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case RADIO_SERVICE: 468e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarRadioManager(binder, mLooper); 469e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 470e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park case TEST_SERVICE: 471e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park /* CarTestManager exist in static library. So instead of constructing it here, 472e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * only pass binder wrapper so that CarTestManager can be constructed outside. */ 473e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park manager = new CarTestManagerBinderWrapper(binder); 474e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park break; 475e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 476e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park return manager; 477e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 478e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 479e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park private void startCarService() { 480e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park Intent intent = new Intent(); 481e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park intent.setPackage(CAR_SERVICE_PACKAGE); 482e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park intent.setAction(Car.CAR_SERVICE_INTERFACE_NAME); 483e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park mContext.startService(intent); 484e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park mContext.bindService(intent, mServiceConnectionListener, 0); 485e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park } 486e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park 487ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private synchronized ICar getICarOrThrow() throws IllegalStateException { 488ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung if (mService == null) { 489ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung throw new IllegalStateException("not connected"); 490ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 491ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung return mService; 492ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 493ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 494ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private void handleRemoteException(RemoteException e) { 495ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung Log.w(CarLibLog.TAG_CAR, "RemoteException", e); 496ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung disconnect(); 497ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 498ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung 499ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung private void tearDownCarManagers() { 500ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung synchronized (mCarManagerLock) { 501ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung for (CarManagerBase manager: mServiceMap.values()) { 502ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung manager.onCarDisconnected(); 503ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 504ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung mServiceMap.clear(); 505ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 506ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung } 507ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung} 508