init.cpp AOSP/system/core/init/init.cpp
SurfaceFlinger是由init进程启动的
int main(int argc, char** argv) {
...
if (bootmode == "charger") {
am.QueueEventTrigger("charger");
} else {
am.QueueEventTrigger("late-init");
}
...
}
触发trigger 这里可以暂时参考一下https://blog.csdn.net/we1less/article/details/116110137?spm=1001.2014.3001.5501
init.rc AOSP/system/core/rootdir/init.rc
on late-init
...
trigger boot
...
on boot
...
class_start core
...
关于启动相应的函数这里可以参考一下https://blog.csdn.net/we1less/article/details/116139142?spm=1001.2014.3001.5501
builtin_functions AOSP/system/core/init/builtins.cpp
可以看出class_start 命令有一个对应的执行函数 do_class_start
onst BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
constexpr std::size_t kMax = std::numeric_limits::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& 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.cpp AOSP/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.cpp AOSP/system/core/init/init.cpp
关于属性服务参考这篇https://blog.csdn.net/we1less/article/details/116035087?spm=1001.2014.3001.5501
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
当然如果在查看源码的过程中发现无法判断调用链的可以使用相关命令 grep "xxxxx" ./ -rn 参考https://blog.csdn.net/we1less/article/details/115792043?spm=1001.2014.3001.5501
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_message AOSP/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
1 首先看构造器
BootAnimation(sp
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;
}
}
2 sp指针在对象第一次初始化的过程中调用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文件 此时开机动画就被播放出来了