PowerManagerService学习笔记一

PowerManagerService(PMS): 主要负责Android系统中电源管理方面的工作。与其直接关系的类成员有如下几个:

PowerManagerService从IPowerManager.Stub派生,并实现了Watchdog.Monitor及LocalPowerManager接口;

IPowerManager.Stub及其内部类Proxy均有aidl工具处理IPower-Mangaer.aidl后得到;

客户端使用PowerManager类,其内部通过BinderProxy端的mService成员变量与PowerManagerService进行Binder通信;


PowerManagerService(PMS)的创建

PMS有SystemServer在ServerThread中创建,这里有几个关键的过程

//SystemServer.java
//ServerThread的run方法
//关键点1
power = new PowerManagerService();
/*注册到SM中*/
ServiceManager.addService(Context.POWER_SERVICE,power);
//关键点2
power.init(context, lights, ActivityManagerService.self(), battery);
......//其它服务
//关键点3
power.systemReady();
......//系统启动完毕会受到ACTION_BOOT_COMPLETED广播
//关键点4
//PMS处理ACTION_BOOT_COMPLETED广播

关键点1:

PowerManagerService() {
        // Hack to get our uid...  should have a func for this.
        long token = Binder.clearCallingIdentity();
        MY_UID = Process.myUid();
        MY_PID = Process.myPid();
        Binder.restoreCallingIdentity(token);

        // XXX remove this when the kernel doesn't timeout wake locks
	//设置超时间为1周
        Power.setLastUserActivityTimeout(7*24*3600*1000); // one week

        // assume nothing is on yet
		//重要的两个成员变量
        mUserState = mPowerState = 0;

		//将自己添加到看门狗的监控管理队列中
        Watchdog.getInstance().addMonitor(this);
}

关键点2:

init主要完成以下几方面的工作:

1> 对一些成员变量进行赋值;

2> 调用nativeInit方法初始化Native层;

3> 调用updateNativePowerStateLocked方法更新Native层的电源状态;

4> 创建mScreenOffThread线程,按Power键关闭屏幕时,屏幕不是突然变黑,而是一个渐暗的过程。mScreenOffThread线程就是用于控制关闭屏幕过程中的亮度调节;

5> 创建mHandlerThread线程,该线程是PMS的主要工作线程;

6> 初始化mHandlerThread线程相关信息;

7> 强制触发一次用户事件;

各方面共做对应的源码:

1>成员变量说明

 

2>nativeInit

//com_android_server_PowerManagerService.cpp

    static void android_server_PowerManagerService_nativeInit(JNIEnv* env, jobject obj) {
     //创建一个全局引用对象
     gPowerManagerServiceObj = env->NewGlobalRef(obj);
    }
3> updateNativePowerStateLocked(待学习)

4> mScreenOffThread创建

//PowerManagerService.java

        mInitComplete = false;
        mScreenOffThread = new HandlerThread("PowerManagerService.mScreenOffThread") {
            @Override
            protected void onLooperPrepared() {
                mScreenOffHandler = new Handler();
                synchronized (mScreenOffThread) {
                    mInitComplete = true;
                    mScreenOffThread.notifyAll();
                }
            }
        };
        mScreenOffThread.start();
	//等待mScreenOffThread线程创建完毕
        synchronized (mScreenOffThread) {
            while (!mInitComplete) {
                try {
                    mScreenOffThread.wait();
                } catch (InterruptedException e) {
                    // Ignore
                }
            }
        }
5> mHandlerThread创建

	mInitComplete = false;
        mHandlerThread = new HandlerThread("PowerManagerService") {
            @Override
            protected void onLooperPrepared() {
                super.onLooperPrepared();
		初始化mHandlerThread线程
                initInThread();
            }
        };
        mHandlerThread.start();
	//等待mHandlerThread线程创建完毕
        synchronized (mHandlerThread) {
            while (!mInitComplete) {
                try {
                    mHandlerThread.wait();
                } catch (InterruptedException e) {
                    // Ignore
                }
            }
        }
6> initInThread分析

