5.3.3 Power类及LightService类介绍
根据前面的分析,PMS有时需要进行点亮屏幕、打开键盘灯等操作,为此Android提供了Power类及LightService满足PMS的要求。这两个类比较简单,但是其背后的Kernel层相对复杂一些。本章仅分析用户空间的内容,有兴趣的读者不妨以此为入口,深入研究Kernel层的实现。
1.Power类介绍
Power类提供了6个函数,如下所示:
[—>Power.java]
int setScreenState(boolean on);//打开或关闭屏幕灯
int setLastUserActivityTimeout(long ms);//设置超时时间
void reboot(String reason);//用于手机重启,内部调用rebootNative
void shutdown();//已作废,建议不要调用
void acquireWakeLock(int lock, String id);//获取Kernel层的WakeLock
void releaseWakeLock(String id);//释放Kernel层的WakeLock
这些函数固有的实现代码如下:
[—>android_os_Power.cpp:acqurieWakeLock]
static void acquireWakeLock(JNIEnv*env, jobject clazz, jint lock, jstring idObj)
{
……
const char*id=env->GetStringUTFChars(idObj, NULL);
acquire_wake_lock(lock, id);//调用此函数和Kernel层交互
env->ReleaseStringUTFChars(idObj, id);
}
static void releaseWakeLock(JNIEnv*env, jobject clazz, jstring idObj)
{
const char*id=env->GetStringUTFChars(idObj, NULL);
release_wake_lock(id);//释放Kernel层的WakeLock
env->ReleaseStringUTFChars(idObj, id);
}
static int setLastUserActivityTimeout(JNIEnv*env, jobject clazz, jlong timeMS)
{
return set_last_user_activity_timeout(timeMS/1000);//设置超时时间
}
static int setScreenState(JNIEnv*env, jobject clazz, jboolean on)
{
return set_screen_state(on);//开启或关闭屏幕灯
}
static void android_os_Power_shutdown(JNIEnv*env, jobject clazz)
{
android_reboot(ANDROID_RB_POWEROFF,0,0);//关机
}
static void android_os_Power_reboot(JNIEnv*env, jobject clazz, jstring reason)
{
if(reason==NULL){
android_reboot(ANDROID_RB_RESTART,0,0);//重启
}else{
const char*chars=env->GetStringUTFChars(reason, NULL);
android_reboot(ANDROID_RB_RESTART2,0,(char*)chars);//重启
env->ReleaseStringUTFChars(reason, chars);
}
jniThrowIOException(env, errno);
}
Power类提供了和内核交互的通道,读者仅作了解即可。
2.LightService介绍
LightService. java比较简单,这里直接介绍Native层的实现,主要关注HAL层的初始化函数init_native及操作函数setLight_native。
首先来看初始化函数init_native,其代码如下:
[com_android_server_LightService.cpp:init_native]
static jint init_native(JNIEnv*env, jobject clazz)
{
int err;
hw_module_t*module;
Devices*devices;
devices=(Devices*)malloc(sizeof(Devices));
//初始化硬件相关的模块,模块名为lights
err=hw_get_module(LIGHTS_HARDWARE_MODULE_ID,
(hw_module_t const**)&module);
if(err==0){
devices->lights[LIGHT_INDEX_BACKLIGHT]//背光
=get_device(module, LIGHT_ID_BACKLIGHT);
devices->lights[LIGHT_INDEX_KEYBOARD]//键盘灯
=get_device(module, LIGHT_ID_KEYBOARD);
devices->lights[LIGHT_INDEX_BUTTONS]//按键灯
=get_device(module, LIGHT_ID_BUTTONS);
devices->lights[LIGHT_INDEX_BATTERY]//电源指示灯
=get_device(module, LIGHT_ID_BATTERY);
devices->lights[LIGHT_INDEX_NOTIFICATIONS]//通知灯
=get_device(module, LIGHT_ID_NOTIFICATIONS);
devices->lights[LIGHT_INDEX_ATTENTION]//警示灯
=get_device(module, LIGHT_ID_ATTENTION);
devices->lights[LIGHT_INDEX_BLUETOOTH]//蓝牙提示灯
=get_device(module, LIGHT_ID_BLUETOOTH);
devices->lights[LIGHT_INDEX_WIFI]//WIFI提示灯
=get_device(module, LIGHT_ID_WIFI);
}else{
memset(devices,0,sizeof(Devices));
}
return(jint)devices;
}
Android系统想得很周到,提供了多达8种不同类型的灯。可是有多少手机包含了所有的灯呢?
PMS点亮或关闭灯时,将调用setLight_native函数,其代码如下:
[com_android_server_LightService.cpp:setLight_native]
static void setLight_native(JNIEnv*env, jobject clazz, int ptr,
int light, int colorARGB, int flashMode, int onMS, int offMS,
int brightnessMode)
{
Devicesdevices=(Devices)ptr;
light_state_t state;
……
memset(&state,0,sizeof(light_state_t));
state.color=colorARGB;//设置颜色
state.flashMode=flashMode;//设置闪光模式
state.flashOnMS=onMS;//和闪光模式有关,例如亮2秒,灭2秒
state.flashOffMS=offMS;
state.brightnessMode=brightnessMode;//
//传递给HAL层模块进行处理
devices->lights[light]->set_light(devices->lights[light],&state);
}