android8.1开机动画停止分析

本文详细分析了Android系统中开机动画的关闭流程,从WindowManagerService的performEnableScreen()方法开始,通过设置'service.bootanim.exit'属性为1来请求结束开机动画。这一过程涉及到SurfaceFlinger服务的交互,最终由SurfaceFlinger设置该属性来完成动画的停止。整个过程涉及跨进程通信和Binder调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

文章初始给大家推荐一篇文章https://blog.youkuaiyun.com/xlnaan/article/details/80904309#commentBox

上篇文章已经分析到开机动画的两种播放形式了https://blog.youkuaiyun.com/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.youkuaiyun.com/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.youkuaiyun.com/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此时一个闭环已经形成了

<think>好的,用户想在Android 8.1中默认启用NFC Beam功能。我需要根据提供的参考资料和系统级指令来回答这个问题。首先,要理解Android 8.1的配置通常涉及系统设置和源码修改。用户提到的其他引用涉及Settings模块的修改、Java环境配置、开关机铃声等,这些可能提供线索。 NFC Beam功能通常与NFC设置相关,可能在Settings应用中有一个开关。要让这个功能默认启用,可能需要修改系统默认值或者预设配置。查看引用中提到的Settings相关的类,比如TetherSettings.java,可能类似的NFC设置会在某个类似的Java类中,比如NfcSettings.java或NfcEnabler.java。 另外,引用[1]提到通过intent-filter的优先级调整菜单顺序,这可能涉及到在AndroidManifest.xml中设置优先级,但不确定是否适用于NFC Beam。不过,修改系统默认设置可能需要更改SharedPreferences的默认值或修改数据库的默认配置。 在Android系统中,默认的开关状态通常存储在SettingsProvider的数据库中,比如Settings.Secure或Settings.Global。因此,可能需要找到对应的键值,然后在系统初始化时设置默认值。例如,NFC Beam的开关可能对应某个特定的key,如“nfc_beam_enabled”。 另外,引用[3]中修改了音频相关的代码,通过属性控制开机动画结束后的音量。类似地,可能需要检查NFC相关的服务代码,在系统启动时自动启用Beam功能。例如,在NfcService启动时,调用相应的API来启用Beam。 总结可能的步骤: 1. 找到控制NFC Beam的Settings键名。 2.系统源码中设置该键的默认值为启用。 3. 修改对应的Settings界面,确保默认选中。 4. 可能需要修改NFC相关的服务代码,确保初始化时启用Beam。 需要验证这些步骤是否可行,并参考类似模块的修改方式,比如引用[4]中的热点设置,可能涉及类似的Enabler类和状态机。可能需要查看NfcEnabler类,确保在初始化时启用Beam功能。 同时,用户可能需要系统级权限或修改系统镜像,因此建议在编译时进行这些更改,并重新生成系统镜像。此外,可能需要处理权限问题,确保应用有权限修改系统设置。</think>在Android 8.1中默认启用NFC Beam功能,需通过系统源码层修改实现。以下是具体操作步骤: ### 一、定位NFC Beam配置参数 1. NFC Beam的控制参数通常存储在`Settings.Secure`数据库中,键名可能为`android_beam_on`或`nfc_beam_enabled`。需在源码中验证具体键名: ```java // frameworks/base/core/java/android/provider/Settings.java public static final String ANDROID_BEAM_ON = "android_beam_on"; ``` ### 二、修改系统默认值 在`frameworks/base/packages/SettingsProvider/res/values/defaults.xml`中添加默认值: ```xml <bool name="def_android_beam_on">true</bool> ``` 并在`SettingsProvider`的数据库初始化逻辑中关联该值[^4]。 ### 三、调整NFC服务初始化 在`NfcService`启动时强制启用Beam功能(路径:`packages/apps/Nfc/src/com/android/nfc/NfcService.java`): ```java // 在onNativeInitialize()或初始化流程末尾添加 mDeviceHost.setBeam(true); mPrefs.edit().putBoolean(PREF_BEAM_ON, true).apply(); ``` ### 四、修改Settings界面逻辑 1. 在`packages/apps/Settings/src/com/android/settings/nfc/NfcEnabler.java`中注释状态监听覆盖: ```java // 原代码:mSwitch.setChecked(mNfcAdapter.isNdefPushEnabled()); mSwitch.setChecked(true); // 强制设为启用状态 ``` 2. 在布局文件`nfc_settings.xml`中设置默认选中状态[^1]。 ### 五、添加系统权限 若遇到权限问题,需在`AndroidManifest.xml`声明系统签名权限: ```xml <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值