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