Android5.1 PowerManagerService深入分析

PowerManagerService提供Android系统的电源管理服务,主要功能是控制系统的待机状态,控制显示屏的开关和亮度调节等。
PowerManagerService在systemserver中创建,加入到serviceManager中:
[java] view plain copy
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);  
先从构造函数分析,代码如下:
   
public PowerManagerService(Context context) {  
       super(context);  
       mContext = context;  
  //创建处理消息的线程  
       mHandlerThread = new ServiceThread(TAG,  
               Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);  
       mHandlerThread.start();  
 //创建Handler,注意mHandlerThread.getLooper(),每一个线程都只有一个looper,这样消息的处理会放在这个线程中  
       mHandler = new PowerManagerHandler(mHandlerThread.getLooper());  
  
       synchronized (mLock) {  
           mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");  
           mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");  
  //防止cpu进入睡眠状态  
           mDisplaySuspendBlocker.acquire();  
           mHoldingDisplaySuspendBlocker = true;  
           mHalAutoSuspendModeEnabled = false;  
           mHalInteractiveModeEnabled = true;  
  //当前系统状态正常运行状态  
           mWakefulness = WAKEFULNESS_AWAKE;  
  
           nativeInit();  
           nativeSetAutoSuspend(false);  
           nativeSetInteractive(true);  
       }  
   }  

