`
womendu
  • 浏览: 1537968 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Android在标准linux基础上对休眠唤醒的实现(三)

阅读更多

四、android层源码解析

linux之上经过android的软件堆层层封装,最终在上层的java应用程序中使用。休眠唤醒也是从最上层发出的命令,然后一层一层地将参数解析,往最底层传,最后走上标准linux的休眠唤醒之路。

这一部分将会初略分析休眠唤醒机制上linux之上所走的路线。

linux之上,存在一个hal层,专门做和linux内核设备打交道的事情,这里也不例外。休眠唤醒机制的hal层源码位于:@hardware/libhardware_legacy/power/power.c

该文件源码比较简单,下面列举重点片段:

enum {

ACQUIRE_PARTIAL_WAKE_LOCK = 0,

RELEASE_WAKE_LOCK,

REQUEST_STATE,

OUR_FD_COUNT

};

const char * const NEW_PATHS[] = {

"/sys/power/wake_lock",

"/sys/power/wake_unlock",

"/sys/power/state"

};

static int g_initialized = 0;

static int g_fds[OUR_FD_COUNT];

static const char *off_state = "mem";

static const char *on_state = "on";

static int open_file_descriptors(const char * const paths[])

{

int i;

for (i=0; i<OUR_FD_COUNT; i++) {

int fd = open(paths[i], O_RDWR);

if (fd < 0) {

fprintf(stderr, "fatal error opening \"%s\"\n", paths[i]);

g_error = errno;

return -1;

}

g_fds[i] = fd;

}

g_error = 0;

return 0;

}

static inline void initialize_fds(void)

{

if (g_initialized == 0) {

if(open_file_descriptors(NEW_PATHS) < 0) {

open_file_descriptors(OLD_PATHS);

on_state = "wake";

off_state = "standby";

}

g_initialized = 1;

}

}

int acquire_wake_lock(int lock, const char* id)

{

initialize_fds();

if (g_error) return g_error;

int fd;

if (lock == PARTIAL_WAKE_LOCK) { // 上层传下来的lock type

fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];

}

else {

return EINVAL;

}

return write(fd, id, strlen(id));

}

int release_wake_lock(const char* id)

{

initialize_fds();

// LOGI("release_wake_lock id='%s'\n", id);

if (g_error) return g_error;

ssize_t len = write(g_fds[RELEASE_WAKE_LOCK], id, strlen(id));

return len >= 0;

}

int set_screen_state(int on)

{

QEMU_FALLBACK(set_screen_state(on));

LOGI("*** set_screen_state %d", on);

initialize_fds();

if (g_error) return g_error;

char buf[32];

int len;

if(on)

len = sprintf(buf, on_state);

else

len = sprintf(buf, off_state);

len = write(g_fds[REQUEST_STATE], buf, len);

if(len < 0) {

LOGE("Failed setting last user activity: g_error=%d\n", g_error);

}

return 0;

}

Hal层的代码在jni层中被使用,源码位于:frameworks/base/core/jni/android_os_Power.cpp,代码片段如下:

static void acquireWakeLock(JNIEnv *env, jobject clazz, jint lock, jstring idObj)

{

if (idObj == NULL) {

throw_NullPointerException(env, "id is null");

return ;

}

const char *id = env->GetStringUTFChars(idObj, NULL);

acquire_wake_lock(lock, id);

env->ReleaseStringUTFChars(idObj, id);

}// wakelock加锁函数

static void releaseWakeLock(JNIEnv *env, jobject clazz, jstring idObj)

{

if (idObj == NULL) {

throw_NullPointerException(env, "id is null");

return ;

}

const char *id = env->GetStringUTFChars(idObj, NULL);

release_wake_lock(id);

env->ReleaseStringUTFChars(idObj, id);

}// wakelock解锁函数

static int setScreenState(JNIEnv *env, jobject clazz, jboolean on)

{

return set_screen_state(on);

}// 休眠唤醒的函数

Jni的方法需要注册到上层才可以使用,同时也需要在上层的对应java类中声明了native才可以使用。那么这里的方法在java中对应的声明在哪里呢?frameworks/base/core/java/android/os/Power.java,该文件定义一个java类,如下:

public class Power

{

// can't instantiate this class

private Power()

{

}

/**

* Wake lock that ensures that the CPU is running. The screen might

* not be on.

*/

public static final int PARTIAL_WAKE_LOCK = 1;

/**

* Wake lock that ensures that the screen is on.

*/

public static final int FULL_WAKE_LOCK = 2;

public static native void acquireWakeLock(int lock, String id);

public static native void releaseWakeLock(String id);

/**

* Turn the screen on or off

*

* @param on Whether you want the screen on or off

*/

public static native int setScreenState(boolean on);

}

声明的jni接口应该是被java server在使用,这里就是专门的电源管理服务:PowerManagerService使用,具体源码位置在:frameworks/base/services/java/com/android/server/PowerManagerService.javaandroid在最上层还提供了现场的android.os.PowerManager

(frameworks/base/core/java/android/os/PowerManager.java)来供app使用,PowerManager类会调用java服务PowerManagerService的方法来完成与wakelock相关的工作。

@ frameworks/base/core/java/android/os/PowerManager.java

PowerManager中内嵌了一个WakeLock类,另外还定义了wakelock的类型,下面是代码片段:

public class PowerManager

{

private static final String TAG = "PowerManager";

/**

* Wake lock that ensures that the CPU is running. The screen might

* not be on.

*/

public static final int PARTIAL_WAKE_LOCK = WAKE_BIT_CPU_STRONG;

/**

* Wake lock that ensures that the screen and keyboard are on at

* full brightness.

*/

public static final int FULL_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_BRIGHT | WAKE_BIT_KEYBOARD_BRIGHT;

/**

* Wake lock that ensures that the screen is on at full brightness;

* the keyboard backlight will be allowed to go off.

*/

public static final int SCREEN_BRIGHT_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_BRIGHT;

/**

* Wake lock that ensures that the screen is on (but may be dimmed);

* the keyboard backlight will be allowed to go off.

*/

public static final int SCREEN_DIM_WAKE_LOCK = WAKE_BIT_CPU_WEAK | WAKE_BIT_SCREEN_DIM;

/**

* Wake lock that turns the screen off when the proximity sensor activates.

* Since not all devices have proximity sensors, use

* {@link #getSupportedWakeLockFlags() getSupportedWakeLockFlags()} to determine if

* this wake lock mode is supported.

*

* {@hide}

*/

public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK

= WAKE_BIT_PROXIMITY_SCREEN_OFF;

public class WakeLock

{

WakeLock(int flags, String tag)

{

switch (flags & LOCK_MASK) {

case PARTIAL_WAKE_LOCK:

case SCREEN_DIM_WAKE_LOCK:

case SCREEN_BRIGHT_WAKE_LOCK:

case FULL_WAKE_LOCK:

case PROXIMITY_SCREEN_OFF_WAKE_LOCK:

break;

default:

throw new IllegalArgumentException();

}

mFlags = flags;

mTag = tag;

mToken = new Binder();

}

public void acquire()

{

synchronized (mToken) {

if (!mRefCounted || mCount++ == 0) {

try {

mService.acquireWakeLock(mFlags, mToken, mTag);

} catch (RemoteException e) {

}

mHeld = true;

}

}

}

public void release(int flags)

{

synchronized (mToken) {

if (!mRefCounted || --mCount == 0) {

try {

mService.releaseWakeLock(mToken, flags);

} catch (RemoteException e) {

}

mHeld = false;

}

if (mCount < 0) {

throw new RuntimeException("WakeLock under-locked " + mTag);

}

}

}

}

public WakeLock newWakeLock(int flags, String tag)

{

if (tag == null) {

throw new NullPointerException("tag is

null in PowerManager.newWakeLock");

}

return new WakeLock(flags, tag);

}

public void goToSleep(long time)

{

try {

mService.goToSleep(time);

} catch (RemoteException e) {

}

}

public PowerManager(IPowerManager service, Handler handler)

{

mService = service;

font-family: Times New

分享到:
评论

相关推荐

    Linux Kernel and Android 休眠与唤醒

    Linux Kernel and Android 休眠与唤醒 Linux Kernel 中的休眠和唤醒机制是非常重要的,嵌入式设备尽可能的进入休眠状态来延长电池的续航时间。本文将详细介绍 Linux 中休眠/唤醒是如何工作的,以及 Android 中如何...

    Linux Kernel and Android 休眠与唤醒(中文版)

    【Android与标准Linux休眠的区别】 相比标准Linux,Android休眠过程更注重与用户界面和应用程序的交互。例如,Android的休眠可能需要考虑后台运行的应用程序、网络连接状态以及用户设置的电源管理选项。此外,...

    android_和linux的休眠唤醒机制

    Android是基于Linux内核的操作系统,它在Linux的基础上增加了多层软件堆栈,包括硬件抽象层(HAL)、Java运行时环境、框架层和应用层等,从而构建了一个完整的移动设备操作系统。 #### 休眠唤醒机制的重要性 休眠...

    linux_休眠唤醒

    Android基于Linux内核,但在休眠唤醒机制上做了一些定制化调整。主要区别在于: - Android引入了早期休眠(EarlySuspend)、晚期唤醒(LateResume)和WakeLock机制,以更好地适应移动设备的需求。 - EarlySuspend和...

    android休眠与唤醒机制.zip

    总结,这个资料包深入解析了Android系统的电源管理策略,特别是Wakelock在保持设备活跃和唤醒过程中的作用,以及如何实现远程唤醒和休眠功能。对于Android应用开发者和系统优化人员来说,理解和掌握这些知识至关重要...

    android和linux的休眠唤醒机制借鉴.pdf

    以下是对Android和Linux休眠唤醒机制的详细解析。 首先,Android系统的休眠唤醒机制是基于Linux内核实现的,但为了适应Android应用环境,它在内核之上增加了一些自定义的抽象层。这些层使得开发者能够在Java应用...

    android和linux的休眠唤醒机制.pdf

    总之,Android和Linux的休眠唤醒机制是一个涉及多层交互的过程,从Java应用程序的API调用,通过JNI层传递到HAL层,最终由Linux内核执行实际的电源管理操作。这一机制确保了设备在不影响用户体验的前提下,能够有效地...

    android休眠与唤醒

    在Android系统中,与休眠唤醒相关的几个关键文件包括: - `kernel/power/main.c`:负责整体电源管理流程。 - `kernel/power/earlysuspend.c`:实现early suspend功能。 - `kernel/power/wakelock.c`:实现wakelock...

    android和linux的唤醒机制

    Android作为基于Linux内核的操作系统,在休眠唤醒机制方面有着独特的实现方式。本篇文章将详细分析Android中的休眠唤醒机制,特别是从Java层到JNI层再到HAL层的具体实现细节。 #### 二、Android休眠唤醒机制层次...

    android休眠与唤醒驱动流程分析.doc

    Android 休眠与唤醒驱动流程分析 Android 休眠与唤醒驱动流程分析是 Android 系统中的一部分,主要负责控制系统的休眠和唤醒过程。该过程是基于 Linux 内核的电源管理设计,但Android 对其进行了修改和优化,以适应...

    Android系统的休眠

    #### Android与标准Linux休眠的区别 虽然Android和标准Linux都使用相同的底层电源管理框架,但Android为了适应移动设备的需求,对电源管理进行了多方面的定制: 1. **更严格的功耗管理**:移动设备需要更长的电池...

    android系统的休眠过程

    #### 六、Android与标准Linux休眠的区别 虽然Android基于Linux内核,但在休眠/唤醒机制上存在一些差异: - **定制化**:Android针对移动设备的特点对Linux的休眠/唤醒机制进行了定制,例如引入了EarlySuspend和...

    Android系统的休眠.pdf

    #### 五、Android与标准Linux休眠的区别 Android在其电源管理系统中添加了额外的层来支持移动设备特有的需求,其中包括: - **更灵活的唤醒机制**:除了标准的唤醒锁(Wake Lock),Android还支持多种类型的唤醒锁,...

    android休眠与唤醒驱动流程分析.pdf

    在Android源代码中,与休眠和唤醒相关的文件主要包括: - `kernel/power/main.c`:电源管理的主要控制逻辑。 - `kernel/power/earlysuspend.c`:实现early_suspend和late_resume机制。 - `kernel/power/wakelock.c`...

    Android-suspend-and-resume.rar_android_android 唤醒_linux suspend

    休眠/唤醒在嵌入式Linux中是非常重要的部分,嵌入式设备尽可能的进入休眠状 态来延长电池的续航时间.这篇文章就详细介绍一下Linux中休眠/唤醒是如何工作 的, 还有Android中如何把这部分和Linux的机制联系起来的.

    Android学习:点击应用休眠

    在Android系统中,"点击应用休眠"是一个实用的功能,它允许用户通过简单的操作让应用程序进入休眠状态,从而节省设备电量和优化性能。休眠不仅仅是关闭应用的界面,更是一种将应用完全暂停运行的方式,使得系统资源...

    LinuxKernelandAndroid休眠与唤醒[参考].pdf

    本文将详细介绍Linux内核以及Android系统中的休眠与唤醒过程,重点解析Early Suspend、Late Resume和Wake Lock这三大特性。 休眠(Suspend)是Linux系统中一种节能模式,它将当前系统的状态保存到内存或硬盘中,...

Global site tag (gtag.js) - Google Analytics