Android battery (III): Android battery system

Source: Internet
Author: User

Keywords: Android battery system architecture uevent Power_Supply driver

Platform information:

Kernel: linux2.6/linux3.0
System: Android/android4.0
Platform: s5pv310 (samsungexynos4210) and Samsung exynos4412

Author: xubin341719 (You are welcome to reprint it. Please note the author)

Correct the mistakes and learn and make progress together !!

Android battery (I): Basic Principles of Lithium Battery

Android battery (2): Charging Process for Android shutdown and display of charging Screen

Android battery (III): Android battery system

Android battery (4): Battery meter (max17040) Driver Analysis

Android battery (5): Analysis of the battery charging IC (pm2301) Driver

I. Battery System Structure

There are three main battery usage methods in Android: AC, USB, battery, and so on. At the application level, the battery state display function is usually included. Therefore, from the software aspects of the Android system (including drivers and user space content), you need to obtain the battery status to a certain extent. The battery system is mainly responsible for battery information statistics and display. The architecture of the battery system is as follows:

From the bottom up, the android battery system is divided into the following parts:

1. Driver:

The battery driver of a specific hardware platform uses the Linux power supply driver to provide information to the user space. The battery driver must provide interfaces to the user space through the Sys File System. The path of the Sys File System is specified by the upper-Layer Program. The file system path used by the Linux Standard power supply driver is/sys/class/Power_Supply. Each subdirectory represents the name of an energy supply device.

The header file of the power supply driver is defined in include/Linux/power_supply.h. The functions for registering and deregistering the driver are as follows:

Int power_supply_register (struct device * parent, struct Power_Supply * Psy); void power_supply_unregister (struct Power_Supply * Psy); struct Power_Supply {const char * Name; /* device name */Enum power_supply_type type;/* type */Enum power_supply_property * properties;/* Property pointer */size_t num_properties; /* Number of attributes */Char ** supplied_to; size_t num_supplicants; int (* get_property) (struct Power_Supply * Psy,/* Get attribute */Enum power_supply_property PSP, union power_supply_propval * val); void (* external_power_changed) (struct Power_Supply * Psy );/*...... partial content omitted */};

Driver in Linux: Power_Supply

2. Local Code-JNI

Code path: Frameworks/base/services/JNI/com_android_server_batteryservice.cpp. This class calls the Sys File System to access the driver and also provides JNI interfaces.

The method list provided by this file is as follows:

static JNINativeMethod sMethods[] = { {"native_update", "()V", (void*)android_server_BatteryService_update}, };  

After determining a device based on the device type, you need more information to obtain relevant properties of each device. For example, if it is an AC or USB device, you only need to obtain whether they are online. If it is an electric pool device, you need more information, such as status ), health, capacity, and voltage.

The Linux driver maintains a group of sysfs files that store battery information. The software can be used to obtain power status:

# Define ac_online_path "/sys/class/Power_Supply/AC/online" AC power connection status # define usb_online_path "/sys/class/Power_Supply/USB/online" USB power connection status # define battery_status_path "/sys/class/Power_Supply/battery/status" charging status # define battery "/sys/class/Power_Supply/battery/Health" batterstate # define battery_present_path "/Power_Supply/battery/present "Usage Status # define battery_capacity_path"/sys/clas S/Power_Supply/battery/capacity "batterlevel # define networking"/sys/class/Power_Supply/battery/batt_vol "battery voltage # define networking"/sys/class/Power_Supply/battery/ batt_temp "battery temperature # define battery_policy_path"/sys/class/Power_Supply/battery/technology "battery technology when the battery status changes, the driver updates these files. Transfer information to Java

3. Java code

Code path:

Frameworks/base/services/Java/COM/Android/Server/batteryservice. Java

Frameworks/base/CORE/Java/Android/OS/: Android. OS: Battery-related parts in the package

Frameworks/base/CORE/Java/COM/Android/Internal/OS/: Internal batteryservice related to battery. java implements COM. android. the batteryservice class in the server package. Batterymanager. Java defines some constants that can be used by the Java application layer.

The default content of the battery system above the driver layer is in the Android system. In the porting process, there is basically no need to change. Only the battery driver is needed for the battery system. The battery driver uses the Linux Standard power supply driver and the upper-layer interface is the Sys File System, which is mainly used to read files in the SYS file system to obtain battery-related information. Contact the components of the entire system:

