blob: 717db064f97807383ea7e39ec759bd591c9a2434 [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>
20
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070021#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>
David Andersonab8f4662019-10-21 16:45:59 -070026#include <android/hardware/boot/1.1/IBootControl.h>
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070027#include <ext4_utils/ext4_utils.h>
David Anderson90fe0a42018-11-05 18:01:32 -080028#include <fs_mgr.h>
Hridya Valsaraju47658ca2018-09-28 11:41:22 -070029#include <healthhalutils/HealthHalUtils.h>
David Anderson90fe0a42018-11-05 18:01:32 -080030#include <liblp/liblp.h>
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070031
32#include "fastboot_device.h"
David Anderson12211d12018-07-24 15:21:20 -070033#include "flashing.h"
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070034#include "utility.h"
35
36using ::android::hardware::boot::V1_0::BoolResult;
37using ::android::hardware::boot::V1_0::Slot;
David Andersonab8f4662019-10-21 16:45:59 -070038using ::android::hardware::boot::V1_1::MergeStatus;
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -070039using ::android::hardware::fastboot::V1_0::FileSystemType;
40using ::android::hardware::fastboot::V1_0::Result;
41using ::android::hardware::fastboot::V1_0::Status;
David Andersonab8f4662019-10-21 16:45:59 -070042using IBootControl1_1 = ::android::hardware::boot::V1_1::IBootControl;
David Anderson90fe0a42018-11-05 18:01:32 -080043using namespace android::fs_mgr;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070044
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070045constexpr char kFastbootProtocolVersion[] = "0.4";
46
David Anderson1fb3fd72018-08-31 14:40:22 -070047bool GetVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
48 std::string* message) {
49 *message = kFastbootProtocolVersion;
50 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070051}
52
David Anderson1fb3fd72018-08-31 14:40:22 -070053bool GetBootloaderVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
54 std::string* message) {
55 *message = android::base::GetProperty("ro.bootloader", "");
56 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070057}
58
David Anderson1fb3fd72018-08-31 14:40:22 -070059bool 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;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070063}
64
David Anderson1fb3fd72018-08-31 14:40:22 -070065bool GetProduct(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
66 std::string* message) {
67 *message = android::base::GetProperty("ro.product.device", "");
68 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070069}
70
David Anderson1fb3fd72018-08-31 14:40:22 -070071bool GetSerial(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
72 std::string* message) {
73 *message = android::base::GetProperty("ro.serialno", "");
74 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070075}
76
David Anderson1fb3fd72018-08-31 14:40:22 -070077bool GetSecure(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
78 std::string* message) {
79 *message = android::base::GetBoolProperty("ro.secure", "") ? "yes" : "no";
80 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070081}
82
Hridya Valsaraju4af80902018-09-26 13:08:16 -070083bool GetVariant(FastbootDevice* device, const std::vector<std::string>& /* args */,
84 std::string* message) {
85 auto fastboot_hal = device->fastboot_hal();
86 if (!fastboot_hal) {
87 *message = "Fastboot HAL not found";
88 return false;
89 }
90
91 Result ret;
92 auto ret_val = fastboot_hal->getVariant([&](std::string device_variant, Result result) {
93 *message = device_variant;
94 ret = result;
95 });
96 if (!ret_val.isOk() || ret.status != Status::SUCCESS) {
97 *message = "Unable to get device variant";
98 return false;
99 }
100
101 return true;
102}
103
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700104bool GetBatteryVoltageHelper(FastbootDevice* device, int32_t* battery_voltage) {
105 using android::hardware::health::V2_0::HealthInfo;
106 using android::hardware::health::V2_0::Result;
107
108 auto health_hal = device->health_hal();
109 if (!health_hal) {
110 return false;
111 }
112
113 Result ret;
114 auto ret_val = health_hal->getHealthInfo([&](Result result, HealthInfo info) {
115 *battery_voltage = info.legacy.batteryVoltage;
116 ret = result;
117 });
118 if (!ret_val.isOk() || (ret != Result::SUCCESS)) {
119 return false;
120 }
121
122 return true;
123}
124
125bool GetBatterySoCOk(FastbootDevice* device, const std::vector<std::string>& /* args */,
126 std::string* message) {
127 int32_t battery_voltage = 0;
128 if (!GetBatteryVoltageHelper(device, &battery_voltage)) {
129 *message = "Unable to read battery voltage";
130 return false;
131 }
132
133 auto fastboot_hal = device->fastboot_hal();
134 if (!fastboot_hal) {
135 *message = "Fastboot HAL not found";
136 return false;
137 }
138
139 Result ret;
140 auto ret_val = fastboot_hal->getBatteryVoltageFlashingThreshold(
141 [&](int32_t voltage_threshold, Result result) {
142 *message = battery_voltage >= voltage_threshold ? "yes" : "no";
143 ret = result;
144 });
145
146 if (!ret_val.isOk() || ret.status != Status::SUCCESS) {
147 *message = "Unable to get battery voltage flashing threshold";
148 return false;
149 }
150
151 return true;
152}
153
Hridya Valsaraju7c9bbe92018-09-27 10:41:01 -0700154bool GetOffModeChargeState(FastbootDevice* device, const std::vector<std::string>& /* args */,
155 std::string* message) {
156 auto fastboot_hal = device->fastboot_hal();
157 if (!fastboot_hal) {
158 *message = "Fastboot HAL not found";
159 return false;
160 }
161
162 Result ret;
163 auto ret_val =
164 fastboot_hal->getOffModeChargeState([&](bool off_mode_charging_state, Result result) {
165 *message = off_mode_charging_state ? "1" : "0";
166 ret = result;
167 });
168 if (!ret_val.isOk() || (ret.status != Status::SUCCESS)) {
169 *message = "Unable to get off mode charge state";
170 return false;
171 }
172
173 return true;
174}
175
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700176bool GetBatteryVoltage(FastbootDevice* device, const std::vector<std::string>& /* args */,
177 std::string* message) {
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700178 int32_t battery_voltage = 0;
179 if (GetBatteryVoltageHelper(device, &battery_voltage)) {
180 *message = std::to_string(battery_voltage);
181 return true;
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700182 }
Hridya Valsarajua534a5a2018-10-03 15:53:22 -0700183 *message = "Unable to get battery voltage";
184 return false;
Hridya Valsaraju47658ca2018-09-28 11:41:22 -0700185}
186
David Anderson1fb3fd72018-08-31 14:40:22 -0700187bool GetCurrentSlot(FastbootDevice* device, const std::vector<std::string>& /* args */,
188 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700189 std::string suffix = device->GetCurrentSlot();
David Anderson1fb3fd72018-08-31 14:40:22 -0700190 *message = suffix.size() == 2 ? suffix.substr(1) : suffix;
191 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700192}
193
David Anderson1fb3fd72018-08-31 14:40:22 -0700194bool GetSlotCount(FastbootDevice* device, const std::vector<std::string>& /* args */,
195 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700196 auto boot_control_hal = device->boot_control_hal();
197 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700198 *message = "0";
199 } else {
200 *message = std::to_string(boot_control_hal->getNumberSlots());
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700201 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700202 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700203}
204
David Anderson1fb3fd72018-08-31 14:40:22 -0700205bool GetSlotSuccessful(FastbootDevice* device, const std::vector<std::string>& args,
206 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700207 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700208 *message = "Missing argument";
209 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700210 }
211 Slot slot;
212 if (!GetSlotNumber(args[0], &slot)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700213 *message = "Invalid slot";
214 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700215 }
216 auto boot_control_hal = device->boot_control_hal();
217 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700218 *message = "Device has no slots";
219 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700220 }
David Anderson856b7ec2018-08-08 17:58:56 -0700221 if (boot_control_hal->isSlotMarkedSuccessful(slot) != BoolResult::TRUE) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700222 *message = "no";
223 } else {
224 *message = "yes";
David Anderson856b7ec2018-08-08 17:58:56 -0700225 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700226 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700227}
228
David Anderson1fb3fd72018-08-31 14:40:22 -0700229bool GetSlotUnbootable(FastbootDevice* device, const std::vector<std::string>& args,
230 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700231 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700232 *message = "Missing argument";
233 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700234 }
235 Slot slot;
236 if (!GetSlotNumber(args[0], &slot)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700237 *message = "Invalid slot";
238 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700239 }
240 auto boot_control_hal = device->boot_control_hal();
241 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700242 *message = "Device has no slots";
243 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700244 }
David Anderson856b7ec2018-08-08 17:58:56 -0700245 if (boot_control_hal->isSlotBootable(slot) != BoolResult::TRUE) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700246 *message = "yes";
247 } else {
248 *message = "no";
David Anderson856b7ec2018-08-08 17:58:56 -0700249 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700250 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700251}
252
David Anderson1fb3fd72018-08-31 14:40:22 -0700253bool GetMaxDownloadSize(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
254 std::string* message) {
David Anderson28b81cd2018-09-04 16:51:29 -0700255 *message = android::base::StringPrintf("0x%X", kMaxDownloadSizeDefault);
David Anderson1fb3fd72018-08-31 14:40:22 -0700256 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700257}
258
David Anderson1fb3fd72018-08-31 14:40:22 -0700259bool GetUnlocked(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
260 std::string* message) {
Hridya Valsarajudca328d2018-09-24 16:01:35 -0700261 *message = GetDeviceLockStatus() ? "no" : "yes";
David Anderson1fb3fd72018-08-31 14:40:22 -0700262 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700263}
264
David Anderson1fb3fd72018-08-31 14:40:22 -0700265bool GetHasSlot(FastbootDevice* device, const std::vector<std::string>& args,
266 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700267 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700268 *message = "Missing argument";
269 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700270 }
271 std::string slot_suffix = device->GetCurrentSlot();
272 if (slot_suffix.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700273 *message = "no";
274 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700275 }
David Anderson79ab0e32018-08-14 16:21:50 -0700276 std::string partition_name = args[0] + slot_suffix;
David Andersond25f1c32018-11-09 20:41:33 -0800277 if (FindPhysicalPartition(partition_name) || LogicalPartitionExists(device, partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700278 *message = "yes";
279 } else {
280 *message = "no";
David Anderson79ab0e32018-08-14 16:21:50 -0700281 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700282 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700283}
David Anderson12211d12018-07-24 15:21:20 -0700284
David Anderson1fb3fd72018-08-31 14:40:22 -0700285bool GetPartitionSize(FastbootDevice* device, const std::vector<std::string>& args,
286 std::string* message) {
David Anderson12211d12018-07-24 15:21:20 -0700287 if (args.size() < 1) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700288 *message = "Missing argument";
289 return false;
David Anderson12211d12018-07-24 15:21:20 -0700290 }
David Anderson88ef0b12018-08-09 10:40:00 -0700291 // Zero-length partitions cannot be created through device-mapper, so we
292 // special case them here.
293 bool is_zero_length;
David Andersond25f1c32018-11-09 20:41:33 -0800294 if (LogicalPartitionExists(device, args[0], &is_zero_length) && is_zero_length) {
Hridya Valsaraju2a377da2018-10-09 10:03:51 -0700295 *message = "0x0";
David Anderson1fb3fd72018-08-31 14:40:22 -0700296 return true;
David Anderson88ef0b12018-08-09 10:40:00 -0700297 }
298 // Otherwise, open the partition as normal.
David Anderson12211d12018-07-24 15:21:20 -0700299 PartitionHandle handle;
300 if (!OpenPartition(device, args[0], &handle)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700301 *message = "Could not open partition";
302 return false;
David Anderson12211d12018-07-24 15:21:20 -0700303 }
304 uint64_t size = get_block_device_size(handle.fd());
David Anderson47589672018-09-04 16:22:41 -0700305 *message = android::base::StringPrintf("0x%" PRIX64, size);
David Anderson1fb3fd72018-08-31 14:40:22 -0700306 return true;
David Anderson12211d12018-07-24 15:21:20 -0700307}
David Anderson0d4277d2018-07-31 13:27:37 -0700308
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700309bool GetPartitionType(FastbootDevice* device, const std::vector<std::string>& args,
310 std::string* message) {
311 if (args.size() < 1) {
312 *message = "Missing argument";
313 return false;
314 }
Hridya Valsaraju4165e002018-10-09 10:40:35 -0700315
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700316 std::string partition_name = args[0];
David Andersond25f1c32018-11-09 20:41:33 -0800317 if (!FindPhysicalPartition(partition_name) && !LogicalPartitionExists(device, partition_name)) {
Hridya Valsaraju4165e002018-10-09 10:40:35 -0700318 *message = "Invalid partition";
319 return false;
320 }
321
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700322 auto fastboot_hal = device->fastboot_hal();
323 if (!fastboot_hal) {
324 *message = "Fastboot HAL not found";
325 return false;
326 }
327
328 FileSystemType type;
329 Result ret;
330 auto ret_val =
331 fastboot_hal->getPartitionType(args[0], [&](FileSystemType fs_type, Result result) {
332 type = fs_type;
333 ret = result;
334 });
335 if (!ret_val.isOk() || (ret.status != Status::SUCCESS)) {
336 *message = "Unable to retrieve partition type";
337 } else {
338 switch (type) {
339 case FileSystemType::RAW:
340 *message = "raw";
341 return true;
342 case FileSystemType::EXT4:
343 *message = "ext4";
344 return true;
345 case FileSystemType::F2FS:
346 *message = "f2fs";
347 return true;
348 default:
349 *message = "Unknown file system type";
350 }
351 }
352
353 return false;
354}
355
David Anderson1fb3fd72018-08-31 14:40:22 -0700356bool GetPartitionIsLogical(FastbootDevice* device, const std::vector<std::string>& args,
357 std::string* message) {
David Anderson0d4277d2018-07-31 13:27:37 -0700358 if (args.size() < 1) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700359 *message = "Missing argument";
360 return false;
David Anderson0d4277d2018-07-31 13:27:37 -0700361 }
362 // Note: if a partition name is in both the GPT and the super partition, we
363 // return "true", to be consistent with prefering to flash logical partitions
364 // over physical ones.
365 std::string partition_name = args[0];
David Andersond25f1c32018-11-09 20:41:33 -0800366 if (LogicalPartitionExists(device, partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700367 *message = "yes";
368 return true;
David Anderson0d4277d2018-07-31 13:27:37 -0700369 }
370 if (FindPhysicalPartition(partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700371 *message = "no";
372 return true;
David Anderson0d4277d2018-07-31 13:27:37 -0700373 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700374 *message = "Partition not found";
375 return false;
David Anderson0d4277d2018-07-31 13:27:37 -0700376}
David Andersond9ba0612018-08-02 11:05:00 -0700377
David Anderson1fb3fd72018-08-31 14:40:22 -0700378bool GetIsUserspace(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
379 std::string* message) {
380 *message = "yes";
381 return true;
David Andersond9ba0612018-08-02 11:05:00 -0700382}
David Anderson0f626632018-08-31 16:44:25 -0700383
384std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device) {
385 std::vector<std::vector<std::string>> args;
386 auto partitions = ListPartitions(device);
387 for (const auto& partition : partitions) {
388 args.emplace_back(std::initializer_list<std::string>{partition});
389 }
390 return args;
391}
392
393std::vector<std::vector<std::string>> GetAllPartitionArgsNoSlot(FastbootDevice* device) {
394 auto partitions = ListPartitions(device);
395
396 std::string slot_suffix = device->GetCurrentSlot();
397 if (!slot_suffix.empty()) {
398 auto names = std::move(partitions);
399 for (const auto& name : names) {
400 std::string slotless_name = name;
401 if (android::base::EndsWith(name, "_a") || android::base::EndsWith(name, "_b")) {
402 slotless_name = name.substr(0, name.rfind("_"));
403 }
404 if (std::find(partitions.begin(), partitions.end(), slotless_name) ==
405 partitions.end()) {
406 partitions.emplace_back(slotless_name);
407 }
408 }
409 }
410
411 std::vector<std::vector<std::string>> args;
412 for (const auto& partition : partitions) {
413 args.emplace_back(std::initializer_list<std::string>{partition});
414 }
415 return args;
416}
David Andersonc091c172018-09-04 18:11:03 -0700417
418bool GetHardwareRevision(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
419 std::string* message) {
420 *message = android::base::GetProperty("ro.revision", "");
421 return true;
422}
David Anderson90fe0a42018-11-05 18:01:32 -0800423
424bool GetSuperPartitionName(FastbootDevice* device, const std::vector<std::string>& /* args */,
425 std::string* message) {
426 uint32_t slot_number = SlotNumberForSlotSuffix(device->GetCurrentSlot());
427 *message = fs_mgr_get_super_partition_name(slot_number);
428 return true;
429}
David Andersonab8f4662019-10-21 16:45:59 -0700430
431bool GetSnapshotUpdateStatus(FastbootDevice* device, const std::vector<std::string>& /* args */,
432 std::string* message) {
433 // Note that we use the HAL rather than mounting /metadata, since we want
434 // our results to match the bootloader.
435 auto hal = device->boot_control_hal();
436 if (!hal) {
437 *message = "not supported";
438 return false;
439 }
440
441 android::sp<IBootControl1_1> hal11 = IBootControl1_1::castFrom(hal);
442 if (!hal11) {
443 *message = "not supported";
444 return false;
445 }
446
447 MergeStatus status = hal11->getSnapshotMergeStatus();
448 switch (status) {
449 case MergeStatus::SNAPSHOTTED:
450 *message = "snapshotted";
451 break;
452 case MergeStatus::MERGING:
453 *message = "merging";
454 break;
455 default:
456 *message = "none";
457 break;
458 }
459 return true;
460}
Bowgo Tsai33da5c92019-11-13 17:13:49 +0800461
462bool GetCpuAbi(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
463 std::string* message) {
464 *message = android::base::GetProperty("ro.product.cpu.abi", "");
465 return true;
466}