SurfaceFlinger英文直译就是surface的投递者,surface就不用翻译了,翻译了反而不好理解。SurfaceFlinger是android的一个服务,其负责管理应用端的surface,将所有的surface复合。他是介于图形库和应用之间的一层。每个应用在它自己的surface完成各种图形操作后,请求SurfaceFlinger显示到屏幕,surfaceflinger就会将所有的surface叠加起来,并且反映到framebuffer. 下面是一张结构图:
zygote实际上是进程的名字,实际的可执行文件是/system/bin下的app_process. app_process的源码在frameworks/base/cmds/app_process下面。
init.rc中启动zygote时候是带有参数的,所以会走到第一个分支
start里主要干了几件事,启动虚拟机,注册android的jni, 告诉虚拟机启动的类名,和启动的函数。这里就是com.android.internal.os.ZygoteInit, 入口函数的main,也就是ZygoteInit.java里的main函数。那么再看看这个main函数干了什么。
刚开始是创建了一堆systemserver启动需要的参数,然后通过zygote.forkSystemServer创建了systemserver.
可以看见
Client表示一个surface,也可以理解为每个应用程序所使用的surface. client属于客户端,surfaceflinger属于服务端,分别属于不同的进程。他们之间通过AIDL通信。surfaceflinger不直接与framebuffer打交道,而是建立在opengl或者skia等图形库之上。opengl, skia都是平台无关的图形库,并不反应具体的图形设备的细节,gralloc.xxx.so才是对每种图形设备framebuffer的抽象,gralloc.xxx.so实现了一套标准的接口,每种具体的图形设备都有一个gralloc文件对应。对图形库而言不关心具体的细节。
在认识了surfaceflinger的作用和在android中的位置之后,再来讲讲surfaceflinger是怎么被系统启动的。先贴一张图:
简单的过程就是Init->Zygote->SystemServer->SurfaceFlinger.
Init是linux启动的第一个进程,Zygote就是由Init进程fork出来的,Zygote在android中非常重要,其负责将每个应该程序fork出一个进程。看看init.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class services
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
# Make zygote depend on av_settings.
disabled
zygote实际上是进程的名字,实际的可执行文件是/system/bin下的app_process. app_process的源码在frameworks/base/cmds/app_process下面。
-Xzygote /system/bin --zygote --start-system-server
这是对应的参数。
看看app_process的main,其中app_process/app_main.cpp中
int main(int argc, const char* const argv[])
{
...........
// Everything up to '--' or first non '-' arg goes to the vm
int i = runtime.addVmArguments(argc, argv);
// Next arg is parent directory
if (i < argc) {
runtime.mParentDir = argv[i++];
}
// Next arg is startup classname or "--zygote"
if (i < argc) {
arg = argv[i++];
if (0 == strcmp("--zygote", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
} else {
set_process_name(argv0);
runtime.mClassName = arg;
// Remainder of args get passed to startup class main()
runtime.mArgC = argc-i;
runtime.mArgV = argv+i;
LOGV("App process is starting with pid=%d, class=%s.\n",
getpid(), runtime.getClassName());
runtime.start();
}
} else {
..........
}
}
init.rc中启动zygote时候是带有参数的,所以会走到第一个分支
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
start的源码中AndroidRuntime.cpp中,第一给参数是类名,第二个是bool型,决定是否要启动systemserver.
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
.....
/* start the virtual machine */
if (startVm(&mJavaVM, &env) != 0)
goto bail;
.......
/*
* Register android functions.
*/
if (startReg(env) < 0) {
LOGE("Unable to register all android natives\n");
goto bail;
}
............
startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
LOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
...............
}
start里主要干了几件事,启动虚拟机,注册android的jni, 告诉虚拟机启动的类名,和启动的函数。这里就是com.android.internal.os.ZygoteInit, 入口函数的main,也就是ZygoteInit.java里的main函数。那么再看看这个main函数干了什么。
public static void main(String argv[]) {
try {
.........
registerZygoteSocket();
................
if (argv[1].equals("true")) {
startSystemServer();
} else if (!argv[1].equals("false")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
Log.i(TAG, "Accepting command socket connections");
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
第一就是注册了socket,其目的是IPC, 如activitiymanager会请求其启动一个应用。第二个就是启动systemserver,第3就是runSelectLoopMode等待请求。
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
/*
* Enable debugging of the system process if *either* the command line flags
* indicate it should be debuggable or the ro.debuggable system property
* is set to "1"
*/
int debugFlags = parsedArgs.debugFlags;
if ("1".equals(SystemProperties.get("ro.debuggable")))
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
刚开始是创建了一堆systemserver启动需要的参数,然后通过zygote.forkSystemServer创建了systemserver.
再看SystemServer.java的main.
public static void main(String[] args) {
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
// If a device's clock is before 1970 (before 0), a lot of
// APIs crash dealing with negative numbers, notably
// java.io.File#setLastModified, so instead we fake it and
// hope that time from cell towers or NTP fixes it
// shortly.
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
// Mmmmmm... more memory!
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
System.loadLibrary("android_servers");
init1(args);
}
重要的就是最后调用了init1(args), 其在com_android_server_SystemServer.cpp, 对应的system_init函数
system_init在system_init.cpp
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());
sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}
// Start the sensor service
SensorService::instantiate();
// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
LOGI("System server: starting Android runtime.\n");
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
LOGI("System server: starting Android services.\n");
runtime->callStatic("com/android/server/SystemServer", "init2");
// If running in our own process, just go into the thread
// pool. Otherwise, call the initialization finished
// func to let this process continue its initilization.
if (proc->supportsProcesses()) {
LOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exiting thread pool.\n");
}
return NO_ERROR;
可以看见
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}
启动了surfaceflinger. 到此surfaceflinger就比较清楚地知道是怎么被启动的了。