Batteryservice is a battery and charging service. It monitors uevent, reads status in sysfs, and broadcasts intent. action_battery_changed.

(1) mueventobserver

Batteryservice implements a uevenobserver mueventobserver. Uevent is a mechanism used by the Linux kernel to actively report events to the user space. For Java programs, it only implements the virtual function onuevent of ueventobserver and then registers it.

Batteryservice only pays attention to the Power_Supply event, so register in the constructor:

(2), update ()

Update reads the sysfs file to obtain battery information synchronously, updates the batteryservice member variables based on the read status, and broadcasts an intent to notify other components that focus on the Power status.

When the kernel has Power_Supply event reporting, the mueventobserver calls the update () function and update calls native_update to read the relevant status from sysfs (com_android_server_batteryservice.cpp ):

(3) sysfs

The Linux driver maintains a group of sysfs files for saving battery information.

Power Supply Status:

Ii. uevent

Uevent is a way for the kernel to notify android of status changes, such as USB cable insertion, unplugging, and battery power change. In essence, the kernel sends a string (through socket). The application layer (Android) receives and interprets the string to obtain the relevant information. As shown in, if there is any information change, uevent is triggered and the corresponding number is updated.

Batteryservice and related components in Android


1. androiduevent Architecture

Many Android events use uevent and kernel for asynchronous communication. Among them, the class ueventobserver is the core. The abstract class that the ueventobserver receives the uevent information of the kernel.

(1) server-Layer Code
Battery Server:
Frameworks/frameworks/base/services/Java/COM/Android/Server/systemserver. Java
Frameworks/frameworks/base/services/Java/COM/Android/Server/batteryservice. Java

(2) Java-Layer Code
Frameworks/base/CORE/Java/Android/OS/ueventobserver. Java
(3) JNI Layer Code
Frameworks/base/CORE/JNI/android_ OS _ueventobserver.cpp
(4) underlying code
Hardware/libhardware_legacy/uevent. c

Socket (pf_netlink, sock_dgram, netlink_kobject_uevent) for reading and writing kernel );
2. Use of ueventobserver

The class ueventobserver provides three interfaces for the subclass to call:
(1) onuevent (uevent event): The subclass must override this onuevent to process uevent.
(2) startobserving (stringmatch): To start a process, you must provide a string parameter.
(3) stopobserving (): Stop the process.
Example: // In batteryservice. Java

 mUEventObserver.startObserving("SUBSYSTEM=power_supply");         private UEventObserver mUEventObserver = new UEventObserver() {         @Override               public void onUEvent(UEventObserver.UEvent event) {                update();               }         };

The Update () method is constantly called in uevent thread to update battery information.

