blob: a946534f4ecddfb99f1d68f03600da2a6251d56a [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.am;
import static org.junit.Assert.assertNotNull;
import android.content.Context;
import android.hardware.power.stats.Channel;
import android.hardware.power.stats.EnergyConsumer;
import android.hardware.power.stats.EnergyConsumerResult;
import android.hardware.power.stats.EnergyConsumerType;
import android.hardware.power.stats.EnergyMeasurement;
import android.hardware.power.stats.PowerEntity;
import android.hardware.power.stats.StateResidencyResult;
import android.power.PowerStatsInternal;
import android.util.SparseArray;
import androidx.test.InstrumentationRegistry;
import com.android.internal.os.BatteryStatsImpl;
import org.junit.Before;
import java.util.concurrent.CompletableFuture;
/**
* Tests for {@link BatteryExternalStatsWorker}.
*
* Build/Install/Run:
* atest FrameworksServicesTests:BatteryExternalStatsWorkerTest
*/
public class BatteryExternalStatsWorkerTest {
private BatteryExternalStatsWorker mBatteryExternalStatsWorker;
private TestBatteryStatsImpl mBatteryStatsImpl;
private TestPowerStatsInternal mPowerStatsInternal;
@Before
public void setUp() {
final Context context = InstrumentationRegistry.getContext();
mBatteryStatsImpl = new TestBatteryStatsImpl();
mPowerStatsInternal = new TestPowerStatsInternal();
mBatteryExternalStatsWorker = new BatteryExternalStatsWorker(new TestInjector(context),
mBatteryStatsImpl);
}
public class TestInjector extends BatteryExternalStatsWorker.Injector {
public TestInjector(Context context) {
super(context);
}
public <T> T getSystemService(Class<T> serviceClass) {
return null;
}
public <T> T getLocalService(Class<T> serviceClass) {
if (serviceClass == PowerStatsInternal.class) {
return (T) mPowerStatsInternal;
}
return null;
}
}
public class TestBatteryStatsImpl extends BatteryStatsImpl {
}
public class TestPowerStatsInternal extends PowerStatsInternal {
private final SparseArray<EnergyConsumer> mEnergyConsumers = new SparseArray<>();
private final SparseArray<EnergyConsumerResult> mEnergyConsumerResults =
new SparseArray<>();
private final int mTimeSinceBoot = 0;
@Override
public EnergyConsumer[] getEnergyConsumerInfo() {
final int size = mEnergyConsumers.size();
final EnergyConsumer[] consumers = new EnergyConsumer[size];
for (int i = 0; i < size; i++) {
consumers[i] = mEnergyConsumers.valueAt(i);
}
return consumers;
}
@Override
public CompletableFuture<EnergyConsumerResult[]> getEnergyConsumedAsync(
int[] energyConsumerIds) {
final CompletableFuture<EnergyConsumerResult[]> future = new CompletableFuture();
final int size = mEnergyConsumerResults.size();
final EnergyConsumerResult[] results = new EnergyConsumerResult[size];
for (int i = 0; i < size; i++) {
results[i] = mEnergyConsumerResults.valueAt(i);
}
future.complete(results);
return future;
}
@Override
public PowerEntity[] getPowerEntityInfo() {
return new PowerEntity[0];
}
@Override
public CompletableFuture<StateResidencyResult[]> getStateResidencyAsync(
int[] powerEntityIds) {
return new CompletableFuture<>();
}
@Override
public Channel[] getEnergyMeterInfo() {
return new Channel[0];
}
@Override
public CompletableFuture<EnergyMeasurement[]> readEnergyMeterAsync(
int[] channelIds) {
return new CompletableFuture<>();
}
/**
* Util method to add a new EnergyConsumer for testing
*
* @return the EnergyConsumer id of the new EnergyConsumer
*/
public int addEnergyConsumer(@EnergyConsumerType byte type, int ordinal, String name) {
final EnergyConsumer consumer = new EnergyConsumer();
final int id = getNextAvailableId();
consumer.id = id;
consumer.type = type;
consumer.ordinal = ordinal;
consumer.name = name;
mEnergyConsumers.put(id, consumer);
final EnergyConsumerResult result = new EnergyConsumerResult();
result.id = id;
result.timestampMs = mTimeSinceBoot;
result.energyUWs = 0;
mEnergyConsumerResults.put(id, result);
return id;
}
public void incrementEnergyConsumption(int id, long energyUWs) {
EnergyConsumerResult result = mEnergyConsumerResults.get(id, null);
assertNotNull(result);
result.energyUWs += energyUWs;
}
private int getNextAvailableId() {
final int size = mEnergyConsumers.size();
// Just return the first index that does not match the key (aka the EnergyConsumer id)
for (int i = size - 1; i >= 0; i--) {
if (mEnergyConsumers.keyAt(i) == i) return i + 1;
}
// Otherwise return the lowest id
return 0;
}
}
}