1 /*
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 <stdlib.h>
18 #include <iostream>
19 //
20 #include <android-base/logging.h>
21 #include <gflags/gflags.h>
22 //
23 #include "host/libs/config/cuttlefish_config.h"
24 #include "host/libs/vm_manager/vm_manager.h"
25 
GetControlSocketPath(const cuttlefish::CuttlefishConfig & config)26 std::string GetControlSocketPath(const cuttlefish::CuttlefishConfig& config) {
27   return config.ForDefaultInstance().CrosvmSocketPath();
28 }
29 
30 static constexpr char kUsageMessage[] =
31     "<key> [value]\n"
32     "Excluding the value will enumerate the possible values to set\n"
33     "\n"
34     "\"status [value]\" - battery status: "
35     "unknown/charging/discharging/notcharging/full\n"
36     "\"health [value]\" - battery health\n"
37     "\"present [value]\" - battery present: 1 or 0\n"
38     "\"capacity [value]\" - battery capacity: 0 to 100\n"
39     "\"aconline [value]\" - battery ac online: 1 or 0\n";
40 
status()41 int status() {
42   std::cout
43       << "health status [value]\n"
44          "\"value\" - unknown, charging, discharging, notcharging, full\n";
45   return 0;
46 }
47 
health()48 int health() {
49   std::cout << "health health [value]\n"
50                "\"value\" - unknown, good, overheat, dead, overvoltage, "
51                "unexpectedfailure,\n"
52                "          cold, watchdogtimerexpire, safetytimerexpire, "
53                "overcurrent\n";
54   return 0;
55 }
56 
present()57 int present() {
58   std::cout << "health present [value]\n"
59                "\"value\" - 1, 0\n";
60   return 0;
61 }
62 
capacity()63 int capacity() {
64   std::cout << "health capacity [value]\n"
65                "\"value\" - 0 to 100\n";
66   return 0;
67 }
68 
aconline()69 int aconline() {
70   std::cout << "health aconline [value]\n"
71                "\"value\" - 1, 0\n";
72   return 0;
73 }
74 
usage()75 int usage() {
76   std::cout << "health " << kUsageMessage;
77   return 1;
78 }
79 
main(int argc,char ** argv)80 int main(int argc, char** argv) {
81   ::android::base::InitLogging(argv, android::base::StderrLogger);
82   gflags::SetUsageMessage(kUsageMessage);
83 
84   auto config = cuttlefish::CuttlefishConfig::Get();
85   if (!config) {
86     LOG(ERROR) << "Failed to obtain config object";
87     return 1;
88   }
89   // TODO(b/260649774): Consistent executable API for selecting an instance
90   auto instance = config->ForInstance(cuttlefish::GetInstance());
91 
92   if (argc != 2 && argc != 3) {
93     return usage();
94   }
95 
96   std::string key = argv[1];
97   std::string value = "";
98   if (argc == 3) {
99     value = argv[2];
100   }
101 
102   if (argc == 2 || value == "--help" || value == "-h" || value == "help") {
103     if (key == "status") {
104       return status();
105     } else if (key == "health") {
106       return health();
107     } else if (key == "present") {
108       return present();
109     } else if (key == "capacity") {
110       return capacity();
111     } else if (key == "aconline") {
112       return aconline();
113     } else {
114       return usage();
115     }
116   }
117 
118   cuttlefish::Command command(instance.crosvm_binary());
119   command.AddParameter("battery");
120   command.AddParameter("goldfish");
121   command.AddParameter(key);
122   command.AddParameter(value);
123   command.AddParameter(GetControlSocketPath(*config));
124 
125   std::string output, error;
126   auto ret = RunWithManagedStdio(std::move(command), NULL, &output, &error);
127   if (ret != 0) {
128     LOG(ERROR) << "goldfish battery returned: " << ret << "\n" << output << "\n" << error;
129   }
130   return ret;
131 }
132