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