1 /*
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 
17 package com.android.car;
18 
19 import android.annotation.MainThread;
20 import android.annotation.Nullable;
21 import android.app.ActivityManager;
22 import android.car.Car;
23 import android.car.CarFeatures;
24 import android.car.ICar;
25 import android.car.cluster.renderer.IInstrumentClusterNavigation;
26 import android.car.user.CarUserManager;
27 import android.car.userlib.CarUserManagerHelper;
28 import android.content.Context;
29 import android.content.pm.PackageManager;
30 import android.content.res.Resources;
31 import android.hardware.automotive.vehicle.V2_0.IVehicle;
32 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
33 import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
34 import android.os.Binder;
35 import android.os.Build;
36 import android.os.IBinder;
37 import android.os.Process;
38 import android.os.RemoteException;
39 import android.os.ResultReceiver;
40 import android.os.ShellCallback;
41 import android.os.Trace;
42 import android.os.UserManager;
43 import android.util.EventLog;
44 import android.util.Log;
45 import android.util.Slog;
46 import android.util.TimingsTraceLog;
47 
48 import com.android.car.am.FixedActivityService;
49 import com.android.car.audio.CarAudioService;
50 import com.android.car.cluster.InstrumentClusterService;
51 import com.android.car.garagemode.GarageModeService;
52 import com.android.car.hal.VehicleHal;
53 import com.android.car.pm.CarPackageManagerService;
54 import com.android.car.stats.CarStatsService;
55 import com.android.car.systeminterface.SystemInterface;
56 import com.android.car.trust.CarTrustedDeviceService;
57 import com.android.car.user.CarUserNoticeService;
58 import com.android.car.user.CarUserService;
59 import com.android.car.vms.VmsBrokerService;
60 import com.android.car.watchdog.CarWatchdogService;
61 import com.android.internal.annotations.GuardedBy;
62 import com.android.internal.annotations.VisibleForTesting;
63 import com.android.internal.car.EventLogTags;
64 import com.android.internal.car.ICarServiceHelper;
65 import com.android.internal.os.IResultReceiver;
66 
67 import java.io.FileDescriptor;
68 import java.io.PrintWriter;
69 import java.util.ArrayList;
70 import java.util.Arrays;
71 import java.util.List;
72 
73 public class ICarImpl extends ICar.Stub {
74 
75     public static final String INTERNAL_INPUT_SERVICE = "internal_input";
76     public static final String INTERNAL_SYSTEM_ACTIVITY_MONITORING_SERVICE =
77             "system_activity_monitoring";
78 
79     private static final int INITIAL_VHAL_GET_RETRY = 2;
80 
81     private final Context mContext;
82     private final VehicleHal mHal;
83 
84     private final CarFeatureController mFeatureController;
85 
86     private final SystemInterface mSystemInterface;
87 
88     private final SystemActivityMonitoringService mSystemActivityMonitoringService;
89     private final CarPowerManagementService mCarPowerManagementService;
90     private final CarPackageManagerService mCarPackageManagerService;
91     private final CarInputService mCarInputService;
92     private final CarDrivingStateService mCarDrivingStateService;
93     private final CarUxRestrictionsManagerService mCarUXRestrictionsService;
94     private final OccupantAwarenessService mOccupantAwarenessService;
95     private final CarAudioService mCarAudioService;
96     private final CarProjectionService mCarProjectionService;
97     private final CarPropertyService mCarPropertyService;
98     private final CarNightService mCarNightService;
99     private final AppFocusService mAppFocusService;
100     private final FixedActivityService mFixedActivityService;
101     private final GarageModeService mGarageModeService;
102     private final InstrumentClusterService mInstrumentClusterService;
103     private final CarLocationService mCarLocationService;
104     private final SystemStateControllerService mSystemStateControllerService;
105     private final CarBluetoothService mCarBluetoothService;
106     private final PerUserCarServiceHelper mPerUserCarServiceHelper;
107     private final CarDiagnosticService mCarDiagnosticService;
108     private final CarStorageMonitoringService mCarStorageMonitoringService;
109     private final CarConfigurationService mCarConfigurationService;
110     private final CarTrustedDeviceService mCarTrustedDeviceService;
111     private final CarMediaService mCarMediaService;
112     private final CarUserManagerHelper mUserManagerHelper;
113     private final CarUserService mCarUserService;
114     private final CarOccupantZoneService mCarOccupantZoneService;
115     private final CarUserNoticeService mCarUserNoticeService;
116     private final VmsBrokerService mVmsBrokerService;
117     private final CarBugreportManagerService mCarBugreportManagerService;
118     private final CarStatsService mCarStatsService;
119     private final CarExperimentalFeatureServiceController mCarExperimentalFeatureServiceController;
120     private final CarWatchdogService mCarWatchdogService;
121 
122     private final CarServiceBase[] mAllServices;
123 
124     private static final String TAG = "ICarImpl";
125     private static final String VHAL_TIMING_TAG = "VehicleHalTiming";
126     private static final boolean DBG = true; // TODO(b/154033860): STOPSHIP if true
127 
128     private TimingsTraceLog mBootTiming;
129 
130     private final Object mLock = new Object();
131 
132     /** Test only service. Populate it only when necessary. */
133     @GuardedBy("mLock")
134     private CarTestService mCarTestService;
135 
136     @GuardedBy("mLock")
137     private ICarServiceHelper mICarServiceHelper;
138 
139     private final String mVehicleInterfaceName;
140 
ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface, CanBusErrorNotifier errorNotifier, String vehicleInterfaceName)141     public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,
142             CanBusErrorNotifier errorNotifier, String vehicleInterfaceName) {
143         this(serviceContext, vehicle, systemInterface, errorNotifier, vehicleInterfaceName,
144                 /* carUserService= */ null, /* carWatchdogService= */ null);
145     }
146 
147     @VisibleForTesting
ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface, CanBusErrorNotifier errorNotifier, String vehicleInterfaceName, @Nullable CarUserService carUserService, @Nullable CarWatchdogService carWatchdogService)148     ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,
149             CanBusErrorNotifier errorNotifier, String vehicleInterfaceName,
150             @Nullable CarUserService carUserService,
151             @Nullable CarWatchdogService carWatchdogService) {
152         mContext = serviceContext;
153         mSystemInterface = systemInterface;
154         mHal = new VehicleHal(serviceContext, vehicle);
155         // Do this before any other service components to allow feature check. It should work
156         // even without init. For that, vhal get is retried as it can be too early.
157         VehiclePropValue disabledOptionalFeatureValue = mHal.getIfAvailableOrFailForEarlyStage(
158                     VehicleProperty.DISABLED_OPTIONAL_FEATURES, INITIAL_VHAL_GET_RETRY);
159         String[] disabledFeaturesFromVhal = null;
160         if (disabledOptionalFeatureValue != null) {
161             String disabledFeatures = disabledOptionalFeatureValue.value.stringValue;
162             if (disabledFeatures != null && !disabledFeatures.isEmpty()) {
163                 disabledFeaturesFromVhal = disabledFeatures.split(",");
164             }
165         }
166         if (disabledFeaturesFromVhal == null) {
167             disabledFeaturesFromVhal = new String[0];
168         }
169         Resources res = mContext.getResources();
170         String[] defaultEnabledFeatures = res.getStringArray(
171                 R.array.config_allowed_optional_car_features);
172         mFeatureController = new CarFeatureController(serviceContext, defaultEnabledFeatures,
173                 disabledFeaturesFromVhal , mSystemInterface.getSystemCarDir());
174         CarLocalServices.addService(CarFeatureController.class, mFeatureController);
175         mVehicleInterfaceName = vehicleInterfaceName;
176         mUserManagerHelper = new CarUserManagerHelper(serviceContext);
177         if (carUserService != null) {
178             mCarUserService = carUserService;
179         } else {
180             UserManager userManager =
181                     (UserManager) serviceContext.getSystemService(Context.USER_SERVICE);
182             int maxRunningUsers = res.getInteger(
183                     com.android.internal.R.integer.config_multiuserMaxRunningUsers);
184             mCarUserService = new CarUserService(serviceContext, mHal.getUserHal(),
185                     mUserManagerHelper, userManager, ActivityManager.getService(), maxRunningUsers);
186         }
187         mCarOccupantZoneService = new CarOccupantZoneService(serviceContext);
188         mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);
189         mCarPowerManagementService = new CarPowerManagementService(mContext, mHal.getPowerHal(),
190                 systemInterface, mCarUserService);
191         if (mFeatureController.isFeatureEnabled(CarFeatures.FEATURE_CAR_USER_NOTICE_SERVICE)) {
192             mCarUserNoticeService = new CarUserNoticeService(serviceContext);
193         } else {
194             mCarUserNoticeService = null;
195         }
196         mCarPropertyService = new CarPropertyService(serviceContext, mHal.getPropertyHal());
197         mCarDrivingStateService = new CarDrivingStateService(serviceContext, mCarPropertyService);
198         mCarUXRestrictionsService = new CarUxRestrictionsManagerService(serviceContext,
199                 mCarDrivingStateService, mCarPropertyService);
200         if (mFeatureController.isFeatureEnabled(Car.OCCUPANT_AWARENESS_SERVICE)) {
201             mOccupantAwarenessService = new OccupantAwarenessService(serviceContext);
202         } else {
203             mOccupantAwarenessService = null;
204         }
205         mCarPackageManagerService = new CarPackageManagerService(serviceContext,
206                 mCarUXRestrictionsService,
207                 mSystemActivityMonitoringService,
208                 mCarUserService);
209         mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext, mCarUserService);
210         mCarBluetoothService = new CarBluetoothService(serviceContext, mPerUserCarServiceHelper);
211         mCarInputService = new CarInputService(serviceContext, mHal.getInputHal(), mCarUserService);
212         mCarProjectionService = new CarProjectionService(
213                 serviceContext, null /* handler */, mCarInputService, mCarBluetoothService);
214         mGarageModeService = new GarageModeService(mContext);
215         mAppFocusService = new AppFocusService(serviceContext, mSystemActivityMonitoringService);
216         mCarAudioService = new CarAudioService(serviceContext);
217         mCarNightService = new CarNightService(serviceContext, mCarPropertyService);
218         mFixedActivityService = new FixedActivityService(serviceContext);
219         mInstrumentClusterService = new InstrumentClusterService(serviceContext,
220                 mAppFocusService, mCarInputService);
221         mSystemStateControllerService = new SystemStateControllerService(
222                 serviceContext, mCarAudioService, this);
223         mCarStatsService = new CarStatsService(serviceContext);
224         mCarStatsService.init();
225         if (mFeatureController.isFeatureEnabled(Car.VEHICLE_MAP_SERVICE)) {
226             mVmsBrokerService = new VmsBrokerService(mContext, mCarStatsService);
227         } else {
228             mVmsBrokerService = null;
229         }
230         if (mFeatureController.isFeatureEnabled(Car.DIAGNOSTIC_SERVICE)) {
231             mCarDiagnosticService = new CarDiagnosticService(serviceContext,
232                     mHal.getDiagnosticHal());
233         } else {
234             mCarDiagnosticService = null;
235         }
236         if (mFeatureController.isFeatureEnabled(Car.STORAGE_MONITORING_SERVICE)) {
237             mCarStorageMonitoringService = new CarStorageMonitoringService(serviceContext,
238                     systemInterface);
239         } else {
240             mCarStorageMonitoringService = null;
241         }
242         mCarConfigurationService =
243                 new CarConfigurationService(serviceContext, new JsonReaderImpl());
244         mCarLocationService = new CarLocationService(serviceContext);
245         mCarTrustedDeviceService = new CarTrustedDeviceService(serviceContext);
246         mCarMediaService = new CarMediaService(serviceContext, mCarUserService);
247         mCarBugreportManagerService = new CarBugreportManagerService(serviceContext);
248         if (!Build.IS_USER) {
249             mCarExperimentalFeatureServiceController = new CarExperimentalFeatureServiceController(
250                     serviceContext);
251         } else {
252             mCarExperimentalFeatureServiceController = null;
253         }
254         if (carWatchdogService == null) {
255             mCarWatchdogService = new CarWatchdogService(serviceContext);
256         } else {
257             mCarWatchdogService = carWatchdogService;
258         }
259 
260         CarLocalServices.addService(CarPowerManagementService.class, mCarPowerManagementService);
261         CarLocalServices.addService(CarPropertyService.class, mCarPropertyService);
262         CarLocalServices.addService(CarUserService.class, mCarUserService);
263         CarLocalServices.addService(CarTrustedDeviceService.class, mCarTrustedDeviceService);
264         CarLocalServices.addService(CarUserNoticeService.class, mCarUserNoticeService);
265         CarLocalServices.addService(SystemInterface.class, mSystemInterface);
266         CarLocalServices.addService(CarDrivingStateService.class, mCarDrivingStateService);
267         CarLocalServices.addService(PerUserCarServiceHelper.class, mPerUserCarServiceHelper);
268         CarLocalServices.addService(FixedActivityService.class, mFixedActivityService);
269         CarLocalServices.addService(VmsBrokerService.class, mVmsBrokerService);
270         CarLocalServices.addService(CarOccupantZoneService.class, mCarOccupantZoneService);
271         CarLocalServices.addService(AppFocusService.class, mAppFocusService);
272 
273         // Be careful with order. Service depending on other service should be inited later.
274         List<CarServiceBase> allServices = new ArrayList<>();
275         allServices.add(mFeatureController);
276         allServices.add(mCarUserService);
277         allServices.add(mSystemActivityMonitoringService);
278         allServices.add(mCarPowerManagementService);
279         allServices.add(mCarPropertyService);
280         allServices.add(mCarDrivingStateService);
281         allServices.add(mCarOccupantZoneService);
282         allServices.add(mCarUXRestrictionsService);
283         addServiceIfNonNull(allServices, mOccupantAwarenessService);
284         allServices.add(mCarPackageManagerService);
285         allServices.add(mCarInputService);
286         allServices.add(mGarageModeService);
287         addServiceIfNonNull(allServices, mCarUserNoticeService);
288         allServices.add(mAppFocusService);
289         allServices.add(mCarAudioService);
290         allServices.add(mCarNightService);
291         allServices.add(mFixedActivityService);
292         allServices.add(mInstrumentClusterService);
293         allServices.add(mSystemStateControllerService);
294         allServices.add(mPerUserCarServiceHelper);
295         allServices.add(mCarBluetoothService);
296         allServices.add(mCarProjectionService);
297         addServiceIfNonNull(allServices, mCarDiagnosticService);
298         addServiceIfNonNull(allServices, mCarStorageMonitoringService);
299         allServices.add(mCarConfigurationService);
300         addServiceIfNonNull(allServices, mVmsBrokerService);
301         allServices.add(mCarTrustedDeviceService);
302         allServices.add(mCarMediaService);
303         allServices.add(mCarLocationService);
304         allServices.add(mCarBugreportManagerService);
305         allServices.add(mCarWatchdogService);
306         // Always put mCarExperimentalFeatureServiceController in last.
307         addServiceIfNonNull(allServices, mCarExperimentalFeatureServiceController);
308         mAllServices = allServices.toArray(new CarServiceBase[allServices.size()]);
309     }
310 
addServiceIfNonNull(List<CarServiceBase> services, CarServiceBase service)311     private void addServiceIfNonNull(List<CarServiceBase> services, CarServiceBase service) {
312         if (service != null) {
313             services.add(service);
314         }
315     }
316 
317     @MainThread
init()318     void init() {
319         mBootTiming = new TimingsTraceLog(VHAL_TIMING_TAG, Trace.TRACE_TAG_HAL);
320         traceBegin("VehicleHal.init");
321         mHal.init();
322         traceEnd();
323         traceBegin("CarService.initAllServices");
324         for (CarServiceBase service : mAllServices) {
325             service.init();
326         }
327         traceEnd();
328     }
329 
release()330     void release() {
331         // release done in opposite order from init
332         for (int i = mAllServices.length - 1; i >= 0; i--) {
333             mAllServices[i].release();
334         }
335         mHal.release();
336     }
337 
vehicleHalReconnected(IVehicle vehicle)338     void vehicleHalReconnected(IVehicle vehicle) {
339         EventLog.writeEvent(EventLogTags.CAR_SERVICE_VHAL_RECONNECTED, mAllServices.length);
340         mHal.vehicleHalReconnected(vehicle);
341         for (CarServiceBase service : mAllServices) {
342             service.vehicleHalReconnected();
343         }
344     }
345 
346     @Override
setCarServiceHelper(IBinder helper)347     public void setCarServiceHelper(IBinder helper) {
348         EventLog.writeEvent(EventLogTags.CAR_SERVICE_SET_CAR_SERVICE_HELPER,
349                 Binder.getCallingPid());
350         assertCallingFromSystemProcess();
351         ICarServiceHelper carServiceHelper = ICarServiceHelper.Stub.asInterface(helper);
352         synchronized (mLock) {
353             mICarServiceHelper = carServiceHelper;
354         }
355         mSystemInterface.setCarServiceHelper(carServiceHelper);
356         mCarOccupantZoneService.setCarServiceHelper(carServiceHelper);
357     }
358 
359     @Override
onUserLifecycleEvent(int eventType, long timestampMs, int fromUserId, int toUserId)360     public void onUserLifecycleEvent(int eventType, long timestampMs, int fromUserId,
361             int toUserId) {
362         assertCallingFromSystemProcess();
363         EventLog.writeEvent(EventLogTags.CAR_SERVICE_ON_USER_LIFECYCLE, eventType, fromUserId,
364                 toUserId);
365         if (DBG) {
366             Log.d(TAG, "onUserLifecycleEvent("
367                     + CarUserManager.lifecycleEventTypeToString(eventType) + ", " + toUserId + ")");
368         }
369         mCarUserService.onUserLifecycleEvent(eventType, timestampMs, fromUserId, toUserId);
370     }
371 
372     @Override
onFirstUserUnlocked(int userId, long timestampMs, long duration, int halResponseTime)373     public void onFirstUserUnlocked(int userId, long timestampMs, long duration,
374             int halResponseTime) {
375         mCarUserService.onFirstUserUnlocked(userId, timestampMs, duration, halResponseTime);
376     }
377 
378     @Override
getInitialUserInfo(int requestType, int timeoutMs, IBinder binder)379     public void getInitialUserInfo(int requestType, int timeoutMs, IBinder binder) {
380         IResultReceiver receiver = IResultReceiver.Stub.asInterface(binder);
381         mCarUserService.getInitialUserInfo(requestType, timeoutMs, receiver);
382     }
383 
384     @Override
setInitialUser(int userId)385     public void setInitialUser(int userId) {
386         EventLog.writeEvent(EventLogTags.CAR_SERVICE_SET_INITIAL_USER, userId);
387         if (DBG) Log.d(TAG, "setInitialUser(): " + userId);
388         mCarUserService.setInitialUser(userId);
389     }
390 
391     @Override
isFeatureEnabled(String featureName)392     public boolean isFeatureEnabled(String featureName) {
393         return mFeatureController.isFeatureEnabled(featureName);
394     }
395 
396     @Override
enableFeature(String featureName)397     public int enableFeature(String featureName) {
398         // permission check inside the controller
399         return mFeatureController.enableFeature(featureName);
400     }
401 
402     @Override
disableFeature(String featureName)403     public int disableFeature(String featureName) {
404         // permission check inside the controller
405         return mFeatureController.disableFeature(featureName);
406     }
407 
408     @Override
getAllEnabledFeatures()409     public List<String> getAllEnabledFeatures() {
410         // permission check inside the controller
411         return mFeatureController.getAllEnabledFeatures();
412     }
413 
414     @Override
getAllPendingDisabledFeatures()415     public List<String> getAllPendingDisabledFeatures() {
416         // permission check inside the controller
417         return mFeatureController.getAllPendingDisabledFeatures();
418     }
419 
420     @Override
getAllPendingEnabledFeatures()421     public List<String> getAllPendingEnabledFeatures() {
422         // permission check inside the controller
423         return mFeatureController.getAllPendingEnabledFeatures();
424     }
425 
426     @Override
getCarManagerClassForFeature(String featureName)427     public String getCarManagerClassForFeature(String featureName) {
428         if (mCarExperimentalFeatureServiceController == null) {
429             return null;
430         }
431         return mCarExperimentalFeatureServiceController.getCarManagerClassForFeature(featureName);
432     }
433 
assertCallingFromSystemProcess()434     static void assertCallingFromSystemProcess() {
435         int uid = Binder.getCallingUid();
436         if (uid != Process.SYSTEM_UID) {
437             throw new SecurityException("Only allowed from system");
438         }
439     }
440 
441     /**
442      * Assert if binder call is coming from system process like system server or if it is called
443      * from its own process even if it is not system. The latter can happen in test environment.
444      * Note that car service runs as system user but test like car service test will not.
445      */
assertCallingFromSystemProcessOrSelf()446     static void assertCallingFromSystemProcessOrSelf() {
447         int uid = Binder.getCallingUid();
448         int pid = Binder.getCallingPid();
449         if (uid != Process.SYSTEM_UID && pid != Process.myPid()) {
450             throw new SecurityException("Only allowed from system or self");
451         }
452     }
453 
454     @Override
getCarService(String serviceName)455     public IBinder getCarService(String serviceName) {
456         if (!mFeatureController.isFeatureEnabled(serviceName)) {
457             Log.w(CarLog.TAG_SERVICE, "getCarService for disabled service:" + serviceName);
458             return null;
459         }
460         switch (serviceName) {
461             case Car.AUDIO_SERVICE:
462                 return mCarAudioService;
463             case Car.APP_FOCUS_SERVICE:
464                 return mAppFocusService;
465             case Car.PACKAGE_SERVICE:
466                 return mCarPackageManagerService;
467             case Car.DIAGNOSTIC_SERVICE:
468                 assertAnyDiagnosticPermission(mContext);
469                 return mCarDiagnosticService;
470             case Car.POWER_SERVICE:
471                 assertPowerPermission(mContext);
472                 return mCarPowerManagementService;
473             case Car.CABIN_SERVICE:
474             case Car.HVAC_SERVICE:
475             case Car.INFO_SERVICE:
476             case Car.PROPERTY_SERVICE:
477             case Car.SENSOR_SERVICE:
478             case Car.VENDOR_EXTENSION_SERVICE:
479                 return mCarPropertyService;
480             case Car.CAR_NAVIGATION_SERVICE:
481                 assertNavigationManagerPermission(mContext);
482                 IInstrumentClusterNavigation navService =
483                         mInstrumentClusterService.getNavigationService();
484                 return navService == null ? null : navService.asBinder();
485             case Car.CAR_INSTRUMENT_CLUSTER_SERVICE:
486                 assertClusterManagerPermission(mContext);
487                 return mInstrumentClusterService.getManagerService();
488             case Car.PROJECTION_SERVICE:
489                 return mCarProjectionService;
490             case Car.VEHICLE_MAP_SERVICE:
491                 assertAnyVmsPermission(mContext);
492                 return mVmsBrokerService;
493             case Car.VMS_SUBSCRIBER_SERVICE:
494                 assertVmsSubscriberPermission(mContext);
495                 return mVmsBrokerService;
496             case Car.TEST_SERVICE: {
497                 assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
498                 synchronized (mLock) {
499                     if (mCarTestService == null) {
500                         mCarTestService = new CarTestService(mContext, this);
501                     }
502                     return mCarTestService;
503                 }
504             }
505             case Car.BLUETOOTH_SERVICE:
506                 return mCarBluetoothService;
507             case Car.STORAGE_MONITORING_SERVICE:
508                 assertPermission(mContext, Car.PERMISSION_STORAGE_MONITORING);
509                 return mCarStorageMonitoringService;
510             case Car.CAR_DRIVING_STATE_SERVICE:
511                 assertDrivingStatePermission(mContext);
512                 return mCarDrivingStateService;
513             case Car.CAR_UX_RESTRICTION_SERVICE:
514                 return mCarUXRestrictionsService;
515             case Car.OCCUPANT_AWARENESS_SERVICE:
516                 return mOccupantAwarenessService;
517             case Car.CAR_CONFIGURATION_SERVICE:
518                 return mCarConfigurationService;
519             case Car.CAR_TRUST_AGENT_ENROLLMENT_SERVICE:
520                 assertTrustAgentEnrollmentPermission(mContext);
521                 return mCarTrustedDeviceService.getCarTrustAgentEnrollmentService();
522             case Car.CAR_MEDIA_SERVICE:
523                 return mCarMediaService;
524             case Car.CAR_OCCUPANT_ZONE_SERVICE:
525                 return mCarOccupantZoneService;
526             case Car.CAR_BUGREPORT_SERVICE:
527                 return mCarBugreportManagerService;
528             case Car.CAR_USER_SERVICE:
529                 return mCarUserService;
530             case Car.CAR_WATCHDOG_SERVICE:
531                 return mCarWatchdogService;
532             case Car.CAR_INPUT_SERVICE:
533                 return mCarInputService;
534             default:
535                 IBinder service = null;
536                 if (mCarExperimentalFeatureServiceController != null) {
537                     service = mCarExperimentalFeatureServiceController.getCarService(serviceName);
538                 }
539                 if (service == null) {
540                     Log.w(CarLog.TAG_SERVICE, "getCarService for unknown service:"
541                             + serviceName);
542                 }
543                 return service;
544         }
545     }
546 
547     @Override
getCarConnectionType()548     public int getCarConnectionType() {
549         return Car.CONNECTION_TYPE_EMBEDDED;
550     }
551 
getCarInternalService(String serviceName)552     public CarServiceBase getCarInternalService(String serviceName) {
553         switch (serviceName) {
554             case INTERNAL_INPUT_SERVICE:
555                 return mCarInputService;
556             case INTERNAL_SYSTEM_ACTIVITY_MONITORING_SERVICE:
557                 return mSystemActivityMonitoringService;
558             default:
559                 Log.w(CarLog.TAG_SERVICE, "getCarInternalService for unknown service:" +
560                         serviceName);
561                 return null;
562         }
563     }
564 
assertVehicleHalMockPermission(Context context)565     public static void assertVehicleHalMockPermission(Context context) {
566         assertPermission(context, Car.PERMISSION_MOCK_VEHICLE_HAL);
567     }
568 
assertNavigationManagerPermission(Context context)569     public static void assertNavigationManagerPermission(Context context) {
570         assertPermission(context, Car.PERMISSION_CAR_NAVIGATION_MANAGER);
571     }
572 
assertClusterManagerPermission(Context context)573     public static void assertClusterManagerPermission(Context context) {
574         assertPermission(context, Car.PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL);
575     }
576 
assertPowerPermission(Context context)577     public static void assertPowerPermission(Context context) {
578         assertPermission(context, Car.PERMISSION_CAR_POWER);
579     }
580 
assertProjectionPermission(Context context)581     public static void assertProjectionPermission(Context context) {
582         assertPermission(context, Car.PERMISSION_CAR_PROJECTION);
583     }
584 
585     /** Verify the calling context has the {@link Car#PERMISSION_CAR_PROJECTION_STATUS} */
assertProjectionStatusPermission(Context context)586     public static void assertProjectionStatusPermission(Context context) {
587         assertPermission(context, Car.PERMISSION_CAR_PROJECTION_STATUS);
588     }
589 
assertAnyDiagnosticPermission(Context context)590     public static void assertAnyDiagnosticPermission(Context context) {
591         assertAnyPermission(context,
592                 Car.PERMISSION_CAR_DIAGNOSTIC_READ_ALL,
593                 Car.PERMISSION_CAR_DIAGNOSTIC_CLEAR);
594     }
595 
assertDrivingStatePermission(Context context)596     public static void assertDrivingStatePermission(Context context) {
597         assertPermission(context, Car.PERMISSION_CAR_DRIVING_STATE);
598     }
599 
600     /**
601      * Verify the calling context has either {@link Car#PERMISSION_VMS_SUBSCRIBER} or
602      * {@link Car#PERMISSION_VMS_PUBLISHER}
603      */
assertAnyVmsPermission(Context context)604     public static void assertAnyVmsPermission(Context context) {
605         assertAnyPermission(context,
606                 Car.PERMISSION_VMS_SUBSCRIBER,
607                 Car.PERMISSION_VMS_PUBLISHER);
608     }
609 
assertVmsPublisherPermission(Context context)610     public static void assertVmsPublisherPermission(Context context) {
611         assertPermission(context, Car.PERMISSION_VMS_PUBLISHER);
612     }
613 
assertVmsSubscriberPermission(Context context)614     public static void assertVmsSubscriberPermission(Context context) {
615         assertPermission(context, Car.PERMISSION_VMS_SUBSCRIBER);
616     }
617 
618     /**
619      * Ensures the caller has the permission to enroll a Trust Agent.
620      */
assertTrustAgentEnrollmentPermission(Context context)621     public static void assertTrustAgentEnrollmentPermission(Context context) {
622         assertPermission(context, Car.PERMISSION_CAR_ENROLL_TRUST);
623     }
624 
assertPermission(Context context, String permission)625     public static void assertPermission(Context context, String permission) {
626         if (context.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
627             throw new SecurityException("requires " + permission);
628         }
629     }
630 
631     /**
632      * Checks to see if the caller has a permission.
633      *
634      * @return boolean TRUE if caller has the permission.
635      */
hasPermission(Context context, String permission)636     public static boolean hasPermission(Context context, String permission) {
637         return context.checkCallingOrSelfPermission(permission)
638                 == PackageManager.PERMISSION_GRANTED;
639     }
640 
assertAnyPermission(Context context, String... permissions)641     public static void assertAnyPermission(Context context, String... permissions) {
642         for (String permission : permissions) {
643             if (context.checkCallingOrSelfPermission(permission)
644                     == PackageManager.PERMISSION_GRANTED) {
645                 return;
646             }
647         }
648         throw new SecurityException("requires any of " + Arrays.toString(permissions));
649     }
650 
651     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)652     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
653         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
654                 != PackageManager.PERMISSION_GRANTED) {
655             writer.println("Permission Denial: can't dump CarService from from pid="
656                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
657                     + " without permission " + android.Manifest.permission.DUMP);
658             return;
659         }
660 
661         if (args == null || args.length == 0 || (args.length > 0 && "-a".equals(args[0]))) {
662             writer.println("*Dump car service*");
663             dumpAllServices(writer);
664             dumpAllHals(writer);
665         } else if ("--list".equals(args[0])) {
666             dumpListOfServices(writer);
667             return;
668         } else if ("--services".equals(args[0])) {
669             if (args.length < 2) {
670                 writer.println("Must pass services to dump when using --services");
671                 return;
672             }
673             int length = args.length - 1;
674             String[] services = new String[length];
675             System.arraycopy(args, 1, services, 0, length);
676             dumpIndividualServices(writer, services);
677             return;
678         } else if ("--metrics".equals(args[0])) {
679             // Strip the --metrics flag when passing dumpsys arguments to CarStatsService
680             // allowing for nested flag selection
681             mCarStatsService.dump(fd, writer, Arrays.copyOfRange(args, 1, args.length));
682         } else if ("--vms-hal".equals(args[0])) {
683             mHal.getVmsHal().dumpMetrics(fd);
684         } else if ("--hal".equals(args[0])) {
685             if (args.length == 1) {
686                 dumpAllHals(writer);
687                 return;
688             }
689             int length = args.length - 1;
690             String[] halNames = new String[length];
691             System.arraycopy(args, 1, halNames, 0, length);
692             mHal.dumpSpecificHals(writer, halNames);
693 
694         } else if ("--list-hals".equals(args[0])) {
695             mHal.dumpListHals(writer);
696             return;
697         } else if ("--user-metrics".equals(args[0])) {
698             mCarUserService.dumpUserMetrics(writer);
699         } else if ("--first-user-metrics".equals(args[0])) {
700             mCarUserService.dumpFirstUserUnlockDuration(writer);
701         } else if ("--help".equals(args[0])) {
702             showDumpHelp(writer);
703         } else {
704             execShellCmd(args, writer);
705         }
706     }
707 
dumpAllHals(PrintWriter writer)708     private void dumpAllHals(PrintWriter writer) {
709         writer.println("*Dump Vehicle HAL*");
710         writer.println("Vehicle HAL Interface: " + mVehicleInterfaceName);
711         try {
712             // TODO dump all feature flags by creating a dumpable interface
713             mHal.dump(writer);
714         } catch (Exception e) {
715             writer.println("Failed dumping: " + mHal.getClass().getName());
716             e.printStackTrace(writer);
717         }
718     }
719 
showDumpHelp(PrintWriter writer)720     private void showDumpHelp(PrintWriter writer) {
721         writer.println("Car service dump usage:");
722         writer.println("[NO ARG]");
723         writer.println("\t  dumps everything (all services and HALs)");
724         writer.println("--help");
725         writer.println("\t  shows this help");
726         writer.println("--list");
727         writer.println("\t  lists the name of all services");
728         writer.println("--list-hals");
729         writer.println("\t  lists the name of all HALs");
730         writer.println("--services <SVC1> [SVC2] [SVCN]");
731         writer.println("\t  dumps just the specific services, where SVC is just the service class");
732         writer.println("\t  name (like CarUserService)");
733         writer.println("--vms-hal");
734         writer.println("\t  dumps the VMS HAL metrics");
735         writer.println("--hal [HAL1] [HAL2] [HALN]");
736         writer.println("\t  dumps just the specified HALs (or all of them if none specified),");
737         writer.println("\t  where HAL is just the class name (like UserHalService)");
738         writer.println("--user-metrics");
739         writer.println("\t  dumps user switching and stopping metrics ");
740         writer.println("--first-user-metrics");
741         writer.println("\t  dumps how long it took to unlock first user since Android started\n");
742         writer.println("\t  (or -1 if not unlocked)");
743         writer.println("-h");
744         writer.println("\t  shows commands usage (NOTE: commands are not available on USER builds");
745         writer.println("[ANYTHING ELSE]");
746         writer.println("\t  runs the given command (use --h to see the available commands)");
747     }
748 
749     @Override
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)750     public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
751             String[] args, ShellCallback callback, ResultReceiver resultReceiver)
752                     throws RemoteException {
753         newCarShellCommand().exec(this, in, out, err, args, callback, resultReceiver);
754     }
755 
newCarShellCommand()756     private CarShellCommand newCarShellCommand() {
757         return new CarShellCommand(mContext, mHal, mCarAudioService, mCarPackageManagerService,
758                 mCarProjectionService, mCarPowerManagementService, mCarTrustedDeviceService,
759                 mFixedActivityService, mFeatureController, mCarInputService, mCarNightService,
760                 mSystemInterface, mGarageModeService, mCarUserService, mCarOccupantZoneService);
761     }
762 
dumpListOfServices(PrintWriter writer)763     private void dumpListOfServices(PrintWriter writer) {
764         for (CarServiceBase service : mAllServices) {
765             writer.println(service.getClass().getName());
766         }
767     }
768 
dumpAllServices(PrintWriter writer)769     private void dumpAllServices(PrintWriter writer) {
770         writer.println("*Dump all services*");
771         for (CarServiceBase service : mAllServices) {
772             dumpService(service, writer);
773         }
774         if (mCarTestService != null) {
775             dumpService(mCarTestService, writer);
776         }
777     }
778 
dumpIndividualServices(PrintWriter writer, String... serviceNames)779     private void dumpIndividualServices(PrintWriter writer, String... serviceNames) {
780         for (String serviceName : serviceNames) {
781             writer.println("** Dumping " + serviceName + "\n");
782             CarServiceBase service = getCarServiceBySubstring(serviceName);
783             if (service == null) {
784                 writer.println("No such service!");
785             } else {
786                 dumpService(service, writer);
787             }
788             writer.println();
789         }
790     }
791 
792     @Nullable
getCarServiceBySubstring(String className)793     private CarServiceBase getCarServiceBySubstring(String className) {
794         return Arrays.asList(mAllServices).stream()
795                 .filter(s -> s.getClass().getSimpleName().equals(className))
796                 .findFirst().orElse(null);
797     }
798 
dumpService(CarServiceBase service, PrintWriter writer)799     private void dumpService(CarServiceBase service, PrintWriter writer) {
800         try {
801             service.dump(writer);
802         } catch (Exception e) {
803             writer.println("Failed dumping: " + service.getClass().getName());
804             e.printStackTrace(writer);
805         }
806     }
807 
execShellCmd(String[] args, PrintWriter writer)808     void execShellCmd(String[] args, PrintWriter writer) {
809         newCarShellCommand().exec(args, writer);
810     }
811 
812     @MainThread
traceBegin(String name)813     private void traceBegin(String name) {
814         Slog.i(TAG, name);
815         mBootTiming.traceBegin(name);
816     }
817 
818     @MainThread
traceEnd()819     private void traceEnd() {
820         mBootTiming.traceEnd();
821     }
822 }
823