a. PMS需要了解外面的状态,所以会注册一些广播接收对象,接收诸如启动完毕,电池变化等广播; 

b. PMS所从事的电源管理工作需要一些规则,需要对其做一些配置,这些配置信息有些是固定的(编译后无法改变),有些是可以在Settings数据库中动态设定的;

c. PMS需要对法发送一些通知,诸如,屏幕关闭/开启;

d. 源代码

对于数据库中的参数配置,需要加入监测机制,通知PMS更新相关配置。

   void initInThread() {
        mHandler = new Handler();

        mBroadcastWakeLock = new UnsynchronizedWakeLock(
                                PowerManager.PARTIAL_WAKE_LOCK, "sleep_broadcast", true);
        mStayOnWhilePluggedInScreenDimLock = new UnsynchronizedWakeLock(
                                PowerManager.SCREEN_DIM_WAKE_LOCK, "StayOnWhilePluggedIn Screen Dim", false);
        mStayOnWhilePluggedInPartialLock = new UnsynchronizedWakeLock(
                                PowerManager.PARTIAL_WAKE_LOCK, "StayOnWhilePluggedIn Partial", false);
        mPreventScreenOnPartialLock = new UnsynchronizedWakeLock(
                                PowerManager.PARTIAL_WAKE_LOCK, "PreventScreenOn Partial", false);
        mProximityPartialLock = new UnsynchronizedWakeLock(
                                PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
	//创建广播通知的intent,用于通知SCREEN_ON/SCREEN_OFF消息
        mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
        mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
        mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
		
	//取得参数配置,编译时确定,运行过程中无法修改
        Resources resources = mContext.getResources();
        mAnimateScreenLights = resources.getBoolean(
                com.android.internal.R.bool.config_animateScreenLights);

        mUnplugTurnsOnScreen = resources.getBoolean(
                com.android.internal.R.bool.config_unplugTurnsOnScreen);

        mScreenBrightnessDim = resources.getInteger(
                com.android.internal.R.integer.config_screenBrightnessDim);

        // read settings for auto-brightness
        mUseSoftwareAutoBrightness = resources.getBoolean(
                com.android.internal.R.bool.config_automatic_brightness_available);
        if (mUseSoftwareAutoBrightness) {
            mAutoBrightnessLevels = resources.getIntArray(
                    com.android.internal.R.array.config_autoBrightnessLevels);
            mLcdBacklightValues = resources.getIntArray(
                    com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
            mButtonBacklightValues = resources.getIntArray(
                    com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);
            mKeyboardBacklightValues = resources.getIntArray(
                    com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues);
            mLightSensorWarmupTime = resources.getInteger(
                    com.android.internal.R.integer.config_lightSensorWarmupTime);
        }
	//取得参数配置完毕
	//取得数据库设置的配置参数
       ContentResolver resolver = mContext.getContentResolver();
        Cursor settingsCursor = resolver.query(Settings.System.CONTENT_URI, null,
                "(" + Settings.System.NAME + "=?) or ("
                        + Settings.System.NAME + "=?) or ("
                        + Settings.System.NAME + "=?) or ("
                        + Settings.System.NAME + "=?) or ("
                        + Settings.System.NAME + "=?) or ("
                        + Settings.System.NAME + "=?)",
                new String[]{STAY_ON_WHILE_PLUGGED_IN, SCREEN_OFF_TIMEOUT, DIM_SCREEN,
                        SCREEN_BRIGHTNESS_MODE, WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE},
                null);
        mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mHandler);
       //观察者模式,监视ContentQueryMap中内容的变化
		SettingsObserver settingsObserver = new SettingsObserver();
        mSettings.addObserver(settingsObserver);

        // pretend that the settings changed so we will get their initial state
        settingsObserver.update(mSettings, null);

	//注册接收通知的BroadCastReceiver对象
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
        mContext.registerReceiver(new BatteryReceiver(), filter);
        filter = new IntentFilter();
        filter.addAction(Intent.ACTION_BOOT_COMPLETED);
        mContext.registerReceiver(new BootCompletedReceiver(), filter);
        filter = new IntentFilter();
        filter.addAction(Intent.ACTION_DOCK_EVENT);
        mContext.registerReceiver(new DockReceiver(), filter);

        // Listen for secure settings changes
	//监视Settings数据库中secure表的变化
        mContext.getContentResolver().registerContentObserver(
            Settings.Secure.CONTENT_URI, true,
            new ContentObserver(new Handler()) {
                public void onChange(boolean selfChange) {
                    updateSettingsValues();
                }
            });
        updateSettingsValues();

        synchronized (mHandlerThread) {
            mInitComplete = true;
            mHandlerThread.notifyAll();
        }
    }
7> forceUserActivityLocked内部调用userActivity,调用该方法后手机被唤醒,屏幕超时时间也将重新计算

    private void forceUserActivityLocked() {
        if (isScreenTurningOffLocked()) {
            // cancel animation so userActivity will succeed
            mScreenBrightness.animating = false;
        }
        boolean savedActivityAllowed = mUserActivityAllowed;
        mUserActivityAllowed = true;
	//唤醒设备屏幕,超时时间重新计算
        userActivity(SystemClock.uptimeMillis(), false);
        mUserActivityAllowed = savedActivityAllowed;
    }
关键点3:

systemReady主要完成以下几方面工作:

1> PMS创建SensorManager,通过它可与对应的传感器交互;PMS仅仅启用特定的传感器,而来自传感器的数据将通过回调方式通知PMS,PMS根据时间作出回应;

2> 通过setPowerState方法设置电源状态为ALL_BRIGHT(不考虑,UserSoftwareAutoBrightness情况),此时屏幕及键盘都会点亮;

3> 通过BatteryStasService提供的方法,通知屏幕打开事件;

void systemReady() {
        mSensorManager = new SensorManager(mHandlerThread.getLooper());
        mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
        // don't bother with the light sensor if auto brightness is handled in hardware
        if (mUseSoftwareAutoBrightness) {
            mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
        }

        // wait until sensors are enabled before turning on screen.
        // some devices will not activate the light sensor properly on boot
        // unless we do this.
        if (mUseSoftwareAutoBrightness) {
            // turn the screen on
            setPowerState(SCREEN_BRIGHT);
        } else {
            // turn everything on
            setPowerState(ALL_BRIGHT);
        }

        synchronized (mLocks) {
            Slog.d(TAG, "system ready!");
            mDoneBooting = true;

            enableLightSensorLocked(mUseSoftwareAutoBrightness && mAutoBrightessEnabled);

            long identity = Binder.clearCallingIdentity();
            try {
                mBatteryStats.noteScreenBrightness(getPreferredBrightness());
                mBatteryStats.noteScreenOn();
            } catch (RemoteException e) {
                // Nothing interesting to do.
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }
    }

关键点4:

当系统的服务在systemReady中进行处理后,系统会发ACTION_BOOT_COMPLETED消息。

1> BootCompletedReceiver

    private final class BootCompletedReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            bootCompleted();
        }
    }
2> bootCompleted

    void bootCompleted() {
        Slog.d(TAG, "bootCompleted");
        synchronized (mLocks) {
            mBootCompleted = true;
            userActivity(SystemClock.uptimeMillis(), false, BUTTON_EVENT, true);
            updateWakeLockLocked();
            mLocks.notifyAll();
        }
    }
3> updateWakeLockLocked

	private void updateWakeLockLocked() {
		/*
		mStayOnConditions用于控制当手机插上USB时,是否需要保持唤醒状态
		mBatteryService.isPowered是否处于USB充电状态。
		如果满足条件,PMS需要使用WakeLock来确保系统不掉电
		*/
        if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
            // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
            mStayOnWhilePluggedInScreenDimLock.acquire();
            mStayOnWhilePluggedInPartialLock.acquire();
        } else {
            mStayOnWhilePluggedInScreenDimLock.release();
            mStayOnWhilePluggedInPartialLock.release();
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值