日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android7.0 PowerManagerService(2) WakeLock的使用及流程

發布時間:2025/3/15 Android 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android7.0 PowerManagerService(2) WakeLock的使用及流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作為移動終端,電量是一種稀缺資源,需要盡可能的節省。于是,Android系統在空閑時,會主動進入到休眠狀態。?
我們知道整個Android系統中運行著很多個進程,因此必須有一種機制能夠知道每個進程是否正在進行重要的工作,只有這樣Android系統才能對整個終端當前的狀態做出判斷。

顯然我們不能啟動一個進程,去主動監管其它所有進程的工作狀態,這樣CPU開銷太大,反而加劇了電量的消耗。為此Android引入了基于WakeLock的電量管理機制,而PMS就是專門負責管理WakeLock的進程。

個人覺得WakeLock機制的思想,有點類似于早期通信領域局域網中的令牌環機制。當局域網中有設備需要發送數據時,需要申請令牌(Token),申請到令牌才能發送數據;設備發送完數據后,再釋放掉令牌。

與此相似,Android設備中運行的進程需要使用電量資源時,也需要向PMS申請一個WakeLock;當工作完成后,就釋放掉申請的WakeLock。PMS通過判斷當前是否還有進程持有WakeLock,就能得出系統是否空閑的結論。

從這里也可以看出,當我們寫一個永不停止工作的線程,但不申請WakeLock時,系統仍然可以休眠。在休眠時,CPU不會再耗費資源去調度該線程,于是“永不停止工作”被打上了引號。

接下來,我們就來看看PMS中的WakeLock。

一、創建WakeLock?
我們以RIL.java為例,看看一般情況下,PMS以外的其它進程如何使用WakeLock。?
在RIL.java的構造函數中:

public RIL(Context context, int preferredNetworkType,int cdmaSubscription, Integer instanceId) {.............PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);//獲取WakeLock,第一個參數決定了WakeLock的等級和flagmWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_LOG_TAG);//默認WakeLocked會ReferenceCounted,即一次申請對應一次釋放//設為false后,一次釋放就可以對應所有的申請mWakeLock.setReferenceCounted(false);...........//RIL.java中自己維護了WakeLockCountmWakeLockCount = 0;........... }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

從上面的代碼,可以看出調用PowerManager的newWakeLock函數,可以創建出WakeLock。

我們看看newWakeLock函數定義:

