-
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;
}
}
先
看
p>
PMS
里
的
acq
uireWakeLock
函
数
,
p>
先
做
一
些
权
限
的
检
查
,
然
后
< 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))
p>
{//
如果属性不一样就
更新
//
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
这个函数是所有的地方都会调用,因此我们
最后分析。
下面看下释放锁,
p>
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
函数,最后会到
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
AKEFULNESS_DOZING, reason);//
设置
p>
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
有
这个状态,
直接睡眠
p>
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,
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
,
-
-
-
-
-
-
-
-
-
上一篇:考研英语常见前后缀
下一篇:java文件上传和拦截器