android6.0休眠流程,按电源键休眠流程(framework层)

这里以Android6.0为例frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.javaPowerManager mPowerManager;

private void powerPress(long eventTime, boolean interactive, int count) {

if (mScreenOnEarly && !mScreenOnFully) {

Slog.i(TAG, "Suppressed redundant power key press while "

+ "already in the process of turning the screen on.");

return;

}

Slog.i(TAG,"eventTime="+eventTime+" interactive="+interactive+" count="+count+" mShortPressOnPowerBehavior="+mShortPressOnPowerBehavior

+" mBeganFromNonInteractive="+mBeganFromNonInteractive);

if (count == 2) {

powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);

} else if (count == 3) {

powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);

} else if (interactive && !mBeganFromNonInteractive) {

switch (mShortPressOnPowerBehavior) {

case SHORT_PRESS_POWER_NOTHING:

break;

case SHORT_PRESS_POWER_GO_TO_SLEEP:

mPowerManager.goToSleep(eventTime,

PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);

break;

case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:

mPowerManager.goToSleep(eventTime,

PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,

PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);

break;

case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:

mPowerManager.goToSleep(eventTime,

PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,

PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);

launchHomeFromHotKey();

break;

case SHORT_PRESS_POWER_GO_HOME:

launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);

break;

}

}

}

//按电源键跑的是SHORT_PRESS_POWER_GO_TO_SLEEPframeworks/base/core/java/android/os/PowerManager.java

final IPowerManager mService;

public void goToSleep(long time, int reason, int flags) {

try {

mService.goToSleep(time, reason, flags);

} catch (RemoteException e) {

}

}

frameworks/base/core/java/android/os/IPowerManager.aidlframeworks/base/services/core/java/com/android/server/power/PowerManagerService.java

public void goToSleep(long eventTime, int reason, int flags) {

if (eventTime > SystemClock.uptimeMillis()) {

throw new IllegalArgumentException("event time must not be in the future");

}

mContext.enforceCallingOrSelfPermission(

android.Manifest.permission.DEVICE_POWER, null);

final int uid = Binder.getCallingUid();

final long ident = Binder.clearCallingIdentity();

try {

goToSleepInternal(eventTime, reason, flags, uid);

} finally {

Binder.restoreCallingIdentity(ident);

}

}

private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {

synchronized (mLock) {

if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {

updatePowerStateLocked();

}

}

}

private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {

if (DEBUG_SPEW) {

Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime

+ ", reason=" + reason + ", flags=" + flags + ", uid=" + uid);

}

if (eventTime < mLastWakeTime

|| mWakefulness == WAKEFULNESS_ASLEEP

|| mWakefulness == WAKEFULNESS_DOZING

|| !mBootCompleted || !mSystemReady) {

return false;

}

Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep");

try {

switch (reason) {

case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:

Slog.i(TAG, "Going to sleep due to device administration policy "

+ "(uid " + uid +")...");

break;

case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:

Slog.i(TAG, "Going to sleep due to screen timeout (uid " + uid +")...");

break;

case PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH:

Slog.i(TAG, "Going to sleep due to lid switch (uid " + uid +")...");

break;

case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:

Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")...");

break;

case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON:

Slog.i(TAG, "Going to sleep due to sleep button (uid " + uid +")...");

break;

case PowerManager.GO_TO_SLEEP_REASON_HDMI:

Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")...");

break;

default:

Slog.i(TAG, "Going to sleep by application request (uid " + uid +")...");

reason = PowerManager.GO_TO_SLEEP_REASON_APPLICATION;

break;

}

mLastSleepTime = eventTime;

mSandmanSummoned = true;

setWakefulnessLocked(WAKEFULNESS_DOZING, reason);

// Report the number of wake locks that will be cleared by going to sleep.

int numWakeLocksCleared = 0;

final int numWakeLocks = mWakeLocks.size();

for (int i = 0; i < numWakeLocks; i++) {

final WakeLock wakeLock = mWakeLocks.get(i);

switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {

case PowerManager.FULL_WAKE_LOCK:

case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:

case PowerManager.SCREEN_DIM_WAKE_LOCK:

numWakeLocksCleared += 1;

break;

}

}

EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);

// Skip dozing if requested.

