linux 电源管理 唤醒,Android 4.0 中的PowerManager(电源管理--休眠唤醒) [转]

转发请注明出处:

最近,在学习让系统进入休眠的过程中,学习了电源管理的相关知识。为了备忘和理清思路现整理成文,以便日后查阅。

移动设备由于自身的限制有一个硬伤就是电量的消耗问题。由于电池的电量有限,所以电源电量的管理显得就比较重要了。我们可以想象一下,当你去超市买完东西之后,却发现无法运回家,是多么难受的一件事情。

Android的电源管理是在Linux电源管理的基础之上更好的一个电源管理方案,在这种策略下,通过Android

framework层和本地的linux库,服务和应用都通过“wake

lock”来取得CPU,从而达到省电的目的。如果没有活跃的唤醒锁,Android将关闭CPU。

在Android 4.0中,为上层提供的休眠函数为goToSleep()。下面详细讲解为什么这个命令会让系统进去休眠模式。

首先,需要明白在Android系统中一般会有这样的一个文件群,XXX.java、XXXservice.java、*XXX*.cpp、*XXX*.c。作为使用者我们首先需要了解的就是这个系统能够为我们提供的服务,如果这些服务会让我们满意,我们才会愿意为这个服务埋单。因此,在这里我们就先从服务入手,也就是从PowerManagerService.java开始入手。在这个文件的line2561出有goToSleep()函数的定义:

public void goToSleep(long time)

{

goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);

}

goToSleep()函数接着调用了下面的goToSleepWithReason()函数。函数的定义如下:

public void goToSleepWithReason(long time, int reason)

{

mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);

synchronized (mLocks) {

goToSleepLocked(time, reason);

}

}

goToSleepLocked()函数的定义如下:

private void goToSleepLocked(long time, int reason) {

if (mLastEventTime <= time) {

mLastEventTime = time;

// cancel all of the wake locks

mWakeLockState = SCREEN_OFF;

int N = mLocks.size();

int numCleared = 0;

boolean proxLock = false;

for (int i=0; iWakeLock wl = mLocks.get(i);

if (isScreenLock(wl.flags)) {

if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)

&& reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {

proxLock = true;

} else {

mLocks.get(i).activated = false;

numCleared++;

}

}

}

if (!proxLock) {

mProxIgnoredBecauseScreenTurnedOff = true;

if (mDebugProximitySensor) {

Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");

}

}

EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);

mStillNeedSleepNotification = true;

mUserState = SCREEN_OFF;

setPowerState(SCREEN_OFF, false, reason);

cancelTimerLocked();

}

}

其中,对我们来讲最有意义的函数为setPowerState()函数。此函数中调用了 setScreenStateLocked()函数

转发请注明出处:

private int setScreenStateLocked(boolean on) {

if (DEBUG_SCREEN_ON) {

RuntimeException e = new RuntimeException("here");

e.fillInStackTrace();

Slog.i(TAG, "Set screen state: " + on, e);

}

if (on) {

if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {

// If we are turning the screen state on, but the screen

// light is currently off, then make sure that we set the

转发请注明出处:

// light at this point to 0.  This is the case where we are

// turning on the screen and waiting for the UI to be drawn

// before showing it to the user.  We want the light off

// until it is ready to be shown to the user, not it using

// whatever the last value it had.

if (DEBUG_SCREEN_ON) {

Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"

+ Integer.toHexString(mPowerState)

+ " mSkippedScreenOn=" + mSkippedScreenOn);

}

mScreenBrightness.forceValueLocked(Power.BRIGHTNESS_OFF);

}

}

int err = Power.setScreenState(on);

if (err == 0) {

mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);

if (mUseSoftwareAutoBrightness) {

enableLightSensorLocked(on);

转发请注明出处:

转发请注明出处:

此函数调用了Power类中的setScreenState()函数。此函数通过JNI机制,最终到达硬件层的

libhardware_legacy/power/Power.c文件通过对寄存器的操作完成对休眠的操作。在此函数中我们通过传入的参数是on,来进

行相应的处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值