public WakeLock newWakeLock(int levelAndFlags, String tag) {//檢查參數有效性,即levelAndFlags必須對應于PowerManager中定義的WakeLock級別和flag,tag不能為空validateWakeLockParameters(levelAndFlags, tag);//此WakeLock為PowerManager定義的內部類return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName()); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

1、WakeLock Level?
newWakeLock中的第一個參數對應于WakeLock的級別和標志位構成的位圖。?
目前,在PowerManger中一共為WakeLock定義了7種level。

/** * Wake lock level: Ensures that the CPU is running; the screen and keyboard * backlight will be allowed to go off. * * If the user presses the power button, then the screen will be turned off * but the CPU will be kept on until all partial wake locks have been released. * / public static final int PARTIAL_WAKE_LOCK = 0x00000001;/** * Wake lock level: Ensures that the screen is on (but may be dimmed); * the keyboard backlight will be allowed to go off. * * If the user presses the power button, then the SCREEN_DIM_WAKE_LOCK will be * implicitly released by the system, causing both the screen and the CPU to be turned off. */ @Deprecated public static final int SCREEN_DIM_WAKE_LOCK = 0x00000006;/** * Wake lock level: Ensures that the screen is on at full brightness; * the keyboard backlight will be allowed to go off. * *If the user presses the power button, then the SCREEN_BRIGHT_WAKE_LOCK will be * implicitly released by the system, causing both the screen and the CPU to be turned off. */ @Deprecated public static final int SCREEN_BRIGHT_WAKE_LOCK = 0x0000000a;/** * Wake lock level: Ensures that the screen and keyboard backlight are on at * full brightness. * *If the user presses the power button, then the FULL_WAKE_LOCK will be * implicitly released by the system, causing both the screen and the CPU to be turned off. */ @Deprecated public static final int FULL_WAKE_LOCK = 0x0000001a;/** * Wake lock level: Turns the screen off when the proximity sensor activates. * If the proximity sensor detects that an object is nearby, the screen turns off * immediately. Shortly after the object moves away, the screen turns on again. * * A proximity wake lock does not prevent the device from falling asleep * unlike link FULL_WAKE_LOCK, SCREEN_BRIGHT_WAKE_LOCK and SCREEN_DIM_WAKE_LOCK. * If there is no user activity and no other wake locks are held, then the device will fall asleep (and lock) as usual. * However, the device will not fall asleep while the screen has been turned off * by the proximity sensor because it effectively counts as ongoing user activity. * * Cannot be used with ACQUIRE_CAUSES_WAKEUP (WakeLock的flag). */ //例如撥號,打通后接聽電話,屏幕變黑 public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 0x00000020;/** * Wake lock level: Put the screen in a low power state and allow the CPU to suspend * if no other wake locks are held. * * This is used by the dream manager to implement doze mode. It currently * has no effect unless the power manager is in the dozing state. * / public static final int DOZE_WAKE_LOCK = 0x00000040;/** * Wake lock level: Keep the device awake enough to allow drawing to occur. * * This is used by the window manager to allow applications to draw while the * system is dozing. It currently has no effect unless the power manager is in * the dozing state. * / public static final int DRAW_WAKE_LOCK = 0x00000080;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

從上面的代碼注釋可以看出,WakeLock主要用于控制CPU、屏幕和鍵盤三大部分(當然,現在的Anroid中基本沒有鍵盤了)。?
對于PARTIAL_WAKE_LOCK、SCREEN_DIM_WAKE_LOCK、SCREEN_BRIGHT_WAKE_LOCK和FULL_WAKE_LOCK而言,不考慮Power鍵的話,隨著等級的提高,權限也相應增大,即持有高等級的鎖,能夠激活的部分越多;如果考慮Power鍵的話,PARTIAL_WAKE_LOCK可以保證CPU不休眠,反而是權限最大的。

PROXIMITY_SCREEN_OFF_WAKE_LOCK、DOZE_WAKE_LOCK和DRAW_WAKE_LOCK都是和具體場景相關的鎖。

2、WakeLock Flag?
PowerManager定義的WakeLock Flag很多,無法一一列舉,就看一下比較常用的:

/** * Wake lock flag: Turn the screen on when the wake lock is acquired. * * Normally wake locks don't actually wake the device, they just cause * the screen to remain on once it's already on. Think of the video player * application as the normal behavior. Notifications that pop up and want * the device to be on are the exception; use this flag to be like them. * * Cannot be used with PARTIAL_WAKE_LOCK. * / public static final int ACQUIRE_CAUSES_WAKEUP = 0x10000000;/** * Wake lock flag: When this wake lock is released, poke the user activity timer * so the screen stays on for a little longer. * * Will not turn the screen on if it is not already on. * * Cannot be used with PARTIAL_WAKE_LOCK. * / public static final int ON_AFTER_RELEASE = 0x20000000;..................
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

總結一下上面的內容,如下所示:?
?
WakeLock Flag一般與WakeLock Level組合使用,使用的時候參照一下注釋即可。

3、WakeLock的構造函數?
最后,我們來看看WakeLock的構造函數:

WakeLock(int flags, String tag, String packageName) {//level and flagmFlags = flags;//創建類對應的打印TagmTag = tag;//創建類的類名 mPackageName = packageName;//創建一個Binder對象//PMS將作為該Binder的客戶端監聽對應進程是否死亡mToken = new Binder();mTraceName = "WakeLock (" + mTag + ")"; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

WakeLock的構造函數中需要注意的地方是,創建了一個Binder對象。?
回憶一下RIL.java中創建WakeLock的過程,我們就知道這個Binder對象應該是創建在RIL.java所在的Phone進程中。

二、Acquire WakeLock?
從上面的分析,我們知道一個進程創建的WakeLock,實際上表明了該進程執行某個工作時對電量的需求,例如聲明該工作需要保持屏幕處于點亮狀態,或該工作需要CPU處于喚醒態等。?
因此,進程創建了WakeLock后,需要將WakeLock發送到PMS中,讓PMS明白該進程的需求。?
這種將WakeLock通知到PMS的過程,就被稱為acquire WakeLock。

同樣,我們還是以RIL.java中的使用過程舉例:

private void send(RILRequest rr) {Message msg;if (mSocket == null) {rr.onError(RADIO_NOT_AVAILABLE, null);rr.release();return;}msg = mSender.obtainMessage(EVENT_SEND, rr);//重點在這里acquireWakeLock(rr, FOR_WAKELOCK);msg.sendToTarget(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

當AP側向modem發送請求時,將要調用RIL.java的send函數。send函數將會發送消息給RILSender,后者利用socket將消息發送給rild進程。?
從上面的代碼可以看出,在發送消息給RILSender之前,調用了acquireWakeLock函數:

private void acquireWakeLock(RILRequest rr, int wakeLockType) {synchronized(rr) {.............switch(wakeLockType) {case FOR_WAKELOCK:synchronized (mWakeLock) {//調用acquire函數mWakeLock.acquire();mWakeLockCount++;mWlSequenceNum++;............}break;.........}rr.mWakeLockType = wakeLockType;} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

我們跟進一下PowerManager中WakeLock的acquire函數:

public void acquire() {synchronized (mToken) {acquireLocked();} }private void acquireLocked() {//前面已經提過,RIL.java中已經將mRefCounted置為false//如果不將mRefCounted置為false,意味著acquire和release必須一一對應//那么每個WakeLock只能acquire一次if (!mRefCounted || mCount++ == 0) {........try {mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,mHistoryTag);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}mHeld = true;} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

容易看出實際的工作流程將通過Binder通信進入到PMS中:

public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,WorkSource ws, String historyTag) {//參數和權限檢查............final int uid = Binder.getCallingUid();final int pid = Binder.getCallingPid();final long ident = Binder.clearCallingIdentity();try {acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);} finally {Binder.restoreCallingIdentity(ident);} }private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,WorkSource ws, String historyTag, int uid, int pid) {synchronized (mLock) {...........//PMS中也定義了WakeLock內部類WakeLock wakeLock;//PMS中維持了一個ArrayList,記錄當前已申請的WakeLock//findWakeLockIndexLocked查找ArrayList,判斷參數對應的WakeLock,是否在之前被申請過int index = findWakeLockIndexLocked(lock);boolean notifyAcquire;if (index >= 0) {//如果index大于0,說明此時Acquire的是一個舊的WakeLock//例如RIL會多次調用send函數,于是除第一次外,都會進入這個分支wakeLock = mWakeLocks.get(index);//這是判斷WakeLock對應的成員變量是否發生改變if (!wakeLock.hasSameProperties(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);//若wakelock屬性發生了變化,更新該屬性wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);}notifyAcquire = false;} else {//創建一個新的WakeLock,例如RIL第一次調用send就會進入該分支wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);try {//1、監控申請WakeLock的進程是否死亡lock.linkToDeath(wakeLock, 0);} catch (RemoteException ex) {throw new IllegalArgumentException("Wake lock is already dead.");}//添加到wakelock列表mWakeLocks.add(wakeLock);//2、特殊處理PARTIAL_WAKE_LOCK//實際上,根據Doze模式的白名單更新wakelock的disabled變量setWakeLockDisabledStateLocked(wakeLock);notifyAcquire = true;}//3、處理WakeLock對應的Flag//實際上判斷WakeLock是否有ACQUIRE_CAUSES_WAKEUP,在必要時喚醒屏幕applyWakeLockFlagsOnAcquireLocked(wakeLock, uid);mDirty |= DIRTY_WAKE_LOCKS;//更新電源狀態,以后單獨分析updatePowerStateLocked();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.//通知wakeLock發生變化 //電量統計服務做相關統計notifyWakeLockAcquiredLocked(wakeLock);}} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

如上代碼中標注的注釋,acquireWakeLockInternal中有幾處比較重要的地方,我們一起來分析一下。

1、監聽客戶端進程死亡?
上面的代碼中,第一次創建WakeLock后,調用了:

......... lock.linkToDeath(wakeLock, 0); .........
  • 1
  • 2
  • 3

我們將acquire WakeLock的進程定義為PMS的客戶端進程,那么上面代碼的lock,就是客戶端進程中創建的Binder對象的代理。對于RIL而言,就是存在于Phone進程中的Binder的代理。?
PMS調用Binder代理的linkToDeath,實際上使得PMS成為了對應進程Binder的客戶端。于是,當對應進程死亡后,將通知PMS。?
linkToDeath傳入的必須是繼承IBinder.DeathRecipient的對象,作為進程死亡的”訃告”接收者。

我們看看PMS中WakeLock與此相關的定義:

private final class WakeLock implements IBinder.DeathRecipient {...........@Overridepublic void binderDied() {//發現客戶端進程死亡后,調用PMS的handleWakeLockDeath進行處理,傳入的參數為WakeLock自己PowerManagerService.this.handleWakeLockDeath(this);}....... }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

我們看看PMS的handleWakeLockDeath函數:

private void handleWakeLockDeath(WakeLock wakeLock) {synchronized (mLock) {..........int index = mWakeLocks.indexOf(wakeLock);if (index < 0) {return;}removeWakeLockLocked(wakeLock, index);} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

跟進removeWakeLockLocked函數:

private void removeWakeLockLocked(WakeLock wakeLock, int index) {mWakeLocks.remove(index);//通知到BatteryStatsServicenotifyWakeLockReleasedLocked(wakeLock);//處理WakeLock對應的flag,與后文applyWakeLockFlagsOnAcquireLocked一起分析//實際上是判斷是否需要立即息屏applyWakeLockFlagsOnReleaseLocked(wakeLock);mDirty |= DIRTY_WAKE_LOCKS;//鎖移除后,還是利用updatePowerStateLocked更新電源狀態updatePowerStateLocked(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2、特殊處理PARTIAL_WAKE_LOCK?
PMS處理第一次創建的WakeLock時,還會調用setWakeLockDisabledStateLocked函數進行處理:

private boolean setWakeLockDisabledStateLocked(WakeLock wakeLock) {//僅會特殊處理PARTIAL_WAKE_LOCK,畢竟PARTIAL_WAKE_LOCK要求按Power鍵后CPU依然可以工作if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)== PowerManager.PARTIAL_WAKE_LOCK) {boolean disabled = false;//設備處于Doze定義的device idle模式時if (mDeviceIdleMode) {final int appid = UserHandle.getAppId(wakeLock.mOwnerUid);// If we are in idle mode, we will ignore all partial wake locks that are// for application uids that are not whitelisted.//判斷是否為非系統應用 if (appid >= Process.FIRST_APPLICATION_UID &&//白名單searchArrays.binarySearch(mDeviceIdleWhitelist, appid) < 0 &&Arrays.binarySearch(mDeviceIdleTempWhitelist, appid) < 0 &&//判斷進程的類型//ActivityManager中定義的數字最小的為:常駐的操作UI的系統進程//因此大概可理解為:數字越大,對處理事件的時效性要求越低mUidState.get(wakeLock.mOwnerUid,ActivityManager.PROCESS_STATE_CACHED_EMPTY)> ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {disabled = true;}}if (wakeLock.mDisabled != disabled) {wakeLock.mDisabled = disabled;return true;}}return false; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

上面代碼大致的含義就是:?
在Android Doze模式下,當終端處于device Idle Mode時,?
對于一個非系統應用而言,如果該應用不在系統定義的白名單中,?
并且該應用所在進程的類型表明,該進程對事件處理的時效性要求不高,?
那么即使該應用申請了PARTIAL_WAKE_LOCK,也不能阻止系統進入休眠狀態。

有些設備商,為了優化系統的功耗,就修改了這個地方。?
例如,有些系統應用其實也很耗電,因此可以去掉該函數中對非系統應用的限制,對系統應用也進行管控。

3、處理WakeLock對應的Flag?
前面的代碼已經提到,當acquire WakeLock時,將調用applyWakeLockFlagsOnAcquireLocked處理WakeLock對應的flag;?
當由于進程死亡,釋放WakeLock時,會調用applyWakeLockFlagsOnReleaseLocked處理WakeLock對應的flag。?
從函數命名來看,這兩個函數應該有相似的地方。

3.1 applyWakeLockFlagsOnAcquireLocked?
我們先看看applyWakeLockFlagsOnAcquireLocked:

private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, int uid) {//僅處理ACQUIRE_CAUSES_WAKEUP flag,同時要求WakeLock的level是與screen有關的,//即FULL_WAKE_LOCK、SCREEN_BRIGHT_WAKE_LOCK和SCREEN_DIM_WAKE_LOCKif ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0&& isScreenLock(wakeLock)) {..............wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), wakeLock.mTag, opUid,opPackageName, opUid);} }private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,String opPackageName, int opUid) {............//不滿足以下條件,沒有喚醒屏幕的必要if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE|| !mBootCompleted || !mSystemReady) {return false;}try {mLastWakeTime = eventTime;//修改PMS的一些成員變量,并進行通知//其中主要的是將mDirty變量的DIRTY_WAKEFULNESS位置為了1//PMS根據mDirty的位信息管理電源狀態,同時喚醒屏幕setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);//通知給電源統計服務mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid);//調用userActivityNoUpdateLocked函數userActivityNoUpdateLocked(eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);} .....return true; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

3.1.1 setWakefulnessLocked?
我們看看喚醒屏幕相關的操作:

private void setWakefulnessLocked(int wakefulness, int reason) {if (mWakefulness != wakefulness) {mWakefulness = wakefulness;mWakefulnessChanging = true;mDirty |= DIRTY_WAKEFULNESS;//定義于frameworks/base/services/core/java/com/android/server/power/Notifier.java中mNotifier.onWakefulnessChangeStarted(wakefulness, reason);} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
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.mHandler.post(new Runnable() {@Overridepublic void run() {mActivityManagerInternal.onWakefulnessChanged(wakefulness);}});// 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();} }/** * 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() {@Overridepublic void run() {EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);//mPolicy對應于PhoneWindowManagermPolicy.startedWakingUp();}});// 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() {@Overridepublic void run() {mPolicy.startedGoingToSleep(why);}});}} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

從上面的代碼來看,應該是PhoneWindowManager完成亮屏前的初始化工作,然后回調到PowerManager的wakeUp函數。?
整個過程還是比較復雜的,需要單獨進行分析,此處不做進一步說明。

3.2 applyWakeLockFlagsOnReleaseLocked?
現在我們再看看applyWakeLockFlagsOnReleaseLocked函數:

private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {//僅處理ON_AFTER_RELEASE,同樣要求WakeLock的level是與screen有關的//ON_AFTER_RELEASE并不會立即息屏if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0&& isScreenLock(wakeLock)) {userActivityNoUpdateLocked(SystemClock.uptimeMillis(),PowerManager.USER_ACTIVITY_EVENT_OTHER,PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,wakeLock.mOwnerUid);} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

可以看出applyWakeLockFlagsOnAcquireLocked和applyWakeLockFlagsOnReleaseLocked最后均會調用userActivityNoUpdateLocked函數,只是參數不同。

3.3 userActivityNoUpdateLocked?
我們一起來看一下userActivityNoUpdateLocked:

private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {.............//過時的事件不需要處理if (eventTime < mLastSleepTime || eventTime < mLastWakeTime|| !mBootCompleted || !mSystemReady) {return false;}...........try {if (eventTime > mLastInteractivePowerHintTime) {//調用native加載的動態庫的powerHint函數,具體意義不是很清楚powerHintInternal(POWER_HINT_INTERACTION, 0);mLastInteractivePowerHintTime = eventTime;}//調用BatteryStatsService的noteUserActivity函數,看代碼好像是做一些記錄mNotifier.onUserActivity(event, uid);//根據參數信息修改mDirty的一些變量.............} finally {........} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

從以上代碼來看,acquire WakeLock將申請信息遞交給PMS統一進行處理。?
PMS根據WakeLock的level和flag,完成修改一些變量、通知BatteryStatsService等工作后,?
最終還是依賴于updatePowerStateLocked函數來進行實際的電源狀態更新操作。

PMS類中有很多***NoUpdateLocked()方法,這些方法都有一些共性,就是僅更新狀態,不負責具體的執行。因為PMS中具體的執行邏輯都是在updatePowerStateLocked方法中。

上述acquire WakeLock主要的工作大致可以總結為下圖:?

三、釋放WakeLock?
當進程完成工作后,需要釋放之前申請的WakeLock。我們同樣以RIL.java中的操作為例:

private void processResponse (Parcel p) {int type;type = p.readInt();if (type == RESPONSE_UNSOLICITED || type == RESPONSE_UNSOLICITED_ACK_EXP) {...........} else if (type == RESPONSE_SOLICITED || type == RESPONSE_SOLICITED_ACK_EXP) {//處理請求對應的回復信息RILRequest rr = processSolicited (p, type);if (rr != null) {if (type == RESPONSE_SOLICITED) {//重點在這里decrementWakeLock(rr);}rr.release();return;}} else if (type == RESPONSE_SOLICITED_ACK) {...........} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

我們跟進decrementWakeLock函數:

private void decrementWakeLock(RILRequest rr) {synchronized(rr) {switch(rr.mWakeLockType) {case FOR_WAKELOCK:synchronized (mWakeLock) {//前面已經提到過,RIL.java多個請求復用同一個WakeLock//并且利用mWakeLockCount記錄復用的次數//這么設計的目的是:RIL發送請求的數量非常多,復用WakeLock可以避免多次構造釋放//同時減少與PMS之間Binder通信的次數if (mWakeLockCount > 1) {mWakeLockCount--;} else {mWakeLockCount = 0;//所有請求均得到了處理,調用PowerManager中WakeLock的release函數mWakeLock.release();}}break;........}}........ }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

現在我們跟進PowerManager中WakeLock定義的release函數:

/** * Releases the wake lock with flags to modify the release behavior. * * This method releases your claim to the CPU or screen being on. * The screen may turn off shortly after you release the wake lock, or it may * not if there are other wake locks still held. * */ public void release(int flags) {synchronized (mToken) {if (!mRefCounted || --mCount == 0) {mHandler.removeCallbacks(mReleaser);if (mHeld) {.......try {//還是會調用到PMS中的函數mService.releaseWakeLock(mToken, flags);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}mHeld = false;}}....} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

最后一起來看看PMS中釋放WakeLock的函數:

public void releaseWakeLock(IBinder lock, int flags) {//參數和權限檢查.............final long ident = Binder.clearCallingIdentity();try {releaseWakeLockInternal(lock, flags);} finally {Binder.restoreCallingIdentity(ident);} }private void releaseWakeLockInternal(IBinder lock, int flags) {synchronized (mLock) {//根據Binder代理,從存儲的ArrayList中找到對應WakeLock的序號int index = findWakeLockIndexLocked(lock);...........WakeLock wakeLock = mWakeLocks.get(index);...........//RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY,表示當sensor判斷終端離物體較遠時,//才真正釋放PROXIMITY_SCREEN_OFF_WAKE_LOCK等級的WakeLockif ((flags & PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) {mRequestWaitForNegativeProximity = true;}//PMS不再關注客戶端進程是否死亡wakeLock.mLock.unlinkToDeath(wakeLock, 0);removeWakeLockLocked(wakeLock, index);} }private void removeWakeLockLocked(WakeLock wakeLock, int index) {mWakeLocks.remove(index);//通知BatteryStatsServicenotifyWakeLockReleasedLocked(wakeLock);//之前分析過,會做一些記錄信息等applyWakeLockFlagsOnReleaseLocked(wakeLock);mDirty |= DIRTY_WAKE_LOCKS;//依然靠updatePowerStateLocked函數更新終端的電源狀態updatePowerStateLocked(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

整個release的過程大致可以總結為下圖:?

四、總結?
通過前面的分析,我們知道了向PMS申請電量的基本用法類似于:

........ //1、創建 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_LOG_TAG); ...... //2、acquire mWakeLock.acquire(); ......... //3、release mWakeLock.release(); ...........
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

當申請發送到PMS后,PMS將針對WakeLock的level和flag信息進行一些處理。?
無論是acquire還是release WakeLock,PMS最終將利用updatePowerStateLocked函數對終端的電源狀態進行調整。?

我們將單獨分析一下PMS核心的updatePowerStateLocked函數。


原文地址:http://blog.csdn.net/gaugamela/article/details/52813400

總結

以上是生活随笔為你收集整理的Android7.0 PowerManagerService(2) WakeLock的使用及流程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

欧美日韩99 | .国产精品成人自产拍在线观看6 | 97视频在线观看播放 | 国产精品va在线 | 日韩av线观看 | 中文在线字幕免费观 | 日韩av电影手机在线观看 | 波多野结衣一区 | 色com | 欧美疯狂性受xxxxx另类 | 免费在线成人av | 国产精品一区二区三区观看 | 又爽又黄在线观看 | 天天干天天玩天天操 | 91成人免费在线 | 伊香蕉大综综综合久久啪 | 激情av在线资源 | 91视频麻豆视频 | 激情av综合 | 91黄色在线视频 | www.色爱| 激情婷婷欧美 | 日韩试看 | 亚洲精品人人 | 一区二区久久久久 | 日韩素人在线观看 | 深爱婷婷久久综合 | 国产成在线观看免费视频 | 久久综合九色综合久久久精品综合 | 中文字幕资源在线观看 | 国产91在线免费视频 | 色婷婷六月| 一区二区视频欧美 | 色婷婷影视 | 尤物一区二区三区 | 国产精品久久一区二区无卡 | 国产网站在线免费观看 | 久久免费视频在线 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 色综合久久五月 | 日韩精品久久久久久 | 中文字幕文字幕一区二区 | 国产资源在线视频 | 亚洲免费在线播放视频 | 人人干干人人 | 欧美不卡视频在线 | 国产精品久久久久国产a级 激情综合中文娱乐网 | 亚洲精品高清在线 | 亚洲午夜精 | 日韩视频精品在线 | 亚洲精品久久久久久久蜜桃 | 99国产精品一区 | 丝袜美腿在线播放 | 欧美一级大片在线观看 | 天天操天天射天天 | 精品久久福利 | 国产成人l区 | 五月婷婷综合久久 | 中文字幕精品一区二区精品 | 97人人添人澡人人爽超碰动图 | 91av在线看| 国产亚洲在线视频 | 中文字幕中文字幕在线中文字幕三区 | 国产精品一区二区久久精品 | 性日韩欧美在线视频 | 国产精品毛片久久蜜 | 97在线精品 | 韩国av一区 | www.人人干| 永久黄网站色视频免费观看w | 西西4444www大胆艺术 | 亚洲激情 在线 | 在线观看第一页 | 国产精品一区免费观看 | 在线观看深夜视频 | 99热在线国产 | 五月激情丁香婷婷 | 亚洲婷婷网| 91天天操 | www.97色.com| 在线视频免费观看 | 91亚洲精品久久久 | 91免费版成人 | 久久精彩视频 | 国产在线免费观看 | 韩国一区二区三区在线观看 | 搡bbbb搡bbb视频 | 日本精品免费看 | 久久综合亚洲鲁鲁五月久久 | 91麻豆精品一区二区三区 | 狠狠狠干| 国产精品高潮久久av | 国产婷婷久久 | 91大神免费视频 | 五月婷婷.com| 99精品福利 | 狠狠躁18三区二区一区ai明星 | 六月婷色 | 久久国产成人午夜av影院宅 | 国产玖玖精品视频 | 国产视频精品久久 | 国产高清在线视频 | 国产欧美综合在线观看 | 一区二区影视 | 一本—道久久a久久精品蜜桃 | 免费在线播放黄色 | 欧美国产一区在线 | 99久久精品一区二区成人 | 色吊丝在线永久观看最新版本 | 日韩精品在线免费观看 | 日韩在线视频线视频免费网站 | 国产成人久久av免费高清密臂 | 爱爱一区 | 在线观看日本高清mv视频 | 日本一区二区三区免费观看 | 日韩视频精品在线 | 四虎小视频| 亚洲欧洲国产视频 | 开心激情综合网 | 免费观看www视频 | 午夜婷婷在线播放 | 激情五月婷婷 | 成人黄色大片网站 | 在线观看亚洲精品视频 | 免费福利视频网 | 亚洲综合在线视频 | 揉bbb玩bbb少妇bbb | 亚洲欧美日韩在线一区二区 | 综合激情网 | 久久se视频 | 亚洲午夜av | 国产精品自产拍在线观看网站 | 五月天视频网站 | 亚洲一区二区三区精品在线观看 | 国产1区2区| 福利网在线 | 丁香 久久 综合 | 久久久久久久久久电影 | 手机av在线网站 | 久久视频这里有精品 | 亚洲精品午夜久久久久久久久久久 | 天天干人人插 | 免费看的国产视频网站 | 精品久久1 | 日日夜夜网站 | 麻豆国产在线播放 | 免费亚洲视频 | 亚洲专区一二三 | 国产精品一区二区三区99 | 一区二区三区在线观看中文字幕 | 成人久久18免费 | 97在线免费观看视频 | 国产高清视频免费最新在线 | 精品国产免费久久 | 国产精品久久久久久999 | 日操操 | 中文字幕欲求不满 | 色综合天天综合 | 国产伦理一区二区三区 | 9ⅰ精品久久久久久久久中文字幕 | 午夜视频在线观看一区二区 | 日韩色在线观看 | 91中文字幕在线视频 | 亚洲色视频 | 国产成人精品午夜在线播放 | 亚洲精品国精品久久99热 | 一区二区三区手机在线观看 | 久久精品国产亚洲 | 欧美日韩一区二区在线观看 | 日韩r级在线 | 日韩在线观看免费 | 91在线视频在线 | 中文字幕亚洲字幕 | 国产黄色在线 | 国产精品美女999 | 激情电影在线观看 | 超碰免费公开 | 91欧美精品| 欧美精品中文在线免费观看 | 中国成人一区 | 久久1区| 色五月成人 | 在线观看免费视频你懂的 | 在线 视频 亚洲 | 中文字幕丝袜一区二区 | 麻豆影视在线免费观看 | 91成人精品观看 | 成人毛片一区二区三区 | 国产高清精品在线 | 最近中文字幕免费av | 欧美午夜精品久久久久 | 国产专区在线播放 | 麻豆 free xxxx movies hd| 免费在线精品视频 | 国产精品网红直播 | 亚洲视频免费在线看 | av软件在线观看 | 精品嫩模福利一区二区蜜臀 | 久色小说 | 伊人五月天综合 | 天天干天天射天天操 | 一区二区三区免费在线播放 | 成人av在线看 | 久久手机看片 | 美女视频一区二区 | 波多野结衣久久资源 | 国产日韩视频在线 | 日韩视频区 | 成年人视频在线免费观看 | 久久精品国产一区二区电影 | 97精品国产aⅴ | 亚洲做受高潮欧美裸体 | a在线一区| 91成年人网站 | 久草在线高清视频 | 在线观看免费成人 | 91精品国产91久久久久久三级 | 亚洲精品在线视频观看 | 国语精品免费视频 | 四虎成人精品永久免费av | 天天色天天上天天操 | 国产手机视频精品 | 国产在线91在线电影 | 天天色天天骑天天射 | 日韩在线色视频 | 亚洲国产精品va在线看黑人动漫 | 色婷婷综合久色 | 99精品国产一区二区三区麻豆 | 久久精品8 | 激情视频91 | av久久久久久| 免费观看av网站 | 久久97精品 | 亚洲国产中文在线观看 | 日韩av在线影视 | 成人久久久久久久久久 | 伊在线视频 | 91视频在线自拍 | 成年人黄色免费网站 | 国产久草在线观看 | 综合影视 | 久久精品国产久精国产 | 久久综合免费 | 国产精品福利一区 | 91精品国产91p65| 激情久久久久久久久久久久久久久久 | av黄色在线| 国产一区在线视频观看 | www.国产视频 | 日韩福利在线观看 | 色婷婷色| 久久综合狠狠综合久久激情 | 久久不射电影网 | 免费在线观看黄 | 精品国产色 | 欧美极品一区二区三区 | 久久天天躁 | 久久在线视频在线 | 中文字幕 国产精品 | 精品国产伦一区二区三区观看体验 | 久久五月网 | 国产精品少妇 | 99久久精品国产亚洲 | 亚洲日本中文字幕在线观看 | 亚洲视频 在线观看 | 97在线免费视频 | 成人黄色av网站 | 午夜私人影院 | 操操日日| 久久综合久久综合这里只有精品 | 日韩69av | 国产高清在线观看 | 国产综合在线视频 | 久久艹国产| 毛片a级片 | 中文字幕在线观看不卡 | 国产精品国产三级在线专区 | 在线国产一区 | 91传媒在线观看 | 欧美va天堂va视频va在线 | 性日韩欧美在线视频 | 国产91免费观看 | 国产手机av在线 | 日韩一区在线播放 | 免费色视频在线 | 成年人免费看 | 国产精品露脸在线 | 日韩欧美大片免费观看 | 国产精在线 | 久久综合久久综合久久综合 | 久久精品久久国产 | 日韩在线免费观看视频 | 亚洲精品一区二区三区新线路 | 奇米四色影狠狠爱7777 | 九九亚洲精品 | 久久久久久国产精品美女 | 国产麻豆电影 | 西西大胆免费视频 | 久草在线综合网 | 日韩中文字幕免费视频 | 久久永久免费 | 极品久久久久久久 | 特级片免费看 | 一区二区精品在线 | 中文字幕在线网址 | 极品嫩模被强到高潮呻吟91 | 欧美精品做受xxx性少妇 | 成人久久精品 | 欧美日韩高清免费 | 日本久久综合网 | 在线а√天堂中文官网 | 久久国产网站 | 婷婷久久一区二区三区 | 最近能播放的中文字幕 | 国产精品婷婷午夜在线观看 | 日韩首页| 91视频91蝌蚪 | 精品久久精品久久 | 天天色天天爱天天射综合 | 超碰在线cao | 99精品久久久久久久久久综合 | 久久久麻豆精品一区二区 | 中文成人字幕 | 永久免费的av电影 | 在线视频免费观看 | 中文字幕视频三区 | 中文字幕在线免费观看 | 欧美孕妇与黑人孕交 | 亚洲精品国精品久久99热一 | 在线观看日韩国产 | 亚洲午夜av久久乱码 | 91福利视频在线 | 亚州激情视频 | 国产精品系列在线 | 亚洲午夜av电影 | 永久免费毛片在线观看 | 黄色亚洲在线 | 国产黄色片久久 | 最近中文字幕免费视频 | 中文字幕亚洲在线观看 | 国产成人精品一二三区 | 黄网在线免费观看 | 午夜一级免费电影 | 五月婷婷亚洲 | 欧美激情综合五月色丁香小说 | 看av免费网站 | 国产精品久久影院 | 深夜免费福利在线 | 天天干天天操天天 | 亚洲精品视频网站在线观看 | 欧美日韩国产综合一区二区 | 四虎影视成人永久免费观看视频 | 久久公开免费视频 | 蜜臀久久99精品久久久无需会员 | 久久免费看a级毛毛片 | 久福利 | 麻豆免费精品视频 | 色婷婷啪啪免费在线电影观看 | 精品一区二区av | 国产一区二区三区高清播放 | 久久免费高清视频 | 天天射天天操天天 | 中文字幕 国产视频 | 日韩最新中文字幕 | 亚洲精品国产精品久久99热 | 五月婷网站 | 一级α片免费看 | 日本aa在线 | 欧亚久久| 免费看国产一级片 | 亚洲精品美女免费 | 色五月色开心色婷婷色丁香 | 五月天婷婷在线观看视频 | 五月天com | 久久精品免视看 | 亚洲免费观看视频 | 国产伦理剧 | 午夜美女福利直播 | 免费试看一区 | 亚洲人人网| 丁香婷婷基地 | 黄色在线看网站 | 808电影 | 91麻豆网站 | 亚州av免费| 九九热免费在线视频 | 亚州av免费 | 亚洲日本成人 | 亚洲视频1 | 国产精品一区在线 | 欧美视频xxx | a在线观看视频 | 欧美伦理一区二区三区 | 国产午夜精品在线 | 亚州精品天堂中文字幕 | 国产一区av在线 | 天天干天天干天天操 | 麻豆影视在线播放 | 97在线影院 | 天天综合婷婷 | 亚洲综合网 | 久久爱综合 | 色香com.| 午夜精品久久久久久99热明星 | 亚洲精品h | 国产视频精选 | 91福利视频一区 | 91热视频 | 麻花天美星空视频 | 国产91国语对白在线 | 99久久精品国产亚洲 | 色 免费观看 | 伊人网av| 国产精品一区二区三区四 | 日本久久综合网 | 成年人av在线播放 | 中文字幕在线专区 | 99电影456麻豆 | 视频在线91| 精精国产xxxx视频在线播放 | 91在线精品视频 | 丁香六月五月婷婷 | 欧美一区二区三区免费观看 | 免费亚洲精品 | 日韩免费高清在线观看 | 久久视了 | 三级黄免费看 | 99精品久久久久久久 | 婷婷5月色| 中文字幕久久久精品 | 国产一区国产二区在线观看 | 中文字幕亚洲精品在线观看 | 中文字幕久久精品亚洲乱码 | 天天干,夜夜操 | 久久精品欧美一区 | av网站大全免费 | 五月婷网 | 日韩综合视频在线观看 | 亚洲精品视频偷拍 | 激情欧美一区二区三区 | 中文字幕一区二区三区精华液 | 久久久久国产成人免费精品免费 | a级国产片 | 色婷婷狠狠五月综合天色拍 | 香蕉视频国产在线观看 | 久久精品福利 | 91九色在线观看 | 久久久久免费精品 | 一区二区三区免费播放 | 日韩在线观看中文字幕 | 麻豆精品视频在线 | 在线播放精品一区二区三区 | 欧美大荫蒂xxx | 成人毛片在线观看 | 日韩久久精品一区二区三区 | av电影免费观看 | 久久综合色播五月 | 成人免费在线看片 | 中文字幕在线观看完整版电影 | 免费观看一级特黄欧美大片 | 精品久久国产 | 久操视频在线播放 | 国内视频 | 久久综合色综合88 | 久草视频在线免费播放 | 国产精品久久久久久久久久妇女 | 天天操欧美 | 五月综合在线观看 | 国产麻豆视频在线观看 | 91av电影网| 成人午夜电影久久影院 | 91精品啪| 国产资源网 | 久久69精品久久久久久久电影好 | 色91在线视频 | 日韩欧美在线不卡 | 国产资源精品在线观看 | 成人黄色免费观看 | 97精品久久人人爽人人爽 | 97偷拍在线视频 | 99精品免费在线 | 国产日韩精品在线观看 | 一区二区在线电影 | 夜夜夜夜夜夜操 | 亚洲成人在线免费 | 特级毛片在线免费观看 | 五月婷婷中文网 | 国产中文字幕视频 | 亚洲国产黄色 | 欧美日韩免费观看一区=区三区 | 韩日电影在线观看 | 97国产一区二区 | 成人国产精品一区 | a v在线观看 | 亚洲专区免费观看 | 欧美日一级片 | 国产一级不卡视频 | 国产午夜小视频 | 国产中年夫妇高潮精品视频 | 久久久久久久久福利 | 超碰人人草人人 | 久久婷婷开心 | 免费在线观看一区二区三区 | 成人国产精品免费 | 99久久精品电影 | 国产精品资源 | 在线观看视频你懂 | 天天操天天射天天插 | 人人舔人人插 | 99精品免费久久久久久久久 | 久久99国产精品二区护士 | 亚洲免费不卡 | 久久人人看 | 中文字幕在线播放av | 国产又粗又猛又色又黄网站 | 精品一区二区在线免费观看 | 国产精品99久久久久久人免费 | 欧美精品亚洲精品 | 99久久精品国产系列 | 久久伦理电影 | 伊香蕉大综综综合久久啪 | 三上悠亚一区二区在线观看 | 欧美成人黄色片 | 天海冀一区二区三区 | 欧美综合在线视频 | 国产黄a三级三级三级三级三级 | 亚洲天堂网站 | 久久久av电影 | 国产精品大尺度 | 久久综合导航 | 午夜av在线 | 国产精品欧美精品 | 国产精品永久免费 | 奇米先锋| 在线观看网站你懂的 | 亚洲区视频在线观看 | 毛片播放网站 | 亚洲无吗视频在线 | 国产精品理论在线观看 | www一起操| 亚洲精品影视在线观看 | 最新av中文字幕 | 日韩在线电影一区 | 亚洲乱码在线观看 | 欧美日韩国产亚洲乱码字幕 | 日韩三级免费观看 | 日本黄区免费视频观看 | 成年人在线观看免费视频 | 国产成人精品午夜在线播放 | 黄网站色欧美视频 | 国产a高清 | 国产高清视频网 | 欧美国产大片 | 欧美成人猛片 | 激情深爱.com | 日韩av进入| 日韩成人av在线 | 一区二区三区中文字幕在线观看 | 国产亚洲欧美在线视频 | 日韩一级片观看 | 免费碰碰| 久久久精品欧美一区二区免费 | 国产一区欧美一区 | 欧美激情片在线观看 | 激情五月婷婷网 | 天堂在线成人 | 正在播放一区 | 国产99免费 | 91精品婷婷国产综合久久蝌蚪 | 亚洲视频精品在线 | 国产黄色免费看 | 精品久久久影院 | 国产高清免费 | 香蕉网站在线观看 | 欧美日韩激情网 | 国产日产精品久久久久快鸭 | 精品 一区 在线 | 美女av免费看 | 色婷婷综合久久久久中文字幕1 | 天天天干 | 91视频高清免费 | 天天操比| 91在线小视频 | 四月婷婷在线观看 | 欧美日韩精品影院 | 女人18毛片90分钟 | 91香蕉视频在线 | 免费看的黄色的网站 | 久久久 精品 | 奇米网网址 | 狠狠久久 | 福利视频区 | 亚洲在线视频免费观看 | 99免费在线视频 | 久久国产视频网 | 91中文字幕在线播放 | 欧美激情精品久久久 | 久久国产系列 | 高清国产在线一区 | 最近中文字幕免费 | 国产无套视频 | 国产一区国产二区在线观看 | 久久久久成人精品 | 97色视频在线 | www黄色| 久久不射电影院 | 搡bbbb搡bbb视频 | 在线亚洲观看 | 色噜噜噜噜 | 亚洲男人天堂a | 欧美国产一区在线 | 久久久精品国产一区二区 | 91av久久| 99视频免费播放 | 精品国产一区二区三区不卡 | 韩国一区在线 | 亚洲老妇xxxxxx | 欧美日韩高清一区二区三区 | 免费看片成年人 | 久久精品久久精品 | 91福利在线导航 | 久久午夜电影网 | 成人免费视频网站在线观看 | 国产精品一区一区三区 | 欧美极品裸体 | 久久艹艹 | 免费网址在线播放 | 国产高清在线免费视频 | 日韩av成人 | 伊人激情网 | 国产 日韩 在线 亚洲 字幕 中文 | 国产精品1区2区在线观看 | 色婷婷国产精品一区在线观看 | 欧美va天堂va视频va在线 | 国产一二三四在线观看视频 | 亚洲人成综合 | 激情婷婷在线 | 免费av在| 黄色aa久久| 激情视频91 | 贫乳av女优大全 | 日韩在线三区 | 99视频精品免费视频 | 欧美亚洲国产精品久久高清浪潮 | 国产又黄又硬又爽 | 色婷婷影视 | 麻豆精品视频在线观看免费 | 日韩欧美高清在线观看 | 草久在线 | 午夜性生活片 | 视频在线观看入口黄最新永久免费国产 | 亚洲欧美激情精品一区二区 | 国产午夜精品免费一区二区三区视频 | 精品1区2区 | 久久精品欧美一区 | 国产精品一区二区中文字幕 | 三级在线视频播放 | 久久精彩| 日韩精选在线观看 | 天堂av影院 | 久热爱 | 97视频免费在线看 | 五月婷婷一区 | 久久天天躁夜夜躁狠狠85麻豆 | 久久在线一区 | 久久久综合精品 | 成人黄色在线看 | 黄色片视频免费 | 成人h电影在线观看 | 日韩性片| 国产高清在线视频 | 麻豆国产视频下载 | 视频国产区 | 国产精品午夜免费福利视频 | 五月激情丁香婷婷 | 国产va在线观看免费 | 五月婷婷狠狠 | 999精品网 | 国产69精品久久99不卡的观看体验 | 91污污| 91日韩在线视频 | 亚洲日b视频 | 久久成人黄色 | 亚洲国产天堂av | 精品国产乱码久久 | 超碰在线最新地址 | 九九天堂 | 国产九九九视频 | 探花视频在线观看免费版 | 亚洲国产中文字幕在线观看 | 欧美精品久久久久久久 | 一区二区伦理电影 | 亚洲天堂色婷婷 | 黄色毛片电影 | jizzjizzjizz亚洲| 国产一级电影在线 | 国产一在线精品一区在线观看 | 97国产大学生情侣白嫩酒店 | 黄色综合| 中文字幕免费国产精品 | 精品久久精品久久 | 免费网站黄 | 在线亚洲欧美视频 | 中文字幕在线免费看线人 | 玖玖玖国产精品 | 波多野结衣亚洲一区二区 | 色婷婷狠狠干 | 97在线精品视频 | 精品一区二区视频 | 午夜精品久久久久久久久久久 | 日韩黄色免费在线观看 | 黄毛片在线观看 | 精品国产91亚洲一区二区三区www | 视频一区二区三区视频 | 91麻豆精品国产自产 | 草久久久久 | 久久热亚洲 | 久久久久久久久久久免费视频 | 国产精品嫩草影视久久久 | 久久国产欧美日韩 | 国产精品99久久久久 | 国产精品 999| japanesexxx乱女另类 | 久久成| 波多野结衣视频在线 | 日本久久成人中文字幕电影 | 一级a性色生活片久久毛片波多野 | 久久亚洲综合色 | 亚洲精品在线视频播放 | 91热在线 | 国产 亚洲 欧美 在线 | 午夜在线观看影院 | 久久er99热精品一区二区三区 | 亚洲欧美日韩精品一区二区 | 亚洲综合视频网 | 夜夜澡人模人人添人人看 | 91精品国产自产在线观看 | 丁香婷婷激情国产高清秒播 | 成人a在线观看高清电影 | 激情五月六月婷婷 | 免费进去里的视频 | 日日日日 | 国产亚洲精品久久久久久 | 在线观看免费视频你懂的 | 99久久精品久久久久久动态片 | 丰满少妇久久久 | 人人狠狠 | 国产黄色看片 | 久久这里只有精品23 | 免费高清男女打扑克视频 | 91亚洲精品乱码久久久久久蜜桃 | 夜夜看av | 视频在线一区二区三区 | 久久免费视频2 | 天干啦夜天干天干在线线 | 麻豆小视频在线观看 | 久久综合免费视频 | 国产精品精品国产婷婷这里av | 日韩欧美xxxx | 日韩中文字幕电影 | www.黄色| 久久好看 | 在线视频一区观看 | 久久亚洲欧美 | 久久午夜国产 | 美女视频一区 | 欧美日高清视频 | 日韩av一区二区在线 | 国产精品久久久久久久久蜜臀 | 黄色免费网 | 色网站在线 | 免费在线播放 | 国产欧美精品xxxx另类 | 久久视频在线视频 | 国产福利免费看 | 欧美无极色 | 色橹橹欧美在线观看视频高清 | 黄色片免费电影 | 久久国产网 | 欧美日韩大片在线观看 | 中文字幕综合在线 | 夜夜骑日日| 久久天堂精品视频 | 美女网站在线免费观看 | 亚洲精品视频在线观看免费 | 国产午夜精品一区二区三区四区 | 免费男女羞羞的视频网站中文字幕 | 国产精品久久久久久久久久久免费看 | 999日韩| 国产91丝袜在线播放动漫 | 人人搞人人爽 | www黄色av | www.五月天色 | 国产精品99久久久久久久久 | 日韩天天干 | 人人添人人澡人人澡人人人爽 | 亚洲va欧美va国产va黑人 | 午夜国产福利视频 | www.一区二区三区 | 亚洲九九 | www91在线观看| 欧美日韩免费视频 | 免费在线播放视频 | 中文字幕资源网 国产 | 精品一区二区免费视频 | 四虎4hu永久免费 | 黄色三级免费网址 | 欧美日韩国产一区二 | 久久夜色精品国产欧美乱极品 | 国产一卡久久电影永久 | 91视频在线网址 | 国产91成人在在线播放 | 操操碰 | 99精品热视频只有精品10 | 久碰视频在线观看 | 尤物一区二区三区 | 久久久精品 一区二区三区 国产99视频在线观看 | 久久成人一区二区 | 91丨九色丨91啦蝌蚪老版 | 在线观看中文字幕第一页 | 午夜在线观看影院 | 国产一区视频在线播放 | 免费在线观看成人小视频 | 久久久久久久久久久久久9999 | 国产一级片免费视频 | 91av99| 综合天天 | 国产精品综合在线 | 在线观看中文字幕 | 久久久官网 | 奇米导航| 欧美国产高清 | 日韩av看片 | 久久这里精品视频 | 精品成人在线 | 国产高清网站 | 91黄视频在线观看 | 黄色小说免费在线观看 | 久久久久久久久黄色 | 日韩二三区 | 日韩欧美电影网 | 亚洲第一中文网 | 涩涩爱夜夜爱 | 最新av中文字幕 | 亚洲国产免费 | 精品欧美小视频在线观看 | japanesexxxhd奶水 91在线精品一区二区 | 中文字幕色在线视频 | 精品久久电影 | www日韩在线观看 | 人人爽网站 | 亚洲色图美腿丝袜 | 亚洲成人在线免费 | 国产精品一区二区av影院萌芽 | 亚洲一区二区高潮无套美女 | 婷婷久久国产 | 国产午夜在线观看视频 | 欧美日韩精品在线免费观看 | 亚洲欧美婷婷六月色综合 | 日韩aⅴ视频 | 国产高清久久久久 | 亚洲国产精品va在线看 | 国产麻豆电影在线观看 | 国产 字幕 制服 中文 在线 | 久久五月婷婷丁香社区 | a极黄色片 | 欧美一级久久久 | 色综合久| 五月激情在线 | 免费日韩电影 | 激情视频一区二区三区 | 色瓜 | 欧美日韩大片在线观看 | 欧美视频在线观看免费网址 | 久久久久久国产精品 | 日本高清中文字幕有码在线 | 丝袜+亚洲+另类+欧美+变态 | 亚洲一级久久 | 超碰成人网 | 视频二区在线 | 草久久久 | 国产视频2区 | 免费久草视频 | 免费视频三区 | 在线观看一级片 | 91超碰免费在线 | 88av色 | 免费在线日韩 | av黄色免费网站 | 欧美一区二区三区四区夜夜大片 | 免费视频一二三 | 99久久精品国产一区二区三区 | 日韩中文字幕在线观看 | 久久一区国产 | 日本中文字幕电影在线免费观看 | 国产精品美女久久久久久 | 香蕉影院在线观看 | 国产黄色精品在线 | www.天天干.com | 精品亚洲视频在线 | 久久香蕉电影网 | 国产精品永久在线观看 | 欧美日韩不卡一区二区 | 九九久久精品 | 成人免费看片网址 | 51久久成人国产精品麻豆 | 91在线视频在线观看 | 中文字幕免费高清av | 国产黄网在线 | 亚洲日本欧美在线 | 免费看麻豆 | 欧美肥妇free| 狠狠色狠狠色综合系列 | 中文字幕在线看片 | 国产伦精品一区二区三区免费 | 成 人 黄 色 视频免费播放 | 久久精品首页 | 精品国产伦一区二区三区观看说明 | 日韩电影中文,亚洲精品乱码 | 九9热这里真品2 | 91免费的视频在线播放 | 色婷婷导航 | 91视频网址入口 | 久久久久久国产精品久久 | 亚洲午夜久久久久久久久电影网 | 九九久久精品 | 国产va饥渴难耐女保洁员在线观看 | 能在线观看的日韩av | 深爱激情五月网 | 91激情视频在线播放 | 久爱综合 | 91大神精品视频在线观看 | 韩日精品视频 | 久久天天躁狠狠躁亚洲综合公司 | 九九九视频在线 | 操久久免费视频 | 麻花豆传媒mv在线观看网站 | 亚洲欧洲美洲av | .国产精品成人自产拍在线观看6 | 亚洲精品在线观看不卡 | 在线免费三级 | 色成人亚洲网 | 欧美成人黄 | 中文在线免费一区三区 | 五月天电影免费在线观看一区 | 久久嗨| 天天干,天天射,天天操,天天摸 | 丁香九月激情 | 国产在线a视频 | 97精品伊人| 成年人免费电影在线观看 | 99久久毛片 | 五月天免费网站 | 色综合久久中文字幕综合网 | 在线99热| 亚洲午夜av电影 | 国产在线更新 | 狠狠狠综合 | 在线中文字幕播放 | 欧美精品乱码久久久久久 | 中文字幕一区二区三区久久 | 欧美做受xxx | 伊人五月天综合 | 国产性天天综合网 | 成人在线视频网 | 97精品国产97久久久久久免费 | 国产精品毛片一区二区三区 | 成人国产电影在线观看 | 99综合视频 | 日韩电影中文,亚洲精品乱码 | 91漂亮少妇露脸在线播放 | 国产一区二区在线免费播放 | 日韩黄色在线观看 | 500部大龄熟乱视频使用方法 | 日韩美女久久 | 91日韩精品| 日韩欧美网址 | 美女黄视频免费 | 天天拍天天爽 | 日韩免费电影网 | 日韩免费大片 | 视频在线观看国产 | 国产精品久久久久久69 | 亚洲精品国偷拍自产在线观看 | 国产精品毛片一区 | 久久久久久激情 | 亚洲涩涩一区 | 日本三级香港三级人妇99 | 色99视频 | 在线久久| 国产一级电影免费观看 | 日韩色综合网 | 91久久一区二区 | 国产破处在线播放 | 日韩理论视频 | 天天干天天插伊人网 | 黄色电影在线免费观看 | 西西大胆啪啪 |