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