mirror of
https://github.com/NixOS/mobile-nixos.git
synced 2024-12-16 20:21:32 +03:00
Merge pull request #245 from samueldr-wip/feature/stage-1-recovery-acknowledge
stage-1: Acknowledge recovery boot mode
This commit is contained in:
commit
8f1cf6fca9
@ -49,6 +49,7 @@ module Tasks
|
||||
# Update the current progress
|
||||
count = @tasks.length.to_f
|
||||
Progress.update({progress: (100 * (1 - (todo.length / count))).ceil})
|
||||
Progress.update({recovery: Hal::Recovery.wants_recovery?})
|
||||
|
||||
todo.each do |task|
|
||||
if task._try_run_task then
|
||||
|
@ -82,7 +82,7 @@ class Tasks::SwitchRoot < SingletonTask
|
||||
|
||||
# May pause the boot to allow the user to select a generation.
|
||||
def selected_generation()
|
||||
if user_wants_selection()
|
||||
if Hal::Recovery.wants_recovery?
|
||||
generate_selection()
|
||||
# FIXME: In the future, boot GUIs will be launched async, before this
|
||||
# task is ran.
|
||||
@ -102,50 +102,8 @@ class Tasks::SwitchRoot < SingletonTask
|
||||
end
|
||||
end
|
||||
|
||||
def boot_as_recovery_wants_recovery()
|
||||
# "Boot as recovery" systems do not have a discrete recovery partition.
|
||||
# For those systems, when `[s_]kip_initramfs` is in the kernel cmdline, we
|
||||
# know the intent is to boot the normal system.
|
||||
# Is a "boot as recovery" device, and Is `[s_]kip_initramfs` missing?
|
||||
Configuration["device"]["boot_as_recovery"] and
|
||||
!File.read("/proc/cmdline").split(/\s+/).grep(/[s_]kip_initramfs/).any?
|
||||
end
|
||||
|
||||
def is_recovery()
|
||||
# Check in /etc/boot/config for `is_recovery`, it's assumed to be set, and
|
||||
# true, for recovery.img.
|
||||
Configuration["is_recovery"] or
|
||||
boot_as_recovery_wants_recovery
|
||||
end
|
||||
|
||||
def is_boot_interrupted()
|
||||
keys = [
|
||||
# Keys used for "mobile" use-cases
|
||||
:KEY_VOLUMEUP,
|
||||
:KEY_VOLUMEDOWN,
|
||||
# Keys used for "computer" use-cases
|
||||
:KEY_LEFTCTRL,
|
||||
:KEY_RIGHTCTRL,
|
||||
:KEY_LEFTSHIFT,
|
||||
:KEY_RIGHTSHIFT,
|
||||
:KEY_ESC,
|
||||
]
|
||||
|
||||
Evdev.keys_held(keys)
|
||||
end
|
||||
|
||||
# Checks if the user wants to select a generation.
|
||||
def user_wants_selection()
|
||||
[
|
||||
# Booted a recovery partition.
|
||||
is_recovery,
|
||||
# Or signaling the boot selection menu should be shown.
|
||||
is_boot_interrupted,
|
||||
].any?
|
||||
end
|
||||
|
||||
def run()
|
||||
if user_wants_selection
|
||||
if Hal::Recovery.wants_recovery?
|
||||
Tasks::Splash.instance.quit("Continuing to recovery menu")
|
||||
else
|
||||
Tasks::Splash.instance.quit("Continuing to stage-2")
|
||||
|
51
boot/lib/hal/recovery.rb
Normal file
51
boot/lib/hal/recovery.rb
Normal file
@ -0,0 +1,51 @@
|
||||
module Hal
|
||||
module Recovery
|
||||
extend self
|
||||
|
||||
KEYS = [
|
||||
# Keys used for "mobile" use-cases
|
||||
:KEY_VOLUMEUP,
|
||||
:KEY_VOLUMEDOWN,
|
||||
# Keys used for "computer" use-cases
|
||||
:KEY_LEFTCTRL,
|
||||
:KEY_RIGHTCTRL,
|
||||
:KEY_LEFTSHIFT,
|
||||
:KEY_RIGHTSHIFT,
|
||||
:KEY_ESC,
|
||||
]
|
||||
|
||||
def firmware_wants_recovery?()
|
||||
# "Boot as recovery" systems do not have a discrete recovery partition.
|
||||
# For those systems, when `[s_]kip_initramfs` is in the kernel cmdline, we
|
||||
# know the intent is to boot the normal system.
|
||||
# Is a "boot as recovery" device, and Is `[s_]kip_initramfs` missing?
|
||||
if Configuration["device"]["boot_as_recovery"] then
|
||||
if File.exists?("/proc/cmdline") then
|
||||
!File.read("/proc/cmdline").split(/\s+/).grep(/[s_]kip_initramfs/).any?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Is this boot image a recovery image, or booted into recovery mode by the
|
||||
# device firmware?
|
||||
def is_recovery?()
|
||||
# Check in /etc/boot/config for `is_recovery`, it's assumed to be set, and
|
||||
# true, for recovery builds.
|
||||
Configuration["is_recovery"] or firmware_wants_recovery?
|
||||
end
|
||||
|
||||
# Is the normal boot flow interrupted by a key input?
|
||||
def boot_interrupted?()
|
||||
Evdev.keys_held(KEYS)
|
||||
end
|
||||
|
||||
def wants_recovery?
|
||||
[
|
||||
# Booted a recovery partition.
|
||||
is_recovery?,
|
||||
# Or signaling the boot selection menu should be shown.
|
||||
boot_interrupted?,
|
||||
].any?
|
||||
end
|
||||
end
|
||||
end
|
@ -26,6 +26,7 @@ class UI
|
||||
add_logo
|
||||
add_progress_bar
|
||||
add_label
|
||||
add_recovery
|
||||
|
||||
add_textarea
|
||||
add_keyboard
|
||||
@ -99,6 +100,34 @@ class UI
|
||||
end
|
||||
end
|
||||
|
||||
def add_recovery()
|
||||
@recovery_container = LVGL::LVContainer.new(@page)
|
||||
@recovery_container.set_hidden(true)
|
||||
@recovery_container.set_width(@page.get_width)
|
||||
@recovery_container.get_style(LVGL::CONT_STYLE::MAIN).dup.tap do |style|
|
||||
@recovery_container.set_style(LVGL::CONT_STYLE::MAIN, style)
|
||||
style.body_main_color = 0xFF000000
|
||||
style.body_grad_color = 0xFF000000
|
||||
style.body_border_width = 0
|
||||
end
|
||||
|
||||
recovery_label = LVGL::LVLabel.new(@recovery_container)
|
||||
recovery_label.get_style(LVGL::LABEL_STYLE::MAIN).dup.tap do |style|
|
||||
recovery_label.set_style(LVGL::LABEL_STYLE::MAIN, style)
|
||||
style.text_color = 0xFFFFFFFF
|
||||
end
|
||||
recovery_label.set_long_mode(LVGL::LABEL_LONG::BREAK)
|
||||
recovery_label.set_align(LVGL::LABEL_ALIGN::CENTER)
|
||||
|
||||
recovery_label.set_width(@recovery_container.get_width() * 0.9)
|
||||
recovery_label.set_text("Booting to recovery menu")
|
||||
recovery_label.set_x(@recovery_container.get_width()/2 - recovery_label.get_width()/2)
|
||||
recovery_label.set_y(@unit)
|
||||
|
||||
@recovery_container.set_height(recovery_label.get_height() + 2*@unit)
|
||||
@recovery_container.set_pos(0, @page.get_height() - @recovery_container.get_height())
|
||||
end
|
||||
|
||||
# Used to handle fade-in/fade-out
|
||||
# This is because opacity handles multiple overlaid objects wrong.
|
||||
def add_cover()
|
||||
@ -167,6 +196,10 @@ class UI
|
||||
end
|
||||
end
|
||||
|
||||
def show_recovery_notice(val = true)
|
||||
@recovery_container.set_hidden(!val)
|
||||
end
|
||||
|
||||
def offset_page(delta)
|
||||
LVGL::LVAnim.new().tap do |anim|
|
||||
anim.set_exec_cb(@page, :lv_obj_set_y)
|
||||
|
@ -42,6 +42,19 @@ LVGUI.main_loop do
|
||||
p msg
|
||||
end
|
||||
|
||||
# Update the UI...
|
||||
|
||||
# First updating the current progress
|
||||
ui.set_progress(msg["progress"])
|
||||
ui.show_recovery_notice(msg["recovery"])
|
||||
|
||||
# Update the label as needed.
|
||||
if msg["label"]
|
||||
ui.set_label(msg["label"])
|
||||
else
|
||||
ui.set_label("")
|
||||
end
|
||||
|
||||
# We might have a special command; handle it.
|
||||
if msg["command"] then
|
||||
command = msg["command"]
|
||||
@ -68,18 +81,6 @@ LVGUI.main_loop do
|
||||
$stderr.puts "[splash] Unexpected command #{command.to_json}..."
|
||||
end
|
||||
end
|
||||
|
||||
# Update the UI...
|
||||
|
||||
# First updating the current progress
|
||||
ui.set_progress(msg["progress"])
|
||||
|
||||
# And updating the label as needed.
|
||||
if msg["label"]
|
||||
ui.set_label(msg["label"])
|
||||
else
|
||||
ui.set_label("")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user