xref: /aosp_15_r20/system/update_engine/common/fake_boot_control.h (revision 5a9231315b4521097b8dc3750bc806fcafe0c72f)
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