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 #define LOG_TAG "android.hardware.health-service.cuttlefish"
17 
18 #include <memory>
19 #include <string_view>
20 
21 #include <android-base/logging.h>
22 #include <android/binder_interface_utils.h>
23 #include <health-impl/Health.h>
24 #include <health/utils.h>
25 
26 using ::aidl::android::hardware::health::BatteryHealth;
27 using ::aidl::android::hardware::health::BatteryStatus;
28 using ::aidl::android::hardware::health::HalHealthLoop;
29 using ::aidl::android::hardware::health::Health;
30 using ::aidl::android::hardware::health::HealthInfo;
31 using ::aidl::android::hardware::health::IHealth;
32 using ::android::hardware::health::InitHealthdConfig;
33 using ::ndk::ScopedAStatus;
34 using ::ndk::SharedRefBase;
35 using namespace std::literals;
36 
37 namespace aidl::android::hardware::health {
38 
39 // Health HAL implementation for cuttlefish. Note that in this implementation,
40 // cuttlefish pretends to be a device with a battery being charged.
41 // Implementations on real devices should not insert these fake values. For
42 // example, a battery-less device should report batteryPresent = false and
43 // batteryStatus = UNKNOWN.
44 
45 class HealthImpl : public Health {
46  public:
47   // Inherit constructor.
48   using Health::Health;
~HealthImpl()49   virtual ~HealthImpl() {}
50 
51   ScopedAStatus getChargeCounterUah(int32_t* out) override;
52   ScopedAStatus getCurrentNowMicroamps(int32_t* out) override;
53   ScopedAStatus getCurrentAverageMicroamps(int32_t* out) override;
54   ScopedAStatus getCapacity(int32_t* out) override;
55   ScopedAStatus getChargeStatus(BatteryStatus* out) override;
56   ScopedAStatus getBatteryHealthData(BatteryHealthData* out) override;
57 
58  protected:
59   void UpdateHealthInfo(HealthInfo* health_info) override;
60 };
61 
UpdateHealthInfo(HealthInfo * health_info)62 void HealthImpl::UpdateHealthInfo(HealthInfo* health_info) {
63   health_info->chargerAcOnline = true;
64   health_info->chargerUsbOnline = true;
65   health_info->chargerWirelessOnline = false;
66   health_info->maxChargingCurrentMicroamps = 500000;
67   health_info->maxChargingVoltageMicrovolts = 5000000;
68   health_info->batteryStatus = BatteryStatus::CHARGING;
69   health_info->batteryHealth = BatteryHealth::GOOD;
70   health_info->batteryPresent = true;
71   health_info->batteryLevel = 85;
72   health_info->batteryVoltageMillivolts = 3600;
73   health_info->batteryTemperatureTenthsCelsius = 250;
74   health_info->batteryCurrentMicroamps = 400000;
75   health_info->batteryCycleCount = 32;
76   health_info->batteryFullChargeUah = 4000000;
77   health_info->batteryChargeCounterUah = 1900000;
78   health_info->batteryTechnology = "Li-ion";
79 }
80 
getChargeCounterUah(int32_t * out)81 ScopedAStatus HealthImpl::getChargeCounterUah(int32_t* out) {
82   *out = 1900000;
83   return ScopedAStatus::ok();
84 }
85 
getCurrentNowMicroamps(int32_t * out)86 ScopedAStatus HealthImpl::getCurrentNowMicroamps(int32_t* out) {
87   *out = 400000;
88   return ScopedAStatus::ok();
89 }
90 
getCurrentAverageMicroamps(int32_t *)91 ScopedAStatus HealthImpl::getCurrentAverageMicroamps(int32_t*) {
92   return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
93 }
94 
getCapacity(int32_t * out)95 ScopedAStatus HealthImpl::getCapacity(int32_t* out) {
96   *out = 85;
97   return ScopedAStatus::ok();
98 }
99 
getChargeStatus(BatteryStatus * out)100 ScopedAStatus HealthImpl::getChargeStatus(BatteryStatus* out) {
101   *out = BatteryStatus::CHARGING;
102   return ScopedAStatus::ok();
103 }
104 
getBatteryHealthData(BatteryHealthData * out)105 ScopedAStatus HealthImpl::getBatteryHealthData(BatteryHealthData* out) {
106   out->batteryManufacturingDateSeconds = 0;
107   out->batteryFirstUsageSeconds = 0;
108   out->batteryStateOfHealth = 99;
109   out->batterySerialNumber = std::nullopt;
110   out->batteryPartStatus = BatteryPartStatus::UNSUPPORTED;
111   return ScopedAStatus::ok();
112 }
113 
114 }  // namespace aidl::android::hardware::health
115 
main(int,char ** argv)116 int main(int, [[maybe_unused]] char** argv) {
117 #ifdef __ANDROID_RECOVERY__
118   android::base::InitLogging(argv, android::base::KernelLogger);
119 #endif
120   // Cuttlefish does not support offline-charging mode, hence do not handle
121   // --charger option.
122   using aidl::android::hardware::health::HealthImpl;
123   LOG(INFO) << "Starting health HAL.";
124   auto config = std::make_unique<healthd_config>();
125   InitHealthdConfig(config.get());
126   auto binder = SharedRefBase::make<HealthImpl>("default", std::move(config));
127   auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
128   return hal_health_loop->StartLoop();
129 }
130