文章目录
知识回顾
启动第一个流程init
1,挂载文件系统,创建文件目录 调用selinux_setup权限安全相关
2,初始化内存空间 初始化属性服务 创建Epoll 注册监听子进程重启异常操作等,对子进程进行线程守护
3,startPropertyServic 开启属性服务 进行监听
4,LoadBootScripts 加载init.rc文件 进行解析 调用do_class_start 文件开启service
5,Service::Start函数->fork子进程->并且执行app_process文件,开启了zygote
Zygote的流程
1,startVm函数注册jvm startReg函数注册jni环境唤起 Zygote.main
2,forkSystemServer
3,preload预加载class 系统资源
4,调用runSelectLoop函数循环等待客户端连接
5,有客户端的连接后调用processOneCommand()函数 fork进程,初始化进程,创建ProcessState初始化binder
6,根据请求的targetClass 执行Main函数
SystemServer
由Zygote调用forkSystemServer来创建system_server进程,调用到Java层SystemServer.java.Main,创建SystemServer的ActivityThread 创建framewok-res.apk的Application调用onCreate,调用startBootstrapServices、startCoreServices、startOtherServices创建各种各样的Service(AMS、PMS等),并开启开门狗检测服务和线程,如果出现问题就会杀死system_server,system_server死亡之后会通知Zygote,Zygote会杀死自己 通知init,init会重启Zygote 并执行对应的onRestart服务。
Binder
Binder是一个虚拟的硬件设备,是一个驱动。是Android中特有的一种通信方式。好处就是一次内存拷贝,安全性高。 它高效的原理是将用户空间、内核空间、物理内存映射在了同一块地址,这样我们就少了一次拷贝。大家也可以参考我前面列出来的管道、socket、共享内存之间的区别来讲。也可以讲讲binder_open、binder_mmap、binder_ioct
1.binder_open:创建binder_proc并且初始化todo,wait队列
2.binder_mmap:开辟内核空间,同时开辟物理内存空间,然后把内核空间和物理空间进行映射,使他们2个指向同一个内存地址。
3.binder_ioctl:根据传入的cmd执行对应的操作 例如BINDER_VERSION、BINDER_WRITE_READ、BINDER_SET_CONTEXT_MGR_EXT等
ServiceManager
1.binder_open:打开binder驱动,对BINDER_VERSION进行校验
2.binder_become_context_manager:设置自己成为binder上下文的管理者(binder_context_mgr_node)
3.binder_loop:给Binder驱动发送BC_ENTER_LOOPER,以及循环读取内容 调用binder_parse解析
4.binder_parse:根据返回数据解析命令,调用svcmgr_handler回调处理
前言
Android系统启动的最后一步是启动一个桌面应用,这个应用用来显示我们已经安装的应用程序,它就是Launcher
源码分析
1.Launcher的启动
private void startOtherServices() {
//……………………
mActivityManagerService.systemReady(() -> {/*……………………*/}, BOOT_TIMINGS_TRACE_LOG);
}
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
//……………………
//开启Launcher
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
//……………………
}
}
2.ActivityTaskManagerService
boolean startHomeOnAllDisplays(int userId, String reason) {
boolean homeStarted = false;
for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
final int displayId = mActivityDisplays.get(i).mDisplayId;
//调用了startHomeOnDisplay 3个参数的
homeStarted |= startHomeOnDisplay(userId, reason, displayId);
}
return homeStarted;
}
boolean startHomeOnDisplay(int userId, String reason, int displayId) {
//接着调用了5个参数的方法
return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
false /* fromHomeKey */);
}
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
// Fallback to top focused display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
displayId = getTopDisplayFocusedStack().mDisplayId;
}
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (displayId == DEFAULT_DISPLAY) {
//拿到需要启动的Launcher的intent,intent action是Intent.ACTION_MAIN category是Intent.CATEGORY_HOME
homeIntent = mService.getHomeIntent();
//拿到需要启动的activityInfo
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
aInfo = info.first;
homeIntent = info.second;
}
if (aInfo == null || homeIntent == null) {
return false;
}
if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
return false;
}
//设置参数Component 就是查到的packageName
homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
//设置flag为new_task
homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
// Updates the extra information of the intent.
if (fromHomeKey) {
homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
}
final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
aInfo.applicationInfo.uid) + ":" + displayId;
//调用ActivityStartController的startHomeActivity方法开启Launcher
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
return true;
}
//获取到Launcher的Intent
String mTopAction = Intent.ACTION_MAIN;
//返回的intent action是Intent.ACTION_MAIN category是Intent.CATEGORY_HOME
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
//通过homeIntent向PackageManagerService 找对应的ActivityInfo
ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
final int flags = ActivityManagerService.STOCK_PM_FLAGS;
final ComponentName comp = homeIntent.getComponent();
ActivityInfo aInfo = null;
try {
if (comp != null) {
// Factory test.
aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
} else {
final String resolvedType =
homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
final ResolveInfo info = AppGlobals.getPackageManager()
.resolveIntent(homeIntent, resolvedType, flags, userId);
if (info != null) {
aInfo = info.activityInfo;
}
}
} catch (RemoteException e) {
// ignore
}
if (aInfo == null) {
Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
return null;
}
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
return aInfo;
}
文件目录`/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java`
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
if (!ActivityRecord.isResolverActivity(aInfo.name)) {
options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
}
options.setLaunchDisplayId(displayId);
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute();//这里执行开启activity 我们先不跟了,后边等将AMS的startActivity的时候再详解。
mLastHomeActivityStartRecord = tmpOutRecord[0];
final ActivityDisplay display =
mService.mRootActivityContainer.getActivityDisplay(displayId);
final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
if (homeStack != null && homeStack.mInResumeTopActivity) {
//如果已经开启过 就重新拉回栈顶
mSupervisor.scheduleResumeTopActivities();
}
}
在system_server中调用了AMS的systemReady,调用RootActivityContainer的startHomeOnAllDisplays 获取到Launcher的Action和Category 通过PackageManagerService来查询到需要开启的Activity(Launcher)
3.开机动画总结
int main()
{
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
bool noBootAnimation = bootAnimationDisabled();//判断是否需要开机动画
ALOGI_IF(noBootAnimation, "boot animation disabled");
if (!noBootAnimation) {
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
// create the boot animation object (may take up to 200ms for 2MB zip)
sp<BootAnimation> boot = new BootAnimation(audioplay::createAnimationCallbacks());
waitForSurfaceFlinger();//等待SurfaceFlinger 因为我们想要画到屏幕上就必须要通过SurfaceFlinger
//调用run函数
boot->run("BootAnimation", PRIORITY_DISPLAY);
ALOGV("Boot animation set up. Joining pool.");
IPCThreadState::self()->joinThreadPool();
}
return 0;
}
//从属性服务中获取是否开启开机动画
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;
}
BootAnimation继承自Thread,
关于Thread之前没有讲 大家可以参考`/system/core/libutils/Threads.cpp`,第一次会调用readyToRun。然后会调用threadLoop
bool BootAnimation::threadLoop()
{
bool r;
if (mZipFileName.isEmpty()) {
r = android();
} else {//走这里,调用movie函数
r = movie();
}
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(mDisplay, mContext);
eglDestroySurface(mDisplay, mSurface);
mFlingerSurface.clear();
mFlingerSurfaceControl.clear();
eglTerminate(mDisplay);
eglReleaseThread();
IPCThreadState::self()->stopProcess();
return r;
}
bool BootAnimation::movie()
{
if (mAnimation == nullptr) {
//加载动画资源 这里我就不跟了 感兴趣的可以自行查看
mAnimation = loadAnimation(mZipFileName);
}
if (mAnimation == nullptr)
return false;
// mCallbacks->init() may get called recursively,
// this loop is needed to get the same results
for (const Animation::Part& part : mAnimation->parts) {
if (part.animation != nullptr) {
mCallbacks->init(part.animation->parts);
}
}
mCallbacks->init(mAnimation->parts);
bool anyPartHasClock = false;
for (size_t i=0; i < mAnimation->parts.size(); i++) {
if(validClock(mAnimation->parts[i])) {
anyPartHasClock = true;
break;
}
}
if (!anyPartHasClock) {
mClockEnabled = false;
}
mUseNpotTextures = false;
String8 gl_extensions;
const char* exts = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
if (!exts) {
glGetError();
} else {
gl_extensions.setTo(exts);
if ((gl_extensions.find("GL_ARB_texture_non_power_of_two") != -1) ||
(gl_extensions.find("GL_OES_texture_npot") != -1)) {
mUseNpotTextures = true;
}
}
// Blend required to draw time on top of animation frames.
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
bool clockFontInitialized = false;
if (mClockEnabled) {
clockFontInitialized =
(initFont(&mAnimation->clockFont, CLOCK_FONT_ASSET) == NO_ERROR);
mClockEnabled = clockFontInitialized;
}
if (mClockEnabled && !updateIsTimeAccurate()) {
mTimeCheckThread = new TimeCheckThread(this);
mTimeCheckThread->run("BootAnimation::TimeCheckThread", PRIORITY_NORMAL);
}
//调用playAnimation 播放动画
playAnimation(*mAnimation);
if (mTimeCheckThread != nullptr) {
mTimeCheckThread->requestExit();
mTimeCheckThread = nullptr;
}
if (clockFontInitialized) {
glDeleteTextures(1, &mAnimation->clockFont.texture.name);
}
releaseAnimation(mAnimation);
mAnimation = nullptr;
return false;
}
播放动画 并且调用checkExit进行检测 是否播放完成
bool BootAnimation::playAnimation(const Animation& animation)
{
const size_t pcount = animation.parts.size();
nsecs_t frameDuration = s2ns(1) / animation.fps;
const int animationX = (mWidth - animation.width) / 2;
const int animationY = (mHeight - animation.height) / 2;
for (size_t i=0 ; i<pcount ; i++) {
const Animation::Part& part(animation.parts[i]);
const size_t fcount = part.frames.size();
glBindTexture(GL_TEXTURE_2D, 0);
// Handle animation package
if (part.animation != nullptr) {
playAnimation(*part.animation);
if (exitPending())
break;
continue; //to next part
}
for (int r=0 ; !part.count || r<part.count ; r++) {
if(exitPending() && !part.playUntilComplete)
break;
mCallbacks->playPart(i, part, r);
glClearColor(
part.backgroundColor[0],
part.backgroundColor[1],
part.backgroundColor[2],
1.0f);
for (size_t j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) {
const Animation::Frame& frame(part.frames[j]);
nsecs_t lastFrame = systemTime();
if (r > 0) {
glBindTexture(GL_TEXTURE_2D, frame.tid);
} else {
if (part.count != 1) {
glGenTextures(1, &frame.tid);
glBindTexture(GL_TEXTURE_2D, frame.tid);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
int w, h;
initTexture(frame.map, &w, &h);
}
const int xc = animationX + frame.trimX;
const int yc = animationY + frame.trimY;
Region clearReg(Rect(mWidth, mHeight));
clearReg.subtractSelf(Rect(xc, yc, xc+frame.trimWidth, yc+frame.trimHeight));
if (!clearReg.isEmpty()) {
Region::const_iterator head(clearReg.begin());
Region::const_iterator tail(clearReg.end());
glEnable(GL_SCISSOR_TEST);
while (head != tail) {
const Rect& r2(*head++);
glScissor(r2.left, mHeight - r2.bottom, r2.width(), r2.height());
glClear(GL_COLOR_BUFFER_BIT);
}
glDisable(GL_SCISSOR_TEST);
}
glDrawTexiOES(xc, mHeight - (yc + frame.trimHeight),
0, frame.trimWidth, frame.trimHeight);
if (mClockEnabled && mTimeIsAccurate && validClock(part)) {
drawClock(animation.clockFont, part.clockPosX, part.clockPosY);
}
handleViewport(frameDuration);
eglSwapBuffers(mDisplay, mSurface);
nsecs_t now = systemTime();
nsecs_t delay = frameDuration - (now - lastFrame);
//SLOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay));
lastFrame = now;
if (delay > 0) {
struct timespec spec;
spec.tv_sec = (now + delay) / 1000000000;
spec.tv_nsec = (now + delay) % 1000000000;
int err;
do {
err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, nullptr);
} while (err<0 && errno == EINTR);
}
//检测释放播放完成
checkExit();
}
usleep(part.pause * ns2us(frameDuration));
if(exitPending() && !part.count && mCurrentInset >= mTargetInset)
break;
}
}
for (const Animation::Part& part : animation.parts) {
if (part.count != 1) {
const size_t fcount = part.frames.size();
for (size_t j = 0; j < fcount; j++) {
const Animation::Frame& frame(part.frames[j]);
glDeleteTextures(1, &frame.tid);
}
}
}
return true;
}
//检测是否完成
void BootAnimation::checkExit() {
char value[PROPERTY_VALUE_MAX];
//根据属性 来判断是否完成
property_get(EXIT_PROP_NAME, value, "0");
int exitnow = atoi(value);
if (exitnow) {
requestExit();//退出BootAnimation
mCallbacks->shutdown();
}
}
文件目录:`/frameworks/base/cmds/bootanimation/audioplay.cpp`
//mCallBacks 音频播放器也需要关闭
void shutdown() override {
audioplay::setPlaying(false);
audioplay::destroy();
};
//做一些准备工作,例如创建surface 设置layer,纹理等。
status_t BootAnimation::readyToRun() {
mAssets.addDefaultAssets();
mDisplayToken = SurfaceComposerClient::getInternalDisplayToken();
if (mDisplayToken == nullptr)
return -1;
DisplayInfo dinfo;
status_t status = SurfaceComposerClient::getDisplayInfo(mDisplayToken, &dinfo);
if (status)
return -1;
//创建Native的Surface
sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
SurfaceComposerClient::Transaction t;
//设置Layer
t.setLayer(control, 0x40000000)
.apply();
sp<Surface> s = control->getSurface();
// initialize opengl and egl
const EGLint attribs[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_DEPTH_SIZE, 0,
EGL_NONE
};
EGLint w, h;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
EGLContext context;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, nullptr, nullptr);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
surface = eglCreateWindowSurface(display, config, s.get(), nullptr);
context = eglCreateContext(display, config, nullptr, nullptr);
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
return NO_INIT;
mDisplay = display;
mContext = context;
mSurface = surface;
mWidth = w;
mHeight = h;
mFlingerSurfaceControl = control;
mFlingerSurface = s;
mTargetInset = -1;
return NO_ERROR;
}
1.在bootanimation_main.cpp的main中创建了BootAnimation并设置了回调监听AudioAnimationCallbacks,BootAnimation继承Thread所以会先执行readyToRun然后执行threadLoop,再readyToRun中创建Surface,threadLoop中 进行资源(loadAnimation)的加载和播放(playAnimation),播放过程中 不停的调用checkExit进行检测 检测属性为: service.bootanim.exit,如果退出 则退出线程以及关闭音频。
2.在Launcher被创建之后会执行ActivityThread的handleResumeActivity函数中给MessageQueue插入了一个只执行一次的Idel,他会调用ActivityTaaskManagerService的activityIdle,接着调用到postFinishBooting会调用enableScreenAfterBoot,进入WMS调用performEnableScreen调用SystemProperties.set(“service.bootanim.exit”, “1”)把值设置成了1,结束了动画的播放。
拓展知识
总结
1.Launcher是由system_server启动,在开启其他服务startOtherServices中,调用了AMS的systemReady,在systemReady中调用了startHomeOnAllDisplays,通过Intent来找到对应的Launcher,条件是action=ACTION_MAIN,CATEGORY=CATEGORY_HOME,找到后开启Launcher
2.Launcher中初始化了LauncherModel并设置了回调函数(CallBacks)调用startLoader函数,创建LoadTask,通过Binder访问LauncherAppService的queryIntentActivies再调用PackageManagerService的queryIntentActivities获取到Launcher的信息返回
3.在LoadTask的回调onAppsUpdated调用rebindAdapters对数据进行绑定 填充
4.在ViewHolder的创建中设置点击事件,在绑定中设置tag为AppInfo,在点击事件中通过tag调用startAppShortcutOrInfoActivity最终调用到Activity的startActivity函数。