Android.Oldboot.1,<Android Framework 之路>BootAnimation(1)

介绍

开机动画,BootAnimation,就是Android手机开机郭晨各种以一个展示给用户的界面,实际是一个多个帧组成的动画,在界面上进行一帧一帧的播放,形成开机动画的效果。

本文针对Android5.1源码分析BootAnimation

源码分析

1. 文件产生

Android平台的开机动画由system/bin下的bootanimation文件完成,而这个文件产生于

frameworks/base/cmds/bootanimation/Android.mk

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= bootanimation_main.cpp AudioPlayer.cpp BootAnimation.cpp

LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES

LOCAL_C_INCLUDES += external/tinyalsa/include

LOCAL_SHARED_LIBRARIES := libcutils liblog libandroidfw libutils libbinder libui libskia libEGL libGLESv1_CM libgui libtinyalsa

LOCAL_MODULE:= bootanimation

ifdef TARGET_32_BIT_SURFACEFLINGER

LOCAL_32_BIT_ONLY := true

endif

include $(BUILD_EXECUTABLE)

编译结果为bootanimation的bin文件,所以,在有足够权限的前提下,在adb shell下执行bootanimation也是可以看到对应的开机动画效果的。

2. 启动开机动画

开机动画是以bin文件的形式存在于手机系统中,开机过程中通过init.rc定义

system/core/rootdir/init.rc

service bootanim /system/bin/bootanimation

class core

user graphics

group graphics audio

disabled//定义了disable,在开机过程中不会自动的启动

oneshot

这里不会启动,那么在哪里启动? 由于开机动画对SurfaceFlinger有依赖,所以应该是在SurfaceFlinger启动之后再开始执行,看一下源码。

SurfaceFlinger的启动在init.rc文件中

service surfaceflinger /system/bin/surfaceflinger

class core

user system

group graphics drmrpc

onrestart restart zygote

与SurfaceFlinger相关的源码存在于

frameworks

ativeservicessurfaceflinger

入口

frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

#if defined(HAVE_PTHREADS)

#include

#endif

#include

#include

#include

#include

#include

#include "SurfaceFlinger.h"

using namespace android;

int main(int, char**) {

// When SF is launched in its own process, limit the number of

// binder threads to 4.

ProcessState::self()->setThreadPoolMaxThreadCount(4);

// start the thread pool

sp ps(ProcessState::self());

ps->startThreadPool();

// instantiate surfaceflinger

sp flinger = new SurfaceFlinger();

#if defined(HAVE_PTHREADS)

setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);

#endif

set_sched_policy(0, SP_FOREGROUND);

// initialize before clients can connect

flinger->init();//开机动画在这里执行,接着往下看

// publish surface flinger

sp sm(defaultServiceManager());

sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);

// run in this thread

flinger->run();

return 0;

}

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::init() {

ALOGI( "SurfaceFlinger's main thread ready to run. "

"Initializing graphics H/W...");

....

// start boot animation

startBootAnim();

}

接着执行startBootAnim();

void SurfaceFlinger::startBootAnim() {

// start boot animation

property_set("service.bootanim.exit", "0");

property_set("ctl.start", "bootanim");

}

这里采用的是通过property_set中”ctl.start”的方式执行bootanim,这里是通过设置属性值的方式来启动的,属性值的设置采用的是C/S模式,socket连接,这里不详述,大致说下,这行代码会执行到

system/core/init/property_service.c

void handle_property_set_fd()

{

......

switch(msg.cmd) {

case PROP_MSG_SETPROP:

......

//这里很关键

if(memcmp(msg.name,"ctl.",4) == 0) {

// Keep the old close-socket-early behavior when handling

// ctl.* properties.

close(s);

if (check_control_mac_perms(msg.value, source_ctx)) {

handle_control_message((char*) msg.name + 4, (char*) msg.value);

} else {

ERROR("sys_prop: Unable to %s service ctl [%s] uid:%d gid:%d pid:%d

",

msg.name + 4, msg.value, cr.uid, cr.gid, cr.pid);

}

//这里很关键

} else {

if (check_perms(msg.name, source_ctx)) {

property_set((char*) msg.name, (char*) msg.value);

} else {

ERROR("sys_prop: permission denied uid:%d name:%s

",

cr.uid, msg.name);

}

// Note: bionic's property client code assumes that the

// property server will not close the socket until *AFTER*

// the property is written to memory.

close(s);

}

freecon(source_ctx);

break;

default:

close(s);

break;

}

}

接下来执行到

system/core/init/init.c

void handle_control_message(const char *msg, const char *arg)

{

if (!strcmp(msg,"start")) {

msg_start(arg);//就是这条路

} else if (!strcmp(msg,"stop")) {

msg_stop(arg);

} else if (!strcmp(msg,"restart")) {

msg_restart(arg);

} else {

ERROR("unknown control msg '%s'

", msg);

}

}

接着往下执行->

static void msg_start(const char *name)

{

struct service *svc = NULL;

char *tmp = NULL;

char *args = NULL;

if (!strchr(name, ':'))

svc = service_find_by_name(name);

else {

tmp = strdup(name);

if (tmp) {

args = strchr(tmp, ':');

*args = ' ';

args++;

svc = service_find_by_name(tmp);

}

}

if (svc) {

service_start(svc, args);

} else {

ERROR("no such service '%s'

", name);

}

if (tmp)

free(tmp);

}

这里找到“bootanim”然后执行service_start函数,这里就是启动bootanim的地方。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值