我们按下电源键就会灭屏,再按一下就会唤醒屏幕,这个是怎样的过程呢。
电源键有许多额外功能,为了能让这个主题更加清晰,额外代码尽量不去分析,另外这篇文章主要是跟踪代码,所以也会贴出更全的源码,帮助分析
首先, PhoneWindowManager.java 会有对Power按键的拦截:
case KeyEvent.KEYCODE_POWER: {
// Any activity on the power button stops the accessibility shortcut
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
//按下亮屏,抬起灭屏 我们同样可以在自己的手机上得到这种结果
if (down) {//按下亮屏
interceptPowerKeyDown(event, interactive);
} else {//抬起灭屏
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
那看起来,主要逻辑就是 interceptPowerKeyDown 与 interceptPowerKeyUp了。
interceptPowerKeyDown 按下过程:
....
if (!mPowerKeyHandled) {//当按键没有被处理
if (interactive) {//交互活动状态
// When interactive, we're already awake.
// Wait for a long press or for the button to be released to decide what to do.
if (hasLongPressOnPowerBehavior()) {
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,
ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
}
} else {
//这个方法,可以放在其他按键的down事件中,也可以起到唤醒屏幕的作用
//当然也可以用PowerManager.ACQUIRE_CAUSES_WAKEUP|PowerManager.SCREEN_DIM_WAKE_LOCK 结合亮屏
wakeUpFromPowerKey(event.getDownTime()); //关键点:唤醒
//长按
if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,
ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
mBeganFromNonInteractive = true;
} else { //多次按
final int maxCount = getMaxMultiPressPowerCount();
if (maxCount <= 1) {
mPowerKeyHandled = true;
} else {
mBeganFromNonInteractive = true;
}
}
}
}
..........
我们看到了wakeUpFromPowerKey 这个方法是唤醒动作
private void wakeUpFromPowerKey(long eventTime) {
wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER");
}
再继续
private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) {
final boolean theaterModeEnabled = isTheaterModeEnabled();
if (!wakeInTheaterMode && theaterModeEnabled) {
return false;
}
if (theaterModeEnabled) {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0);
}
mPowerManager.wakeUp(wakeTime, reason);//关键点
return true;
}
这个 mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
继续跟进到 PowerManager.java 里面的方法大都是 PowerManagerService的实现
public void wakeUp(long time) {
try {
mService.wakeUp(time, "wakeUp", mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
PowerManagerService
@Override // Binder call
public void wakeUp(long eventTime, String reason, String opPackageName) {
if (eventTime > SystemClock.uptimeMillis()) {
throw new IllegalArgumentException("event time must not be in the future");
}
//检查调用者是否有DEVICE_POWER 权限 Not for use by third-party applications.
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
wakeUpInternal(eventTime, reason, uid, opPackageName, uid); //关键点
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private void wakeUpInternal(long eventTime, String reason, int uid, String opPackageName,
int opUid) {
synchronized (mLock) {
if (wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {// 通知消息
updatePowerStateLocked(); //更新电池状态
}
}
}
private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,
String opPackageName, int opUid) {
.....
setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);
return true;
}
@VisibleForTesting
void setWakefulnessLocked(int wakefulness, int reason) {
if (mWakefulness != wakefulness) {
.....
if (mNotifier != null) { //wakefulness = WAKEFULNESS_AWAKE
mNotifier.onWakefulnessChangeStarted(wakefulness, reason);//通知状态改变
}
}
}
Notifier.java
/**
* Notifies that the device is changing wakefulness.
* This function may be called even if the previous change hasn't finished in
* which case it will assume that the state did not fully converge before the
* next transition began and will recover accordingly.
*/
public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
// Tell the activity manager about changes in wakefulness, not just interactivity.
// It needs more granularity than other components.
mHandler.post(new Runnable() {
@Override
public void run() {
mActivityManagerInternal.onWakefulnessChanged(wakefulness);// 更新awake状态
}
});
if (mInteractive != interactive) {
// Finish up late behaviors if needed.
if (mInteractiveChanging) {//更改为true才会继续[2]
handleLateInteractiveChange(); // 唤醒后更新唤醒状态信息
}
......
mInteractiveChanging = true; // 这一步先执行了 handleLateInteractiveChange 才会执行[1]
handleEarlyInteractiveChange();//开始唤醒
}
}
/**
* Handle early interactive state changes such as getting applications or the lock
* screen running and ready for the user to see (such as when turning on the screen).
*/
private void handleEarlyInteractiveChange() {
synchronized (mLock) {
if (mInteractive) {
// Waking up...
mHandler.post(new Runnable() {
@Override
public void run() {
// Note a SCREEN tron event is logged in PowerManagerService.
//mPolicy 是 WindowManagerPolicy 而PhoneWindowManager 是其实现
mPolicy.startedWakingUp(); //我们的跟踪点
}
});
// Send interactive broadcast.
mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
mPendingWakeUpBroadcast = true;
updatePendingBroadcastLocked();
} else { //这部分代码包含了 go to sleep的过程也可以看看
// 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);
}
});
}
}
}
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
// Called on the PowerManager's Notifier thread.
@Override
public void startedWakingUp() { //唤醒屏幕
EventLog.writeEvent(70000, 1);
if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up...");
// Since goToSleep performs these functions synchronously, we must
// do the same here. We cannot post this work to a handler because
// that might cause it to become reordered with respect to what
// may happen in a future call to goToSleep.
synchronized (mLock) {
mAwake = true;
updateWakeGestureListenerLp(); //根据awake状态 处理手势sensor监听
updateOrientationListenerLp(); //根据awake状态 处理 OrientationSensor 监听
updateLockScreenTimeout(); //锁屏处理
}
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onStartedWakingUp(); //状态栏变化 以及相关唤醒相关回调
}
}
我们再回到 PMS的wakeUpInternal
if (wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {// 上面跟踪完了
updatePowerStateLocked(); //再从这里开始
}
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
/**
* Updates the global power state based on dirty bits recorded in mDirty.
*
* This is the main function that performs power state transitions.
* We centralize them here so that we can recompute the power state completely
* each time something important changes, and ensure that we do it the same
* way each time. The point is to gather all of the transition logic here.
*/
protected 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.
updateIsPoweredLocked(mDirty);//更新电池基本信息:是否充电,插入,电量
updateStayOnLocked(mDirty); //更新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;
//通过PowerManager.WAKE_LOCK_LEVEL_MASK 这个Mask 更新mWakeLockSummary的值,
//后面会根据这个值影响display显示
updateWakeLockSummaryLocked(dirtyPhase1);
// Updates the value of mUserActivitySummary to summarize the user requested
// state of the system such as whether the screen should be bright or dim.
// Note that user activity is ignored when the system is asleep.
updateUserActivitySummaryLocked(now, dirtyPhase1);
if (!updateWakefulnessLocked(dirtyPhase1)) {
break;
}
}
// Phase 2: Update display power state.
boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);//更新屏幕显示亮屏
// Phase 3: Update dream state (depends on display ready signal).
updateDreamLocked(dirtyPhase2, displayBecameReady);
// Phase 4: Send notifications, if needed.
finishWakefulnessChangeIfNeededLocked();// 关键点:发送唤醒通知
// 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(); //激活hal层 以及cpu
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
/**
* Updates the display power state asynchronously.
* When the update is finished, mDisplayReady will be set to true. The display
* controller posts a message to tell us when the actual display power state
* has been updated so we come back here to double-check and finish up.
*
* This function recalculates the display power state each time.
*
* @return True if the display became ready.
*/
private boolean updateDisplayPowerStateLocked(int dirty) {
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(); //更新亮屏policy为POLICY_BRIGHT
.........
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
mRequestWaitForNegativeProximity);//跳转到DisplayManagerService 显示的一些逻辑处理
}
int getDesiredScreenPolicyLocked() {
.......
if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
|| (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
|| !mBootCompleted
|| mScreenBrightnessBoostInProgress) {
return DisplayPowerRequest.POLICY_BRIGHT; //更新policy
}
.......
}
frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
@Override
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
return mDisplayPowerController.requestPowerState(request,
waitForNegativeProximity);//DisplayPowerController
}
frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
/**
* Requests a new power state.
* The controller makes a copy of the provided object and then
* begins adjusting the power state to match what was requested.
*
* @param request The requested power state.
* @param waitForNegativeProximity If true, issues a request to wait for
* negative proximity before turning the screen back on, assuming the screen
* was turned off by the proximity sensor.
* @return True if display is ready, false if there are important changes that must
* be made asynchronously (such as turning the screen on), in which case the caller
* should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
* then try the request again later until the state converges.
*/
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
.....
if (changed && !mPendingRequestChangedLocked) {
mPendingRequestChangedLocked = true;
sendUpdatePowerStateLocked(); //实际上就是个handler发送消息处理
}
......
}
private void sendUpdatePowerStateLocked() {
if (!mPendingUpdatePowerStateLocked) {
mPendingUpdatePowerStateLocked = true;
Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
}
}
.....
case MSG_UPDATE_POWER_STATE:
updatePowerState();
break;
.....
private void updatePowerState() {
//这个方法太长就不贴了 其中包括更新Proximity sensor信息
//重置动画信息, 更新屏幕状态 state = Display.STATE_OFF/STATE_ON 等等
//还有一些对autoBrightness, lowPowerMode的处理, 还有屏幕亮度变化的动画过程
// Animate the screen state change unless already animating.
// The transition may be deferred, so after this point we will use the
// actual state instead of the desired one.
final int oldState = mPowerState.getScreenState();
animateScreenStateChange(state, performScreenOffTransition); //动画处理亮屏幕
state = mPowerState.getScreenState();
}
//这个方法主要跟踪setScreenState 屏幕状态变化
private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
......
if (mDisplayBlanksAfterDozeConfig
&& Display.isDozeState(mPowerState.getScreenState())
&& !Display.isDozeState(target)) {
// Some display hardware will blank itself on the transition between doze and non-doze
// but still on display states. In this case we want to report to policy that the
// display has turned off so it can prepare the appropriate power on animation, but we
// don't want to actually transition to the fully off state since that takes
// significantly longer to transition from.
setScreenState(Display.STATE_OFF, target != Display.STATE_OFF /*reportOnly*/);
}
// If we were in the process of turning off the screen but didn't quite
// finish. Then finish up now to prevent a jarring transition back
// to screen on if we skipped blocking screen on as usual.
if (mPendingScreenOff && target != Display.STATE_OFF) {
setScreenState(Display.STATE_OFF);
mPendingScreenOff = false;
mPowerState.dismissColorFadeResources();
}
if (target == Display.STATE_ON) {
// Want screen on. The contents of the screen may not yet
// be visible if the color fade has not been dismissed because
// its last frame of animation is solid black.
if (!setScreenState(Display.STATE_ON)) {
return; // screen on blocked
}
.........
}
private boolean setScreenState(int state) {
return setScreenState(state, false /*reportOnly*/);
}
private boolean setScreenState(int state, boolean reportOnly) {
..........
if (!reportOnly) {
mPowerState.setScreenState(state); // DisplayPowerState.setScreenState 状态变化的通知【1】
// Tell battery stats about the transition.
try {
mBatteryStats.noteScreenState(state); //电池状态信息变化
} catch (RemoteException ex) {
// same process
}
}
............
//PoneWindowManager的实现【2】
mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
}
我们先把比较短的【2】走完
public class PhoneWindowManager implements WindowManagerPolicy
.....
// Called on the DisplayManager's DisplayPowerController thread.
@Override
public void screenTurningOn(final ScreenOnListener screenOnListener) {
if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");
updateScreenOffSleepToken(false);
synchronized (mLock) {
mScreenOnEarly = true;
mScreenOnFully = false;
mKeyguardDrawComplete = false;
mWindowManagerDrawComplete = false;
mScreenOnListener = screenOnListener;
if (mKeyguardDelegate != null) {
mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,
getKeyguardDrawnTimeout()); //调用finishKeyguardDrawn(); 完成绘制
//锁屏逻辑处理
//KeyguardServiceDelegate-> KeyguardService -> KeyguardViewMediator -> StatusBarKeyguardViewManager
mKeyguardDelegate.onScreenTurningOn(mKeyguardDrawnCallback);
} else {
if (DEBUG_WAKEUP) Slog.d(TAG,
"null mKeyguardDelegate: setting mKeyguardDrawComplete.");
finishKeyguardDrawn(); //如果mKeyguardDelegate null 仍然会走到这里
}
}
}
private void finishKeyguardDrawn() {
// ... eventually calls finishWindowsDrawn which will finalize our screen turn on
// as well as enabling the orientation change logic/sensor.
mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback,
WAITING_FOR_DRAWN_TIMEOUT); //主要这个消息的处理
}
final Runnable mWindowManagerDrawCallback = new Runnable() {
@Override
public void run() {
if (DEBUG_WAKEUP) Slog.i(TAG, "All windows ready for display!");
mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE);
}
};
case MSG_WINDOW_MANAGER_DRAWN_COMPLETE:
if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mWindowManagerDrawComplete");
finishWindowsDrawn();
break;
private void finishWindowsDrawn() {
synchronized (mLock) {
if (!mScreenOnEarly || mWindowManagerDrawComplete) {
return; // Screen is not turned on or we did already handle this case earlier.
}
mWindowManagerDrawComplete = true;
}
finishScreenTurningOn();
}
private void finishScreenTurningOn() {
final ScreenOnListener listener;
final boolean enableScreen;
.....
if (listener != null) {
listener.onScreenOn(); //回调
}
if (enableScreen) {
try {
mWindowManager.enableScreenIfNeeded();
} catch (RemoteException unhandled) {
}
}
}
WindowManagerService
@Override
public void enableScreenIfNeeded() {
synchronized (mWindowMap) {
enableScreenIfNeededLocked();
}
}
void enableScreenIfNeededLocked() {
if (mDisplayEnabled) {
return;
}
if (!mSystemBooted && !mShowingBootMessages) {
return;
}
mH.sendEmptyMessage(H.ENABLE_SCREEN);
}
case ENABLE_SCREEN: {
performEnableScreen(); // 开机启动也会走到这个方法,这里包括surfaceFlinger 渲染 mInputMonitor派发,并且调用AMS的bootAnimationComplete处理
break;
}
【1】我们再来看看电亮屏幕的过程
frameworks/base/services/core/java/com/android/server/display/DisplayPowerState.java
/**
* Sets whether the screen is on, off, or dozing.
*/
public void setScreenState(int state) {
if (mScreenState != state) {
if (DEBUG) {
Slog.d(TAG, "setScreenState: state=" + state);
}
mScreenState = state;
mScreenReady = false;
scheduleScreenUpdate();//通过handler另起一个线程处理
}
}
private void scheduleScreenUpdate() {
if (!mScreenUpdatePending) {
mScreenUpdatePending = true;
postScreenUpdateThreadSafe();
}
}
private void postScreenUpdateThreadSafe() {
mHandler.removeCallbacks(mScreenUpdateRunnable);
mHandler.post(mScreenUpdateRunnable);
}
private final Runnable mScreenUpdateRunnable = new Runnable() {
@Override
public void run() {
mScreenUpdatePending = false;
int brightness = mScreenState != Display.STATE_OFF
&& mColorFadeLevel > 0f ? mScreenBrightness : 0;
//关键点, 通过mPhotonicModulator 更新状态
if (mPhotonicModulator.setState(mScreenState, brightness)) {
if (DEBUG) {
Slog.d(TAG, "Screen ready");
}
mScreenReady = true;
invokeCleanListenerIfNeeded();
} else {
if (DEBUG) {
Slog.d(TAG, "Screen not ready");
}
}
}
};
//通过PhotonicModulator是个线程并且是DisplayPowerState的子类,这里主要更新状态的处理
public boolean setState(int state, int backlight) {
synchronized (mLock) {
boolean stateChanged = state != mPendingState;
boolean backlightChanged = backlight != mPendingBacklight;
if (stateChanged || backlightChanged) {
if (DEBUG) {
Slog.d(TAG, "Requesting new screen state: state="
+ Display.stateToString(state) + ", backlight=" + backlight);
}
mPendingState = state;
mPendingBacklight = backlight;//我们找到了背光,这个在哪里用呢?
boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
mStateChangeInProgress = stateChanged || mStateChangeInProgress;
mBacklightChangeInProgress = backlightChanged || mBacklightChangeInProgress;
if (!changeInProgress) {
mLock.notifyAll();
}
}
return !mStateChangeInProgress;
}
}
//再来看看DisplayPowerState 的构造函数, 原来PhotonicModulator在初始化的时候就一直在后台运行,
//只要setState状态变化,就会触发一些机制
public DisplayPowerState(DisplayBlanker blanker, ColorFade colorFade) {
mHandler = new Handler(true /*async*/);
mChoreographer = Choreographer.getInstance();
mBlanker = blanker;
mColorFade = colorFade;
mPhotonicModulator = new PhotonicModulator();
mPhotonicModulator.start();//跑起来了
}
//我们再看看 PhotonicModulator 这个线程的run方法
@Override
public void run() {
for (;;) {
// Get pending change.
final int state;
final boolean stateChanged;
final int backlight;
final boolean backlightChanged;
synchronized (mLock) {
state = mPendingState;
stateChanged = (state != mActualState);
backlight = mPendingBacklight; //用到了刚才的背光
backlightChanged = (backlight != mActualBacklight);
if (!stateChanged) {
// State changed applied, notify outer class.
postScreenUpdateThreadSafe();
mStateChangeInProgress = false;
}
if (!backlightChanged) {
mBacklightChangeInProgress = false;
}
if (!stateChanged && !backlightChanged) {
try {
mLock.wait();
} catch (InterruptedException ex) { }
continue;
}
mActualState = state;
mActualBacklight = backlight;
}
// Apply pending change.
if (DEBUG) {
Slog.d(TAG, "Updating screen state: state="
+ Display.stateToString(state) + ", backlight=" + backlight);
}
//DisplayBlanker是个接口 在DisplayManagerService的 子类LocalService 会有它的实现
mBlanker.requestDisplayState(state, backlight);//关键步骤 继续走下去
}
}
LocalService 的实现:
private final class LocalService extends DisplayManagerInternal {
@Override
public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager) {
synchronized (mSyncRoot) {
DisplayBlanker blanker = new DisplayBlanker() {
@Override
public void requestDisplayState(int state, int brightness) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness);
}
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness);
}
}
};
mDisplayPowerController = new DisplayPowerController(
mContext, callbacks, handler, sensorManager, blanker);
}
}
.............
}
private void requestGlobalDisplayStateInternal(int state, int brightness) {
if (state == Display.STATE_UNKNOWN) {
state = Display.STATE_ON;
}
if (state == Display.STATE_OFF) {
brightness = PowerManager.BRIGHTNESS_OFF;
} else if (brightness < 0) {
brightness = PowerManager.BRIGHTNESS_DEFAULT;
} else if (brightness > PowerManager.BRIGHTNESS_ON) {
brightness = PowerManager.BRIGHTNESS_ON;
}
synchronized (mTempDisplayStateWorkQueue) {
......
synchronized (mSyncRoot) {
if (mGlobalDisplayState == state
&& mGlobalDisplayBrightness == brightness) {
return; // no change
}
Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
+ Display.stateToString(state)
+ ", brightness=" + brightness + ")");
mGlobalDisplayState = state;
mGlobalDisplayBrightness = brightness;
applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);//继续跟踪
}
........
}
private void applyGlobalDisplayStateLocked(List workQueue) {
final int count = mDisplayDevices.size();
for (int i = 0; i < count; i++) {
DisplayDevice device = mDisplayDevices.get(i);
Runnable runnable = updateDisplayStateLocked(device);
if (runnable != null) {
workQueue.add(runnable); //队列处理
}
}
}
private Runnable updateDisplayStateLocked(DisplayDevice device) {
// Blank or unblank the display immediately to match the state requested
// by the display power controller (if known).
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
//DisplayDevice 是一个接口他的实现在LocalDisplayAdapter的子类LocalDisplayDevice中
return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
}
return null;
}
frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
//这部分代码很多 主要是亮度的状态的处理 还包括vr的一些逻辑 我们看主要的
@Override
public Runnable requestDisplayStateLocked(final int state, final int brightness) {
// Defer actually setting the display state until after we have exited
// the critical section since it can take hundreds of milliseconds
// to complete.
return new Runnable() {
@Override
public void run() {
// Apply brightness changes given that we are in a non-suspended state.
if (brightnessChanged || vrModeChange) {
setDisplayBrightness(brightness);//主要跟踪逻辑
}
// Enter the final desired state, possibly suspended.
if (state != currentState) {
setDisplayState(state);
}
}
private void setDisplayBrightness(int brightness) {
try {
mBacklight.setBrightness(brightness); //就是这里了
Trace.traceCounter(Trace.TRACE_TAG_POWER,
"ScreenBrightness", brightness);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
};
}
return null;
}
LocalDisplayAdapter.java
构造函数中初始化了 mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
并且在 requestDisplayStateLocked(); 中调用 mBacklight.setBrightness(brightness);
frameworks/base/services/core/java/com/android/server/lights/LightsService.java
找到setBrightness的实现:
@Override
public void setBrightness(int brightness) {
setBrightness(brightness, BRIGHTNESS_MODE_USER);
}
@Override
public void setBrightness(int brightness, int brightnessMode) {
synchronized (this) {
........
int color = brightness & 0x000000ff;
color = 0xff000000 | (color << 16) | (color << 8) | color;
setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
}
}
private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
..........
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"
+ Integer.toHexString(color) + ")");
try {
setLight_native(mId, color, mode, onMS, offMS, brightnessMode);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
}
最终是调用native方法 setLight_native
继续跟踪到JNI
frameworks/base/services/core/jni/com_android_server_lights_LightsService.cpp
static void setLight_native(
JNIEnv* /* env */,
jobject /* clazz */,
jint light,
jint colorARGB,
jint flashMode,
jint onMS,
jint offMS,
jint brightnessMode) {
sp hal = LightHal::associate();
Type type = static_cast(light);
LightState state = constructState(
colorARGB, flashMode, onMS, offMS, brightnessMode);
{
//通过LightHal调用setLight
android::base::Timer t; Return ret = hal->setLight(type, state);
processReturn(ret, type, state);
}
}
继续往下,我们跟到了hardware
hardware/interfaces/light/2.0/default/Light.cpp
Light::Light(std::map &&lights)
: mLights(std::move(lights)) {}
// Methods from ::android::hardware::light::V2_0::ILight follow.Return Light::setLight(Type type, const LightState& state) {
auto it = mLights.find(type);
...
light_device_t* hwLight = it->second;
....
int ret = hwLight->set_light(hwLight, &legacyState);
}
set_light 是调用的关键函数, 跟踪调用路径 hwLight -> it->second -> mLights 发现是一个集合,找到赋值点
通过HIDL new出集合中的对象
ILight* HIDL_FETCH_ILight(const char* /* name */) { std::map lights;
for(auto const &pair : kLogicalLights) {
Type type = pair.first;
const char* name = pair.second;
light_device_t* light = getLightDevice(name);
}
....
return new Light(std::move(lights));
}
集合:
const static std::map kLogicalLights = {
{Type::BACKLIGHT, LIGHT_ID_BACKLIGHT},
{Type::KEYBOARD, LIGHT_ID_KEYBOARD},
{Type::BUTTONS, LIGHT_ID_BUTTONS},
{Type::BATTERY, LIGHT_ID_BATTERY},
{Type::NOTIFICATIONS, LIGHT_ID_NOTIFICATIONS},
{Type::ATTENTION, LIGHT_ID_ATTENTION},
{Type::BLUETOOTH, LIGHT_ID_BLUETOOTH},
{Type::WIFI, LIGHT_ID_WIFI}
};
LIGHT_ID_BACKLIGHT在hardware/libhardware/include/hardware/lights.h 有声明
#define LIGHT_ID_BACKLIGHT "backlight"
继续跟踪LIGHT_ID_BACKLIGHT
在hardware/qcom/display/liblight/lights.c 我们发现
/** Open a new instance of a lights device using name */
static int open_lights(const struct hw_module_t* module, char const* name,
struct hw_device_t** device)
{
// 设置对应name的led节点
if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {
.......
set_light = set_light_backlight;
} else if (0 == strcmp(LIGHT_ID_BATTERY, name))
set_light = set_light_battery;
else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
set_light = set_light_notifications;
else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) {
.......
dev->set_light = set_light;
return 0;
}
static int set_light_backlight(struct light_device_t* dev,
struct light_state_t const* state)
{
...
g_last_backlight_mode = state->brightnessMode;
if (!err) {
if (!access(LCD_FILE, F_OK)) {
err = write_int(LCD_FILE, brightness);//背光节点
} else {
err = write_int(LCD_FILE2, brightness);
}
}
...........
pthread_mutex_unlock(&g_lock);
return err;
}
char const*const LCD_FILE
= "/sys/class/leds/lcd-backlight/brightness";//最终作用的节点
char const*const LCD_FILE2
= "/sys/class/backlight/panel0-backlight/brightness";
char const*const BUTTON_FILE
= "/sys/class/leds/button-backlight/brightness";
char const*const PERSISTENCE_FILE
= "/sys/class/graphics/fb0/msm_fb_persist_mode";
代码还是比较枯燥的,很难沉下心分析,但是还是有收获。
总结:
1. PhonewindowManger 对按键的拦截,以及后续对startedWakingUp的调用
2. PowerManagerService 对电池状态的更新和消息通知
3. DisplayPowerController与DisplayManagerService 对显示的逻辑处理
4. LightsService通过jni 触发底层亮屏
网友评论