blob: c296c5355943ce23762cfcfb2033c0a33337829a [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
Keun-young Parke54ac272016-02-16 19:02:18 -080019import android.car.Car;
20import android.car.ICar;
Pavel Maltsev0477e292016-05-27 12:22:36 -070021import android.car.cluster.renderer.IInstrumentClusterNavigation;
keunyoungca515072015-07-10 12:21:47 -070022import android.content.Context;
keunyoung1ab8e182015-09-24 09:25:22 -070023import android.content.pm.PackageManager;
keunyoungca515072015-07-10 12:21:47 -070024import android.os.IBinder;
keunyoungca515072015-07-10 12:21:47 -070025import android.util.Log;
26
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -080027import com.android.car.cluster.InstrumentClusterService;
keunyoungcc449f72015-08-12 10:46:27 -070028import com.android.car.hal.VehicleHal;
Keun-young Park4aeb4bf2015-12-08 18:31:33 -080029import com.android.car.pm.CarPackageManagerService;
keunyoungca515072015-07-10 12:21:47 -070030import com.android.internal.annotations.GuardedBy;
31
keunyounga3b28d82015-08-25 13:05:15 -070032import java.io.PrintWriter;
33
keunyoungca515072015-07-10 12:21:47 -070034public class ICarImpl extends ICar.Stub {
keunyoungca515072015-07-10 12:21:47 -070035
Keun-young Parka28d7b22016-02-29 16:54:29 -080036 public static final String INTERNAL_INPUT_SERVICE = "internal_input";
Keun-young Park4727da32016-05-31 10:00:51 -070037 public static final String INTERNAL_SYSTEM_ACTIVITY_MONITORING_SERVICE =
38 "system_activity_monitoring";
Keun-young Parka28d7b22016-02-29 16:54:29 -080039
40 // load jni for all services here
41 static {
42 System.loadLibrary("jni_car_service");
43 }
44
keunyoungca515072015-07-10 12:21:47 -070045 @GuardedBy("ICarImpl.class")
46 private static ICarImpl sInstance = null;
47
48 private final Context mContext;
keunyoungcc449f72015-08-12 10:46:27 -070049 private final VehicleHal mHal;
keunyoungca515072015-07-10 12:21:47 -070050
Keun-young Park4727da32016-05-31 10:00:51 -070051 private final SystemActivityMonitoringService mSystemActivityMonitoringService;
keunyoung4b0212c2015-10-29 17:11:57 -070052 private final CarPowerManagementService mCarPowerManagementService;
Keun-young Parka28d7b22016-02-29 16:54:29 -080053 private final CarPackageManagerService mCarPackageManagerService;
54 private final CarInputService mCarInputService;
keunyoungca515072015-07-10 12:21:47 -070055 private final CarSensorService mCarSensorService;
keunyounga3b28d82015-08-25 13:05:15 -070056 private final CarInfoService mCarInfoService;
keunyoungd32f4e62015-09-21 11:33:06 -070057 private final CarAudioService mCarAudioService;
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -080058 private final CarProjectionService mCarProjectionService;
Steve Paik875616c2016-02-05 10:55:59 -080059 private final CarCameraService mCarCameraService;
Steve Paik66481982015-10-27 15:22:38 -070060 private final CarHvacService mCarHvacService;
Sanket Agarwal3cf096a2015-10-13 14:46:31 -070061 private final CarRadioService mCarRadioService;
Joseph Pirozzo317343d2016-01-25 10:22:37 -080062 private final CarNightService mCarNightService;
Vitalii Tomkiv46371472016-05-23 16:55:22 -070063 private final AppFocusService mAppFocusService;
Yao Chen3a7976d2016-01-20 17:27:08 -080064 private final GarageModeService mGarageModeService;
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -080065 private final InstrumentClusterService mInstrumentClusterService;
Keun-young Parkd73afae2016-04-08 20:03:32 -070066 private final SystemStateControllerService mSystemStateControllerService;
keunyounga74b9ca2015-10-21 13:33:58 -070067
keunyoung1ab8e182015-09-24 09:25:22 -070068 /** Test only service. Populate it only when necessary. */
69 @GuardedBy("this")
70 private CarTestService mCarTestService;
keunyounga3b28d82015-08-25 13:05:15 -070071 private final CarServiceBase[] mAllServices;
keunyoungca515072015-07-10 12:21:47 -070072
73 public synchronized static ICarImpl getInstance(Context serviceContext) {
74 if (sInstance == null) {
75 sInstance = new ICarImpl(serviceContext);
76 sInstance.init();
77 }
78 return sInstance;
79 }
80
81 public synchronized static void releaseInstance() {
82 if (sInstance == null) {
83 return;
84 }
85 sInstance.release();
86 sInstance = null;
87 }
88
89 public ICarImpl(Context serviceContext) {
90 mContext = serviceContext;
keunyoungfe30ba02015-09-17 17:56:35 -070091 mHal = VehicleHal.getInstance();
Keun-young Park4727da32016-05-31 10:00:51 -070092 mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);
keunyoung4b0212c2015-10-29 17:11:57 -070093 mCarPowerManagementService = new CarPowerManagementService(serviceContext);
Keun-young Park4727da32016-05-31 10:00:51 -070094 mCarSensorService = new CarSensorService(serviceContext);
95 mCarPackageManagerService = new CarPackageManagerService(serviceContext, mCarSensorService,
96 mSystemActivityMonitoringService);
Keun-young Parka28d7b22016-02-29 16:54:29 -080097 mCarInputService = new CarInputService(serviceContext);
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -080098 mCarProjectionService = new CarProjectionService(serviceContext, mCarInputService);
Yao Chen3a7976d2016-01-20 17:27:08 -080099 mGarageModeService = new GarageModeService(mContext, mCarPowerManagementService);
keunyounga3b28d82015-08-25 13:05:15 -0700100 mCarInfoService = new CarInfoService(serviceContext);
Vitalii Tomkiv46371472016-05-23 16:55:22 -0700101 mAppFocusService = new AppFocusService(serviceContext);
Yao Chenc4d442f2016-04-08 11:33:47 -0700102 mCarAudioService = new CarAudioService(serviceContext, mCarInputService);
Steve Paik66481982015-10-27 15:22:38 -0700103 mCarHvacService = new CarHvacService(serviceContext);
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700104 mCarRadioService = new CarRadioService(serviceContext);
Steve Paik875616c2016-02-05 10:55:59 -0800105 mCarCameraService = new CarCameraService(serviceContext);
Joseph Pirozzo317343d2016-01-25 10:22:37 -0800106 mCarNightService = new CarNightService(serviceContext);
Pavel Maltsev0477e292016-05-27 12:22:36 -0700107 mInstrumentClusterService = new InstrumentClusterService(serviceContext,
108 mAppFocusService);
Keun-young Parkd73afae2016-04-08 20:03:32 -0700109 mSystemStateControllerService = new SystemStateControllerService(serviceContext,
Keun-young Park3cb89102016-05-05 13:16:03 -0700110 mCarPowerManagementService, mCarAudioService, this);
keunyounga74b9ca2015-10-21 13:33:58 -0700111
keunyounga3b28d82015-08-25 13:05:15 -0700112 // Be careful with order. Service depending on other service should be inited later.
113 mAllServices = new CarServiceBase[] {
Keun-young Park4727da32016-05-31 10:00:51 -0700114 mSystemActivityMonitoringService,
keunyoung4b0212c2015-10-29 17:11:57 -0700115 mCarPowerManagementService,
Keun-young Park4727da32016-05-31 10:00:51 -0700116 mCarSensorService,
Keun-young Park45fdcba2015-12-08 11:38:58 -0800117 mCarPackageManagerService,
Keun-young Parka28d7b22016-02-29 16:54:29 -0800118 mCarInputService,
119 mGarageModeService,
keunyounga3b28d82015-08-25 13:05:15 -0700120 mCarInfoService,
Vitalii Tomkiv46371472016-05-23 16:55:22 -0700121 mAppFocusService,
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700122 mCarAudioService,
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,
Keun-young Parkd73afae2016-04-08 20:03:32 -0700129 mSystemStateControllerService
keunyounga74b9ca2015-10-21 13:33:58 -0700130 };
keunyoungca515072015-07-10 12:21:47 -0700131 }
132
133 private void init() {
keunyounga3b28d82015-08-25 13:05:15 -0700134 for (CarServiceBase service: mAllServices) {
135 service.init();
136 }
keunyoungca515072015-07-10 12:21:47 -0700137 }
138
139 private void release() {
keunyounga3b28d82015-08-25 13:05:15 -0700140 // release done in opposite order from init
141 for (int i = mAllServices.length - 1; i >= 0; i--) {
142 mAllServices[i].release();
143 }
keunyoungcc449f72015-08-12 10:46:27 -0700144 VehicleHal.releaseInstance();
keunyoungca515072015-07-10 12:21:47 -0700145 }
146
keunyoung4b0212c2015-10-29 17:11:57 -0700147 /** Only for CarTestService */
148 void startMocking() {
keunyoung1ab8e182015-09-24 09:25:22 -0700149 reinitServices();
150 }
151
keunyoung4b0212c2015-10-29 17:11:57 -0700152 /** Only for CarTestService */
153 void stopMocking() {
keunyoung1ab8e182015-09-24 09:25:22 -0700154 reinitServices();
155 }
156
keunyoung6b197692015-11-16 13:54:38 -0800157 /** Reset all services when starting / stopping vehicle hal mocking */
keunyoung1ab8e182015-09-24 09:25:22 -0700158 private void reinitServices() {
159 for (int i = mAllServices.length - 1; i >= 0; i--) {
160 mAllServices[i].release();
161 }
Keun-young Park021310d2016-04-25 21:09:39 -0700162 VehicleHal.getInstance().release();
163 VehicleHal.getInstance().init();
keunyoung1ab8e182015-09-24 09:25:22 -0700164 for (CarServiceBase service: mAllServices) {
165 service.init();
166 }
167 }
168
keunyoungca515072015-07-10 12:21:47 -0700169 @Override
keunyoungca515072015-07-10 12:21:47 -0700170 public IBinder getCarService(String serviceName) {
171 switch (serviceName) {
Keun-young Park5672e852016-02-09 19:53:48 -0800172 case Car.AUDIO_SERVICE:
173 return mCarAudioService;
keunyoungca515072015-07-10 12:21:47 -0700174 case Car.SENSOR_SERVICE:
175 return mCarSensorService;
keunyounga3b28d82015-08-25 13:05:15 -0700176 case Car.INFO_SERVICE:
177 return mCarInfoService;
Vitalii Tomkiv46371472016-05-23 16:55:22 -0700178 case Car.APP_FOCUS_SERVICE:
179 return mAppFocusService;
Keun-young Park45fdcba2015-12-08 11:38:58 -0800180 case Car.PACKAGE_SERVICE:
181 return mCarPackageManagerService;
Steve Paik875616c2016-02-05 10:55:59 -0800182 case Car.CAMERA_SERVICE:
183 assertCameraPermission(mContext);
184 return mCarCameraService;
Keun-young Parke54ac272016-02-16 19:02:18 -0800185 case Car.HVAC_SERVICE:
Steve Paik66481982015-10-27 15:22:38 -0700186 assertHvacPermission(mContext);
187 return mCarHvacService;
Keun-young Parke54ac272016-02-16 19:02:18 -0800188 case Car.RADIO_SERVICE:
keunyoung6b197692015-11-16 13:54:38 -0800189 assertRadioPermission(mContext);
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700190 return mCarRadioService;
Pavel Maltsev7a948e52016-02-02 23:30:14 -0800191 case Car.CAR_NAVIGATION_SERVICE:
Keun-young Parke31a8b22016-03-16 17:34:08 -0700192 assertNavigationManagerPermission(mContext);
Pavel Maltsev0477e292016-05-27 12:22:36 -0700193 IInstrumentClusterNavigation navService =
194 mInstrumentClusterService.getNavigationService();
195 return navService == null ? null : navService.asBinder();
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -0800196 case Car.PROJECTION_SERVICE:
197 assertProjectionPermission(mContext);
198 return mCarProjectionService;
Keun-young Parke54ac272016-02-16 19:02:18 -0800199 case Car.TEST_SERVICE: {
keunyoung1ab8e182015-09-24 09:25:22 -0700200 assertVehicleHalMockPermission(mContext);
201 synchronized (this) {
202 if (mCarTestService == null) {
203 mCarTestService = new CarTestService(mContext, this);
204 }
205 return mCarTestService;
206 }
207 }
keunyoungca515072015-07-10 12:21:47 -0700208 default:
209 Log.w(CarLog.TAG_SERVICE, "getCarService for unknown service:" + serviceName);
210 return null;
211 }
212 }
213
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800214 @Override
215 public int getCarConnectionType() {
216 if (!isInMocking()) {
217 return Car.CONNECTION_TYPE_EMBEDDED;
218 } else {
219 return Car.CONNECTION_TYPE_EMBEDDED_MOCKING;
220 }
221 }
222
Keun-young Parka28d7b22016-02-29 16:54:29 -0800223 public CarServiceBase getCarInternalService(String serviceName) {
224 switch (serviceName) {
225 case INTERNAL_INPUT_SERVICE:
226 return mCarInputService;
Keun-young Park4727da32016-05-31 10:00:51 -0700227 case INTERNAL_SYSTEM_ACTIVITY_MONITORING_SERVICE:
228 return mSystemActivityMonitoringService;
Keun-young Parka28d7b22016-02-29 16:54:29 -0800229 default:
230 Log.w(CarLog.TAG_SERVICE, "getCarInternalService for unknown service:" +
231 serviceName);
232 return null;
233 }
234 }
235
keunyoung4b0212c2015-10-29 17:11:57 -0700236 /**
237 * Whether mocking underlying HAL or not.
238 * @return
239 */
240 public synchronized boolean isInMocking() {
241 if (mCarTestService == null) {
242 return false;
243 }
244 return mCarTestService.isInMocking();
245 }
246
keunyoung1ab8e182015-09-24 09:25:22 -0700247 public static void assertVehicleHalMockPermission(Context context) {
Keun-young Parke54ac272016-02-16 19:02:18 -0800248 if (context.checkCallingOrSelfPermission(Car.PERMISSION_MOCK_VEHICLE_HAL)
keunyoung1ab8e182015-09-24 09:25:22 -0700249 != PackageManager.PERMISSION_GRANTED) {
250 throw new SecurityException("requires CAR_MOCK_VEHICLE_HAL permission");
251 }
252 }
253
Steve Paik875616c2016-02-05 10:55:59 -0800254 public static void assertCameraPermission(Context context) {
255 if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_CAMERA)
256 != PackageManager.PERMISSION_GRANTED) {
257 throw new SecurityException(
258 "requires " + Car.PERMISSION_CAR_CAMERA);
259 }
260 }
261
Keun-young Parke31a8b22016-03-16 17:34:08 -0700262 public static void assertNavigationManagerPermission(Context context) {
Pavel Maltsevce4ffd92016-03-09 10:56:23 -0800263 if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_NAVIGATION_MANAGER)
264 != PackageManager.PERMISSION_GRANTED) {
265 throw new SecurityException(
266 "requires " + Car.PERMISSION_CAR_NAVIGATION_MANAGER);
267 }
268 }
269
Steve Paik66481982015-10-27 15:22:38 -0700270 public static void assertHvacPermission(Context context) {
Keun-young Parke54ac272016-02-16 19:02:18 -0800271 if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_HVAC)
Steve Paik66481982015-10-27 15:22:38 -0700272 != PackageManager.PERMISSION_GRANTED) {
273 throw new SecurityException(
Keun-young Parke54ac272016-02-16 19:02:18 -0800274 "requires " + Car.PERMISSION_CAR_HVAC);
Steve Paik66481982015-10-27 15:22:38 -0700275 }
276 }
277
keunyoung6b197692015-11-16 13:54:38 -0800278 private static void assertRadioPermission(Context context) {
Keun-young Parke54ac272016-02-16 19:02:18 -0800279 if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_RADIO)
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700280 != PackageManager.PERMISSION_GRANTED) {
281 throw new SecurityException(
Keun-young Parke54ac272016-02-16 19:02:18 -0800282 "requires permission " + Car.PERMISSION_CAR_RADIO);
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700283 }
284 }
285
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -0800286 public static void assertProjectionPermission(Context context) {
287 if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_PROJECTION)
288 != PackageManager.PERMISSION_GRANTED) {
289 throw new SecurityException(
290 "requires " + Car.PERMISSION_CAR_PROJECTION);
291 }
292 }
293
keunyoungcc449f72015-08-12 10:46:27 -0700294 void dump(PrintWriter writer) {
keunyounga3b28d82015-08-25 13:05:15 -0700295 writer.println("*Dump all services*");
296 for (CarServiceBase service: mAllServices) {
297 service.dump(writer);
298 }
keunyoung1ab8e182015-09-24 09:25:22 -0700299 CarTestService testService = mCarTestService;
300 if (testService != null) {
301 testService.dump(writer);
302 }
keunyoungcc449f72015-08-12 10:46:27 -0700303 }
keunyoungca515072015-07-10 12:21:47 -0700304}