voidBootAnimation::onFirstRef() {
status_t err= mSession->linkToComposerDeath(this);//注册surfaceflinger死亡消息的通知书
ALOGE_IF(err, "linkToComposerDeath failed (%s)", strerror(-err));if (err ==NO_ERROR) {
run("BootAnimation", PRIORITY_DISPLAY);//开跑
}
}
linkTocomposerDeath的作用是当surfaceflinger死掉是,BootAnimation就会得到通知。
如下,收到通知后就退出动画了,因为surfaceflinger都挂掉了,播放不了了。
void BootAnimation::binderDied(const wp&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 );//收到surfaceflinger死亡的消息,好吧自己也跟着去了。
requestExit();
}
另一个函数run()在BootAnimation的父类Thead里,用来创建一个线程并跑起来。
父类
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{boolresult;if(first) {
first= false;
self->mStatus = self->readyToRun();//这个函数被bootanimation重写了
result = (self->mStatus ==NO_ERROR);if (result && !self->exitPending()) {
...
result= self->threadLoop();//这个函数被bootanimation重写了
}
}else{
result= self->threadLoop();
}
...return 0;
}
readyToRun函数实现
status_t BootAnimation::readyToRun() {
mAssets.addDefaultAssets();
spdtoken(SurfaceComposerClient::getBuiltInDisplay(
ISurfaceComposer::eDisplayIdMain));
DisplayInfo dinfo;
status_t status= SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);if(status)return -1;charvalue[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 control = session()->createSurface(String8("BootAnimation"),
dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
SurfaceComposerClient::openGlobalTransaction();
control->setLayer(0x40000000);
SurfaceComposerClient::closeGlobalTransaction();
sp 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)returnNO_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.
chardecrypt[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;
}returnNO_ERROR;
}
threadloop实现
boolBootAnimation::threadLoop()
{boolr;if(mAndroidAnimation) {
r= android();//显示android默认动画
} else{
r= movie();//显示自定义的动画
}//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();returnr;
}
movie()的实现
boolBootAnimation::movie()
{//读取bootanimation.zip文件并解释//clear screen//下面是循环显示
for (int i=0 ; i
glBindTexture(GL_TEXTURE_2D,0);for (int r=0 ; !part.count || r
if(exitPending() && !part.playUntilComplete)break;for (int j=0 ; 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) {structtimespec spec;
spec.tv_sec= (now + delay) / 1000000000;
spec.tv_nsec= (now + delay) % 1000000000;interr;do{
err= clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
}while (err<0 && errno ==EINTR);
}
checkExit();//检测是否退出动画
}
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
glDeleteTextures(1, &frame.tid);
}
}
}return false;
}
那么到movie为止,动画是在播放了,而且还在循环检测是否退出,即checkExit()
checkExit()的实现
voidBootAnimation::checkExit() {//Allow surface flinger to gracefully request shutdown
charvalue[PROPERTY_VALUE_MAX];
property_get(EXIT_PROP_NAME, value,"0");//属性为1,说明要退出了
int exitnow =atoi(value);if(exitnow) {
requestExit();
}
}
property_get(EXIT_PROP_NAME, value, "0");检测这个属性,=1就退出动画
#define EXIT_PROP_NAME "service.bootanim.exit"
这个属性就是上面讲到的,等到launcher跑起来后就会置1
那动画是什么时候退出的?
当launcher应用程序主线程跑起来后,如果主线程处于空闲,就会向ActivityManagerService发送一个activityIdle的消息。
应用程序主线程是ActivityThread.java来描述的,activityIdle是这个类来实现的
private classIdler implements MessageQueue.IdleHandler {
...
IActivityManager am=ActivityManagerNative.getDefault();
...try{
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig= null;
}catch(RemoteException ex) {//Ignore
}
....
}
上面的ActivityManagerNavtive.getDefault()得到am
来到frameworks/base/core/java/android/app/ActivityManagerNative.java
static publicIActivityManager getDefault() {return gDefault.get();//getDefault的实现
}private static final Singleton gDefault = new Singleton() {protectedIActivityManager 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);
}returnam;
}
};
gDefault实际上是IActivityManager,往下看
class ActivityManagerProxy implements IActivityManager
{
ActivityManagerProxy实现了IActivityManager
那么am.activityIdle()就是ActivityManagerProxy里的函数,如下
public voidactivityIdle(IBinder token, Configuration config, boolean stopProfiling)
throws RemoteException
{
...
mRemote.transact(ACTIVITY_IDLE_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);//发送ACTIVITY_IDLE_TRANSACTION
....
}
发送了ACTIVITY_IDLE_TRANSACTION的进程间通信,这个消息被ActivityManagerNative接收处理了。
case ACTIVITY_IDLE_TRANSACTION: {//收到消息
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);//这个函数在ActivityManagerService被重写
}
reply.writeNoException();return true;
}
收到消息后就调用了activityIdle函数,这个函数被ActivityManagerService重写了,如下
frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
@Overridepublic final voidactivityIdle(IBinder token, Configuration config, boolean stopProfiling) {
finallong 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函数,在下面实现
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类的enableScreenAfterBoot()函数
}
....if(activityRemoved) {
resumeTopActivitiesLocked();
}returnr;
}
来到frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
voidenableScreenAfterBoot() {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
SystemClock.uptimeMillis());
mWindowManager.enableScreenAfterBoot();//调WindowManagerService类里的enableScreenAfterBoot()函数
synchronized (this) {
updateEventDispatchingLocked();
}
}
来到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);
....
}
发送了FIRST_CALL_TRANSACTION的请求
因为从下面知道FIRST_CALL_TRANSACTION = BOOT_FINISHED
所以BnSurfaceComposer收到消息
frameworks/native/include/gui/ISurfaceComposer.h
class BnSurfaceComposer: public BnInterface{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);
};
frameworks/native/libs/gui/ISurfaceComposer.cpp
status_t BnSurfaceComposer::onTransact(
uint32_t code,const Parcel& data, Parcel*reply, uint32_t flags)
{switch(code) {
....caseBOOT_FINISHED: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
bootFinished();//调用 bootFinished()
returnNO_ERROR;
}
....
}//should be unreachable
returnNO_ERROR;
}
bootFinished()函数BpSurfaceComposer里实现,但发现没有,他又发了一个BOOT_FINISHED,死循环了,其实没有。bootFinished()被SurfaceFlinger类重写了
class BpSurfaceComposer : public BpInterface{virtual voidbootFinished()
{
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进程的checkExit()检测到就退出进程,停止播放。