if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {

reallyGoToSleepNoUpdateLocked(eventTime, uid);

}

} finally {

Trace.traceEnd(Trace.TRACE_TAG_POWER);

}

return true;

}

private void updatePowerStateLocked() {

if (!mSystemReady || mDirty == 0) {

return;

}

if (!Thread.holdsLock(mLock)) {

Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");

}

Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");

try {

// Phase 0: Basic state updates.

updateIsPoweredLocked(mDirty);

updateStayOnLocked(mDirty);

updateScreenBrightnessBoostLocked(mDirty);

// Phase 1: Update wakefulness.

// Loop because the wake lock and user activity computations are influenced

// by changes in wakefulness.

final long now = SystemClock.uptimeMillis();

int dirtyPhase2 = 0;

for (;;) {

int dirtyPhase1 = mDirty;

dirtyPhase2 |= dirtyPhase1;

mDirty = 0;

updateWakeLockSummaryLocked(dirtyPhase1);

updateUserActivitySummaryLocked(now, dirtyPhase1);

if (!updateWakefulnessLocked(dirtyPhase1)) {

break;

}

}

// Phase 2: Update display power state.

boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);

// Phase 3: Update dream state (depends on display ready signal).

updateDreamLocked(dirtyPhase2, displayBecameReady);

// Phase 4: Send notifications, if needed.

finishWakefulnessChangeIfNeededLocked();

// Phase 5: Update suspend blocker.

// Because we might release the last suspend blocker here, we need to make sure

// we finished everything else first!

updateSuspendBlockerLocked();

} finally {

Trace.traceEnd(Trace.TRACE_TAG_POWER);

}

}

private void updateSuspendBlockerLocked() {

final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);

final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();

final boolean autoSuspend = !needDisplaySuspendBlocker;

final boolean interactive = mDisplayPowerRequest.isBrightOrDim();

// Disable auto-suspend if needed.

// FIXME We should consider just leaving auto-suspend enabled forever since

// we already hold the necessary wakelocks.

if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {

setHalAutoSuspendModeLocked(false);

}

// First acquire suspend blockers if needed.

if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {

mWakeLockSuspendBlocker.acquire();

mHoldingWakeLockSuspendBlocker = true;

}

if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {

mDisplaySuspendBlocker.acquire();

mHoldingDisplaySuspendBlocker = true;

}

// Inform the power HAL about interactive mode.

// Although we could set interactive strictly based on the wakefulness

// as reported by isInteractive(), it is actually more desirable to track

// the display policy state instead so that the interactive state observed

// by the HAL more accurately tracks transitions between AWAKE and DOZING.

// Refer to getDesiredScreenPolicyLocked() for details.

if (mDecoupleHalInteractiveModeFromDisplayConfig) {

// When becoming non-interactive, we want to defer sending this signal

// until the display is actually ready so that all transitions have

// completed. This is probably a good sign that things have gotten

// too tangled over here...

if (interactive || mDisplayReady) {

setHalInteractiveModeLocked(interactive);

}

}

// Then release suspend blockers if needed.

if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {

mWakeLockSuspendBlocker.release();

mHoldingWakeLockSuspendBlocker = false;

}

if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {

mDisplaySuspendBlocker.release();

mHoldingDisplaySuspendBlocker = false;

}

// Enable auto-suspend if needed.

if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {

setHalAutoSuspendModeLocked(true);

}

}

private void setHalAutoSuspendModeLocked(boolean enable) {

if (enable != mHalAutoSuspendModeEnabled) {

if (DEBUG) {

Slog.d(TAG, "Setting HAL auto-suspend mode to " + enable);

}

mHalAutoSuspendModeEnabled = enable;

Trace.traceBegin(Trace.TRACE_TAG_POWER, "setHalAutoSuspend(" + enable + ")");

try {

nativeSetAutoSuspend(enable);

} finally {

Trace.traceEnd(Trace.TRACE_TAG_POWER);

}

}

}frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cppstatic void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {

if (enable) {

ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off");

autosuspend_enable();

} else {

ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_disable() while turning screen on");

autosuspend_disable();

}

}最终跑autosuspend_enable,内核的休眠流程可参考https://blog.csdn.net/mike8825/article/details/80420213

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值