1 //
2 // Copyright (C) 2023 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #pragma once
17 
18 #include <stdint.h>
19 
20 #include <memory>
21 #include <ostream>
22 #include <string>
23 #include <unordered_map>
24 #include <utility>
25 
26 #include <android-base/unique_fd.h>
27 #include <liblp/builder.h>
28 
29 namespace android {
30 namespace fs_mgr {
31 
32 struct SuperImageExtent {
33     enum class Type { INVALID, DATA, PARTITION, ZERO, DONTCARE };
34 
35     SuperImageExtent(const SuperImageExtent& other) = default;
36     SuperImageExtent(SuperImageExtent&& other) = default;
SuperImageExtentSuperImageExtent37     SuperImageExtent(uint64_t offset, uint64_t size, Type type)
38         : offset(offset), size(size), type(type) {}
39 
SuperImageExtentSuperImageExtent40     SuperImageExtent(uint64_t offset, std::shared_ptr<std::string> blob)
41         : SuperImageExtent(offset, blob->size(), Type::DATA) {
42         this->blob = blob;
43     }
44 
SuperImageExtentSuperImageExtent45     SuperImageExtent(uint64_t offset, uint64_t size, const std::string& image_name,
46                      uint64_t image_offset)
47         : SuperImageExtent(offset, size, Type::PARTITION) {
48         this->image_name = image_name;
49         this->image_offset = image_offset;
50     }
51 
52     SuperImageExtent& operator=(const SuperImageExtent& other) = default;
53     SuperImageExtent& operator=(SuperImageExtent&& other) = default;
54 
55     bool operator<(const SuperImageExtent& other) const { return offset < other.offset; }
56     bool operator==(const SuperImageExtent& other) const;
57 
58     // Location, size, and type of the extent.
59     uint64_t offset = 0;
60     uint64_t size = 0;
61     Type type = Type::INVALID;
62 
63     // If type == DATA, this contains the bytes to write.
64     std::shared_ptr<std::string> blob;
65     // If type == PARTITION, this contains the partition image name and
66     // offset within that file.
67     std::string image_name;
68     uint64_t image_offset = 0;
69 };
70 
71 // The SuperLayoutBuilder allows building a sparse view of a super image. This
72 // is useful for efficient flashing, eg to bypass fastbootd and directly flash
73 // super without physically building and storing the image.
74 class SuperLayoutBuilder final {
75   public:
76     // Open a super_empty.img, return false on failure. This must be called to
77     // initialize the tool. If it returns false, either the image failed to
78     // parse, or the tool is not compatible with how the device is configured
79     // (in which case fastbootd should be preferred).
80     [[nodiscard]] bool Open(android::base::borrowed_fd fd);
81     [[nodiscard]] bool Open(const void* data, size_t bytes);
82     [[nodiscard]] bool Open(const LpMetadata& metadata);
83 
84     // Add a partition's image and size to the work list. If false is returned,
85     // there was either a duplicate partition or not enough space in super.
86     bool AddPartition(const std::string& partition_name, const std::string& image_name,
87                       uint64_t partition_size);
88 
89     // Return the list of extents describing the super image. If this list is
90     // empty, then there was an unrecoverable error in building the list.
91     std::vector<SuperImageExtent> GetImageLayout();
92 
93     // Return the current metadata.
Export()94     std::unique_ptr<LpMetadata> Export() const { return builder_->Export(); }
95 
96   private:
97     std::unique_ptr<MetadataBuilder> builder_;
98     std::unordered_map<std::string, std::string> image_map_;
99 };
100 
101 std::ostream& operator<<(std::ostream& stream, const SuperImageExtent& extent);
102 
103 }  // namespace fs_mgr
104 }  // namespace android
105