adb shell dumpsys power|grep -i wake
C:\Users\Administrator>adb shell dumpsys power| findstr -i wake
no_cached_wake_locks=true
mWakefulness=Awake
mWakefulnessChanging=false
mWakeLockSummary=0x1
mLastWakeTime=187182227 (24697 ms ago)
mHoldingWakeLockSuspendBlocker=true
mWakeUpWhenPluggedOrUnpluggedConfig=true
mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig=false
mDrawWakeLockOverrideFromSidekick=false
mDoubleTapWakeEnabled=false
Wake Locks: size=2
PARTIAL_WAKE_LOCK 'AudioMixAudioOut_D' ACQ=-831ms (uid=1041 ws=WorkSource{10139})
PARTIAL_WAKE_LOCK 'com.netease.cloudmusic.module.player.NeteaseAudioPlayer' ON_AFTER_RELEASE ACQ=-1s168ms (uid=10139 pid=26062)
PowerManagerService.WakeLocks: ref count=1
wakeLock的tag标志是‘’AudioMixAudioOut_D‘’,我们就可以通过这个tag来判断是不是音乐类的应用,那怎么判断是否正在播放音乐呢,下面开始分析
framewroks\base\core\java\android\os\PowerManagerInternal.java有个内部接口PowerControllerInternalCallback
public interface PowerControllerInternalCallback {
public void onWakeLockAcquired(String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource);
public void onWakeLockReleased(String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource);
public void onWakeLockChanging(String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource, String newTag,
String newPackageName, int newOwnerUid, int newOwnerPid, WorkSource newWorkSource);
public void onConstraintAppAcquireWakeLock(long nowElapsed, long wakelockStartTime);
}
首先实现PowerControllerInternalCallback接口:
frameworks\base\services\core\java\com\android\server\power\sprdpower\WakelockConstraintHelper.java
private class WakeLockObserver
implements PowerManagerInternal.PowerControllerInternalCallback {
@Override
public void onWakeLockAcquired(String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource) {
noteAudioWakeLockAcquired(tag, packageName, ownerUid, ownerPid, workSource);
}
@Override
public void onWakeLockReleased(String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource) {
noteAudioWakeLockReleased(tag, packageName, ownerUid, ownerPid, workSource);
}
@Override
public void onWakeLockChanging(String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource,String newTag,
String newPackageName, int newOwnerUid, int newOwnerPid, WorkSource newWorkSource) {
noteAudioWakeLockChanging(tag, packageName,
ownerUid, ownerPid, workSource, newTag,
newPackageName, newOwnerUid, newOwnerPid, newWorkSource);
}
@Override
public void onConstraintAppAcquireWakeLock(long nowElapsed, long wakelockStartTime) {
noteConstraintAppAcquireWakeLock(nowElapsed, wakelockStartTime);
}
}
再将这个WakeLockObserver注册到PowerManagerInternal
mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
......
mLocalPowerManager.registerPowerControllerInternalCallback(mWakeLockObserver);
PowerManagerInternal.java是个抽象类,在PowerManagerService.java中的内部类LocalService继承了PowerManagerInternal
这样当系统监听到有wakelock申请就会调用onWakeLockAcquired()方法
1. frameworks/base/core/java/android/os/PowerManager.java
acquire--->acquireLocked---->PowerManagerService.acquireWakeLock
2. frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
-->acquireWakeLock
-->acquireWakeLockInternal
-->updatePowerStateLocked
-->updateSuspendBlockerLocked
-->updatePowerStateLocked
-->updateSuspendBlockerLocked
-->mWakeLockSuspendBlocker.acquire
-->PowerManagerService$SuspendBlockerImpl.acquire-->nativeAcquireSuspendBlocker
3. frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
nativeAcquireSuspendBlocker-->acquire_wake_lock
回归我们的主题
PowerManagerService.java-->acquireWakeLockInternal()就会调用我们需要的方法notifyWakeLockAcquiredLocked()
private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
if (mSystemReady && !wakeLock.mDisabled) {
wakeLock.mNotifiedAcquired = true;
mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
wakeLock.mHistoryTag);
restartNofifyLongTimerLocked(wakeLock);
// NOTE: Bug #627645 low power Feature BEG-->
// notify listeners
mPowerControllerHelper.notifyWakeLockAcquiredLocked(wakeLock);
// <-- NOTE: Bug #627645 low power Feature END
}
}
PowerControllerHelper是展讯在PowerManagerService.java增加的一个内部类
PowerControllerHelper-->notifyWakeLockAcquiredLocked()
public void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
if (wakeLock.mStartAcquireTimeStamp <= 0) {
wakeLock.mStartAcquireTimeStamp = SystemClock.elapsedRealtime();
} else {
Slog.d(TAG, "call notifyWakeLockAcquiredLocked > 1, wake lock:" + wakeLock.mTag
+ " from " + wakeLock.mPackageName + "(" + wakeLock.mOwnerUid +")");
}
// if Audio acquired a wakelock notify listeners
if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) == PowerManager.PARTIAL_WAKE_LOCK
&& Process.AUDIOSERVER_UID == wakeLock.mOwnerUid) {
if (mPowerControllerInternalCallback != null) {
mPowerControllerInternalCallback.onWakeLockAcquired(wakeLock.mTag, wakeLock.mPackageName,
wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
}
}
}
在这里判断锁的level等级是PARTIAL_WAKE_LOCK,再判断进程uid是不是AUDIOSERVER_UID
/**
* Defines the UID/GID for the audioserver process.
* @hide
*/
public static final int AUDIOSERVER_UID = 1041;
先补充说明下WakeLock levelAndFlags和使用场景
除了这四个Level之外,PowerMager还提供了两个Flag,可以配合Level使用。
现在再回过头看notifyWakeLockAcquiredLocked(),如果满足PARTIAL_WAKE_LOCK和AUDIOSERVER_UID的判断条件就会调用我们上面说的接口PowerControllerInternalCallback里的onWakeLockAcquired()方法了
现在就走进了WakelockConstraintHelper.java的onWakeLockAcquired()中
public void onWakeLockAcquired(String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource) {
noteAudioWakeLockAcquired(tag, packageName, ownerUid, ownerPid, workSource);
}
private void noteAudioWakeLockAcquired(String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource) {
if (DEBUG) Slog.d(TAG, "noteAudioWakeLockAcquired: workSource:" + workSource);
// only care about the workSource
if (workSource == null) return;
if (!AUDIO_PACKAGE_NAME.equals(packageName) || Process.AUDIOSERVER_UID != ownerUid) return;
//try {
ArrayList uids = new ArrayList();
if (workSource != null) {
int num = workSource.size();
int count = 0;
for (; count
case MSG_AUDIOOUT_WAKELOCK_UPDATED:
handleAudioOutWakeLockUpdated((WakeLockInfo)msg.obj);
break;
private void handleAudioOutWakeLockUpdated(WakeLockInfo wakeLockInfo) {
......
appState.updateAudioState(audioFlag);
......
}
public void updateAudioState(int audioState) {
if (mAudioFlag != audioState
&& (audioState & AUDIO_TYPE_OUT) != 0) {
mLastTimePlayingMusicSeen = SystemClock.elapsedRealtime();
}
mAudioFlag = audioState;
}
public boolean isPlayingMusic() {
return (mAudioFlag & AUDIO_TYPE_OUT) != 0;
}
当需要判断是否在播放音乐的时候,就会结合这个mAudioFlag和AudioManager的isMusicActive()来判断是否正在播放音乐
private boolean isPlayingMusicInternal(AppState appState) {
if (appState.mPlayingMusic) return true;
if(mAudioManager != null && !mAudioManager.isMusicActive()
/*&& !mAudioManager.isFmActive()*/){
return false;
}
if (DEBUG_MORE) Slog.d(TAG, "mAudioManager.isMusicActive(): " + mAudioManager.isMusicActive()
+ " getMode():" + mAudioManager.getMode());
boolean playing = appState.isPlayingMusic();
// if app is still playing music after system standby for APP_PLAYING_MUSIC_THRESHOLD
// set app to be playing music
if (playing && mStandbyStartTime > 0) {
long standbyDuration = SystemClock.elapsedRealtime() - mStandbyStartTime;
if (standbyDuration > APP_PLAYING_MUSIC_THRESHOLD)
appState.setPlayingMusicState(true);
}
return playing;
}