欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Framework实战视频--BootAnimation的启动源码分析(Android8.1)

程序员文章站 2022-06-06 09:21:14
...

课程答疑和新课信息:QQ交流群:422901085进行课程讨论
FrameWork入门课视频链接:https://edu.csdn.net/course/detail/30298
FrameWork实战课1视频链接:https://edu.csdn.net/course/detail/30275
专题博客系列:
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 Framework实战视频–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;
}