3. vold Server Analysis
(1) In System/vold/netlinkmanager. cpp:

 if ((mSock = socket(PF_NETLINK,SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) {               SLOGE("Unable to create uevent socket: %s", strerror(errno));               return -1;       }       if (setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) {               SLOGE("Unable to set uevent socket options: %s", strerror(errno));               return -1;       }       if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {               SLOGE("Unable to bind uevent socket: %s", strerror(errno));               return -1;       }

(2) then process it in netlinkhandler: onevent of system/vold/netlinkhandler. cpp.

             void NetlinkHandler::onEvent(NetlinkEvent *evt) {                      VolumeManager *vm = VolumeManager::Instance();                     const char *subsys = evt->getSubsystem();                     if (!subsys) {                           SLOGW("No subsystem found in netlink event");                           return;                     }                     if (!strcmp(subsys, "block")) {                           vm->handleBlockEvent(evt);                     } else if (!strcmp(subsys, "switch")) {                           vm->handleSwitchEvent(evt);                     } else if (!strcmp(subsys, "battery")) {                     } else if (!strcmp(subsys, "power_supply")) {                     }             }

(3) listen in system/CORE/libsysutils/src/netlinklistener. cpp.
4. batteryserver Analysis

Java code:Frameworks/frameworks/base/services/Java/COM/Android/Server/batteryservice. Java
JNI code:Frameworks/base/services/JNI/com_android_server_batteryservice.cpp

(1) batteryservice runs in system_process and is started during system initialization.,

In batteryservice. Java:

        Log.i(TAG, “Starting Battery Service.”);        BatteryService battery = new BatteryService(context);        ServiceManager.addService(“battery”, battery);

(2) Data Source
Batteryservice reads data through JNI (com_android_server_batteryservice.cpp.
Batteryservice not only registers functions but also variables through JNI. As follows:Batteryservice runs in system_process and starts during system initialization.In batteryservice. Java:

// ############## In batteryservice. variables declared in Java ################ private Boolean maconline; private Boolean musbonline; private int mbatterystatus; private int mbatteryhealth; private Boolean mbatterypresent; private int mbatterylevel; private int mbatteryvoltage; private int mbatterytemperature; private string mbatterytechnology; // In batteryservice. variables declared in Java are commonly used in com_android_server_batteryservice.cpp, that is In om_android_server_batteryservice.cpp, the variable declared in batteryservice. Java is also operated. Gfieldids. maconline = env-> getfieldid (clazz, "maconline", "Z"); gfieldids. musbonline = env-> getfieldid (clazz, "musbonline", "Z"); gfieldids. mbatterystatus = env-> getfieldid (clazz, "mbatterystatus", "I"); gfieldids. mbatteryhealth = env-> getfieldid (clazz, "mbatteryhealth", "I"); gfieldids. mbatterypresent = env-> getfieldid (clazz, "mbatterypresent", "Z"); gfieldids. mbatterylevel = env-> getfieldid (claz Z, "mbatterylevel", "I"); gfieldids. mbatterytechnology = env-> getfieldid (clazz, "mbatterytechnology", ljava/lang/string; "); gfieldids. mbatteryvoltage = env-> getfieldid (clazz, "mbatteryvoltage", "I"); gfieldids. mbatterytemperature = env-> getfieldid (clazz, "mbatterytemperature", "I"); // The values of the preceding variables, which are read from the following files, A file stores a value. # Define ac_online_path "/sys/class/Power_Supply/AC/online" # define usb_online_path "/sys/class/Power_Supply/USB/online" # define limit "/sys/class/Power_Supply /battery/status # define criteria "/sys/class/Power_Supply/battery/Health" # define battery_present_path "/sys/class/Power_Supply/battery/present" # define criteria "/ sys/class/Power_Supply/battery/capacity "# define tuning"/sys/class/Power_Supply/battery/batt_vol "# define tuning"/sys/class/Power_Supply/battery/batt_temp" # define battery_policy_path "/sys/class/Power_Supply/battery/technology"

(3) Data Transmission
Batteryservice actively transmits data to applications of interest, and all battery information data is transmitted through intent. In batteryservice. Java, the Code is as follows:

        Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);        intent.putExtra(“status”, mBatteryStatus);        intent.putExtra(“health”, mBatteryHealth);        intent.putExtra(“present”, mBatteryPresent);        intent.putExtra(“level”, mBatteryLevel);        intent.putExtra(“scale”, BATTERY_SCALE);        intent.putExtra(“icon-small”, icon);        intent.putExtra(“plugged”, mPlugType);        intent.putExtra(“voltage”, mBatteryVoltage);        intent.putExtra(“temperature”, mBatteryTemperature);        intent.putExtra(“technology”, mBatteryTechnology);        ActivityManagerNative.broadcastStickyIntent(intent, null);

(4) receive data

If the application wants to receive batteryservice batteryinformation, it needs to register a broadcastreceiver whose intent is intent. action_battery_changed.

The registration method is as follows:

        IntentFilter mIntentFilter = new IntentFilter();        mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);        registerReceiver(mIntentReceiver, mIntentFilter);        private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {            @Override            public void onReceive(Context context, Intent intent) {                // TODO Auto-generated method stub                String action = intent.getAction();                if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {                    int nVoltage = intent.getIntExtra(“voltage”, 0);                    if(nVoltage!=0){                        mVoltage.setText(“V: ” + nVoltage + “mV – Success…”);                    }                    else{                        mVoltage.setText(“V: ” + nVoltage + “mV – fail…”);                    }                }            }        };

(5) data update
Battery information changes constantly over time. Naturally, you need to consider how to update battery data in real time. When batteryservice is started, an onuevent thread is started through ueventobserver at the same time. Each process can have only one onuevent thread at most, even if the process has multiple ueventobserver instances. In a process, after the first call startobserving () method, the uevent thread starts. Once the uevent thread is started, it will not stop.

// In batteryservice. Java

        mUEventObserver.startObserving(“SUBSYSTEM=power_supply”);        private UEventObserver mUEventObserver = new UEventObserver() {            @Override            public void onUEvent(UEventObserver.UEvent event) {                update();            }        };

The Update () method is constantly called in uevent thread to update battery information.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.