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.app.ActivityManager; 21 import android.app.UiModeManager; 22 import android.car.Car; 23 import android.car.ICar; 24 import android.car.cluster.renderer.IInstrumentClusterNavigation; 25 import android.car.userlib.CarUserManagerHelper; 26 import android.content.Context; 27 import android.content.pm.PackageManager; 28 import android.content.res.Resources; 29 import android.hardware.automotive.vehicle.V2_0.IVehicle; 30 import android.hardware.automotive.vehicle.V2_0.VehicleArea; 31 import android.os.Binder; 32 import android.os.Build; 33 import android.os.IBinder; 34 import android.os.Process; 35 import android.os.Trace; 36 import android.util.Log; 37 import android.util.Slog; 38 import android.util.TimingsTraceLog; 39 40 import com.android.car.audio.CarAudioService; 41 import com.android.car.cluster.InstrumentClusterService; 42 import com.android.car.garagemode.GarageModeService; 43 import com.android.car.hal.VehicleHal; 44 import com.android.car.internal.FeatureConfiguration; 45 import com.android.car.pm.CarPackageManagerService; 46 import com.android.car.systeminterface.SystemInterface; 47 import com.android.car.trust.CarTrustedDeviceService; 48 import com.android.car.user.CarUserService; 49 import com.android.car.vms.VmsBrokerService; 50 import com.android.car.vms.VmsClientManager; 51 import com.android.internal.annotations.GuardedBy; 52 import com.android.internal.car.ICarServiceHelper; 53 54 import java.io.FileDescriptor; 55 import java.io.PrintWriter; 56 import java.util.ArrayList; 57 import java.util.Arrays; 58 import java.util.List; 59 60 public class ICarImpl extends ICar.Stub { 61 62 public static final String INTERNAL_INPUT_SERVICE = "internal_input"; 63 public static final String INTERNAL_SYSTEM_ACTIVITY_MONITORING_SERVICE = 64 "system_activity_monitoring"; 65 66 private final Context mContext; 67 private final VehicleHal mHal; 68 69 private final SystemInterface mSystemInterface; 70 71 private final SystemActivityMonitoringService mSystemActivityMonitoringService; 72 private final CarPowerManagementService mCarPowerManagementService; 73 private final CarPackageManagerService mCarPackageManagerService; 74 private final CarInputService mCarInputService; 75 private final CarDrivingStateService mCarDrivingStateService; 76 private final CarUxRestrictionsManagerService mCarUXRestrictionsService; 77 private final CarAudioService mCarAudioService; 78 private final CarProjectionService mCarProjectionService; 79 private final CarPropertyService mCarPropertyService; 80 private final CarNightService mCarNightService; 81 private final AppFocusService mAppFocusService; 82 private final GarageModeService mGarageModeService; 83 private final InstrumentClusterService mInstrumentClusterService; 84 private final CarLocationService mCarLocationService; 85 private final SystemStateControllerService mSystemStateControllerService; 86 private final CarBluetoothService mCarBluetoothService; 87 private final PerUserCarServiceHelper mPerUserCarServiceHelper; 88 private final CarDiagnosticService mCarDiagnosticService; 89 private final CarStorageMonitoringService mCarStorageMonitoringService; 90 private final CarConfigurationService mCarConfigurationService; 91 private final CarTrustedDeviceService mCarTrustedDeviceService; 92 private final CarMediaService mCarMediaService; 93 private final CarUserManagerHelper mUserManagerHelper; 94 private final CarUserService mCarUserService; 95 private final VmsClientManager mVmsClientManager; 96 private final VmsBrokerService mVmsBrokerService; 97 private final VmsSubscriberService mVmsSubscriberService; 98 private final VmsPublisherService mVmsPublisherService; 99 private final CarBugreportManagerService mCarBugreportManagerService; 100 101 private final CarServiceBase[] mAllServices; 102 103 private static final String TAG = "ICarImpl"; 104 private static final String VHAL_TIMING_TAG = "VehicleHalTiming"; 105 106 private TimingsTraceLog mBootTiming; 107 108 /** Test only service. Populate it only when necessary. */ 109 @GuardedBy("this") 110 private CarTestService mCarTestService; 111 112 @GuardedBy("this") 113 private ICarServiceHelper mICarServiceHelper; 114 115 private final String mVehicleInterfaceName; 116 ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface, CanBusErrorNotifier errorNotifier, String vehicleInterfaceName)117 public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface, 118 CanBusErrorNotifier errorNotifier, String vehicleInterfaceName) { 119 mContext = serviceContext; 120 mSystemInterface = systemInterface; 121 mHal = new VehicleHal(vehicle); 122 mVehicleInterfaceName = vehicleInterfaceName; 123 mUserManagerHelper = new CarUserManagerHelper(serviceContext); 124 final Resources res = mContext.getResources(); 125 final int maxRunningUsers = res.getInteger( 126 com.android.internal.R.integer.config_multiuserMaxRunningUsers); 127 mCarUserService = new CarUserService(serviceContext, mUserManagerHelper, 128 ActivityManager.getService(), maxRunningUsers); 129 mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext); 130 mCarPowerManagementService = new CarPowerManagementService(mContext, mHal.getPowerHal(), 131 systemInterface, mUserManagerHelper); 132 mCarPropertyService = new CarPropertyService(serviceContext, mHal.getPropertyHal()); 133 mCarDrivingStateService = new CarDrivingStateService(serviceContext, mCarPropertyService); 134 mCarUXRestrictionsService = new CarUxRestrictionsManagerService(serviceContext, 135 mCarDrivingStateService, mCarPropertyService); 136 mCarPackageManagerService = new CarPackageManagerService(serviceContext, 137 mCarUXRestrictionsService, 138 mSystemActivityMonitoringService, 139 mUserManagerHelper); 140 mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext); 141 mCarBluetoothService = new CarBluetoothService(serviceContext, mPerUserCarServiceHelper); 142 mCarInputService = new CarInputService(serviceContext, mHal.getInputHal()); 143 mCarProjectionService = new CarProjectionService( 144 serviceContext, null /* handler */, mCarInputService, mCarBluetoothService); 145 mGarageModeService = new GarageModeService(mContext); 146 mAppFocusService = new AppFocusService(serviceContext, mSystemActivityMonitoringService); 147 mCarAudioService = new CarAudioService(serviceContext); 148 mCarNightService = new CarNightService(serviceContext, mCarPropertyService); 149 mInstrumentClusterService = new InstrumentClusterService(serviceContext, 150 mAppFocusService, mCarInputService); 151 mSystemStateControllerService = new SystemStateControllerService( 152 serviceContext, mCarAudioService, this); 153 mVmsBrokerService = new VmsBrokerService(mContext.getPackageManager()); 154 mVmsClientManager = new VmsClientManager( 155 serviceContext, mCarUserService, mUserManagerHelper, mHal.getVmsHal()); 156 mVmsSubscriberService = new VmsSubscriberService( 157 serviceContext, mVmsBrokerService, mHal.getVmsHal()); 158 mVmsPublisherService = new VmsPublisherService( 159 serviceContext, mVmsBrokerService, mVmsClientManager); 160 mCarDiagnosticService = new CarDiagnosticService(serviceContext, mHal.getDiagnosticHal()); 161 mCarStorageMonitoringService = new CarStorageMonitoringService(serviceContext, 162 systemInterface); 163 mCarConfigurationService = 164 new CarConfigurationService(serviceContext, new JsonReaderImpl()); 165 mCarLocationService = new CarLocationService(mContext, mUserManagerHelper); 166 mCarTrustedDeviceService = new CarTrustedDeviceService(serviceContext); 167 mCarMediaService = new CarMediaService(serviceContext); 168 mCarBugreportManagerService = new CarBugreportManagerService(serviceContext); 169 170 CarLocalServices.addService(CarPowerManagementService.class, mCarPowerManagementService); 171 CarLocalServices.addService(CarUserService.class, mCarUserService); 172 CarLocalServices.addService(CarTrustedDeviceService.class, mCarTrustedDeviceService); 173 CarLocalServices.addService(SystemInterface.class, mSystemInterface); 174 CarLocalServices.addService(CarDrivingStateService.class, mCarDrivingStateService); 175 CarLocalServices.addService(PerUserCarServiceHelper.class, mPerUserCarServiceHelper); 176 177 // Be careful with order. Service depending on other service should be inited later. 178 List<CarServiceBase> allServices = new ArrayList<>(); 179 allServices.add(mCarUserService); 180 allServices.add(mSystemActivityMonitoringService); 181 allServices.add(mCarPowerManagementService); 182 allServices.add(mCarPropertyService); 183 allServices.add(mCarDrivingStateService); 184 allServices.add(mCarUXRestrictionsService); 185 allServices.add(mCarPackageManagerService); 186 allServices.add(mCarInputService); 187 allServices.add(mGarageModeService); 188 allServices.add(mAppFocusService); 189 allServices.add(mCarAudioService); 190 allServices.add(mCarNightService); 191 allServices.add(mInstrumentClusterService); 192 allServices.add(mSystemStateControllerService); 193 allServices.add(mPerUserCarServiceHelper); 194 allServices.add(mCarBluetoothService); 195 allServices.add(mCarProjectionService); 196 allServices.add(mCarDiagnosticService); 197 allServices.add(mCarStorageMonitoringService); 198 allServices.add(mCarConfigurationService); 199 allServices.add(mVmsClientManager); 200 allServices.add(mVmsSubscriberService); 201 allServices.add(mVmsPublisherService); 202 allServices.add(mCarTrustedDeviceService); 203 allServices.add(mCarMediaService); 204 allServices.add(mCarLocationService); 205 allServices.add(mCarBugreportManagerService); 206 mAllServices = allServices.toArray(new CarServiceBase[allServices.size()]); 207 } 208 209 @MainThread init()210 void init() { 211 mBootTiming = new TimingsTraceLog(VHAL_TIMING_TAG, Trace.TRACE_TAG_HAL); 212 traceBegin("VehicleHal.init"); 213 mHal.init(); 214 traceEnd(); 215 traceBegin("CarService.initAllServices"); 216 for (CarServiceBase service : mAllServices) { 217 service.init(); 218 } 219 traceEnd(); 220 mSystemInterface.reconfigureSecondaryDisplays(); 221 } 222 release()223 void release() { 224 // release done in opposite order from init 225 for (int i = mAllServices.length - 1; i >= 0; i--) { 226 mAllServices[i].release(); 227 } 228 mHal.release(); 229 CarLocalServices.removeAllServices(); 230 } 231 vehicleHalReconnected(IVehicle vehicle)232 void vehicleHalReconnected(IVehicle vehicle) { 233 mHal.vehicleHalReconnected(vehicle); 234 for (CarServiceBase service : mAllServices) { 235 service.vehicleHalReconnected(); 236 } 237 } 238 239 @Override setCarServiceHelper(IBinder helper)240 public void setCarServiceHelper(IBinder helper) { 241 assertCallingFromSystemProcess(); 242 synchronized (this) { 243 mICarServiceHelper = ICarServiceHelper.Stub.asInterface(helper); 244 mSystemInterface.setCarServiceHelper(mICarServiceHelper); 245 } 246 } 247 248 @Override setUserLockStatus(int userHandle, int unlocked)249 public void setUserLockStatus(int userHandle, int unlocked) { 250 assertCallingFromSystemProcess(); 251 mCarUserService.setUserLockStatus(userHandle, unlocked == 1); 252 } 253 254 @Override onSwitchUser(int userHandle)255 public void onSwitchUser(int userHandle) { 256 assertCallingFromSystemProcess(); 257 258 Log.i(TAG, "Foreground user switched to " + userHandle); 259 mCarUserService.onSwitchUser(userHandle); 260 } 261 assertCallingFromSystemProcess()262 static void assertCallingFromSystemProcess() { 263 int uid = Binder.getCallingUid(); 264 if (uid != Process.SYSTEM_UID) { 265 throw new SecurityException("Only allowed from system"); 266 } 267 } 268 269 /** 270 * Assert if binder call is coming from system process like system server or if it is called 271 * from its own process even if it is not system. The latter can happen in test environment. 272 * Note that car service runs as system user but test like car service test will not. 273 */ assertCallingFromSystemProcessOrSelf()274 static void assertCallingFromSystemProcessOrSelf() { 275 int uid = Binder.getCallingUid(); 276 int pid = Binder.getCallingPid(); 277 if (uid != Process.SYSTEM_UID && pid != Process.myPid()) { 278 throw new SecurityException("Only allowed from system or self"); 279 } 280 } 281 282 @Override getCarService(String serviceName)283 public IBinder getCarService(String serviceName) { 284 switch (serviceName) { 285 case Car.AUDIO_SERVICE: 286 return mCarAudioService; 287 case Car.APP_FOCUS_SERVICE: 288 return mAppFocusService; 289 case Car.PACKAGE_SERVICE: 290 return mCarPackageManagerService; 291 case Car.DIAGNOSTIC_SERVICE: 292 assertAnyDiagnosticPermission(mContext); 293 return mCarDiagnosticService; 294 case Car.POWER_SERVICE: 295 assertPowerPermission(mContext); 296 return mCarPowerManagementService; 297 case Car.CABIN_SERVICE: 298 case Car.HVAC_SERVICE: 299 case Car.INFO_SERVICE: 300 case Car.PROPERTY_SERVICE: 301 case Car.SENSOR_SERVICE: 302 case Car.VENDOR_EXTENSION_SERVICE: 303 return mCarPropertyService; 304 case Car.CAR_NAVIGATION_SERVICE: 305 assertNavigationManagerPermission(mContext); 306 IInstrumentClusterNavigation navService = 307 mInstrumentClusterService.getNavigationService(); 308 return navService == null ? null : navService.asBinder(); 309 case Car.CAR_INSTRUMENT_CLUSTER_SERVICE: 310 assertClusterManagerPermission(mContext); 311 return mInstrumentClusterService.getManagerService(); 312 case Car.PROJECTION_SERVICE: 313 return mCarProjectionService; 314 case Car.VMS_SUBSCRIBER_SERVICE: 315 assertVmsSubscriberPermission(mContext); 316 return mVmsSubscriberService; 317 case Car.TEST_SERVICE: { 318 assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE); 319 synchronized (this) { 320 if (mCarTestService == null) { 321 mCarTestService = new CarTestService(mContext, this); 322 } 323 return mCarTestService; 324 } 325 } 326 case Car.BLUETOOTH_SERVICE: 327 return mCarBluetoothService; 328 case Car.STORAGE_MONITORING_SERVICE: 329 assertPermission(mContext, Car.PERMISSION_STORAGE_MONITORING); 330 return mCarStorageMonitoringService; 331 case Car.CAR_DRIVING_STATE_SERVICE: 332 assertDrivingStatePermission(mContext); 333 return mCarDrivingStateService; 334 case Car.CAR_UX_RESTRICTION_SERVICE: 335 return mCarUXRestrictionsService; 336 case Car.CAR_CONFIGURATION_SERVICE: 337 return mCarConfigurationService; 338 case Car.CAR_TRUST_AGENT_ENROLLMENT_SERVICE: 339 assertTrustAgentEnrollmentPermission(mContext); 340 return mCarTrustedDeviceService.getCarTrustAgentEnrollmentService(); 341 case Car.CAR_MEDIA_SERVICE: 342 return mCarMediaService; 343 case Car.CAR_BUGREPORT_SERVICE: 344 return mCarBugreportManagerService; 345 default: 346 Log.w(CarLog.TAG_SERVICE, "getCarService for unknown service:" + serviceName); 347 return null; 348 } 349 } 350 351 @Override getCarConnectionType()352 public int getCarConnectionType() { 353 return Car.CONNECTION_TYPE_EMBEDDED; 354 } 355 getCarInternalService(String serviceName)356 public CarServiceBase getCarInternalService(String serviceName) { 357 switch (serviceName) { 358 case INTERNAL_INPUT_SERVICE: 359 return mCarInputService; 360 case INTERNAL_SYSTEM_ACTIVITY_MONITORING_SERVICE: 361 return mSystemActivityMonitoringService; 362 default: 363 Log.w(CarLog.TAG_SERVICE, "getCarInternalService for unknown service:" + 364 serviceName); 365 return null; 366 } 367 } 368 assertVehicleHalMockPermission(Context context)369 public static void assertVehicleHalMockPermission(Context context) { 370 assertPermission(context, Car.PERMISSION_MOCK_VEHICLE_HAL); 371 } 372 assertNavigationManagerPermission(Context context)373 public static void assertNavigationManagerPermission(Context context) { 374 assertPermission(context, Car.PERMISSION_CAR_NAVIGATION_MANAGER); 375 } 376 assertClusterManagerPermission(Context context)377 public static void assertClusterManagerPermission(Context context) { 378 assertPermission(context, Car.PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL); 379 } 380 assertPowerPermission(Context context)381 public static void assertPowerPermission(Context context) { 382 assertPermission(context, Car.PERMISSION_CAR_POWER); 383 } 384 assertProjectionPermission(Context context)385 public static void assertProjectionPermission(Context context) { 386 assertPermission(context, Car.PERMISSION_CAR_PROJECTION); 387 } 388 389 /** Verify the calling context has the {@link Car#PERMISSION_CAR_PROJECTION_STATUS} */ assertProjectionStatusPermission(Context context)390 public static void assertProjectionStatusPermission(Context context) { 391 assertPermission(context, Car.PERMISSION_CAR_PROJECTION_STATUS); 392 } 393 assertAnyDiagnosticPermission(Context context)394 public static void assertAnyDiagnosticPermission(Context context) { 395 assertAnyPermission(context, 396 Car.PERMISSION_CAR_DIAGNOSTIC_READ_ALL, 397 Car.PERMISSION_CAR_DIAGNOSTIC_CLEAR); 398 } 399 assertDrivingStatePermission(Context context)400 public static void assertDrivingStatePermission(Context context) { 401 assertPermission(context, Car.PERMISSION_CAR_DRIVING_STATE); 402 } 403 assertVmsPublisherPermission(Context context)404 public static void assertVmsPublisherPermission(Context context) { 405 assertPermission(context, Car.PERMISSION_VMS_PUBLISHER); 406 } 407 assertVmsSubscriberPermission(Context context)408 public static void assertVmsSubscriberPermission(Context context) { 409 assertPermission(context, Car.PERMISSION_VMS_SUBSCRIBER); 410 } 411 412 /** 413 * Ensures the caller has the permission to enroll a Trust Agent. 414 */ assertTrustAgentEnrollmentPermission(Context context)415 public static void assertTrustAgentEnrollmentPermission(Context context) { 416 assertPermission(context, Car.PERMISSION_CAR_ENROLL_TRUST); 417 } 418 assertPermission(Context context, String permission)419 public static void assertPermission(Context context, String permission) { 420 if (context.checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { 421 throw new SecurityException("requires " + permission); 422 } 423 } 424 425 /** 426 * Checks to see if the caller has a permission. 427 * 428 * @return boolean TRUE if caller has the permission. 429 */ hasPermission(Context context, String permission)430 public static boolean hasPermission(Context context, String permission) { 431 return context.checkCallingOrSelfPermission(permission) 432 == PackageManager.PERMISSION_GRANTED; 433 } 434 assertAnyPermission(Context context, String... permissions)435 public static void assertAnyPermission(Context context, String... permissions) { 436 for (String permission : permissions) { 437 if (context.checkCallingOrSelfPermission(permission) == 438 PackageManager.PERMISSION_GRANTED) { 439 return; 440 } 441 } 442 throw new SecurityException("requires any of " + Arrays.toString(permissions)); 443 } 444 445 @Override dump(FileDescriptor fd, PrintWriter writer, String[] args)446 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 447 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 448 != PackageManager.PERMISSION_GRANTED) { 449 writer.println("Permission Denial: can't dump CarService from from pid=" 450 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 451 + " without permission " + android.Manifest.permission.DUMP); 452 return; 453 } 454 455 if (args == null || args.length == 0 || (args.length > 0 && "-a".equals(args[0]))) { 456 writer.println("*Dump car service*"); 457 writer.println("*FutureConfig, DEFAULT:" + FeatureConfiguration.DEFAULT); 458 writer.println("*Dump all services*"); 459 460 dumpAllServices(writer, false); 461 462 writer.println("*Dump Vehicle HAL*"); 463 writer.println("Vehicle HAL Interface: " + mVehicleInterfaceName); 464 try { 465 // TODO dump all feature flags by creating a dumpable interface 466 mHal.dump(writer); 467 } catch (Exception e) { 468 writer.println("Failed dumping: " + mHal.getClass().getName()); 469 e.printStackTrace(writer); 470 } 471 } else if ("--metrics".equals(args[0])) { 472 writer.println("*Dump car service metrics*"); 473 dumpAllServices(writer, true); 474 } else if (Build.IS_USERDEBUG || Build.IS_ENG) { 475 execShellCmd(args, writer); 476 } else { 477 writer.println("Commands not supported in " + Build.TYPE); 478 } 479 } 480 dumpAllServices(PrintWriter writer, boolean dumpMetricsOnly)481 private void dumpAllServices(PrintWriter writer, boolean dumpMetricsOnly) { 482 for (CarServiceBase service : mAllServices) { 483 dumpService(service, writer, dumpMetricsOnly); 484 } 485 if (mCarTestService != null) { 486 dumpService(mCarTestService, writer, dumpMetricsOnly); 487 } 488 489 } 490 dumpService(CarServiceBase service, PrintWriter writer, boolean dumpMetricsOnly)491 private void dumpService(CarServiceBase service, PrintWriter writer, boolean dumpMetricsOnly) { 492 try { 493 if (dumpMetricsOnly) { 494 service.dumpMetrics(writer); 495 } else { 496 service.dump(writer); 497 } 498 } catch (Exception e) { 499 writer.println("Failed dumping: " + service.getClass().getName()); 500 e.printStackTrace(writer); 501 } 502 } 503 execShellCmd(String[] args, PrintWriter writer)504 void execShellCmd(String[] args, PrintWriter writer) { 505 new CarShellCommand().exec(args, writer); 506 } 507 508 @MainThread traceBegin(String name)509 private void traceBegin(String name) { 510 Slog.i(TAG, name); 511 mBootTiming.traceBegin(name); 512 } 513 514 @MainThread traceEnd()515 private void traceEnd() { 516 mBootTiming.traceEnd(); 517 } 518 519 private class CarShellCommand { 520 private static final String COMMAND_HELP = "-h"; 521 private static final String COMMAND_DAY_NIGHT_MODE = "day-night-mode"; 522 private static final String COMMAND_INJECT_VHAL_EVENT = "inject-vhal-event"; 523 private static final String COMMAND_INJECT_ERROR_EVENT = "inject-error-event"; 524 private static final String COMMAND_ENABLE_UXR = "enable-uxr"; 525 private static final String COMMAND_GARAGE_MODE = "garage-mode"; 526 private static final String COMMAND_GET_DO_ACTIVITIES = "get-do-activities"; 527 private static final String COMMAND_GET_CARPROPERTYCONFIG = "get-carpropertyconfig"; 528 private static final String COMMAND_GET_PROPERTY_VALUE = "get-property-value"; 529 private static final String COMMAND_PROJECTION_AP_TETHERING = "projection-tethering"; 530 private static final String COMMAND_PROJECTION_UI_MODE = "projection-ui-mode"; 531 private static final String COMMAND_RESUME = "resume"; 532 private static final String COMMAND_SUSPEND = "suspend"; 533 private static final String COMMAND_ENABLE_TRUSTED_DEVICE = "enable-trusted-device"; 534 private static final String COMMAND_REMOVE_TRUSTED_DEVICES = "remove-trusted-devices"; 535 536 private static final String PARAM_DAY_MODE = "day"; 537 private static final String PARAM_NIGHT_MODE = "night"; 538 private static final String PARAM_SENSOR_MODE = "sensor"; 539 private static final String PARAM_VEHICLE_PROPERTY_AREA_GLOBAL = "0"; 540 private static final String PARAM_ON_MODE = "on"; 541 private static final String PARAM_OFF_MODE = "off"; 542 private static final String PARAM_QUERY_MODE = "query"; 543 544 dumpHelp(PrintWriter pw)545 private void dumpHelp(PrintWriter pw) { 546 pw.println("Car service commands:"); 547 pw.println("\t-h"); 548 pw.println("\t Print this help text."); 549 pw.println("\tday-night-mode [day|night|sensor]"); 550 pw.println("\t Force into day/night mode or restore to auto."); 551 pw.println("\tinject-vhal-event property [zone] data(can be comma separated list)"); 552 pw.println("\t Inject a vehicle property for testing."); 553 pw.println("\tinject-error-event property zone errorCode"); 554 pw.println("\t Inject an error event from VHAL for testing."); 555 pw.println("\tenable-uxr true|false"); 556 pw.println("\t Enable/Disable UX restrictions and App blocking."); 557 pw.println("\tgarage-mode [on|off|query]"); 558 pw.println("\t Force into garage mode or check status."); 559 pw.println("\tget-do-activities pkgname"); 560 pw.println("\t Get Distraction Optimized activities in given package."); 561 pw.println("\tget-carpropertyconfig [propertyId]"); 562 pw.println("\t Get a CarPropertyConfig by Id in Hex or list all CarPropertyConfigs"); 563 pw.println("\tget-property-value [propertyId] [areaId]"); 564 pw.println("\t Get a vehicle property value by property id in Hex and areaId"); 565 pw.println("\t or list all property values for all areaId"); 566 pw.println("\tsuspend"); 567 pw.println("\t Suspend the system to Deep Sleep."); 568 pw.println("\tresume"); 569 pw.println("\t Wake the system up after a 'suspend.'"); 570 pw.println("\tenable-trusted-device true|false"); 571 pw.println("\t Enable/Disable Trusted device feature."); 572 pw.println("\tremove-trusted-devices"); 573 pw.println("\t Remove all trusted devices for the current foreground user."); 574 pw.println("\tprojection-tethering [true|false]"); 575 pw.println("\t Whether tethering should be used when creating access point for" 576 + " wireless projection"); 577 pw.println("\t--metrics"); 578 pw.println("\t When used with dumpsys, only metrics will be in the dumpsys output."); 579 } 580 exec(String[] args, PrintWriter writer)581 public void exec(String[] args, PrintWriter writer) { 582 String arg = args[0]; 583 switch (arg) { 584 case COMMAND_HELP: 585 dumpHelp(writer); 586 break; 587 case COMMAND_DAY_NIGHT_MODE: { 588 String value = args.length < 2 ? "" : args[1]; 589 forceDayNightMode(value, writer); 590 break; 591 } 592 case COMMAND_GARAGE_MODE: { 593 String value = args.length < 2 ? "" : args[1]; 594 forceGarageMode(value, writer); 595 break; 596 } 597 case COMMAND_INJECT_VHAL_EVENT: 598 String zone = PARAM_VEHICLE_PROPERTY_AREA_GLOBAL; 599 String data; 600 if (args.length != 3 && args.length != 4) { 601 writer.println("Incorrect number of arguments."); 602 dumpHelp(writer); 603 break; 604 } else if (args.length == 4) { 605 // Zoned 606 zone = args[2]; 607 data = args[3]; 608 } else { 609 // Global 610 data = args[2]; 611 } 612 injectVhalEvent(args[1], zone, data, false, writer); 613 break; 614 case COMMAND_INJECT_ERROR_EVENT: 615 if (args.length != 4) { 616 writer.println("Incorrect number of arguments"); 617 dumpHelp(writer); 618 break; 619 } 620 String errorAreaId = args[2]; 621 String errorCode = args[3]; 622 injectVhalEvent(args[1], errorAreaId, errorCode, true, writer); 623 break; 624 case COMMAND_ENABLE_UXR: 625 if (args.length != 2) { 626 writer.println("Incorrect number of arguments"); 627 dumpHelp(writer); 628 break; 629 } 630 boolean enableBlocking = Boolean.valueOf(args[1]); 631 if (mCarPackageManagerService != null) { 632 mCarPackageManagerService.setEnableActivityBlocking(enableBlocking); 633 } 634 break; 635 case COMMAND_GET_DO_ACTIVITIES: 636 if (args.length != 2) { 637 writer.println("Incorrect number of arguments"); 638 dumpHelp(writer); 639 break; 640 } 641 String pkgName = args[1].toLowerCase(); 642 if (mCarPackageManagerService != null) { 643 String[] doActivities = 644 mCarPackageManagerService.getDistractionOptimizedActivities( 645 pkgName); 646 if (doActivities != null) { 647 writer.println("DO Activities for " + pkgName); 648 for (String a : doActivities) { 649 writer.println(a); 650 } 651 } else { 652 writer.println("No DO Activities for " + pkgName); 653 } 654 } 655 break; 656 case COMMAND_GET_CARPROPERTYCONFIG: 657 String propertyId = args.length < 2 ? "" : args[1]; 658 mHal.dumpPropertyConfigs(writer, propertyId); 659 break; 660 case COMMAND_GET_PROPERTY_VALUE: 661 String propId = args.length < 2 ? "" : args[1]; 662 String areaId = args.length < 3 ? "" : args[2]; 663 mHal.dumpPropertyValueByCommend(writer, propId, areaId); 664 break; 665 case COMMAND_PROJECTION_UI_MODE: 666 if (args.length != 2) { 667 writer.println("Incorrect number of arguments"); 668 dumpHelp(writer); 669 break; 670 } 671 mCarProjectionService.setUiMode(Integer.valueOf(args[1])); 672 break; 673 case COMMAND_PROJECTION_AP_TETHERING: 674 if (args.length != 2) { 675 writer.println("Incorrect number of arguments"); 676 dumpHelp(writer); 677 break; 678 } 679 mCarProjectionService.setAccessPointTethering(Boolean.valueOf(args[1])); 680 break; 681 case COMMAND_RESUME: 682 mCarPowerManagementService.forceSimulatedResume(); 683 writer.println("Resume: Simulating resuming from Deep Sleep"); 684 break; 685 case COMMAND_SUSPEND: 686 mCarPowerManagementService.forceSimulatedSuspend(); 687 writer.println("Resume: Simulating powering down to Deep Sleep"); 688 break; 689 case COMMAND_ENABLE_TRUSTED_DEVICE: 690 if (args.length != 2) { 691 writer.println("Incorrect number of arguments"); 692 dumpHelp(writer); 693 break; 694 } 695 mCarTrustedDeviceService.getCarTrustAgentEnrollmentService() 696 .setTrustedDeviceEnrollmentEnabled(Boolean.valueOf(args[1])); 697 mCarTrustedDeviceService.getCarTrustAgentUnlockService() 698 .setTrustedDeviceUnlockEnabled(Boolean.valueOf(args[1])); 699 break; 700 case COMMAND_REMOVE_TRUSTED_DEVICES: 701 mCarTrustedDeviceService.getCarTrustAgentEnrollmentService() 702 .removeAllTrustedDevices( 703 mUserManagerHelper.getCurrentForegroundUserId()); 704 break; 705 default: 706 writer.println("Unknown command: \"" + arg + "\""); 707 dumpHelp(writer); 708 } 709 } 710 711 private void forceDayNightMode(String arg, PrintWriter writer) { 712 int mode; 713 switch (arg) { 714 case PARAM_DAY_MODE: 715 mode = CarNightService.FORCED_DAY_MODE; 716 break; 717 case PARAM_NIGHT_MODE: 718 mode = CarNightService.FORCED_NIGHT_MODE; 719 break; 720 case PARAM_SENSOR_MODE: 721 mode = CarNightService.FORCED_SENSOR_MODE; 722 break; 723 default: 724 writer.println("Unknown value. Valid argument: " + PARAM_DAY_MODE + "|" 725 + PARAM_NIGHT_MODE + "|" + PARAM_SENSOR_MODE); 726 return; 727 } 728 int current = mCarNightService.forceDayNightMode(mode); 729 String currentMode = null; 730 switch (current) { 731 case UiModeManager.MODE_NIGHT_AUTO: 732 currentMode = PARAM_SENSOR_MODE; 733 break; 734 case UiModeManager.MODE_NIGHT_YES: 735 currentMode = PARAM_NIGHT_MODE; 736 break; 737 case UiModeManager.MODE_NIGHT_NO: 738 currentMode = PARAM_DAY_MODE; 739 break; 740 } 741 writer.println("DayNightMode changed to: " + currentMode); 742 } 743 744 private void forceGarageMode(String arg, PrintWriter writer) { 745 switch (arg) { 746 case PARAM_ON_MODE: 747 mGarageModeService.forceStartGarageMode(); 748 writer.println("Garage mode: " + mGarageModeService.isGarageModeActive()); 749 break; 750 case PARAM_OFF_MODE: 751 mGarageModeService.stopAndResetGarageMode(); 752 writer.println("Garage mode: " + mGarageModeService.isGarageModeActive()); 753 break; 754 case PARAM_QUERY_MODE: 755 mGarageModeService.dump(writer); 756 break; 757 default: 758 writer.println("Unknown value. Valid argument: " + PARAM_ON_MODE + "|" 759 + PARAM_OFF_MODE + "|" + PARAM_QUERY_MODE); 760 } 761 } 762 763 /** 764 * Inject a fake VHAL event 765 * 766 * @param property the Vehicle property Id as defined in the HAL 767 * @param zone Zone that this event services 768 * @param isErrorEvent indicates the type of event 769 * @param value Data value of the event 770 * @param writer PrintWriter 771 */ 772 private void injectVhalEvent(String property, String zone, String value, 773 boolean isErrorEvent, PrintWriter writer) { 774 if (zone != null && (zone.equalsIgnoreCase(PARAM_VEHICLE_PROPERTY_AREA_GLOBAL))) { 775 if (!isPropertyAreaTypeGlobal(property)) { 776 writer.println("Property area type inconsistent with given zone"); 777 return; 778 } 779 } 780 try { 781 if (isErrorEvent) { 782 mHal.injectOnPropertySetError(property, zone, value); 783 } else { 784 mHal.injectVhalEvent(property, zone, value); 785 } 786 } catch (NumberFormatException e) { 787 writer.println("Invalid property Id zone Id or value" + e); 788 dumpHelp(writer); 789 } 790 } 791 792 // Check if the given property is global 793 private boolean isPropertyAreaTypeGlobal(String property) { 794 if (property == null) { 795 return false; 796 } 797 return (Integer.decode(property) & VehicleArea.MASK) == VehicleArea.GLOBAL; 798 } 799 } 800 } 801