监听系统属性SystemProperties值变化

基于 Android-S

一、实现逻辑

相关文件:
frameworks/native/libs/binder/Binder.cpp
/system/core/libutils/misc.cpp
/android/frameworks/base/core/java/android/os/SystemProperties.java
/android/frameworks/base/core/jni/android_os_SystemProperties.cpp
/android/frameworks/base/core/jni/android_util_Binder.cpp

1. callback注册:

private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>(); //SystemProperties.java
static Vector<sysprop_change_callback_info>* gSyspropList = nullptr; //misc.c

    addChangeCallback(Runnable callback) //SystemProperties.java public static的
        native_add_change_callback() //只对首个callback的注册执行,注意没有传任何参数 #####
            SystemProperties_add_change_callback(JNIEnv *env, jobject clazz) //android_os_SystemProperties.cpp
                sCallChangeCallbacks = env->GetStaticMethodID(sClazz, "callChangeCallbacks", "()V"); //记录java函数的id
                add_sysprop_change_callback(do_report_sysprop_change, -10000); //形参(cb, priority)
                    sysprop_change_callback_info info;
                    info.callback = cb; //固定是 do_report_sysprop_change()
                    info.priority = priority;
                    bool added = false;
                    for (size_t i=0; i<gSyspropList->size(); i++) { //(只有首个才会)插入到全局vector gSyspropList 中
                        if (priority >= gSyspropList->itemAt(i).priority) {
                            gSyspropList->insertAt(info, i); //priority数值大的插入在前面
                            added = true;
                            break;
                        }
                    }
                    if (!added) {
                        gSyspropList->add(info); //优先级数值最小的插入在末尾
                    }
        sChangeCallbacks.add(callback) //SystemProperties.java 添加到 ArrayList<Runnable> 链表中


2. 服务端响应,调用回调:

onTransact() //android_util_Binder.cpp if (code == SYSPROPS_TRANSACTION) 成立才调用
    BBinder::onTransact() //Binder.cpp
        case SYSPROPS_TRANSACTION:
            report_sysprop_change() //misc.cpp
                do_report_sysprop_change //android_os_SystemProperties.cpp 使用的是namespace Android里面的函数 【1】
                    env->CallStaticVoidMethod(sClazz, sCallChangeCallbacks); //native回调Java函数
                        callChangeCallbacks() //SystemProperties.java 看下面首个注册,是这个函数
                            ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
                            for (int i = 0; i < callbacks.size(); i++) {
                                callbacks.get(i).run(); //直接调用Runnable类的run()方法,相当于在本线程中执行
                            }
                get_report_sysprop_change_func() //misc.cpp
                    do_report_sysprop_change //misc.cpp 通过dlopen(libutils.so)获取的,它本身也属于这个库。
                        Vector<sysprop_change_callback_info> listeners = *gSyspropList; //每个进程首个插入callback时会添加到这里来
                        for (size_t i=0; i<listeners.size(); i++) {
                            listeners[i].callback();
                                do_report_sysprop_change() //android_os_SystemProperties.cpp callback只有一个,固定为它,它的执行内容就是【1】
                        }

TODO: 【1】为啥会重复执行呢?是不同的内容执行的不一样吗?


3. 客户端调用,使用服务:

/android/frameworks/base/packages/SettingsLib/src/com/android/settingslib/development/SystemPropPoker.java

SystemPropPoker.poke() //这个是通知所有有名服务
    createPokerTask().execute()
        doInBackground(Void... params)
            String[] services = listServices(); //对系统中的每一个有名服务都调用(你也可以单独调用某一个服务的)########
            for (String service : services) {
                IBinder obj = checkService(service);
                obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0)
            }

触发所有有名服务注册的callback回调。

 

二、其它使用位置

1. ANRdaemon

main(int argc, char* argv[])
    start() //ANRdaemon.cpp
        dfs_poke_binder() //ANRdaemon.cpp
            sp<IServiceManager> sm = defaultServiceManager();
            Vector<String16> services = sm->listServices();
            for (size_t i = 0; i < services.size(); i++) {
                sp<IBinder> obj = sm->checkService(services[i]);
                if (obj != NULL) {
                    Parcel data;
                    obj->transact(IBinder::SYSPROPS_TRANSACTION, data, NULL, 0);
                }
            }

编译成 anrd 这个可执行文件,一般不集成。

 

三、总结

高负载下此调用会导致SS的绝大多数binder线程被卡住。

 

 

参考:

监听SystemProperties变化: https://blog.csdn.net/m0_52481422/article/details/109776370

 

posted on 2024-11-01 22:08  Hello-World3  阅读(18)  评论(0编辑  收藏  举报

导航