🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
根据前面的分析,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** ~~~ static void acquireWakeLock(JNIEnv *env, jobjectclazz, jint lock, jstring idObj) { ...... constchar *id = env->GetStringUTFChars(idObj, NULL); acquire_wake_lock(lock, id);//调用此函数和Kernel层交互 env->ReleaseStringUTFChars(idObj, id); } static void releaseWakeLock(JNIEnv *env, jobjectclazz, jstring idObj) { constchar *id = env->GetStringUTFChars(idObj, NULL); release_wake_lock(id);//释放Kernel层的WakeLock env->ReleaseStringUTFChars(idObj,id); } static int setLastUserActivityTimeout(JNIEnv *env,jobject clazz, jlong timeMS) { returnset_last_user_activity_timeout(timeMS/1000);//设置超时时间 } static int setScreenState(JNIEnv *env, jobjectclazz, 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, jobjectclazz) { int err; hw_module_t* module; Devices*devices; devices= (Devices*)malloc(sizeof(Devices)); //初始化硬件相关的模块,模块名为“lights” err =hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_tconst**)&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, jobjectclazz, int ptr, intlight, int colorARGB, int flashMode, int onMS, int offMS, intbrightnessMode) { Devices*devices = (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); } ~~~