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 20 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO; 21 22 import android.car.builtin.os.ServiceManagerHelper; 23 import android.car.builtin.os.SystemPropertiesHelper; 24 import android.car.builtin.os.TraceHelper; 25 import android.car.builtin.util.EventLogHelper; 26 import android.car.builtin.util.Slogf; 27 import android.content.Intent; 28 import android.os.IBinder; 29 import android.os.Process; 30 31 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport; 32 import com.android.car.internal.ProxiedService; 33 import com.android.car.systeminterface.SystemInterface; 34 import com.android.car.util.LimitedTimingsTraceLog; 35 import com.android.internal.annotations.Keep; 36 37 import java.io.FileDescriptor; 38 import java.io.PrintWriter; 39 40 /** Implementation of CarService */ 41 @Keep 42 public class CarServiceImpl extends ProxiedService { 43 public static final String CAR_SERVICE_INIT_TIMING_TAG = "CAR.InitTiming"; 44 public static final int CAR_SERVICE_INIT_TIMING_MIN_DURATION_MS = 5; 45 46 private ICarImpl mICarImpl; 47 private VehicleStub mVehicle; 48 49 private String mVehicleInterfaceName; 50 51 private final VehicleDeathRecipient mVehicleDeathRecipient = new VehicleDeathRecipient(); 52 53 @Override onCreate()54 public void onCreate() { 55 LimitedTimingsTraceLog initTiming = new LimitedTimingsTraceLog(CAR_SERVICE_INIT_TIMING_TAG, 56 TraceHelper.TRACE_TAG_CAR_SERVICE, CAR_SERVICE_INIT_TIMING_MIN_DURATION_MS); 57 initTiming.traceBegin("CarService.onCreate"); 58 59 initTiming.traceBegin("getVehicle"); 60 mVehicle = VehicleStub.newVehicleStub(); 61 initTiming.traceEnd(); // "getVehicle" 62 63 EventLogHelper.writeCarServiceCreate(/* hasVhal= */ mVehicle.isValid()); 64 65 mVehicleInterfaceName = mVehicle.getInterfaceDescriptor(); 66 67 Slogf.i(CarLog.TAG_SERVICE, "Connected to " + mVehicleInterfaceName); 68 EventLogHelper.writeCarServiceConnected(mVehicleInterfaceName); 69 70 mICarImpl = new ICarImpl(this, 71 getBuiltinPackageContext(), 72 mVehicle, 73 SystemInterface.Builder.defaultSystemInterface(this).build(), 74 mVehicleInterfaceName); 75 mICarImpl.init(); 76 77 mVehicle.linkToDeath(mVehicleDeathRecipient); 78 79 ServiceManagerHelper.addService("car_service", mICarImpl); 80 SystemPropertiesHelper.set("boot.car_service_created", "1"); 81 82 super.onCreate(); 83 84 initTiming.traceEnd(); // "CarService.onCreate" 85 } 86 87 // onDestroy is best-effort and might not get called on shutdown/reboot. As such it is not 88 // suitable for permanently saving state or other need-to-happen operation. If you have a 89 // cleanup task that you want to make sure happens on shutdown/reboot, see OnShutdownReboot. 90 @Override onDestroy()91 public void onDestroy() { 92 EventLogHelper.writeCarServiceDestroy(/* hasVhal= */ mVehicle.isValid()); 93 Slogf.i(CarLog.TAG_SERVICE, "Service onDestroy"); 94 mICarImpl.release(); 95 96 mVehicle.unlinkToDeath(mVehicleDeathRecipient); 97 mVehicle = null; 98 99 super.onDestroy(); 100 } 101 102 @Override onStartCommand(Intent intent, int flags, int startId)103 public int onStartCommand(Intent intent, int flags, int startId) { 104 // keep it alive. 105 return START_STICKY; 106 } 107 108 @Override onBind(Intent intent)109 public IBinder onBind(Intent intent) { 110 return mICarImpl; 111 } 112 113 @Override 114 @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO) dump(FileDescriptor fd, PrintWriter writer, String[] args)115 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 116 // historically, the way to get a dumpsys from CarService has been to use 117 // "dumpsys activity service com.android.car/.CarService" - leaving this 118 // as a forward to car_service makes the previously well-known command still work 119 mICarImpl.dump(fd, writer, args); 120 } 121 122 private static class VehicleDeathRecipient implements IVehicleDeathRecipient { 123 124 @Override serviceDied(long cookie)125 public void serviceDied(long cookie) { 126 EventLogHelper.writeCarServiceVhalDied(cookie); 127 Slogf.wtf(CarLog.TAG_SERVICE, "***Vehicle HAL died. Car service will restart***"); 128 Process.killProcess(Process.myPid()); 129 } 130 131 @Override binderDied()132 public void binderDied() { 133 EventLogHelper.writeCarServiceVhalDied(/*cookie=*/ 0); 134 Slogf.wtf(CarLog.TAG_SERVICE, "***Vehicle HAL died. Car service will restart***"); 135 Process.killProcess(Process.myPid()); 136 } 137 } 138 } 139