硬件访问服务

因为一个硬件可能会被多个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);    // 调用硬件访问服务
posted @ 2018-01-23 15:06  __千里之行  阅读(282)  评论(0编辑  收藏  举报