• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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