• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.power.stats;
17 
18 import static org.junit.Assert.assertNotNull;
19 
20 import android.hardware.power.stats.Channel;
21 import android.hardware.power.stats.EnergyConsumer;
22 import android.hardware.power.stats.EnergyConsumerResult;
23 import android.hardware.power.stats.EnergyConsumerType;
24 import android.hardware.power.stats.EnergyMeasurement;
25 import android.hardware.power.stats.PowerEntity;
26 import android.hardware.power.stats.State;
27 import android.hardware.power.stats.StateResidency;
28 import android.hardware.power.stats.StateResidencyResult;
29 import android.power.PowerStatsInternal;
30 import android.util.SparseArray;
31 
32 import java.util.Arrays;
33 import java.util.concurrent.CompletableFuture;
34 
35 class MockPowerStatsInternal extends PowerStatsInternal {
36     private final SparseArray<PowerEntity> mPowerEntities = new SparseArray<>();
37     private final SparseArray<StateResidencyResult> mStateResidencyResults = new SparseArray<>();
38     private final SparseArray<EnergyConsumer> mEnergyConsumers = new SparseArray<>();
39     private final SparseArray<EnergyConsumerResult> mEnergyConsumerResults = new SparseArray<>();
40     private final int mTimeSinceBoot = 0;
41 
42     @Override
getEnergyConsumerInfo()43     public EnergyConsumer[] getEnergyConsumerInfo() {
44         final int size = mEnergyConsumers.size();
45         final EnergyConsumer[] consumers = new EnergyConsumer[size];
46         for (int i = 0; i < size; i++) {
47             consumers[i] = mEnergyConsumers.valueAt(i);
48         }
49         return consumers;
50     }
51 
52     @Override
getEnergyConsumedAsync( int[] energyConsumerIds)53     public CompletableFuture<EnergyConsumerResult[]> getEnergyConsumedAsync(
54             int[] energyConsumerIds) {
55         final CompletableFuture<EnergyConsumerResult[]> future = new CompletableFuture();
56         final EnergyConsumerResult[] results;
57         final int length = energyConsumerIds.length;
58         if (length == 0) {
59             final int size = mEnergyConsumerResults.size();
60             results = new EnergyConsumerResult[size];
61             for (int i = 0; i < size; i++) {
62                 results[i] = mEnergyConsumerResults.valueAt(i);
63             }
64         } else {
65             results = new EnergyConsumerResult[length];
66             for (int i = 0; i < length; i++) {
67                 results[i] = mEnergyConsumerResults.get(energyConsumerIds[i]);
68             }
69         }
70         future.complete(results);
71         return future;
72     }
73 
74     @Override
getPowerEntityInfo()75     public PowerEntity[] getPowerEntityInfo() {
76         final int size = mPowerEntities.size();
77         final PowerEntity[] entities = new PowerEntity[size];
78         for (int i = 0; i < size; i++) {
79             entities[i] = mPowerEntities.valueAt(i);
80         }
81         return entities;
82     }
83 
84     @Override
getStateResidencyAsync( int[] powerEntityIds)85     public CompletableFuture<StateResidencyResult[]> getStateResidencyAsync(
86             int[] powerEntityIds) {
87         final CompletableFuture<StateResidencyResult[]> future = new CompletableFuture<>();
88         final StateResidencyResult[] results;
89         final int length = powerEntityIds.length;
90         if (length == 0) {
91             final int size = mStateResidencyResults.size();
92             results = new StateResidencyResult[size];
93             for (int i = 0; i < size; i++) {
94                 results[i] = mStateResidencyResults.valueAt(i);
95             }
96         } else {
97             results = new StateResidencyResult[length];
98             for (int i = 0; i < length; i++) {
99                 results[i] = mStateResidencyResults.get(powerEntityIds[i]);
100             }
101         }
102         future.complete(results);
103         return future;
104     }
105 
106     @Override
getEnergyMeterInfo()107     public Channel[] getEnergyMeterInfo() {
108         return new Channel[0];
109     }
110 
111     @Override
readEnergyMeterAsync( int[] channelIds)112     public CompletableFuture<EnergyMeasurement[]> readEnergyMeterAsync(
113             int[] channelIds) {
114         return new CompletableFuture<>();
115     }
116 
reset()117     public void reset() {
118         mStateResidencyResults.clear();
119         mEnergyConsumerResults.clear();
120     }
121 
addPowerEntity(int id, String name)122     public void addPowerEntity(int id, String name) {
123         PowerEntity powerEntity = new PowerEntity();
124         powerEntity.id = id;
125         powerEntity.name = name;
126         powerEntity.states = new State[0];
127         mPowerEntities.put(id, powerEntity);
128     }
129 
addPowerEntityState(int powerEntityId, int stateId, String name)130     public void addPowerEntityState(int powerEntityId, int stateId, String name) {
131         State state = new State();
132         state.id = stateId;
133         state.name = name;
134 
135         PowerEntity powerEntity = mPowerEntities.get(powerEntityId);
136         powerEntity.states = Arrays.copyOf(powerEntity.states, powerEntity.states.length + 1);
137         powerEntity.states[powerEntity.states.length - 1] = state;
138     }
139 
addStateResidencyResult(int entityId, int stateId, long totalTimeInStateMs, long totalStateEntryCount, long lastEntryTimestampMs)140     public void addStateResidencyResult(int entityId, int stateId, long totalTimeInStateMs,
141             long totalStateEntryCount, long lastEntryTimestampMs) {
142         StateResidencyResult result = mStateResidencyResults.get(entityId);
143         if (result == null) {
144             result = new StateResidencyResult();
145             result.id = entityId;
146             result.stateResidencyData = new StateResidency[0];
147             mStateResidencyResults.put(entityId, result);
148         }
149 
150         StateResidency residency = new StateResidency();
151         residency.id = stateId;
152         residency.totalTimeInStateMs = totalTimeInStateMs;
153         residency.totalStateEntryCount = totalStateEntryCount;
154         residency.lastEntryTimestampMs = lastEntryTimestampMs;
155 
156         result.stateResidencyData = Arrays.copyOf(result.stateResidencyData,
157                 result.stateResidencyData.length + 1);
158         result.stateResidencyData[result.stateResidencyData.length - 1] = residency;
159     }
160 
161     /**
162      * Util method to add a new EnergyConsumer for testing
163      *
164      * @return the EnergyConsumer id of the new EnergyConsumer
165      */
addEnergyConsumer(@nergyConsumerType byte type, int ordinal, String name)166     public int addEnergyConsumer(@EnergyConsumerType byte type, int ordinal, String name) {
167         final EnergyConsumer consumer = new EnergyConsumer();
168         final int id = getNextAvailableId();
169         consumer.id = id;
170         consumer.type = type;
171         consumer.ordinal = ordinal;
172         consumer.name = name;
173         mEnergyConsumers.put(id, consumer);
174 
175         final EnergyConsumerResult result = new EnergyConsumerResult();
176         result.id = id;
177         result.timestampMs = mTimeSinceBoot;
178         result.energyUWs = 0;
179         mEnergyConsumerResults.put(id, result);
180         return id;
181     }
182 
incrementEnergyConsumption(int id, long energyUWs)183     public void incrementEnergyConsumption(int id, long energyUWs) {
184         EnergyConsumerResult result = mEnergyConsumerResults.get(id, null);
185         assertNotNull(result);
186         result.energyUWs += energyUWs;
187     }
188 
getNextAvailableId()189     private int getNextAvailableId() {
190         final int size = mEnergyConsumers.size();
191         // Just return the first index that does not match the key (aka the EnergyConsumer id)
192         for (int i = size - 1; i >= 0; i--) {
193             if (mEnergyConsumers.keyAt(i) == i) return i + 1;
194         }
195         // Otherwise return the lowest id
196         return 0;
197     }
198 }
199