关键词不能为空

当前您在: 主页 > 英语 >

and5.1PowerManagerService深入分析(二)PowerManager中各函数

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-13 16:02
tags:

-

2021年2月13日发(作者:盎)


and5.1PowerManagerService


深入分析


(二)


PowerManager


中各函数< /p>



今天主要从


PowerManager


中的接口入手去分析


PowerManagerService .


先分析


PowerManager


中的一个内部类


WakeLock


,可以使用这个类持睡眠锁。



下面是


PowerManager< /p>



WakeLock


内部类来里面的代码 :



[java] view plain copy


public void acquire() {









synchronized (mToken) {













acquireLocked();









}





}








/**





* Acquires the wake lock with a timeout.





*





* Ensures that the device is on at the level requested when





* the wake lock was created.



The lock will be released after the given timeout





* expires.





*





*





* @param timeout The timeout after which to release the wake lock, in milliseconds.





*/





public void acquire(long timeout) {









synchronized (mToken) {













acquireLocked();













layed(mReleaser, timeout);//


利用消息机制做一个


timeout


的持锁,

< br>mReleaser


中是对该锁释放了










}





}








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.













Callbacks(mReleaser);













raceBegin(_TAG_POWER, mTraceName, 0);













try {

















eWakeLock(mToken,


mFlags,


mTag,


mPackageName,

< br>mWorkSource,//


调用


PMS



acquireWakeLock

























mHistoryTag);













} catch (RemoteException e) {













}













mHeld = true;









}





}






PMS




acq uireWakeLock
















< br>就




acquireWake LockInternal


函数。



[java] view plain copy


@Override // Binder call




public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,












WorkSource ws, String historyTag) {








if (lock == null) {












throw new IllegalArgumentException(








}








if (packageName == null) {












throw new IllegalArgumentException(








}








teWakeLockParameters(flags, tag);











eCallingOrSelfPermission(_LOCK,


null);








if ((flags & _W


AKE_LOCK) != 0) {












eCallingOrSelfPermission(




















_POWER, null);








}








if (ws != null && () != 0) {












eCallingOrSelfPermission(




















_DEVICE_STATS, null);








} else {












ws = null;








}











final int uid = lingUid();








final int pid = lingPid();








final long ident = allingIdentity();








try {












acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);








} finally {












eCallingIdentity(ident);








}




}




ac quireWakeLockInternal


函数



[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) {












if (DEBUG_SPEW) {
















Slog.d(TAG


,
























+
























+












}















WakeLock wakeLock;












int index = fin dWakeLockIndexLocked(lock);//


查找这个


IBinder


的锁。因为每个应用


都是一个进程, 通过


binder


通信与


PMS


交互。


IBinder


是唯一的













boolean notifyAcquire;












if (index >= 0) {//


找到

















wakeLock = (index);
















if


(!eProperties(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);




















Properties(flags,


tag,


packageName,


ws,


historyTag,


uid,


pid);
















}
















notifyAcquire = false;












} else {//


没找到

















wakeLock


=


new


WakeLock(lock,


flags,


tag,


packageName,


ws,


historyTag,


uid,


pid);//


新建一个


WakeLock

加入列表

















try {




















Death(wakeLock, 0);
















} catch (RemoteException ex) {




















throw new IllegalArgumentException(
















}
















(wakeLock);
















notifyAcquire = true;












}















app lyWakeLockFlagsOnAcquireLocked(wakeLock, uid);//


下面详细分析













mDirty |= DIRTY_WAKE_LOCKS;//mDirty


标志位置位













updatePowerStateLocked();//


更新


power


状态

< br>












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.
















notifyWakeLockAcquiredLocke d(wakeLock);//


通知电池统计那块













}








}




}




fi ndWakeLockIndexLocked


函数



[java] view plain copy


private int findWakeLockIndexLocked(IBinder lock) {








final int count = ();








for (int i = 0; i < count; i++) {












if ((i).mLock == lock) {
















return i;












}








}








return -1;




}




ap plyWakeLockFlagsOnAcquireLocked


函数



[java] view plain copy


private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, int uid) {








if


((


&


E_CAUSES_WAKEUP)


!=

< br>0//


如果持的


锁有


ACQUI RE_CAUSES_WAKEUP


,还有屏幕锁的话,会


wa keup


设备

















&& isScreenLock(wakeLock)) {












wakeUpNoUpdateLocked(Millis(), uid);








}




}




[java] view plain copy


@SuppressWarnings(




private static boolean isScreenLock(final WakeLock wakeLock) {








switch ( & PowerManager.W


AKE_LOCK_LEVEL_MASK) {












case _WAKE_LOCK:












case _BRIGHT_W


AKE_LOCK:












case _DIM_WAKE_LOCK:
















return true;








}








return false;




}




up datePowerStateLocked


这个函数是所有的地方都会调用,因此我们 最后分析。




下面看下释放锁,


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


,




























+
















}
















return;












}















WakeLock wakeLock = (index);












if (DEBUG_SPEW) {
















Slog.d(TAG


,
























+












}















if ((flags & E_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) {
















mRequestWaitForNegativeProximity = true;//


和距离传感器有关













}















ToDeath(wakeLock, 0);












removeWakeLockLocked(wakeLock, index);








}




}



< /p>


removeWakeLockLocked


函数



[java] view plain copy


