blob: 89ee5daa5e4ddc38d0cc252e2af803944ada2973 [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;
keunyoungca515072015-07-10 12:21:47 -070021import android.content.Context;
keunyoung1ab8e182015-09-24 09:25:22 -070022import android.content.pm.PackageManager;
keunyoungca515072015-07-10 12:21:47 -070023import android.os.IBinder;
keunyoungca515072015-07-10 12:21:47 -070024import android.util.Log;
25
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -080026import com.android.car.cluster.CarNavigationService;
27import com.android.car.cluster.InstrumentClusterService;
28import com.android.car.cluster.MediaStatusService;
keunyoungcc449f72015-08-12 10:46:27 -070029import com.android.car.hal.VehicleHal;
Keun-young Park4aeb4bf2015-12-08 18:31:33 -080030import com.android.car.pm.CarPackageManagerService;
keunyoungca515072015-07-10 12:21:47 -070031import com.android.internal.annotations.GuardedBy;
32
keunyounga3b28d82015-08-25 13:05:15 -070033import java.io.PrintWriter;
34
keunyoungca515072015-07-10 12:21:47 -070035public class ICarImpl extends ICar.Stub {
keunyoungca515072015-07-10 12:21:47 -070036
Keun-young Parka28d7b22016-02-29 16:54:29 -080037 public static final String INTERNAL_INPUT_SERVICE = "internal_input";
38
39 // load jni for all services here
40 static {
41 System.loadLibrary("jni_car_service");
42 }
43
keunyoungca515072015-07-10 12:21:47 -070044 @GuardedBy("ICarImpl.class")
45 private static ICarImpl sInstance = null;
46
47 private final Context mContext;
keunyoungcc449f72015-08-12 10:46:27 -070048 private final VehicleHal mHal;
keunyoungca515072015-07-10 12:21:47 -070049
keunyoung4b0212c2015-10-29 17:11:57 -070050 private final CarPowerManagementService mCarPowerManagementService;
Keun-young Parka28d7b22016-02-29 16:54:29 -080051 private final CarPackageManagerService mCarPackageManagerService;
52 private final CarInputService mCarInputService;
keunyoungca515072015-07-10 12:21:47 -070053 private final CarSensorService mCarSensorService;
keunyounga3b28d82015-08-25 13:05:15 -070054 private final CarInfoService mCarInfoService;
keunyoungd32f4e62015-09-21 11:33:06 -070055 private final CarAudioService mCarAudioService;
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -080056 private final CarProjectionService mCarProjectionService;
Steve Paik875616c2016-02-05 10:55:59 -080057 private final CarCameraService mCarCameraService;
Steve Paik66481982015-10-27 15:22:38 -070058 private final CarHvacService mCarHvacService;
Sanket Agarwal3cf096a2015-10-13 14:46:31 -070059 private final CarRadioService mCarRadioService;
Joseph Pirozzo317343d2016-01-25 10:22:37 -080060 private final CarNightService mCarNightService;
keunyounga74b9ca2015-10-21 13:33:58 -070061 private final AppContextService mAppContextService;
Yao Chen3a7976d2016-01-20 17:27:08 -080062 private final GarageModeService mGarageModeService;
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -080063 private final CarNavigationService mCarNavigationService;
64 private final MediaStatusService mMediaStatusService;
65 private final InstrumentClusterService mInstrumentClusterService;
keunyounga74b9ca2015-10-21 13:33:58 -070066
keunyoung1ab8e182015-09-24 09:25:22 -070067 /** Test only service. Populate it only when necessary. */
68 @GuardedBy("this")
69 private CarTestService mCarTestService;
keunyounga3b28d82015-08-25 13:05:15 -070070 private final CarServiceBase[] mAllServices;
keunyoungca515072015-07-10 12:21:47 -070071
72 public synchronized static ICarImpl getInstance(Context serviceContext) {
73 if (sInstance == null) {
74 sInstance = new ICarImpl(serviceContext);
75 sInstance.init();
76 }
77 return sInstance;
78 }
79
80 public synchronized static void releaseInstance() {
81 if (sInstance == null) {
82 return;
83 }
84 sInstance.release();
85 sInstance = null;
86 }
87
88 public ICarImpl(Context serviceContext) {
89 mContext = serviceContext;
keunyoungfe30ba02015-09-17 17:56:35 -070090 mHal = VehicleHal.getInstance();
keunyoung4b0212c2015-10-29 17:11:57 -070091 mCarPowerManagementService = new CarPowerManagementService(serviceContext);
Keun-young Parka28d7b22016-02-29 16:54:29 -080092 mCarInputService = new CarInputService(serviceContext);
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -080093 mCarProjectionService = new CarProjectionService(serviceContext, mCarInputService);
Yao Chen3a7976d2016-01-20 17:27:08 -080094 mGarageModeService = new GarageModeService(mContext, mCarPowerManagementService);
keunyounga3b28d82015-08-25 13:05:15 -070095 mCarInfoService = new CarInfoService(serviceContext);
keunyounga74b9ca2015-10-21 13:33:58 -070096 mAppContextService = new AppContextService(serviceContext);
keunyoungca515072015-07-10 12:21:47 -070097 mCarSensorService = new CarSensorService(serviceContext);
Keun-young Parka28d7b22016-02-29 16:54:29 -080098 mCarAudioService = new CarAudioService(serviceContext);
Steve Paik66481982015-10-27 15:22:38 -070099 mCarHvacService = new CarHvacService(serviceContext);
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700100 mCarRadioService = new CarRadioService(serviceContext);
Steve Paik875616c2016-02-05 10:55:59 -0800101 mCarCameraService = new CarCameraService(serviceContext);
Joseph Pirozzo317343d2016-01-25 10:22:37 -0800102 mCarNightService = new CarNightService(serviceContext);
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800103 mCarPackageManagerService = new CarPackageManagerService(serviceContext);
104 mInstrumentClusterService = new InstrumentClusterService(serviceContext);
105 mMediaStatusService = new MediaStatusService(serviceContext, mInstrumentClusterService);
106 mCarNavigationService = new CarNavigationService(
107 serviceContext, mAppContextService, mInstrumentClusterService);
keunyounga74b9ca2015-10-21 13:33:58 -0700108
keunyounga3b28d82015-08-25 13:05:15 -0700109 // Be careful with order. Service depending on other service should be inited later.
110 mAllServices = new CarServiceBase[] {
keunyoung4b0212c2015-10-29 17:11:57 -0700111 mCarPowerManagementService,
Keun-young Park45fdcba2015-12-08 11:38:58 -0800112 mCarPackageManagerService,
Keun-young Parka28d7b22016-02-29 16:54:29 -0800113 mCarInputService,
114 mGarageModeService,
keunyounga3b28d82015-08-25 13:05:15 -0700115 mCarInfoService,
keunyounga74b9ca2015-10-21 13:33:58 -0700116 mAppContextService,
keunyoungd32f4e62015-09-21 11:33:06 -0700117 mCarSensorService,
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700118 mCarAudioService,
Steve Paik66481982015-10-27 15:22:38 -0700119 mCarHvacService,
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800120 mCarRadioService,
121 mCarCameraService,
Joseph Pirozzo317343d2016-01-25 10:22:37 -0800122 mCarNightService,
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800123 mInstrumentClusterService,
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -0800124 mCarProjectionService,
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800125 mCarNavigationService,
126 mMediaStatusService
keunyounga74b9ca2015-10-21 13:33:58 -0700127 };
keunyoungca515072015-07-10 12:21:47 -0700128 }
129
130 private void init() {
keunyounga3b28d82015-08-25 13:05:15 -0700131 for (CarServiceBase service: mAllServices) {
132 service.init();
133 }
keunyoungca515072015-07-10 12:21:47 -0700134 }
135
136 private void release() {
keunyounga3b28d82015-08-25 13:05:15 -0700137 // release done in opposite order from init
138 for (int i = mAllServices.length - 1; i >= 0; i--) {
139 mAllServices[i].release();
140 }
keunyoungcc449f72015-08-12 10:46:27 -0700141 VehicleHal.releaseInstance();
keunyoungca515072015-07-10 12:21:47 -0700142 }
143
keunyoung4b0212c2015-10-29 17:11:57 -0700144 /** Only for CarTestService */
145 void startMocking() {
keunyoung1ab8e182015-09-24 09:25:22 -0700146 reinitServices();
147 }
148
keunyoung4b0212c2015-10-29 17:11:57 -0700149 /** Only for CarTestService */
150 void stopMocking() {
keunyoung1ab8e182015-09-24 09:25:22 -0700151 reinitServices();
152 }
153
keunyoung6b197692015-11-16 13:54:38 -0800154 /** Reset all services when starting / stopping vehicle hal mocking */
keunyoung1ab8e182015-09-24 09:25:22 -0700155 private void reinitServices() {
156 for (int i = mAllServices.length - 1; i >= 0; i--) {
157 mAllServices[i].release();
158 }
159 for (CarServiceBase service: mAllServices) {
160 service.init();
161 }
162 }
163
keunyoungca515072015-07-10 12:21:47 -0700164 @Override
keunyoungca515072015-07-10 12:21:47 -0700165 public IBinder getCarService(String serviceName) {
166 switch (serviceName) {
Keun-young Park5672e852016-02-09 19:53:48 -0800167 case Car.AUDIO_SERVICE:
168 return mCarAudioService;
keunyoungca515072015-07-10 12:21:47 -0700169 case Car.SENSOR_SERVICE:
170 return mCarSensorService;
keunyounga3b28d82015-08-25 13:05:15 -0700171 case Car.INFO_SERVICE:
172 return mCarInfoService;
keunyounge4c90c42015-11-16 18:42:52 -0800173 case Car.APP_CONTEXT_SERVICE:
174 return mAppContextService;
Keun-young Park45fdcba2015-12-08 11:38:58 -0800175 case Car.PACKAGE_SERVICE:
176 return mCarPackageManagerService;
Steve Paik875616c2016-02-05 10:55:59 -0800177 case Car.CAMERA_SERVICE:
178 assertCameraPermission(mContext);
179 return mCarCameraService;
Keun-young Parke54ac272016-02-16 19:02:18 -0800180 case Car.HVAC_SERVICE:
Steve Paik66481982015-10-27 15:22:38 -0700181 assertHvacPermission(mContext);
182 return mCarHvacService;
Keun-young Parke54ac272016-02-16 19:02:18 -0800183 case Car.RADIO_SERVICE:
keunyoung6b197692015-11-16 13:54:38 -0800184 assertRadioPermission(mContext);
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700185 return mCarRadioService;
Pavel Maltsev7a948e52016-02-02 23:30:14 -0800186 case Car.CAR_NAVIGATION_SERVICE:
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800187 return mCarNavigationService;
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -0800188 case Car.PROJECTION_SERVICE:
189 assertProjectionPermission(mContext);
190 return mCarProjectionService;
Keun-young Parke54ac272016-02-16 19:02:18 -0800191 case Car.TEST_SERVICE: {
keunyoung1ab8e182015-09-24 09:25:22 -0700192 assertVehicleHalMockPermission(mContext);
193 synchronized (this) {
194 if (mCarTestService == null) {
195 mCarTestService = new CarTestService(mContext, this);
196 }
197 return mCarTestService;
198 }
199 }
keunyoungca515072015-07-10 12:21:47 -0700200 default:
201 Log.w(CarLog.TAG_SERVICE, "getCarService for unknown service:" + serviceName);
202 return null;
203 }
204 }
205
Pavel Maltsev1ecdd6c2016-03-02 16:33:44 -0800206 @Override
207 public int getCarConnectionType() {
208 if (!isInMocking()) {
209 return Car.CONNECTION_TYPE_EMBEDDED;
210 } else {
211 return Car.CONNECTION_TYPE_EMBEDDED_MOCKING;
212 }
213 }
214
Keun-young Parka28d7b22016-02-29 16:54:29 -0800215 public CarServiceBase getCarInternalService(String serviceName) {
216 switch (serviceName) {
217 case INTERNAL_INPUT_SERVICE:
218 return mCarInputService;
219 default:
220 Log.w(CarLog.TAG_SERVICE, "getCarInternalService for unknown service:" +
221 serviceName);
222 return null;
223 }
224 }
225
keunyoung4b0212c2015-10-29 17:11:57 -0700226 /**
227 * Whether mocking underlying HAL or not.
228 * @return
229 */
230 public synchronized boolean isInMocking() {
231 if (mCarTestService == null) {
232 return false;
233 }
234 return mCarTestService.isInMocking();
235 }
236
keunyoung1ab8e182015-09-24 09:25:22 -0700237 public static void assertVehicleHalMockPermission(Context context) {
Keun-young Parke54ac272016-02-16 19:02:18 -0800238 if (context.checkCallingOrSelfPermission(Car.PERMISSION_MOCK_VEHICLE_HAL)
keunyoung1ab8e182015-09-24 09:25:22 -0700239 != PackageManager.PERMISSION_GRANTED) {
240 throw new SecurityException("requires CAR_MOCK_VEHICLE_HAL permission");
241 }
242 }
243
Steve Paik875616c2016-02-05 10:55:59 -0800244 public static void assertCameraPermission(Context context) {
245 if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_CAMERA)
246 != PackageManager.PERMISSION_GRANTED) {
247 throw new SecurityException(
248 "requires " + Car.PERMISSION_CAR_CAMERA);
249 }
250 }
251
Steve Paik66481982015-10-27 15:22:38 -0700252 public static void assertHvacPermission(Context context) {
Keun-young Parke54ac272016-02-16 19:02:18 -0800253 if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_HVAC)
Steve Paik66481982015-10-27 15:22:38 -0700254 != PackageManager.PERMISSION_GRANTED) {
255 throw new SecurityException(
Keun-young Parke54ac272016-02-16 19:02:18 -0800256 "requires " + Car.PERMISSION_CAR_HVAC);
Steve Paik66481982015-10-27 15:22:38 -0700257 }
258 }
259
keunyoung6b197692015-11-16 13:54:38 -0800260 private static void assertRadioPermission(Context context) {
Keun-young Parke54ac272016-02-16 19:02:18 -0800261 if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_RADIO)
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700262 != PackageManager.PERMISSION_GRANTED) {
263 throw new SecurityException(
Keun-young Parke54ac272016-02-16 19:02:18 -0800264 "requires permission " + Car.PERMISSION_CAR_RADIO);
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700265 }
266 }
267
Vitalii Tomkiv6e5ee612016-03-09 14:57:32 -0800268 public static void assertProjectionPermission(Context context) {
269 if (context.checkCallingOrSelfPermission(Car.PERMISSION_CAR_PROJECTION)
270 != PackageManager.PERMISSION_GRANTED) {
271 throw new SecurityException(
272 "requires " + Car.PERMISSION_CAR_PROJECTION);
273 }
274 }
275
keunyoungcc449f72015-08-12 10:46:27 -0700276 void dump(PrintWriter writer) {
keunyounga3b28d82015-08-25 13:05:15 -0700277 writer.println("*Dump all services*");
278 for (CarServiceBase service: mAllServices) {
279 service.dump(writer);
280 }
keunyoung1ab8e182015-09-24 09:25:22 -0700281 CarTestService testService = mCarTestService;
282 if (testService != null) {
283 testService.dump(writer);
284 }
keunyoungcc449f72015-08-12 10:46:27 -0700285 }
keunyoungca515072015-07-10 12:21:47 -0700286}