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