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