1.surfaceflinger进程启动
init启动surfaceflinger.rc的过程可以参考 SurfaceFlinger启动流程分析
###xref: /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
2.surfaceflinger main()函数
main()主要工作
1、SurfaceFlinger首先忽略了SIGPIPE信号,为什么要这么做呢?因为在SurfaceFlinger的Client-Server模型中,或者说IPC机制中,很可能会触发SIGPIPE信号,而这个信号的默认动作是终止进程,并不是我们想要的行为,所以主动对SIGPIPE信号进行处理。
2、接着,开启线程池,不过限制了线程的最大数量为4个,如果线程过多,可能会影响程序性能。
3、随后,创建SurfaceFlinger对象,在其构造函数中,主要是一些成员变量的初始化工作,同时还有一个高逼格的DDMS配置,即Dalvik Debug Monitor Service,是一个调试神器。如果配置了DDMS,就会dlopen libsurfaceflinger_ddmconnection.so,并dlsym其中的DdmConnection_start,最后建立SurfaceFlinger与DDMS的连接。
4、因为这里的SurfaceFlinger对象是一个StrongPointer,所以首先会走到RefBase的onFirstRef,这里就做了一件事情,MessageQueue初始化,保存SurfaceFlinger,并创建了消息队列所需的Looper和Handler。
5、SurfaceFlinger实例化后,设置进程优先级和事务处理策略。
6、然后,进入如下的SurfaceFlinger::init,主要是EGL配置、event线程启动、硬件composer初始化等,而且著名的VSync也在这里出现了。
7、在Android系统中有一个ServiceManager,专门用来管理所有的服务,而SurfaceFlinger不是由ServiceManager启动的,因此需要向ServiceManager注册SurfaceFlinger,同时还注册了GpuService。
8、最后通过SurfaceFlinger::run,进入消息循环,SurfaceFlinger启动成功,开始工作。
##/frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {
signal(SIGPIPE, SIG_IGN); //ignore sigpipe信号
hardware::configureRpcThreadpool(1 /* maxThreads */,
false /* callerWillJoin */);
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4); //限制最大线程数为4
// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger(); //定义为sp指针,执行onFirstRef
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
// initialize before clients can connect
flinger->init(); //执行init
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
// publish GpuService
sp<GpuService> gpuservice = new GpuService();
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
startDisplayService(); // dependency on SF getting registered above
// run surface flinger in this thread
flinger->run(); //运行
return 0;
}
因为这里的SurfaceFlinger对象是一个StrongPointer,所以首先会走到RefBase的onFirstRef,这里就做了一件事情,MessageQueue初始化,保存SurfaceFlinger,并创建了消息队列所需的Looper和Handler。
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
3.surfaceflinger init()函数
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
Mutex::Autolock _l(mStateLock); //持mutex lock
// 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) { //运行线程
ALOGE("Run StartPropertySetThread failed!");
}
ALOGV("Done initializing");
}
init函数主要工作:
1.初始化OpenGL ES图形库。
2. 创建显示设备的抽象代表,负责和显示设备打交道。
3. 创建显示设备对象。
4. 启动EventThread。监听和处理SurfaceFlinger中的事件。
5.设置软件VSync信号周期。
6.初始化显示设备,调用initializeDisplays完成。
7.启动开机动画,mStartPropertySetThread,只是设置了两个属性,其中一个ctl.start是启动了bootanim进程。
4.通过ctl.start属性启动bootanim
###xref: /frameworks/native/services/surfaceflinger/StartPropertySetThread.cpp
namespace android {
StartPropertySetThread::StartPropertySetThread(bool timestampPropertyValue):
Thread(false), mTimestampPropertyValue(timestampPropertyValue) {}
status_t StartPropertySetThread::Start() {
return run("SurfaceFlinger::StartPropertySetThread", PRIORITY_NORMAL);
}
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"); //Start BootAnimation
// Exit immediately
return false;
}
} // namespace android
5.init进程初始化时注册 property epoll
###xref: /system/core/init/init.cpp
int main(int argc, char** argv) {
start_property_service();
}
###xref: /system/core/init/property_service.cpp
void start_property_service() {
selinux_callback cb;
cb.func_audit = SelinuxAuditCallback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
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);
if (property_set_fd == -1) {
PLOG(FATAL) << "start_property_service socket creation failed";
}
listen(property_set_fd, 8);
register_epoll_handler(property_set_fd, handle_property_set_fd); //注册epoll
}
6.处理ctl.start属性变化
###xref: /system/core/init/property_service.cpp
static void handle_property_set_fd() {
switch (cmd) {
case PROP_MSG_SETPROP: {
uint32_t result =
HandlePropertySet(prop_name, prop_value, socket.source_context(), cr, &error);
if (result != PROP_SUCCESS) {
LOG(ERROR) << "Unable to set property '" << prop_name << "' to '" << prop_value
<< "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": "
<< error;
}
break;
}
case PROP_MSG_SETPROP2: {
uint32_t result = HandlePropertySet(name, value, socket.source_context(), cr, &error);
if (result != PROP_SUCCESS) {
LOG(ERROR) << "Unable to set property '" << name << "' to '" << value
<< "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": "
<< error;
}
socket.SendUint32(result);
break;
}
}
}
7.处理属性ctl.start变化
// This returns one of the enum of PROP_SUCCESS or PROP_ERROR*.
uint32_t HandlePropertySet(const std::string& name, const std::string& value,
const std::string& source_context, const ucred& cr, std::string* error) {
if (StartsWith(name, "ctl.")) { //property_set("ctl.start", "bootanim");
if (!CheckControlPropertyPerms(name, value, source_context, cr)) {
*error = StringPrintf("Invalid permissions to perform '%s' on '%s'", name.c_str() + 4,
value.c_str());
return PROP_ERROR_HANDLE_CONTROL_MESSAGE;
}
HandleControlMessage(name.c_str() + 4, value, cr.pid); //和android n名字一样
return PROP_SUCCESS;
}
return PropertySet(name, value, error);
}
8.处理handlecontrolMessage
HandleControlMessage(name.c_str() + 4, value, cr.pid);
从名字推断name.c_str() + 4 = ctl.start 也就是start,value = bootanim
### /system/core/init/init.cpp
void HandleControlMessage(const std::string& msg, const std::string& name, pid_t pid) {
const auto& map = get_control_message_map();
const auto it = map.find(msg); //msg = start,it应该是{ControlTarget::SERVICE, DoControlStart}
const ControlMessageFunction& function = it->second; //c++ it first是迭代器指向键值,it second是迭代器指向对应的值!
if (function.target == ControlTarget::SERVICE) { //if target = start
//通过bootanim找到对应的service
Service* svc = ServiceList::GetInstance().FindService(name);
if (svc == nullptr) {
LOG(ERROR) << "No such service '" << name << "' for ctl." << msg;
return;
}
//function.target function.action {ControlTarget::SERVICE, DoControlStart}
if (auto result = function.action(svc); !result) {
LOG(ERROR) << "Could not ctl." << msg << " for service " << name << ": "
<< result.error();
}
return;
}
}
static const std::map<std::string, ControlMessageFunction>& get_control_message_map() {
// clang-format off
static const std::map<std::string, ControlMessageFunction> control_message_functions = {
{"start", {ControlTarget::SERVICE, DoControlStart}},
{"stop", {ControlTarget::SERVICE, DoControlStop}},
{"restart", {ControlTarget::SERVICE, DoControlRestart}},
{"interface_start", {ControlTarget::INTERFACE, DoControlStart}},
{"interface_stop", {ControlTarget::INTERFACE, DoControlStop}},
{"interface_restart", {ControlTarget::INTERFACE, DoControlRestart}},
};
// clang-format on
return control_message_functions;
}
9.bootanim start
###xref: /system/core/init/init.cpp
static Result<Success> DoControlStart(Service* service) {
return service->Start(); //启动对应的service
}
static Result<Success> DoControlStop(Service* service) {
service->Stop();
return Success();
}
10.bootanition流程
可参照上一篇博客 Android O 开机动画流程以及制作(c片段和p片段)