1*5a923131SAndroid Build Coastguard Worker // 2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2015 The Android Open Source Project 3*5a923131SAndroid Build Coastguard Worker // 4*5a923131SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 5*5a923131SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 6*5a923131SAndroid Build Coastguard Worker // You may obtain a copy of the License at 7*5a923131SAndroid Build Coastguard Worker // 8*5a923131SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 9*5a923131SAndroid Build Coastguard Worker // 10*5a923131SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 11*5a923131SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 12*5a923131SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*5a923131SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 14*5a923131SAndroid Build Coastguard Worker // limitations under the License. 15*5a923131SAndroid Build Coastguard Worker // 16*5a923131SAndroid Build Coastguard Worker 17*5a923131SAndroid Build Coastguard Worker #ifndef UPDATE_ENGINE_COMMON_FAKE_BOOT_CONTROL_H_ 18*5a923131SAndroid Build Coastguard Worker #define UPDATE_ENGINE_COMMON_FAKE_BOOT_CONTROL_H_ 19*5a923131SAndroid Build Coastguard Worker 20*5a923131SAndroid Build Coastguard Worker #include <map> 21*5a923131SAndroid Build Coastguard Worker #include <memory> 22*5a923131SAndroid Build Coastguard Worker #include <string> 23*5a923131SAndroid Build Coastguard Worker #include <vector> 24*5a923131SAndroid Build Coastguard Worker 25*5a923131SAndroid Build Coastguard Worker #include <base/time/time.h> 26*5a923131SAndroid Build Coastguard Worker 27*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/boot_control_interface.h" 28*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/dynamic_partition_control_stub.h" 29*5a923131SAndroid Build Coastguard Worker 30*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine { 31*5a923131SAndroid Build Coastguard Worker 32*5a923131SAndroid Build Coastguard Worker // Implements a fake bootloader control interface used for testing. 33*5a923131SAndroid Build Coastguard Worker class FakeBootControl : public BootControlInterface { 34*5a923131SAndroid Build Coastguard Worker public: FakeBootControl()35*5a923131SAndroid Build Coastguard Worker FakeBootControl() { 36*5a923131SAndroid Build Coastguard Worker SetNumSlots(num_slots_); 37*5a923131SAndroid Build Coastguard Worker // The current slot should be bootable. 38*5a923131SAndroid Build Coastguard Worker is_bootable_[current_slot_] = true; 39*5a923131SAndroid Build Coastguard Worker 40*5a923131SAndroid Build Coastguard Worker dynamic_partition_control_.reset(new DynamicPartitionControlStub()); 41*5a923131SAndroid Build Coastguard Worker } 42*5a923131SAndroid Build Coastguard Worker 43*5a923131SAndroid Build Coastguard Worker // BootControlInterface overrides. GetNumSlots()44*5a923131SAndroid Build Coastguard Worker unsigned int GetNumSlots() const override { return num_slots_; } GetCurrentSlot()45*5a923131SAndroid Build Coastguard Worker BootControlInterface::Slot GetCurrentSlot() const override { 46*5a923131SAndroid Build Coastguard Worker return current_slot_; 47*5a923131SAndroid Build Coastguard Worker } 48*5a923131SAndroid Build Coastguard Worker GetPartitionDevice(const std::string & partition_name,BootControlInterface::Slot slot,bool not_in_payload,std::string * device,bool * is_dynamic)49*5a923131SAndroid Build Coastguard Worker bool GetPartitionDevice(const std::string& partition_name, 50*5a923131SAndroid Build Coastguard Worker BootControlInterface::Slot slot, 51*5a923131SAndroid Build Coastguard Worker bool not_in_payload, 52*5a923131SAndroid Build Coastguard Worker std::string* device, 53*5a923131SAndroid Build Coastguard Worker bool* is_dynamic) const override { 54*5a923131SAndroid Build Coastguard Worker auto dev = 55*5a923131SAndroid Build Coastguard Worker GetPartitionDevice(partition_name, slot, current_slot_, not_in_payload); 56*5a923131SAndroid Build Coastguard Worker if (!dev.has_value()) { 57*5a923131SAndroid Build Coastguard Worker return false; 58*5a923131SAndroid Build Coastguard Worker } 59*5a923131SAndroid Build Coastguard Worker if (is_dynamic) { 60*5a923131SAndroid Build Coastguard Worker *is_dynamic = dev->is_dynamic; 61*5a923131SAndroid Build Coastguard Worker } 62*5a923131SAndroid Build Coastguard Worker if (device) { 63*5a923131SAndroid Build Coastguard Worker *device = dev->rw_device_path; 64*5a923131SAndroid Build Coastguard Worker } 65*5a923131SAndroid Build Coastguard Worker return true; 66*5a923131SAndroid Build Coastguard Worker } 67*5a923131SAndroid Build Coastguard Worker GetPartitionDevice(const std::string & partition_name,BootControlInterface::Slot slot,std::string * device)68*5a923131SAndroid Build Coastguard Worker bool GetPartitionDevice(const std::string& partition_name, 69*5a923131SAndroid Build Coastguard Worker BootControlInterface::Slot slot, 70*5a923131SAndroid Build Coastguard Worker std::string* device) const override { 71*5a923131SAndroid Build Coastguard Worker return GetPartitionDevice(partition_name, slot, false, device, nullptr); 72*5a923131SAndroid Build Coastguard Worker } 73*5a923131SAndroid Build Coastguard Worker IsSlotBootable(BootControlInterface::Slot slot)74*5a923131SAndroid Build Coastguard Worker bool IsSlotBootable(BootControlInterface::Slot slot) const override { 75*5a923131SAndroid Build Coastguard Worker return slot < num_slots_ && is_bootable_[slot]; 76*5a923131SAndroid Build Coastguard Worker } 77*5a923131SAndroid Build Coastguard Worker MarkSlotUnbootable(BootControlInterface::Slot slot)78*5a923131SAndroid Build Coastguard Worker bool MarkSlotUnbootable(BootControlInterface::Slot slot) override { 79*5a923131SAndroid Build Coastguard Worker if (slot >= num_slots_) 80*5a923131SAndroid Build Coastguard Worker return false; 81*5a923131SAndroid Build Coastguard Worker is_bootable_[slot] = false; 82*5a923131SAndroid Build Coastguard Worker return true; 83*5a923131SAndroid Build Coastguard Worker } 84*5a923131SAndroid Build Coastguard Worker SetActiveBootSlot(Slot slot)85*5a923131SAndroid Build Coastguard Worker bool SetActiveBootSlot(Slot slot) override { return true; } GetActiveBootSlot()86*5a923131SAndroid Build Coastguard Worker Slot GetActiveBootSlot() override { return kInvalidSlot; } 87*5a923131SAndroid Build Coastguard Worker MarkBootSuccessfulAsync(base::Callback<void (bool)> callback)88*5a923131SAndroid Build Coastguard Worker bool MarkBootSuccessfulAsync(base::Callback<void(bool)> callback) override { 89*5a923131SAndroid Build Coastguard Worker // We run the callback directly from here to avoid having to setup a message 90*5a923131SAndroid Build Coastguard Worker // loop in the test environment. 91*5a923131SAndroid Build Coastguard Worker is_marked_successful_[GetCurrentSlot()] = true; 92*5a923131SAndroid Build Coastguard Worker callback.Run(true); 93*5a923131SAndroid Build Coastguard Worker return true; 94*5a923131SAndroid Build Coastguard Worker } 95*5a923131SAndroid Build Coastguard Worker IsSlotMarkedSuccessful(Slot slot)96*5a923131SAndroid Build Coastguard Worker bool IsSlotMarkedSuccessful(Slot slot) const override { 97*5a923131SAndroid Build Coastguard Worker return slot < num_slots_ && is_marked_successful_[slot]; 98*5a923131SAndroid Build Coastguard Worker } 99*5a923131SAndroid Build Coastguard Worker 100*5a923131SAndroid Build Coastguard Worker // Setters SetNumSlots(unsigned int num_slots)101*5a923131SAndroid Build Coastguard Worker void SetNumSlots(unsigned int num_slots) { 102*5a923131SAndroid Build Coastguard Worker num_slots_ = num_slots; 103*5a923131SAndroid Build Coastguard Worker is_bootable_.resize(num_slots_, false); 104*5a923131SAndroid Build Coastguard Worker is_marked_successful_.resize(num_slots_, false); 105*5a923131SAndroid Build Coastguard Worker devices_.resize(num_slots_); 106*5a923131SAndroid Build Coastguard Worker } 107*5a923131SAndroid Build Coastguard Worker SetCurrentSlot(BootControlInterface::Slot slot)108*5a923131SAndroid Build Coastguard Worker void SetCurrentSlot(BootControlInterface::Slot slot) { current_slot_ = slot; } 109*5a923131SAndroid Build Coastguard Worker SetPartitionDevice(const std::string & partition_name,BootControlInterface::Slot slot,const std::string & device)110*5a923131SAndroid Build Coastguard Worker void SetPartitionDevice(const std::string& partition_name, 111*5a923131SAndroid Build Coastguard Worker BootControlInterface::Slot slot, 112*5a923131SAndroid Build Coastguard Worker const std::string& device) { 113*5a923131SAndroid Build Coastguard Worker DCHECK(slot < num_slots_); 114*5a923131SAndroid Build Coastguard Worker devices_[slot][partition_name] = device; 115*5a923131SAndroid Build Coastguard Worker } 116*5a923131SAndroid Build Coastguard Worker SetSlotBootable(BootControlInterface::Slot slot,bool bootable)117*5a923131SAndroid Build Coastguard Worker void SetSlotBootable(BootControlInterface::Slot slot, bool bootable) { 118*5a923131SAndroid Build Coastguard Worker DCHECK(slot < num_slots_); 119*5a923131SAndroid Build Coastguard Worker is_bootable_[slot] = bootable; 120*5a923131SAndroid Build Coastguard Worker } 121*5a923131SAndroid Build Coastguard Worker GetDynamicPartitionControl()122*5a923131SAndroid Build Coastguard Worker DynamicPartitionControlInterface* GetDynamicPartitionControl() override { 123*5a923131SAndroid Build Coastguard Worker return dynamic_partition_control_.get(); 124*5a923131SAndroid Build Coastguard Worker } 125*5a923131SAndroid Build Coastguard Worker 126*5a923131SAndroid Build Coastguard Worker std::optional<PartitionDevice> GetPartitionDevice( 127*5a923131SAndroid Build Coastguard Worker const std::string& partition_name, 128*5a923131SAndroid Build Coastguard Worker uint32_t slot, 129*5a923131SAndroid Build Coastguard Worker uint32_t current_slot, 130*5a923131SAndroid Build Coastguard Worker bool not_in_payload = false) const override { 131*5a923131SAndroid Build Coastguard Worker if (slot >= devices_.size()) { 132*5a923131SAndroid Build Coastguard Worker return {}; 133*5a923131SAndroid Build Coastguard Worker } 134*5a923131SAndroid Build Coastguard Worker auto device_path = devices_[slot].find(partition_name); 135*5a923131SAndroid Build Coastguard Worker if (device_path == devices_[slot].end()) { 136*5a923131SAndroid Build Coastguard Worker return {}; 137*5a923131SAndroid Build Coastguard Worker } 138*5a923131SAndroid Build Coastguard Worker PartitionDevice device; 139*5a923131SAndroid Build Coastguard Worker device.is_dynamic = false; 140*5a923131SAndroid Build Coastguard Worker device.rw_device_path = device_path->second; 141*5a923131SAndroid Build Coastguard Worker device.readonly_device_path = device.rw_device_path; 142*5a923131SAndroid Build Coastguard Worker return device; 143*5a923131SAndroid Build Coastguard Worker } 144*5a923131SAndroid Build Coastguard Worker 145*5a923131SAndroid Build Coastguard Worker private: 146*5a923131SAndroid Build Coastguard Worker BootControlInterface::Slot num_slots_{2}; 147*5a923131SAndroid Build Coastguard Worker BootControlInterface::Slot current_slot_{0}; 148*5a923131SAndroid Build Coastguard Worker 149*5a923131SAndroid Build Coastguard Worker std::vector<bool> is_bootable_; 150*5a923131SAndroid Build Coastguard Worker std::vector<bool> is_marked_successful_; 151*5a923131SAndroid Build Coastguard Worker std::vector<std::map<std::string, std::string>> devices_; 152*5a923131SAndroid Build Coastguard Worker 153*5a923131SAndroid Build Coastguard Worker std::unique_ptr<DynamicPartitionControlInterface> dynamic_partition_control_; 154*5a923131SAndroid Build Coastguard Worker 155*5a923131SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(FakeBootControl); 156*5a923131SAndroid Build Coastguard Worker }; 157*5a923131SAndroid Build Coastguard Worker 158*5a923131SAndroid Build Coastguard Worker } // namespace chromeos_update_engine 159*5a923131SAndroid Build Coastguard Worker 160*5a923131SAndroid Build Coastguard Worker #endif // UPDATE_ENGINE_COMMON_FAKE_BOOT_CONTROL_H_ 161