xref: /aosp_15_r20/bootable/recovery/fastboot/fastboot.cpp (revision e7c364b630b241adcb6c7726a21055250b91fdac)
1*e7c364b6SAndroid Build Coastguard Worker /*
2*e7c364b6SAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*e7c364b6SAndroid Build Coastguard Worker  *
4*e7c364b6SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e7c364b6SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e7c364b6SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e7c364b6SAndroid Build Coastguard Worker  *
8*e7c364b6SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e7c364b6SAndroid Build Coastguard Worker  *
10*e7c364b6SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e7c364b6SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e7c364b6SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e7c364b6SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e7c364b6SAndroid Build Coastguard Worker  * limitations under the License.
15*e7c364b6SAndroid Build Coastguard Worker  */
16*e7c364b6SAndroid Build Coastguard Worker 
17*e7c364b6SAndroid Build Coastguard Worker #include "fastboot.h"
18*e7c364b6SAndroid Build Coastguard Worker 
19*e7c364b6SAndroid Build Coastguard Worker #include <stdio.h>
20*e7c364b6SAndroid Build Coastguard Worker #include <stdlib.h>
21*e7c364b6SAndroid Build Coastguard Worker 
22*e7c364b6SAndroid Build Coastguard Worker #include <algorithm>
23*e7c364b6SAndroid Build Coastguard Worker #include <string>
24*e7c364b6SAndroid Build Coastguard Worker #include <vector>
25*e7c364b6SAndroid Build Coastguard Worker 
26*e7c364b6SAndroid Build Coastguard Worker #include <android-base/logging.h>
27*e7c364b6SAndroid Build Coastguard Worker #include <android-base/properties.h>
28*e7c364b6SAndroid Build Coastguard Worker #include <bootloader_message/bootloader_message.h>
29*e7c364b6SAndroid Build Coastguard Worker 
30*e7c364b6SAndroid Build Coastguard Worker #include "recovery_ui/ui.h"
31*e7c364b6SAndroid Build Coastguard Worker 
32*e7c364b6SAndroid Build Coastguard Worker static const std::vector<std::pair<std::string, Device::BuiltinAction>> kFastbootMenuActions{
33*e7c364b6SAndroid Build Coastguard Worker   { "Reboot system now", Device::REBOOT_FROM_FASTBOOT },
34*e7c364b6SAndroid Build Coastguard Worker   { "Enter recovery", Device::ENTER_RECOVERY },
35*e7c364b6SAndroid Build Coastguard Worker   { "Reboot to bootloader", Device::REBOOT_BOOTLOADER },
36*e7c364b6SAndroid Build Coastguard Worker   { "Power off", Device::SHUTDOWN_FROM_FASTBOOT },
37*e7c364b6SAndroid Build Coastguard Worker };
38*e7c364b6SAndroid Build Coastguard Worker 
FillDefaultFastbootLines(std::vector<std::string> & title_lines)39*e7c364b6SAndroid Build Coastguard Worker void FillDefaultFastbootLines(std::vector<std::string>& title_lines) {
40*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back("Android Fastboot");
41*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back("Product name - " + android::base::GetProperty("ro.product.device", ""));
42*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back("Bootloader version - " + android::base::GetProperty("ro.bootloader", ""));
43*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back("Baseband version - " +
44*e7c364b6SAndroid Build Coastguard Worker                         android::base::GetProperty("ro.build.expect.baseband", ""));
45*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back("Serial number - " + android::base::GetProperty("ro.serialno", ""));
46*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back(std::string("Secure boot - ") +
47*e7c364b6SAndroid Build Coastguard Worker                         ((android::base::GetProperty("ro.secure", "") == "1") ? "yes" : "no"));
48*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back("HW version - " + android::base::GetProperty("ro.revision", ""));
49*e7c364b6SAndroid Build Coastguard Worker }
50*e7c364b6SAndroid Build Coastguard Worker 
FillWearableFastbootLines(std::vector<std::string> & title_lines)51*e7c364b6SAndroid Build Coastguard Worker void FillWearableFastbootLines(std::vector<std::string>& title_lines) {
52*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back("Android Fastboot");
53*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back(android::base::GetProperty("ro.product.device", "") + " - " +
54*e7c364b6SAndroid Build Coastguard Worker                         android::base::GetProperty("ro.revision", ""));
55*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back(android::base::GetProperty("ro.bootloader", ""));
56*e7c364b6SAndroid Build Coastguard Worker 
57*e7c364b6SAndroid Build Coastguard Worker   const size_t max_baseband_len = 24;
58*e7c364b6SAndroid Build Coastguard Worker   const std::string& baseband = android::base::GetProperty("ro.build.expect.baseband", "");
59*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back(baseband.length() > max_baseband_len
60*e7c364b6SAndroid Build Coastguard Worker                             ? baseband.substr(0, max_baseband_len - 3) + "..."
61*e7c364b6SAndroid Build Coastguard Worker                             : baseband);
62*e7c364b6SAndroid Build Coastguard Worker 
63*e7c364b6SAndroid Build Coastguard Worker   title_lines.push_back("Serial #: " + android::base::GetProperty("ro.serialno", ""));
64*e7c364b6SAndroid Build Coastguard Worker }
65*e7c364b6SAndroid Build Coastguard Worker 
StartFastboot(Device * device,const std::vector<std::string> &)66*e7c364b6SAndroid Build Coastguard Worker Device::BuiltinAction StartFastboot(Device* device, const std::vector<std::string>& /* args */) {
67*e7c364b6SAndroid Build Coastguard Worker   RecoveryUI* ui = device->GetUI();
68*e7c364b6SAndroid Build Coastguard Worker   std::vector<std::string> title_lines;
69*e7c364b6SAndroid Build Coastguard Worker 
70*e7c364b6SAndroid Build Coastguard Worker   if (ui->IsWearable()) {
71*e7c364b6SAndroid Build Coastguard Worker     FillWearableFastbootLines(title_lines);
72*e7c364b6SAndroid Build Coastguard Worker   } else {
73*e7c364b6SAndroid Build Coastguard Worker     ui->SetEnableFastbootdLogo(true);
74*e7c364b6SAndroid Build Coastguard Worker     FillDefaultFastbootLines(title_lines);
75*e7c364b6SAndroid Build Coastguard Worker   }
76*e7c364b6SAndroid Build Coastguard Worker 
77*e7c364b6SAndroid Build Coastguard Worker   ui->ResetKeyInterruptStatus();
78*e7c364b6SAndroid Build Coastguard Worker   ui->SetTitle(title_lines);
79*e7c364b6SAndroid Build Coastguard Worker   ui->ShowText(true);
80*e7c364b6SAndroid Build Coastguard Worker   device->StartFastboot();
81*e7c364b6SAndroid Build Coastguard Worker 
82*e7c364b6SAndroid Build Coastguard Worker   // Reset to normal system boot so recovery won't cycle indefinitely.
83*e7c364b6SAndroid Build Coastguard Worker   // TODO(b/112277594) Clear only if 'recovery' field of BCB is empty. If not,
84*e7c364b6SAndroid Build Coastguard Worker   // set the 'command' field of BCB to 'boot-recovery' so the next boot is into recovery
85*e7c364b6SAndroid Build Coastguard Worker   // to finish any interrupted tasks.
86*e7c364b6SAndroid Build Coastguard Worker   std::string err;
87*e7c364b6SAndroid Build Coastguard Worker   if (!clear_bootloader_message(&err)) {
88*e7c364b6SAndroid Build Coastguard Worker     LOG(ERROR) << "Failed to clear BCB message: " << err;
89*e7c364b6SAndroid Build Coastguard Worker   }
90*e7c364b6SAndroid Build Coastguard Worker 
91*e7c364b6SAndroid Build Coastguard Worker   std::vector<std::string> fastboot_menu_items;
92*e7c364b6SAndroid Build Coastguard Worker   std::transform(kFastbootMenuActions.cbegin(), kFastbootMenuActions.cend(),
93*e7c364b6SAndroid Build Coastguard Worker                  std::back_inserter(fastboot_menu_items),
94*e7c364b6SAndroid Build Coastguard Worker                  [](const auto& entry) { return entry.first; });
95*e7c364b6SAndroid Build Coastguard Worker 
96*e7c364b6SAndroid Build Coastguard Worker   auto chosen_item = ui->ShowMenu(
97*e7c364b6SAndroid Build Coastguard Worker       {}, fastboot_menu_items, 0, false,
98*e7c364b6SAndroid Build Coastguard Worker       std::bind(&Device::HandleMenuKey, device, std::placeholders::_1, std::placeholders::_2));
99*e7c364b6SAndroid Build Coastguard Worker 
100*e7c364b6SAndroid Build Coastguard Worker   if (chosen_item == static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED)) {
101*e7c364b6SAndroid Build Coastguard Worker     return Device::KEY_INTERRUPTED;
102*e7c364b6SAndroid Build Coastguard Worker   }
103*e7c364b6SAndroid Build Coastguard Worker   if (chosen_item == static_cast<size_t>(RecoveryUI::KeyError::TIMED_OUT)) {
104*e7c364b6SAndroid Build Coastguard Worker     return Device::BuiltinAction::NO_ACTION;
105*e7c364b6SAndroid Build Coastguard Worker   }
106*e7c364b6SAndroid Build Coastguard Worker   return kFastbootMenuActions[chosen_item].second;
107*e7c364b6SAndroid Build Coastguard Worker }
108