课程答疑和新课信息:QQ交流群:422901085进行课程讨论
FrameWork入门课视频链接:https://edu.csdn.net/course/detail/30298
FrameWork实战课1视频链接:https://edu.csdn.net/course/detail/30275
FrameWork跨进程通信视频链接:https://edu.csdn.net/course/detail/35911
专题博客系列:
Android 8.1 zygote 启动过程源码
Android Framework实战视频–Zygote的fork进程篇
Android Framework实战视频–SystemServer启动篇
Android Framework实战视频–SystemServer启动FallbackHome篇
Android Framework实战视频–FallbackHome进程启动及Activity启动篇
Android Framework实战视频–FallbackHome结束启动Launcher篇
Android Framework实战视频–BootAnimation的启动源码分析(Android8.1)
Android Framework实战视频–init进程的bootanimation启动源码分析(补充Android 10部分的BootAnimation的启动源码分析)
提示:代码基于Android 8.1
代码路径介绍哦:
bootanimation frameworks/base/cmds/bootanimation/
surfaceflinger frameworks/native/services/surfaceflinger/
init system/core/init/
启动流程详细分析:
内核起来后会启动第一个进程,即init进程。
init进程会根据init.rc配置启动surfaceflinger进程。
service surfaceflinger /system/bin/surfaceflinger class main user system group graphics drmrpc onrestart restart zygote
surfaceflinger进程便启动了,跟着就会跑进程的main()函数。
frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int argc, char** argv) { .... // instantiate surfaceflinger sp<SurfaceFlinger> flinger = new SurfaceFlinger();//创建surfaceflinger服务实例 .... flinger->init(); // publish surface flinger sp<IServiceManager> sm(defaultServiceManager()); sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//注册到service manager里 // run in this thread flinger->run();//开跑 return 0; }
首先new一个SurfaceFlinger实例,然后init,然后run
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
// Do not call property_set on main thread which will be blocked by init
// Use StartPropertySetThread instead.
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger’s main thread ready to run. "
“Initializing graphics H/W…”);
// Inform native graphics APIs whether the present timestamp is supported: if (getHwComposer().hasCapability( HWC2::Capability::PresentFenceIsNotReliable)) { mStartPropertySetThread = new StartPropertySetThread(false); } else { 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(false), mTimestampPropertyValue(timestampPropertyValue) {}
status_t StartPropertySetThread::Start() {
return run(“SurfaceFlinger::StartPropertySetThread”, PRIORITY_NORMAL);
}
bool StartPropertySetThread::threadLoop() {
// Set property service.sf.present_timestamp, consumer need check its readiness
property_set(kTimestampProperty, mTimestampPropertyValue ? “1” : “0”);
// Clear BootAnimation exit flag
property_set(“service.bootanim.exit”, “0”);//关键属性
// Start BootAnimation if not started
property_set(“ctl.start”, “bootanim”);//关键属性
// Exit immediately
return false;
}
这样bootanim进程就会启动?凭什么设置了一个属性就启动了?那么下面我们来看,/system/core/init/init.cpp ,在看init进程的init.cpp的main函数中:
int main(int argc, char** argv) {
…
property_load_boot_defaults(); export_oem_lock_status(); start_property_service(); //start_property_service set_usb_controller();
}
下面来来看看start_property_service方法,在/system/core/init/property_service.cpp:
main函数中start_property_service(),在这个函数中注册一个epoll handle 的机制 register_epoll_handler():
666 void start_property_service() { 667 property_set("ro.property_service.version", "2"); 668 669 property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 670 0666, 0, 0, NULL); 671 if (property_set_fd == -1) { 672 PLOG(ERROR) << "start_property_service socket creation failed"; 673 exit(1); 674 } 675 676 listen(property_set_fd, 8); 677 678 register_epoll_handler(property_set_fd, handle_property_set_fd); 679 }
init进程会使用epoll机制来轮询事件,其中一个事件是系统属性值被修改。得到该事件后,会执行handle_property_set_fd(),代码如下:通过handle_property_set_fd():
static void handle_property_set_fd() {
…
switch (cmd) {
409 case PROP_MSG_SETPROP: {
410 char prop_name[PROP_NAME_MAX];
411 char prop_value[PROP_VALUE_MAX];
412
413 if (!socket.RecvChars(prop_name, PROP_NAME_MAX, &timeout_ms) ||
414 !socket.RecvChars(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_set(socket, prop_value, prop_value, true);
423 break;
424 }
该函数会进执行handle_property_set()
static void handle_property_set(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/init.cpp,传入的参数msg.name=ctl.start,msg.value=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 service '" << name << "'"; 183 return; 184 } 185 186 if (msg == "start") { 187 svc->Start(); 188 } else if (msg == "stop") { 189 svc->Stop(); 190 } else if (msg == "restart") { 191 svc->Restart(); 192 } else { 193 LOG(ERROR) << "unknown control msg '" << msg << "'"; 194 } 195 } 该函数首先调用FindServiceByName,从service_list中查询要启动的服务是否有存在,若存在,返回服务的相关信息。因为init.rc中有bootanimation的定义,因此在init进程执行parse_config()时,会将该服务添加到service_list中,所以bootanimation应用是存在的。然后,如果找到了该服务,就调用service_start启动服务。
把service.bootanim.exit属性设为0,这个属性bootanimation进程里会周期检查,=1时就退出动画,这里=0表示要播放动画。
后面通过ctl.start的命令启动bootanimation进程,动画就开始播放了。
下面来到bootanimation的实现
frameworks/base/cmds/bootanimation/bootanimation_main.cpp
int main(int argc, char** argv) { sp<ProcessState> proc(ProcessState::self()); ProcessState::self()->startThreadPool(); // create the boot animation object sp<BootAnimation> boot = new BootAnimation();//创建BootAnimation实例 IPCThreadState::self()->joinThreadPool();//binder线程池,与surfaceflinger通信用的。 } return 0; }