android開機動畫啓動流程
發表時(shí)間:2020-11-6
發布人(rén):融晨科技
浏覽次數:49
從android的(de)Surface Flinger服務啓動分析知道(dào),開機動畫是(shì)在(zài)SurfaceFlinger實例通過調用startBootAnim()啓動的(de)。
下面我們就(jiù)一起學習BootAnim是(shì)如何啓動和(hé / huò)結束的(de),我精讀代碼前都喜歡先描出(chū)框架圖,以(yǐ)此圖爲(wéi / wèi)基礎再去研讀會達到(dào)事半功倍的(de)效果。好吧,直接上(shàng)圖。
[img]http://img.blog.csdn.net/20141231162020380?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaG92YW4=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
内核起來(lái)後會啓動第一個(gè)進程,即init進程。
init進程會根據init.rc配置啓動surfaceflinger進程。
service surfaceflinger /system/bin/surfaceflinger class main user system group graphics drmrpc onrestart restart zygote
surfaceflinger進程便啓動了(le/liǎo),跟着就(jiù)會跑進程的(de)main()函數。
frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int argc, char** argv) { .... // instantiate surfaceflinger sp<SurfaceFlinger> flinger = new SurfaceFlinger();//創建surfaceflinger服務實例 .... flinger->init(); // publish surface flinger sp<IServiceManager> sm(defaultServiceManager()); sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//注冊到(dào)service manager裏 // run in this thread flinger->run();//開跑 return 0; }
首先new一個(gè)SurfaceFlinger實例,然後init,然後run
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();//開始播放動畫 }
初始化graphics之(zhī)後,就(jiù)調用startBootAnim()播放開機動畫。
void SurfaceFlinger::startBootAnim() { // start boot animation mBootFinished = false; property_set("service.bootanim.exit", "0");//這(zhè)個(gè)會有bootanimation進程周期檢測,=1退出(chū)動畫 property_set("ctl.start", "bootanim");//通過ctl.start命令啓動bootanim }
把service.bootanim.exit屬性設爲(wéi / wèi)0,這(zhè)個(gè)屬性bootanimation進程裏會周期檢查,=1時(shí)就(jiù)退出(chū)動畫,這(zhè)裏=0表示要(yào / yāo)播放動畫。
後面通過ctl.start的(de)命令啓動bootanim進程,動畫就(jiù)開始播放了(le/liǎo)。
下面來(lái)到(dào)bootanimation的(de)實現
frameworks/base/cmds/bootanimation/bootanimation_main.cpp
int main(int argc, char** argv) { sp<ProcessState> proc(ProcessState::self()); ProcessState::self()->startThreadPool(); // create the boot animation object sp<BootAnimation> boot = new BootAnimation();//創建BootAnimation實例 IPCThreadState::self()->joinThreadPool();//binder線程池,與surfaceflinger通信用的(de)。 } return 0; }
new一個(gè)BootAnimation實例,然後建個(gè)binder線程池,因爲(wéi / wèi)BootAnimation在(zài)顯示動畫時(shí)要(yào / yāo)與SurfaceFlinger服務進程通信,所以(yǐ)要(yào / yāo)啓個(gè)binder線程池。
frameworks/base/cmds/bootanimation/BootAnimation.cpp
BootAnimation::BootAnimation() : Thread(false) { mSession = new SurfaceComposerClient();//創建一個(gè)對象 }
創建實例時(shí),構造函數就(jiù)會被調用,new一個(gè)SurfaceComposerClient實例,他(tā)是(shì)用來(lái)與surfaceflinger通信的(de)
void BootAnimation::onFirstRef() { status_t err = mSession->linkToComposerDeath(this);//注冊surfaceflinger死亡消息的(de)通知書 ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err)); if (err == NO_ERROR) { run("BootAnimation", PRIORITY_DISPLAY);//開跑 } }
linkTocomposerDeath的(de)作用是(shì)當surfaceflinger死掉是(shì),BootAnimation就(jiù)會得到(dào)通知。
如下,收到(dào)通知後就(jiù)退出(chū)動畫了(le/liǎo),因爲(wéi / wèi)surfaceflinger都挂掉了(le/liǎo),播放不(bù)了(le/liǎo)了(le/liǎo)。
void BootAnimation::binderDied(const wp<IBinder>& who) { // woah, surfaceflinger died! ALOGD("SurfaceFlinger died, exiting..."); // calling requestExit() is not enough here because the Surface code // might be blocked on a condition variable that will never be updated. kill( getpid(), SIGKILL );//收到(dào)surfaceflinger死亡的(de)消息,好吧自己也(yě)跟着去了(le/liǎo)。 requestExit(); }
另一個(gè)函數run()在(zài)BootAnimation的(de)父類Thead裏,用來(lái)創建一個(gè)線程并跑起來(lái)。
父類
system/core/libutils/Threads.cpp
status_t Thread::run(const char* name, int32_t priority, size_t stack) { ... if (mCanCallJava) { res = createThreadEtc(_threadLoop,//創建線程 this, name, priority, stack, &mThread); } else { res = androidCreateRawThreadEtc(_threadLoop, this, name, priority, stack, &mThread); } .... }
創建_threadLoop線程
int Thread::_threadLoop(void* user) { .... do { bool result; if (first) { first = false; self->mStatus = self->readyToRun();//這(zhè)個(gè)函數被bootanimation重寫了(le/liǎo) result = (self->mStatus == NO_ERROR); if (result && !self->exitPending()) { ... result = self->threadLoop();//這(zhè)個(gè)函數被bootanimation重寫了(le/liǎo) } } else { result = self->threadLoop(); } ... return 0; }
readyToRun函數實現
status_t BootAnimation::readyToRun() { mAssets.addDefaultAssets(); sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay( ISurfaceComposer::eDisplayIdMain)); DisplayInfo dinfo; status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo); if (status) return -1; char value[PROPERTY_VALUE_MAX]; property_get("persist.panel.orientation", value, "0"); int orient = atoi(value) / 90; if(orient == eOrientation90 || orient == eOrientation270) { int temp = dinfo.h; dinfo.h = dinfo.w; dinfo.w = temp; } Rect destRect(dinfo.w, dinfo.h); mSession->setDisplayProjection(dtoken, orient, destRect, destRect); // create the native surface sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"), dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565); SurfaceComposerClient::openGlobalTransaction(); control->setLayer(0x40000000); SurfaceComposerClient::closeGlobalTransaction(); 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, dummy; EGLint numConfigs; EGLConfig config; EGLSurface surface; EGLContext context; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, 0, 0); eglChooseConfig(display, attribs, &config, 1, &numConfigs); surface = eglCreateWindowSurface(display, config, s.get(), NULL); context = eglCreateContext(display, config, NULL, NULL); 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; mAndroidAnimation = true; // If the device has encryption turned on or is in process // of being encrypted we show the encrypted boot animation. char decrypt[PROPERTY_VALUE_MAX]; property_get("vold.decrypt", decrypt, ""); bool encryptedAnimation = atoi(decrypt) != 0 || !strcmp("trigger_restart_min_framework", decrypt); if ((encryptedAnimation && (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) && (mZip.open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE) == NO_ERROR)) || ((access(USER_BOOTANIMATION_FILE, R_OK) == 0) && (mZip.open(USER_BOOTANIMATION_FILE) == NO_ERROR)) || ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) && (mZip.open(SYSTEM_BOOTANIMATION_FILE) == NO_ERROR))) { mAndroidAnimation = false; } return NO_ERROR; }
threadloop實現
bool BootAnimation::threadLoop() { bool r; if (mAndroidAnimation) { r = android();//顯示android默認動畫 } else { r = movie();//顯示自定義的(de)動畫 } // No need to force exit anymore property_set(EXIT_PROP_NAME, "0"); eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(mDisplay, mContext); eglDestroySurface(mDisplay, mSurface); mFlingerSurface.clear(); mFlingerSurfaceControl.clear(); eglTerminate(mDisplay); IPCThreadState::self()->stopProcess(); return r; }
movie()的(de)實現
bool BootAnimation::movie() { //讀取bootanimation.zip文件并解釋 // clear screen //下面是(shì)循環顯示 for (int i=0 ; i<pcount ; i++) { const Animation::Part& part(animation.parts[i]); const size_t fcount = part.frames.size(); glBindTexture(GL_TEXTURE_2D, 0); for (int r=0 ; !part.count || r<part.count ; r++) { // Exit any non playuntil complete parts immediately if(exitPending() && !part.playUntilComplete) break; for (int 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); } initTexture( frame.map->getDataPtr(), frame.map->getDataLength()); } if (!clearReg.isEmpty()) { Region::const_iterator head(clearReg.begin()); Region::const_iterator tail(clearReg.end()); glEnable(GL_SCISSOR_TEST); while (head != tail) { const Rect& r(*head++); glScissor(r.left, mHeight - r.bottom, r.width(), r.height()); glClear(GL_COLOR_BUFFER_BIT); } glDisable(GL_SCISSOR_TEST); } glDrawTexiOES(xc, yc, 0, animation.width, animation.height); eglSwapBuffers(mDisplay, mSurface); nsecs_t now = systemTime(); nsecs_t delay = frameDuration - (now - lastFrame); //ALOGD("%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, NULL); } while (err<0 && errno == EINTR); } checkExit();//檢測是(shì)否退出(chū)動畫 } usleep(part.pause * ns2us(frameDuration)); // For infinite parts, we've now played them at least once, so perhaps exit if(exitPending() && !part.count) break; } // free the textures for this part if (part.count != 1) { for (int j=0 ; j<fcount ; j++) { const Animation::Frame& frame(part.frames[j]); glDeleteTextures(1, &frame.tid); } } } return false; }
那麽到(dào)movie爲(wéi / wèi)止,動畫是(shì)在(zài)播放了(le/liǎo),而(ér)且還在(zài)循環檢測是(shì)否退出(chū),即checkExit()
checkExit()的(de)實現
void BootAnimation::checkExit() { // Allow surface flinger to gracefully request shutdown char value[PROPERTY_VALUE_MAX]; property_get(EXIT_PROP_NAME, value, "0");//屬性爲(wéi / wèi)1,說(shuō)明要(yào / yāo)退出(chū)了(le/liǎo) int exitnow = atoi(value); if (exitnow) { requestExit(); } }
property_get(EXIT_PROP_NAME, value, "0");檢測這(zhè)個(gè)屬性,=1就(jiù)退出(chū)動畫
#define EXIT_PROP_NAME "service.bootanim.exit"這(zhè)個(gè)屬性就(jiù)是(shì)上(shàng)面講到(dào)的(de),等到(dào)launcher跑起來(lái)後就(jiù)會置1
那動畫是(shì)什麽時(shí)候退出(chū)的(de)?
當launcher應用程序主線程跑起來(lái)後,如果主線程處于(yú)空閑,就(jiù)會向ActivityManagerService發送一個(gè)activityIdle的(de)消息。
應用程序主線程是(shì)ActivityThread.java來(lái)描述的(de),activityIdle是(shì)這(zhè)個(gè)類來(lái)實現的(de)
private class Idler implements MessageQueue.IdleHandler { ... IActivityManager am = ActivityManagerNative.getDefault(); ... try { am.activityIdle(a.token, a.createdConfig, stopProfiling); a.createdConfig = null; } catch (RemoteException ex) { // Ignore } .... }
上(shàng)面的(de)ActivityManagerNavtive.getDefault()得到(dào)am
來(lái)到(dào)frameworks/base/core/java/android/app/ActivityManagerNative.java
static public IActivityManager getDefault() { return gDefault.get();//getDefault的(de)實現 }
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } };
gDefault實際上(shàng)是(shì)IActivityManager,往下看
class ActivityManagerProxy implements IActivityManager {
ActivityManagerProxy實現了(le/liǎo)IActivityManager
那麽am.activityIdle()就(jiù)是(shì)ActivityManagerProxy裏的(de)函數,如下
public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) throws RemoteException { ... mRemote.transact(ACTIVITY_IDLE_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);//發送ACTIVITY_IDLE_TRANSACTION .... }
發送了(le/liǎo)ACTIVITY_IDLE_TRANSACTION的(de)進程間通信,這(zhè)個(gè)消息被ActivityManagerNative接收處理了(le/liǎo)。
case ACTIVITY_IDLE_TRANSACTION: {//收到(dào)消息 data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Configuration config = null; if (data.readInt() != 0) { config = Configuration.CREATOR.createFromParcel(data); } boolean stopProfiling = data.readInt() != 0; if (token != null) { activityIdle(token, config, stopProfiling);//這(zhè)個(gè)函數在(zài)ActivityManagerService被重寫 } reply.writeNoException(); return true; }
收到(dào)消息後就(jiù)調用了(le/liǎo)activityIdle函數,這(zhè)個(gè)函數被ActivityManagerService重寫了(le/liǎo),如下
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
@Override public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { final long origId = Binder.clearCallingIdentity(); synchronized (this) { ActivityStack stack = ActivityRecord.getStackLocked(token); if (stack != null) { ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token, false, config); if (stopProfiling) { if ((mProfileProc == r.app) && (mProfileFd != null)) { try { mProfileFd.close(); } catch (IOException e) { } clearProfilerLocked(); } } } } Binder.restoreCallingIdentity(origId); }
調用activityIdleInternalLocked函數,在(zài)下面實現
frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, Configuration config) { .... if (enableScreen) { mService.enableScreenAfterBoot();//調ActivityManagerService類的(de)enableScreenAfterBoot()函數 } .... if (activityRemoved) { resumeTopActivitiesLocked(); } return r; }
來(lái)到(dào)frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
void enableScreenAfterBoot() { EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, SystemClock.uptimeMillis()); mWindowManager.enableScreenAfterBoot();//調WindowManagerService類裏的(de)enableScreenAfterBoot()函數 synchronized (this) { updateEventDispatchingLocked(); } }
來(lái)到(dào)frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
public void enableScreenAfterBoot() { .... performEnableScreen(); }
performEnableScreen()實現
public void performEnableScreen() { ..... surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED data, null, 0); .... }
發送了(le/liǎo)FIRST_CALL_TRANSACTION的(de)請求
因爲(wéi / wèi)從下面知道(dào)FIRST_CALL_TRANSACTION = BOOT_FINISHED
所以(yǐ)BnSurfaceComposer收到(dào)消息
frameworks/native/include/gui/ISurfaceComposer.h
class BnSurfaceComposer: public BnInterface<ISurfaceComposer> { public: enum { // Note: BOOT_FINISHED must remain this value, it is called from // Java by ActivityManagerService. BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION, ... }; virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); };
</pre></p><p><span style="color:#333333;">frameworks/native/libs/gui/ISurfaceComposer.cpp</span></p><p><span style="color:#333333;"></span><pre name="code" class="cpp">status_t BnSurfaceComposer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { .... case BOOT_FINISHED: { CHECK_INTERFACE(ISurfaceComposer, data, reply); bootFinished();//調用 bootFinished() return NO_ERROR; } .... } // should be unreachable return NO_ERROR; }
bootFinished()函數BpSurfaceComposer裏實現,但發現沒有,他(tā)又發了(le/liǎo)一個(gè)BOOT_FINISHED,死循環了(le/liǎo),其實沒有。bootFinished()被SurfaceFlinger類重寫了(le/liǎo)
class BpSurfaceComposer : public BpInterface<ISurfaceComposer> { virtual void bootFinished() { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply); }
重寫
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::bootFinished() { ... property_set("service.bootanim.exit", "1"); }
把service.bootanim.exit寫成1,然後bootanimation進程的(de)checkExit()檢測到(dào)就(jiù)退出(chū)進程,停止播放。