blob: 068946a99395930e8180a5e0dfca12fc33745945 [file] [log] [blame]
Kelvin Zhang97cb0582020-12-02 16:42:15 -05001//
2// Copyright (C) 2020 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
17#ifndef UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_CHROMEOS_H_
18#define UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_CHROMEOS_H_
19
20#include <fcntl.h>
21#include <sys/stat.h>
22#include <sys/types.h>
23
24#include <memory>
25#include <string>
26
27#include "update_engine/common/action.h"
28#include "update_engine/common/boot_control_interface.h"
29#include "update_engine/common/download_action.h"
30#include "update_engine/common/http_fetcher.h"
31#include "update_engine/common/multi_range_http_fetcher.h"
32#include "update_engine/payload_consumer/delta_performer.h"
33#include "update_engine/payload_consumer/install_plan.h"
34
35// The Download Action downloads a specified url to disk. The url should point
36// to an update in a delta payload format. The payload will be piped into a
37// DeltaPerformer that will apply the delta to the disk.
38
39namespace chromeos_update_engine {
40
41class PrefsInterface;
42
43class DownloadActionChromeos : public InstallPlanAction,
44 public HttpFetcherDelegate {
45 public:
46 static std::string StaticType() { return "DownloadActionChromeos"; }
47
48 // Takes ownership of the passed in HttpFetcher. Useful for testing.
49 // A good calling pattern is:
50 // DownloadActionChromeos(prefs, boot_contol, hardware, system_state,
51 // new WhateverHttpFetcher, false);
52 DownloadActionChromeos(PrefsInterface* prefs,
53 BootControlInterface* boot_control,
54 HardwareInterface* hardware,
55 HttpFetcher* http_fetcher,
56 bool interactive);
57 ~DownloadActionChromeos() override;
58
59 // InstallPlanAction overrides.
60 void PerformAction() override;
61 void SuspendAction() override;
62 void ResumeAction() override;
63 void TerminateProcessing() override;
64 std::string Type() const override { return StaticType(); }
65
66 // Testing
67 void SetTestFileWriter(FileWriter* writer) { writer_ = writer; }
68
69 int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); }
70
71 // HttpFetcherDelegate methods (see http_fetcher.h)
72 bool ReceivedBytes(HttpFetcher* fetcher,
73 const void* bytes,
74 size_t length) override;
75 void SeekToOffset(off_t offset) override;
76 void TransferComplete(HttpFetcher* fetcher, bool successful) override;
77 void TransferTerminated(HttpFetcher* fetcher) override;
78
79 DownloadActionDelegate* delegate() const { return delegate_; }
80 void set_delegate(DownloadActionDelegate* delegate) { delegate_ = delegate; }
81
82 void set_base_offset(int64_t base_offset) { base_offset_ = base_offset; }
83
84 HttpFetcher* http_fetcher() { return http_fetcher_.get(); }
85
86 // Returns the p2p file id for the file being written or the empty
87 // string if we're not writing to a p2p file.
88 std::string p2p_file_id() { return p2p_file_id_; }
89
90 private:
91 // Closes the file descriptor for the p2p file being written and
92 // clears |p2p_file_id_| to indicate that we're no longer sharing
93 // the file. If |delete_p2p_file| is True, also deletes the file.
94 // If there is no p2p file descriptor, this method does nothing.
95 void CloseP2PSharingFd(bool delete_p2p_file);
96
97 // Starts sharing the p2p file. Must be called before
98 // WriteToP2PFile(). Returns True if this worked.
99 bool SetupP2PSharingFd();
100
101 // Writes |length| bytes of payload from |data| into |file_offset|
102 // of the p2p file. Also does validation checks; for example ensures we
103 // don't end up with a file with holes in it.
104 //
105 // This method does nothing if SetupP2PSharingFd() hasn't been
106 // called or if CloseP2PSharingFd() has been called.
107 void WriteToP2PFile(const void* data, size_t length, off_t file_offset);
108
109 // Attempt to load cached manifest data from prefs
110 // return true on success, false otherwise.
111 bool LoadCachedManifest(int64_t manifest_size);
112
113 // Start downloading the current payload using delta_performer.
114 void StartDownloading();
115
116 // Pointer to the current payload in install_plan_.payloads.
117 InstallPlan::Payload* payload_{nullptr};
118
119 PrefsInterface* prefs_;
120 BootControlInterface* boot_control_;
121 HardwareInterface* hardware_;
122
123 // Pointer to the MultiRangeHttpFetcher that does the http work.
124 std::unique_ptr<MultiRangeHttpFetcher> http_fetcher_;
125
126 // If |true|, the update is user initiated (vs. periodic update checks). Hence
127 // the |delta_performer_| can decide not to use O_DSYNC flag for faster
128 // update.
129 bool interactive_;
130
131 // The FileWriter that downloaded data should be written to. It will
132 // either point to *decompressing_file_writer_ or *delta_performer_.
133 FileWriter* writer_;
134
135 std::unique_ptr<DeltaPerformer> delta_performer_;
136
137 // Used by TransferTerminated to figure if this action terminated itself or
138 // was terminated by the action processor.
139 ErrorCode code_;
140
141 // For reporting status to outsiders
142 DownloadActionDelegate* delegate_;
143 uint64_t bytes_received_{0}; // per file/range
144 uint64_t bytes_received_previous_payloads_{0};
145 uint64_t bytes_total_{0};
146 bool download_active_{false};
147
148 // The file-id for the file we're sharing or the empty string
149 // if we're not using p2p to share.
150 std::string p2p_file_id_;
151
152 // The file descriptor for the p2p file used for caching the payload or -1
153 // if we're not using p2p to share.
154 int p2p_sharing_fd_;
155
156 // Set to |false| if p2p file is not visible.
157 bool p2p_visible_;
158
159 // Loaded from prefs before downloading any payload.
160 size_t resume_payload_index_{0};
161
162 // Offset of the payload in the download URL, used by UpdateAttempterAndroid.
163 int64_t base_offset_{0};
164
165 DISALLOW_COPY_AND_ASSIGN(DownloadActionChromeos);
166};
167
168// We want to be sure that we're compiled with large file support on linux,
169// just in case we find ourselves downloading large images.
170static_assert(8 == sizeof(off_t), "off_t not 64 bit");
171
172} // namespace chromeos_update_engine
173
174#endif // UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_CHROMEOS_H_