blob: 6a5f51277c4b1cc3397064baaca33382cfb1db06 [file] [log] [blame]
Yifan Hong7a6956e2021-11-08 23:52:44 -08001/*
2 * Copyright (C) 2021 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#include <android-base/logging.h>
18#include <android/hardware/health/translate-ndk.h>
19#include <health-shim/shim.h>
20
21using ::android::sp;
22using ::android::h2a::translate;
23using ::android::hardware::Return;
24using ::android::hardware::Void;
25using ::android::hardware::health::V2_0::Result;
26using ::android::hardware::health::V2_0::toString;
27using ::ndk::ScopedAStatus;
28using HidlHealth = ::android::hardware::health::V2_0::IHealth;
29using HidlHealthInfoCallback = ::android::hardware::health::V2_0::IHealthInfoCallback;
30using HidlHealthInfo = ::android::hardware::health::V2_0::HealthInfo;
31
32namespace aidl::android::hardware::health {
33
34namespace {
35
36class HealthInfoCallbackShim : public HidlHealthInfoCallback {
37 using AidlHealthInfoCallback = ::aidl::android::hardware::health::IHealthInfoCallback;
38 using AidlHealthInfo = ::aidl::android::hardware::health::HealthInfo;
39
40 public:
41 explicit HealthInfoCallbackShim(const std::shared_ptr<AidlHealthInfoCallback>& impl)
42 : impl_(impl) {}
43 Return<void> healthInfoChanged(const HidlHealthInfo& info) override {
44 AidlHealthInfo aidl_info;
45 // translate() should always return true.
46 CHECK(translate(info, &aidl_info));
47 // This is a oneway function, so we can't (and shouldn't) check for errors.
48 (void)impl_->healthInfoChanged(aidl_info);
49 return Void();
50 }
51
52 private:
53 std::shared_ptr<AidlHealthInfoCallback> impl_;
54};
55
56ScopedAStatus ResultToStatus(Result result) {
57 switch (result) {
58 case Result::SUCCESS:
59 return ScopedAStatus::ok();
60 case Result::NOT_SUPPORTED:
61 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
62 case Result::UNKNOWN:
63 return ScopedAStatus::fromServiceSpecificError(IHealth::STATUS_UNKNOWN);
64 case Result::NOT_FOUND:
65 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
66 case Result::CALLBACK_DIED:
67 return ScopedAStatus::fromServiceSpecificError(IHealth::STATUS_CALLBACK_DIED);
68 }
69 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
70 IHealth::STATUS_UNKNOWN, ("Unrecognized result value " + toString(result)).c_str());
71}
72
73template <typename T>
74ScopedAStatus ReturnAndResultToStatus(const Return<T>& ret, Result result) {
75 if (ret.isOk()) {
76 return ResultToStatus(result);
77 }
78 if (ret.isDeadObject()) {
79 return ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT);
80 }
81 return ScopedAStatus::fromServiceSpecificErrorWithMessage(IHealth::STATUS_UNKNOWN,
82 ret.description().c_str());
83}
84
85ScopedAStatus ReturnResultToStatus(const Return<Result>& return_result) {
86 return ReturnAndResultToStatus(return_result, return_result.isOk()
87 ? static_cast<Result>(return_result)
88 : Result::UNKNOWN);
89}
90
91} // namespace
92
93HealthShim::HealthShim(const sp<HidlHealth>& service) : service_(service) {}
94
95ScopedAStatus HealthShim::registerCallback(
96 const std::shared_ptr<IHealthInfoCallback>& in_callback) {
97 sp<HidlHealthInfoCallback> shim(new HealthInfoCallbackShim(in_callback));
98 callback_map_.emplace(in_callback, shim);
99 return ReturnResultToStatus(service_->registerCallback(shim));
100}
101
102ScopedAStatus HealthShim::unregisterCallback(
103 const std::shared_ptr<IHealthInfoCallback>& in_callback) {
104 auto it = callback_map_.find(in_callback);
105 if (it == callback_map_.end()) {
106 return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
107 }
108 sp<HidlHealthInfoCallback> shim = it->second;
109 callback_map_.erase(it);
110 return ReturnResultToStatus(service_->unregisterCallback(shim));
111}
112
113ScopedAStatus HealthShim::update() {
114 return ReturnResultToStatus(service_->update());
115}
116
117ScopedAStatus HealthShim::getChargeCounterUah(int32_t* out) {
118 Result out_result = Result::UNKNOWN;
119 auto ret = service_->getChargeCounter([out, &out_result](auto result, auto value) {
120 out_result = result;
121 if (out_result != Result::SUCCESS) return;
122 *out = value;
123 });
124 return ReturnAndResultToStatus(ret, out_result);
125}
126
127ScopedAStatus HealthShim::getCurrentNowMicroamps(int32_t* out) {
128 Result out_result = Result::UNKNOWN;
129 auto ret = service_->getCurrentNow([out, &out_result](auto result, auto value) {
130 out_result = result;
131 if (out_result != Result::SUCCESS) return;
132 *out = value;
133 });
134 return ReturnAndResultToStatus(ret, out_result);
135}
136
137ScopedAStatus HealthShim::getCurrentAverageMicroamps(int32_t* out) {
138 Result out_result = Result::UNKNOWN;
139 auto ret = service_->getCurrentAverage([out, &out_result](auto result, auto value) {
140 out_result = result;
141 if (out_result != Result::SUCCESS) return;
142 *out = value;
143 });
144 return ReturnAndResultToStatus(ret, out_result);
145}
146
147ScopedAStatus HealthShim::getCapacity(int32_t* out) {
148 Result out_result = Result::UNKNOWN;
149 auto ret = service_->getCapacity([out, &out_result](auto result, auto value) {
150 out_result = result;
151 if (out_result != Result::SUCCESS) return;
152 *out = value;
153 });
154 return ReturnAndResultToStatus(ret, out_result);
155}
156
157ScopedAStatus HealthShim::getEnergyCounterNwh(int64_t* out) {
158 Result out_result = Result::UNKNOWN;
159 auto ret = service_->getEnergyCounter([out, &out_result](auto result, auto value) {
160 out_result = result;
161 if (out_result != Result::SUCCESS) return;
162 *out = value;
163 });
164 return ReturnAndResultToStatus(ret, out_result);
165}
166
167ScopedAStatus HealthShim::getChargeStatus(BatteryStatus* out) {
168 Result out_result = Result::UNKNOWN;
169 auto ret = service_->getChargeStatus([out, &out_result](auto result, auto value) {
170 out_result = result;
171 if (out_result != Result::SUCCESS) return;
172 *out = static_cast<BatteryStatus>(value);
173 });
174 return ReturnAndResultToStatus(ret, out_result);
175}
176
177ScopedAStatus HealthShim::getStorageInfo(std::vector<StorageInfo>* out) {
178 Result out_result = Result::UNKNOWN;
179 auto ret = service_->getStorageInfo([out, &out_result](auto result, const auto& value) {
180 out_result = result;
181 if (out_result != Result::SUCCESS) return;
182 out->clear();
183 out->reserve(value.size());
184 for (const auto& hidl_info : value) {
185 auto& aidl_info = out->emplace_back();
186 // translate() should always return true.
187 CHECK(translate(hidl_info, &aidl_info));
188 }
189 });
190 return ReturnAndResultToStatus(ret, out_result);
191}
192
193ScopedAStatus HealthShim::getDiskStats(std::vector<DiskStats>* out) {
194 Result out_result = Result::UNKNOWN;
195 auto ret = service_->getDiskStats([out, &out_result](auto result, const auto& value) {
196 out_result = result;
197 if (out_result != Result::SUCCESS) return;
198 out->clear();
199 out->reserve(value.size());
200 for (const auto& hidl_info : value) {
201 auto& aidl_info = out->emplace_back();
202 // translate() should always return true.
203 CHECK(translate(hidl_info, &aidl_info));
204 }
205 });
206 return ReturnAndResultToStatus(ret, out_result);
207}
208
209ScopedAStatus HealthShim::getHealthInfo(HealthInfo* out) {
210 Result out_result = Result::UNKNOWN;
211 auto ret = service_->getHealthInfo([out, &out_result](auto result, const auto& value) {
212 out_result = result;
213 if (out_result != Result::SUCCESS) return;
214 // translate() should always return true.
215 CHECK(translate(value, out));
216 });
217 return ReturnAndResultToStatus(ret, out_result);
218}
219
Jack Wu33561612022-11-24 12:10:55 +0800220ScopedAStatus HealthShim::setChargingPolicy(BatteryChargingPolicy in_value) {
221 in_value = static_cast<BatteryChargingPolicy>(0);
222 return ResultToStatus(Result::NOT_SUPPORTED);
223}
224
225ScopedAStatus HealthShim::getChargingPolicy(BatteryChargingPolicy* out) {
226 *out = static_cast<BatteryChargingPolicy>(0);
227 return ResultToStatus(Result::NOT_SUPPORTED);
228}
229
230ScopedAStatus HealthShim::getBatteryHealthData(BatteryHealthData* out) {
231 out->batteryManufacturingDateSeconds = 0;
232 out->batteryFirstUsageSeconds = 0;
233 return ResultToStatus(Result::NOT_SUPPORTED);
234}
235
Yifan Hong7a6956e2021-11-08 23:52:44 -0800236} // namespace aidl::android::hardware::health