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 #include "src/android_internal/health_hal.h"
18 
19 #include <android/hardware/health/2.0/IHealth.h>
20 #include <healthhalutils/HealthHalUtils.h>
21 
22 namespace perfetto {
23 namespace android_internal {
24 
25 using ::android::hardware::health::V2_0::IHealth;
26 using ::android::hardware::health::V2_0::Result;
27 
28 namespace {
29 
30 android::sp<IHealth> g_svc;
31 
ResetService()32 void ResetService() {
33   g_svc = ::android::hardware::health::V2_0::get_health_service();
34 }
35 
36 }  // namespace
37 
GetBatteryCounter(BatteryCounter counter,int64_t * value)38 bool GetBatteryCounter(BatteryCounter counter, int64_t* value) {
39   *value = 0;
40   if (!g_svc)
41     ResetService();
42 
43   if (!g_svc)
44     return false;
45 
46   // The Android VNDK documentation states that for blocking services, the
47   // caller blocks until the reply is received and the callback is called inline
48   // in the same thread.
49   // See https://source.android.com/devices/architecture/hidl/threading .
50 
51   Result res;
52   switch (counter) {
53     case BatteryCounter::kUnspecified:
54       res = Result::NOT_FOUND;
55       break;
56 
57     case BatteryCounter::kCharge:
58       g_svc->getChargeCounter([&res, value](Result hal_res, int32_t hal_value) {
59         res = hal_res;
60         *value = hal_value;
61       });
62       break;
63 
64     case BatteryCounter::kCapacityPercent:
65       g_svc->getCapacity([&res, value](Result hal_res, int64_t hal_value) {
66         res = hal_res;
67         *value = hal_value;
68       });
69       break;
70 
71     case BatteryCounter::kCurrent:
72       g_svc->getCurrentNow([&res, value](Result hal_res, int32_t hal_value) {
73         res = hal_res;
74         *value = hal_value;
75       });
76       break;
77 
78     case BatteryCounter::kCurrentAvg:
79       g_svc->getCurrentAverage(
80           [&res, value](Result hal_res, int32_t hal_value) {
81             res = hal_res;
82             *value = hal_value;
83           });
84       break;
85   }  // switch(counter)
86 
87   if (res == Result::CALLBACK_DIED)
88     g_svc.clear();
89 
90   return res == Result::SUCCESS;
91 }
92 
93 }  // namespace android_internal
94 }  // namespace perfetto
95