Android电池

Android电池

Android电池系列三之BatteryService

前置文章

  1. Android电池-Android电池概述
  2. Android电池-Android电池守护进程

前言

在上篇文章《Android电池-Android电池守护进程》中,我们学习了 Android 电池状态变化的传递框架,其中从 Native 层传送到 Framework 层时,Framework 层就是由 BatteryService 完成这一任务。

BatteryService概述

BatteryService 的定义如下:

public final class BatteryService extends SystemService {
    .....
}

这个类定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。

在笔者的文章《Android系统之System Server大纲》一文中,有详细介绍继承 SystemService 的 Service 的特点,因此,在 BatteryService 启动的时候,会回调方法 onStart()。

这里顺便粘贴一下 BatteryService 的启动代码,如果读者想了解更多 Android Service 的内容,可以阅读文章《Android系统之System Server大纲》。

private void startCoreServices() {
        // Tracks the battery level.  Requires LightService.
        mSystemServiceManager.startService(BatteryService.class);
}

这个方法定义在文件 frameworks/base/services/java/com/android/server/SystemServer.java 中。

BatteryService 的 onStart() 方法定义如下:

public void onStart() {
    //首先注册Battery Listener 到 BatteryPropertiesRegistrar
    IBinder b = ServiceManager.getService("batteryproperties");
    final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
            IBatteryPropertiesRegistrar.Stub.asInterface(b);
    try {
        batteryPropertiesRegistrar.registerListener(new BatteryListener());
    } catch (RemoteException e) {
        // Should never happen.
    }
    //添加Service到ServiceManager
    mBinderService = new BinderService();
    publishBinderService("battery", mBinderService);
    publishLocalService(BatteryManagerInternal.class, new LocalService());
    }

这个方法定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。

在这个方法中,我们重点关注注册 BatteryProperties 监听器。在文章《Android电池-Android电池守护进程》中,我们已经了解 BatteryPropertiesRegistrar 这个 Service 的创建过程和作用。BatteryPropertiesRegistrar 的 Server 端运行在 healthd 进程中,实现上层注册 BatteryProperties 监听器,从而实现 Battery 状态由 Native 上报到 Framework 或者 App 层。

在文章《Android电池-Android电池守护进程》中,我们已经了解,如果电池状态有任何变化,会执行如下代码:

void healthd_mode_android_battery_update(
    struct android::BatteryProperties *props) {
    if (gBatteryPropertiesRegistrar != NULL)
        //通知 framework 或 app
        gBatteryPropertiesRegistrar->notifyListeners(*props);
    return;
}

这个函数定义在文件 system/core/healthd/healthd_mode_android.cpp 中。

notifyListeners(*props) 实际上就会调用到 BatteryService 中注册的 BatteryListener 的 batteryPropertiesChanged() 方法。BatteryListener 的定义如下:

private final class BatteryListener extends IBatteryPropertiesListener.Stub {
    @Override public void batteryPropertiesChanged(BatteryProperties props) {
        final long identity = Binder.clearCallingIdentity();
        try {
            BatteryService.this.update(props);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
   }
}

这个方法定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。

当然,在方法 batteryPropertiesChanged() 中,看不到什么有用的信息,因为这里直接调用了 BatteryService.this.update() 把任务转移到 BatterService。

BatteryService接收电池状态

在上面章节 BatteryService概述 中,我们已经知道 BatteryService 是如何地接收 healthd 上报的电池的状态变化。下面我们接着看 BatteryService 接收到电池变化数据后,如果处理这些变化,BatteryService 的 update() 方法定义如下:

private void update(BatteryProperties props) {
    synchronized (mLock) {
        .....
        if (!mUpdatesStopped) {
            processValuesLocked(false);
        .....
    }
}

这个方法定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。

这里,有一个 mUpdatesStopped 的条件判断,也就是说,可以打开或关闭电池状态的更新,可以通过命令来实现这个功能,详情可查阅 onStart() 方法中的 BinderService。我们继续往下跟踪 processValuesLocked() 做了什么事情。

private void processValuesLocked(boolean force) {
    //这里从上报的的BatteryProperties中取出数据赋值到 BatteryService中的变量
    //包括电量,充电状态,电压,温度等等,这里省略其它的赋值代码
    mBatteryLevelCritical = (mBatteryProps.batteryLevel <= mCriticalBatteryLevel);
    if (mBatteryProps.chargerAcOnline) {
        mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
    } else if (mBatteryProps.chargerUsbOnline) {
        mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
    .....
    //更新电池状态变化到 BatterStatsService,下篇文章我们再阐述它
    mBatteryStats.setBatteryState(mBatteryProps.batteryStatus,...)
    //处理电量过低处理关机事宜
    shutdownIfNoPowerLocked();
    //处理电池温度异常关机事宜
    shutdownIfOverTempLocked();
    //插上电源广播Intent.ACTION_POWER_CONNECTED
    if (mPlugType != 0 && mLastPlugType == 0) {
        Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
        .....
    }else if (mPlugType == 0 && mLastPlugType != 0) {
        //断开电源广播Intent.ACTION_POWER_DISCONNECTED
        Intent statusIntent = new Intent(Intent.ACTION_POWER_DISCONNECTED);
        .....
    }
    if (shouldSendBatteryLowLocked()) {
        //低电量广播Intent.ACTION_BATTERY_LOW
        Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);
    } else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= mLowBatteryCloseWarningLevel) {
        //取消低电量广播Intent.ACTION_BATTERY_OKAY
        Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);
    }
    //电池状态变化广播Intent.ACTION_BATTERY_CHANGED
    sendIntentLocked();
}

这个方法定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。

在这个方法中,所完成的任务都在源码的注释中写明了,我们再详细看看 sendIntentLocked() 这个方法,具体会传送那些数据到相应的广播接收器

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_STATUS_SMARTBOOK, mBatteryProps.batteryStatus_smb);
    intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryProps.batteryHealth);
    intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryProps.batteryPresent);
    intent.putExtra(BatteryManager.EXTRA_PRESENT_SMARTBOOK, mBatteryProps.batteryPresent_smb);
    intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryProps.batteryLevel);
    intent.putExtra(BatteryManager.EXTRA_LEVEL_SMARTBOOK, mBatteryProps.batteryLevel_smb);
    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);
    intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mBatteryProps.maxChargingCurrent);
    intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mBatteryProps.maxChargingVoltage);
    intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mBatteryProps.batteryChargeCounter);
    mHandler.post(new Runnable() {
        @Override
        public void run() {
            ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL);
        }
    });

这个方法定义在文件 frameworks/base/services/core/java/com/android/server/BatteryService.java 中。

在这个方法中,当电池状态变化后,会发送广播 Intent.ACTION_BATTERY_CHANGED 通知 App 等,并在 Intent 中传送电池状态的数据,状态,电量,电压等等。

总结

BatteryService 的功能到这里就介绍完毕了,BatteryService 完成的功能还是比较简单。

  1. 第一接收 Native 层上报的电池数据
  2. 第二通知 BatteryStatsService 数据的变化
  3. 广播电池数据的变化

另外,还有如下两个功能,本文不再阐述他们的过程。

  1. 电池 led 的处理(充电提示灯常亮,低电量闪烁等)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值