MTK项目 简谈andriod suspendresume流程

更新时间:2024-01-20 19:26:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

最近有再看和功耗相关的问题,需要了解系统suspend/resume,因此对其基本流程梳理了下。

1.liunx 有如下3个文件与系统睡眠唤醒有关,如下:

sys/power/state

sys/power/wake_lock sys/power/wake_unlock

当我们在adb下执行 echo mem > sys/power/state 的时候可以看到屏幕熄灭了,这个时候系统执行完early_syspend后熄灭屏幕,

如果sys/power/wake_lock中没有wakelock存在,系统就会执行suspend进入睡眠模式。 那么在代码中系统又是如何相互调用的呢?

2. 在一个apk中可以通过如下方法向PowerManagerService注册一个wakelock,如果系统持有锁就不能进入睡眠。

PowerManager pm = (PowerManager) mInst.getContext().getSystemService( Context.POWER_SERVICE);

mWakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, TAG); mWakeLock.acquire();

3.下来重点看下mWakeLock.acquire()函数的实现。 在PowerManager.java这只文件中有如下实现

public final class WakeLock { public void acquire() { synchronized (mToken) { acquireLocked(); } }

private void acquireLocked() {

mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,

mHistoryTag); } }

这里的mService定义为 final IPowerManager mService; 在IPowerManager.cpp 文件中实现

virtual status_t acquireWakeLock(int flags, const sp& lock, const String16& tag,

const String16& packageName, bool isOneWay) {

Parcel data, reply;

data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor());

data.writeStrongBinder(lock);

data.writeInt32(flags); data.writeString16(tag);

data.writeString16(packageName); data.writeInt32(0); // no WorkSource

data.writeString16(NULL, 0); // no history tag

return remote()->transact(ACQUIRE_WAKE_LOCK, data, &reply, isOneWay ? IBinder::FLAG_ONEWAY : 0); }

这里通过一个IBinder发送消息给PowerMangerService,PowerMangerService接收到消息后处理如下函数

public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, WorkSource ws, String historyTag) {

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

private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,

WorkSource ws, String historyTag, int uid, int pid) { if (DEBUG_SPEW) { Slog.d(TAG, \lock=\+ Objects.hashCode(lock)

+ \.toHexString(flags)

+ \+ pid);

}

updatePowerStateLocked(); }

这里说明下在sys_log 中搜索acquireWakeLockInternal: lock= 字样可以知道在这段时间里那个应用持有wakelock

eg: PowerManagerService: acquireWakeLockInternal: lock=131758235, flags=0x1, tag=\

private void updatePowerStateLocked() { updateSuspendBlockerLocked(); }

private void updateSuspendBlockerLocked() {

final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);

final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked(); final boolean autoSuspend = !needDisplaySuspendBlocker;

final boolean interactive = mDisplayPowerRequest.isBrightOrDim();

// Disable auto-suspend if needed.

// FIXME We should consider just leaving auto-suspend enabled forever since // we already hold the necessary wakelocks.

if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) { setHalAutoSuspendModeLocked(false); }

// First acquire suspend blockers if needed.

if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) { mWakeLockSuspendBlocker.acquire();

mHoldingWakeLockSuspendBlocker = true; }

if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) { mDisplaySuspendBlocker.acquire();

mHoldingDisplaySuspendBlocker = true; }

if (mDecoupleHalInteractiveModeFromDisplayConfig) { if (interactive || mDisplayReady) {

setHalInteractiveModeLocked(interactive); } }

// Then release suspend blockers if needed.

if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) { mWakeLockSuspendBlocker.release();

mHoldingWakeLockSuspendBlocker = false; }

if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) { mDisplaySuspendBlocker.release();

mHoldingDisplaySuspendBlocker = false; }

// Enable auto-suspend if needed.

if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) { setHalAutoSuspendModeLocked(true); } }

这个函数很重要,包括psensor控制灭屏的基本逻辑也在这里,现在只看标红的函数。 1)

mWakeLockSuspendBlocker.acquire() 和 mDisplaySuspendBlocker.acquire()

在PowerManagerService的构造函数中有对mWakeLockSuspendBlocker和mDisplaySuspendBlocker赋值。

public PowerManagerService(Context context) { mWakeLockSuspendBlocker

createSuspendBlockerLocked(\ mDisplaySuspendBlocker

createSuspendBlockerLocked(\ }

private SuspendBlocker createSuspendBlockerLocked(String name) {

SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name); mSuspendBlockers.add(suspendBlocker); return suspendBlocker; }

= =

private final class SuspendBlockerImpl implements SuspendBlocker { public void acquire() {

nativeAcquireSuspendBlocker(mName); ----终于到JIN的调用了 } }

在com_android_server_power_PowerManagerService.cpp中定义

static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) { acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str()); }

在power.c中实现

acquire_wake_lock(int lock, const char* id) {

initialize_fds();

// ALOGI(\

if (g_error) return -g_error;

int fd;

if (lock == PARTIAL_WAKE_LOCK) {

fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK]; }

else {

return -EINVAL; }

return write(fd, id, strlen(id)); }

initialize_fds(void)

{

// XXX: should be this:

//pthread_once(&g_initialized, open_file_descriptors); // XXX: not this:

if (g_initialized == 0) {

if(open_file_descriptors(NEW_PATHS) < 0) open_file_descriptors(OLD_PATHS); g_initialized = 1; } }

const char * const NEW_PATHS[] = { \ \ };

2)关于文件/sys/power/wake_locksetHalAutoSuspendModeLocked函数

的调用已经看完了,下面再看

private void setHalAutoSuspendModeLocked(boolean enable) { nativeSetAutoSuspend(enable); }

在com_android_server_power_PowerManagerService.cpp中定义

static void nativeSetAutoSuspend(JNIEnv *env, jclass clazz, jboolean enable) { if (enable) {

ALOGD_IF_SLOW(100, \screen off\

autosuspend_enable(); } else {

ALOGD_IF_SLOW(100, \screen on\

autosuspend_disable(); } }

在 autosuspend.c中 int autosuspend_enable(void) {

int ret;

ret = autosuspend_init(); if (ret) {

return ret; }

ALOGV(\

if (autosuspend_enabled) { return 0; }

ret = autosuspend_ops->enable(); if (ret) {

return ret; }

autosuspend_enabled = true; return 0; }

static int autosuspend_init(void) {

autosuspend_ops = autosuspend_earlysuspend_init(); return 0; }

struct autosuspend_ops *autosuspend_earlysuspend_init(void) {

char buf[80]; int ret;

sPowerStatefd = open(EARLYSUSPEND_SYS_POWER_STATE, O_RDWR);

if (sPowerStatefd < 0) {

strerror_r(errno, buf, sizeof(buf));

ALOGW(\ return NULL; }

start_earlysuspend_thread();

return &autosuspend_earlysuspend_ops;

err_write:

close(sPowerStatefd); return NULL; }

struct autosuspend_ops autosuspend_earlysuspend_ops = { .enable = autosuspend_earlysuspend_enable, .disable = autosuspend_earlysuspend_disable, };

static int autosuspend_earlysuspend_enable(void) {

char buf[80]; int ret;

ALOGV(\

ret = write(sPowerStatefd, pwr_state_mem, strlen(pwr_state_mem)); if (ret < 0) {

strerror_r(errno, buf, sizeof(buf));

ALOGE(\ goto err; }

return ret; }

#define EARLYSUSPEND_SYS_POWER_STATE \\ static const char *pwr_state_mem = \到此调用完成

本文来源:https://www.bwwdw.com/article/a4ao.html

Top