• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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