summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/test-current.txt8
-rw-r--r--core/java/android/os/BatteryManagerInternal.java25
-rw-r--r--core/java/android/os/BatteryStatsManager.java73
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl11
-rw-r--r--services/core/java/com/android/server/BatteryService.java130
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java44
6 files changed, 253 insertions, 38 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index c8e54e46255c..1713e2d50b81 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1496,6 +1496,14 @@ package android.net {
package android.os {
+ public final class BatteryStatsManager {
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void resetBattery(boolean);
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void setBatteryLevel(int, boolean);
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void setChargerAcOnline(boolean, boolean);
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void suspendBatteryInput();
+ method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void unplugBattery(boolean);
+ }
+
public class Build {
method public static boolean is64BitAbi(String);
field public static final boolean IS_EMULATOR;
diff --git a/core/java/android/os/BatteryManagerInternal.java b/core/java/android/os/BatteryManagerInternal.java
index a86237dd271f..97ec5940ccb0 100644
--- a/core/java/android/os/BatteryManagerInternal.java
+++ b/core/java/android/os/BatteryManagerInternal.java
@@ -83,4 +83,29 @@ public abstract class BatteryManagerInternal {
* wait on the battery service lock.
*/
public abstract int getInvalidCharger();
+
+ /**
+ * Sets battery AC charger to enabled/disabled, and freezes the battery state.
+ */
+ public abstract void setChargerAcOnline(boolean online, boolean forceUpdate);
+
+ /**
+ * Sets battery level, and freezes the battery state.
+ */
+ public abstract void setBatteryLevel(int level, boolean forceUpdate);
+
+ /**
+ * Unplugs battery, and freezes the battery state.
+ */
+ public abstract void unplugBattery(boolean forceUpdate);
+
+ /**
+ * Unfreezes battery state, returning to current hardware values.
+ */
+ public abstract void resetBattery(boolean forceUpdate);
+
+ /**
+ * Suspend charging even if plugged in.
+ */
+ public abstract void suspendBatteryInput();
}
diff --git a/core/java/android/os/BatteryStatsManager.java b/core/java/android/os/BatteryStatsManager.java
index 1905d708d6d3..e47478abf439 100644
--- a/core/java/android/os/BatteryStatsManager.java
+++ b/core/java/android/os/BatteryStatsManager.java
@@ -23,6 +23,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.content.Context;
import android.net.NetworkStack;
import android.os.connectivity.CellularBatteryStats;
@@ -487,4 +488,74 @@ public final class BatteryStatsManager {
return isActive ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
: DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
}
-}
+
+ /**
+ * Sets battery AC charger to enabled/disabled, and freezes the battery state.
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void setChargerAcOnline(boolean online, boolean forceUpdate) {
+ try {
+ mBatteryStats.setChargerAcOnline(online, forceUpdate);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Sets battery level, and freezes the battery state.
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void setBatteryLevel(int level, boolean forceUpdate) {
+ try {
+ mBatteryStats.setBatteryLevel(level, forceUpdate);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Unplugs battery, and freezes the battery state.
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void unplugBattery(boolean forceUpdate) {
+ try {
+ mBatteryStats.unplugBattery(forceUpdate);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Unfreezes battery state, returning to current hardware values.
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void resetBattery(boolean forceUpdate) {
+ try {
+ mBatteryStats.resetBattery(forceUpdate);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Suspend charging even if plugged in.
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
+ public void suspendBatteryInput() {
+ try {
+ mBatteryStats.suspendBatteryInput();
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+} \ No newline at end of file
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index c1952c7d52cf..957e416986e0 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -166,4 +166,15 @@ interface IBatteryStats {
/** {@hide} */
boolean setChargingStateUpdateDelayMillis(int delay);
+
+ /** Exposed as a test API. */
+ void setChargerAcOnline(boolean online, boolean forceUpdate);
+ /** Exposed as a test API. */
+ void setBatteryLevel(int level, boolean forceUpdate);
+ /** Exposed as a test API. */
+ void unplugBattery(boolean forceUpdate);
+ /** Exposed as a test API. */
+ void resetBattery(boolean forceUpdate);
+ /** Exposed as a test API. */
+ void suspendBatteryInput();
}
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index bb4bbd5bc6d4..fbfde436a16f 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -918,19 +918,7 @@ public final class BatteryService extends SystemService {
int opts = parseOptions(shell);
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
- if (!mUpdatesStopped) {
- copy(mLastHealthInfo, mHealthInfo);
- }
- mHealthInfo.chargerAcOnline = false;
- mHealthInfo.chargerUsbOnline = false;
- mHealthInfo.chargerWirelessOnline = false;
- final long ident = Binder.clearCallingIdentity();
- try {
- mUpdatesStopped = true;
- processValuesFromShellLocked(pw, opts);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ unplugBattery(/* forceUpdate= */ (opts & OPTION_FORCE_UPDATE) != 0, pw);
} break;
case "set": {
int opts = parseOptions(shell);
@@ -990,7 +978,8 @@ public final class BatteryService extends SystemService {
final long ident = Binder.clearCallingIdentity();
try {
mUpdatesStopped = true;
- processValuesFromShellLocked(pw, opts);
+ processValuesLocked(
+ /* forceUpdate= */ (opts & OPTION_FORCE_UPDATE) != 0, pw);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -1004,30 +993,12 @@ public final class BatteryService extends SystemService {
int opts = parseOptions(shell);
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
- final long ident = Binder.clearCallingIdentity();
- try {
- if (mUpdatesStopped) {
- mUpdatesStopped = false;
- copy(mHealthInfo, mLastHealthInfo);
- processValuesFromShellLocked(pw, opts);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- if (mBatteryInputSuspended) {
- PowerProperties.battery_input_suspended(false);
- mBatteryInputSuspended = false;
- }
+ resetBattery(/* forceUpdate= */ (opts & OPTION_FORCE_UPDATE) != 0, pw);
} break;
case "suspend_input": {
- if (!Build.IS_DEBUGGABLE) {
- throw new SecurityException(
- "battery suspend_input is only supported on debuggable builds");
- }
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
- PowerProperties.battery_input_suspended(true);
- mBatteryInputSuspended = true;
+ suspendBatteryInput();
} break;
default:
return shell.handleDefaultCommands(cmd);
@@ -1035,9 +1006,59 @@ public final class BatteryService extends SystemService {
return 0;
}
- private void processValuesFromShellLocked(PrintWriter pw, int opts) {
- processValuesLocked((opts & OPTION_FORCE_UPDATE) != 0);
- if ((opts & OPTION_FORCE_UPDATE) != 0) {
+ private void setChargerAcOnline(boolean online, boolean forceUpdate) {
+ if (!mUpdatesStopped) {
+ copy(mLastHealthInfo, mHealthInfo);
+ }
+ mHealthInfo.chargerAcOnline = online;
+ mUpdatesStopped = true;
+ Binder.withCleanCallingIdentity(() -> processValuesLocked(forceUpdate));
+ }
+
+ private void setBatteryLevel(int level, boolean forceUpdate) {
+ if (!mUpdatesStopped) {
+ copy(mLastHealthInfo, mHealthInfo);
+ }
+ mHealthInfo.batteryLevel = level;
+ mUpdatesStopped = true;
+ Binder.withCleanCallingIdentity(() -> processValuesLocked(forceUpdate));
+ }
+
+ private void unplugBattery(boolean forceUpdate, PrintWriter pw) {
+ if (!mUpdatesStopped) {
+ copy(mLastHealthInfo, mHealthInfo);
+ }
+ mHealthInfo.chargerAcOnline = false;
+ mHealthInfo.chargerUsbOnline = false;
+ mHealthInfo.chargerWirelessOnline = false;
+ mUpdatesStopped = true;
+ Binder.withCleanCallingIdentity(() -> processValuesLocked(forceUpdate, pw));
+ }
+
+ private void resetBattery(boolean forceUpdate, @Nullable PrintWriter pw) {
+ if (mUpdatesStopped) {
+ mUpdatesStopped = false;
+ copy(mHealthInfo, mLastHealthInfo);
+ Binder.withCleanCallingIdentity(() -> processValuesLocked(forceUpdate, pw));
+ }
+ if (mBatteryInputSuspended) {
+ PowerProperties.battery_input_suspended(false);
+ mBatteryInputSuspended = false;
+ }
+ }
+
+ private void suspendBatteryInput() {
+ if (!Build.IS_DEBUGGABLE) {
+ throw new SecurityException(
+ "battery suspend_input is only supported on debuggable builds");
+ }
+ PowerProperties.battery_input_suspended(true);
+ mBatteryInputSuspended = true;
+ }
+
+ private void processValuesLocked(boolean forceUpdate, @Nullable PrintWriter pw) {
+ processValuesLocked(forceUpdate);
+ if (pw != null && forceUpdate) {
pw.println(mSequence);
}
}
@@ -1363,6 +1384,41 @@ public final class BatteryService extends SystemService {
return mInvalidCharger;
}
}
+
+ @Override
+ public void setChargerAcOnline(boolean online, boolean forceUpdate) {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, /* message= */ null);
+ BatteryService.this.setChargerAcOnline(online, forceUpdate);
+ }
+
+ @Override
+ public void setBatteryLevel(int level, boolean forceUpdate) {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, /* message= */ null);
+ BatteryService.this.setBatteryLevel(level, forceUpdate);
+ }
+
+ @Override
+ public void unplugBattery(boolean forceUpdate) {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, /* message= */ null);
+ BatteryService.this.unplugBattery(forceUpdate, /* printWriter= */ null);
+ }
+
+ @Override
+ public void resetBattery(boolean forceUpdate) {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, /* message= */ null);
+ BatteryService.this.resetBattery(forceUpdate, /* printWriter= */ null);
+ }
+
+ @Override
+ public void suspendBatteryInput() {
+ getContext().enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, /* message= */ null);
+ BatteryService.this.suspendBatteryInput();
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index dbfa7f34c6f9..6b9fc0718879 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -32,6 +32,7 @@ import android.net.ConnectivityManager;
import android.net.INetworkManagementEventObserver;
import android.net.Network;
import android.net.NetworkCapabilities;
+import android.os.BatteryManagerInternal;
import android.os.BatteryStats;
import android.os.BatteryStatsInternal;
import android.os.BatteryUsageStats;
@@ -184,6 +185,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
};
+ private BatteryManagerInternal mBatteryManagerInternal;
+
private void populatePowerEntityMaps() {
PowerEntity[] entities = mPowerStatsInternal.getPowerEntityInfo();
if (entities == null) {
@@ -370,6 +373,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
Slog.e(TAG, "Could not register PowerStatsInternal");
}
}
+ mBatteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class);
Watchdog.getInstance().addMonitor(this);
@@ -2715,4 +2719,44 @@ public final class BatteryStatsService extends IBatteryStats.Stub
});
}
}
+
+ /**
+ * Sets battery AC charger to enabled/disabled, and freezes the battery state.
+ */
+ @Override
+ public void setChargerAcOnline(boolean online, boolean forceUpdate) {
+ mBatteryManagerInternal.setChargerAcOnline(online, forceUpdate);
+ }
+
+ /**
+ * Sets battery level, and freezes the battery state.
+ */
+ @Override
+ public void setBatteryLevel(int level, boolean forceUpdate) {
+ mBatteryManagerInternal.setBatteryLevel(level, forceUpdate);
+ }
+
+ /**
+ * Unplugs battery, and freezes the battery state.
+ */
+ @Override
+ public void unplugBattery(boolean forceUpdate) {
+ mBatteryManagerInternal.unplugBattery(forceUpdate);
+ }
+
+ /**
+ * Unfreezes battery state, returning to current hardware values.
+ */
+ @Override
+ public void resetBattery(boolean forceUpdate) {
+ mBatteryManagerInternal.resetBattery(forceUpdate);
+ }
+
+ /**
+ * Suspend charging even if plugged in.
+ */
+ @Override
+ public void suspendBatteryInput() {
+ mBatteryManagerInternal.suspendBatteryInput();
+ }
}