1 关于APM
APM是电源管理的一种实现方案,在linux平台上,qtopia实际上并不关心电源管理的具体实现,它只是通过访问文件/proc/apm获取相关信息参数,本文也只是讲述qtopia获取apm相关参数后的处理流程。
2 qtopia中的相关类
我们先看看qtopia中涉及到的类,QPowerStatus、QPowserStatusManager、QWSScreenSaver、 PowerManagerTask、QtopiaPowerManager、PhonePowerManager,它们的组织关系如下图示。
QPowerStatus,一个独立的类,用于提供一些状态信息。
QPowerStatusManager,派生自QObject的类,它定义了一些接口,如APMEnabled、getProcApmStatus、getStatus等。
PowerManagerTask,派生自QPowerStatusManager,它主要完成了两个接口,一是构造函数,二是定义了槽函数powerStatusChanged。
QWSScreenSaver,一个纯虚函数,仅定义了两个接口。
QtopiaPowerManager,qtopia电源管理类,实现了电源管理的基本功能,定义了用于派生类待于实现的接口。
PhonePowerManager,phone版的电源管理实现函数。
3 处理流程
下面具体看看电源管理方面的处理流程。
(1) QTOPIA_TASK(PowerManagerTask,PowerManagerTask)
该宏负责初始化一个task,也就是执行一个绑定的函数,其执行过程在主函数main之前执行,可以想当然的理解为声明了一个全局变量(只不过这里执行一段代码而已),在这里就是要执行PowerManagerTask的构造函数。至于QTOPIA_TASK在此不再赘述,详见代码。
构造函数执行如下:
QPowerStatusManager *manager = new QPowerStatusManager(this);
QObject::connect(manager, SIGNAL(powerStatusChanged(const QPowerStatus &)),
this, SLOT(powerStatusChanged(const QPowerStatus &)));
QPowerStatus status = manager->readStatus();
powerStatusChanged(status); // force an update
上述代码创建了QPowerStatusManager,并将其powerStatusChanged信号帮定到PowerManagerTask的powerStatusChanged槽上。并读取一次状态信息,调用了一次槽函数。
(2) QPowerStatusManager构造
该构造函数代码如下:
if(!ps) ps = new QPowerStatus;
仅仅创建了QPowerStatus的实例。
(3) QPowerStatusManager的两个函数
函数connectNotify,当某对象被connect连接时该函数被调用,即PowerManagerTask构造函数中会触发该函数的执行,connectNotify函数里面最重要的就是创建了一个timer。
函数timerEvent,它实际上是一个超时函数,connectNotify里创建了一个timer定时器,timerEvent函数就会定期被执行,其函数主体如下
readStatus();
if(oldStatus != *ps) {
oldStatus = *ps;
emit powerStatusChanged(oldStatus);
}
上述代码实质上就是不断检测电源状态,一旦状态发生改变,就发出信号powerStatusChanged。
(4) 槽函数powerStatusChanged
步骤3里面得知会发出信号函数,那该信号对应的槽在哪里那?这里的信号槽的绑定在步骤1里完成的,当发出信号powerStatusChanged时会执行 PowerManagerTask::powerStatusChanged函数,该函数是虚函数,具体就会执行到派生类中的函数,如下:
void QtopiaPowerManager::powerStatusChanged(const QPowerStatus &ps)
{
QPowerStatus status = ps;
applyLightSettings(&status);
}
applyLightSettings是一个全局函数,它会保存一些配置,并发出消息
QtopiaServiceRequest eB("QtopiaPowerManager", "setBacklight(int)" );
eB << -3; //forced on
eB.send();
QtopiaServiceRequest e("QtopiaPowerManager", "setIntervals(int,int,int)" );
#ifndef QTOPIA_PHONE
e << i_dim << i_lightoff << i_suspend;
#else
e << i_dim << i_lightoff << i_home;
#endif
e.send();
最终会调用QtopiaPowerManager::setBacklight()和QtopiaPowerManager::setIntervals()
分别用于设置背光和屏保时间间隔。
阅读(1753) | 评论(0) | 转发(0) |