android8.0之前的BatteryService

##转载###
版权声明:本文为CSDN博主「sanzhong104204」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq759981398/article/details/73155782

【注意】本文在原作者的基础上做了一些补充

本文进行第一层分解,将整个电池电量上报的过程分解到Android的不同层次。
先上一幅图,对电量上报的流程有个整体的概念,后续对该图的各个部分进行讲解。

在这里插入图片描述

如图中所述,整个电量上报过程分为4个层次:

1. Kernel 层
本层属于电池的驱动部分,负责与硬件进行交互,当电池电量信息发生变化时,生成相应的uevent,上报给用户层。

主要相关代码路径:

/linux-4.5/drivers/ower/power_supply_core.c
/linux-4.5/drivers/power/power_supply_sysfs.c

2. Healthd守护进程
本层在Android中属于Native层,healthd中运行一个系统服务batteryproperties,负责监听Kernel中上报的uevent,对电池电量进行实时监控。监听的路径主要是:

/sys/class/power_supply/battery/uevent

当监听路径有数据发生变化时,healtd调用bool BatteryMonitor::update来更新电池信息,代码实现如下

bool BatteryMonitor::update(void) {
.......
    //更新电池信息
    if (mBatteryPropertiesRegistrar != NULL)
        mBatteryPropertiesRegistrar->notifyListeners(props);//更新电池信息

    return props.chargerAcOnline | props.chargerUsbOnline |
            props.chargerWirelessOnline;
}

BatteryPropertiesRegistrar::notifyListener的实现如下:

void BatteryPropertiesRegistrar::notifyListeners(struct BatteryProperties props) {
    Mutex::Autolock _l(mRegistrationLock);
    for (size_t i = 0; i < mListeners.size(); i++) {
        //调用java层BatteryListener的batteryPropertiesChanged方法
        mListeners[i]->batteryPropertiesChanged(props);
    }
}

主要相关代码路径:

./system/core/healthd/healthd.cpp
./system/core/healthd/BatteryMonitor.cpp
./system/core/healthd/BatteryPropertiesRegistrar.cpp
./system/core/healthd/BatteryMonitor.cpp

3. BatteryService系统服务
本层提供了C++/Java两套接口来访问batteryproperties系统服务。
本层的系统服务battery使用Java代码写成,运行在fwk的中SystemServer进程。
该系统服务的主要作用是:监听batteryproperties服务中的电池信息变化消息,并将该消息以系统广播的形式转发至Android系统中各处。

主要相关代码路径:

/frameworks/native/services/batteryservice/IBatteryPropertiesRegistrar.cpp
/frameworks/native/services/batteryservice/IBatteryPropertiesListener.cpp
/frameworks/native/services/batteryservice/BatteryProperties.cpp
/frameworks/base/core/java/android/os/IBatteryPropertiesRegistrar.aidl
/frameworks/base/core/java/android/os/IBatteryPropertiesListener.aidl
/frameworks/base/core/java/android/os/BatteryProperties.java
/frameworks/base/services/core/java/com/android/server/BatteryService.java

如上的 mListeners[i]->batteryPropertiesChanged是如何注册到BatteryPropertiesRegistrar中的呢?注册监听电池变化代码如下:

\frameworks\base\services\core\java\com\android\server\BatteryService.java

    //获取监听对象BatteryListener
	mBatteryPropertiesListener = new BatteryListener();
	
	IBinder b = ServiceManager.getService("batterypropreg");
	mBatteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);
	
	try {
	    //注册监听对像mBatteryPropertiesListener
	    mBatteryPropertiesRegistrar.registerListener(mBatteryPropertiesListener);
	} catch (RemoteException e) {
	    // Should never happen.
	}

    private final class BatteryListener extends IBatteryPropertiesListener.Stub {
        public void batteryPropertiesChanged(BatteryProperties props) {
            //当电池变化的时候,监听回调update方法进而实现更新电池状态。
            BatteryService.this.update(props);
       }
    }

mBatteryPropertiesRegistrar.registerListener电池回调监听注册代码实现如下。

./system/core/healthd/BatteryPropertiesRegistrar.cpp

