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