blob: bcf13a540249c2ca7159fec66862e40f91518a62 [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>
26#include <ext4_utils/ext4_utils.h>
27
28#include "fastboot_device.h"
David Anderson12211d12018-07-24 15:21:20 -070029#include "flashing.h"
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070030#include "utility.h"
31
32using ::android::hardware::boot::V1_0::BoolResult;
33using ::android::hardware::boot::V1_0::Slot;
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -070034using ::android::hardware::fastboot::V1_0::FileSystemType;
35using ::android::hardware::fastboot::V1_0::Result;
36using ::android::hardware::fastboot::V1_0::Status;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070037
38constexpr int kMaxDownloadSizeDefault = 0x20000000;
39constexpr char kFastbootProtocolVersion[] = "0.4";
40
David Anderson1fb3fd72018-08-31 14:40:22 -070041bool GetVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
42 std::string* message) {
43 *message = kFastbootProtocolVersion;
44 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070045}
46
David Anderson1fb3fd72018-08-31 14:40:22 -070047bool GetBootloaderVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
48 std::string* message) {
49 *message = android::base::GetProperty("ro.bootloader", "");
50 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070051}
52
David Anderson1fb3fd72018-08-31 14:40:22 -070053bool GetBasebandVersion(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
54 std::string* message) {
55 *message = android::base::GetProperty("ro.build.expect.baseband", "");
56 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070057}
58
David Anderson1fb3fd72018-08-31 14:40:22 -070059bool GetProduct(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
60 std::string* message) {
61 *message = android::base::GetProperty("ro.product.device", "");
62 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070063}
64
David Anderson1fb3fd72018-08-31 14:40:22 -070065bool GetSerial(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
66 std::string* message) {
67 *message = android::base::GetProperty("ro.serialno", "");
68 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070069}
70
David Anderson1fb3fd72018-08-31 14:40:22 -070071bool GetSecure(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
72 std::string* message) {
73 *message = android::base::GetBoolProperty("ro.secure", "") ? "yes" : "no";
74 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -070075}
76
Hridya Valsaraju4af80902018-09-26 13:08:16 -070077bool GetVariant(FastbootDevice* device, const std::vector<std::string>& /* args */,
78 std::string* message) {
79 auto fastboot_hal = device->fastboot_hal();
80 if (!fastboot_hal) {
81 *message = "Fastboot HAL not found";
82 return false;
83 }
84
85 Result ret;
86 auto ret_val = fastboot_hal->getVariant([&](std::string device_variant, Result result) {
87 *message = device_variant;
88 ret = result;
89 });
90 if (!ret_val.isOk() || ret.status != Status::SUCCESS) {
91 *message = "Unable to get device variant";
92 return false;
93 }
94
95 return true;
96}
97
Hridya Valsaraju7c9bbe92018-09-27 10:41:01 -070098bool GetOffModeChargeState(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 }
105
106 Result ret;
107 auto ret_val =
108 fastboot_hal->getOffModeChargeState([&](bool off_mode_charging_state, Result result) {
109 *message = off_mode_charging_state ? "1" : "0";
110 ret = result;
111 });
112 if (!ret_val.isOk() || (ret.status != Status::SUCCESS)) {
113 *message = "Unable to get off mode charge state";
114 return false;
115 }
116
117 return true;
118}
119
David Anderson1fb3fd72018-08-31 14:40:22 -0700120bool GetCurrentSlot(FastbootDevice* device, const std::vector<std::string>& /* args */,
121 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700122 std::string suffix = device->GetCurrentSlot();
David Anderson1fb3fd72018-08-31 14:40:22 -0700123 *message = suffix.size() == 2 ? suffix.substr(1) : suffix;
124 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700125}
126
David Anderson1fb3fd72018-08-31 14:40:22 -0700127bool GetSlotCount(FastbootDevice* device, const std::vector<std::string>& /* args */,
128 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700129 auto boot_control_hal = device->boot_control_hal();
130 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700131 *message = "0";
132 } else {
133 *message = std::to_string(boot_control_hal->getNumberSlots());
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700134 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700135 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700136}
137
David Anderson1fb3fd72018-08-31 14:40:22 -0700138bool GetSlotSuccessful(FastbootDevice* device, const std::vector<std::string>& args,
139 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700140 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700141 *message = "Missing argument";
142 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700143 }
144 Slot slot;
145 if (!GetSlotNumber(args[0], &slot)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700146 *message = "Invalid slot";
147 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700148 }
149 auto boot_control_hal = device->boot_control_hal();
150 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700151 *message = "Device has no slots";
152 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700153 }
David Anderson856b7ec2018-08-08 17:58:56 -0700154 if (boot_control_hal->isSlotMarkedSuccessful(slot) != BoolResult::TRUE) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700155 *message = "no";
156 } else {
157 *message = "yes";
David Anderson856b7ec2018-08-08 17:58:56 -0700158 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700159 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700160}
161
David Anderson1fb3fd72018-08-31 14:40:22 -0700162bool GetSlotUnbootable(FastbootDevice* device, const std::vector<std::string>& args,
163 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700164 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700165 *message = "Missing argument";
166 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700167 }
168 Slot slot;
169 if (!GetSlotNumber(args[0], &slot)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700170 *message = "Invalid slot";
171 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700172 }
173 auto boot_control_hal = device->boot_control_hal();
174 if (!boot_control_hal) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700175 *message = "Device has no slots";
176 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700177 }
David Anderson856b7ec2018-08-08 17:58:56 -0700178 if (boot_control_hal->isSlotBootable(slot) != BoolResult::TRUE) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700179 *message = "yes";
180 } else {
181 *message = "no";
David Anderson856b7ec2018-08-08 17:58:56 -0700182 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700183 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700184}
185
David Anderson1fb3fd72018-08-31 14:40:22 -0700186bool GetMaxDownloadSize(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
187 std::string* message) {
David Anderson28b81cd2018-09-04 16:51:29 -0700188 *message = android::base::StringPrintf("0x%X", kMaxDownloadSizeDefault);
David Anderson1fb3fd72018-08-31 14:40:22 -0700189 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700190}
191
David Anderson1fb3fd72018-08-31 14:40:22 -0700192bool GetUnlocked(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
193 std::string* message) {
Hridya Valsarajudca328d2018-09-24 16:01:35 -0700194 *message = GetDeviceLockStatus() ? "no" : "yes";
David Anderson1fb3fd72018-08-31 14:40:22 -0700195 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700196}
197
David Anderson1fb3fd72018-08-31 14:40:22 -0700198bool GetHasSlot(FastbootDevice* device, const std::vector<std::string>& args,
199 std::string* message) {
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700200 if (args.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700201 *message = "Missing argument";
202 return false;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700203 }
204 std::string slot_suffix = device->GetCurrentSlot();
205 if (slot_suffix.empty()) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700206 *message = "no";
207 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700208 }
David Anderson79ab0e32018-08-14 16:21:50 -0700209 std::string partition_name = args[0] + slot_suffix;
210 if (FindPhysicalPartition(partition_name) ||
211 LogicalPartitionExists(partition_name, slot_suffix)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700212 *message = "yes";
213 } else {
214 *message = "no";
David Anderson79ab0e32018-08-14 16:21:50 -0700215 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700216 return true;
Hridya Valsaraju31d2c262018-07-20 13:35:50 -0700217}
David Anderson12211d12018-07-24 15:21:20 -0700218
David Anderson1fb3fd72018-08-31 14:40:22 -0700219bool GetPartitionSize(FastbootDevice* device, const std::vector<std::string>& args,
220 std::string* message) {
David Anderson12211d12018-07-24 15:21:20 -0700221 if (args.size() < 1) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700222 *message = "Missing argument";
223 return false;
David Anderson12211d12018-07-24 15:21:20 -0700224 }
David Anderson88ef0b12018-08-09 10:40:00 -0700225 // Zero-length partitions cannot be created through device-mapper, so we
226 // special case them here.
227 bool is_zero_length;
228 if (LogicalPartitionExists(args[0], device->GetCurrentSlot(), &is_zero_length) &&
229 is_zero_length) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700230 *message = "0";
231 return true;
David Anderson88ef0b12018-08-09 10:40:00 -0700232 }
233 // Otherwise, open the partition as normal.
David Anderson12211d12018-07-24 15:21:20 -0700234 PartitionHandle handle;
235 if (!OpenPartition(device, args[0], &handle)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700236 *message = "Could not open partition";
237 return false;
David Anderson12211d12018-07-24 15:21:20 -0700238 }
239 uint64_t size = get_block_device_size(handle.fd());
David Anderson47589672018-09-04 16:22:41 -0700240 *message = android::base::StringPrintf("0x%" PRIX64, size);
David Anderson1fb3fd72018-08-31 14:40:22 -0700241 return true;
David Anderson12211d12018-07-24 15:21:20 -0700242}
David Anderson0d4277d2018-07-31 13:27:37 -0700243
Hridya Valsarajubf9f8d12018-09-05 16:57:24 -0700244bool GetPartitionType(FastbootDevice* device, const std::vector<std::string>& args,
245 std::string* message) {
246 if (args.size() < 1) {
247 *message = "Missing argument";
248 return false;
249 }
250 std::string partition_name = args[0];
251 auto fastboot_hal = device->fastboot_hal();
252 if (!fastboot_hal) {
253 *message = "Fastboot HAL not found";
254 return false;
255 }
256
257 FileSystemType type;
258 Result ret;
259 auto ret_val =
260 fastboot_hal->getPartitionType(args[0], [&](FileSystemType fs_type, Result result) {
261 type = fs_type;
262 ret = result;
263 });
264 if (!ret_val.isOk() || (ret.status != Status::SUCCESS)) {
265 *message = "Unable to retrieve partition type";
266 } else {
267 switch (type) {
268 case FileSystemType::RAW:
269 *message = "raw";
270 return true;
271 case FileSystemType::EXT4:
272 *message = "ext4";
273 return true;
274 case FileSystemType::F2FS:
275 *message = "f2fs";
276 return true;
277 default:
278 *message = "Unknown file system type";
279 }
280 }
281
282 return false;
283}
284
David Anderson1fb3fd72018-08-31 14:40:22 -0700285bool GetPartitionIsLogical(FastbootDevice* device, const std::vector<std::string>& args,
286 std::string* message) {
David Anderson0d4277d2018-07-31 13:27:37 -0700287 if (args.size() < 1) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700288 *message = "Missing argument";
289 return false;
David Anderson0d4277d2018-07-31 13:27:37 -0700290 }
291 // Note: if a partition name is in both the GPT and the super partition, we
292 // return "true", to be consistent with prefering to flash logical partitions
293 // over physical ones.
294 std::string partition_name = args[0];
295 if (LogicalPartitionExists(partition_name, device->GetCurrentSlot())) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700296 *message = "yes";
297 return true;
David Anderson0d4277d2018-07-31 13:27:37 -0700298 }
299 if (FindPhysicalPartition(partition_name)) {
David Anderson1fb3fd72018-08-31 14:40:22 -0700300 *message = "no";
301 return true;
David Anderson0d4277d2018-07-31 13:27:37 -0700302 }
David Anderson1fb3fd72018-08-31 14:40:22 -0700303 *message = "Partition not found";
304 return false;
David Anderson0d4277d2018-07-31 13:27:37 -0700305}
David Andersond9ba0612018-08-02 11:05:00 -0700306
David Anderson1fb3fd72018-08-31 14:40:22 -0700307bool GetIsUserspace(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
308 std::string* message) {
309 *message = "yes";
310 return true;
David Andersond9ba0612018-08-02 11:05:00 -0700311}
David Anderson0f626632018-08-31 16:44:25 -0700312
313std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device) {
314 std::vector<std::vector<std::string>> args;
315 auto partitions = ListPartitions(device);
316 for (const auto& partition : partitions) {
317 args.emplace_back(std::initializer_list<std::string>{partition});
318 }
319 return args;
320}
321
322std::vector<std::vector<std::string>> GetAllPartitionArgsNoSlot(FastbootDevice* device) {
323 auto partitions = ListPartitions(device);
324
325 std::string slot_suffix = device->GetCurrentSlot();
326 if (!slot_suffix.empty()) {
327 auto names = std::move(partitions);
328 for (const auto& name : names) {
329 std::string slotless_name = name;
330 if (android::base::EndsWith(name, "_a") || android::base::EndsWith(name, "_b")) {
331 slotless_name = name.substr(0, name.rfind("_"));
332 }
333 if (std::find(partitions.begin(), partitions.end(), slotless_name) ==
334 partitions.end()) {
335 partitions.emplace_back(slotless_name);
336 }
337 }
338 }
339
340 std::vector<std::vector<std::string>> args;
341 for (const auto& partition : partitions) {
342 args.emplace_back(std::initializer_list<std::string>{partition});
343 }
344 return args;
345}
David Andersonc091c172018-09-04 18:11:03 -0700346
347bool GetHardwareRevision(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
348 std::string* message) {
349 *message = android::base::GetProperty("ro.revision", "");
350 return true;
351}