PowerManagerService分析之Notifier分析

穆正祥
2023-12-01

这个类在PowerManagerService中是非常重要的,当PowerManagerService的状态改变时,都是靠这个类通知。比如常用的灭屏和亮屏广播,也是在这个类中发送的。

一、Notifier初始化

首先我们来看它在PowerManagerService构造函数中的初始化:

  mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
                    mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
                    mPolicy);

PowerManagerService把自己的main looper传进去了,说明在Notifier的消息处理是在PowerManagerService的主线程中,还有一点和之前的WakeLocks,和Display锁一样,这里也为Notifier创建了一个Broadcasts锁。

Notifier类

public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
            IAppOpsService appOps, SuspendBlocker suspendBlocker,
            WindowManagerPolicy policy) {
        mContext = context;
        mBatteryStats = batteryStats;
        mAppOps = appOps;
        mSuspendBlocker = suspendBlocker;
        mPolicy = policy;
        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
        mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
        mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);

        mHandler = new NotifierHandler(looper);
        mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
        ...
        // Initialize interactive state for battery stats.
        try {
            mBatteryStats.noteInteractive(true);
        } catch (RemoteException ex) { }
    }

//
private final class NotifierHandler extends Handler {
        public NotifierHandler(Looper looper) {
            super(looper, null, true /*async*/);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_USER_ACTIVITY:
                    sendUserActivity();
                    break;

                case MSG_BROADCAST:
                    sendNextBroadcast();
                    break;

                case MSG_WIRELESS_CHARGING_STARTED:
                    playWirelessChargingStartedSound();
                    break;
                case MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED:
                    sendBrightnessBoostChangedBroadcast();
                    break;
            }
        }
    }

二、唤醒

在PowerManagerService的wakeUpNoUpdateLocked函数会调用如下函数:

mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid);

再看下Notifier处理:

public void onWakeUp(String reason, int reasonUid, String opPackageName, int opUid) {
        try {
            mBatteryStats.noteWakeUp(reason, reasonUid);
            if (opPackageName != null) {
                mAppOps.noteOperation(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
            }
        } catch (RemoteException ex) {
            // Ignore
        }
 
    }

三、userActivity

在userActivityNoUpdateLocked函数中也会调用如下函数:

mNotifier.onUserActivity(event, uid);

我们看下Notifier的处理

public void onUserActivity(int event, int uid) {
        try {
            mBatteryStats.noteUserActivity(uid, event);
        } catch (RemoteException ex) {
            // Ignore
        }
 
        synchronized (mLock) {
            if (!mUserActivityPending) {
                mUserActivityPending = true;
                Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY);
                msg.setAsynchronous(true);
                mHandler.sendMessage(msg);
            }
        }
    }

消息处理函数为:sendUserActivity

private void sendUserActivity() {
        synchronized (mLock) {
            if (!mUserActivityPending) {
                return;
            }
            mUserActivityPending = false;
        }
        mPolicy.userActivity();
    }

最后是在PhoneWindowManager中处理好像是在keyguard中处理。

四、更新屏幕最亮化

我们再来看updateScreenBrightnessBoostLocked函数,也会调用mNotifier.onScreenBrightnessBoostChanged函数

private void updateScreenBrightnessBoostLocked(int dirty) {
        if ((dirty & DIRTY_SCREEN_BRIGHTNESS_BOOST) != 0) {
            if (mScreenBrightnessBoostInProgress) {
                final long now = SystemClock.uptimeMillis();
                mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
                if (mLastScreenBrightnessBoostTime > mLastSleepTime) {
                    final long boostTimeout = mLastScreenBrightnessBoostTime +
                            SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
                    if (boostTimeout > now) {
                        Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
                        msg.setAsynchronous(true);
                        mHandler.sendMessageAtTime(msg, boostTimeout);
                        return;
                    }
                }
                mScreenBrightnessBoostInProgress = false;
                mNotifier.onScreenBrightnessBoostChanged();
                userActivityNoUpdateLocked(now,
                        PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
            }
        }
    }

onScreenBrightnessBoostChanged函数,发送了消息

public void onScreenBrightnessBoostChanged() {
 
        mSuspendBlocker.acquire();// 持锁了
        Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED);
        msg.setAsynchronous(true);
        mHandler.sendMessage(msg);
    }

最后在sendBrightnessBoostChangedBroadcast处理了消息,发送广播。

private void sendBrightnessBoostChangedBroadcast() {
        if (DEBUG) {
            Slog.d(TAG, "Sending brightness boost changed broadcast.");
        }
 
        mContext.sendOrderedBroadcastAsUser(mScreenBrightnessBoostIntent, UserHandle.ALL, null,
                mScreeBrightnessBoostChangedDone, mHandler, 0, null, null);
    }

mScreeBrightnessBoostChangedDone函数是所有广播收到后处理mScreeBrightnessBoostChangedDone函数,mScreeBrightnessBoostChangedDone函数是在mHandler中进行处理。
mScreeBrightnessBoostChangedDone 中就是把之前的Broadcast锁释放了。

 private final BroadcastReceiver mScreeBrightnessBoostChangedDone = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            mSuspendBlocker.release();
        }
    };

五、setWakefulnessLocked

在PowerManagerService的每个setWakefulnessLocked,都会调用mNotifier.onWakefulnessChangeStarted函数

