应用层需要拿到不同的CarService
CarService
中各个服务本质上是AIDL接口的实现类,属于Server端,而对应的Client端就需要一个IBinder
对象来访问Server端的方法,这些IBinder
对象在Car API中被封装在一个个XXXManager
类中。
Car API与CarService
中的服务,名称上存在对应关系,所以很好理解。例如:CarWatchdogManager
对应CarWatchdogService
,CarMediaManager
对应CarMediaService
以获取CarinputService为例:
应用层:主要看createCar()和getCarManager()
mCar = Car.createCar(this, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER,
(car, ready) -> {
mCar = car;
if (ready) {
mCarInputManager =
(CarInputManager) mCar.getCarManager(Car.CAR_INPUT_SERVICE);
//INPUT_TYPE_ALL_INPUTS : 对KeyEvent事件的监听 测试命令adb shell cmd car_service inject-key 3
//INPUT_TYPE_CUSTOM_INPUT_EVENT : 对CustomInputEvent事件的监听 测试命令adb shell cmd car_service inject-custom-input -d 0 f10
//INPUT_TYPE_ROTARY_NAVIGATION : 对旋转事件的监听,测试命令adb shell cmd car_service inject-rotary
//不添加相应参数,则不对相应事件做监听,收不到相应事件的回调
mCarInputManager.requestInputEventCapture(
CarOccupantZoneManager.DISPLAY_TYPE_MAIN,
new int[]{CarInputManager.INPUT_TYPE_ALL_INPUTS,
CarInputManager.INPUT_TYPE_CUSTOM_INPUT_EVENT,
CarInputManager.INPUT_TYPE_ROTARY_NAVIGATION},
CarInputManager.CAPTURE_REQ_FLAGS_ALLOW_DELAYED_GRANT,
/* callback= */ this);
mEventHandler = new CustomInputEventListener(getApplicationContext(),
(CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE),
(CarOccupantZoneManager) mCar.getCarManager(
Car.CAR_OCCUPANT_ZONE_SERVICE),
this);
}
});
客户端Car.java(Android13/packages/services/Car/car-lib/src/android/car/Car.java)
在createCar中通过ServiceManagerHelper.getService(CAR_SERVICE_BINDER_SERVICE_NAME)拿到CarService对象,创建Car对象实例并传入CarService,将CarService赋值给private ICar mService;
//Car.java
public static Car createCar(@NonNull Context context,
@Nullable Handler handler, long waitTimeoutMs,
@NonNull CarServiceLifecycleListener statusChangeListener) {
assertNonNullContext(context);
Objects.requireNonNull(statusChangeListener);
Car car = null;
IBinder service = null;
boolean started = false;
int retryCount = 0;
long maxRetryCount = 0;
if (waitTimeoutMs > 0) {
maxRetryCount = waitTimeoutMs / CAR_SERVICE_BINDER_POLLING_INTERVAL_MS;
// at least wait once if it is positive value.
if (maxRetryCount == 0) {
maxRetryCount = 1;
}
}
boolean isMainThread = Looper.myLooper() == Looper.getMainLooper();
while (true) {
service = ServiceManagerHelper.getService(CAR_SERVICE_BINDER_SERVICE_NAME);
if (car == null) {
// service can be still null. The constructor is safe for null service.
car = new Car(context, ICar.Stub.asInterface(service), null, statusChangeListener,
handler);
}
if (service != null) {
if (!started) { // specialization for most common case : car service already ready
car.dispatchCarReadyToMainThread(isMainThread);
// Needs this for CarServiceLifecycleListener. Note that ServiceConnection
// will skip the callback as valid mService is set already.
car.startCarService();
return car;
}
// service available after starting.
break;
}
if (!started) {
car.startCarService();
started = true;
}
retryCount++;
if (waitTimeoutMs < 0 && retryCount >= CAR_SERVICE_BINDER_POLLING_MAX_RETRY
&& retryCount % CAR_SERVICE_BINDER_POLLING_MAX_RETRY == 0) {
// Log warning if car service is not alive even for waiting forever case.
Log.w(TAG_CAR, "car_service not ready, waited for car service (ms):"
+ retryCount * CAR_SERVICE_BINDER_POLLING_INTERVAL_MS,
new RuntimeException());
} else if (waitTimeoutMs >= 0 && retryCount > maxRetryCount) {
if (waitTimeoutMs > 0) {
Log.w(TAG_CAR, "car_service not ready, waited for car service (ms):"
+ waitTimeoutMs,
new RuntimeException());
}
return car;
}
try {
Thread.sleep(CAR_SERVICE_BINDER_POLLING_INTERVAL_MS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Log.w(TAG_CAR, "interrupted", new RuntimeException());
return car;
}
}
// Can be accessed from mServiceConnectionListener in main thread.
synchronized (car.mLock) {
Log.w(TAG_CAR,
"waited for car_service (ms):"
+ retryCount * CAR_SERVICE_BINDER_POLLING_INTERVAL_MS,
new RuntimeException());
// ServiceConnection has handled everything.
if (car.mService != null) {
return car;
}
// mService check in ServiceConnection prevents calling
// onLifecycleChanged. So onLifecycleChanged should be called explicitly
// but do it outside lock.
car.mService = ICar.Stub.asInterface(service);
car.mConnectionState = STATE_CONNECTED;
}
car.dispatchCarReadyToMainThread(isMainThread);
return car;
}
//Car.java
private Car(Context context, @Nullable ICar service,
@Nullable ServiceConnection serviceConnectionListener,
@Nullable CarServiceLifecycleListener statusChangeListener,
@Nullable Handler handler) {
mContext = context;
mEventHandler = determineEventHandler(handler);
mMainThreadEventHandler = determineMainThreadEventHandler(mEventHandler);
mService = service;
if (service != null) {
mConnectionState = STATE_CONNECTED;
} else {
mConnectionState = STATE_DISCONNECTED;
}
mServiceConnectionListenerClient = serviceConnectionListener;
mStatusChangeCallback = statusChangeListener;
// Store construction stack so that client can get help when it crashes when car service
// crashes.
if (serviceConnectionListener == null && statusChangeListener == null) {
mConstructionStack = new RuntimeException();
} else {
mConstructionStack = null;
}
}
到此已经拿到了CarService对象,接下来只要调用getCarService根据serviceName拿到对应的XXXManager
应用层调用getCarManager具体实现:主要看mService.getCarService(serviceName)和createCarManagerLocked(serviceName, binder);
//Car.java
@Nullable
@AddedInOrBefore(majorVersion = 33)
public Object getCarManager(String serviceName) {
CarManagerBase manager;
synchronized (mLock) {
if (mService == null) {
Log.w(TAG_CAR, "getCarManager not working while car service not ready");
return null;
}
manager = mServiceMap.get(serviceName);
if (manager == null) {
try {
IBinder binder = mService.getCarService(serviceName);
if (binder == null) {
Log.w(TAG_CAR, "getCarManager could not get binder for service:"
+ serviceName);
return null;
}
manager = createCarManagerLocked(serviceName, binder);
if (manager == null) {
Log.w(TAG_CAR, "getCarManager could not create manager for service:"
+ serviceName);
return null;
}
mServiceMap.put(serviceName, manager);
} catch (RemoteException e) {
handleRemoteExceptionFromCarService(e);
}
}
}
return manager;
}
通过调用mService(也就是CarService,在Android13中改为ICarimpl)的getCarService方法拿到想要的binder对象(例如mCarInputService)
//ICarImpl.java
//源码路径Android13/packages/services/Car/service/src/com/android/car/ICarImpl.java
public IBinder getCarService(String serviceName) {
if (!mFeatureController.isFeatureEnabled(serviceName)) {
Slogf.w(CarLog.TAG_SERVICE, "getCarService for disabled service:" + serviceName);
return null;
}
switch (serviceName) {
case Car.AUDIO_SERVICE:
return mCarAudioService;
case Car.APP_FOCUS_SERVICE:
return mAppFocusService;
case Car.PACKAGE_SERVICE:
return mCarPackageManagerService;
case Car.DIAGNOSTIC_SERVICE:
CarServiceUtils.assertAnyDiagnosticPermission(mContext);
return mCarDiagnosticService;
......
......
case Car.CAR_INPUT_SERVICE:
return mCarInputService;
;
default:
IBinder service = null;
if (mCarExperimentalFeatureServiceController != null) {
service = mCarExperimentalFeatureServiceController.getCarService(serviceName);
}
if (service == null) {
Slogf.w(CarLog.TAG_SERVICE, "getCarService for unknown service:"
+ serviceName);
}
return service;
}
}
通过再接着通过createCarManagerLocked传入对应的binder创建想要的xxxManager对象实例
//Car.java
private CarManagerBase createCarManagerLocked(String serviceName, IBinder binder) {
CarManagerBase manager = null;
switch (serviceName) {
case AUDIO_SERVICE:
manager = new CarAudioManager(this, binder);
break;
case SENSOR_SERVICE:
manager = new CarSensorManager(this, binder);
break;
case INFO_SERVICE:
manager = new CarInfoManager(this, binder);
break;
case APP_FOCUS_SERVICE:
manager = new CarAppFocusManager(this, binder);
break;
case PACKAGE_SERVICE:
manager = new CarPackageManager(this, binder);
break;
case CAR_OCCUPANT_ZONE_SERVICE:
manager = new CarOccupantZoneManager(this, binder);
break;
case CAR_NAVIGATION_SERVICE:
manager = new CarNavigationStatusManager(this, binder);
break;
case CABIN_SERVICE:
manager = new CarCabinManager(this, binder);
break;
case DIAGNOSTIC_SERVICE:
manager = new CarDiagnosticManager(this, binder);
break;
case HVAC_SERVICE:
manager = new CarHvacManager(this, binder);
break;
case POWER_SERVICE:
manager = new CarPowerManager(this, binder);
break;
case PROJECTION_SERVICE:
manager = new CarProjectionManager(this, binder);
break;
......
......
default:
// Experimental or non-existing
String className = null;
try {
className = mService.getCarManagerClassForFeature(serviceName);
} catch (RemoteException e) {
handleRemoteExceptionFromCarService(e);
return null;
}
if (className == null) {
Log.e(TAG_CAR, "Cannot construct CarManager for service:" + serviceName
+ " : no class defined");
return null;
}
manager = constructCarManager(className, binder);
break;
}
return manager;
}
然后client端的xxxManager(例如CarInputManager)就拿到了对应的server端的service对像(CarInputService)
//CarInputManager.java
//Android13/packages/services/Car/car-lib/src/android/car/input/CarInputManager.java
public CarInputManager(Car car, IBinder service) {
super(car);
mService = ICarInput.Stub.asInterface(service);
}
这时就完成了应用层拿到想要的xxxManager对象,xxxManager拿到了xxxService对象,之后想要做具体的事情应用层只要调用xxManager提供的API,xxxManager再调用xxxService的api就行了
参考内容:
【Android R】车载 Android 核心服务 - CarService 解析 - 简书
Android Automotive(五) CarService_android car service_探求之路的博客-优快云博客
【IVI】Car.java获取Car相关服务和对应管理器_car_vendor_extension_xhBruce的博客-优快云博客