android 电源管理介绍

(本文讲解基于API23)

电源管理主要由PowerManagerService 负责, 那我们就先从 PowerManagerService讲起


PowerManagerService是系统核心服务之一, 由SystemServer 来启动。 首先我们看到SystemServer 类的main方法

SystemServer .java

   /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();

    }

从注释可以看出, zygote会启动这个main方法, 并new 一个SystemServer, 并知性run方法

在线程的run方法中,会启动各种系统服务, 其中与本文主题有关的代码如下:

SystemServer .java

  @Override
    public void run() {

......

        // Start services.
        try {
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        }

在run方法中,会调用三个启动服务的方法, 其中startBootstrapServices 启动有相互依赖关系的服务, startCoreServices 启动一些没有相互依赖关系的核心服务, startOtherServices 启动其他服务

PowerManagerService 是在startBootstrapServices  中启动, 我们来一起看一下源码:

SystemServer .java

 private void startBootstrapServices() {
        ......

        // Power manager needs to be started early because other services need it.
        // Native daemons may be watching for it to be registered so it must be ready
        // to handle incoming binder calls immediately (including being able to verify
        // the permissions for those calls).
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
......

    }

private void startOtherServices() {

...... 

       try {
            // TODO: use boot phase
            mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
        } catch (Throwable e) {
            reportWtf("making Power Manager Service ready", e);
        }

......

}

通过调用startService来启动PowerManagerService , 源码如下:

SystemServiceManager.java

    public <T extends SystemService> T startService(Class<T> serviceClass) {
       ......

        // Create the service.
      ......
        final T service;
        ......
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
......

        // Register it.
        mServices.add(service);

        // Start it.
        ......
            service.onStart();
......
        return service;
    }


通过反射机制, 调用了PowerManagerService  的构造函数, 并注册到SystemService 中, 然后调用onStart 方法启动了PowerManagerService  


下面看一下 PowerManagerService   的构造方法

PowerManagerService.java

    public PowerManagerService(Context context) {
......

//建立handle,处理一下异步操作
        mHandler = new PowerManagerHandler(mHandlerThread.getLooper());


        synchronized (mLock) {
            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
            mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
            mDisplaySuspendBlocker.acquire();
            mHoldingDisplaySuspendBlocker = true;
            mHalAutoSuspendModeEnabled = false;
            mHalInteractiveModeEnabled = true;


            mWakefulness = WAKEFULNESS_AWAKE;


            nativeInit();
            nativeSetAutoSuspend(false);
            nativeSetInteractive(true);
            nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
        }
    }


    @Override
    public void onStart() {

//注册binder服务
        publishBinderService(Context.POWER_SERVICE, new BinderService());

//注册本地服务
        publishLocalService(PowerManagerInternal.class, new LocalService());
//设置看门狗
        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
    }




    public void systemReady(IAppOpsService appOps) {
        synchronized (mLock) {
          ......
         
            // 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();
      ......
            // Initialize display power management.
            mDisplayManagerInternal.initPowerManagement(
                    mDisplayPowerCallbacks, mHandler, sensorManager);


            // Register for broadcasts from other components of the system.
            IntentFilter filter = new IntentFilter();
  ......
            // Register for settings changes.
            final ContentResolver resolver = mContext.getContentResolver();
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.SCREENSAVER_ENABLED),
                    false, mSettingsObserver, UserHandle.USER_ALL);
     ......
    }



wakeLock 是应用程序获取电力资源的途径,, 只要还有地方在使用WakeLock , 系统就不会进入休眠状态。 

WakeLock 通过 PowerManager  的 newWakeLock 方法获得。

    public WakeLock newWakeLock(int levelAndFlags, String tag) {

// 验证参数是否正确
        validateWakeLockParameters(levelAndFlags, tag);

// new一个新的WakeLock 对象
        return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName());
    }


WakeLock 的构造方法如下:

PowerManager.java--------------------------

        WakeLock(int flags, String tag, String packageName) {

// flags参数用于控制休眠状态, 可选值

/*不受电源键影响, CPU on , 屏幕和键盘off PARTIAL_WAKE_LOCK
     * 按下电源键会进入休眠,
CPU 屏幕,键盘都工作 FULL_WAKE_LOCK
     * 按下电源键会进入休眠, 屏幕变暗, 键盘关闭 SCREEN_DIM_WAKE_LOCK
     * 按下电源键会进入休眠, 屏幕工作, 键盘关闭SCREEN_BRIGHT_WAKE_LOCK
     *
当距离传感器发现被遮挡,关闭屏幕 PROXIMITY_SCREEN_OFF_WAKE_LOCK
     *
用于来电提醒和提示框 ACQUIRE_CAUSES_WAKEUP
     * WakeLock 
 释放之后屏幕不会立刻黑屏, 会延长一段时间  ON_AFTER_RELEASE    */


            mFlags = flags;
            mTag = tag;
       ......

//建立一个Binder 作为token,并监视客户端生死情况
            mToken = new Binder();
           ......
        }


        public void acquire() {
            synchronized (mToken) {
                acquireLocked();
            }
        }


        private void acquireLocked() {
            if (!mRefCounted || mCount++ == 0) {
                // Do this even if the wake lock is already thought to be held (mHeld == true)
                // because non-reference counted wake locks are not always properly released.
                // For example, the keyguard's wake lock might be forcibly released by the
                // power manager without the keyguard knowing.  A subsequent call to acquire
                // should immediately acquire the wake lock once again despite never having
                // been explicitly released by the keyguard.
                mHandler.removeCallbacks(mReleaser);
                Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
                try {
                    mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
                            mHistoryTag);
                } catch (RemoteException e) {
                }
                mHeld = true;
            }
        }


这里可以看到, 调用了PowerManagerService 里面的 acquireWakeLock

PowerManagerService.java ----------------------------------------------------

        @Override // Binder call
        public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
                WorkSource ws, String historyTag) {
......
//检查权限
            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
......

//调用acquireWakeLockInternal
                acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);
      ......
        }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值