blob: 153a8f06fd0db55d06ca74c28c3fafca5508c855 [file] [log] [blame]
keunyoungca515072015-07-10 12:21:47 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.car;
18
Yao Chene33f07e2016-07-26 12:02:51 -070019import android.app.UiModeManager;
Keun-young Parke54ac272016-02-16 19:02:18 -080020import android.car.Car;
21import android.car.ICar;
Pavel Maltsev0477e292016-05-27 12:22:36 -070022import android.car.cluster.renderer.IInstrumentClusterNavigation;
keunyoungca515072015-07-10 12:21:47 -070023import android.content.Context;
keunyoung1ab8e182015-09-24 09:25:22 -070024import android.content.pm.PackageManager;
Pavel Maltsevcfe93102017-02-02 12:38:08 -080025import android.hardware.automotive.vehicle.V2_0.IVehicle;
keunyoungca515072015-07-10 12:21:47 -070026import android.os.IBinder;
keunyoungca515072015-07-10 12:21:47 -070027import android.util.Log;
28
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -080029import com.android.car.cluster.InstrumentClusterService;
keunyoungcc449f72015-08-12 10:46:27 -070030import com.android.car.hal.VehicleHal;
Keun-young Park4aeb4bf2015-12-08 18:31:33 -080031import com.android.car.pm.CarPackageManagerService;
keunyoungca515072015-07-10 12:21:47 -070032import com.android.internal.annotations.GuardedBy;
33
keunyounga3b28d82015-08-25 13:05:15 -070034import java.io.PrintWriter;
35
keunyoungca515072015-07-10 12:21:47 -070036public class ICarImpl extends ICar.Stub {
keunyoungca515072015-07-10 12:21:47 -070037
Keun-young Parka28d7b22016-02-29 16:54:29 -080038 public static final String INTERNAL_INPUT_SERVICE = "internal_input";
Keun-young Park4727da32016-05-31 10:00:51 -070039 public static final String INTERNAL_SYSTEM_ACTIVITY_MONITORING_SERVICE =
40 "system_activity_monitoring";
Keun-young Parka28d7b22016-02-29 16:54:29 -080041
42 // load jni for all services here
43 static {
Pavel Maltsev0d07c762016-11-03 16:40:15 -070044 try {
45 System.loadLibrary("jni_car_service");
46 } catch (UnsatisfiedLinkError ex) {
47 // Unable to load native library when loaded from the testing framework.
48 Log.e(CarLog.TAG_SERVICE, "Failed to load jni_car_service library: " + ex.getMessage());
49 }
Keun-young Parka28d7b22016-02-29 16:54:29 -080050 }
51
keunyoungca515072015-07-10 12:21:47 -070052 private final Context mContext;
Pavel Maltsevec83b632017-01-05 15:10:55 -080053 private final VehicleHal mHal;
keunyoungca515072015-07-10 12:21:47 -070054
Keun-young Park4727da32016-05-31 10:00:51 -070055 private final SystemActivityMonitoringService mSystemActivityMonitoringService;
keunyoung4b0212c2015-10-29 17:11:57 -070056 private final CarPowerManagementService mCarPowerManagementService;
Keun-young Parka28d7b22016-02-29 16:54:29 -080057 private final CarPackageManagerService mCarPackageManagerService;
58 private final CarInputService mCarInputService;
keunyoungca515072015-07-10 12:21:47 -070059 private final CarSensorService mCarSensorService;
keunyounga3b28d82015-08-25 13:05:15 -070060 private final CarInfoService mCarInfoService;
keunyoungd32f4e62015-09-21 11:33:06 -070061 private final CarAudioService mCarAudioService;
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -080062 private final CarProjectionService mCarProjectionService;
Steve Paik43c04a72016-07-08 19:12:09 -070063 private final CarCabinService mCarCabinService;
Steve Paik875616c2016-02-05 10:55:59 -080064 private final CarCameraService mCarCameraService;
Steve Paik66481982015-10-27 15:22:38 -070065 private final CarHvacService mCarHvacService;
Sanket Agarwal3cf096a2015-10-13 14:46:31 -070066 private final CarRadioService mCarRadioService;
Joseph Pirozzo317343d2016-01-25 10:22:37 -080067 private final CarNightService mCarNightService;
Vitalii Tomkiv46371472016-05-23 16:55:22 -070068 private final AppFocusService mAppFocusService;
Yao Chen3a7976d2016-01-20 17:27:08 -080069 private final GarageModeService mGarageModeService;
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -080070 private final InstrumentClusterService mInstrumentClusterService;
Keun-young Parkd73afae2016-04-08 20:03:32 -070071 private final SystemStateControllerService mSystemStateControllerService;
Pavel Maltsev634e1ff2016-07-14 15:41:26 -070072 private final CarVendorExtensionService mCarVendorExtensionService;
Ram Periathiruvadi7ed84182017-01-20 15:18:08 -080073 private final CarBluetoothService mCarBluetoothService;
keunyounga74b9ca2015-10-21 13:33:58 -070074
Pavel Maltsev0d07c762016-11-03 16:40:15 -070075 private final CarServiceBase[] mAllServices;
76
keunyoung1ab8e182015-09-24 09:25:22 -070077 /** Test only service. Populate it only when necessary. */
78 @GuardedBy("this")
79 private CarTestService mCarTestService;
keunyoungca515072015-07-10 12:21:47 -070080
Pavel Maltsevec83b632017-01-05 15:10:55 -080081 public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,
82 CanBusErrorNotifier errorNotifier) {
keunyoungca515072015-07-10 12:21:47 -070083 mContext = serviceContext;
Pavel Maltsev0d07c762016-11-03 16:40:15 -070084 mHal = new VehicleHal(vehicle);
Keun-young Park4727da32016-05-31 10:00:51 -070085 mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);
Pavel Maltsev0d07c762016-11-03 16:40:15 -070086 mCarPowerManagementService = new CarPowerManagementService(
87 mHal.getPowerHal(), systemInterface);
88 mCarSensorService = new CarSensorService(serviceContext, mHal.getSensorHal());
Keun-young Park4727da32016-05-31 10:00:51 -070089 mCarPackageManagerService = new CarPackageManagerService(serviceContext, mCarSensorService,
90 mSystemActivityMonitoringService);
Pavel Maltsev0d07c762016-11-03 16:40:15 -070091 mCarInputService = new CarInputService(serviceContext, mHal.getInputHal());
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -080092 mCarProjectionService = new CarProjectionService(serviceContext, mCarInputService);
Yao Chen3a7976d2016-01-20 17:27:08 -080093 mGarageModeService = new GarageModeService(mContext, mCarPowerManagementService);
Pavel Maltsev0d07c762016-11-03 16:40:15 -070094 mCarInfoService = new CarInfoService(serviceContext, mHal.getInfoHal());
Vitalii Tomkiv8c7f2972016-07-11 15:42:04 -070095 mAppFocusService = new AppFocusService(serviceContext, mSystemActivityMonitoringService);
Pavel Maltsev0d07c762016-11-03 16:40:15 -070096 mCarAudioService = new CarAudioService(serviceContext, mHal.getAudioHal(),
Pavel Maltsevec83b632017-01-05 15:10:55 -080097 mCarInputService, errorNotifier);
Pavel Maltsev0d07c762016-11-03 16:40:15 -070098 mCarCabinService = new CarCabinService(serviceContext, mHal.getCabinHal());
99 mCarHvacService = new CarHvacService(serviceContext, mHal.getHvacHal());
100 mCarRadioService = new CarRadioService(serviceContext, mHal.getRadioHal());
Steve Paik875616c2016-02-05 10:55:59 -0800101 mCarCameraService = new CarCameraService(serviceContext);
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700102 mCarNightService = new CarNightService(serviceContext, mCarSensorService);
Pavel Maltsev0477e292016-05-27 12:22:36 -0700103 mInstrumentClusterService = new InstrumentClusterService(serviceContext,
Pavel Maltsev03cf60c2016-06-27 15:11:51 -0700104 mAppFocusService, mCarInputService);
Keun-young Parkd73afae2016-04-08 20:03:32 -0700105 mSystemStateControllerService = new SystemStateControllerService(serviceContext,
Keun-young Park3cb89102016-05-05 13:16:03 -0700106 mCarPowerManagementService, mCarAudioService, this);
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700107 mCarVendorExtensionService = new CarVendorExtensionService(serviceContext,
108 mHal.getVendorExtensionHal());
Ram Periathiruvadi7ed84182017-01-20 15:18:08 -0800109 mCarBluetoothService = new CarBluetoothService(serviceContext, mCarCabinService);
keunyounga74b9ca2015-10-21 13:33:58 -0700110
keunyounga3b28d82015-08-25 13:05:15 -0700111 // Be careful with order. Service depending on other service should be inited later.
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700112 mAllServices = new CarServiceBase[]{
Keun-young Park4727da32016-05-31 10:00:51 -0700113 mSystemActivityMonitoringService,
keunyoung4b0212c2015-10-29 17:11:57 -0700114 mCarPowerManagementService,
Keun-young Park4727da32016-05-31 10:00:51 -0700115 mCarSensorService,
Keun-young Park45fdcba2015-12-08 11:38:58 -0800116 mCarPackageManagerService,
Keun-young Parka28d7b22016-02-29 16:54:29 -0800117 mCarInputService,
118 mGarageModeService,
keunyounga3b28d82015-08-25 13:05:15 -0700119 mCarInfoService,
Vitalii Tomkiv46371472016-05-23 16:55:22 -0700120 mAppFocusService,
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700121 mCarAudioService,
Steve Paik43c04a72016-07-08 19:12:09 -0700122 mCarCabinService,
Steve Paik66481982015-10-27 15:22:38 -0700123 mCarHvacService,
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800124 mCarRadioService,
125 mCarCameraService,
Joseph Pirozzo317343d2016-01-25 10:22:37 -0800126 mCarNightService,
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800127 mInstrumentClusterService,
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -0800128 mCarProjectionService,
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700129 mSystemStateControllerService,
Ram Periathiruvadi7ed84182017-01-20 15:18:08 -0800130 mCarVendorExtensionService,
131 mCarBluetoothService
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700132 };
keunyoungca515072015-07-10 12:21:47 -0700133 }
134
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700135 public void init() {
136 mHal.init();
keunyounga3b28d82015-08-25 13:05:15 -0700137 for (CarServiceBase service: mAllServices) {
138 service.init();
139 }
keunyoungca515072015-07-10 12:21:47 -0700140 }
141
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700142 public void release() {
keunyounga3b28d82015-08-25 13:05:15 -0700143 // release done in opposite order from init
144 for (int i = mAllServices.length - 1; i >= 0; i--) {
145 mAllServices[i].release();
146 }
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700147 mHal.release();
keunyoung1ab8e182015-09-24 09:25:22 -0700148 }
149
Pavel Maltsevec83b632017-01-05 15:10:55 -0800150 public void vehicleHalReconnected(IVehicle vehicle) {
151 mHal.vehicleHalReconnected(vehicle);
152 for (CarServiceBase service : mAllServices) {
153 service.vehicleHalReconnected();
154 }
155 }
156
keunyoungca515072015-07-10 12:21:47 -0700157 @Override
keunyoungca515072015-07-10 12:21:47 -0700158 public IBinder getCarService(String serviceName) {
159 switch (serviceName) {
Keun-young Park5672e852016-02-09 19:53:48 -0800160 case Car.AUDIO_SERVICE:
161 return mCarAudioService;
keunyoungca515072015-07-10 12:21:47 -0700162 case Car.SENSOR_SERVICE:
163 return mCarSensorService;
keunyounga3b28d82015-08-25 13:05:15 -0700164 case Car.INFO_SERVICE:
165 return mCarInfoService;
Vitalii Tomkiv46371472016-05-23 16:55:22 -0700166 case Car.APP_FOCUS_SERVICE:
167 return mAppFocusService;
Keun-young Park45fdcba2015-12-08 11:38:58 -0800168 case Car.PACKAGE_SERVICE:
169 return mCarPackageManagerService;
Steve Paik43c04a72016-07-08 19:12:09 -0700170 case Car.CABIN_SERVICE:
171 assertCabinPermission(mContext);
172 return mCarCabinService;
Steve Paik875616c2016-02-05 10:55:59 -0800173 case Car.CAMERA_SERVICE:
174 assertCameraPermission(mContext);
175 return mCarCameraService;
Keun-young Parke54ac272016-02-16 19:02:18 -0800176 case Car.HVAC_SERVICE:
Steve Paik66481982015-10-27 15:22:38 -0700177 assertHvacPermission(mContext);
178 return mCarHvacService;
Keun-young Parke54ac272016-02-16 19:02:18 -0800179 case Car.RADIO_SERVICE:
keunyoung6b197692015-11-16 13:54:38 -0800180 assertRadioPermission(mContext);
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700181 return mCarRadioService;
Pavel Maltsev7a948e52016-02-02 23:30:14 -0800182 case Car.CAR_NAVIGATION_SERVICE:
Keun-young Parke31a8b22016-03-16 17:34:08 -0700183 assertNavigationManagerPermission(mContext);
Pavel Maltsev0477e292016-05-27 12:22:36 -0700184 IInstrumentClusterNavigation navService =
185 mInstrumentClusterService.getNavigationService();
186 return navService == null ? null : navService.asBinder();
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -0800187 case Car.PROJECTION_SERVICE:
188 assertProjectionPermission(mContext);
189 return mCarProjectionService;
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700190 case Car.VENDOR_EXTENSION_SERVICE:
191 assertVendorExtensionPermission(mContext);
192 return mCarVendorExtensionService;
Keun-young Parke54ac272016-02-16 19:02:18 -0800193 case Car.TEST_SERVICE: {
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700194 assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
keunyoung1ab8e182015-09-24 09:25:22 -0700195 synchronized (this) {
196 if (mCarTestService == null) {
197 mCarTestService = new CarTestService(mContext, this);
198 }
199 return mCarTestService;
200 }
201 }
keunyoungca515072015-07-10 12:21:47 -0700202 default:
203 Log.w(CarLog.TAG_SERVICE, "getCarService for unknown service:" + serviceName);
204 return null;
205 }
206 }
207
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800208 @Override
209 public int getCarConnectionType() {
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700210 return Car.CONNECTION_TYPE_EMBEDDED;
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800211 }
212
Keun-young Parka28d7b22016-02-29 16:54:29 -0800213 public CarServiceBase getCarInternalService(String serviceName) {
214 switch (serviceName) {
215 case INTERNAL_INPUT_SERVICE:
216 return mCarInputService;
Keun-young Park4727da32016-05-31 10:00:51 -0700217 case INTERNAL_SYSTEM_ACTIVITY_MONITORING_SERVICE:
218 return mSystemActivityMonitoringService;
Keun-young Parka28d7b22016-02-29 16:54:29 -0800219 default:
220 Log.w(CarLog.TAG_SERVICE, "getCarInternalService for unknown service:" +
221 serviceName);
222 return null;
223 }
224 }
225
keunyoung1ab8e182015-09-24 09:25:22 -0700226 public static void assertVehicleHalMockPermission(Context context) {
Steve Paik461ecc62016-06-08 15:28:32 -0700227 assertPermission(context, Car.PERMISSION_MOCK_VEHICLE_HAL);
keunyoung1ab8e182015-09-24 09:25:22 -0700228 }
229
Steve Paik43c04a72016-07-08 19:12:09 -0700230 public static void assertCabinPermission(Context context) {
231 assertPermission(context, Car.PERMISSION_CAR_CABIN);
232 }
233
Steve Paik875616c2016-02-05 10:55:59 -0800234 public static void assertCameraPermission(Context context) {
Steve Paik461ecc62016-06-08 15:28:32 -0700235 assertPermission(context, Car.PERMISSION_CAR_CAMERA);
Steve Paik875616c2016-02-05 10:55:59 -0800236 }
237
Keun-young Parke31a8b22016-03-16 17:34:08 -0700238 public static void assertNavigationManagerPermission(Context context) {
Steve Paik461ecc62016-06-08 15:28:32 -0700239 assertPermission(context, Car.PERMISSION_CAR_NAVIGATION_MANAGER);
Pavel Maltsevce4ffd92016-03-09 10:56:23 -0800240 }
241
Steve Paik66481982015-10-27 15:22:38 -0700242 public static void assertHvacPermission(Context context) {
Steve Paik461ecc62016-06-08 15:28:32 -0700243 assertPermission(context, Car.PERMISSION_CAR_HVAC);
Steve Paik66481982015-10-27 15:22:38 -0700244 }
245
keunyoung6b197692015-11-16 13:54:38 -0800246 private static void assertRadioPermission(Context context) {
Steve Paik461ecc62016-06-08 15:28:32 -0700247 assertPermission(context, Car.PERMISSION_CAR_RADIO);
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700248 }
249
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -0800250 public static void assertProjectionPermission(Context context) {
Steve Paik461ecc62016-06-08 15:28:32 -0700251 assertPermission(context, Car.PERMISSION_CAR_PROJECTION);
252 }
253
Pavel Maltsev634e1ff2016-07-14 15:41:26 -0700254 public static void assertVendorExtensionPermission(Context context) {
255 assertPermission(context, Car.PERMISSION_VENDOR_EXTENSION);
256 }
257
Steve Paik461ecc62016-06-08 15:28:32 -0700258 public static void assertPermission(Context context, String permission) {
259 if (context.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
260 throw new SecurityException("requires " + permission);
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -0800261 }
262 }
263
keunyoungcc449f72015-08-12 10:46:27 -0700264 void dump(PrintWriter writer) {
Keun-young Parkbae6e252017-01-25 12:30:15 -0800265 writer.println("*FutureConfig, DEFAULT:" + FeatureConfiguration.DEFAULT);
266 //TODO dump all feature flags by reflection
keunyounga3b28d82015-08-25 13:05:15 -0700267 writer.println("*Dump all services*");
268 for (CarServiceBase service: mAllServices) {
269 service.dump(writer);
270 }
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700271 if (mCarTestService != null) {
272 mCarTestService.dump(writer);
keunyoung1ab8e182015-09-24 09:25:22 -0700273 }
Pavel Maltsev0d07c762016-11-03 16:40:15 -0700274 writer.println("*Dump Vehicle HAL*");
275 mHal.dump(writer);
keunyoungcc449f72015-08-12 10:46:27 -0700276 }
Yao Chene33f07e2016-07-26 12:02:51 -0700277
278 void execShellCmd(String[] args, PrintWriter writer) {
279 new CarShellCommand().exec(args, writer);
280 }
281
282 private class CarShellCommand {
283 private static final String COMMAND_HELP = "-h";
284 private static final String COMMAND_DAY_NIGHT_MODE = "day-night-mode";
285 private static final String PARAM_DAY_MODE = "day";
286 private static final String PARAM_NIGHT_MODE = "night";
287 private static final String PARAM_SENSOR_MODE = "sensor";
288
289 private void dumpHelp(PrintWriter pw) {
290 pw.println("Car service commands:");
291 pw.println("\t-h");
292 pw.println("\t Print this help text.");
293 pw.println("\tday-night-mode [day|night|sensor]");
294 pw.println("\t Force into day/night mode or restore to auto.");
295 }
296
297 public void exec(String[] args, PrintWriter writer) {
298 String arg = args[0];
299 switch (arg) {
300 case COMMAND_HELP:
301 dumpHelp(writer);
302 break;
303 case COMMAND_DAY_NIGHT_MODE:
304 String value = args.length < 1 ? "" : args[1];
305 forceDayNightMode(value, writer);
306 break;
307 default:
308 writer.println("Unknown command.");
309 dumpHelp(writer);
310 }
311 }
312
313 private void forceDayNightMode(String arg, PrintWriter writer) {
314 int mode;
315 switch (arg) {
316 case PARAM_DAY_MODE:
317 mode = CarNightService.FORCED_DAY_MODE;
318 break;
319 case PARAM_NIGHT_MODE:
320 mode = CarNightService.FORCED_NIGHT_MODE;
321 break;
322 case PARAM_SENSOR_MODE:
323 mode = CarNightService.FORCED_SENSOR_MODE;
324 break;
325 default:
326 writer.println("Unknown value. Valid argument: " + PARAM_DAY_MODE + "|"
327 + PARAM_NIGHT_MODE + "|" + PARAM_SENSOR_MODE);
328 return;
329 }
330 int current = mCarNightService.forceDayNightMode(mode);
331 String currentMode = null;
332 switch (current) {
333 case UiModeManager.MODE_NIGHT_AUTO:
334 currentMode = PARAM_SENSOR_MODE;
335 break;
336 case UiModeManager.MODE_NIGHT_YES:
337 currentMode = PARAM_NIGHT_MODE;
338 break;
339 case UiModeManager.MODE_NIGHT_NO:
340 currentMode = PARAM_DAY_MODE;
341 break;
342 }
343 writer.println("DayNightMode changed to: " + currentMode);
344 }
345 }
346}