2023年12月9日发(作者:笔调)
AndroidFramework实战视频--BootAnimation的启动源码分析(An。。。
Android Framework实战视频–BootAnimation的启动源码分析
提示:代码基于Android 8.1
代码路径介绍哦:
bootanimation frameworks/ba/cmds/bootanimation/
surfaceflinger frameworks/native/rvices/surfaceflinger/
init system/core/init/
启动流程详细分析:
内核起来后会启动第一个进程,即init进程。
init进程会根据配置启动surfaceflinger进程。
rvice surfaceflinger /system/bin/surfaceflinger
class main
ur system
group graphics drmrpc
onrestart restart zygote
surfaceflinger进程便启动了,跟着就会跑进程的main()函数。
frameworks/native/rvices/surfaceflinger/main_
int main(int argc, char** argv) {
....
// instantiate surfaceflinger
sp
....
flinger->init();
// publish surface flinger
sp
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, fal);//注册到rvice manager里
// run in this thread
flinger->run();//开跑
return 0;
}
首先new一个SurfaceFlinger实例,然后init,然后run
frameworks/native/rvices/surfaceflinger/
// Do not call property_t on main thread which will be blocked by init
// U StartPropertySetThread instead.
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger’s main thread ready to run. "
“Initializing graphics H/W…”);
// Inform native graphics APIs whether the prent timestamp is supported:
if (getHwCompor().hasCapability(
HWC2::Capability::PrentFenceIsNotReliable)) {
mStartPropertySetThread = new StartPropertySetThread(fal);
} el {
mStartPropertySetThread = new StartPropertySetThread(true);
}
if (mStartPropertySetThread->Start() != NO_ERROR) { //真正启动设置bootanimation的属性线程
ALOGE("Run StartPropertySetThread failed!");
}
ALOGV("Done initializing");
}
初始化graphics之后,mStartPropertySetThread()播放开机动画。//注意已经不是以前的startBootAnim方法
StartPropertySetThread如下定义:
StartPropertySetThread::StartPropertySetThread(bool timestampPropertyValue):
Thread(fal), mTimestampPropertyValue(timestampPropertyValue) {}
status_t StartPropertySetThread::Start() {
return run(“SurfaceFlinger::StartPropertySetThread”, PRIORITY_NORMAL);
}
bool StartPropertySetThread::threadLoop() {
// Set property t_timestamp, consumer need check its readiness
property_t(kTimestampProperty, mTimestampPropertyValue ? “1” : “0”);
// Clear BootAnimation exit flag
property_t(“”, “0”);//关键属性
// Start BootAnimation if not started
property_t(“”, “bootanim”);//关键属性
// Exit immediately
return fal;
}
这样bootanim进程就会启动?凭什么设置了一个属性就启动了?那么下面我们来看,/system/core/init/ ,在看init进程的
的main函数中:
int main(int argc, char** argv) {
…
property_load_boot_defaults();
export_oem_lock_status();
start_property_rvice(); //start_property_rvice
t_usb_controller();
}
下面来来看看start_property_rvice方法,在/system/core/init/property_:
main函数中start_property_rvice(),在这个函数中注册一个epoll handle 的机制 register_epoll_handler():
666 void start_property_rvice() {
667 property_t("ty_n", "2");
668
669 property_t_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
670 0666, 0, 0, NULL);
671 if (property_t_fd == -1) {
672 PLOG(ERROR) << "start_property_rvice socket creation failed";
673 exit(1);
674 }
675
676 listen(property_t_fd, 8);
677
678 register_epoll_handler(property_t_fd, handle_property_t_fd);
679 }
init进程会使用epoll机制来轮询事件,其中一个事件是系统属性值被修改。得到该事件后,会执行handle_property_t_fd(),代码如下:
通过handle_property_t_fd():
static void handle_property_t_fd() {
…
switch (cmd) {
409 ca PROP_MSG_SETPROP: {
410 char prop_name[PROP_NAME_MAX];
411 char prop_value[PROP_VALUE_MAX];
412
413 if (!ars(prop_name, PROP_NAME_MAX, &timeout_ms) ||
414 !ars(prop_value, PROP_VALUE_MAX, &timeout_ms)) {
415 PLOG(ERROR) << “sys_prop(PROP_MSG_SETPROP): error while reading name/value from the socket”;
416 return;
417 }
418
419 prop_name[PROP_NAME_MAX-1] = 0;
420 prop_value[PROP_VALUE_MAX-1] = 0;
421
422 handle_property_t(socket, prop_value, prop_value, true);
423 break;
424 }
该函数会进执行handle_property_t()
static void handle_property_t(SocketConnection& socket,
const std::string& name,
const std::string& value,
bool legacy_protocol) {
。。。。。。
handle_control_message(name.c_str() + 4, value.c_str());
。。。。。。
}
该函数会进一步执行handle_control_message(),在/system/core/init/,传入的参数=,=bootanim
179 void handle_control_message(const std::string& msg, const std::string& name) {
180 Service* svc = ServiceManager::GetInstance().FindServiceByName(name);
181 if (svc == nullptr) {
182 LOG(ERROR) << "no such rvice '" << name << "'";
183 return;
184 }
185
186 if (msg == "start") {
187 svc->Start();
188 } el if (msg == "stop") {
189 svc->Stop();
190 } el if (msg == "restart") {
191 svc->Restart();
192 } el {
193 LOG(ERROR) << "unknown control msg '" << msg << "'";
194 }
195 }
该函数首先调用FindServiceByName,从rvice_list中查询要启动的服务是否有存在,若存在,返回服务的相关信息。因为中有bootanimation的定义,
因此在init进程执行par_config()时,会将该服务添加到rvice_list中,所以bootanimation应用是存在的。然后,如果找到了该服务,就调用rvice_start启
动服务。
把属性设为0,这个属性bootanimation进程里会周期检查,=1时就退出动画,这里=0表示要播放动画。
后面通过的命令启动bootanimation进程,动画就开始播放了。
下面来到bootanimation的实现
frameworks/ba/cmds/bootanimation/bootanimation_
int main(int argc, char** argv)
{
sp
ProcessState::lf()->startThreadPool();
// create the boot animation object
sp
IPCThreadState::lf()->joinThreadPool();//binder线程池,与surfaceflinger通信用的。
}
return 0;
}
本文发布于:2023-12-09 21:34:33,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/zhishi/a/1702128873116504.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:AndroidFramework实战视频--BootAnimation的启动源码分析(An。。。_百.doc
本文 PDF 下载地址:AndroidFramework实战视频--BootAnimation的启动源码分析(An。。。_百.pdf
留言与评论(共有 0 条评论) |