Exposed some testAPIs in BatteryStatsManager

Added the following testsAPIs to replace the usage
of adb shell commands in tests:
* setChargerAcOnline
* setBatteryLevel
* unplugBattery
* resetBattery
* suspendBatteryInput

Test: atest MixedDeviceOwnerTest#testInstallUpdate using the adb
commands and the new testAPIs
Bug: 182260585

Change-Id: I48c2ad37f6240f4d7a3c437416fdcc0beeed6bd1
This commit is contained in:
kholoud mohamed
2021-03-09 14:15:15 +00:00
parent 8923c65435
commit ceac8bbb50
6 changed files with 253 additions and 38 deletions

View File

@@ -1495,6 +1495,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;

View File

@@ -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();
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}

View File

@@ -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();
}
}
/**

View File

@@ -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();
}
}