private void removeWakeLockLocked(WakeLock wakeLock, int index) {








(index);//


列表中去除









notifyWakeLockR eleasedLocked(wakeLock);//


通知电池统计












applyWakeLockFl agsOnReleaseLocked(wakeLock);








mDirty |= DIRTY_W


AKE_LOCKS;//mDirty


置标志位









updatePowerStateLocked();




}



< /p>


applyWakeLockFlagsOnReleaseLocked


函数



[java] view plain copy


private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {








if (( & _AFTER_RELEASE) != 0//


当有这个标志位的


锁,释放的时候。需要触发


useractivity

< br>,因此会延长亮屏时间

















&& isScreenLock(wakeLock)) {//


是否是屏幕锁













userActivityNoUpdateLocked( Millis(),//


触发


userActivity


事件,



面详细分析





















_ACTIVITY_EVENT_OTHER,




















_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,




















Uid);








}




}





接下来我们来分析下


gotoSle ep


函数:



调用

PowerManger



gotoSleep

< p>
函数,最后会到


PMS



goToSleepInternal


函数



[java] view plain copy


private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {








synchronized (mLock) {












if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {
















updatePowerStateLocked();












}








}




}




goToSleepNoUpda teLocked


函数



[java] view plain copy


private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {








if (DEBUG_SPEW) {












Slog.d(TAG


,




















+








}











if (eventTime < mLastWakeTime//


如果时间不对,状态已经是


W


AKEFULNESS_ASLEEP


或者

W


AKEFULNESS_DOZING


,或者系统没准备 好直接出去

















|| mWakefulness == W


AKEFULNESS_ASLEEP
















|| mWakefulness == W


AKEFULNESS_DOZING
















|| !mBootCompleted || !mSystemReady) {












return false;








}











egin(_TAG_POWER,








try {












switch (reason) {//


打印下原因

















case _TO_SLEEP_REASON_DEVICE_ADMIN:




















Slog.i(TAG


,




























+




















break;
















case _TO_SLEEP_REASON_TIMEOUT:




















Slog.i(TAG


,




















break;
















case _TO_SLEEP_REASON_LID_SWITCH:




















Slog.i(TAG


,




















break;
















case _TO_SLEEP_REASON_POWER_BUTTON:




















Slog.i(TAG


,




















break;
















case _TO_SLEEP_REASON_HDMI:




















Slog.i(TAG


,




















break;
















default:




















Slog.i(TAG


,




















reason = _TO_SLEEP_REASON_APPLICATION;




















break;












}















mLastSleepTime = eventTime;












mSandmanSummoned = true;//


和做梦有关













setWakefulnessLocked(W

< p>
AKEFULNESS_DOZING, reason);//


设置


mWakefulness


的状

















// Report the number of wake locks that will be cleared by going to sleep.












int numWakeLocksCleared = 0;












final int numWakeLocks = ();












for (int i = 0; i < numWakeLocks; i++) {
















final WakeLock wakeLock = (i);
















switch ( & _LOCK_LEVEL_MASK) {




















case _WAKE_LOCK:




















case _BRIGHT_WAKE_LOCK:




















case _DIM_WAKE_LOCK:
























numWakeLocksCleared += 1;
























break;
















}












}












vent(_SLEEP_REQUESTED,


numWa keLocksCleared);//


打印当前屏幕锁的个数
















// Skip dozing if requested.












if ((flags & _TO_SLEEP_FLAG_NO_DOZE) != 0) {//


如果


flags



这个状态, 直接睡眠

















reallyGoToSleepNoUpdateLocked(eventTime, uid);












}








} finally {












nd(_TAG_POWER);








}








return true;




}



< /p>


我们先看下


setWakefulnessLocked


函数:



[java] view plain copy


private void setWakefulnessLocked(int wakefulness, int reason) {








if (mWakefulness != wakefulness) {












finishWakefulnessChangeLocked();















mWakefulness = wakefulness; //



mWakefulness


赋值













mWakefulnessChanging = true;












mDirty |= DIRTY_WAKEFULNESS;//mDirty


置位













fulnessChangeStarted(wakefulness,

< p>
reason);//










onWakefulnessChangeStarted








}




}







private void finishWakefulnessChangeLocked() {








if (mWakefulnessChanging) {












fulnessChangeFinished(mWakefulness);












mWakefulnessChanging = false;








}




}



< /p>


然后我们看下


notifier



onWakefulnessChangeStarted


函数



[java] view plain copy


public void onWakefulnessChangeStarted(int wakefulness, int reason) {








if (DEBUG) {












Slog.d(TAG


,




















+








}











// We handle interactive state changes once they start so that the system can








// set everything up or the user to begin interacting with applications.








final boolean interactive = ractive(wakefulness);








if (interactive) {












handleWakefulnessChange(wakefulness, interactive, reason);//


如果当前是要点亮屏幕









} else {












mLastReason = reason;








}











// Start input as soon as we start waking up or going to sleep.








eractive(interactive);//



InputmanagerService


中去调用


JNI



没细跟





}





onW akefulnessChangeFinished


函数都是调用

handleWakefulnessChange


只是


i nteractive



数相反



[java] view plain copy


public void onWakefulnessChangeFinished(int wakefulness) {








if (DEBUG) {












Slog.d(TAG


,



-


-


-


-


-


-


-


-



本文更新与2021-02-13 16:02,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/651175.html

and5.1PowerManagerService深入分析(二)PowerManager中各函数的相关文章

and5.1PowerManagerService深入分析(二)PowerManager中各函数随机文章