c语言for循环开机动画,android8.1开机动画启动分析
init.cppAOSP/system/core/init/init.cppSurfaceFlinger是由init进程启动的int main(int argc, char** argv) {...if (bootmode == "charger") {am.QueueEventTrigger("charger");} else {am.QueueEventTrigger("late-init")
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文件 此时开机动画就被播放出来了
更多推荐
所有评论(0)