安卓12开机动画Bootanimation源码分析-启动流程
1.配置文件路径介绍
目录: bootanimation: frameworks/base/cmds/bootanimation/ surfaceflinger : frameworks/native/services/surfaceflinger/ init : system/core/init/ 文件: main_surfaceflinger.cpp : frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
2.Bootanimation服务启动分析
内核起来后会启动第一个进程,即init进程。 init进程会根据配置bootanim.rc还有surfaceflinger.rc(以前都包含在init.rc中)启动surfaceflinger进程。由于bootanim.rc文件中包含 disabled,所以现在并不会启动。 bootanim.rc文件:
service bootanim /system/bin/bootanimation
class core animation
user graphics
group graphics audio
disabled
oneshot
ioprio rt 0
task_profiles MaxPerformance
surfaceflinger.rc文件:
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
capabilities SYS_NICE
onrestart restart --only-if-running zygote
task_profiles HighPerformance
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
可以看出他们都是/system/bin/下面的服务。 首先执行main_surfaceflinger.cpp里面的main(),里面会创建SurfaceFlinger对象。
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
后面会调用
flinger->init();
flinger->run();
接下来打开同目录下的SurfaceFlinger.cpp,看他的init()执行了什么。
mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
if (mStartPropertySetThread->Start() != NO_ERROR) {
ALOGE("Run StartPropertySetThread failed!");
}
发现调用了StartPropertySetThread对象的start(),开启了一个线程。 接下来打开同目录下的StartPropertySetThread.cpp,看他的线程执行了什么。
#include <cutils/properties.h>
#include "StartPropertySetThread.h"
namespace android {
StartPropertySetThread::StartPropertySetThread(bool timestampPropertyValue):
Thread(false), mTimestampPropertyValue(timestampPropertyValue) {}
status_t StartPropertySetThread::Start() {
return run("SurfaceFlinger::StartPropertySetThread", PRIORITY_NORMAL);
}
bool StartPropertySetThread::threadLoop() {
property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");
property_set("service.bootanim.exit", "0");
property_set("service.bootanim.progress", "0");
property_set("ctl.start", "bootanim");
return false;
}
}
线程开启后会执行threadLoop(),可以发现是 property_set(“ctl.start”, “bootanim”);启动了bootanim服务。为什么设置了一个属性值后会启动bootanim服务呢? 我们再回到init进程中,打开init.cpp文件。首先会执行里面的SecondStageMain(int argc, char** argv),我们看一下里面执行了什么。
PropertyInit();
StartPropertyService(&property_fd);
while (true) {
auto epoll_timeout = std::optional<std::chrono::milliseconds>{};
auto shutdown_command = shutdown_state.CheckShutdown();
if (shutdown_command) {
LOG(INFO) << "Got shutdown_command '" << *shutdown_command
<< "' Calling HandlePowerctlMessage()";
HandlePowerctlMessage(*shutdown_command);
shutdown_state.set_do_shutdown(false);
}
if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
am.ExecuteOneCommand();
}
if (!IsShuttingDown()) {
auto next_process_action_time = HandleProcessActions();
if (next_process_action_time) {
epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
*next_process_action_time - boot_clock::now());
if (*epoll_timeout < 0ms) epoll_timeout = 0ms;
}
}
if (!(prop_waiter_state.MightBeWaiting() || Service::is_exec_service_running())) {
if (am.HasMoreCommands()) epoll_timeout = 0ms;
}
auto pending_functions = epoll.Wait(epoll_timeout);
if (!pending_functions.ok()) {
LOG(ERROR) << pending_functions.error();
} else if (!pending_functions->empty()) {
ReapAnyOutstandingChildren();
for (const auto& function : *pending_functions) {
(*function)();
}
}
if (!IsShuttingDown()) {
HandleControlMessages();
SetUsbController();
}
}
可以看到,执行了一个方法StartPropertyService(&property_fd); 。对应的文件是property_service.cpp(与init.cpp同目录)。还有一段while (true) {},里面会在条件为true的情况下不断执行 HandleControlMessages();接下来我们看看property_service.cpp里面执行了什么。 在里面搜索方法 StartPropertyService。发现里面执行了
void StartPropertyService(int* epoll_socket) {
InitPropertySet("ro.property_service.version", "2");
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockets) != 0) {
PLOG(FATAL) << "Failed to socketpair() between property_service and init";
}
*epoll_socket = from_init_socket = sockets[0];
init_socket = sockets[1];
StartSendingMessages();
if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
false, 0666, 0, 0, {});
result.ok()) {
property_set_fd = *result;
} else {
LOG(FATAL) << "start_property_service socket creation failed: " << result.error();
}
listen(property_set_fd, 8);
auto new_thread = std::thread{PropertyServiceThread};
property_service_thread.swap(new_thread);
}
接下来在里面搜索方法 StartSendingMessages。发现里面只是进行了数据赋值。
void StartSendingMessages() {
auto lock = std::lock_guard{accept_messages_lock};
accept_messages = true;
}
我们接下来在里面搜索PropertyServiceThread。发现它是一个方法。
static void PropertyServiceThread() {
Epoll epoll;
if (auto result = epoll.Open(); !result.ok()) {
LOG(FATAL) << result.error();
}
if (auto result = epoll.RegisterHandler(property_set_fd, handle_property_set_fd);
!result.ok()) {
LOG(FATAL) << result.error();
}
if (auto result = epoll.RegisterHandler(init_socket, HandleInitSocket); !result.ok()) {
LOG(FATAL) << result.error();
}
while (true) {
auto pending_functions = epoll.Wait(std::nullopt);
if (!pending_functions.ok()) {
LOG(ERROR) << pending_functions.error();
} else {
for (const auto& function : *pending_functions) {
(*function)();
}
}
}
}
epoll.RegisterHandler(property_set_fd, handle_property_set_fd);代表注册了一个回调函数,会回调执行handle_property_set_fd方法。 我们接下来在里面搜索handle_property_set_fd方法,发现里面会执行HandlePropertySet方法。
uint32_t result =
HandlePropertySet(prop_name, prop_value, source_context, cr, nullptr, &error);
我们接下来在里面搜索HandlePropertySet方法,发现里面出现关键信息。以"ctl."开始的会执行 SendControlMessage方法。
if (StartsWith(name, "ctl.")) {
return SendControlMessage(name.c_str() + 4, value, cr.pid, socket, error);
}
我们接下来在里面搜索SendControlMessage方法,发现里面和msg相关的只有QueueControlMessage方法。
bool queue_success = QueueControlMessage(msg, name, pid, fd);
我们接下来在里面搜索QueueControlMessage方法,发现没有搜到,于是在init.rc里面搜索,QueueControlMessage方法。
bool QueueControlMessage(const std::string& message, const std::string& name, pid_t pid, int fd) {
auto lock = std::lock_guard{pending_control_messages_lock};
if (pending_control_messages.size() > 100) {
LOG(ERROR) << "Too many pending control messages, dropped '" << message << "' for '" << name
<< "' from pid: " << pid;
return false;
}
pending_control_messages.push({message, name, pid, fd});
WakeMainInitThread();
return true;
}
可以发现调用了pending_control_messages的push方法。在里面搜索pending_control_messages得知它是一个队列。
static std::queue<PendingControlMessage> pending_control_messages;
上面我们说到在条件为true的情况下会不断执行 HandleControlMessages()。
static void HandleControlMessages() {
auto lock = std::unique_lock{pending_control_messages_lock};
if (!pending_control_messages.empty()) {
auto control_message = pending_control_messages.front();
pending_control_messages.pop();
lock.unlock();
bool success = HandleControlMessage(control_message.message, control_message.name,
control_message.pid);
uint32_t response = success ? PROP_SUCCESS : PROP_ERROR_HANDLE_CONTROL_MESSAGE;
if (control_message.fd != -1) {
TEMP_FAILURE_RETRY(send(control_message.fd, &response, sizeof(response), 0));
close(control_message.fd);
}
lock.lock();
}
if (!pending_control_messages.empty()) {
WakeMainInitThread();
}
}
里面执行了 pending_control_messages.pop()方法弹出一个消息,然后HandleControlMessage(control_message.message, control_message.name, control_message.pid)进行消费,我们搜索一下该方法。
static bool HandleControlMessage(std::string_view message, const std::string& name,
pid_t from_pid) {
std::string cmdline_path = StringPrintf("proc/%d/cmdline", from_pid);
std::string process_cmdline;
if (ReadFileToString(cmdline_path, &process_cmdline)) {
std::replace(process_cmdline.begin(), process_cmdline.end(), '\0', ' ');
process_cmdline = Trim(process_cmdline);
} else {
process_cmdline = "unknown process";
}
Service* service = nullptr;
auto action = message;
if (ConsumePrefix(&action, "interface_")) {
service = ServiceList::GetInstance().FindInterface(name);
} else {
service = ServiceList::GetInstance().FindService(name);
}
if (service == nullptr) {
LOG(ERROR) << "Control message: Could not find '" << name << "' for ctl." << message
<< " from pid: " << from_pid << " (" << process_cmdline << ")";
return false;
}
const auto& map = GetControlMessageMap();
const auto it = map.find(action);
if (it == map.end()) {
LOG(ERROR) << "Unknown control msg '" << message << "'";
return false;
}
const auto& function = it->second;
if (auto result = function(service); !result.ok()) {
LOG(ERROR) << "Control message: Could not ctl." << message << " for '" << name
<< "' from pid: " << from_pid << " (" << process_cmdline
<< "): " << result.error();
return false;
}
LOG(INFO) << "Control message: Processed ctl." << message << " for '" << name
<< "' from pid: " << from_pid << " (" << process_cmdline << ")";
return true;
}
里面首先将 Service* service = nullptr;以及action = message;然后执行了 service = ServiceList::GetInstance().FindService(name);根据名称找到对应的服务,这里的name就是bootanim。然后const auto& map = GetControlMessageMap();最后执行了 const auto it = map.find(action); 我们在里面搜索GetControlMessageMap()
static const std::map<std::string, ControlMessageFunction, std::less<>>& GetControlMessageMap() {
static const std::map<std::string, ControlMessageFunction, std::less<>> control_message_functions = {
{"sigstop_on", [](auto* service) { service->set_sigstop(true); return Result<void>{}; }},
{"sigstop_off", [](auto* service) { service->set_sigstop(false); return Result<void>{}; }},
{"oneshot_on", [](auto* service) { service->set_oneshot(true); return Result<void>{}; }},
{"oneshot_off", [](auto* service) { service->set_oneshot(false); return Result<void>{}; }},
{"start", DoControlStart},
{"stop", DoControlStop},
{"restart", DoControlRestart},
};
return control_message_functions;
}
所以最后会执行 DoControlStart方法, function(service) 这里的function就是 DoControlStart方法然后启动服务。
static Result<void> DoControlStart(Service* service) {
return service->Start();
}
|