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