文章初始给大家推荐一篇文章https://blog.csdn.net/xlnaan/article/details/80904309#commentBox
上篇文章已经分析到开机动画的两种播放形式了https://blog.csdn.net/we1less/article/details/116464874
首先以android()方式播放
android() AOSP/frameworks/base/cmds/bootanimation/BootAnimation.cpp
bool BootAnimation::android()
{
{
...
checkExit();
} while (!exitPending());
...
return false;
}
这里可以看到在开机动画播放的循环当中以checkExit()判断终止循环播放
void BootAnimation::checkExit() {
// Allow surface flinger to gracefully request shutdown
char value[PROPERTY_VALUE_MAX];
property_get(EXIT_PROP_NAME, value, "0");
int exitnow = atoi(value);
if (exitnow) {
requestExit();
mCallbacks->shutdown();
}
}
关于这个requestExit() 和exitPending()可以参考https://blog.csdn.net/llping2011/article/details/9706599 大致意思就是调用requestExit() ExitexitPending()就会返回true
可以在这看出 退出循环的标志就是 EXIT_PROP_NAME 的值 默认是0
static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
可以查询一下这个属性到底在哪做过设置
godv@godv-OptiPlex-7070:~/godv/AOSP/android-8.1.0_r1/frameworks$ grep "service.bootanim.exit" ./ -rn
./native/services/surfaceflinger/SurfaceFlinger_hwc1.cpp:341: property_set("service.bootanim.exit", "1");
./native/services/surfaceflinger/StartPropertySetThread.cpp:33: property_set("service.bootanim.exit", "0");
./native/services/surfaceflinger/SurfaceFlinger.cpp:388: property_set("service.bootanim.exit", "1");
./base/cmds/bootanimation/BootAnimation.cpp:93:static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
./base/cmds/bootanimation/FORMAT.md:77:the system property `service.bootanim.exit` to a nonzero string.)
./base/services/core/java/com/android/server/wm/WindowManagerService.java:3509: SystemProperties.set("service.bootanim.exit", "1");
可以看出 service.bootanim.exit 这个属性在 SurfaceFlinger.cpp:388 和 WindowManagerService.java:3509 出现过
首先看WindowManagerService出现的位置
WindowManagerService.java AOSP/frameworks/base/services/core/java/com/android/server/wm
private void performEnableScreen() {
synchronized(mWindowMap) {
...
if (!mBootAnimationStopped) {
Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
// stop boot animation
// formerly we would just kill the process, but we now ask it to exit so it
// can choose where to stop the animation.
SystemProperties.set("service.bootanim.exit", "1");
mBootAnimationStopped = true;
}
...
}
在不明确当前函数performEnableScreen()如何调用 可以使用打印堆栈来实现查看调用链 具体可以参考https://blog.csdn.net/we1less/article/details/115792043
03-09 00:53:27.569 1712 1712 I lsm2 : Scheduling idle handler for ActivityRecord{5c8f360 token=android.os.BinderProxy@6d26d5c {com.android.settings/com.android.settings.FallbackHome}}
//1、进入idle
03-09 00:53:27.687 1712 1712 I lsm2 : activityIdle a.activity ComponentInfo{com.android.settings/com.android.settings.FallbackHome}
//2、跨进程调用到AMS中,执行了postFinishBooting
03-09 00:53:27.941 1529 1584 D lsm2 : postFinishBooting finishBooting true enableScreen true
03-09 00:53:27.941 1529 1584 D lsm2 : java.lang.Exception
03-09 00:53:27.941 1529 1584 D lsm2 : at com.android.server.am.ActivityManagerService.postFinishBooting(ActivityManagerService.java:7244)
03-09 00:53:27.941 1529 1584 D lsm2 : at com.android.server.am.ActivityStackSupervisor.checkFinishBootingLocked(ActivityStackSupervisor.java:1874)
03-09 00:53:27.941 1529 1584 D lsm2 : at com.android.server.am.ActivityStackSupervisor.activityIdleInternalLocked(ActivityStackSupervisor.java:1916)
03-09 00:53:27.941 1529 1584 D lsm2 : at com.android.server.am.ActivityManagerService.activityIdle(ActivityManagerService.java:7231)
03-09 00:53:27.941 1529 1584 D lsm2 : at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:309)
03-09 00:53:27.941 1529 1584 D lsm2 : at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2919)
03-09 00:53:27.941 1529 1584 D lsm2 : at android.os.Binder.execTransact(Binder.java:697)
//3、调用到WMS中的performEnableScreen
03-09 00:52:44.223 1529 1552 D lsm2 : WindowManagerService performEnableScreen Stop bootanim
03-09 00:52:44.223 1529 1552 D lsm2 : java.lang.Exception
03-09 00:52:44.223 1529 1552 D lsm2 : at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3511)
03-09 00:52:44.223 1529 1552 D lsm2 : at com.android.server.wm.WindowManagerService.-wrap6(Unknown Source:0)
03-09 00:52:44.223 1529 1552 D lsm2 : at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:5065)
03-09 00:52:44.223 1529 1552 D lsm2 : at android.os.Handler.dispatchMessage(Handler.java:106)
03-09 00:52:44.223 1529 1552 D lsm2 : at android.os.Looper.loop(Looper.java:164)
03-09 00:52:44.223 1529 1552 D lsm2 : at android.os.HandlerThread.run(HandlerThread.java:65)
03-09 00:52:44.223 1529 1552 D lsm2 : at com.android.server.ServiceThread.run(ServiceThread.java:46)
//4、跨进程调用到SurfaceFlinger
03-09 00:52:44.310 1529 1552 D lsm2 : WindowManagerService performEnableScreen surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION
//5、SurfaceFlinger执行prop的设置
03-09 00:52:44.311 1368 1594 I SurfaceFlinger: lsm2 SurfaceFlinger service.bootanim.exit 1
03-09 00:52:45.573 2014 2014 I lsm2 : Scheduling idle handler for ActivityRecord{f5df6ba token=android.os.BinderProxy@80709eb {com.android.launcher/com.android.launcher2.Launcher}}
可以从上述log中看出当FallbackHome进入idle的状态后会跨进程通信调用到AMS中再跨进程通信调用到WMS中调用performEnableScreen()方法 这个方法设置属性控制开机动画结束
/native/services/surfaceflinger/SurfaceFlinger.cpp:388: property_set("service.bootanim.exit", "1");
第二也可以在SurfaceFlinger 388行发现设置开机动画结束属性
bootFinished() AOSP/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::bootFinished()
{
...
// stop boot animation
// formerly we would just kill the process, but we now ask it to exit so it
// can choose where to stop the animation.
property_set("service.bootanim.exit", "1");
...
}
利用查询bootFinished()的调用过程
godv@godv-OptiPlex-7070:~/godv/AOSP/android-8.1.0_r1/frameworks$ grep "bootFinished()" ./ -rn
./native/libs/gui/ISurfaceComposer.cpp:96: virtual void bootFinished()
./native/libs/gui/ISurfaceComposer.cpp:537: bootFinished();
./native/libs/gui/include/gui/ISurfaceComposer.h:123: virtual void bootFinished() = 0;
./native/libs/gui/tests/Surface_test.cpp:479: void bootFinished() override {}
./native/services/surfaceflinger/SurfaceFlinger_hwc1.cpp:321:void SurfaceFlinger::bootFinished()
./native/services/surfaceflinger/SurfaceFlinger.h:287: virtual void bootFinished();
./native/services/surfaceflinger/SurfaceFlinger.cpp:365:void SurfaceFlinger::bootFinished()
发现是在 ISurfaceComposer.cpp 中调用的
status_t BnSurfaceComposer::onTransact AOSP/android-8.1.0_r1/frameworks/native/libs/gui/ISurfaceComposer.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();
return NO_ERROR;
}
...
}
}
同样的搜索BOOT_FINISHED
godv@godv-OptiPlex-7070:~/godv/AOSP/android-8.1.0_r1/frameworks$ grep "BOOT_FINISHED" ./ -rn
./native/libs/gui/ISurfaceComposer.cpp:100: remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
./native/libs/gui/ISurfaceComposer.cpp:535: case BOOT_FINISHED: {
./native/libs/gui/include/gui/ISurfaceComposer.h:205: // Note: BOOT_FINISHED must remain this value, it is called from
./native/libs/gui/include/gui/ISurfaceComposer.h:207: BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
./native/services/surfaceflinger/SurfaceFlinger_hwc1.cpp:3384: case BOOT_FINISHED:
./native/services/surfaceflinger/SurfaceFlinger.cpp:3889: case BOOT_FINISHED:
./base/services/core/java/com/android/server/wm/WindowManagerService.java:3525: surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
./native/libs/gui/include/gui/ISurfaceComposer.h:207: BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
继续搜索 IBinder::FIRST_CALL_TRANSACTION
godv@godv-OptiPlex-7070:~/godv/AOSP/android-8.1.0_r1/frameworks$ grep "FIRST_CALL_TRANSACTION," ./ -rn | grep "surface"
./base/services/core/java/com/android/server/wm/WindowManagerService.java:3525: surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
发现同样的又在WMS中调用的 看WMS中的代码
WindowManagerService.java AOSP/frameworks/base/services/core/java/com/android/server/wm
private void performEnableScreen() {
synchronized(mWindowMap) {
...
if (!mBootAnimationStopped) {
Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
// stop boot animation
// formerly we would just kill the process, but we now ask it to exit so it
// can choose where to stop the animation.
SystemProperties.set("service.bootanim.exit", "1");
mBootAnimationStopped = true;
}
...
try {
IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
if (surfaceFlinger != null) {
Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
data, null, 0);
data.recycle();
}
} catch (RemoteException ex) {
Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
}
}
此时发现两个不同设置开机动画属性停止动画的起始位置居然是同一个函数而且还是先后顺序执行的
这样就调到了surfaceFlinger.transact
SurfaceFlinger::onTransact AOSP/android-8.1.0_r1/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
...
status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
...
}
由此调用BnSurfaceComposer::onTransact此时一个闭环已经形成了