android6.0 PowerManagerService
dream分析
一、Dream关闭
首先我们结合打印的log,看看handleSandman函数,log直接加在下面的函数中。当然我们现在说的情况是mWakefulness是dozing状态。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private void handleSandman() { // runs on handler thread // Handle preconditions. final boolean startDreaming; final int wakefulness; synchronized (mLock) {
mSandmanScheduled = false; wakefulness = mWakefulness;
if (mSandmanSummoned && mDisplayReady) {
startDreaming = canDreamLocked() || canDozeLocked();
Slog.d(TAG, \这个变量log打印为true
mSandmanSummoned = false; } else {
startDreaming = false; } }
// Start dreaming if needed.
// We only control the dream on the handler thread, so we don't need to worry about // concurrent attempts to start or stop the dream. final boolean isDreaming; if (mDreamManager != null) {
// Restart the dream whenever the sandman is summoned. if (startDreaming) {
mDreamManager.stopDream(false /*immediate*/);
mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);//调用startStream }
isDreaming = mDreamManager.isDreaming();
Slog.d(TAG, \返回false } else {
Slog.d(TAG, \ isDreaming = false; }
// Update dream state. synchronized (mLock) {
// Remember the initial battery level when the dream started. if (startDreaming && isDreaming) {
mBatteryLevelWhenDreamStarted = mBatteryLevel; if (wakefulness == WAKEFULNESS_DOZING) { Slog.i(TAG, \ } else {
Slog.i(TAG, \ } }
// If preconditions changed, wait for the next iteration to determine // whether the dream should continue (or be restarted).
if (mSandmanSummoned || mWakefulness != wakefulness) { return; // wait for next cycle }
// Determine whether the dream should continue.
if (wakefulness == WAKEFULNESS_DREAMING) {
Slog.d(TAG, \ if (isDreaming && canDreamLocked()) {
if (mDreamsBatteryLevelDrainCutoffConfig >= 0
&& mBatteryLevel < mBatteryLevelWhenDreamStarted - mDreamsBatteryLevelDrainCutoffConfig && !isBeingKeptAwakeLocked()) {
// If the user activity timeout expired and the battery appears // to be draining faster than it is charging then stop dreaming // and go to sleep.
Slog.i(TAG, \ + \ \ + \
+ mBatteryLevelWhenDreamStarted + \ \ + \ } else {
return; // continue dreaming } }
// Dream has ended or will be stopped. Update the power state. if (isItBedTimeYetLocked()) {
goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID);
0,
updatePowerStateLocked(); } else {
wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), \
Process.SYSTEM_UID, mContext.getOpPackageName(), Process.SYSTEM_UID);
updatePowerStateLocked(); }
} else if (wakefulness == WAKEFULNESS_DOZING) { if (isDreaming) {//为false
Slog.d(TAG, \ return; // continue dozing }
// Doze has ended or will be stopped. Update the power state.
Slog.d(TAG, \状态 reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);
Slog.d(TAG, \状态了 updatePowerStateLocked(); } }
Slog.d(TAG, \
// Stop dream. if (isDreaming) {
mDreamManager.stopDream(false /*immediate*/); } }
看了上面的注释很明显,我们是调用了startdream,但是isDreaming返回是false。明显是没有支持dream。因此power也就直接进入的sleep状态。
那我们再来看看这个dream,下面是DreamManagerService的LocalService [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private final class LocalService extends DreamManagerInternal { @Override
public void startDream(boolean doze) { startDreamInternal(doze); }
@Override
public void stopDream(boolean immediate) { stopDreamInternal(immediate);
}
@Override
public boolean isDreaming() { return isDreamingInternal(); } }
我们来看startDreamInternal函数
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private void startDreamInternal(boolean doze) { Slog.d(TAG, \
final int userId = ActivityManager.getCurrentUser();
final ComponentName dream = chooseDreamForUser(doze, userId);
if (dream != null) {
synchronized (mLock) {
startDreamLocked(dream, false /*isTest*/, doze, userId); } } else {
Slog.d(TAG, \加的打印log } }
我们在这个函数中加了log,发现dream为null,所以压根美欧调用startDreamLocked函数。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片
private ComponentName chooseDreamForUser(boolean doze, int userId) { if (doze) {
ComponentName dozeComponent = getDozeComponent(userId); return validateDream(dozeComponent) ? dozeComponent : null; }
ComponentName[] dreams = getDreamComponentsForUser(userId); return dreams != null && dreams.length != 0 ? dreams[0] : null; }
chooseDreamForUser返回为null,是因为getDozeComponent返回为null。 我们再看getDozeComponent函数:
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private ComponentName getDozeComponent(int userId) {
String name = Build.IS_DEBUGGABLE ? SystemProperties.get(\null;
if (TextUtils.isEmpty(name)) {
name = mContext.getResources().getString(
com.android.internal.R.string.config_dozeComponent); }
boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.DOZE_ENABLED, 1, userId) != 0;
return TextUtils.isEmpty(name) || !enabled ? null : ComponentName.unflattenFromString(name); }
上面这个变量name是null,导致返回null。还是系统没有支持dream的原因。
二、DreamService
虽然我们系统不支持,我们也看下代码,先看下startDreamLocked函数 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 private void startDreamLocked(final ComponentName name,
final boolean isTest, final boolean canDoze, final int userId) { if (Objects.equal(mCurrentDreamName, name) && mCurrentDreamIsTest == isTest
&& mCurrentDreamCanDoze == canDoze && mCurrentDreamUserId == userId) { return; }
stopDreamLocked(true /*immediate*/);
Slog.i(TAG, \
final Binder newToken = new Binder(); mCurrentDreamToken = newToken; mCurrentDreamName = name; mCurrentDreamIsTest = isTest;
mCurrentDreamCanDoze = canDoze; mCurrentDreamUserId = userId;
mHandler.post(new Runnable() { @Override
public void run() {
mController.startDream(newToken, name, isTest, canDoze, userId); } }); }
最终是调用了mController.startDream函数,再来看DreamController类的startDream函数 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 public void startDream(Binder token, ComponentName name, boolean isTest, boolean canDoze, int userId) { stopDream(true /*immediate*/);
Trace.traceBegin(Trace.TRACE_TAG_POWER, \ try {
// Close the nowww.sm136.comtification shade. Don't need to send to all, but better to