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);

}