#pragma once #include namespace ota::installation { enum class Progress { Idle, Writing, Prepared, TrialRequested }; enum class BootRecord { ASelected, BTrial, Invalid }; enum class WriteResult { OldRecord, NewRecord, InvalidRecord }; enum class RecoveryAction { RestartPreparation, ReadyToActivate, PreserveTrial, SeparateRecovery }; // This object stands for persistent storage. Each assignment is a completed // durable operation in the model, not a real storage implementation. struct Storage { std::string a_contents = "release-1"; std::string b_contents; std::string release; Progress progress = Progress::Idle; BootRecord boot = BootRecord::ASelected; int attempts_left = 0; }; const std::string &expected_contents(); const char *name(RecoveryAction action); const char *boot_choice(BootRecord record); class Installer { public: explicit Installer(Storage &storage) : storage_(storage) {} void begin(); void write_partial(); void finish_write(); void verify(); void save_prepared(); void request_trial(WriteResult result = WriteResult::NewRecord); void save_requested(); RecoveryAction recover(); private: void require_writable() const; Storage &storage_; // Lost when the installer is reconstructed after a simulated reset. bool verified_ = false; }; // Ordered operations; cut points are before step 0 and after each step. constexpr int installation_steps = 7; void perform_step(Installer &installer, int step); }// namespace ota::installation