• android 5.1 BatteryManager深入分析


    BatteryManager主要是去主动查看电池状态,主要通过binder通信去healthd中查看电池的各个属性。

    可以看下BatteryManager的主要代码

    private long queryProperty(int id) {
        long ret;
    
        if (mBatteryPropertiesRegistrar == null) {
            IBinder b = ServiceManager.getService("batteryproperties");//这个service就是在healthd中加入ServiceManager中
            mBatteryPropertiesRegistrar =
                IBatteryPropertiesRegistrar.Stub.asInterface(b);//转化接口
    
            if (mBatteryPropertiesRegistrar == null)
                return Long.MIN_VALUE;
        }
    
        try {
            BatteryProperty prop = new BatteryProperty();//新建一个数据类型
    
            if (mBatteryPropertiesRegistrar.getProperty(id, prop) == 0)//prop作为结果返回
                ret = prop.getLong();
            else
                ret = Long.MIN_VALUE;
        } catch (RemoteException e) {
            ret = Long.MIN_VALUE;
        }
    
        return ret;
    }
    
    public int getIntProperty(int id) {
        return (int)queryProperty(id);
    }
    
    public long getLongProperty(int id) {
        return queryProperty(id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    }

    接下来我们看下healthd中batteryproperties这个service:

    void BatteryPropertiesRegistrar::publish() {
    defaultServiceManager()->addService(String16(“batteryproperties”), this);//将service加入到serviceManager中
    }

    void BatteryPropertiesRegistrar::notifyListeners(struct BatteryProperties props) {
    Mutex::Autolock _l(mRegistrationLock);
    for (size_t i = 0; i < mListeners.size(); i++) {//通知各个注册到healthd中的listener,类似BatteryService中注册到healthd中的listener(binder通信)
    mListeners[i]->batteryPropertiesChanged(props);
    }
    }

    void BatteryPropertiesRegistrar::registerListener(const sp& listener) {//注册到healthd的函数,比如BatteryService中,实现一个aidl,然后将这个类的stub实现,发到这边注册
    //这样BatteryService中的BatteryLIstener就类似这边的一个server端,把接口发过来,到时候利用notifyListener来进行跨进程调用。
    {
    if (listener == NULL)
    return;
    Mutex::Autolock _l(mRegistrationLock);
    // check whether this is a duplicate
    for (size_t i = 0; i < mListeners.size(); i++) {
    if (mListeners[i]->asBinder() == listener->asBinder()) {
    return;
    }
    }

        mListeners.add(listener);
        listener->asBinder()->linkToDeath(this);
    }
    healthd_battery_update();
    
    • 1
    • 2
    • 3
    • 4

    }

    status_t BatteryPropertiesRegistrar::getProperty(int id, struct BatteryProperty *val) {
    return healthd_get_property(id, val);
    }

    当BatteryManager中调用getProperty会到healthd中的getProperty,下面我们再详细看看这个函数:

    status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {
    status_t ret = BAD_VALUE;

    val->valueInt64 = LONG_MIN;
    
    switch(id) {
    case BATTERY_PROP_CHARGE_COUNTER:
        if (!mHealthdConfig->batteryChargeCounterPath.isEmpty()) {
            val->valueInt64 =
                getIntField(mHealthdConfig->batteryChargeCounterPath);//将结果返回到BatteryProperty对象中
            ret = NO_ERROR;//返回0是没有错
        } else {
            ret = NAME_NOT_FOUND;
        }
        break;
    
    case BATTERY_PROP_CURRENT_NOW:
        if (!mHealthdConfig->batteryCurrentNowPath.isEmpty()) {
            val->valueInt64 =
                getIntField(mHealthdConfig->batteryCurrentNowPath);
            ret = NO_ERROR;
        } else {
            ret = NAME_NOT_FOUND;
        }
        break;
    
    case BATTERY_PROP_CURRENT_AVG:
        if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty()) {
            val->valueInt64 =
                getIntField(mHealthdConfig->batteryCurrentAvgPath);
            ret = NO_ERROR;
        } else {
            ret = NAME_NOT_FOUND;
        }
        break;
    
    case BATTERY_PROP_CAPACITY:
        if (!mHealthdConfig->batteryCapacityPath.isEmpty()) {
            val->valueInt64 =
                getIntField(mHealthdConfig->batteryCapacityPath);
            ret = NO_ERROR;
        } else {
            ret = NAME_NOT_FOUND;
        }
        break;
    
    case BATTERY_PROP_ENERGY_COUNTER:
        if (mHealthdConfig->energyCounter) {
            ret = mHealthdConfig->energyCounter(&val->valueInt64);
        } else {
            ret = NAME_NOT_FOUND;
        }
        break;
    
    default:
        break;
    }
    
    return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
  • 相关阅读:
    从零开始学习JavaScript:轻松掌握编程语言的核心技能①
    【C++】之类和对象 - 初始化列表
    mysql源码分析——InnoDB的磁盘结构之表空间格式
    信息学奥赛一本通:1175:除以13
    centos如何安装最新版nodejs
    Java版直播商城免 费 搭 建:电商、小程序、三级分销及免 费 搭 建,平台规划与营销策略全掌握
    LeetCode刷题:27. 移除元素
    vulnhub靶机hacksudoLPE中Challenge-1
    【个人简历】如何让人眼前一亮?简约大方(附模板)
    什么是生成对抗网络 (GAN)?
  • 原文地址:https://blog.csdn.net/baiyifei2016/article/details/126027966