Android System Server大纲之VibratorService
2017-02-15 15:14
405 查看
Android System Server大纲之VibratorService
vibratorAndroid System Server大纲之VibratorService
前言
VibratorService类型
APP使用VibratorService
VibratorService驱动硬件
前言
VibratorService即安卓震动服务,是Android系统中一个和硬件相关的服务,管理和驱动着设备的振动器。在Android手持设备,如手机,平板等,振动器是不可或缺的硬件设备,在给用户震动反馈的用户交互中发挥了举足轻重的作用。既然是和硬件相关的服务,那么以Android系统的架构模式,VibratorService将对应以下架构
VibratorService类型
直接上代码:public class VibratorService extends IVibratorService.Stub implements InputManager.InputDeviceListener { }
上述代码可以看到,VibratorService继承了IVibratorService.Stub,也就是说,VibratorService直接支持Android IPC Binder通信,那么上层APP就可以通过AIDL使用VibratorService,驱动设备上的振动器,从而给用户震动的反馈。
VibratorService提供哪些接口可以给上层使用呢?看看接口IVibratorService:
public interface IVibratorService extends android.os.IInterface{ public boolean hasVibrator(); public void vibrate(); public void vibratePattern(); public void cancelVibrate(); }
上述代码可以看到,VibratorService提供上述四个接口给上层调用,hasVibrator()判断是当前设备否有支持振动器,然后通过vibrate()或vibratePattern()驱动震动器发起震动,前者只需要关心参数milliseconds,即震动的时间,时间结束后,震动停止,后者需要关心的参数有pattern和repeat,pattern是long型的数组,保存的是每次震动持续的时间,即milliseconds,repeat固然就是重复的次数。所以vibrate()是一次性振动器,vibratePattern()是重复多次震动。cancelVibrate()固然是取消震动了。
APP使用VibratorService
Android针对上层APP使用System Server的功能,提供了一套机制,首先是获取到封装了VibratorService Binder句柄的对象,然后通过该对象间接调用System Server中service的接口。Android通用的代码实现方式如下:Context.getSystemService()
通过上下文Context的getSystemService()方法获取封装了Binder句柄的framework对象实例,返回值是一个Object类型,需要相应向下强制转换成对应的类型。对于VibratorService,通过getSystemService()传入的参数是Context.VIBRATOR_SERVICE。
public abstract class Context { /** * Use with {@link #getSystemService} to retrieve a {@link * android.os.Vibrator} for interacting with the vibration hardware. * * @see #getSystemService * @see android.os.Vibrato f4f2 r */ public static final String VIBRATOR_SERVICE = "vibrator"; }
getSystemService(Context.VIBRATOR_SERVICE)返回的是一个android.os.Vibrator的实例。Context.VIBRATOR_SERVICE的值是vibrator,获取的对应的远程是否就是VibratorService呢?先来回顾一下另外一篇文章《Android系统之System Server大纲》中的服务启动过程,VibratorService是继承了IPC通信接口,所以是通过ServiceManager.addService()的方式启动该系统服务,读者可以参考Android系统之System Server大纲,看VibratorService的启动代码:
vibrator = new VibratorService(context); ServiceManager.addService("vibrator", vibrator);
VibratorService启动后正是以”vibrator”这个标签加入到ServiceManager中,所以getSystemService(Context.VIBRATOR_SERVICE)返回的android.os.Vibrator实例刚好是对应了VibratorService。在看看android.os.Vibrator这个类:
public abstract class Vibrator { }
android.os.Vibrator是一个抽象类,而Java是不能new一个抽象类的实例的,所以getSystemService(Context.VIBRATOR_SERVICE)返回来的只是android.os.Vibrator的子类的实例,到底是那个实现类呢?追踪Context.getSystemService(Context.VIBRATOR_SERVICE)的过程寻找点线索,然而Context也是一个抽象了,所以Context.getSystemService(Context.VIBRATOR_SERVICE)也是在Context的实现类中去执行
public abstract class Context { public abstract Object getSystemService(@ServiceName @NonNull String name); }
Context的实现类是android/app/ContextImpl.java,getSystemService()的实现如下:
class ContextImpl extends Context { @Override public Object getSystemService(String name) { return SystemServiceRegistry.getSystemService(this, name); } }
这里直接调用了SystemServiceRegistry的getSystemService()方法,继续往下看代码:
final class SystemServiceRegistry { /** * Gets a system service from a given context. */ public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); return fetcher != null ? fetcher.getService(ctx) : null; } }
通过name作为key在SYSTEM_SERVICE_FETCHERS中获取ServiceFetcher
final class SystemServiceRegistry { private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new HashMap<String, ServiceFetcher<?>>(); }
上述代码可知SYSTEM_SERVICE_FETCHERS是一个HashMap的对象实例,通过name = vibrator作为Map的查询values,查看SYSTEM_SERVICE_FETCHERS中保存的values对象,就可以寻找到Context.getSystemService(Context.VIBRATOR_SERVICE)返回的真正的对象实例是什么类型。看SYSTEM_SERVICE_FETCHERS的填充数据过程:
final class SystemServiceRegistry { private static <T> void registerService(String serviceName, Class<T> serviceClass, ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); } }
通过registerService()的方式注册,再继续跟踪vibrator在哪里被注册到SYSTEM_SERVICE_FETCHERS:
final class SystemServiceRegistry { static { registerService(Context.VIBRATOR_SERVICE, Vibrator.class, new CachedServiceFetcher<Vibrator>() { @Override public Vibrator createService(ContextImpl ctx) { return new SystemVibrator(ctx); }}); } }
上述代码中可以看到,registerService()传入的key正好是Context.VIBRATOR_SERVICE,和Context.getSystemService(Context.VIBRATOR_SERVICE)中的参数一致,registerService()中传入的android.os.Vibrator是android/os/SystemVibrator.java,所以Context.getSystemService(Context.VIBRATOR_SERVICE)返回的真正的实例是SystemVibrator:
public class SystemVibrator extends Vibrator { private final IVibratorService mService; public SystemVibrator() { mService = IVibratorService.Stub.asInterface( ServiceManager.getService("vibrator")); } public void cancel() {} public boolean hasVibrator() {} public void vibrate(..... long milliseconds .....) {} public void vibrate(..... long[] pattern, int repeat .....) { }
上述代码可以看到,SystemVibrator的构造方法中初始化了IVibratorService的对象mService,通过ServiceManager.getService(“vibrator”)获取到VibratorService的句柄。
因此,APP通过Context.getSystemService(Context.VIBRATOR_SERVICE)获取到的SystemVibrator对象,通过android.os.Vibrator的方法vibrate(),hasVibrator()和cancel()通过SystemVibrator的对象实例mService实现对VibratorService的控制,从而实现对硬件震动器的控制。
VibratorService驱动硬件
以APP请求震动服务为例,看看这个过程,首先是APP调用Vibrator.vibrate(),然后IPC通信到VibratorService到:public class VibratorService extends IVibratorService.Stub implements InputManager.InputDeviceListener { @Override // Binder call public void vibrate(int uid, String opPkg, long milliseconds, int usageHint, IBinder token) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires VIBRATE permission"); } Vibration vib = new Vibration(token, milliseconds, usageHint, uid, opPkg); try { synchronized (mVibrations) { ...... startVibrationLocked(vib); } } finally { Binder.restoreCallingIdentity(ident); } } }
看上述代码,首先是通过checkCallingOrSelfPermission()检测调用者APP是否已经有android.Manifest.permission.VIBRATE这个权限,所以APP要使用震动服务,需要在AndroidManifest.xml中声明权限android.Manifest.permission.VIBRATE的值android.permission.VIBRATE权限,权限保护等级为normal,即安装时授权。
随后,把token, milliseconds, usageHint, uid, opPkg封装到Vibration对象中,那么就把震动更好地抽象成一次震动对象,通过startVibrationLocked继续传输:
private void startVibrationLocked(final Vibration vib) { ...... if (vib.mTimeout != 0) { doVibratorOn(vib.mTimeout, vib.mUid, vib.mUsageHint); mH.postDelayed(mVibrationRunnable, vib.mTimeout); } else { // mThread better be null here. doCancelVibrate should always be // called before startNextVibrationLocked or startVibrationLocked. mThread = new VibrateThread(vib); mThread.start(); } }
这里有一个分支,判断依据是vib.mTimeout,vib.mTimeout什么时候等于0,什么时候不等于0呢?回顾Vibration的初始化过程:
public class VibratorService extends IVibratorService.Stub implements InputManager.InputDeviceListener { @Override // Binder call public void vibrate(int uid, String opPkg, long milliseconds, int usageHint, IBinder token) { ...... Vibration vib = new Vibration(token, milliseconds, usageHint, uid, opPkg); ...... } } private class Vibration implements IBinder.DeathRecipient { private final IBinder mToken; private final long mTimeout; ...... Vibration(IBinder token, long millis, int usageHint, int uid, String opPkg) { this(token, millis, null, 0, usageHint, uid, opPkg); } private Vibration(IBinder token, long millis, long[] pattern, int repeat, int usageHint, int uid, String opPkg) { mToken = token; mTimeout = millis; ...... }
在vibrate()这个方法中可以看到,实例化Vibration对象时,传入了milliseconds,在Vibration的构造方法中,把milliseconds赋值给mTimeout,也就是说mTimeout保存的是震动持续的时间。前文提到,启动震动有两个接口,如下:
public class SystemVibrator extends Vibrator { ...... public void vibrate(..... long milliseconds .....) {} public void vibrate(..... long[] pattern, int repeat .....) { }
一个是带milliseconds的作为参数的,另外一个是不带milliseconds参数的,前文有说明,前者是一次性震动,后者是重复多次震动,那么,也就是在下面的代码中:
private void startVibrationLocked(final Vibration vib) { ...... if (vib.mTimeout != 0) { doVibratorOn(vib.mTimeout, vib.mUid, vib.mUsageHint); mH.postDelayed(mVibrationRunnable, vib.mTimeout); } else { // mThread better be null here. doCancelVibrate should always be // called before startNextVibrationLocked or startVibrationLocked. mThread = new VibrateThread(vib); mThread.start(); } }
一次性震动走的是vib.mTimeout != 0的情况,重复震动的走的是!(vib.mTimeout != 0)的情况,那么这里的代码就很符合这个实际情况了,vib.mTimeout != 0时,直接调用doVibratorOn()启动震动,而重复震动时,通过VibrateThread线程实现重复震动的功能,这里就不在赘述这个重复的实现过程了。
接着追踪doVibratorOn()方法:
private void doVibratorOn(long millis, int uid, int usageHint) { synchronized (mInputDeviceVibrators) { ...... if (vibratorCount != 0) { ...... for (int i = 0; i < vibratorCount; i++) { mInputDeviceVibrators.get(i).vibrate(millis, attributes); } } else { vibratorOn(millis); } } }
这里会考虑多个振动器的情况,本文默认只有一个,则直接调用vibratorOn(millis)这个方法:
public class VibratorService extends IVibratorService.Stub implements InputManager.InputDeviceListener { native static void vibratorOn(long milliseconds); }
如上述代码,vibratorOn()是一个native方法,也就通过JNI,调用到Native framework了,传递的参数只有一个,就是mills,震动持续的时间。VibratorService的JNI实现是frameworks/base/services/core/jni/com_android_server_VibratorService.cpp中,继续看vibratorOn()这个方法:
static void vibratorOn(JNIEnv* /* env */, jobject /* clazz */, jlong timeout_ms) { if (gVibraDevice) { int err = gVibraDevice->vibrator_on(gVibraDevice, timeout_ms); ...... } else { ALOGW("Tried to vibrate but there is no vibrator device."); } }
这里有个对象gVibraDevice,gVibraDevice实际代表的就是振动器,有振动器,才会实例化gVibraDevice。gVibraDevice调用了vibrator_on函数。先看gVibraDevice的定义,在hardware/libhardware/include/hardware/vibrator.h中:
typedef struct vibrator_device { struct hw_device_t common; /** Turn on vibrator */ int (*vibrator_on)(struct vibrator_device* vibradev, unsigned int timeout_ms); /** Turn off vibrator */ int (*vibrator_off)(struct vibrator_device* vibradev); } vibrator_device_t;
vibrator.h中定义了vibrator_device_t,以及它的函数vibrator_on和vibrator_off,再继续看调用gVibraDevice->vibrator_on(gVibraDevice, timeout_ms)如何发起震动。vibrator_on的具体实现是在hardware/libhardware/modules/vibrator/vibrator.c 中,先看如下代码:
static int vibra_open(const hw_module_t* module, const char* id __unused, hw_device_t** device __unused) { ...... vibrator_device_t *vibradev = calloc(1, sizeof(vibrator_device_t)); ...... vibradev->vibrator_on = vibra_on; vibradev->vibrator_off = vibra_off; *device = (hw_device_t *) vibradev; return 0; }
上述C语言代码中,vibra_open函数中在初始化震动器是就被调用了,vibra_open在vibrator_on的前面,在本文就不再赘述这个过程。通过上述代码可知,gVibraDevice->vibrator_on(gVibraDevice, timeout_ms)实际是调用了函数vibra_on,继续看vibra_on的实现:
static int vibra_on(vibrator_device_t* vibradev __unused, unsigned int timeout_ms) { /* constant on, up to maximum allowed time */ return sendit(timeout_ms); }
直接调用了函数sendit(timeout_ms),往下看:
static int sendit(unsigned int timeout_ms) { int to_write, written, ret, fd; char value[20]; /* large enough for millions of years */ fd = TEMP_FAILURE_RETRY(open(THE_DEVICE, O_RDWR)); to_write = snprintf(value, sizeof(value), "%u\n", timeout_ms); written = TEMP_FAILURE_RETRY(write(fd, value, to_write)); ...... return ret; }
在这里,打开设备,写入数据。到此,本文就不再往下继续分析这个过程了,有兴趣的读者可以自行分析研究。
总结
本文赘述了VibratorService的创建过程,上层APP如何使用VibratorService提供的震动服务,以及APP发起震动时,从APP到HAL层的整过流程详细记录下来。
相关文章推荐
- Android System Server大纲之TelecomLoaderService
- Android System Server大纲之ContentService和ContentProvider原理剖析
- Android System Server大纲之ClipboardService
- Android System Server大纲之StatusBarManagerService
- Android 5.1 SystemServer SystemService 各个系统Manager
- Android 5.1 SystemServer SystemService 各个系统Manager
- Android系统之System Server大纲
- Android systemserver分析ThrottleService 介绍
- Android系统之System Server大纲
- (OK) Android 5 SystemServer 各个系统Manager-startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY)
- Android系统中SystemServer进程中初始化的系统service
- Android systemserver分析ThrottleService 介绍
- Android的 getSystemService
- android 源码分析--system-server
- Android增加一个System Service
- Android Audio System 之三: AudioPolicyService 和 AudioPolicyManager
- android system server 启动流程
- system server crash//Android 信号
- Android SystemServer学习
- android的HAL第二种调用hal方法中的SystemServer (属于APP层)代码的实现: