xref: /aosp_15_r20/bootable/recovery/fastboot/fastboot.cpp (revision e7c364b630b241adcb6c7726a21055250b91fdac)
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 "fastboot.h"
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 
22 #include <algorithm>
23 #include <string>
24 #include <vector>
25 
26 #include <android-base/logging.h>
27 #include <android-base/properties.h>
28 #include <bootloader_message/bootloader_message.h>
29 
30 #include "recovery_ui/ui.h"
31 
32 static const std::vector<std::pair<std::string, Device::BuiltinAction>> kFastbootMenuActions{
33   { "Reboot system now", Device::REBOOT_FROM_FASTBOOT },
34   { "Enter recovery", Device::ENTER_RECOVERY },
35   { "Reboot to bootloader", Device::REBOOT_BOOTLOADER },
36   { "Power off", Device::SHUTDOWN_FROM_FASTBOOT },
37 };
38 
FillDefaultFastbootLines(std::vector<std::string> & title_lines)39 void FillDefaultFastbootLines(std::vector<std::string>& title_lines) {
40   title_lines.push_back("Android Fastboot");
41   title_lines.push_back("Product name - " + android::base::GetProperty("ro.product.device", ""));
42   title_lines.push_back("Bootloader version - " + android::base::GetProperty("ro.bootloader", ""));
43   title_lines.push_back("Baseband version - " +
44                         android::base::GetProperty("ro.build.expect.baseband", ""));
45   title_lines.push_back("Serial number - " + android::base::GetProperty("ro.serialno", ""));
46   title_lines.push_back(std::string("Secure boot - ") +
47                         ((android::base::GetProperty("ro.secure", "") == "1") ? "yes" : "no"));
48   title_lines.push_back("HW version - " + android::base::GetProperty("ro.revision", ""));
49 }
50 
FillWearableFastbootLines(std::vector<std::string> & title_lines)51 void FillWearableFastbootLines(std::vector<std::string>& title_lines) {
52   title_lines.push_back("Android Fastboot");
53   title_lines.push_back(android::base::GetProperty("ro.product.device", "") + " - " +
54                         android::base::GetProperty("ro.revision", ""));
55   title_lines.push_back(android::base::GetProperty("ro.bootloader", ""));
56 
57   const size_t max_baseband_len = 24;
58   const std::string& baseband = android::base::GetProperty("ro.build.expect.baseband", "");
59   title_lines.push_back(baseband.length() > max_baseband_len
60                             ? baseband.substr(0, max_baseband_len - 3) + "..."
61                             : baseband);
62 
63   title_lines.push_back("Serial #: " + android::base::GetProperty("ro.serialno", ""));
64 }
65 
StartFastboot(Device * device,const std::vector<std::string> &)66 Device::BuiltinAction StartFastboot(Device* device, const std::vector<std::string>& /* args */) {
67   RecoveryUI* ui = device->GetUI();
68   std::vector<std::string> title_lines;
69 
70   if (ui->IsWearable()) {
71     FillWearableFastbootLines(title_lines);
72   } else {
73     ui->SetEnableFastbootdLogo(true);
74     FillDefaultFastbootLines(title_lines);
75   }
76 
77   ui->ResetKeyInterruptStatus();
78   ui->SetTitle(title_lines);
79   ui->ShowText(true);
80   device->StartFastboot();
81 
82   // Reset to normal system boot so recovery won't cycle indefinitely.
83   // TODO(b/112277594) Clear only if 'recovery' field of BCB is empty. If not,
84   // set the 'command' field of BCB to 'boot-recovery' so the next boot is into recovery
85   // to finish any interrupted tasks.
86   std::string err;
87   if (!clear_bootloader_message(&err)) {
88     LOG(ERROR) << "Failed to clear BCB message: " << err;
89   }
90 
91   std::vector<std::string> fastboot_menu_items;
92   std::transform(kFastbootMenuActions.cbegin(), kFastbootMenuActions.cend(),
93                  std::back_inserter(fastboot_menu_items),
94                  [](const auto& entry) { return entry.first; });
95 
96   auto chosen_item = ui->ShowMenu(
97       {}, fastboot_menu_items, 0, false,
98       std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2));
99 
100   if (chosen_item == static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED)) {
101     return Device::KEY_INTERRUPTED;
102   }
103   if (chosen_item == static_cast<size_t>(RecoveryUI::KeyError::TIMED_OUT)) {
104     return Device::BuiltinAction::NO_ACTION;
105   }
106   return kFastbootMenuActions[chosen_item].second;
107 }
108