1 /*
2  * Copyright (C) 2018 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 
17 #define LOG_TAG "android.power.stats.vts"
18 
19 #include <android-base/logging.h>
20 #include <android/hardware/power/stats/1.0/IPowerStats.h>
21 #include <fmq/MessageQueue.h>
22 #include <gtest/gtest.h>
23 #include <hidl/GtestPrinter.h>
24 #include <hidl/MQDescriptor.h>
25 #include <hidl/ServiceManagement.h>
26 #include <inttypes.h>
27 
28 #include <algorithm>
29 #include <random>
30 #include <thread>
31 
32 namespace android {
33 namespace power {
34 namespace stats {
35 namespace vts {
36 namespace {
37 
38 using android::sp;
39 using android::hardware::hidl_vec;
40 using android::hardware::kSynchronizedReadWrite;
41 using android::hardware::Return;
42 using android::hardware::Void;
43 using android::hardware::power::stats::V1_0::EnergyData;
44 using android::hardware::power::stats::V1_0::IPowerStats;
45 using android::hardware::power::stats::V1_0::PowerEntityInfo;
46 using android::hardware::power::stats::V1_0::PowerEntityStateResidencyResult;
47 using android::hardware::power::stats::V1_0::PowerEntityStateSpace;
48 using android::hardware::power::stats::V1_0::RailInfo;
49 using android::hardware::power::stats::V1_0::Status;
50 
51 }  // namespace
52 
53 typedef hardware::MessageQueue<EnergyData, kSynchronizedReadWrite> MessageQueueSync;
54 
55 class PowerStatsHidlTest : public ::testing::TestWithParam<std::string> {
56    public:
SetUp()57     virtual void SetUp() override {
58         service_ = IPowerStats::getService(GetParam());
59         ASSERT_NE(service_, nullptr);
60     }
61 
TearDown()62     virtual void TearDown() override {}
63 
64     void getInfos(hidl_vec<PowerEntityInfo>& infos);
65     void getStateSpaces(hidl_vec<PowerEntityStateSpace>& stateSpaces,
66                         const std::vector<uint32_t>& ids);
67     void getResidencyResults(hidl_vec<PowerEntityStateResidencyResult>& results,
68                              const std::vector<uint32_t>& ids);
69     void getRandomIds(std::vector<uint32_t>& ids);
70 
71     sp<IPowerStats> service_;
72 };
73 
getInfos(hidl_vec<PowerEntityInfo> & infos)74 void PowerStatsHidlTest::getInfos(hidl_vec<PowerEntityInfo>& infos) {
75     Status status;
76     Return<void> ret = service_->getPowerEntityInfo([&status, &infos](auto rInfos, auto rStatus) {
77         status = rStatus;
78         infos = rInfos;
79     });
80     ASSERT_TRUE(ret.isOk());
81 
82     if (status == Status::SUCCESS) {
83         ASSERT_NE(infos.size(), 0) << "powerEntityInfos must have entries if supported";
84     } else {
85         ASSERT_EQ(status, Status::NOT_SUPPORTED);
86         ASSERT_EQ(infos.size(), 0);
87         LOG(INFO) << "getPowerEntityInfo not supported";
88     }
89 }
90 
getStateSpaces(hidl_vec<PowerEntityStateSpace> & stateSpaces,const std::vector<uint32_t> & ids={})91 void PowerStatsHidlTest::getStateSpaces(hidl_vec<PowerEntityStateSpace>& stateSpaces,
92                                         const std::vector<uint32_t>& ids = {}) {
93     Status status;
94     Return<void> ret = service_->getPowerEntityStateInfo(
__anon4a02aa110302(auto rStateSpaces, auto rStatus) 95         ids, [&status, &stateSpaces](auto rStateSpaces, auto rStatus) {
96             status = rStatus;
97             stateSpaces = rStateSpaces;
98         });
99     ASSERT_TRUE(ret.isOk());
100 
101     if (status == Status::SUCCESS) {
102         ASSERT_NE(stateSpaces.size(), 0) << "powerEntityStateSpaces must have entries if supported";
103     } else {
104         ASSERT_EQ(status, Status::NOT_SUPPORTED);
105         ASSERT_EQ(stateSpaces.size(), 0);
106         LOG(INFO) << "getPowerEntityStateInfo not supported";
107     }
108 }
109 
getResidencyResults(hidl_vec<PowerEntityStateResidencyResult> & results,const std::vector<uint32_t> & ids={})110 void PowerStatsHidlTest::getResidencyResults(hidl_vec<PowerEntityStateResidencyResult>& results,
111                                              const std::vector<uint32_t>& ids = {}) {
112     Status status;
113     Return<void> ret = service_->getPowerEntityStateResidencyData(
__anon4a02aa110402(auto rResults, auto rStatus) 114         ids, [&status, &results](auto rResults, auto rStatus) {
115             status = rStatus;
116             results = rResults;
117         });
118     ASSERT_TRUE(ret.isOk());
119 
120     if (status == Status::SUCCESS) {
121         ASSERT_NE(results.size(), 0);
122     } else {
123         ASSERT_EQ(status, Status::NOT_SUPPORTED);
124         ASSERT_EQ(results.size(), 0);
125         LOG(INFO) << "getPowerEntityStateResidencyData not supported";
126     }
127 }
128 
getRandomIds(std::vector<uint32_t> & ids)129 void PowerStatsHidlTest::getRandomIds(std::vector<uint32_t>& ids) {
130     hidl_vec<PowerEntityStateSpace> stateSpaces;
131     getStateSpaces(stateSpaces);
132 
133     if (stateSpaces.size() == 0) {
134         return;
135     }
136 
137     for (auto stateSpace : stateSpaces) {
138         ids.push_back(stateSpace.powerEntityId);
139     }
140 
141     unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
142     auto gen = std::default_random_engine(seed);
143     std::uniform_int_distribution<uint32_t> dist(1, stateSpaces.size());
144 
145     std::shuffle(ids.begin(), ids.end(), gen);
146     ids.resize(dist(gen));
147 }
148 
149 // Each PowerEntity must have a valid name
TEST_P(PowerStatsHidlTest,ValidatePowerEntityNames)150 TEST_P(PowerStatsHidlTest, ValidatePowerEntityNames) {
151     hidl_vec<PowerEntityInfo> infos;
152     getInfos(infos);
153     for (auto info : infos) {
154         ASSERT_NE(info.powerEntityName, "");
155     }
156 }
157 
158 // Each PowerEntity must have a unique ID
TEST_P(PowerStatsHidlTest,ValidatePowerEntityIds)159 TEST_P(PowerStatsHidlTest, ValidatePowerEntityIds) {
160     hidl_vec<PowerEntityInfo> infos;
161     getInfos(infos);
162 
163     std::set<uint32_t> ids;
164     for (auto info : infos) {
165         ASSERT_TRUE(ids.insert(info.powerEntityId).second);
166     }
167 }
168 
169 // Each PowerEntityStateSpace must have an associated PowerEntityInfo
TEST_P(PowerStatsHidlTest,ValidateStateInfoAssociation)170 TEST_P(PowerStatsHidlTest, ValidateStateInfoAssociation) {
171     hidl_vec<PowerEntityInfo> infos;
172     getInfos(infos);
173 
174     hidl_vec<PowerEntityStateSpace> stateSpaces;
175     getStateSpaces(stateSpaces);
176 
177     std::set<uint32_t> ids;
178     for (auto info : infos) {
179         ids.insert(info.powerEntityId);
180     }
181 
182     for (auto stateSpace : stateSpaces) {
183         ASSERT_NE(ids.count(stateSpace.powerEntityId), 0);
184     }
185 }
186 
187 // Each state must have a valid name
TEST_P(PowerStatsHidlTest,ValidateStateNames)188 TEST_P(PowerStatsHidlTest, ValidateStateNames) {
189     hidl_vec<PowerEntityStateSpace> stateSpaces;
190     getStateSpaces(stateSpaces);
191 
192     for (auto stateSpace : stateSpaces) {
193         for (auto state : stateSpace.states) {
194             ASSERT_NE(state.powerEntityStateName, "");
195         }
196     }
197 }
198 
199 // Each state must have an ID that is unique to the PowerEntityStateSpace
TEST_P(PowerStatsHidlTest,ValidateStateUniqueIds)200 TEST_P(PowerStatsHidlTest, ValidateStateUniqueIds) {
201     hidl_vec<PowerEntityStateSpace> stateSpaces;
202     getStateSpaces(stateSpaces);
203 
204     for (auto stateSpace : stateSpaces) {
205         std::set<uint32_t> stateIds;
206         for (auto state : stateSpace.states) {
207             ASSERT_TRUE(stateIds.insert(state.powerEntityStateId).second);
208         }
209     }
210 }
211 
212 // getPowerEntityStateInfo must support passing in requested IDs
213 // Results must contain state space information for all requested IDs
TEST_P(PowerStatsHidlTest,ValidateStateInfoAssociationSelect)214 TEST_P(PowerStatsHidlTest, ValidateStateInfoAssociationSelect) {
215     std::vector<uint32_t> randomIds;
216     getRandomIds(randomIds);
217 
218     if (randomIds.empty()) {
219         return;
220     }
221 
222     hidl_vec<PowerEntityStateSpace> stateSpaces;
223     getStateSpaces(stateSpaces, randomIds);
224 
225     ASSERT_EQ(stateSpaces.size(), randomIds.size());
226 
227     std::set<uint32_t> ids;
228     for (auto id : randomIds) {
229         ids.insert(id);
230     }
231     for (auto stateSpace : stateSpaces) {
232         ASSERT_NE(ids.count(stateSpace.powerEntityId), 0);
233     }
234 }
235 
236 // Requested state space info must match initially obtained stateinfos
TEST_P(PowerStatsHidlTest,ValidateStateInfoSelect)237 TEST_P(PowerStatsHidlTest, ValidateStateInfoSelect) {
238     hidl_vec<PowerEntityStateSpace> stateSpaces;
239     getStateSpaces(stateSpaces);
240     if (stateSpaces.size() == 0) {
241         return;
242     }
243 
244     std::vector<uint32_t> randomIds;
245     getRandomIds(randomIds);
246     ASSERT_FALSE(randomIds.empty());
247 
248     hidl_vec<PowerEntityStateSpace> selectedStateSpaces;
249     getStateSpaces(selectedStateSpaces, randomIds);
250 
251     std::map<uint32_t, PowerEntityStateSpace> stateSpaceMap;
252     for (auto stateSpace : stateSpaces) {
253         stateSpaceMap[stateSpace.powerEntityId] = stateSpace;
254     }
255 
256     for (auto stateSpace : selectedStateSpaces) {
257         auto it = stateSpaceMap.find(stateSpace.powerEntityId);
258         ASSERT_NE(it, stateSpaceMap.end());
259 
260         ASSERT_EQ(stateSpace.states.size(), it->second.states.size());
261         for (auto i = 0; i < stateSpace.states.size(); i++) {
262             ASSERT_EQ(stateSpace.states[i].powerEntityStateId,
263                       it->second.states[i].powerEntityStateId);
264             ASSERT_EQ(stateSpace.states[i].powerEntityStateName,
265                       it->second.states[i].powerEntityStateName);
266         }
267     }
268 }
269 
270 // stateResidencyResults must contain results for every PowerEntityStateSpace
271 // returned by getPowerEntityStateInfo
TEST_P(PowerStatsHidlTest,ValidateResidencyResultsAssociation)272 TEST_P(PowerStatsHidlTest, ValidateResidencyResultsAssociation) {
273     hidl_vec<PowerEntityStateSpace> stateSpaces;
274     getStateSpaces(stateSpaces);
275 
276     hidl_vec<PowerEntityStateResidencyResult> results;
277     getResidencyResults(results);
278 
279     std::map<uint32_t, PowerEntityStateResidencyResult> resultsMap;
280     for (auto result : results) {
281         resultsMap[result.powerEntityId] = result;
282     }
283 
284     for (auto stateSpace : stateSpaces) {
285         auto it = resultsMap.find(stateSpace.powerEntityId);
286         ASSERT_NE(it, resultsMap.end());
287 
288         ASSERT_EQ(stateSpace.states.size(), it->second.stateResidencyData.size());
289 
290         std::set<uint32_t> stateIds;
291         for (auto residency : it->second.stateResidencyData) {
292             stateIds.insert(residency.powerEntityStateId);
293         }
294 
295         for (auto state : stateSpace.states) {
296             ASSERT_NE(stateIds.count(state.powerEntityStateId), 0);
297         }
298     }
299 }
300 
301 // getPowerEntityStateResidencyData must support passing in requested IDs
302 // stateResidencyResults must contain results for each PowerEntityStateSpace
303 // returned by getPowerEntityStateInfo
TEST_P(PowerStatsHidlTest,ValidateResidencyResultsAssociationSelect)304 TEST_P(PowerStatsHidlTest, ValidateResidencyResultsAssociationSelect) {
305     std::vector<uint32_t> randomIds;
306     getRandomIds(randomIds);
307     if (randomIds.empty()) {
308         return;
309     }
310 
311     hidl_vec<PowerEntityStateSpace> stateSpaces;
312     getStateSpaces(stateSpaces, randomIds);
313 
314     hidl_vec<PowerEntityStateResidencyResult> results;
315     getResidencyResults(results, randomIds);
316 
317     std::map<uint32_t, PowerEntityStateResidencyResult> resultsMap;
318     for (auto result : results) {
319         resultsMap[result.powerEntityId] = result;
320     }
321 
322     for (auto stateSpace : stateSpaces) {
323         auto it = resultsMap.find(stateSpace.powerEntityId);
324         ASSERT_NE(it, resultsMap.end());
325 
326         ASSERT_EQ(stateSpace.states.size(), it->second.stateResidencyData.size());
327 
328         std::set<uint32_t> stateIds;
329         for (auto residency : it->second.stateResidencyData) {
330             stateIds.insert(residency.powerEntityStateId);
331         }
332 
333         for (auto state : stateSpace.states) {
334             ASSERT_NE(stateIds.count(state.powerEntityStateId), 0);
335         }
336     }
337 }
338 
TEST_P(PowerStatsHidlTest,ValidateRailInfo)339 TEST_P(PowerStatsHidlTest, ValidateRailInfo) {
340     hidl_vec<RailInfo> rails[2];
341     Status s;
342     auto cb = [&rails, &s](hidl_vec<RailInfo> rail_subsys, Status status) {
343         rails[0] = rail_subsys;
344         s = status;
345     };
346     Return<void> ret = service_->getRailInfo(cb);
347     EXPECT_TRUE(ret.isOk());
348     if (s == Status::SUCCESS) {
349         /* Rails size should be non-zero on SUCCESS*/
350         ASSERT_NE(rails[0].size(), 0);
351         /* check if indices returned are unique*/
352         std::set<uint32_t> ids;
353         for (auto rail : rails[0]) {
354             ASSERT_TRUE(ids.insert(rail.index).second);
355         }
356         auto cb = [&rails, &s](hidl_vec<RailInfo> rail_subsys, Status status) {
357             rails[1] = rail_subsys;
358             s = status;
359         };
360         Return<void> ret = service_->getRailInfo(cb);
361         EXPECT_TRUE(ret.isOk());
362         ASSERT_EQ(s, Status::SUCCESS);
363         ASSERT_EQ(rails[0].size(), rails[1].size());
364         /* check if data returned by two calls to getRailInfo is same*/
365         for (int i = 0; i < rails[0].size(); i++) {
366             ASSERT_NE(rails[0][i].railName, "");
367             ASSERT_NE(rails[0][i].subsysName, "");
368             int j = 0;
369             bool match = false;
370             for (j = 0; j < rails[1].size(); j++) {
371                 if (rails[0][i].index == rails[1][j].index) {
372                     ASSERT_EQ(rails[0][i].railName, rails[1][i].railName);
373                     ASSERT_EQ(rails[0][i].subsysName, rails[1][i].subsysName);
374                     match = true;
375                     break;
376                 }
377             }
378             ASSERT_TRUE(match);
379         }
380     } else if (s == Status::FILESYSTEM_ERROR) {
381         ALOGI("ValidateRailInfo returned FILESYSTEM_ERROR");
382         ASSERT_EQ(rails[0].size(), 0);
383     } else if (s == Status::NOT_SUPPORTED) {
384         ALOGI("ValidateRailInfo returned NOT_SUPPORTED");
385         ASSERT_EQ(rails[0].size(), 0);
386     } else if (s == Status::INVALID_INPUT) {
387         ALOGI("ValidateRailInfo returned INVALID_INPUT");
388         ASSERT_EQ(rails[0].size(), 0);
389     } else if (s == Status::INSUFFICIENT_RESOURCES) {
390         ALOGI("ValidateRailInfo returned INSUFFICIENT_RESOURCES");
391         ASSERT_EQ(rails[0].size(), 0);
392     }
393 }
394 
TEST_P(PowerStatsHidlTest,ValidateAllPowerData)395 TEST_P(PowerStatsHidlTest, ValidateAllPowerData) {
396     hidl_vec<EnergyData> measurements[2];
397     Status s;
398     auto cb = [&measurements, &s](hidl_vec<EnergyData> measure, Status status) {
399         measurements[0] = measure;
400         s = status;
401     };
402     Return<void> ret = service_->getEnergyData(hidl_vec<uint32_t>(), cb);
403     EXPECT_TRUE(ret.isOk());
404     if (s == Status::SUCCESS) {
405         /*measurements size should be non-zero on SUCCESS*/
406         ASSERT_NE(measurements[0].size(), 0);
407         auto cb = [&measurements, &s](hidl_vec<EnergyData> measure, Status status) {
408             measurements[1] = measure;
409             s = status;
410         };
411         Return<void> ret = service_->getEnergyData(hidl_vec<uint32_t>(), cb);
412         EXPECT_TRUE(ret.isOk());
413         ASSERT_EQ(s, Status::SUCCESS);
414         /*Both calls should returns same amount of data*/
415         ASSERT_EQ(measurements[0].size(), measurements[1].size());
416         /*Check is energy and timestamp are monotonically increasing*/
417         for (int i = 0; i < measurements[0].size(); i++) {
418             int j;
419             for (j = 0; j < measurements[1].size(); j++) {
420                 if (measurements[0][i].index == measurements[1][j].index) {
421                     EXPECT_GE(measurements[1][j].timestamp, measurements[0][i].timestamp);
422                     EXPECT_GE(measurements[1][j].energy, measurements[0][i].energy);
423                     break;
424                 }
425             }
426             /*Check is indices for two call match*/
427             ASSERT_NE(j, measurements[1].size());
428         }
429     } else if (s == Status::FILESYSTEM_ERROR) {
430         ALOGI("ValidateAllPowerData returned FILESYSTEM_ERROR");
431         ASSERT_EQ(measurements[0].size(), 0);
432     } else if (s == Status::NOT_SUPPORTED) {
433         ALOGI("ValidateAllPowerData returned NOT_SUPPORTED");
434         ASSERT_EQ(measurements[0].size(), 0);
435     } else if (s == Status::INVALID_INPUT) {
436         ALOGI("ValidateAllPowerData returned INVALID_INPUT");
437         ASSERT_EQ(measurements[0].size(), 0);
438     } else if (s == Status::INSUFFICIENT_RESOURCES) {
439         ALOGI("ValidateAllPowerData returned INSUFFICIENT_RESOURCES");
440         ASSERT_EQ(measurements[0].size(), 0);
441     }
442 }
443 
TEST_P(PowerStatsHidlTest,ValidateFilteredPowerData)444 TEST_P(PowerStatsHidlTest, ValidateFilteredPowerData) {
445     hidl_vec<RailInfo> rails;
446     hidl_vec<EnergyData> measurements;
447     hidl_vec<uint32_t> indices;
448     std::string debugString;
449     Status s;
450     auto cb = [&rails, &s](hidl_vec<RailInfo> rail_subsys, Status status) {
451         rails = rail_subsys;
452         s = status;
453     };
454     Return<void> ret = service_->getRailInfo(cb);
455     EXPECT_TRUE(ret.isOk());
456     std::time_t seed = std::time(nullptr);
457     std::srand(seed);
458     if (s == Status::SUCCESS) {
459         size_t sz = std::max(1, (int)(std::rand() % rails.size()));
460         indices.resize(sz);
461         for (int i = 0; i < sz; i++) {
462             int j = std::rand() % rails.size();
463             indices[i] = rails[j].index;
464             debugString += std::to_string(indices[i]) + ", ";
465         }
466         debugString += "\n";
467         ALOGI("ValidateFilteredPowerData for indices: %s", debugString.c_str());
468         auto cb = [&measurements, &s](hidl_vec<EnergyData> measure, Status status) {
469             measurements = measure;
470             s = status;
471         };
472         Return<void> ret = service_->getEnergyData(indices, cb);
473         EXPECT_TRUE(ret.isOk());
474         if (s == Status::SUCCESS) {
475             /* Make sure that all the measurements are returned */
476             ASSERT_EQ(sz, measurements.size());
477             for (int i = 0; i < measurements.size(); i++) {
478                 int j;
479                 bool match = false;
480                 /* Check that the measurement belongs to the requested index */
481                 for (j = 0; j < indices.size(); j++) {
482                     if (indices[j] == measurements[i].index) {
483                         match = true;
484                         break;
485                     }
486                 }
487                 ASSERT_TRUE(match);
488             }
489         }
490     } else {
491         /* size should be zero is stats is NOT SUCCESS */
492         ASSERT_EQ(rails.size(), 0);
493     }
494 }
495 
readEnergy(sp<IPowerStats> service_,uint32_t timeMs)496 void readEnergy(sp<IPowerStats> service_, uint32_t timeMs) {
497     std::unique_ptr<MessageQueueSync> mQueue;
498     Status s;
499     uint32_t railsInSample;
500     uint32_t totalSamples;
501     auto cb = [&s, &mQueue, &totalSamples, &railsInSample](
502                   const hardware::MQDescriptorSync<EnergyData>& in, uint32_t numSamples,
503                   uint32_t railsPerSample, Status status) {
504         mQueue.reset(new (std::nothrow) MessageQueueSync(in));
505         s = status;
506         totalSamples = numSamples;
507         railsInSample = railsPerSample;
508     };
509     service_->streamEnergyData(timeMs, 10, cb);
510     if (s == Status::SUCCESS) {
511         ASSERT_NE(nullptr, mQueue);
512         ASSERT_TRUE(mQueue->isValid());
513         bool rc;
514         int sampleCount = 0;
515         uint32_t totalQuants = railsInSample * totalSamples;
516         uint64_t timeout_ns = 10000000000;
517         if (totalSamples > 0) {
518             uint32_t batch = std::max(1, (int)((std::rand() % totalSamples) * railsInSample));
519             ALOGI("Read energy, timsMs: %u, batch: %u", timeMs, batch);
520             std::vector<EnergyData> data(batch);
521             while (sampleCount < totalQuants) {
522                 rc = mQueue->readBlocking(&data[0], batch, timeout_ns);
523                 if (rc == false) {
524                     break;
525                 }
526                 sampleCount = sampleCount + batch;
527                 if (batch > totalQuants - sampleCount) {
528                     batch = 1;
529                 }
530             }
531             ASSERT_EQ(totalQuants, sampleCount);
532         }
533     } else if (s == Status::FILESYSTEM_ERROR) {
534         ASSERT_FALSE(mQueue->isValid());
535         ASSERT_EQ(totalSamples, 0);
536         ASSERT_EQ(railsInSample, 0);
537     } else if (s == Status::NOT_SUPPORTED) {
538         ASSERT_FALSE(mQueue->isValid());
539         ASSERT_EQ(totalSamples, 0);
540         ASSERT_EQ(railsInSample, 0);
541     } else if (s == Status::INVALID_INPUT) {
542         ASSERT_FALSE(mQueue->isValid());
543         ASSERT_EQ(totalSamples, 0);
544         ASSERT_EQ(railsInSample, 0);
545     } else if (s == Status::INSUFFICIENT_RESOURCES) {
546         ASSERT_FALSE(mQueue->isValid());
547         ASSERT_EQ(totalSamples, 0);
548         ASSERT_EQ(railsInSample, 0);
549     }
550 }
551 
TEST_P(PowerStatsHidlTest,StreamEnergyData)552 TEST_P(PowerStatsHidlTest, StreamEnergyData) {
553     std::time_t seed = std::time(nullptr);
554     std::srand(seed);
555     std::thread thread1 = std::thread(readEnergy, service_, std::rand() % 5000);
556     thread1.join();
557 }
558 
559 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerStatsHidlTest);
560 INSTANTIATE_TEST_SUITE_P(
561         PerInstance, PowerStatsHidlTest,
562         testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPowerStats::descriptor)),
563         android::hardware::PrintInstanceNameToString);
564 
565 }  // namespace vts
566 }  // namespace stats
567 }  // namespace power
568 }  // namespace android
569