1
1
mirror of https://github.com/NixOS/mobile-nixos.git synced 2024-12-18 21:41:53 +03:00
mobile-nixos/boot/recovery-menu/main.rb
Samuel Dionne-Riel fb4984cb90 s/boot-gui/boot-recovery-menu/g
The applet is specifically written to show what we call the "recovery
menu". Yes, it's also the boot selection, but it will get confusing with
the upcoming boot tracking splash UI that's upcoming.
2020-10-27 15:23:40 -04:00

122 lines
3.5 KiB
Ruby

# File with boot selection
SELECTIONS = "/run/boot/selection.json"
# Runs and prints a command. Probably.
def run(*cmd)
$stderr.puts " $ " + cmd.join(" ")
system(*cmd) unless LVGL::Introspection.simulator?
end
module RebootModes
Android = {
"recovery" => ["Reboot to recovery", ->() { run("reboot recovery") }],
"bootloader" => ["Reboot to bootloader", ->() { run("reboot bootloader") }],
}
def self.options()
[
["Reboot to system", ->() { run("reboot") }],
] +
Configuration["HAL"]["boot"]["rebootModes"].map do |identifier|
const, key = identifier.split(".", 2)
const_get(const)[key]
end
end
end
module BootGUI
class MainWindow < LVGUI::BaseWindow
include LVGUI::ButtonPalette
# Add the logo to the view.
def logo()
# Try to find the logo, but don't fail if there isn't one.
file = nil
file = "/etc/logo.svg" if File.exist?("/etc/logo.svg")
file = "./logo.svg" if File.exist?("./logo.svg")
return unless file
if @container.get_height > @container.get_width
LVGL::Hacks::LVNanoSVG.resize_next_width((@container.get_width_fit * 0.8).to_i)
else
# Detecting the available space where the layout will stretch into is
# apparently hard with lvgl, thus we rely on the vertical resolution.
# Meh, that's not *so* bad.
# While it's a crude approximation, for layouting it's fine.
LVGL::Hacks::LVNanoSVG.resize_next_height((@container.get_height * 0.15).to_i)
end
@logo = LVGL::LVImage.new(@container)
@logo.set_src(file)
end
def initialize()
super()
# Add the logo
logo
# An explanatory label
LVGL::LVLabel.new(@container).tap do |label|
label.set_long_mode(LVGL::LABEL_LONG::BREAK)
label.set_text(%Q{Your device booted in recovery mode.})
label.set_align(LVGL::LABEL_ALIGN::CENTER)
label.set_width(@container.get_width_fit)
end
# Our buttons palette!
add_buttons([
["Generations #{LVGL::Symbols::RIGHT}", ->() { GenerationsWindow.instance.present }],
*(RebootModes.options),
["Power off", ->() { run("poweroff") }],
])
end
end
# Shows the list of generations to boot into.
class GenerationsWindow < LVGUI::BaseWindow
include LVGUI::ButtonPalette
include LVGUI::Window::WithBackButton
goes_back_to ->() { MainWindow.instance }
def initialize()
super()
if File.exist?(::SELECTIONS)
JSON.parse(File.read(::SELECTIONS)).each do |selection|
add_button(selection["name"]) do
File.open("/run/boot/choice", "w") do |file|
file.write(selection["id"])
end
# Put back the console on the framebuffer
VTConsole.map_console(1)
exit 0
end
end
else
LVGL::LVLabel.new(@container).tap do |label|
text = "No generations could be found.\n\n"
if LVGL::Introspection.simulator?
text += "This is normal in the simulator."
else
text += "This is anormal, and may be a sign of things being wrong."
end
label.set_long_mode(LVGL::LABEL_LONG::BREAK)
label.set_text(text)
label.set_align(LVGL::LABEL_ALIGN::CENTER)
label.set_width(@container.get_width_fit)
end
end
end
end
end
# We need to start somewhere...
BootGUI::MainWindow.instance.present
# And keep the GUI active.
LVGUI.main_loop