blob: 320e188881a810de7501a6e76c5391f4732710ff [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
19import android.content.Context;
20import android.content.Intent;
keunyoung1ab8e182015-09-24 09:25:22 -070021import android.content.pm.PackageManager;
keunyoungca515072015-07-10 12:21:47 -070022import android.os.IBinder;
Sanket Agarwal3cf096a2015-10-13 14:46:31 -070023import android.os.Process;
keunyoungca515072015-07-10 12:21:47 -070024import android.support.car.Car;
keunyoungca515072015-07-10 12:21:47 -070025import android.support.car.ICar;
26import android.support.car.ICarConnectionListener;
keunyoungca515072015-07-10 12:21:47 -070027import android.util.Log;
28
Sanket Agarwal3cf096a2015-10-13 14:46:31 -070029import com.android.car.CarSystem;
keunyoungcc449f72015-08-12 10:46:27 -070030import com.android.car.hal.VehicleHal;
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 {
36 private static final int VERSION = 1;
37
38 @GuardedBy("ICarImpl.class")
39 private static ICarImpl sInstance = null;
40
41 private final Context mContext;
keunyoungcc449f72015-08-12 10:46:27 -070042 private final VehicleHal mHal;
keunyoungca515072015-07-10 12:21:47 -070043
keunyoung4b0212c2015-10-29 17:11:57 -070044 private final CarPowerManagementService mCarPowerManagementService;
keunyoungca515072015-07-10 12:21:47 -070045 private final CarSensorService mCarSensorService;
keunyounga3b28d82015-08-25 13:05:15 -070046 private final CarInfoService mCarInfoService;
keunyoungd32f4e62015-09-21 11:33:06 -070047 private final CarAudioService mCarAudioService;
Sanket Agarwal3cf096a2015-10-13 14:46:31 -070048 private final CarRadioService mCarRadioService;
keunyounga74b9ca2015-10-21 13:33:58 -070049 private final AppContextService mAppContextService;
50
keunyoung1ab8e182015-09-24 09:25:22 -070051 /** Test only service. Populate it only when necessary. */
52 @GuardedBy("this")
53 private CarTestService mCarTestService;
keunyounga3b28d82015-08-25 13:05:15 -070054 private final CarServiceBase[] mAllServices;
keunyoungca515072015-07-10 12:21:47 -070055
56 public synchronized static ICarImpl getInstance(Context serviceContext) {
57 if (sInstance == null) {
58 sInstance = new ICarImpl(serviceContext);
59 sInstance.init();
60 }
61 return sInstance;
62 }
63
64 public synchronized static void releaseInstance() {
65 if (sInstance == null) {
66 return;
67 }
68 sInstance.release();
69 sInstance = null;
70 }
71
72 public ICarImpl(Context serviceContext) {
73 mContext = serviceContext;
keunyoungfe30ba02015-09-17 17:56:35 -070074 mHal = VehicleHal.getInstance();
keunyoung4b0212c2015-10-29 17:11:57 -070075 mCarPowerManagementService = new CarPowerManagementService(serviceContext);
keunyounga3b28d82015-08-25 13:05:15 -070076 mCarInfoService = new CarInfoService(serviceContext);
keunyounga74b9ca2015-10-21 13:33:58 -070077 mAppContextService = new AppContextService(serviceContext);
keunyoungca515072015-07-10 12:21:47 -070078 mCarSensorService = new CarSensorService(serviceContext);
keunyounga74b9ca2015-10-21 13:33:58 -070079 mCarAudioService = new CarAudioService(serviceContext, mAppContextService);
Sanket Agarwal3cf096a2015-10-13 14:46:31 -070080 mCarRadioService = new CarRadioService(serviceContext);
keunyounga74b9ca2015-10-21 13:33:58 -070081
keunyounga3b28d82015-08-25 13:05:15 -070082 // Be careful with order. Service depending on other service should be inited later.
83 mAllServices = new CarServiceBase[] {
keunyoung4b0212c2015-10-29 17:11:57 -070084 mCarPowerManagementService,
keunyounga3b28d82015-08-25 13:05:15 -070085 mCarInfoService,
keunyounga74b9ca2015-10-21 13:33:58 -070086 mAppContextService,
keunyoungd32f4e62015-09-21 11:33:06 -070087 mCarSensorService,
Sanket Agarwal3cf096a2015-10-13 14:46:31 -070088 mCarAudioService,
keunyounga74b9ca2015-10-21 13:33:58 -070089 mCarRadioService,
90 };
keunyoungca515072015-07-10 12:21:47 -070091 }
92
93 private void init() {
keunyounga3b28d82015-08-25 13:05:15 -070094 for (CarServiceBase service: mAllServices) {
95 service.init();
96 }
keunyoungca515072015-07-10 12:21:47 -070097 }
98
99 private void release() {
keunyounga3b28d82015-08-25 13:05:15 -0700100 // release done in opposite order from init
101 for (int i = mAllServices.length - 1; i >= 0; i--) {
102 mAllServices[i].release();
103 }
keunyoungcc449f72015-08-12 10:46:27 -0700104 VehicleHal.releaseInstance();
keunyoungca515072015-07-10 12:21:47 -0700105 }
106
keunyoung4b0212c2015-10-29 17:11:57 -0700107 /** Only for CarTestService */
108 void startMocking() {
keunyoung1ab8e182015-09-24 09:25:22 -0700109 reinitServices();
110 }
111
keunyoung4b0212c2015-10-29 17:11:57 -0700112 /** Only for CarTestService */
113 void stopMocking() {
keunyoung1ab8e182015-09-24 09:25:22 -0700114 reinitServices();
115 }
116
117 private void reinitServices() {
118 for (int i = mAllServices.length - 1; i >= 0; i--) {
119 mAllServices[i].release();
120 }
121 for (CarServiceBase service: mAllServices) {
122 service.init();
123 }
124 }
125
keunyoungca515072015-07-10 12:21:47 -0700126 @Override
127 public int getVersion() {
128 return VERSION;
129 }
130
131 @Override
132 public IBinder getCarService(String serviceName) {
133 switch (serviceName) {
134 case Car.SENSOR_SERVICE:
135 return mCarSensorService;
keunyounga3b28d82015-08-25 13:05:15 -0700136 case Car.INFO_SERVICE:
137 return mCarInfoService;
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700138 case CarSystem.RADIO_SERVICE:
139 assertSystemUidOrPermission(mContext);
140 return mCarRadioService;
keunyoung1ab8e182015-09-24 09:25:22 -0700141 case CarSystemTest.TEST_SERVICE: {
142 assertVehicleHalMockPermission(mContext);
143 synchronized (this) {
144 if (mCarTestService == null) {
145 mCarTestService = new CarTestService(mContext, this);
146 }
147 return mCarTestService;
148 }
149 }
keunyoungca515072015-07-10 12:21:47 -0700150 default:
151 Log.w(CarLog.TAG_SERVICE, "getCarService for unknown service:" + serviceName);
152 return null;
153 }
154 }
155
156 @Override
keunyoungca515072015-07-10 12:21:47 -0700157 public boolean isConnectedToCar() {
158 return true; // always connected in embedded
159 }
160
161 @Override
162 public int getCarConnectionType() {
163 return Car.CONNECTION_TYPE_EMBEDDED;
164 }
165
166 @Override
167 public void registerCarConnectionListener(int clientVersion, ICarConnectionListener listener) {
168 //TODO
169 }
170
171 @Override
172 public void unregisterCarConnectionListener(ICarConnectionListener listener) {
173 //TODO
174 }
175
176 @Override
177 public boolean startCarActivity(Intent intent) {
178 //TODO
179 return false;
180 }
keunyoungcc449f72015-08-12 10:46:27 -0700181
keunyoung4b0212c2015-10-29 17:11:57 -0700182 /**
183 * Whether mocking underlying HAL or not.
184 * @return
185 */
186 public synchronized boolean isInMocking() {
187 if (mCarTestService == null) {
188 return false;
189 }
190 return mCarTestService.isInMocking();
191 }
192
keunyoung1ab8e182015-09-24 09:25:22 -0700193 public static void assertVehicleHalMockPermission(Context context) {
194 if (context.checkCallingOrSelfPermission(CarSystemTest.PERMISSION_MOCK_VEHICLE_HAL)
195 != PackageManager.PERMISSION_GRANTED) {
196 throw new SecurityException("requires CAR_MOCK_VEHICLE_HAL permission");
197 }
198 }
199
Sanket Agarwal3cf096a2015-10-13 14:46:31 -0700200 private static void assertSystemUidOrPermission(Context context) {
201 if (getCallingUid() != Process.SYSTEM_UID &&
202 context.checkCallingOrSelfPermission(CarSystem.PERMISSION_RADIO_VEHICLE_HAL)
203 != PackageManager.PERMISSION_GRANTED) {
204 throw new SecurityException(
205 "requires system app or " + CarSystem.PERMISSION_RADIO_VEHICLE_HAL);
206 }
207 }
208
keunyoungcc449f72015-08-12 10:46:27 -0700209 void dump(PrintWriter writer) {
keunyounga3b28d82015-08-25 13:05:15 -0700210 writer.println("*Dump all services*");
211 for (CarServiceBase service: mAllServices) {
212 service.dump(writer);
213 }
keunyoung1ab8e182015-09-24 09:25:22 -0700214 CarTestService testService = mCarTestService;
215 if (testService != null) {
216 testService.dump(writer);
217 }
keunyoungcc449f72015-08-12 10:46:27 -0700218 }
keunyoungca515072015-07-10 12:21:47 -0700219}