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文件  此时开机动画就被播放出来了

c语言for循环开机动画,android8.1开机动画启动分析相关推荐

  1. c语言循环语句相关摘要,C语言中循环语句的应用研究

    为了帮助初学者尽快掌握C语言的循环语句,通过实例较详细的分析了循环语句的结构.功能和应用方法,以便读者能在实际应用中能够合理地选择循环语句,编出满足需要的程序来. . 26 0 价值工程 C语言中循环 ...

  2. android默认开机动画,修改安卓开机动画(除了部分系统 如MIUI等)

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 这技术已经很久了,但还是忍不住搬运了一下. 出处是百度的,很久很久以前玩手机在百度上学的 我这里说的开机动画是指开机的第二屏 开机动画可以在下载的rom里 ...

  3. android更换开机动画,修改安卓开机动画(除了部分系统 如MIUI等)

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 这技术已经很久了,但还是忍不住搬运了一下. 出处是百度的,很久很久以前玩手机在百度上学的 我这里说的开机动画是指开机的第二屏 开机动画可以在下载的rom里 ...

  4. ATV 开发 一、ATV 开机动画定制 android 开机动画

    定制ATV开机动画 谷歌ATV的开机动画必须符合如下要求: 必须遵循以下顺序: 第一屏logo画面修改:允许客户修改 ATV 允许添加自己的开机动画. Android TV 谷歌原生开机动画,此动画不 ...

  5. android9开机动画,修改安卓开机动画(除了部分系统 如MIUI等)

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 这技术已经很久了,但还是忍不住搬运了一下. 出处是百度的,很久很久以前玩手机在百度上学的 我这里说的开机动画是指开机的第二屏 开机动画可以在下载的rom里 ...

  6. R语言使用gganimate包和ggforce包可视化动画并动态缩放(zoom)移动动画的内容

    R语言使用gganimate包和ggforce包可视化动画并动态缩放(zoom)移动动画的内容 目录 R语言使用gganimate包和ggforce包可视化动画并动态缩放(zoom)移动

  7. Java语言的循环控制结构

    Java语言的循环控制结构 循环控制结构:是在一定条件下,反复执行某段程序的流程结构,被反复执行的程序称为循环体.循环控制结构是程序中非常重要和基本的一种结构,它是由循环语句来实现的. Java 的循 ...

  8. c语言for循环的第三句,for循环语句的用法

    for循环有三种结构:列表for循环,不带列表for循环和类C风格for循环. do和done之间的命令成为循环体,执行次数和list列表中常熟或字符串的个数相同.for循环,首相是将in后list的 ...

  9. c语言for循环说课稿,C语言FOR循环说课稿.docx

    C语言FOR循环说课稿 各位评委老师上午好,我今天说课的内容是"FOR循环"(板书),下面我将从教材的地位及作用.学生学情.教学目标.教学重难点.教法.学法.教学过程.教学效果的预 ...

最新文章

  1. 网页中添加QQ,msn留言按钮
  2. python学习总目录
  3. Opencv 去高光或镜面反射(illuminationChange)
  4. C++矩阵运算库推荐
  5. bat修改文件内容_在win10系统中一键修改MapGIS67系统库背景色
  6. Java实体类对象修改日志记录
  7. Luogu P4708 画画 (Burnside引理、组合计数)
  8. Mysql(10)——聚合函数的用法
  9. java图像处理,拷贝图像EXIF信息
  10. SAP Spartacus not found页面的显示触发机制 - ErrorPageTemplate
  11. EF批量插入太慢?那是你的姿势不对
  12. Mysql更新计数器_MySQL实现计数器如何在高并发场景下更新并保持数据正确性
  13. Swaps and Inversions hdu多校训练第二场 树状数组求逆序数+离散化
  14. lzg_ad:使用EWF API开发常见问题
  15. 中小企业信息化规划案例--初级篇
  16. 电脑鼠标右键菜单太多了怎么办?Windows右键菜单清理删除方法
  17. 面对面教你如何用Python提取快递信息
  18. 计算机学院云毕业,“云端”相约,逐梦起航——计算机与设计学院举办2020届线上毕业典礼...
  19. 计算机怎么打出$符号,细说电脑上怎么打出特殊符号
  20. 密码学DAY1_02

热门文章

  1. 计算机术语rander是什么意思,Rendering Engine,呈现引擎还是渲染引擎?
  2. 2014-11-20动态规划:顺推法与逆推法中递推公式的不同!
  3. 河南大学计算机类保研率,郑州大学、河南大学、河南农业大学2021届保研率
  4. 几个技术虚拟小组会议的思考
  5. 用原生js实现淘宝详情页图片放大镜效果
  6. Python实用技巧:global关键字的用法详解
  7. postman模拟并发请求
  8. 攻击JavaWeb应用————2、CS交互安全
  9. shell笔记本xmind导出
  10. 用vue写一个计算总价