1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 #pragma once
29 
30 #include <functional>
31 #include <memory>
32 #include <string>
33 #include "fastboot_driver_interface.h"
34 #include "filesystem.h"
35 #include "task.h"
36 #include "util.h"
37 
38 #include <bootimg.h>
39 
40 #include "result.h"
41 #include "socket.h"
42 #include "util.h"
43 #include "ziparchive/zip_archive.h"
44 
45 class FastBootTool {
46   public:
47     int Main(int argc, char* argv[]);
48 
49     void ParseOsPatchLevel(boot_img_hdr_v1*, const char*);
50     void ParseOsVersion(boot_img_hdr_v1*, const char*);
51     unsigned ParseFsOption(const char*);
52 };
53 
54 enum fb_buffer_type {
55     FB_BUFFER_FD,
56     FB_BUFFER_SPARSE,
57 };
58 
59 struct fastboot_buffer {
60     fb_buffer_type type;
61     fb_buffer_type file_type;
62     std::vector<SparsePtr> files;
63     int64_t sz;
64     unique_fd fd;
65     int64_t image_size;
66 };
67 
68 enum class ImageType {
69     // Must be flashed for device to boot into the kernel.
70     BootCritical,
71     // Normal partition to be flashed during "flashall".
72     Normal,
73     // Partition that is never flashed during "flashall".
74     Extra
75 };
76 
77 struct Image {
78     std::string nickname;
79     std::string img_name;
80     std::string sig_name;
81     std::string part_name;
82     bool optional_if_no_image;
83     ImageType type;
IsSecondaryImage84     bool IsSecondary() const { return nickname.empty(); }
85 };
86 
87 using ImageEntry = std::pair<const Image*, std::string>;
88 
89 struct FlashingPlan {
90     unsigned fs_options = 0;
91     // If the image uses the default slot, or the user specified "all", then
92     // the paired string will be empty. If the image requests a specific slot
93     // (for example, system_other) it is specified instead.
94     std::unique_ptr<ImageSource> source;
95     bool wants_wipe = false;
96     bool skip_reboot = false;
97     bool wants_set_active = false;
98     bool skip_secondary = false;
99     bool force_flash = false;
100     bool should_optimize_flash_super = true;
101     bool should_use_fastboot_info = true;
102     bool exclude_dynamic_partitions = false;
103     uint64_t sparse_limit = 0;
104 
105     std::string slot_override;
106     std::string current_slot;
107     std::string secondary_slot;
108 
109     fastboot::IFastBootDriver* fb;
110 };
111 
112 class FlashAllTool {
113   public:
114     FlashAllTool(FlashingPlan* fp);
115 
116     void Flash();
117     std::vector<std::unique_ptr<Task>> CollectTasks();
118 
119   private:
120     void CheckRequirements();
121     void DetermineSlot();
122     void CollectImages();
123     void AddFlashTasks(const std::vector<std::pair<const Image*, std::string>>& images,
124                        std::vector<std::unique_ptr<Task>>& tasks);
125 
126     std::vector<std::unique_ptr<Task>> CollectTasksFromFastbootInfo();
127     std::vector<std::unique_ptr<Task>> CollectTasksFromImageList();
128 
129     std::vector<ImageEntry> boot_images_;
130     std::vector<ImageEntry> os_images_;
131     std::vector<std::unique_ptr<Task>> tasks_;
132 
133     FlashingPlan* fp_;
134 };
135 
136 class ZipImageSource final : public ImageSource {
137   public:
ZipImageSource(ZipArchiveHandle zip)138     explicit ZipImageSource(ZipArchiveHandle zip) : zip_(zip) {}
139     bool ReadFile(const std::string& name, std::vector<char>* out) const override;
140     unique_fd OpenFile(const std::string& name) const override;
141 
142   private:
143     ZipArchiveHandle zip_;
144 };
145 
146 class LocalImageSource final : public ImageSource {
147   public:
148     bool ReadFile(const std::string& name, std::vector<char>* out) const override;
149     unique_fd OpenFile(const std::string& name) const override;
150 };
151 
152 char* get_android_product_out();
153 bool should_flash_in_userspace(const ImageSource* source, const std::string& partition_name);
154 bool is_userspace_fastboot();
155 void do_flash(const char* pname, const char* fname, const bool apply_vbmeta,
156               const FlashingPlan* fp);
157 void do_for_partitions(const std::string& part, const std::string& slot,
158                        const std::function<void(const std::string&)>& func, bool force_slot);
159 std::string find_item(const std::string& item);
160 void reboot_to_userspace_fastboot();
161 void syntax_error(const char* fmt, ...);
162 std::string get_current_slot();
163 
164 // Code for Parsing fastboot-info.txt
165 bool CheckFastbootInfoRequirements(const std::vector<std::string>& command,
166                                    uint32_t host_tool_version);
167 std::unique_ptr<FlashTask> ParseFlashCommand(const FlashingPlan* fp,
168                                              const std::vector<std::string>& parts);
169 std::unique_ptr<RebootTask> ParseRebootCommand(const FlashingPlan* fp,
170                                                const std::vector<std::string>& parts);
171 std::unique_ptr<WipeTask> ParseWipeCommand(const FlashingPlan* fp,
172                                            const std::vector<std::string>& parts);
173 std::unique_ptr<Task> ParseFastbootInfoLine(const FlashingPlan* fp,
174                                             const std::vector<std::string>& command);
175 bool AddResizeTasks(const FlashingPlan* fp, std::vector<std::unique_ptr<Task>>& tasks);
176 std::vector<std::unique_ptr<Task>> ParseFastbootInfo(const FlashingPlan* fp,
177                                                      const std::vector<std::string>& file);
178 
179 struct NetworkSerial {
180     Socket::Protocol protocol;
181     std::string address;
182     int port;
183 };
184 
185 Result<NetworkSerial, FastbootError> ParseNetworkSerial(const std::string& serial);
186 std::string GetPartitionName(const ImageEntry& entry, const std::string& current_slot_);
187 void flash_partition_files(const std::string& partition, const std::vector<SparsePtr>& files);
188 int64_t get_sparse_limit(int64_t size, const FlashingPlan* fp);
189 std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size);
190 
191 bool supports_AB(fastboot::IFastBootDriver* fb);
192 bool is_logical(const std::string& partition);
193 void fb_perform_format(const std::string& partition, int skip_if_not_supported,
194                        const std::string& type_override, const std::string& size_override,
195                        const unsigned fs_options, const FlashingPlan* fp);
196