private void setWakefulnessLocked(int wakefulness, int reason) {
        if (mWakefulness != wakefulness) {
            mWakefulness = wakefulness;
            mWakefulnessChanging = true;
            mDirty |= DIRTY_WAKEFULNESS;
            mNotifier.onWakefulnessChangeStarted(wakefulness, reason);
        }
    }

Notifier的onWakefulnessChangeStarted函数:

public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
        final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mActivityManagerInternal.onWakefulnessChanged(wakefulness);//调用AMS的onWakefulnessChanged函数
            }
        });
 
        // Handle any early interactive state changes.
        // Finish pending incomplete ones from a previous cycle.
        if (mInteractive != interactive) {//屏幕状态改变
            // Finish up late behaviors if needed.
            if (mInteractiveChanging) {
                handleLateInteractiveChange();
            }
 
            // Start input as soon as we start waking up or going to sleep.
            mInputManagerInternal.setInteractive(interactive);
            mInputMethodManagerInternal.setInteractive(interactive);
 
            // Notify battery stats.
            try {
                mBatteryStats.noteInteractive(interactive);
            } catch (RemoteException ex) { }
 
            // Handle early behaviors.
            mInteractive = interactive;
            mInteractiveChangeReason = reason;
            mInteractiveChanging = true;
            handleEarlyInteractiveChange();
        }
    }

我们先来看handleEarlyInteractiveChange函数

private void handleEarlyInteractiveChange() {
        synchronized (mLock) {
            if (mInteractive) {
                // Waking up...
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
                        mPolicy.startedWakingUp();//调用PhoneWindowManager
                    }
                });
 
                // Send interactive broadcast.
                mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
                mPendingWakeUpBroadcast = true;
                updatePendingBroadcastLocked();//发送亮屏广播
            } else {
                // Going to sleep...
                // Tell the policy that we started going to sleep.
                final int why = translateOffReason(mInteractiveChangeReason);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mPolicy.startedGoingToSleep(why);//调用PhoneWindowManager
                    }
                });
            }
        }
    }

updatePendingBroadcastLocked发送消息处理广播,并且持锁Broadcast

private void updatePendingBroadcastLocked() {
        if (!mBroadcastInProgress
                && mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN
                && (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
                        || mPendingInteractiveState != mBroadcastedInteractiveState)) {
            mBroadcastInProgress = true;
            mSuspendBlocker.acquire();//持锁
            Message msg = mHandler.obtainMessage(MSG_BROADCAST);
            msg.setAsynchronous(true);
            mHandler.sendMessage(msg);
        }
    }

六、finishWakefulnessChangeIfNeededLocked

在PowerManagerService的updatePowerState中会调用finishWakefulnessChangeIfNeededLocked函数,这个函数最后调用了mNotifier.onWakefulnessChangeFinished

 private void finishWakefulnessChangeIfNeededLocked() {
        if (mWakefulnessChanging && mDisplayReady) {
            if (mWakefulness == WAKEFULNESS_DOZING
                    && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
                return; // wait until dream has enabled dozing
            }
            mWakefulnessChanging = false;
            mNotifier.onWakefulnessChangeFinished();
        }
    }

onWakefulnessChangeFinished函数:

public void onWakefulnessChangeFinished() {
        if (mInteractiveChanging) {
            mInteractiveChanging = false;
            handleLateInteractiveChange();
        }
    }

这个函数调用了handleLateInteractiveChange函数

private void handleLateInteractiveChange() {
        synchronized (mLock) {
            if (mInteractive) {
                // Finished waking up...
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mPolicy.finishedWakingUp();//PhoneWindowManager的finish wakeingUp
                    }
                });
            } else {
                // Finished going to sleep...
                // This is a good time to make transitions that we don't want the user to see,
                // such as bringing the key guard to focus.  There's no guarantee for this
                // however because the user could turn the device on again at any time.
                // Some things may need to be protected by other mechanisms that defer screen on.
 
                // Cancel pending user activity.
                if (mUserActivityPending) {
                    mUserActivityPending = false;
                    mHandler.removeMessages(MSG_USER_ACTIVITY);
                }
 
                // Tell the policy we finished going to sleep.
                final int why = translateOffReason(mInteractiveChangeReason);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
                        mPolicy.finishedGoingToSleep(why);// phoneWindowManager的finsh goToSleep
                    }
                });
 
                // Send non-interactive broadcast.
                mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
                mPendingGoToSleepBroadcast = true;
                updatePendingBroadcastLocked();//发送广播
            }
        }
    }

这第五和第六需要结合起来看,onWakefulnessChangeStarted是刚设置状态,onWakefulnessChangeFinished是设置状态结束了。onWakefulnessChangeStarted函数中先调用handleEarlyInteractiveChange,然后onWakefulnessChangeFinished调用handleLateInteractiveChange,并且用mInteractiveChanging变量来控制。
而handleEarlyInteractiveChange处理亮屏,先发广播调用mPolicy.startedWakingUp,然后在handleLateInteractiveChange函数中mPolicy.finishedWakingUp

而处理灭屏事件,现在handleEarlyInteractiveChange函数中mPolicy.startedGoingToSleep,然后在handleLateInteractiveChange函数中mPolicy.finishedGoingToSleep,然后发送灭屏广播。

七、总结

我们主要在这篇博客分析了,PowerManagerService的各个状态变化后用Notifier类做一些通知,比如发送广播,通知PhoneWindowManager,AMS的一些接口等。

 类似资料: