init.cppAOSP/system/core/init/init.cpp

SurfaceFlinger是由init进程启动的

int main(int argc, char** argv) {

...

if (bootmode == "charger") {

am.QueueEventTrigger("charger");

} else {

am.QueueEventTrigger("late-init");

}

...

}

init.rcAOSP/system/core/rootdir/init.rc

on late-init

...

trigger boot

...

on boot

...

class_start core

...

builtin_functionsAOSP/system/core/init/builtins.cpp

可以看出class_start 命令有一个对应的执行函数 do_class_start

onst BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {

constexpr std::size_t kMax = std::numeric_limits<:size_t>::max();

// clang-format off

static const Map builtin_functions = {

{"bootchart", {1, 1, do_bootchart}},

{"chmod", {2, 2, do_chmod}},

{"chown", {2, 3, do_chown}},

{"class_reset", {1, 1, do_class_reset}},

{"class_restart", {1, 1, do_class_restart}},

{"class_start", {1, 1, do_class_start}},

}

static int do_class_start(const std::vector<:string>& args) {

/* Starting a class does not start services

* which are explicitly disabled. They must

* be started individually.

*/

ServiceManager::GetInstance().

ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });

return 0;

}

@services.cpp

bool Service::StartIfNotDisabled() { //定义为disabled不会被启动

if (!(flags_ & SVC_DISABLED)) {

return Start();

} else {

flags_ |= SVC_DISABLED_START;

}

return true;

}

surfaceflinger.rc    AOSP/frameworks/native/services/surfaceflinger/surfaceflinger.rc

service surfaceflinger /system/bin/surfaceflinger

class core animation

user system

group graphics drmrpc readproc

onrestart restart zygote

writepid /dev/stune/foreground/tasks

socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0

socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0

socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0

通过mk文件  LOCAL_MODULE := surfaceflinger 可以寻找到相关的cpp文件

main_surfaceflinger.cppAOSP/frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int, char**) {

...

// instantiate surfaceflinger

sp flinger = new SurfaceFlinger();

...

// initialize before clients can connect

flinger->init();

...

// run surface flinger in this thread

flinger->run();

return 0;

}

flinger->init()

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");

}

mStartPropertySetThread->Start()AOSP/frameworks/native/services/surfaceflinger/StartPropertySetThread.cpp

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进程就会启动

为什么设置属性就会启动bootanim服务

init.cppAOSP/system/core/init/init.cpp

int main(int argc, char** argv) {

...

start_property_service(); //start_property_service

...

}

start_property_service     AOSP/system/core/init/property_service.cpp

void start_property_service() {

property_set("ro.property_service.version", "2");

property_set_fd = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,

false, 0666, 0, 0, nullptr, sehandle);

if (property_set_fd == -1) {

PLOG(ERROR) << "start_property_service socket creation failed";

exit(1);

}

listen(property_set_fd, 8);

register_epoll_handler(property_set_fd, handle_property_set_fd);

}

在这个函数中注册一个epoll handle 的机制 register_epoll_handler()  简单的来说就是通过监听socket轮询  如果有属性设置上来了  就调用handle_property_set_fd

handle_property_set_fd

static void handle_property_set_fd() {

...

switch (cmd) {

case PROP_MSG_SETPROP: {

....

return;

}

...

handle_property_set(socket, prop_value, prop_value, true);

break;

}

}

该函数会进执行handle_property_set()

handle_property_set