void BatteryPropertiesRegistrar::registerListener(const sp<IBatteryPropertiesListener>& listener) {
    {
        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;
            }
        }

       //将BatteryService中的mBatteryPropertiesListener注册到mListeners中。
       //等电池变化的时候,healthd会调用 mListeners[i]->batteryPropertiesChanged(props);
       //mListeners[i]便是此处进行赋值注册的
        mListeners.add(listener);
        listener->asBinder()->linkToDeath(this);
    }
    mBatteryMonitor->update();
}

发送广播:
当BatteryService.this.update被调用的时候,会发送ACTION_BATTERY_CHANGED广播来通知SystemUI以及感兴趣的应用。代码流程如下

代码路径:
./frameworks/base/services/java/com/android/server/BatteryService.java

private final class BatteryListener extends IBatteryPropertiesListener.Stub {
    public void batteryPropertiesChanged(BatteryProperties props) {
        //(1)更新电池信息
        BatteryService.this.update(props);
   }
}

(1)update的实现

代码路径:
./frameworks/base/services/java/com/android/server/BatteryService.java

   private void update(BatteryProperties props) {
        synchronized (mLock) {
            if (!mUpdatesStopped) {
                mBatteryProps = props;
                // Process the new values.
                processValuesLocked();
            }
        }
    }

(2)processValuesLocked的主要实现

代码路径:
./frameworks/base/services/java/com/android/server/BatteryService.java

 private void processValuesLocked() {
	 ......
	 //发送广播
	 sendIntentLocked();
	 ......
 }

(3)sendIntentLocked的实现,可见主要是发送ACTION_BATTERY_CHANGED广播,并附带电池信息。

代码路径:
./frameworks/base/services/java/com/android/server/BatteryService.java

  private void sendIntentLocked() {
        //  Pack up the values and broadcast them to everyone
        final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                | Intent.FLAG_RECEIVER_REPLACE_PENDING);

        int icon = getIconLocked(mBatteryProps.batteryLevel);

        intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryProps.batteryStatus);
        intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryProps.batteryHealth);
        intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryProps.batteryPresent);
        intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryProps.batteryLevel);
        intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
        intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
        intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
        intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryProps.batteryVoltage);
        intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryProps.batteryTemperature);
        intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryProps.batteryTechnology);
        intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);

        if (DEBUG) {
            Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED.  level:" + mBatteryProps.batteryLevel +
                    ", scale:" + BATTERY_SCALE + ", status:" + mBatteryProps.batteryStatus +
                    ", health:" + mBatteryProps.batteryHealth +  ", present:" + mBatteryProps.batteryPresent +
                    ", voltage: " + mBatteryProps.batteryVoltage +
                    ", temperature: " + mBatteryProps.batteryTemperature +
                    ", technology: " + mBatteryProps.batteryTechnology +
                    ", AC powered:" + mBatteryProps.chargerAcOnline + ", USB powered:" + mBatteryProps.chargerUsbOnline +
                    ", Wireless powered:" + mBatteryProps.chargerWirelessOnline +
                    ", icon:" + icon  + ", invalid charger:" + mInvalidCharger);
        }

        mHandler.post(new Runnable() {
            @Override
            public void run() {
                ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
            }
        });
    }

4. SystemUI 应用
该部分属于电量上报的最后的环节。其主要工作是:监听系统广播Intent.ACTION_BATTERY_CHANGED,并对UI作出相应更新。

主要相关代码路径:
./frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerUI.java

代码逻辑:
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            //接收电池变化的广播
            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
               ......
                if (!plugged
                        && (bucket < oldBucket || oldPlugged)
                        && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
                        && bucket < 0) {
                    //根据电量的情况判读是否显示电量过低等
                    showLowBatteryWarning();

                    // only play SFX when the dialog comes up or the bucket changes
                    if (bucket != oldBucket || oldPlugged) {
                        playLowBatterySound();
                    }
                } else if (plugged || (bucket > oldBucket && bucket > 0)) {
                    dismissLowBatteryWarning();
                } else if (mBatteryLevelTextView != null) {
                    //根据电量的情况判读是否显示电量过低等
                    showLowBatteryWarning();
                }
            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
                mScreenOffTime = SystemClock.elapsedRealtime();
            } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
                mScreenOffTime = -1;
            } else {
                Slog.w(TAG, "unknown intent: " + intent);
            }
        }
    };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值