Add feature flag for PowerMonitor API
Bug: 273308894 Test: atest FrameworksServicesTests:PowerStatsServiceTest Change-Id: I1b027c2f24cb6aeeba7e790fc279fc4d69d33ef8
This commit is contained in:
@@ -29,6 +29,7 @@ import android.hardware.power.stats.StateResidencyResult;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerExecutor;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.IPowerStatsService;
|
||||
@@ -38,6 +39,8 @@ import android.os.PowerMonitorReadings;
|
||||
import android.os.ResultReceiver;
|
||||
import android.os.UserHandle;
|
||||
import android.power.PowerStatsInternal;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.DeviceConfigInterface;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -56,6 +59,7 @@ import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* This class provides a system service that estimates system power usage
|
||||
@@ -76,8 +80,12 @@ public class PowerStatsService extends SystemService {
|
||||
private static final String RESIDENCY_CACHE_FILENAME = "residencyCache";
|
||||
private static final long MAX_POWER_MONITOR_AGE_MILLIS = 30_000;
|
||||
|
||||
static final String KEY_POWER_MONITOR_API_ENABLED = "power_monitor_api_enabled";
|
||||
|
||||
private final Injector mInjector;
|
||||
private final Clock mClock;
|
||||
private final DeviceConfigInterface mDeviceConfig;
|
||||
private final DeviceConfigListener mDeviceConfigListener = new DeviceConfigListener();
|
||||
private File mDataStoragePath;
|
||||
|
||||
private Context mContext;
|
||||
@@ -177,6 +185,10 @@ public class PowerStatsService extends SystemService {
|
||||
PowerStatsInternal powerStatsInternal) {
|
||||
return new StatsPullAtomCallbackImpl(context, powerStatsInternal);
|
||||
}
|
||||
|
||||
DeviceConfigInterface getDeviceConfig() {
|
||||
return DeviceConfigInterface.REAL;
|
||||
}
|
||||
}
|
||||
|
||||
private final IBinder mService = new IPowerStatsService.Stub() {
|
||||
@@ -223,6 +235,20 @@ public class PowerStatsService extends SystemService {
|
||||
}
|
||||
};
|
||||
|
||||
private class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener {
|
||||
public Executor mExecutor = new HandlerExecutor(getHandler());
|
||||
|
||||
void startListening() {
|
||||
mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BATTERY_STATS,
|
||||
mExecutor, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPropertiesChanged(DeviceConfig.Properties properties) {
|
||||
refreshFlags();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBootPhase(int phase) {
|
||||
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
|
||||
@@ -243,6 +269,8 @@ public class PowerStatsService extends SystemService {
|
||||
|
||||
private void onSystemServicesReady() {
|
||||
mPullAtomCallback = mInjector.createStatsPullerImpl(mContext, mPowerStatsInternal);
|
||||
mDeviceConfigListener.startListening();
|
||||
refreshFlags();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -330,6 +358,12 @@ public class PowerStatsService extends SystemService {
|
||||
mContext = context;
|
||||
mInjector = injector;
|
||||
mClock = injector.getClock();
|
||||
mDeviceConfig = injector.getDeviceConfig();
|
||||
}
|
||||
|
||||
void refreshFlags() {
|
||||
setPowerMonitorApiEnabled(mDeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BATTERY_STATS,
|
||||
KEY_POWER_MONITOR_API_ENABLED, true));
|
||||
}
|
||||
|
||||
private final class LocalService extends PowerStatsInternal {
|
||||
@@ -466,9 +500,18 @@ public class PowerStatsService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean mPowerMonitorApiEnabled = true;
|
||||
private volatile PowerMonitor[] mPowerMonitors;
|
||||
private volatile PowerMonitorState[] mPowerMonitorStates;
|
||||
|
||||
private void setPowerMonitorApiEnabled(boolean powerMonitorApiEnabled) {
|
||||
if (powerMonitorApiEnabled != mPowerMonitorApiEnabled) {
|
||||
mPowerMonitorApiEnabled = powerMonitorApiEnabled;
|
||||
mPowerMonitors = null;
|
||||
mPowerMonitorStates = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ensurePowerMonitors() {
|
||||
if (mPowerMonitors != null) {
|
||||
return;
|
||||
@@ -479,6 +522,12 @@ public class PowerStatsService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mPowerMonitorApiEnabled) {
|
||||
mPowerMonitors = new PowerMonitor[0];
|
||||
mPowerMonitorStates = new PowerMonitorState[0];
|
||||
return;
|
||||
}
|
||||
|
||||
List<PowerMonitor> monitors = new ArrayList<>();
|
||||
List<PowerMonitorState> states = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ import android.os.IPowerStatsService;
|
||||
import android.os.Looper;
|
||||
import android.os.PowerMonitor;
|
||||
import android.os.ResultReceiver;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.DeviceConfigInterface;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
@@ -53,6 +55,7 @@ import com.android.server.powerstats.nano.PowerStatsServiceResidencyProto;
|
||||
import com.android.server.powerstats.nano.StateProto;
|
||||
import com.android.server.powerstats.nano.StateResidencyProto;
|
||||
import com.android.server.powerstats.nano.StateResidencyResultProto;
|
||||
import com.android.server.testutils.FakeDeviceConfigInterface;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -105,6 +108,7 @@ public class PowerStatsServiceTest {
|
||||
private BatteryTrigger mBatteryTrigger;
|
||||
private PowerStatsLogger mPowerStatsLogger;
|
||||
private MockClock mMockClock = new MockClock();
|
||||
private DeviceConfigInterface mMockDeviceConfig = new FakeDeviceConfigInterface();
|
||||
|
||||
private class MockClock extends Clock {
|
||||
public long realtime;
|
||||
@@ -197,6 +201,10 @@ public class PowerStatsServiceTest {
|
||||
false /* trigger enabled */);
|
||||
return mTimerTrigger;
|
||||
}
|
||||
|
||||
DeviceConfigInterface getDeviceConfig() {
|
||||
return mMockDeviceConfig;
|
||||
}
|
||||
};
|
||||
|
||||
public static final class TestPowerStatsHALWrapper implements IPowerStatsHALWrapper {
|
||||
@@ -1073,6 +1081,7 @@ public class PowerStatsServiceTest {
|
||||
}
|
||||
|
||||
private static class GetPowerMonitorsResult extends ResultReceiver {
|
||||
public int resultCode;
|
||||
public long[] energyUws;
|
||||
public long[] timestamps;
|
||||
|
||||
@@ -1082,8 +1091,11 @@ public class PowerStatsServiceTest {
|
||||
|
||||
@Override
|
||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||
energyUws = resultData.getLongArray(IPowerStatsService.KEY_ENERGY);
|
||||
timestamps = resultData.getLongArray(IPowerStatsService.KEY_TIMESTAMPS);
|
||||
this.resultCode = resultCode;
|
||||
if (resultData != null) {
|
||||
energyUws = resultData.getLongArray(IPowerStatsService.KEY_ENERGY);
|
||||
timestamps = resultData.getLongArray(IPowerStatsService.KEY_TIMESTAMPS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1151,4 +1163,30 @@ public class PowerStatsServiceTest {
|
||||
assertThat(result.energyUws).isEqualTo(new long[]{300, 400});
|
||||
assertThat(result.timestamps).isEqualTo(new long[]{600_301, 600_401});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void featureFlag() {
|
||||
mMockDeviceConfig.setProperty(DeviceConfig.NAMESPACE_BATTERY_STATS,
|
||||
PowerStatsService.KEY_POWER_MONITOR_API_ENABLED, "false", false);
|
||||
|
||||
mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
|
||||
|
||||
GetSupportedPowerMonitorsResult supportedPowerMonitorsResult =
|
||||
new GetSupportedPowerMonitorsResult();
|
||||
mService.getSupportedPowerMonitorsImpl(supportedPowerMonitorsResult);
|
||||
assertThat(supportedPowerMonitorsResult.powerMonitors).isNotNull();
|
||||
assertThat(supportedPowerMonitorsResult.powerMonitors).isEmpty();
|
||||
|
||||
GetPowerMonitorsResult getPowerMonitorsResult = new GetPowerMonitorsResult();
|
||||
mService.getPowerMonitorReadingsImpl(new int[]{0}, getPowerMonitorsResult);
|
||||
assertThat(getPowerMonitorsResult.resultCode).isEqualTo(
|
||||
IPowerStatsService.RESULT_UNSUPPORTED_POWER_MONITOR);
|
||||
|
||||
mMockDeviceConfig.setProperty(DeviceConfig.NAMESPACE_BATTERY_STATS,
|
||||
PowerStatsService.KEY_POWER_MONITOR_API_ENABLED, "true", false);
|
||||
supportedPowerMonitorsResult = new GetSupportedPowerMonitorsResult();
|
||||
mService.getSupportedPowerMonitorsImpl(supportedPowerMonitorsResult);
|
||||
assertThat(Arrays.stream(supportedPowerMonitorsResult.powerMonitors)
|
||||
.map(pm -> pm.name).toList()).contains("energyconsumer0");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user