static void handle_property_set(SocketConnection& socket,

const std::string& name,

const std::string& value,

bool legacy_protocol) {

...

if (android::base::StartsWith(name, "ctl.")) {

if (check_control_mac_perms(value.c_str(), source_ctx, &cr)) {

handle_control_message(name.c_str() + 4, value.c_str());

if (!legacy_protocol) {

socket.SendUint32(PROP_SUCCESS);

}

} ...

}

这里可以看到在判断是否以  ctl.开头接着调用handle_control_message

godv@godv-OptiPlex-7070:~/godv/AOSP/android-8.1.0_r1/system/core/init$ grep "handle_control_message" ./ -rn

./init.cpp:209:void handle_control_message(const std::string& msg, const std::string& name) {

./init.h:35:void handle_control_message(const std::string& msg, const std::string& arg);

./property_service.cpp:427: handle_control_message(name.c_str() + 4, value.c_str());

这样就能查询到相关方法出现的位置  这里我们可以定位到这是init.cpp中的方法

handle_control_messageAOSP/system/core/init/init.cpp

void handle_control_message(const std::string& msg, const std::string& name) {

Service* svc = ServiceManager::GetInstance().FindServiceByName(name);

if (svc == nullptr) {

LOG(ERROR) << "no such service '" << name << "'";

return;

}

if (msg == "start") {

svc->Start();

} else if (msg == "stop") {

svc->Stop();

} else if (msg == "restart") {

svc->Restart();

} else {

LOG(ERROR) << "unknown control msg '" << msg << "'";

}

}

查询相关service  调用start

bootanim.rc    frameworks/base/cmds/bootanimation/bootanim.rc

service bootanim /system/bin/bootanimation

class core animation

user graphics

group graphics audio

disabled

oneshot

writepid /dev/stune/top-app/tasks

根据mk文件找到启动文件  bootanimation_main.cpp

main()AOSP/frameworks/base/cmds/bootanimation/bootanimation_main.cpp

int main()

{

setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);

bool noBootAnimation = bootAnimationDisabled();

ALOGI_IF(noBootAnimation, "boot animation disabled");

if (!noBootAnimation) {

...

waitForSurfaceFlinger();

// create the boot animation object

sp boot = new BootAnimation(new AudioAnimationCallbacks());

ALOGV("Boot animation set up. Joining pool.");

IPCThreadState::self()->joinThreadPool();

}

ALOGV("Boot animation exit");

return 0;

}

进入main函数首先判断开机动画是否被禁用bootAnimationDisabled()

如果实在无法找到函数调用出可以使用    grep "xxx" ./ -rn

godv@godv-OptiPlex-7070:~/godv/AOSP/android-8.1.0_r1/frameworks/base$ grep "bootAnimationDisabled" ./ -rn

./cmds/bootanimation/iot/iotbootanimation_main.cpp:79: if (bootAnimationDisabled()) {

./cmds/bootanimation/BootAnimationUtil.h:20:bool bootAnimationDisabled();

./cmds/bootanimation/BootAnimationUtil.cpp:28:bool bootAnimationDisabled() {

./cmds/bootanimation/bootanimation_main.cpp:149: bool noBootAnimation = bootAnimationDisabled();

在这里我们可以分析bootAnimationDisabled被定义在BootAnimationUtil.cpp里面

bootAnimationDisabled()AOSP/frameworks/base/cmds/bootanimation/BootAnimationUtil.cpp

bool bootAnimationDisabled() {

char value[PROPERTY_VALUE_MAX];

property_get("debug.sf.nobootanimation", value, "0");

if (atoi(value) > 0) {

return true;

}

property_get("ro.boot.quiescent", value, "0");

return atoi(value) > 0;

}

由此可以看出默认状态下返回的是false  继续分析sp boot = new BootAnimation(new AudioAnimationCallbacks());

1 首先看构造器

BootAnimation(sp callbacks)AOSP/frameworks/base/cmds/bootanimation/BootAnimation.cpp

BootAnimation::BootAnimation(sp callbacks)

: Thread(false), mClockEnabled(true), mTimeIsAccurate(false),

mTimeFormat12Hour(false), mTimeCheckThread(NULL), mCallbacks(callbacks) {

mSession = new SurfaceComposerClient();

std::string powerCtl = android::base::GetProperty("sys.powerctl", "");

if (powerCtl.empty()) {

mShuttingDown = false;

} else {

mShuttingDown = true;

}

}

2sp指针在对象第一次初始化的过程中调用onFirstRef()

onFirstRef()

void BootAnimation::onFirstRef() {

status_t err = mSession->linkToComposerDeath(this);

ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));

if (err == NO_ERROR) {

run("BootAnimation", PRIORITY_DISPLAY);·

}

}

在这可以看到调用了run方法  在查看文件  BootAnimation.h头文件BootAnimation继承自  Thread这样就可以理解这个run方法了

class BootAnimation : public Thread, public IBinder::DeathRecipient

{

...

}

既然是线程类肯定就要有 readyToRun()

这个方法里面主要创建了surface  和初始化opengl 和 egl

status_t BootAnimation::readyToRun() {

...

static const char* bootFiles[] = {OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE};

static const char* shutdownFiles[] =

{OEM_SHUTDOWNANIMATION_FILE, SYSTEM_SHUTDOWNANIMATION_FILE};

for (const char* f : (!mShuttingDown ? bootFiles : shutdownFiles)) {

if (access(f, R_OK) == 0) {

mZipFileName = f;

return NO_ERROR;

}

}

return NO_ERROR;

}

bootFiles开机  shutdownFiles关机  重要看bootFiles[]中的两个字符串  这两个字符串就代表了zip放置的路径

static const char OEM_BOOTANIMATION_FILE[] = "/oem/media/bootanimation.zip";

static const char SYSTEM_BOOTANIMATION_FILE[] = "/system/media/bootanimation.zip";

接下来看  threadLoop()

bool BootAnimation::threadLoop()

{

bool r;

// We have no bootanimation file, so we use the stock android logo

// animation.

if (mZipFileName.isEmpty()) {

r = android();

} else {

r = movie();

}

...

return r;

}

android()  没有文件使用opengl绘制  movie则代表opengl渲染zip文件  此时开机动画就被播放出来了

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