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 "variables.h"
18
19 #include <inttypes.h>
20 #include <stdio.h>
21
22 #include <android-base/file.h>
23 #include <android-base/logging.h>
24 #include <android-base/properties.h>
25 #include <android-base/stringprintf.h>
26 #include <android-base/strings.h>
27 #include <android/hardware/boot/1.1/IBootControl.h>
28 #include <ext4_utils/ext4_utils.h>
29 #include <fs_mgr.h>
30 #include <liblp/liblp.h>
31
32 #include "BootControlClient.h"
33 #include "fastboot_device.h"
34 #include "flashing.h"
35 #include "utility.h"
36
37 #ifdef FB_ENABLE_FETCH
38 static constexpr bool kEnableFetch = true;
39 #else
40 static constexpr bool kEnableFetch = false;
41 #endif
42
43 using MergeStatus = android::hal::BootControlClient::MergeStatus;
44 using aidl::android::hardware::fastboot::FileSystemType;
45 using namespace android::fs_mgr;
46 using namespace std::string_literals;
47
48 constexpr char kFastbootProtocolVersion[] = "0.4";
49
GetVersion(FastbootDevice *,const std::vector<std::string> &,std::string * message)50 bool GetVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
51 std::string* message) {
52 *message = kFastbootProtocolVersion;
53 return true;
54 }
55
GetBootloaderVersion(FastbootDevice *,const std::vector<std::string> &,std::string * message)56 bool GetBootloaderVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
57 std::string* message) {
58 *message = android::base::GetProperty("ro.bootloader", "");
59 return true;
60 }
61
GetBasebandVersion(FastbootDevice *,const std::vector<std::string> &,std::string * message)62 bool GetBasebandVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
63 std::string* message) {
64 *message = android::base::GetProperty("ro.build.expect.baseband", "");
65 return true;
66 }
67
GetOsVersion(FastbootDevice *,const std::vector<std::string> &,std::string * message)68 bool GetOsVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
69 std::string* message) {
70 *message = android::base::GetProperty("ro.build.version.release", "");
71 return true;
72 }
73
GetVndkVersion(FastbootDevice *,const std::vector<std::string> &,std::string * message)74 bool GetVndkVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
75 std::string* message) {
76 *message = android::base::GetProperty("ro.vndk.version", "");
77 return true;
78 }
79
GetProduct(FastbootDevice *,const std::vector<std::string> &,std::string * message)80 bool GetProduct(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
81 std::string* message) {
82 *message = android::base::GetProperty("ro.product.device", "");
83 return true;
84 }
85
GetSerial(FastbootDevice *,const std::vector<std::string> &,std::string * message)86 bool GetSerial(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
87 std::string* message) {
88 *message = android::base::GetProperty("ro.serialno", "");
89 return true;
90 }
91
GetSecure(FastbootDevice *,const std::vector<std::string> &,std::string * message)92 bool GetSecure(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
93 std::string* message) {
94 *message = android::base::GetBoolProperty("ro.secure", "") ? "yes" : "no";
95 return true;
96 }
97
GetVariant(FastbootDevice * device,const std::vector<std::string> &,std::string * message)98 bool GetVariant(FastbootDevice* device, const std::vector<std::string>& /* args */,
99 std::string* message) {
100 auto fastboot_hal = device->fastboot_hal();
101 if (!fastboot_hal) {
102 *message = "Fastboot HAL not found";
103 return false;
104 }
105 std::string device_variant = "";
106 auto status = fastboot_hal->getVariant(&device_variant);
107
108 if (!status.isOk()) {
109 *message = "Unable to get device variant";
110 LOG(ERROR) << message->c_str() << status.getDescription();
111 return false;
112 }
113
114 *message = device_variant;
115 return true;
116 }
117
GetBatteryVoltageHelper(FastbootDevice * device,int32_t * battery_voltage)118 bool GetBatteryVoltageHelper(FastbootDevice* device, int32_t* battery_voltage) {
119 using aidl::android::hardware::health::HealthInfo;
120
121 auto health_hal = device->health_hal();
122 if (!health_hal) {
123 return false;
124 }
125
126 HealthInfo health_info;
127 auto res = health_hal->getHealthInfo(&health_info);
128 if (!res.isOk()) return false;
129 *battery_voltage = health_info.batteryVoltageMillivolts;
130 return true;
131 }
132
GetBatterySoCOk(FastbootDevice * device,const std::vector<std::string> &,std::string * message)133 bool GetBatterySoCOk(FastbootDevice* device, const std::vector<std::string>& /* args */,
134 std::string* message) {
135 int32_t battery_voltage = 0;
136 if (!GetBatteryVoltageHelper(device, &battery_voltage)) {
137 *message = "Unable to read battery voltage";
138 return false;
139 }
140
141 auto fastboot_hal = device->fastboot_hal();
142 if (!fastboot_hal) {
143 *message = "Fastboot HAL not found";
144 return false;
145 }
146
147 auto voltage_threshold = 0;
148 auto status = fastboot_hal->getBatteryVoltageFlashingThreshold(&voltage_threshold);
149 if (!status.isOk()) {
150 *message = "Unable to get battery voltage flashing threshold";
151 LOG(ERROR) << message->c_str() << status.getDescription();
152 return false;
153 }
154 *message = battery_voltage >= voltage_threshold ? "yes" : "no";
155
156 return true;
157 }
158
GetOffModeChargeState(FastbootDevice * device,const std::vector<std::string> &,std::string * message)159 bool GetOffModeChargeState(FastbootDevice* device, const std::vector<std::string>& /* args */,
160 std::string* message) {
161 auto fastboot_hal = device->fastboot_hal();
162 if (!fastboot_hal) {
163 *message = "Fastboot HAL not found";
164 return false;
165 }
166 bool off_mode_charging_state = false;
167 auto status = fastboot_hal->getOffModeChargeState(&off_mode_charging_state);
168 if (!status.isOk()) {
169 *message = "Unable to get off mode charge state";
170 LOG(ERROR) << message->c_str() << status.getDescription();
171 return false;
172 }
173 *message = off_mode_charging_state ? "1" : "0";
174 return true;
175 }
176
GetBatteryVoltage(FastbootDevice * device,const std::vector<std::string> &,std::string * message)177 bool GetBatteryVoltage(FastbootDevice* device, const std::vector<std::string>& /* args */,
178 std::string* message) {
179 int32_t battery_voltage = 0;
180 if (GetBatteryVoltageHelper(device, &battery_voltage)) {
181 *message = std::to_string(battery_voltage);
182 return true;
183 }
184 *message = "Unable to get battery voltage";
185 return false;
186 }
187
GetCurrentSlot(FastbootDevice * device,const std::vector<std::string> &,std::string * message)188 bool GetCurrentSlot(FastbootDevice* device, const std::vector<std::string>& /* args */,
189 std::string* message) {
190 std::string suffix = device->GetCurrentSlot();
191 *message = suffix.size() == 2 ? suffix.substr(1) : suffix;
192 return true;
193 }
194
GetSlotCount(FastbootDevice * device,const std::vector<std::string> &,std::string * message)195 bool GetSlotCount(FastbootDevice* device, const std::vector<std::string>& /* args */,
196 std::string* message) {
197 auto boot_control_hal = device->boot_control_hal();
198 if (!boot_control_hal) {
199 *message = "0";
200 } else {
201 *message = std::to_string(boot_control_hal->GetNumSlots());
202 }
203 return true;
204 }
205
GetSlotSuccessful(FastbootDevice * device,const std::vector<std::string> & args,std::string * message)206 bool GetSlotSuccessful(FastbootDevice* device, const std::vector<std::string>& args,
207 std::string* message) {
208 if (args.empty()) {
209 *message = "Missing argument";
210 return false;
211 }
212 int32_t slot = -1;
213 if (!GetSlotNumber(args[0], &slot)) {
214 *message = "Invalid slot";
215 return false;
216 }
217 auto boot_control_hal = device->boot_control_hal();
218 if (!boot_control_hal) {
219 *message = "Device has no slots";
220 return false;
221 }
222 if (boot_control_hal->IsSlotMarkedSuccessful(slot).value_or(false)) {
223 *message = "no";
224 } else {
225 *message = "yes";
226 }
227 return true;
228 }
229
GetSlotUnbootable(FastbootDevice * device,const std::vector<std::string> & args,std::string * message)230 bool GetSlotUnbootable(FastbootDevice* device, const std::vector<std::string>& args,
231 std::string* message) {
232 if (args.empty()) {
233 *message = "Missing argument";
234 return false;
235 }
236 int32_t slot = -1;
237 if (!GetSlotNumber(args[0], &slot)) {
238 *message = "Invalid slot";
239 return false;
240 }
241 auto boot_control_hal = device->boot_control_hal();
242 if (!boot_control_hal) {
243 *message = "Device has no slots";
244 return false;
245 }
246 if (!boot_control_hal->IsSlotBootable(slot).value_or(false)) {
247 *message = "yes";
248 } else {
249 *message = "no";
250 }
251 return true;
252 }
253
GetMaxDownloadSize(FastbootDevice *,const std::vector<std::string> &,std::string * message)254 bool GetMaxDownloadSize(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
255 std::string* message) {
256 *message = android::base::StringPrintf("0x%X", kMaxDownloadSizeDefault);
257 return true;
258 }
259
GetUnlocked(FastbootDevice *,const std::vector<std::string> &,std::string * message)260 bool GetUnlocked(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
261 std::string* message) {
262 *message = GetDeviceLockStatus() ? "no" : "yes";
263 return true;
264 }
265
GetHasSlot(FastbootDevice * device,const std::vector<std::string> & args,std::string * message)266 bool GetHasSlot(FastbootDevice* device, const std::vector<std::string>& args,
267 std::string* message) {
268 if (args.empty()) {
269 *message = "Missing argument";
270 return false;
271 }
272 std::string slot_suffix = device->GetCurrentSlot();
273 if (slot_suffix.empty()) {
274 *message = "no";
275 return true;
276 }
277 std::string partition_name = args[0] + slot_suffix;
278 if (FindPhysicalPartition(partition_name) || LogicalPartitionExists(device, partition_name)) {
279 *message = "yes";
280 } else {
281 *message = "no";
282 }
283 return true;
284 }
285
GetPartitionSize(FastbootDevice * device,const std::vector<std::string> & args,std::string * message)286 bool GetPartitionSize(FastbootDevice* device, const std::vector<std::string>& args,
287 std::string* message) {
288 if (args.size() < 1) {
289 *message = "Missing argument";
290 return false;
291 }
292 // Zero-length partitions cannot be created through device-mapper, so we
293 // special case them here.
294 bool is_zero_length;
295 if (LogicalPartitionExists(device, args[0], &is_zero_length) && is_zero_length) {
296 *message = "0x0";
297 return true;
298 }
299 // Otherwise, open the partition as normal.
300 PartitionHandle handle;
301 if (!OpenPartition(device, args[0], &handle)) {
302 *message = "Could not open partition";
303 return false;
304 }
305 uint64_t size = get_block_device_size(handle.fd());
306 *message = android::base::StringPrintf("0x%" PRIX64, size);
307 return true;
308 }
309
GetPartitionType(FastbootDevice * device,const std::vector<std::string> & args,std::string * message)310 bool GetPartitionType(FastbootDevice* device, const std::vector<std::string>& args,
311 std::string* message) {
312 if (args.size() < 1) {
313 *message = "Missing argument";
314 return false;
315 }
316
317 std::string partition_name = args[0];
318 if (!FindPhysicalPartition(partition_name) && !LogicalPartitionExists(device, partition_name)) {
319 *message = "Invalid partition";
320 return false;
321 }
322
323 auto fastboot_hal = device->fastboot_hal();
324 if (!fastboot_hal) {
325 *message = "raw";
326 return true;
327 }
328
329 FileSystemType type;
330 auto status = fastboot_hal->getPartitionType(args[0], &type);
331
332 if (!status.isOk()) {
333 *message = "Unable to retrieve partition type";
334 LOG(ERROR) << message->c_str() << status.getDescription();
335 } else {
336 switch (type) {
337 case FileSystemType::RAW:
338 *message = "raw";
339 return true;
340 case FileSystemType::EXT4:
341 *message = "ext4";
342 return true;
343 case FileSystemType::F2FS:
344 *message = "f2fs";
345 return true;
346 default:
347 *message = "Unknown file system type";
348 }
349 }
350
351 return false;
352 }
353
GetPartitionIsLogical(FastbootDevice * device,const std::vector<std::string> & args,std::string * message)354 bool GetPartitionIsLogical(FastbootDevice* device, const std::vector<std::string>& args,
355 std::string* message) {
356 if (args.size() < 1) {
357 *message = "Missing argument";
358 return false;
359 }
360 // Note: if a partition name is in both the GPT and the super partition, we
361 // return "true", to be consistent with prefering to flash logical partitions
362 // over physical ones.
363 std::string partition_name = args[0];
364 if (LogicalPartitionExists(device, partition_name)) {
365 *message = "yes";
366 return true;
367 }
368 if (FindPhysicalPartition(partition_name)) {
369 *message = "no";
370 return true;
371 }
372 *message = "Partition not found";
373 return false;
374 }
375
GetIsUserspace(FastbootDevice *,const std::vector<std::string> &,std::string * message)376 bool GetIsUserspace(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
377 std::string* message) {
378 *message = "yes";
379 return true;
380 }
381
GetIsForceDebuggable(FastbootDevice *,const std::vector<std::string> &,std::string * message)382 bool GetIsForceDebuggable(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
383 std::string* message) {
384 *message = android::base::GetBoolProperty("ro.force.debuggable", false) ? "yes" : "no";
385 return true;
386 }
387
GetAllPartitionArgsWithSlot(FastbootDevice * device)388 std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device) {
389 std::vector<std::vector<std::string>> args;
390 auto partitions = ListPartitions(device);
391 for (const auto& partition : partitions) {
392 args.emplace_back(std::initializer_list<std::string>{partition});
393 }
394 return args;
395 }
396
GetAllPartitionArgsNoSlot(FastbootDevice * device)397 std::vector<std::vector<std::string>> GetAllPartitionArgsNoSlot(FastbootDevice* device) {
398 auto partitions = ListPartitions(device);
399
400 std::string slot_suffix = device->GetCurrentSlot();
401 if (!slot_suffix.empty()) {
402 auto names = std::move(partitions);
403 for (const auto& name : names) {
404 std::string slotless_name = name;
405 if (android::base::EndsWith(name, "_a") || android::base::EndsWith(name, "_b")) {
406 slotless_name = name.substr(0, name.rfind("_"));
407 }
408 if (std::find(partitions.begin(), partitions.end(), slotless_name) ==
409 partitions.end()) {
410 partitions.emplace_back(slotless_name);
411 }
412 }
413 }
414
415 std::vector<std::vector<std::string>> args;
416 for (const auto& partition : partitions) {
417 args.emplace_back(std::initializer_list<std::string>{partition});
418 }
419 return args;
420 }
421
GetHardwareRevision(FastbootDevice *,const std::vector<std::string> &,std::string * message)422 bool GetHardwareRevision(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
423 std::string* message) {
424 *message = android::base::GetProperty("ro.revision", "");
425 return true;
426 }
427
GetSuperPartitionName(FastbootDevice * device,const std::vector<std::string> &,std::string * message)428 bool GetSuperPartitionName(FastbootDevice* device, const std::vector<std::string>& /* args */,
429 std::string* message) {
430 uint32_t slot_number = SlotNumberForSlotSuffix(device->GetCurrentSlot());
431 *message = fs_mgr_get_super_partition_name(slot_number);
432 return true;
433 }
434
GetSnapshotUpdateStatus(FastbootDevice * device,const std::vector<std::string> &,std::string * message)435 bool GetSnapshotUpdateStatus(FastbootDevice* device, const std::vector<std::string>& /* args */,
436 std::string* message) {
437 // Note that we use the HAL rather than mounting /metadata, since we want
438 // our results to match the bootloader.
439 auto hal = device->boot1_1();
440 if (!hal) {
441 *message = "not supported";
442 return false;
443 }
444
445 MergeStatus status = hal->getSnapshotMergeStatus();
446 switch (status) {
447 case MergeStatus::SNAPSHOTTED:
448 *message = "snapshotted";
449 break;
450 case MergeStatus::MERGING:
451 *message = "merging";
452 break;
453 default:
454 *message = "none";
455 break;
456 }
457 return true;
458 }
459
GetCpuAbi(FastbootDevice *,const std::vector<std::string> &,std::string * message)460 bool GetCpuAbi(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
461 std::string* message) {
462 *message = android::base::GetProperty("ro.product.cpu.abi", "");
463 return true;
464 }
465
GetSystemFingerprint(FastbootDevice *,const std::vector<std::string> &,std::string * message)466 bool GetSystemFingerprint(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
467 std::string* message) {
468 *message = android::base::GetProperty("ro.system.build.fingerprint", "");
469 if (message->empty()) {
470 *message = android::base::GetProperty("ro.build.fingerprint", "");
471 }
472 return true;
473 }
474
GetVendorFingerprint(FastbootDevice *,const std::vector<std::string> &,std::string * message)475 bool GetVendorFingerprint(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
476 std::string* message) {
477 *message = android::base::GetProperty("ro.vendor.build.fingerprint", "");
478 return true;
479 }
480
GetDynamicPartition(FastbootDevice *,const std::vector<std::string> &,std::string * message)481 bool GetDynamicPartition(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
482 std::string* message) {
483 *message = android::base::GetProperty("ro.boot.dynamic_partitions", "");
484 return true;
485 }
486
GetFirstApiLevel(FastbootDevice *,const std::vector<std::string> &,std::string * message)487 bool GetFirstApiLevel(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
488 std::string* message) {
489 *message = android::base::GetProperty("ro.product.first_api_level", "");
490 return true;
491 }
492
GetSecurityPatchLevel(FastbootDevice *,const std::vector<std::string> &,std::string * message)493 bool GetSecurityPatchLevel(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
494 std::string* message) {
495 *message = android::base::GetProperty("ro.build.version.security_patch", "");
496 return true;
497 }
498
GetTrebleEnabled(FastbootDevice *,const std::vector<std::string> &,std::string * message)499 bool GetTrebleEnabled(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
500 std::string* message) {
501 *message = android::base::GetProperty("ro.treble.enabled", "");
502 return true;
503 }
504
GetMaxFetchSize(FastbootDevice *,const std::vector<std::string> &,std::string * message)505 bool GetMaxFetchSize(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
506 std::string* message) {
507 if (!kEnableFetch) {
508 *message = "fetch not supported on user builds";
509 return false;
510 }
511 *message = android::base::StringPrintf("0x%X", kMaxFetchSizeDefault);
512 return true;
513 }
514
GetDmesg(FastbootDevice * device)515 bool GetDmesg(FastbootDevice* device) {
516 if (GetDeviceLockStatus()) {
517 return device->WriteFail("Cannot use when device flashing is locked");
518 }
519
520 std::unique_ptr<FILE, decltype(&::fclose)> fp(popen("/system/bin/dmesg", "re"), ::fclose);
521 if (!fp) {
522 PLOG(ERROR) << "popen /system/bin/dmesg";
523 return device->WriteFail("Unable to run dmesg: "s + strerror(errno));
524 }
525
526 ssize_t rv;
527 size_t n = 0;
528 char* str = nullptr;
529 while ((rv = ::getline(&str, &n, fp.get())) > 0) {
530 if (str[rv - 1] == '\n') {
531 rv--;
532 }
533 device->WriteInfo(std::string(str, rv));
534 }
535
536 int saved_errno = errno;
537 ::free(str);
538
539 if (rv < 0 && saved_errno) {
540 LOG(ERROR) << "dmesg getline: " << strerror(saved_errno);
541 device->WriteFail("Unable to read dmesg: "s + strerror(saved_errno));
542 return false;
543 }
544
545 return true;
546 }
547