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

2021/10/4 20:40:59

本文主要是介绍Android Framework实战视频--BootAnimation的启动源码分析(Android8.1),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

课程答疑和新课信息: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 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;
}


这篇关于Android Framework实战视频--BootAnimation的启动源码分析(Android8.1)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程