blob: cbd2856dcde907f75ec3f1ed46285103e18391b1 [file] [log] [blame]
Hridya Valsaraju31d2c262018-07-20 13:35:50 -07001/*
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 "variables.h"
18
David Anderson12211d12018-07-24 15:21:20 -070019#include <inttypes.h>
20
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070021#include <android-base/file.h>
22#include <android-base/logging.h>
23#include <android-base/properties.h>
24#include <android-base/stringprintf.h>
25#include <android-base/strings.h>
26#include <ext4_utils/ext4_utils.h>
Hridya Valsaraju47658ca2018-09-28 11:41:22 -070027#include <healthhalutils/HealthHalUtils.h>
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070028
29#include "fastboot_device.h"
David Anderson12211d12018-07-24 15:21:20 -070030#include "flashing.h"
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070031#include "utility.h"
32
33using ::android::hardware::boot::V1_0::BoolResult;
34using ::android::hardware::boot::V1_0::Slot;
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -070035using ::android::hardware::fastboot::V1_0::FileSystemType;
36using ::android::hardware::fastboot::V1_0::Result;
37using ::android::hardware::fastboot::V1_0::Status;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070038
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070039constexpr char kFastbootProtocolVersion[] = "0.4";
40
David Anderson1fb3fd72018-08-31 14:40:22 -070041bool GetVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
42 std::string* message) {
43 *message = kFastbootProtocolVersion;
44 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070045}
46
David Anderson1fb3fd72018-08-31 14:40:22 -070047bool GetBootloaderVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
48 std::string* message) {
49 *message = android::base::GetProperty("ro.bootloader", "");
50 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070051}
52
David Anderson1fb3fd72018-08-31 14:40:22 -070053bool GetBasebandVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
54 std::string* message) {
55 *message = android::base::GetProperty("ro.build.expect.baseband", "");
56 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070057}
58
David Anderson1fb3fd72018-08-31 14:40:22 -070059bool GetProduct(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
60 std::string* message) {
61 *message = android::base::GetProperty("ro.product.device", "");
62 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070063}
64
David Anderson1fb3fd72018-08-31 14:40:22 -070065bool GetSerial(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
66 std::string* message) {
67 *message = android::base::GetProperty("ro.serialno", "");
68 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070069}
70
David Anderson1fb3fd72018-08-31 14:40:22 -070071bool GetSecure(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
72 std::string* message) {
73 *message = android::base::GetBoolProperty("ro.secure", "") ? "yes" : "no";
74 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070075}
76
Hridya Valsaraju4af80902018-09-26 13:08:16 -070077bool GetVariant(FastbootDevice* device, const std::vector<std::string>& /* args */,
78 std::string* message) {
79 auto fastboot_hal = device->fastboot_hal();
80 if (!fastboot_hal) {
81 *message = "Fastboot HAL not found";
82 return false;
83 }
84
85 Result ret;
86 auto ret_val = fastboot_hal->getVariant([&](std::string device_variant, Result result) {
87 *message = device_variant;
88 ret = result;
89 });
90 if (!ret_val.isOk() || ret.status != Status::SUCCESS) {
91 *message = "Unable to get device variant";
92 return false;
93 }
94
95 return true;
96}
97
Hridya Valsarajua534a5a2018-10-03 15:53:22 -070098bool GetBatteryVoltageHelper(FastbootDevice* device, int32_t* battery_voltage) {
99 using android::hardware::health::V2_0::HealthInfo;
100 using android::hardware::health::V2_0::Result;
101
102 auto health_hal = device->health_hal();
103 if (!health_hal) {
104 return false;
105 }
106
107 Result ret;
108 auto ret_val = health_hal->getHealthInfo([&](Result result, HealthInfo info) {
109 *battery_voltage = info.legacy.batteryVoltage;
110 ret = result;
111 });
112 if (!ret_val.isOk() || (ret != Result::SUCCESS)) {
113 return false;
114 }
115
116 return true;
117}
118
119bool GetBatterySoCOk(FastbootDevice* device, const std::vector<std::string>& /* args */,
120 std::string* message) {
121 int32_t battery_voltage = 0;
122 if (!GetBatteryVoltageHelper(device, &battery_voltage)) {
123 *message = "Unable to read battery voltage";
124 return false;
125 }
126
127 auto fastboot_hal = device->fastboot_hal();
128 if (!fastboot_hal) {
129 *message = "Fastboot HAL not found";
130 return false;
131 }
132
133 Result ret;
134 auto ret_val = fastboot_hal->getBatteryVoltageFlashingThreshold(
135 [&](int32_t voltage_threshold, Result result) {
136 *message = battery_voltage >= voltage_threshold ? "yes" : "no";
137 ret = result;
138 });
139
140 if (!ret_val.isOk() || ret.status != Status::SUCCESS) {
141 *message = "Unable to get battery voltage flashing threshold";
142 return false;
143 }
144
145 return true;
146}
147
Hridya Valsaraju7c9bbe92018-09-27 10:41:01 -0700148bool GetOffModeChargeState(FastbootDevice* device, const std::vector<std::string>& /* args */,
149 std::string* message) {
150 auto fastboot_hal = device->fastboot_hal();
151 if (!fastboot_hal) {
152 *message = "Fastboot HAL not found";
153 return false;
154 }
155
156 Result ret;
157 auto ret_val =
158 fastboot_hal->getOffModeChargeState([&](bool off_mode_charging_state, Result result) {
159 *message = off_mode_charging_state ? "1" : "0";
160 ret = result;
161 });
162 if (!ret_val.isOk() || (ret.status != Status::SUCCESS)) {
163 *message = "Unable to get off mode charge state";
164 return false;
165 }
166
167 return true;
168}
169
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700170bool GetBatteryVoltage(FastbootDevice* device, const std::vector<std::string>& /* args */,
171 std::string* message) {
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700172 int32_t battery_voltage = 0;
173 if (GetBatteryVoltageHelper(device, &battery_voltage)) {
174 *message = std::to_string(battery_voltage);
175 return true;
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700176 }
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700177 *message = "Unable to get battery voltage";
178 return false;
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700179}
180
David Anderson1fb3fd72018-08-31 14:40:22 -0700181bool GetCurrentSlot(FastbootDevice* device, const std::vector<std::string>& /* args */,
182 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700183 std::string suffix = device->GetCurrentSlot();
David Anderson1fb3fd72018-08-31 14:40:22 -0700184 *message = suffix.size() == 2 ? suffix.substr(1) : suffix;
185 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700186}
187
David Anderson1fb3fd72018-08-31 14:40:22 -0700188bool GetSlotCount(FastbootDevice* device, const std::vector<std::string>& /* args */,
189 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700190 auto boot_control_hal = device->boot_control_hal();
191 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700192 *message = "0";
193 } else {
194 *message = std::to_string(boot_control_hal->getNumberSlots());
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700195 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700196 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700197}
198
David Anderson1fb3fd72018-08-31 14:40:22 -0700199bool GetSlotSuccessful(FastbootDevice* device, const std::vector<std::string>& args,
200 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700201 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700202 *message = "Missing argument";
203 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700204 }
205 Slot slot;
206 if (!GetSlotNumber(args[0], &slot)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700207 *message = "Invalid slot";
208 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700209 }
210 auto boot_control_hal = device->boot_control_hal();
211 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700212 *message = "Device has no slots";
213 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700214 }
David Anderson856b7ec2018-08-08 17:58:56 -0700215 if (boot_control_hal->isSlotMarkedSuccessful(slot) != BoolResult::TRUE) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700216 *message = "no";
217 } else {
218 *message = "yes";
David Anderson856b7ec2018-08-08 17:58:56 -0700219 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700220 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700221}
222
David Anderson1fb3fd72018-08-31 14:40:22 -0700223bool GetSlotUnbootable(FastbootDevice* device, const std::vector<std::string>& args,
224 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700225 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700226 *message = "Missing argument";
227 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700228 }
229 Slot slot;
230 if (!GetSlotNumber(args[0], &slot)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700231 *message = "Invalid slot";
232 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700233 }
234 auto boot_control_hal = device->boot_control_hal();
235 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700236 *message = "Device has no slots";
237 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700238 }
David Anderson856b7ec2018-08-08 17:58:56 -0700239 if (boot_control_hal->isSlotBootable(slot) != BoolResult::TRUE) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700240 *message = "yes";
241 } else {
242 *message = "no";
David Anderson856b7ec2018-08-08 17:58:56 -0700243 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700244 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700245}
246
David Anderson1fb3fd72018-08-31 14:40:22 -0700247bool GetMaxDownloadSize(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
248 std::string* message) {
David Anderson28b81cd2018-09-04 16:51:29 -0700249 *message = android::base::StringPrintf("0x%X", kMaxDownloadSizeDefault);
David Anderson1fb3fd72018-08-31 14:40:22 -0700250 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700251}
252
David Anderson1fb3fd72018-08-31 14:40:22 -0700253bool GetUnlocked(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
254 std::string* message) {
Hridya Valsarajudca328d2018-09-24 16:01:35 -0700255 *message = GetDeviceLockStatus() ? "no" : "yes";
David Anderson1fb3fd72018-08-31 14:40:22 -0700256 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700257}
258
David Anderson1fb3fd72018-08-31 14:40:22 -0700259bool GetHasSlot(FastbootDevice* device, const std::vector<std::string>& args,
260 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700261 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700262 *message = "Missing argument";
263 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700264 }
265 std::string slot_suffix = device->GetCurrentSlot();
266 if (slot_suffix.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700267 *message = "no";
268 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700269 }
David Anderson79ab0e32018-08-14 16:21:50 -0700270 std::string partition_name = args[0] + slot_suffix;
271 if (FindPhysicalPartition(partition_name) ||
272 LogicalPartitionExists(partition_name, slot_suffix)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700273 *message = "yes";
274 } else {
275 *message = "no";
David Anderson79ab0e32018-08-14 16:21:50 -0700276 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700277 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700278}
David Anderson12211d12018-07-24 15:21:20 -0700279
David Anderson1fb3fd72018-08-31 14:40:22 -0700280bool GetPartitionSize(FastbootDevice* device, const std::vector<std::string>& args,
281 std::string* message) {
David Anderson12211d12018-07-24 15:21:20 -0700282 if (args.size() < 1) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700283 *message = "Missing argument";
284 return false;
David Anderson12211d12018-07-24 15:21:20 -0700285 }
David Anderson88ef0b12018-08-09 10:40:00 -0700286 // Zero-length partitions cannot be created through device-mapper, so we
287 // special case them here.
288 bool is_zero_length;
289 if (LogicalPartitionExists(args[0], device->GetCurrentSlot(), &is_zero_length) &&
290 is_zero_length) {
Hridya Valsaraju2a377da2018-10-09 10:03:51 -0700291 *message = "0x0";
David Anderson1fb3fd72018-08-31 14:40:22 -0700292 return true;
David Anderson88ef0b12018-08-09 10:40:00 -0700293 }
294 // Otherwise, open the partition as normal.
David Anderson12211d12018-07-24 15:21:20 -0700295 PartitionHandle handle;
296 if (!OpenPartition(device, args[0], &handle)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700297 *message = "Could not open partition";
298 return false;
David Anderson12211d12018-07-24 15:21:20 -0700299 }
300 uint64_t size = get_block_device_size(handle.fd());
David Anderson47589672018-09-04 16:22:41 -0700301 *message = android::base::StringPrintf("0x%" PRIX64, size);
David Anderson1fb3fd72018-08-31 14:40:22 -0700302 return true;
David Anderson12211d12018-07-24 15:21:20 -0700303}
David Anderson0d4277d2018-07-31 13:27:37 -0700304
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700305bool GetPartitionType(FastbootDevice* device, const std::vector<std::string>& args,
306 std::string* message) {
307 if (args.size() < 1) {
308 *message = "Missing argument";
309 return false;
310 }
Hridya Valsaraju4165e002018-10-09 10:40:35 -0700311
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700312 std::string partition_name = args[0];
Hridya Valsaraju4165e002018-10-09 10:40:35 -0700313 if (!FindPhysicalPartition(partition_name) &&
314 !LogicalPartitionExists(partition_name, device->GetCurrentSlot())) {
315 *message = "Invalid partition";
316 return false;
317 }
318
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700319 auto fastboot_hal = device->fastboot_hal();
320 if (!fastboot_hal) {
321 *message = "Fastboot HAL not found";
322 return false;
323 }
324
325 FileSystemType type;
326 Result ret;
327 auto ret_val =
328 fastboot_hal->getPartitionType(args[0], [&](FileSystemType fs_type, Result result) {
329 type = fs_type;
330 ret = result;
331 });
332 if (!ret_val.isOk() || (ret.status != Status::SUCCESS)) {
333 *message = "Unable to retrieve partition type";
334 } else {
335 switch (type) {
336 case FileSystemType::RAW:
337 *message = "raw";
338 return true;
339 case FileSystemType::EXT4:
340 *message = "ext4";
341 return true;
342 case FileSystemType::F2FS:
343 *message = "f2fs";
344 return true;
345 default:
346 *message = "Unknown file system type";
347 }
348 }
349
350 return false;
351}
352
David Anderson1fb3fd72018-08-31 14:40:22 -0700353bool GetPartitionIsLogical(FastbootDevice* device, const std::vector<std::string>& args,
354 std::string* message) {
David Anderson0d4277d2018-07-31 13:27:37 -0700355 if (args.size() < 1) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700356 *message = "Missing argument";
357 return false;
David Anderson0d4277d2018-07-31 13:27:37 -0700358 }
359 // Note: if a partition name is in both the GPT and the super partition, we
360 // return "true", to be consistent with prefering to flash logical partitions
361 // over physical ones.
362 std::string partition_name = args[0];
363 if (LogicalPartitionExists(partition_name, device->GetCurrentSlot())) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700364 *message = "yes";
365 return true;
David Anderson0d4277d2018-07-31 13:27:37 -0700366 }
367 if (FindPhysicalPartition(partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700368 *message = "no";
369 return true;
David Anderson0d4277d2018-07-31 13:27:37 -0700370 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700371 *message = "Partition not found";
372 return false;
David Anderson0d4277d2018-07-31 13:27:37 -0700373}
David Andersond9ba0612018-08-02 11:05:00 -0700374
David Anderson1fb3fd72018-08-31 14:40:22 -0700375bool GetIsUserspace(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
376 std::string* message) {
377 *message = "yes";
378 return true;
David Andersond9ba0612018-08-02 11:05:00 -0700379}
David Anderson0f626632018-08-31 16:44:25 -0700380
381std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device) {
382 std::vector<std::vector<std::string>> args;
383 auto partitions = ListPartitions(device);
384 for (const auto& partition : partitions) {
385 args.emplace_back(std::initializer_list<std::string>{partition});
386 }
387 return args;
388}
389
390std::vector<std::vector<std::string>> GetAllPartitionArgsNoSlot(FastbootDevice* device) {
391 auto partitions = ListPartitions(device);
392
393 std::string slot_suffix = device->GetCurrentSlot();
394 if (!slot_suffix.empty()) {
395 auto names = std::move(partitions);
396 for (const auto& name : names) {
397 std::string slotless_name = name;
398 if (android::base::EndsWith(name, "_a") || android::base::EndsWith(name, "_b")) {
399 slotless_name = name.substr(0, name.rfind("_"));
400 }
401 if (std::find(partitions.begin(), partitions.end(), slotless_name) ==
402 partitions.end()) {
403 partitions.emplace_back(slotless_name);
404 }
405 }
406 }
407
408 std::vector<std::vector<std::string>> args;
409 for (const auto& partition : partitions) {
410 args.emplace_back(std::initializer_list<std::string>{partition});
411 }
412 return args;
413}
David Andersonc091c172018-09-04 18:11:03 -0700414
415bool GetHardwareRevision(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
416 std::string* message) {
417 *message = android::base::GetProperty("ro.revision", "");
418 return true;
419}