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