powerd's PowerSupply class is responsible for reading information about power supplies (e.g. line power and batteries) from device directories under /sys/class/power_supply
in sysfs. The kernel documentation contains incomplete information about these directories.
powerd reads power supply information at startup and then polls periodically at 30-second intervals. The information is also refreshed immediately in response to several events:
power_supply
subsystemThe information is copied to PowerSupplyProperties protocol buffers that are included in PowerSupplyPoll
D-Bus signals.
“Line power” refers to chargers or other external power sources; it's sometimes also referred to as “AC” in the code. Information about line power sources is read by PowerSupply::ReadLinePowerDirectory
. The following sysfs nodes are particularly relevant:
type
describes the connected device's type. Notable values include:Unknown
- A sink-only device that can't supply power to the Chrome OS device.Mains
- A dedicated charger or direct power source. Most pre-USB-C chargers use this type. This type may also appear in conjunction with an online
value of 0
when nothing is connected to a dedicated charging port on a pre-USB-C device.USB
, USB_ACA
, USB_CDP
, USB_DCP
- A low-power USB BC1.2 power supply. USB-C ports with nothing connected to them may report a USB
type in conjunction with an online
value of 0
.USB_C
, USB_PD
- A USB Type-C power supply.USB_PD_DRP
- A dual-role USB Type-C device (i.e. one capable of either delivering or receiving power).BrickID
- An Apple legacy USB charger. May be either USB-A or USB-C.online
typically describes whether anything is connected to the port; a value of 1
indicates a connection. If type
is USB_PD_DRP
, an online
value of 0
indicates that a dual-role device is connected but that it is not currently delivering power to the Chrome OS device.status
describes the status of a bidirectional/dual-role port. The node is expected to be nonexistent or to contain an empty value for non-dual-role ports. If the node is present, a value of Charging
indicates that the port is delivering power to the Chrome OS device.voltage_max_design
and current_max
are used to compute the maximum power that can be delivered by the power supply.voltage_now
and current_now
are used to compute the instantaneous power.If multiple line power directories are found, powerd will report all of them. This typically happens in the case of Chrome OS devices with multiple USB Type-C ports.
Only one power source may deliver power at a given time; Chrome displays the active source at chrome://settings/power
. If multiple sources are available, the user may use this page to select which one to use. Chrome makes a SetPowerSource
D-Bus method call to powerd containing the ID of the desired source (taken from an earlier PowerSupplyProperties protobuf), and PowerSupply::SetPowerSource
writes 0
to the device‘s charge_control_limit_max
sysfs node. Chrome can also pass an empty ID to switch to battery power; powerd writes -1
to the active power source’s node in this case.
Battery information is read by PowerSupply::ReadBatteryDirectory
. The following sysfs nodes are relevant:
status
describes the battery‘s current status. The kernel documentation describes possible values. powerd does not distinguish between Charging
and Full
and instead uses the battery’s reported charge to determine if it is full.voltage_now
contains the instantaneous voltage.voltage_min_design
and voltage_max_design
are read to determine the nominal voltage.current_now
, charge_now
, and charge_full
are read on charge_battery
systems to get the battery's current and charge.power_now
, energy_now
, and energy_full
are read on energy_battery
systems to get the battery's current and charge.PowerSupply::UpdateBatteryPercentagesAndState
uses the above information to determine the battery status and charge that should be displayed by the UI. Many batteries charge more slowly as they approach a full charge, so the power_supply_full_factor
powerd pref is used to set the charge percentage at which powerd should report the battery as fully-charged. Similarly, powerd will automatically shut the system down before the battery has fully discharged, so the displayed percentage is also scaled based on the low_battery_shutdown_percent
pref.
Starting from M92 crrev/c/2984168, on start-up, powerd tries to read low_battery_shutdown_percent
and full_factor
from CrOS EC using EC_CMD_DISPLAY_SOC
. PowerSupply::UpdateBatteryPercentagesAndState
also reads the display SoC (state of charge) from CrOS EC using EC_CMD_DISPLAY_SOC
. If the command isn't available, the display SoC is computed by powerd using low_battery_shutdown_percent
and full_factor
read from the pref directories.
PowerSupply::UpdateBatteryTimeEstimates
attempts to estimate the time until the battery will be fully charged or until the system will shut down due to a low charge. To do this, PowerSupply
maintains a rolling average of samples of the battery‘s current. Sampling is temporarily deferred after events like system resume, but these estimates may still be noisy, particularly when the system’s workload is changing frequently.
The Battery Notifications document contains more information about how these estimates are computed and used.
If the multiple_batteries
pref is set, powerd will use PowerSupply::ReadMultipleBatteryDirectories
to read multiple battery power supply directories if present. Most statistics, including the charge and full charge, are just summed across all batteries. If any batteries are charging, the overall state is reported as charging. The UI doesn't currently differentiate between a single battery and multiple batteries; the main difference in the latter scenario is that the displayed charge percentage may change when a battery is connected or disconnected.