硬件访问服务
因为一个硬件可能会被多个app使用,所以必须使用硬件访问服务来保证硬件资源的有序使用。
总体而言,访问硬件资源的程序有且只有一个,即SystemServer,其它要访问这个硬件资源的APP必须给Server发请求,由Server间接的操作硬件,从而实现资源的访问
以vibrator为例分析代码
HAL
hardware\libhardware_legacy\vibrator\Vibrator.c
往"/sys/class/timed_output/vibrator/enable"中写入振动时间
int vibrator_on(int timeout_ms)
return sendit(timeout_ms);
fd = open(THE_DEVICE, O_RDWR); // "/sys/class/timed_output/vibrator/enable"
nwr = sprintf(value, "%d\n", timeout_ms);
ret = write(fd, value, nwr);
close(fd);
JNI
base\services\core\jni\com_android_server_VibratorService.cpp
// 注册
static JNINativeMethod method_table[] = {
{ "vibratorExists", "()Z", (void*)vibratorExists },
{ "vibratorOn", "(J)V", (void*)vibratorOn },
{ "vibratorOff", "()V", (void*)vibratorOff }
};
int register_android_server_VibratorService(JNIEnv *env)
return jniRegisterNativeMethods(env, "com/android/server/VibratorService", method_table, NELEM(method_table));
static void vibratorOn(JNIEnv *env, jobject clazz, jlong timeout_ms)
vibrator_on(timeout_ms); // 调用HAL
硬件访问服务
- 封装硬件访问接口
frameworks/base/core/java/android/os/IVibratorService.aidl
定义接口
interface IVibratorService
{
boolean hasVibrator();
void vibrate(int uid, String opPkg, long milliseconds, int usageHint, IBinder token);
void vibratePattern(int uid, String opPkg, in long[] pattern, int repeat, int usageHint, IBinder token);
void cancelVibrate(IBinder token);
}
base\services\core\java\com\android\server\VibratorService.java
实现接口
public void vibrate(int uid, String opPkg, long milliseconds, int usageHint, IBinder token)
startVibrationLocked(vib);
doVibratorOn(vib.mTimeout, vib.mUid, vib.mUsageHint);
vibratorOn(millis); // 调用JNI
mH.postDelayed(mVibrationRunnable, vib.mTimeout);
- 注册硬件访问服务
base\services\java\com\android\server\SystemServer.java
private void startOtherServices()
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
- 使用
base\core\java\android\os\SystemVibrator.java
// getService
public SystemVibrator()
mService = IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));
// 调用硬件访问接口
public void vibrate(int uid, String opPkg, long milliseconds, AudioAttributes attributes)
mService.vibrate(uid, opPkg, milliseconds, usageForAttributes(attributes), mToken); // 调用硬件访问服务