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