构造函数比较简单,创建了一个接受消息处理的线程,cpu持锁不让手机睡眠,以及一些变量的初始化。
SystemServer创建完PowerManagerService后,继续调用SystemReady方法,再做一些初始化的工作,代码如下:
[java] view plain copy
public void systemReady(IAppOpsService appOps) {  
        synchronized (mLock) {  
            mSystemReady = true;  
            mAppOps = appOps;  
            //android5.0后的新方法,localService可以直接取,在4.4中这样service是在init中传对象进来的  
            mDreamManager = getLocalService(DreamManagerInternal.class);  
            mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);  
            mPolicy = getLocalService(WindowManagerPolicy.class);  
            mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);  
  
            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);  
            //获取缺省、最大、最小屏幕亮度  
            mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();  
            mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();  
            mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();  
            //创建sensorManager和sersorservice交互  
            SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());  
  
            // The notifier runs on the system server's main looper so as not to interfere  
            // with the animations and other critical functions of the power manager.  
            mBatteryStats = BatteryStatsService.getService();  
            mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,  
                    mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),  
                    mPolicy);  
            //创建检测无线充电的对象  
            mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,  
                    createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),  
                    mHandler);  
            mSettingsObserver = new SettingsObserver(mHandler);  
  
            mLightsManager = getLocalService(LightsManager.class);  
            mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);  
  
            // Initialize display power management.  
            mDisplayManagerInternal.initPowerManagement(  
                    mDisplayPowerCallbacks, mHandler, sensorManager);  
  
            // Register for broadcasts from other components of the system.  
            //监听其他模块的广播  
            IntentFilter filter = new IntentFilter();  
            filter.addAction(Intent.ACTION_BATTERY_CHANGED);  
            filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);  
            mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);  
  
            filter = new IntentFilter();  
            filter.addAction(Intent.ACTION_DREAMING_STARTED);  
            filter.addAction(Intent.ACTION_DREAMING_STOPPED);  
            mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);  
  
            filter = new IntentFilter();  
            filter.addAction(Intent.ACTION_USER_SWITCHED);  
            mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);  
  
            filter = new IntentFilter();  
            filter.addAction(Intent.ACTION_DOCK_EVENT);  
            mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);  
  
            // Register for settings changes.  
            final ContentResolver resolver = mContext.getContentResolver();  
            resolver.registerContentObserver(Settings.Secure.getUriFor(  
                    Settings.Secure.SCREENSAVER_ENABLED),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.Secure.getUriFor(  
                    Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.Secure.getUriFor(  
                    Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.System.getUriFor(  
                    Settings.System.SCREEN_OFF_TIMEOUT),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.Secure.getUriFor(  
                    Settings.Secure.SLEEP_TIMEOUT),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.Global.getUriFor(  
                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.System.getUriFor(  
                    Settings.System.SCREEN_BRIGHTNESS),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.System.getUriFor(  
                    Settings.System.SCREEN_BRIGHTNESS_MODE),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.System.getUriFor(  
                    Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.Global.getUriFor(  
                    Settings.Global.LOW_POWER_MODE),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.Global.getUriFor(  
                    Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            resolver.registerContentObserver(Settings.Global.getUriFor(  
                    Settings.Global.THEATER_MODE_ON),  
                    false, mSettingsObserver, UserHandle.USER_ALL);  
            // Go.  
            readConfigurationLocked();  
            updateSettingsLocked();  
            mDirty |= DIRTY_BATTERY_STATE;  
            updatePowerStateLocked();  
        }  
    }  

从在android5.1.1中,service一般都会继承一个虚类SystemService,在其中定义了两个接口onStart和onBootPhase,分别是PowerManagerService启动的时候会调用,而onBootPhase会在系统启动的各个阶段来调用,下面我们分别来看看在powerManagerService中这两个函数的实现:
[java] view plain copy
@Override  
public void onStart() {  
    publishBinderService(Context.POWER_SERVICE, new BinderService());  
    publishLocalService(PowerManagerInternal.class, new LocalService());  
  
    Watchdog.getInstance().addMonitor(this);  
    Watchdog.getInstance().addThread(mHandler);  
}  
在onstart函数中,必须把一些接口publish,像在之前Binder的接口,都是通过PowerManagerService extends IPowerManager.Stub形式在PowerManagerService中实现接口
而在android5.1.1中都是通过方式重新定义一个类,然后把这个类publish出去。
[java] view plain copy
private final class BinderService extends IPowerManager.Stub {  
    @Override // Binder call  
    public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,  
            String packageName, int uid) {  
        if (uid < 0) {  
            uid = Binder.getCallingUid();  
        }  
        acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null);  
    }  
  
    @Override // Binder call  
    public void powerHint(int hintId, int data) {  
        if (!mSystemReady) {  
            // Service not ready yet, so who the heck cares about power hints, bah.  
            return;  
        }  
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);  
        powerHintInternal(hintId, data);  
    }  
  
    @Override // Binder call  
    public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,  
            WorkSource ws, String historyTag) {  
[java] view plain copy
。。。。。。。。。。。。。。  
而localservice都是一些本地的服务,不是通过Binder实现的。

    我们接下来从,powerManager中的wakeLock说起,在powerManager中调用newWakeLock接口会生成一个WakeLock对象,而调用器acqure方法,最终会调用PowerManagerService中的acquireWakeLock方法
而具体的WakeLock有几种如下:
PARTIAL_WAKE_LOCK:只保持CPU运行,屏幕和键盘光关闭。
FULL_WAKE_LOCK:都不关闭
SCREEN_BRIGHT_WAKE_LOCK:屏幕背光不关闭,键盘光关闭
SCREEN_DIM_WAKE_LOCK:屏幕背光不关闭,键盘光关闭。但是屏幕背光可以变暗
PROXIMITY_SCREEN_OFF_WAKE_LOCK当持有这种类型wakelock,当距离传感器被遮挡,屏幕将被关闭。打电话时用这个功能
在PowerManagerService中的acquieWakeLock先要检查权限然后调用acquireWakeLockInternal接口,代码如下:
[java] view plain copy
private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,  
          WorkSource ws, String historyTag, int uid, int pid) {  
      synchronized (mLock) {  
          WakeLock wakeLock;  
          //查找wakelock  
          int index = findWakeLockIndexLocked(lock);  
          boolean notifyAcquire;  
          if (index >= 0) {查找到  
              wakeLock = mWakeLocks.get(index);  
              if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {属性不一样,更新  
                  // Update existing wake lock.  This shouldn't happen but is harmless.  
                  notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName,  
                          uid, pid, ws, historyTag);  
                  wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);  
              }  
              notifyAcquire = false;  
          } else {没找到,重新建立,添加  
              wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);  
              try {  
                  lock.linkToDeath(wakeLock, 0);  
              } catch (RemoteException ex) {  
                  throw new IllegalArgumentException("Wake lock is already dead.");  
              }  
              mWakeLocks.add(wakeLock);  
              notifyAcquire = true;  
          }  
          //看是否需要点亮屏幕  
          applyWakeLockFlagsOnAcquireLocked(wakeLock, uid);  
          //整个PowermanagerService用来记录各个状态变化的一个标志位  
          mDirty |= DIRTY_WAKE_LOCKS;  
          //更新各个状态  
          updatePowerStateLocked();  
          if (notifyAcquire) {  
              // This needs to be done last so we are sure we have acquired the  
              // kernel wake lock.  Otherwise we have a race where the system may  
              // go to sleep between the time we start the accounting in battery  
              // stats and when we actually get around to telling the kernel to  
              // stay awake.  
              notifyWakeLockAcquiredLocked(wakeLock);  
          }  
      }  
  }  
