blob: 2847e35ab6ad03997b8a7033e30cd2e1e2c78e40 [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
Kelvin Zhang6befe782022-06-21 14:20:54 -070032#include "BootControlClient.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
Kelvin Zhang6befe782022-06-21 14:20:54 -070043using MergeStatus = android::hal::BootControlClient::MergeStatus;
Sandeep Dhavale2534d482022-11-08 22:30:05 +000044using aidl::android::hardware::fastboot::FileSystemType;
David Anderson90fe0a42018-11-05 18:01:32 -080045using namespace android::fs_mgr;
David Andersonebc8fe12022-06-17 19:17:43 -070046using namespace std::string_literals;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070047
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070048constexpr char kFastbootProtocolVersion[] = "0.4";
49
David Anderson1fb3fd72018-08-31 14:40:22 -070050bool GetVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
51 std::string* message) {
52 *message = kFastbootProtocolVersion;
53 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070054}
55
David Anderson1fb3fd72018-08-31 14:40:22 -070056bool GetBootloaderVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
57 std::string* message) {
58 *message = android::base::GetProperty("ro.bootloader", "");
59 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070060}
61
David Anderson1fb3fd72018-08-31 14:40:22 -070062bool 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;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070066}
67
Bowgo Tsai99f9a382020-01-21 18:31:23 +080068bool 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
74bool 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
David Anderson1fb3fd72018-08-31 14:40:22 -070080bool GetProduct(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
81 std::string* message) {
82 *message = android::base::GetProperty("ro.product.device", "");
83 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070084}
85
David Anderson1fb3fd72018-08-31 14:40:22 -070086bool GetSerial(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
87 std::string* message) {
88 *message = android::base::GetProperty("ro.serialno", "");
89 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070090}
91
David Anderson1fb3fd72018-08-31 14:40:22 -070092bool 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;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070096}
97
Hridya Valsaraju4af80902018-09-26 13:08:16 -070098bool 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 }
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000105 std::string device_variant = "";
106 auto status = fastboot_hal->getVariant(&device_variant);
Hridya Valsaraju4af80902018-09-26 13:08:16 -0700107
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000108 if (!status.isOk()) {
Hridya Valsaraju4af80902018-09-26 13:08:16 -0700109 *message = "Unable to get device variant";
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000110 LOG(ERROR) << message->c_str() << status.getDescription();
Hridya Valsaraju4af80902018-09-26 13:08:16 -0700111 return false;
112 }
113
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000114 *message = device_variant;
Hridya Valsaraju4af80902018-09-26 13:08:16 -0700115 return true;
116}
117
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700118bool GetBatteryVoltageHelper(FastbootDevice* device, int32_t* battery_voltage) {
Yifan Hong4cb88dc2021-12-02 18:58:02 -0800119 using aidl::android::hardware::health::HealthInfo;
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700120
121 auto health_hal = device->health_hal();
122 if (!health_hal) {
123 return false;
124 }
125
Yifan Hong4cb88dc2021-12-02 18:58:02 -0800126 HealthInfo health_info;
127 auto res = health_hal->getHealthInfo(&health_info);
128 if (!res.isOk()) return false;
129 *battery_voltage = health_info.batteryVoltageMillivolts;
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700130 return true;
131}
132
Harry Pan7fa8dd62023-10-03 17:48:26 +0000133bool GetBatterySoCHelper(FastbootDevice* device, int32_t* battery_soc) {
134 using aidl::android::hardware::health::HealthInfo;
135
136 auto health_hal = device->health_hal();
137 if (!health_hal) {
138 return false;
139 }
140
141 HealthInfo health_info;
142 auto res = health_hal->getHealthInfo(&health_info);
143 if (!res.isOk()) return false;
144 *battery_soc = health_info.batteryLevel;
145 return true;
146}
147
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700148bool GetBatterySoCOk(FastbootDevice* device, const std::vector<std::string>& /* args */,
149 std::string* message) {
150 int32_t battery_voltage = 0;
151 if (!GetBatteryVoltageHelper(device, &battery_voltage)) {
152 *message = "Unable to read battery voltage";
153 return false;
154 }
155
156 auto fastboot_hal = device->fastboot_hal();
157 if (!fastboot_hal) {
158 *message = "Fastboot HAL not found";
159 return false;
160 }
161
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000162 auto voltage_threshold = 0;
163 auto status = fastboot_hal->getBatteryVoltageFlashingThreshold(&voltage_threshold);
164 if (!status.isOk()) {
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700165 *message = "Unable to get battery voltage flashing threshold";
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000166 LOG(ERROR) << message->c_str() << status.getDescription();
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700167 return false;
168 }
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000169 *message = battery_voltage >= voltage_threshold ? "yes" : "no";
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700170
171 return true;
172}
173
Hridya Valsaraju7c9bbe92018-09-27 10:41:01 -0700174bool GetOffModeChargeState(FastbootDevice* device, const std::vector<std::string>& /* args */,
175 std::string* message) {
176 auto fastboot_hal = device->fastboot_hal();
177 if (!fastboot_hal) {
178 *message = "Fastboot HAL not found";
179 return false;
180 }
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000181 bool off_mode_charging_state = false;
182 auto status = fastboot_hal->getOffModeChargeState(&off_mode_charging_state);
183 if (!status.isOk()) {
Hridya Valsaraju7c9bbe92018-09-27 10:41:01 -0700184 *message = "Unable to get off mode charge state";
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000185 LOG(ERROR) << message->c_str() << status.getDescription();
Hridya Valsaraju7c9bbe92018-09-27 10:41:01 -0700186 return false;
187 }
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000188 *message = off_mode_charging_state ? "1" : "0";
Hridya Valsaraju7c9bbe92018-09-27 10:41:01 -0700189 return true;
190}
191
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700192bool GetBatteryVoltage(FastbootDevice* device, const std::vector<std::string>& /* args */,
193 std::string* message) {
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700194 int32_t battery_voltage = 0;
195 if (GetBatteryVoltageHelper(device, &battery_voltage)) {
196 *message = std::to_string(battery_voltage);
197 return true;
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700198 }
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700199 *message = "Unable to get battery voltage";
200 return false;
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700201}
202
Harry Pan7fa8dd62023-10-03 17:48:26 +0000203bool GetBatterySoC(FastbootDevice* device, const std::vector<std::string>& /* args */,
204 std::string* message) {
205 int32_t battery_soc = 0;
206 if (GetBatterySoCHelper(device, &battery_soc)) {
207 *message = std::to_string(battery_soc);
208 return true;
209 }
210 *message = "Unable to get battery soc";
211 return false;
212}
213
David Anderson1fb3fd72018-08-31 14:40:22 -0700214bool GetCurrentSlot(FastbootDevice* device, const std::vector<std::string>& /* args */,
215 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700216 std::string suffix = device->GetCurrentSlot();
David Anderson1fb3fd72018-08-31 14:40:22 -0700217 *message = suffix.size() == 2 ? suffix.substr(1) : suffix;
218 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700219}
220
David Anderson1fb3fd72018-08-31 14:40:22 -0700221bool GetSlotCount(FastbootDevice* device, const std::vector<std::string>& /* args */,
222 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700223 auto boot_control_hal = device->boot_control_hal();
224 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700225 *message = "0";
226 } else {
Kelvin Zhang6befe782022-06-21 14:20:54 -0700227 *message = std::to_string(boot_control_hal->GetNumSlots());
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700228 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700229 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700230}
231
David Anderson1fb3fd72018-08-31 14:40:22 -0700232bool GetSlotSuccessful(FastbootDevice* device, const std::vector<std::string>& args,
233 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700234 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700235 *message = "Missing argument";
236 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700237 }
Kelvin Zhang6befe782022-06-21 14:20:54 -0700238 int32_t slot = -1;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700239 if (!GetSlotNumber(args[0], &slot)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700240 *message = "Invalid slot";
241 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700242 }
243 auto boot_control_hal = device->boot_control_hal();
244 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700245 *message = "Device has no slots";
246 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700247 }
Kelvin Zhang6befe782022-06-21 14:20:54 -0700248 if (boot_control_hal->IsSlotMarkedSuccessful(slot).value_or(false)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700249 *message = "no";
250 } else {
251 *message = "yes";
David Anderson856b7ec2018-08-08 17:58:56 -0700252 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700253 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700254}
255
David Anderson1fb3fd72018-08-31 14:40:22 -0700256bool GetSlotUnbootable(FastbootDevice* device, const std::vector<std::string>& args,
257 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700258 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700259 *message = "Missing argument";
260 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700261 }
Kelvin Zhang6befe782022-06-21 14:20:54 -0700262 int32_t slot = -1;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700263 if (!GetSlotNumber(args[0], &slot)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700264 *message = "Invalid slot";
265 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700266 }
267 auto boot_control_hal = device->boot_control_hal();
268 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700269 *message = "Device has no slots";
270 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700271 }
Kelvin Zhang6befe782022-06-21 14:20:54 -0700272 if (!boot_control_hal->IsSlotBootable(slot).value_or(false)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700273 *message = "yes";
274 } else {
275 *message = "no";
David Anderson856b7ec2018-08-08 17:58:56 -0700276 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700277 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700278}
279
David Anderson1fb3fd72018-08-31 14:40:22 -0700280bool GetMaxDownloadSize(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
281 std::string* message) {
David Anderson28b81cd2018-09-04 16:51:29 -0700282 *message = android::base::StringPrintf("0x%X", kMaxDownloadSizeDefault);
David Anderson1fb3fd72018-08-31 14:40:22 -0700283 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700284}
285
David Anderson1fb3fd72018-08-31 14:40:22 -0700286bool GetUnlocked(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
287 std::string* message) {
Hridya Valsarajudca328d2018-09-24 16:01:35 -0700288 *message = GetDeviceLockStatus() ? "no" : "yes";
David Anderson1fb3fd72018-08-31 14:40:22 -0700289 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700290}
291
David Anderson1fb3fd72018-08-31 14:40:22 -0700292bool GetHasSlot(FastbootDevice* device, const std::vector<std::string>& args,
293 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700294 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700295 *message = "Missing argument";
296 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700297 }
298 std::string slot_suffix = device->GetCurrentSlot();
299 if (slot_suffix.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700300 *message = "no";
301 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700302 }
David Anderson79ab0e32018-08-14 16:21:50 -0700303 std::string partition_name = args[0] + slot_suffix;
David Andersond25f1c32018-11-09 20:41:33 -0800304 if (FindPhysicalPartition(partition_name) || LogicalPartitionExists(device, partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700305 *message = "yes";
306 } else {
307 *message = "no";
David Anderson79ab0e32018-08-14 16:21:50 -0700308 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700309 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700310}
David Anderson12211d12018-07-24 15:21:20 -0700311
David Anderson1fb3fd72018-08-31 14:40:22 -0700312bool GetPartitionSize(FastbootDevice* device, const std::vector<std::string>& args,
313 std::string* message) {
David Anderson12211d12018-07-24 15:21:20 -0700314 if (args.size() < 1) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700315 *message = "Missing argument";
316 return false;
David Anderson12211d12018-07-24 15:21:20 -0700317 }
David Anderson88ef0b12018-08-09 10:40:00 -0700318 // Zero-length partitions cannot be created through device-mapper, so we
319 // special case them here.
320 bool is_zero_length;
David Andersond25f1c32018-11-09 20:41:33 -0800321 if (LogicalPartitionExists(device, args[0], &is_zero_length) && is_zero_length) {
Hridya Valsaraju2a377da2018-10-09 10:03:51 -0700322 *message = "0x0";
David Anderson1fb3fd72018-08-31 14:40:22 -0700323 return true;
David Anderson88ef0b12018-08-09 10:40:00 -0700324 }
325 // Otherwise, open the partition as normal.
David Anderson12211d12018-07-24 15:21:20 -0700326 PartitionHandle handle;
327 if (!OpenPartition(device, args[0], &handle)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700328 *message = "Could not open partition";
329 return false;
David Anderson12211d12018-07-24 15:21:20 -0700330 }
331 uint64_t size = get_block_device_size(handle.fd());
David Anderson47589672018-09-04 16:22:41 -0700332 *message = android::base::StringPrintf("0x%" PRIX64, size);
David Anderson1fb3fd72018-08-31 14:40:22 -0700333 return true;
David Anderson12211d12018-07-24 15:21:20 -0700334}
David Anderson0d4277d2018-07-31 13:27:37 -0700335
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700336bool GetPartitionType(FastbootDevice* device, const std::vector<std::string>& args,
337 std::string* message) {
338 if (args.size() < 1) {
339 *message = "Missing argument";
340 return false;
341 }
Hridya Valsaraju4165e002018-10-09 10:40:35 -0700342
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700343 std::string partition_name = args[0];
David Andersond25f1c32018-11-09 20:41:33 -0800344 if (!FindPhysicalPartition(partition_name) && !LogicalPartitionExists(device, partition_name)) {
Hridya Valsaraju4165e002018-10-09 10:40:35 -0700345 *message = "Invalid partition";
346 return false;
347 }
348
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700349 auto fastboot_hal = device->fastboot_hal();
350 if (!fastboot_hal) {
LuK13379dd073e2022-03-02 14:18:27 +0100351 *message = "raw";
352 return true;
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700353 }
354
355 FileSystemType type;
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000356 auto status = fastboot_hal->getPartitionType(args[0], &type);
357
358 if (!status.isOk()) {
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700359 *message = "Unable to retrieve partition type";
Sandeep Dhavale2534d482022-11-08 22:30:05 +0000360 LOG(ERROR) << message->c_str() << status.getDescription();
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700361 } else {
362 switch (type) {
363 case FileSystemType::RAW:
364 *message = "raw";
365 return true;
366 case FileSystemType::EXT4:
367 *message = "ext4";
368 return true;
369 case FileSystemType::F2FS:
370 *message = "f2fs";
371 return true;
372 default:
373 *message = "Unknown file system type";
374 }
375 }
376
377 return false;
378}
379
David Anderson1fb3fd72018-08-31 14:40:22 -0700380bool GetPartitionIsLogical(FastbootDevice* device, const std::vector<std::string>& args,
381 std::string* message) {
David Anderson0d4277d2018-07-31 13:27:37 -0700382 if (args.size() < 1) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700383 *message = "Missing argument";
384 return false;
David Anderson0d4277d2018-07-31 13:27:37 -0700385 }
386 // Note: if a partition name is in both the GPT and the super partition, we
387 // return "true", to be consistent with prefering to flash logical partitions
388 // over physical ones.
389 std::string partition_name = args[0];
David Andersond25f1c32018-11-09 20:41:33 -0800390 if (LogicalPartitionExists(device, partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700391 *message = "yes";
392 return true;
David Anderson0d4277d2018-07-31 13:27:37 -0700393 }
394 if (FindPhysicalPartition(partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700395 *message = "no";
396 return true;
David Anderson0d4277d2018-07-31 13:27:37 -0700397 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700398 *message = "Partition not found";
399 return false;
David Anderson0d4277d2018-07-31 13:27:37 -0700400}
David Andersond9ba0612018-08-02 11:05:00 -0700401
David Anderson1fb3fd72018-08-31 14:40:22 -0700402bool GetIsUserspace(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
403 std::string* message) {
404 *message = "yes";
405 return true;
David Andersond9ba0612018-08-02 11:05:00 -0700406}
David Anderson0f626632018-08-31 16:44:25 -0700407
Yi-Yo Chiang38b68c62022-11-22 17:32:21 +0800408bool GetIsForceDebuggable(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
409 std::string* message) {
410 *message = android::base::GetBoolProperty("ro.force.debuggable", false) ? "yes" : "no";
411 return true;
412}
413
David Anderson0f626632018-08-31 16:44:25 -0700414std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device) {
415 std::vector<std::vector<std::string>> args;
416 auto partitions = ListPartitions(device);
417 for (const auto& partition : partitions) {
418 args.emplace_back(std::initializer_list<std::string>{partition});
419 }
420 return args;
421}
422
423std::vector<std::vector<std::string>> GetAllPartitionArgsNoSlot(FastbootDevice* device) {
424 auto partitions = ListPartitions(device);
425
426 std::string slot_suffix = device->GetCurrentSlot();
427 if (!slot_suffix.empty()) {
428 auto names = std::move(partitions);
429 for (const auto& name : names) {
430 std::string slotless_name = name;
431 if (android::base::EndsWith(name, "_a") || android::base::EndsWith(name, "_b")) {
432 slotless_name = name.substr(0, name.rfind("_"));
433 }
434 if (std::find(partitions.begin(), partitions.end(), slotless_name) ==
435 partitions.end()) {
436 partitions.emplace_back(slotless_name);
437 }
438 }
439 }
440
441 std::vector<std::vector<std::string>> args;
442 for (const auto& partition : partitions) {
443 args.emplace_back(std::initializer_list<std::string>{partition});
444 }
445 return args;
446}
David Andersonc091c172018-09-04 18:11:03 -0700447
448bool GetHardwareRevision(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
449 std::string* message) {
450 *message = android::base::GetProperty("ro.revision", "");
451 return true;
452}
David Anderson90fe0a42018-11-05 18:01:32 -0800453
454bool GetSuperPartitionName(FastbootDevice* device, const std::vector<std::string>& /* args */,
455 std::string* message) {
456 uint32_t slot_number = SlotNumberForSlotSuffix(device->GetCurrentSlot());
457 *message = fs_mgr_get_super_partition_name(slot_number);
458 return true;
459}
David Andersonab8f4662019-10-21 16:45:59 -0700460
461bool GetSnapshotUpdateStatus(FastbootDevice* device, const std::vector<std::string>& /* args */,
462 std::string* message) {
463 // Note that we use the HAL rather than mounting /metadata, since we want
464 // our results to match the bootloader.
David Anderson220ddb12019-10-31 18:02:41 -0700465 auto hal = device->boot1_1();
David Andersonab8f4662019-10-21 16:45:59 -0700466 if (!hal) {
467 *message = "not supported";
468 return false;
469 }
470
David Anderson220ddb12019-10-31 18:02:41 -0700471 MergeStatus status = hal->getSnapshotMergeStatus();
David Andersonab8f4662019-10-21 16:45:59 -0700472 switch (status) {
473 case MergeStatus::SNAPSHOTTED:
474 *message = "snapshotted";
475 break;
476 case MergeStatus::MERGING:
477 *message = "merging";
478 break;
479 default:
480 *message = "none";
481 break;
482 }
483 return true;
484}
Bowgo Tsai33da5c92019-11-13 17:13:49 +0800485
486bool GetCpuAbi(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
487 std::string* message) {
488 *message = android::base::GetProperty("ro.product.cpu.abi", "");
489 return true;
490}
Bowgo Tsai99f9a382020-01-21 18:31:23 +0800491
492bool GetSystemFingerprint(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
493 std::string* message) {
494 *message = android::base::GetProperty("ro.system.build.fingerprint", "");
495 if (message->empty()) {
496 *message = android::base::GetProperty("ro.build.fingerprint", "");
497 }
498 return true;
499}
500
501bool GetVendorFingerprint(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
502 std::string* message) {
503 *message = android::base::GetProperty("ro.vendor.build.fingerprint", "");
504 return true;
505}
506
507bool GetDynamicPartition(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
508 std::string* message) {
509 *message = android::base::GetProperty("ro.boot.dynamic_partitions", "");
510 return true;
511}
512
513bool GetFirstApiLevel(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
514 std::string* message) {
515 *message = android::base::GetProperty("ro.product.first_api_level", "");
516 return true;
517}
518
519bool GetSecurityPatchLevel(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
520 std::string* message) {
521 *message = android::base::GetProperty("ro.build.version.security_patch", "");
522 return true;
523}
524
525bool GetTrebleEnabled(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
526 std::string* message) {
527 *message = android::base::GetProperty("ro.treble.enabled", "");
528 return true;
529}
Yifan Hongb299cb72021-02-17 13:44:49 -0800530
531bool GetMaxFetchSize(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
532 std::string* message) {
533 if (!kEnableFetch) {
534 *message = "fetch not supported on user builds";
535 return false;
536 }
537 *message = android::base::StringPrintf("0x%X", kMaxFetchSizeDefault);
538 return true;
539}
David Andersonebc8fe12022-06-17 19:17:43 -0700540
541bool GetDmesg(FastbootDevice* device) {
542 if (GetDeviceLockStatus()) {
543 return device->WriteFail("Cannot use when device flashing is locked");
544 }
545
546 std::unique_ptr<FILE, decltype(&::fclose)> fp(popen("/system/bin/dmesg", "re"), ::fclose);
547 if (!fp) {
548 PLOG(ERROR) << "popen /system/bin/dmesg";
549 return device->WriteFail("Unable to run dmesg: "s + strerror(errno));
550 }
551
552 ssize_t rv;
553 size_t n = 0;
554 char* str = nullptr;
555 while ((rv = ::getline(&str, &n, fp.get())) > 0) {
556 if (str[rv - 1] == '\n') {
557 rv--;
558 }
559 device->WriteInfo(std::string(str, rv));
560 }
561
562 int saved_errno = errno;
563 ::free(str);
564
565 if (rv < 0 && saved_errno) {
566 LOG(ERROR) << "dmesg getline: " << strerror(saved_errno);
567 device->WriteFail("Unable to read dmesg: "s + strerror(saved_errno));
568 return false;
569 }
570
571 return true;
572}