blob: 0de00b1f66cdd4b9f623d1eee30cffe2b6859396 [file] [log] [blame]
Hridya Valsaraju31d2c262018-07-20 13:35:50 -07001/*
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
David Anderson12211d12018-07-24 15:21:20 -070019#include <inttypes.h>
David Andersonebc8fe12022-06-17 19:17:43 -070020#include <stdio.h>
David Anderson12211d12018-07-24 15:21:20 -070021
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070022#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>
David Andersonab8f4662019-10-21 16:45:59 -070027#include <android/hardware/boot/1.1/IBootControl.h>
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070028#include <ext4_utils/ext4_utils.h>
David Anderson90fe0a42018-11-05 18:01:32 -080029#include <fs_mgr.h>
David Anderson90fe0a42018-11-05 18:01:32 -080030#include <liblp/liblp.h>
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070031
David Andersonebc8fe12022-06-17 19:17:43 -070032#include "constants.h"
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070033#include "fastboot_device.h"
David Anderson12211d12018-07-24 15:21:20 -070034#include "flashing.h"
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070035#include "utility.h"
36
Yifan Hongb299cb72021-02-17 13:44:49 -080037#ifdef FB_ENABLE_FETCH
38static constexpr bool kEnableFetch = true;
39#else
40static constexpr bool kEnableFetch = false;
41#endif
42
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070043using ::android::hardware::boot::V1_0::BoolResult;
44using ::android::hardware::boot::V1_0::Slot;
David Andersonab8f4662019-10-21 16:45:59 -070045using ::android::hardware::boot::V1_1::MergeStatus;
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -070046using ::android::hardware::fastboot::V1_0::FileSystemType;
47using ::android::hardware::fastboot::V1_0::Result;
48using ::android::hardware::fastboot::V1_0::Status;
David Andersonab8f4662019-10-21 16:45:59 -070049using IBootControl1_1 = ::android::hardware::boot::V1_1::IBootControl;
David Anderson90fe0a42018-11-05 18:01:32 -080050using namespace android::fs_mgr;
David Andersonebc8fe12022-06-17 19:17:43 -070051using namespace std::string_literals;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070052
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070053constexpr char kFastbootProtocolVersion[] = "0.4";
54
David Anderson1fb3fd72018-08-31 14:40:22 -070055bool GetVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
56 std::string* message) {
57 *message = kFastbootProtocolVersion;
58 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070059}
60
David Anderson1fb3fd72018-08-31 14:40:22 -070061bool GetBootloaderVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
62 std::string* message) {
63 *message = android::base::GetProperty("ro.bootloader", "");
64 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070065}
66
David Anderson1fb3fd72018-08-31 14:40:22 -070067bool GetBasebandVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
68 std::string* message) {
69 *message = android::base::GetProperty("ro.build.expect.baseband", "");
70 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070071}
72
Bowgo Tsai99f9a382020-01-21 18:31:23 +080073bool GetOsVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
74 std::string* message) {
75 *message = android::base::GetProperty("ro.build.version.release", "");
76 return true;
77}
78
79bool GetVndkVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
80 std::string* message) {
81 *message = android::base::GetProperty("ro.vndk.version", "");
82 return true;
83}
84
David Anderson1fb3fd72018-08-31 14:40:22 -070085bool GetProduct(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
86 std::string* message) {
87 *message = android::base::GetProperty("ro.product.device", "");
88 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070089}
90
David Anderson1fb3fd72018-08-31 14:40:22 -070091bool GetSerial(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
92 std::string* message) {
93 *message = android::base::GetProperty("ro.serialno", "");
94 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070095}
96
David Anderson1fb3fd72018-08-31 14:40:22 -070097bool GetSecure(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
98 std::string* message) {
99 *message = android::base::GetBoolProperty("ro.secure", "") ? "yes" : "no";
100 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700101}
102
Hridya Valsaraju4af80902018-09-26 13:08:16 -0700103bool GetVariant(FastbootDevice* device, const std::vector<std::string>& /* args */,
104 std::string* message) {
105 auto fastboot_hal = device->fastboot_hal();
106 if (!fastboot_hal) {
107 *message = "Fastboot HAL not found";
108 return false;
109 }
110
111 Result ret;
112 auto ret_val = fastboot_hal->getVariant([&](std::string device_variant, Result result) {
113 *message = device_variant;
114 ret = result;
115 });
116 if (!ret_val.isOk() || ret.status != Status::SUCCESS) {
117 *message = "Unable to get device variant";
118 return false;
119 }
120
121 return true;
122}
123
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700124bool GetBatteryVoltageHelper(FastbootDevice* device, int32_t* battery_voltage) {
Yifan Hong4cb88dc2021-12-02 18:58:02 -0800125 using aidl::android::hardware::health::HealthInfo;
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700126
127 auto health_hal = device->health_hal();
128 if (!health_hal) {
129 return false;
130 }
131
Yifan Hong4cb88dc2021-12-02 18:58:02 -0800132 HealthInfo health_info;
133 auto res = health_hal->getHealthInfo(&health_info);
134 if (!res.isOk()) return false;
135 *battery_voltage = health_info.batteryVoltageMillivolts;
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700136 return true;
137}
138
139bool GetBatterySoCOk(FastbootDevice* device, const std::vector<std::string>& /* args */,
140 std::string* message) {
141 int32_t battery_voltage = 0;
142 if (!GetBatteryVoltageHelper(device, &battery_voltage)) {
143 *message = "Unable to read battery voltage";
144 return false;
145 }
146
147 auto fastboot_hal = device->fastboot_hal();
148 if (!fastboot_hal) {
149 *message = "Fastboot HAL not found";
150 return false;
151 }
152
153 Result ret;
154 auto ret_val = fastboot_hal->getBatteryVoltageFlashingThreshold(
155 [&](int32_t voltage_threshold, Result result) {
156 *message = battery_voltage >= voltage_threshold ? "yes" : "no";
157 ret = result;
158 });
159
160 if (!ret_val.isOk() || ret.status != Status::SUCCESS) {
161 *message = "Unable to get battery voltage flashing threshold";
162 return false;
163 }
164
165 return true;
166}
167
Hridya Valsaraju7c9bbe92018-09-27 10:41:01 -0700168bool GetOffModeChargeState(FastbootDevice* device, const std::vector<std::string>& /* args */,
169 std::string* message) {
170 auto fastboot_hal = device->fastboot_hal();
171 if (!fastboot_hal) {
172 *message = "Fastboot HAL not found";
173 return false;
174 }
175
176 Result ret;
177 auto ret_val =
178 fastboot_hal->getOffModeChargeState([&](bool off_mode_charging_state, Result result) {
179 *message = off_mode_charging_state ? "1" : "0";
180 ret = result;
181 });
182 if (!ret_val.isOk() || (ret.status != Status::SUCCESS)) {
183 *message = "Unable to get off mode charge state";
184 return false;
185 }
186
187 return true;
188}
189
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700190bool GetBatteryVoltage(FastbootDevice* device, const std::vector<std::string>& /* args */,
191 std::string* message) {
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700192 int32_t battery_voltage = 0;
193 if (GetBatteryVoltageHelper(device, &battery_voltage)) {
194 *message = std::to_string(battery_voltage);
195 return true;
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700196 }
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700197 *message = "Unable to get battery voltage";
198 return false;
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700199}
200
David Anderson1fb3fd72018-08-31 14:40:22 -0700201bool GetCurrentSlot(FastbootDevice* device, const std::vector<std::string>& /* args */,
202 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700203 std::string suffix = device->GetCurrentSlot();
David Anderson1fb3fd72018-08-31 14:40:22 -0700204 *message = suffix.size() == 2 ? suffix.substr(1) : suffix;
205 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700206}
207
David Anderson1fb3fd72018-08-31 14:40:22 -0700208bool GetSlotCount(FastbootDevice* device, const std::vector<std::string>& /* args */,
209 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700210 auto boot_control_hal = device->boot_control_hal();
211 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700212 *message = "0";
213 } else {
214 *message = std::to_string(boot_control_hal->getNumberSlots());
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700215 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700216 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700217}
218
David Anderson1fb3fd72018-08-31 14:40:22 -0700219bool GetSlotSuccessful(FastbootDevice* device, const std::vector<std::string>& args,
220 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700221 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700222 *message = "Missing argument";
223 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700224 }
225 Slot slot;
226 if (!GetSlotNumber(args[0], &slot)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700227 *message = "Invalid slot";
228 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700229 }
230 auto boot_control_hal = device->boot_control_hal();
231 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700232 *message = "Device has no slots";
233 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700234 }
David Anderson856b7ec2018-08-08 17:58:56 -0700235 if (boot_control_hal->isSlotMarkedSuccessful(slot) != BoolResult::TRUE) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700236 *message = "no";
237 } else {
238 *message = "yes";
David Anderson856b7ec2018-08-08 17:58:56 -0700239 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700240 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700241}
242
David Anderson1fb3fd72018-08-31 14:40:22 -0700243bool GetSlotUnbootable(FastbootDevice* device, const std::vector<std::string>& args,
244 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700245 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700246 *message = "Missing argument";
247 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700248 }
249 Slot slot;
250 if (!GetSlotNumber(args[0], &slot)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700251 *message = "Invalid slot";
252 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700253 }
254 auto boot_control_hal = device->boot_control_hal();
255 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700256 *message = "Device has no slots";
257 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700258 }
David Anderson856b7ec2018-08-08 17:58:56 -0700259 if (boot_control_hal->isSlotBootable(slot) != BoolResult::TRUE) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700260 *message = "yes";
261 } else {
262 *message = "no";
David Anderson856b7ec2018-08-08 17:58:56 -0700263 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700264 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700265}
266
David Anderson1fb3fd72018-08-31 14:40:22 -0700267bool GetMaxDownloadSize(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
268 std::string* message) {
David Anderson28b81cd2018-09-04 16:51:29 -0700269 *message = android::base::StringPrintf("0x%X", kMaxDownloadSizeDefault);
David Anderson1fb3fd72018-08-31 14:40:22 -0700270 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700271}
272
David Anderson1fb3fd72018-08-31 14:40:22 -0700273bool GetUnlocked(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
274 std::string* message) {
Hridya Valsarajudca328d2018-09-24 16:01:35 -0700275 *message = GetDeviceLockStatus() ? "no" : "yes";
David Anderson1fb3fd72018-08-31 14:40:22 -0700276 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700277}
278
David Anderson1fb3fd72018-08-31 14:40:22 -0700279bool GetHasSlot(FastbootDevice* device, const std::vector<std::string>& args,
280 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700281 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700282 *message = "Missing argument";
283 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700284 }
285 std::string slot_suffix = device->GetCurrentSlot();
286 if (slot_suffix.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700287 *message = "no";
288 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700289 }
David Anderson79ab0e32018-08-14 16:21:50 -0700290 std::string partition_name = args[0] + slot_suffix;
David Andersond25f1c32018-11-09 20:41:33 -0800291 if (FindPhysicalPartition(partition_name) || LogicalPartitionExists(device, partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700292 *message = "yes";
293 } else {
294 *message = "no";
David Anderson79ab0e32018-08-14 16:21:50 -0700295 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700296 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700297}
David Anderson12211d12018-07-24 15:21:20 -0700298
David Anderson1fb3fd72018-08-31 14:40:22 -0700299bool GetPartitionSize(FastbootDevice* device, const std::vector<std::string>& args,
300 std::string* message) {
David Anderson12211d12018-07-24 15:21:20 -0700301 if (args.size() < 1) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700302 *message = "Missing argument";
303 return false;
David Anderson12211d12018-07-24 15:21:20 -0700304 }
David Anderson88ef0b12018-08-09 10:40:00 -0700305 // Zero-length partitions cannot be created through device-mapper, so we
306 // special case them here.
307 bool is_zero_length;
David Andersond25f1c32018-11-09 20:41:33 -0800308 if (LogicalPartitionExists(device, args[0], &is_zero_length) && is_zero_length) {
Hridya Valsaraju2a377da2018-10-09 10:03:51 -0700309 *message = "0x0";
David Anderson1fb3fd72018-08-31 14:40:22 -0700310 return true;
David Anderson88ef0b12018-08-09 10:40:00 -0700311 }
312 // Otherwise, open the partition as normal.
David Anderson12211d12018-07-24 15:21:20 -0700313 PartitionHandle handle;
314 if (!OpenPartition(device, args[0], &handle)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700315 *message = "Could not open partition";
316 return false;
David Anderson12211d12018-07-24 15:21:20 -0700317 }
318 uint64_t size = get_block_device_size(handle.fd());
David Anderson47589672018-09-04 16:22:41 -0700319 *message = android::base::StringPrintf("0x%" PRIX64, size);
David Anderson1fb3fd72018-08-31 14:40:22 -0700320 return true;
David Anderson12211d12018-07-24 15:21:20 -0700321}
David Anderson0d4277d2018-07-31 13:27:37 -0700322
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700323bool GetPartitionType(FastbootDevice* device, const std::vector<std::string>& args,
324 std::string* message) {
325 if (args.size() < 1) {
326 *message = "Missing argument";
327 return false;
328 }
Hridya Valsaraju4165e002018-10-09 10:40:35 -0700329
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700330 std::string partition_name = args[0];
David Andersond25f1c32018-11-09 20:41:33 -0800331 if (!FindPhysicalPartition(partition_name) && !LogicalPartitionExists(device, partition_name)) {
Hridya Valsaraju4165e002018-10-09 10:40:35 -0700332 *message = "Invalid partition";
333 return false;
334 }
335
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700336 auto fastboot_hal = device->fastboot_hal();
337 if (!fastboot_hal) {
LuK13379dd073e2022-03-02 14:18:27 +0100338 *message = "raw";
339 return true;
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700340 }
341
342 FileSystemType type;
343 Result ret;
344 auto ret_val =
345 fastboot_hal->getPartitionType(args[0], [&](FileSystemType fs_type, Result result) {
346 type = fs_type;
347 ret = result;
348 });
349 if (!ret_val.isOk() || (ret.status != Status::SUCCESS)) {
350 *message = "Unable to retrieve partition type";
351 } else {
352 switch (type) {
353 case FileSystemType::RAW:
354 *message = "raw";
355 return true;
356 case FileSystemType::EXT4:
357 *message = "ext4";
358 return true;
359 case FileSystemType::F2FS:
360 *message = "f2fs";
361 return true;
362 default:
363 *message = "Unknown file system type";
364 }
365 }
366
367 return false;
368}
369
David Anderson1fb3fd72018-08-31 14:40:22 -0700370bool GetPartitionIsLogical(FastbootDevice* device, const std::vector<std::string>& args,
371 std::string* message) {
David Anderson0d4277d2018-07-31 13:27:37 -0700372 if (args.size() < 1) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700373 *message = "Missing argument";
374 return false;
David Anderson0d4277d2018-07-31 13:27:37 -0700375 }
376 // Note: if a partition name is in both the GPT and the super partition, we
377 // return "true", to be consistent with prefering to flash logical partitions
378 // over physical ones.
379 std::string partition_name = args[0];
David Andersond25f1c32018-11-09 20:41:33 -0800380 if (LogicalPartitionExists(device, partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700381 *message = "yes";
382 return true;
David Anderson0d4277d2018-07-31 13:27:37 -0700383 }
384 if (FindPhysicalPartition(partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700385 *message = "no";
386 return true;
David Anderson0d4277d2018-07-31 13:27:37 -0700387 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700388 *message = "Partition not found";
389 return false;
David Anderson0d4277d2018-07-31 13:27:37 -0700390}
David Andersond9ba0612018-08-02 11:05:00 -0700391
David Anderson1fb3fd72018-08-31 14:40:22 -0700392bool GetIsUserspace(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
393 std::string* message) {
394 *message = "yes";
395 return true;
David Andersond9ba0612018-08-02 11:05:00 -0700396}
David Anderson0f626632018-08-31 16:44:25 -0700397
398std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device) {
399 std::vector<std::vector<std::string>> args;
400 auto partitions = ListPartitions(device);
401 for (const auto& partition : partitions) {
402 args.emplace_back(std::initializer_list<std::string>{partition});
403 }
404 return args;
405}
406
407std::vector<std::vector<std::string>> GetAllPartitionArgsNoSlot(FastbootDevice* device) {
408 auto partitions = ListPartitions(device);
409
410 std::string slot_suffix = device->GetCurrentSlot();
411 if (!slot_suffix.empty()) {
412 auto names = std::move(partitions);
413 for (const auto& name : names) {
414 std::string slotless_name = name;
415 if (android::base::EndsWith(name, "_a") || android::base::EndsWith(name, "_b")) {
416 slotless_name = name.substr(0, name.rfind("_"));
417 }
418 if (std::find(partitions.begin(), partitions.end(), slotless_name) ==
419 partitions.end()) {
420 partitions.emplace_back(slotless_name);
421 }
422 }
423 }
424
425 std::vector<std::vector<std::string>> args;
426 for (const auto& partition : partitions) {
427 args.emplace_back(std::initializer_list<std::string>{partition});
428 }
429 return args;
430}
David Andersonc091c172018-09-04 18:11:03 -0700431
432bool GetHardwareRevision(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
433 std::string* message) {
434 *message = android::base::GetProperty("ro.revision", "");
435 return true;
436}
David Anderson90fe0a42018-11-05 18:01:32 -0800437
438bool GetSuperPartitionName(FastbootDevice* device, const std::vector<std::string>& /* args */,
439 std::string* message) {
440 uint32_t slot_number = SlotNumberForSlotSuffix(device->GetCurrentSlot());
441 *message = fs_mgr_get_super_partition_name(slot_number);
442 return true;
443}
David Andersonab8f4662019-10-21 16:45:59 -0700444
445bool GetSnapshotUpdateStatus(FastbootDevice* device, const std::vector<std::string>& /* args */,
446 std::string* message) {
447 // Note that we use the HAL rather than mounting /metadata, since we want
448 // our results to match the bootloader.
David Anderson220ddb12019-10-31 18:02:41 -0700449 auto hal = device->boot1_1();
David Andersonab8f4662019-10-21 16:45:59 -0700450 if (!hal) {
451 *message = "not supported";
452 return false;
453 }
454
David Anderson220ddb12019-10-31 18:02:41 -0700455 MergeStatus status = hal->getSnapshotMergeStatus();
David Andersonab8f4662019-10-21 16:45:59 -0700456 switch (status) {
457 case MergeStatus::SNAPSHOTTED:
458 *message = "snapshotted";
459 break;
460 case MergeStatus::MERGING:
461 *message = "merging";
462 break;
463 default:
464 *message = "none";
465 break;
466 }
467 return true;
468}
Bowgo Tsai33da5c92019-11-13 17:13:49 +0800469
470bool GetCpuAbi(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
471 std::string* message) {
472 *message = android::base::GetProperty("ro.product.cpu.abi", "");
473 return true;
474}
Bowgo Tsai99f9a382020-01-21 18:31:23 +0800475
476bool GetSystemFingerprint(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
477 std::string* message) {
478 *message = android::base::GetProperty("ro.system.build.fingerprint", "");
479 if (message->empty()) {
480 *message = android::base::GetProperty("ro.build.fingerprint", "");
481 }
482 return true;
483}
484
485bool GetVendorFingerprint(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
486 std::string* message) {
487 *message = android::base::GetProperty("ro.vendor.build.fingerprint", "");
488 return true;
489}
490
491bool GetDynamicPartition(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
492 std::string* message) {
493 *message = android::base::GetProperty("ro.boot.dynamic_partitions", "");
494 return true;
495}
496
497bool GetFirstApiLevel(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
498 std::string* message) {
499 *message = android::base::GetProperty("ro.product.first_api_level", "");
500 return true;
501}
502
503bool GetSecurityPatchLevel(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
504 std::string* message) {
505 *message = android::base::GetProperty("ro.build.version.security_patch", "");
506 return true;
507}
508
509bool GetTrebleEnabled(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
510 std::string* message) {
511 *message = android::base::GetProperty("ro.treble.enabled", "");
512 return true;
513}
Yifan Hongb299cb72021-02-17 13:44:49 -0800514
515bool GetMaxFetchSize(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
516 std::string* message) {
517 if (!kEnableFetch) {
518 *message = "fetch not supported on user builds";
519 return false;
520 }
521 *message = android::base::StringPrintf("0x%X", kMaxFetchSizeDefault);
522 return true;
523}
David Andersonebc8fe12022-06-17 19:17:43 -0700524
525bool GetDmesg(FastbootDevice* device) {
526 if (GetDeviceLockStatus()) {
527 return device->WriteFail("Cannot use when device flashing is locked");
528 }
529
530 std::unique_ptr<FILE, decltype(&::fclose)> fp(popen("/system/bin/dmesg", "re"), ::fclose);
531 if (!fp) {
532 PLOG(ERROR) << "popen /system/bin/dmesg";
533 return device->WriteFail("Unable to run dmesg: "s + strerror(errno));
534 }
535
536 ssize_t rv;
537 size_t n = 0;
538 char* str = nullptr;
539 while ((rv = ::getline(&str, &n, fp.get())) > 0) {
540 if (str[rv - 1] == '\n') {
541 rv--;
542 }
543 device->WriteInfo(std::string(str, rv));
544 }
545
546 int saved_errno = errno;
547 ::free(str);
548
549 if (rv < 0 && saved_errno) {
550 LOG(ERROR) << "dmesg getline: " << strerror(saved_errno);
551 device->WriteFail("Unable to read dmesg: "s + strerror(saved_errno));
552 return false;
553 }
554
555 return true;
556}