huangcm
2024-12-18 9d29be7f7249789d6ffd0440067187a9f040c2cd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 * Copyright (C) 2019 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.
 */
 
#include "src/android_internal/power_stats_hal.h"
 
#include <string.h>
 
#include <algorithm>
 
#include <android/hardware/power/stats/1.0/IPowerStats.h>
 
namespace perfetto {
namespace android_internal {
 
using android::hardware::hidl_vec;
using android::hardware::Return;
using android::hardware::power::stats::V1_0::EnergyData;
using android::hardware::power::stats::V1_0::IPowerStats;
using android::hardware::power::stats::V1_0::RailInfo;
using android::hardware::power::stats::V1_0::Status;
 
namespace {
 
android::sp<IPowerStats> g_svc;
 
bool GetService() {
  if (!g_svc)
    g_svc = IPowerStats::getService();
 
  return g_svc != nullptr;
}
 
}  // namespace
 
bool GetAvailableRails(RailDescriptor* rail_descriptors, size_t* size_of_arr) {
  const size_t in_array_size = *size_of_arr;
  *size_of_arr = 0;
  if (!GetService())
    return false;
 
  Status status;
  auto rails_cb = [rail_descriptors, size_of_arr, &in_array_size, &status](
                      hidl_vec<RailInfo> r, Status s) {
    status = s;
    if (status == Status::SUCCESS) {
      *size_of_arr = std::min(in_array_size, r.size());
      for (int i = 0; i < *size_of_arr; ++i) {
        const RailInfo& rail_info = r[i];
        RailDescriptor& descriptor = rail_descriptors[i];
 
        descriptor.index = rail_info.index;
        descriptor.sampling_rate = rail_info.samplingRate;
 
        strncpy(descriptor.rail_name, rail_info.railName.c_str(),
                sizeof(descriptor.rail_name));
        strncpy(descriptor.subsys_name, rail_info.subsysName.c_str(),
                sizeof(descriptor.subsys_name));
        descriptor.rail_name[sizeof(descriptor.rail_name) - 1] = '\0';
        descriptor.subsys_name[sizeof(descriptor.subsys_name) - 1] = '\0';
      }
    }
  };
 
  Return<void> ret = g_svc->getRailInfo(rails_cb);
  return status == Status::SUCCESS;
}
 
bool GetRailEnergyData(RailEnergyData* rail_energy_array, size_t* size_of_arr) {
  const size_t in_array_size = *size_of_arr;
  *size_of_arr = 0;
 
  if (!GetService())
    return false;
 
  Status status;
  auto energy_cb = [rail_energy_array, size_of_arr, &in_array_size, &status](
                       hidl_vec<EnergyData> m, Status s) {
    status = s;
    if (status == Status::SUCCESS) {
      *size_of_arr = std::min(in_array_size, m.size());
      for (int i = 0; i < *size_of_arr; ++i) {
        const EnergyData& measurement = m[i];
        RailEnergyData& element = rail_energy_array[i];
 
        element.index = measurement.index;
        element.timestamp = measurement.timestamp;
        element.energy = measurement.energy;
      }
    }
  };
 
  Return<void> ret = g_svc->getEnergyData(hidl_vec<uint32_t>(), energy_cb);
  return status == Status::SUCCESS;
}
 
}  // namespace android_internal
}  // namespace perfetto