整个PowermanagerService都是靠一个mDirty的各个标志位来记录各个状态的变化,随后会调用一个updatePowerStateLocked来更新各个状态。
同样解锁会调用到releaseWakeLockInternal,代码如下:
[java] view plain copy
 private void releaseWakeLockInternal(IBinder lock, int flags) {  
        synchronized (mLock) {  
            int index = findWakeLockIndexLocked(lock);  
            if (index < 0) {//没有找到退出  
                if (DEBUG_SPEW) {  
                    Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)  
                            + " [not found], flags=0x" + Integer.toHexString(flags));  
                }  
                return;  
            }  
  
            WakeLock wakeLock = mWakeLocks.get(index);  
            if (DEBUG_SPEW) {  
                Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)  
                        + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags));  
            }  
  
            if ((flags & PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) {  
                mRequestWaitForNegativeProximity = true;  
            }  
            //去除wakelock  
            wakeLock.mLock.unlinkToDeath(wakeLock, 0);  
            removeWakeLockLocked(wakeLock, index);  
        }  
    }  
  
PowerManagerService中最终各个接口都会调一个函数updatePowerStateLocked,主要用来更新power的各个状态  
  
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.  
            //更新充电的各个状态(是否充电、电池电量、充电方式、是否低电量),以及更新低功耗模式(android5.0增加的)  
            updateIsPoweredLocked(mDirty);  
            //更新mStayOn状态,为true,屏幕常亮  
            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;  
                //更新mWakeLockSummary的状态  
                updateWakeLockSummaryLocked(dirtyPhase1);  
                //更新mUserActivitySummary状态  
                updateUserActivitySummaryLocked(now, dirtyPhase1);  
                if (!updateWakefulnessLocked(dirtyPhase1)) {  
                    break;  
                }  
            }  
  
            // Phase 2: Update display power state.  
            boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);//更新display状态,在displaypowercontrol中会控制亮度,灭屏等  
  
            // Phase 3: Update dream state (depends on display ready signal).  
            //更新梦的状态,用dreammanager控制梦,powermanagerservice中记录mWakefulness  
            updateDreamLocked(dirtyPhase2, displayBecameReady);  
  
            // Phase 4: Send notifications, if needed.  
            if (mDisplayReady) {  
                finishWakefulnessChangeLocked();  
            }  
  
            // 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);  
        }  
    }  

