Skip to content

Commit d4cca21

Browse files
Vachounetnpjohnson
authored andcommitted
BatteryService: Add support for battery Moto Mods
* This relies on the prebuilt Moto Health service being included device side. Reference: I48803eeb72499fe8459805f6ef80ef5f868f431e Change-Id: I41a4d5fdeb5e1f2ad7838851ad0815cef7d72980
1 parent 3e9fa16 commit d4cca21

3 files changed

Lines changed: 147 additions & 4 deletions

File tree

core/java/android/os/BatteryManager.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,54 @@ public class BatteryManager {
164164
@SystemApi
165165
public static final String EXTRA_EVENT_TIMESTAMP = "android.os.extra.EVENT_TIMESTAMP";
166166

167+
/**
168+
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
169+
* Contains a value that forces Moto Mod battery level `mod_level`
170+
* to overwrite the interal battery level and act as the device's
171+
* sole battery. This isn't used by any Mods we have come across.
172+
* {@hide}
173+
*/
174+
public static final String EXTRA_MOD_FLAG = "mod_flag";
175+
176+
/**
177+
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
178+
* Contains battery percentage value for Moto Mod devices.
179+
* {@hide}
180+
*/
181+
public static final String EXTRA_MOD_LEVEL = "mod_level";
182+
183+
/**
184+
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
185+
* Contains Moto Mod power source type value.
186+
* {@hide}
187+
*/
188+
public static final String EXTRA_MOD_POWER_SOURCE = "mod_psrc";
189+
190+
/**
191+
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
192+
* Contains Moto Mod status (ready, charging, etc.) value.
193+
* {@hide}
194+
*/
195+
public static final String EXTRA_MOD_STATUS = "mod_status";
196+
197+
/**
198+
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
199+
* Contains Moto Mod type information (battery, audio, input).
200+
* {@hide}
201+
*/
202+
public static final String EXTRA_MOD_TYPE = "mod_type";
203+
204+
/**
205+
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
206+
* Contains Moto Mod connection indicator.
207+
* {@hide}
208+
*/
209+
public static final String EXTRA_PLUGGED_RAW = "plugged_raw";
210+
211+
public static final int BATTERY_PROPERTY_MOD_CHARGE_FULL = 100;
212+
public static final int BATTERY_PROPERTY_CHARGE_FULL = 101;
213+
public static final int BATTERY_PLUGGED_MOD = 8;
214+
167215
// values for "status" field in the ACTION_BATTERY_CHANGED Intent
168216
public static final int BATTERY_STATUS_UNKNOWN = Constants.BATTERY_STATUS_UNKNOWN;
169217
public static final int BATTERY_STATUS_CHARGING = Constants.BATTERY_STATUS_CHARGING;
@@ -191,7 +239,8 @@ public class BatteryManager {
191239

192240
/** @hide */
193241
public static final int BATTERY_PLUGGED_ANY =
194-
BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS;
242+
BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS |
243+
BATTERY_PLUGGED_MOD;
195244

196245
/**
197246
* Sent when the device's battery has started charging (or has reached full charge

services/core/Android.bp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ java_library_static {
129129
"android.hidl.manager-V1.2-java",
130130
"capture_state_listener-aidl-java",
131131
"dnsresolver_aidl_interface-java",
132+
"motorola.hardware.health-V1.0-java",
132133
"netd_aidl_interfaces-platform-java",
133134
"org.lineageos.platform.internal",
134135
"overlayable_policy_aidl-java",

services/core/java/com/android/server/BatteryService.java

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import android.os.ShellCallback;
5555
import android.os.ShellCommand;
5656
import android.os.SystemClock;
57+
import android.os.SystemProperties;
5758
import android.os.Trace;
5859
import android.os.UEventObserver;
5960
import android.os.UserHandle;
@@ -75,9 +76,11 @@
7576
import org.lineageos.internal.notification.LedValues;
7677
import org.lineageos.internal.notification.LineageBatteryLights;
7778

79+
import java.io.BufferedReader;
7880
import java.io.File;
7981
import java.io.FileDescriptor;
8082
import java.io.FileOutputStream;
83+
import java.io.FileReader;
8184
import java.io.IOException;
8285
import java.io.PrintWriter;
8386
import java.util.ArrayDeque;
@@ -88,6 +91,9 @@
8891
import java.util.Objects;
8992
import java.util.concurrent.atomic.AtomicReference;
9093

94+
import motorola.hardware.health.V1_0.BatteryProperties;
95+
import motorola.hardware.health.V1_0.IMotHealth;
96+
9197
/**
9298
* <p>BatteryService monitors the charging status, and charge level of the device
9399
* battery. When these values change this service broadcasts the new values
@@ -201,6 +207,16 @@ public final class BatteryService extends SystemService {
201207

202208
private LineageBatteryLights mLineageBatteryLights;
203209

210+
private static final int MOD_TYPE_EMERGENCY = 3;
211+
private static final int MOD_TYPE_SUPPLEMENTAL = 2;
212+
private BatteryProperties mBatteryModProps;
213+
private IMotHealth mMotHealthService = null;
214+
private int mLastModFlag;
215+
private int mLastModLevel;
216+
private int mLastModPowerSource;
217+
private int mLastModStatus;
218+
private int mLastModType;
219+
204220
public BatteryService(Context context) {
205221
super(context);
206222

@@ -238,6 +254,20 @@ public void onUEvent(UEvent event) {
238254
invalidChargerObserver.startObserving(
239255
"DEVPATH=/devices/virtual/switch/invalid_charger");
240256
}
257+
258+
mBatteryModProps = new BatteryProperties();
259+
mBatteryModProps.modLevel = -1;
260+
mBatteryModProps.modStatus = 1;
261+
mBatteryModProps.modFlag = 0;
262+
mBatteryModProps.modType = 0;
263+
mBatteryModProps.modPowerSource = 0;
264+
try {
265+
mMotHealthService = IMotHealth.getService();
266+
} catch (RemoteException e) {
267+
Slog.e(TAG, "health: cannot get service. (RemoteException)");
268+
} catch (NoSuchElementException e2) {
269+
Slog.e(TAG, "mothealth: cannot get service. (no supported health HAL service)");
270+
}
241271
}
242272

243273
@Override
@@ -357,6 +387,10 @@ private boolean isPoweredLocked(int plugTypeSet) {
357387
if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0 && mHealthInfo.chargerWirelessOnline) {
358388
return true;
359389
}
390+
if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_MOD) != 0 ||
391+
mPlugType == BatteryManager.BATTERY_PLUGGED_MOD || isModBatteryActive()) {
392+
return true;
393+
}
360394
return false;
361395
}
362396

@@ -449,6 +483,16 @@ private void update(android.hardware.health.V2_1.HealthInfo info) {
449483
if (!mUpdatesStopped) {
450484
mHealthInfo = info.legacy.legacy;
451485
mHealthInfo2p1 = info;
486+
if (mMotHealthService != null) {
487+
try {
488+
mBatteryModProps = mMotHealthService.getModBatteryProperties();
489+
if (mBatteryModProps.modFlag > 0) {
490+
mHealthInfo.batteryLevel = mBatteryModProps.batteryLevel;
491+
}
492+
} catch (RemoteException e) {
493+
Slog.e(TAG, "getModBatteryProperties fail!");
494+
}
495+
}
452496
// Process the new values.
453497
processValuesLocked(false);
454498
mLock.notifyAll(); // for any waiters on new info
@@ -491,6 +535,8 @@ private void processValuesLocked(boolean force) {
491535
mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
492536
} else if (mHealthInfo.chargerWirelessOnline) {
493537
mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
538+
} else if (supplementalOrEmergencyModOnline()) {
539+
mPlugType = BatteryManager.BATTERY_PLUGGED_MOD;
494540
} else {
495541
mPlugType = BATTERY_PLUGGED_NONE;
496542
}
@@ -505,7 +551,7 @@ private void processValuesLocked(boolean force) {
505551
// Let the battery stats keep track of the current level.
506552
try {
507553
mBatteryStats.setBatteryState(mHealthInfo.batteryStatus, mHealthInfo.batteryHealth,
508-
mPlugType, mHealthInfo.batteryLevel, mHealthInfo.batteryTemperature,
554+
maybeTranslatePlugType(mPlugType), mHealthInfo.batteryLevel, mHealthInfo.batteryTemperature,
509555
mHealthInfo.batteryVoltage, mHealthInfo.batteryChargeCounter,
510556
mHealthInfo.batteryFullCharge,
511557
mHealthInfo2p1.batteryChargeTimeToFullNowSeconds);
@@ -526,7 +572,12 @@ private void processValuesLocked(boolean force) {
526572
mHealthInfo.maxChargingCurrent != mLastMaxChargingCurrent ||
527573
mHealthInfo.maxChargingVoltage != mLastMaxChargingVoltage ||
528574
mHealthInfo.batteryChargeCounter != mLastChargeCounter ||
529-
mInvalidCharger != mLastInvalidCharger)) {
575+
mInvalidCharger != mLastInvalidCharger ||
576+
mBatteryModProps.modLevel != mLastModLevel ||
577+
mBatteryModProps.modStatus != mLastModStatus ||
578+
mBatteryModProps.modFlag != mLastModFlag ||
579+
mBatteryModProps.modType != mLastModType ||
580+
mBatteryModProps.modPowerSource != mLastModPowerSource)) {
530581

531582
if (mPlugType != mLastPlugType) {
532583
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -697,6 +748,12 @@ public void run() {
697748
mLastChargeCounter = mHealthInfo.batteryChargeCounter;
698749
mLastBatteryLevelCritical = mBatteryLevelCritical;
699750
mLastInvalidCharger = mInvalidCharger;
751+
mLastModLevel = mBatteryModProps.modLevel;
752+
mLastModStatus = mBatteryModProps.modStatus;
753+
mLastModFlag = mBatteryModProps.modFlag;
754+
mLastModType = mBatteryModProps.modType;
755+
mLastModPowerSource = mBatteryModProps.modPowerSource;
756+
700757
}
701758
}
702759

@@ -716,14 +773,20 @@ private void sendBatteryChangedIntentLocked() {
716773
intent.putExtra(BatteryManager.EXTRA_BATTERY_LOW, mSentLowBatteryBroadcast);
717774
intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
718775
intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
719-
intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
776+
intent.putExtra(BatteryManager.EXTRA_PLUGGED, maybeTranslatePlugType(mPlugType));
720777
intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mHealthInfo.batteryVoltage);
721778
intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mHealthInfo.batteryTemperature);
722779
intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mHealthInfo.batteryTechnology);
723780
intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger);
724781
intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mHealthInfo.maxChargingCurrent);
725782
intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mHealthInfo.maxChargingVoltage);
726783
intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mHealthInfo.batteryChargeCounter);
784+
intent.putExtra(BatteryManager.EXTRA_MOD_LEVEL, mBatteryModProps.modLevel);
785+
intent.putExtra(BatteryManager.EXTRA_MOD_STATUS, mBatteryModProps.modStatus);
786+
intent.putExtra(BatteryManager.EXTRA_MOD_FLAG, mBatteryModProps.modFlag);
787+
intent.putExtra(BatteryManager.EXTRA_PLUGGED_RAW, mPlugType);
788+
intent.putExtra(BatteryManager.EXTRA_MOD_TYPE, mBatteryModProps.modType);
789+
intent.putExtra(BatteryManager.EXTRA_MOD_POWER_SOURCE, mBatteryModProps.modPowerSource);
727790
if (DEBUG) {
728791
Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. scale:" + BATTERY_SCALE
729792
+ ", info:" + mHealthInfo.toString());
@@ -862,6 +925,36 @@ private int getIconLocked(int level) {
862925
}
863926
}
864927

928+
private int maybeTranslatePlugType(int plugType) {
929+
if (plugType != BatteryManager.BATTERY_PLUGGED_MOD) {
930+
return plugType;
931+
}
932+
if (this.mHealthInfo.batteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
933+
return 1;
934+
}
935+
return 0;
936+
}
937+
938+
private boolean supplementalOrEmergencyModOnline() {
939+
return mBatteryModProps.modLevel > 0 &&
940+
(mBatteryModProps.modType == MOD_TYPE_SUPPLEMENTAL ||
941+
mBatteryModProps.modType == MOD_TYPE_EMERGENCY);
942+
}
943+
944+
private boolean isModBatteryActive() {
945+
if (mBatteryModProps.modLevel <= 0 || mBatteryModProps.modType != MOD_TYPE_SUPPLEMENTAL) {
946+
return false;
947+
}
948+
String batteryMode = SystemProperties.get("sys.mod.batterymode");
949+
if ("0".equals(batteryMode)) {
950+
return true;
951+
}
952+
if (!"2".equals(batteryMode) && mHealthInfo.batteryLevel <= 80) {
953+
return true;
954+
}
955+
return false;
956+
}
957+
865958
class Shell extends ShellCommand {
866959
@Override
867960
public int onCommand(String cmd) {

0 commit comments

Comments
 (0)