updateIsPoweredLocked、updateStayOnLocked、updateScreenBrightnessBoostLocked、updateWakeLockSummaryLocked、updateUserActivitySummaryLocked都是比较简单、在上面的函数注释中都有介绍。下面我们先看下updateWakefulnessLocked函数,代码如下:
[java] view plain copy
private boolean updateWakefulnessLocked(int dirty) {  
    boolean changed = false;  
    if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED  
            | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE  
            | DIRTY_DOCK_STATE)) != 0) {  
        //当前状态是醒着,并且准备开始睡眠了  
        if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {  
            if (DEBUG_SPEW) {  
                Slog.d(TAG, "updateWakefulnessLocked: Bed time...");  
            }  
            final long time = SystemClock.uptimeMillis();  
            //是应该开始做梦,还是先睡眠  
            if (shouldNapAtBedTimeLocked()) {  
                //当前状态设置为睡眠状态  
                changed = napNoUpdateLocked(time, Process.SYSTEM_UID);  
            } else {  
                //当前状态设置为假寐状态  
                changed = goToSleepNoUpdateLocked(time,  
                        PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);  
            }  
        }  
    }  
    return changed;  
}  
[java] view plain copy
private boolean isBeingKeptAwakeLocked() {  
    return mStayOn  
            || mProximityPositive//距离传感器  
            || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0//wakelock锁  
            || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT  
                    | USER_ACTIVITY_SCREEN_DIM)) != 0//用户行为、和用户点击屏幕、自动灭屏时间等有关  
            || mScreenBrightnessBoostInProgress;\\是否要保持处于最亮状态  
}  
  
  
private boolean isItBedTimeYetLocked() {  
//当启动完成、并且设备不必保持唤醒状态是的时候返回true  
    return mBootCompleted && !isBeingKeptAwakeLocked();  
}  

updateDreamLocked函数通过发送消息,最终会调用handleSandman:

[java] view plain copy
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();  
            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);  
        }  
        isDreaming = mDreamManager.isDreaming();  
    } else {  
        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, "Dozing...");  
            } else {  
                Slog.i(TAG, "Dreaming...");  
            }  
        }  
  
        // 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) {  
            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, "Stopping dream because the battery appears to "  
                            + "be draining faster than it is charging.  "  
                            + "Battery level when dream started: "  
                            + mBatteryLevelWhenDreamStarted + "%.  "  
                            + "Battery level now: " + mBatteryLevel + "%.");  
                } else {  
                    //继续做梦  
                    return; // continue dreaming  
                }  
            }  
  
            // Dream has ended or will be stopped.  Update the power state.  
            //结束做梦,要么唤醒、要么继续goToSleep  
            if (isItBedTimeYetLocked()) {  
                goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),  
                        PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);  
                updatePowerStateLocked();  
            } else {  
                wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);  
                updatePowerStateLocked();  
            }  
        } else if (wakefulness == WAKEFULNESS_DOZING) {  
            if (isDreaming) {  
                return; // continue dozing  
            }  
            //直接睡眠,跳过做梦  
            // Doze has ended or will be stopped.  Update the power state.  
            reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);  
            updatePowerStateLocked();  
        }  
    }  
  
    // Stop dream.能走到这说明,肯定结束做梦  
    if (isDreaming) {  
        mDreamManager.stopDream(false /*immediate*/);  
    }  
}  
updateSuspendBlockerLocked函数是是否要Cpu持锁。

[java] view plain copy
private void updateSuspendBlockerLocked() {  
    final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);//是否要cpu持锁  
    final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();//是否display要持锁  
    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) {//当屏幕亮着|| 当屏幕暗着,displayPowerControl准备好了,进入该条件设置  
            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);  
    }  
}  

下来介绍下powermanager中其他的接口,
1、gotosleep,让设备睡眠,按power键会调用这个函数
private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {  
       synchronized (mLock) {  
           //返回true,才更新状态  
           if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {  
               updatePowerStateLocked();  
           }  
       }  
   }  
  
   @SuppressWarnings("deprecation")  
   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;  
。。。。。。。。。。。。  
           }  
  
           mLastSleepTime = eventTime;  
           mSandmanSummoned = true;  
           setWakefulnessLocked(WAKEFULNESS_DOZING, reason);  
  
           // Report the number of wake locks that will be cleared by going to sleep.  
           //统计wakelock的数量  
           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;  
   }  
2、useractivity是当用户点击屏幕等行为,会重新计算自动灭屏的时间等,然后回去updatepowerstate
3、wakeup唤醒设备,与gotosleep对应。
4、nap,使设备处于一种假寐的状态
5、boostScreenBrightness,是屏幕达到最亮持续一段时间
这其中每个函数都会调用updatepowerstate

转载于:https://my.oschina.net/u/2542649/blog/967492

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值