blob: fc320688b07d6263b9d6ad9e30410bcb3b9e763b [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2011 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//
rspangler@google.com49fdf182009-10-10 00:57:34 +000016
Alex Deymo39910dc2015-11-09 17:04:30 -080017#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
18#define UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
rspangler@google.com49fdf182009-10-10 00:57:34 +000019
rspangler@google.com49fdf182009-10-10 00:57:34 +000020#include <fcntl.h>
Alex Vakulenko44cab302014-07-23 13:12:15 -070021#include <sys/stat.h>
22#include <sys/types.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000023
Ben Chan02f7c1d2014-10-18 15:18:02 -070024#include <memory>
rspangler@google.com49fdf182009-10-10 00:57:34 +000025#include <string>
26
27#include <curl/curl.h>
28
Alex Deymo39910dc2015-11-09 17:04:30 -080029#include "update_engine/common/action.h"
Alex Deymo1b3556c2016-02-03 09:54:02 -080030#include "update_engine/common/boot_control_interface.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080031#include "update_engine/common/http_fetcher.h"
32#include "update_engine/payload_consumer/delta_performer.h"
33#include "update_engine/payload_consumer/install_plan.h"
Jay Srinivasanf0572052012-10-23 18:12:56 -070034#include "update_engine/system_state.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000035
Darin Petkov7ed561b2011-10-04 02:59:03 -070036// The Download Action downloads a specified url to disk. The url should point
37// to an update in a delta payload format. The payload will be piped into a
Andrew de los Reyesf9185172010-05-03 11:07:05 -070038// DeltaPerformer that will apply the delta to the disk.
rspangler@google.com49fdf182009-10-10 00:57:34 +000039
rspangler@google.com49fdf182009-10-10 00:57:34 +000040namespace chromeos_update_engine {
41
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070042class DownloadActionDelegate {
43 public:
Alex Deymoe8948702014-11-11 21:44:45 -080044 virtual ~DownloadActionDelegate() = default;
45
Alex Deymo22ad8612015-11-20 17:59:11 -030046 // Called periodically after bytes are received. This method will be invoked
Alex Deymo542c19b2015-12-03 07:43:31 -030047 // only if the DownloadAction is running. |bytes_progressed| is the number of
48 // bytes downloaded since the last call of this method, |bytes_received|
49 // the number of bytes downloaded thus far and |total| is the number of bytes
50 // expected.
51 virtual void BytesReceived(uint64_t bytes_progressed,
52 uint64_t bytes_received,
53 uint64_t total) = 0;
54
55 // Returns whether the download should be canceled, in which case the
56 // |cancel_reason| error should be set to the reason why the download was
57 // canceled.
58 virtual bool ShouldCancel(ErrorCode* cancel_reason) = 0;
59
60 // Called once the complete payload has been downloaded. Note that any errors
61 // while applying or downloading the partial payload will result in this
62 // method not being called.
63 virtual void DownloadComplete() = 0;
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070064};
65
Darin Petkov73058b42010-10-06 16:32:19 -070066class PrefsInterface;
rspangler@google.com49fdf182009-10-10 00:57:34 +000067
Chris Sosad317e402013-06-12 13:47:09 -070068class DownloadAction : public InstallPlanAction,
rspangler@google.com49fdf182009-10-10 00:57:34 +000069 public HttpFetcherDelegate {
70 public:
Alex Deymof2858572016-02-25 11:20:13 -080071 // Debugging/logging
72 static std::string StaticType() { return "DownloadAction"; }
73
rspangler@google.com49fdf182009-10-10 00:57:34 +000074 // Takes ownership of the passed in HttpFetcher. Useful for testing.
75 // A good calling pattern is:
Alex Deymo1b3556c2016-02-03 09:54:02 -080076 // DownloadAction(prefs, boot_contol, hardware, system_state,
77 // new WhateverHttpFetcher);
Jay Srinivasanf0572052012-10-23 18:12:56 -070078 DownloadAction(PrefsInterface* prefs,
Alex Deymo1b3556c2016-02-03 09:54:02 -080079 BootControlInterface* boot_control,
80 HardwareInterface* hardware,
Jay Srinivasanf0572052012-10-23 18:12:56 -070081 SystemState* system_state,
82 HttpFetcher* http_fetcher);
Alex Deymo610277e2014-11-11 21:18:11 -080083 ~DownloadAction() override;
Alex Deymof2858572016-02-25 11:20:13 -080084
85 // InstallPlanAction overrides.
Alex Deymo610277e2014-11-11 21:18:11 -080086 void PerformAction() override;
Alex Deymof2858572016-02-25 11:20:13 -080087 void SuspendAction() override;
88 void ResumeAction() override;
Alex Deymo610277e2014-11-11 21:18:11 -080089 void TerminateProcessing() override;
Alex Deymof2858572016-02-25 11:20:13 -080090 std::string Type() const override { return StaticType(); }
rspangler@google.com49fdf182009-10-10 00:57:34 +000091
Andrew de los Reyesf9185172010-05-03 11:07:05 -070092 // Testing
93 void SetTestFileWriter(FileWriter* writer) {
94 writer_ = writer;
95 }
96
Darin Petkov1023a602010-08-30 13:47:51 -070097 int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); }
98
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070099 // HttpFetcherDelegate methods (see http_fetcher.h)
Alex Deymo60ca1a72015-06-18 18:19:15 -0700100 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800101 const void* bytes, size_t length) override;
Alex Deymo610277e2014-11-11 21:18:11 -0800102 void SeekToOffset(off_t offset) override;
Alex Deymo60ca1a72015-06-18 18:19:15 -0700103 void TransferComplete(HttpFetcher* fetcher, bool successful) override;
104 void TransferTerminated(HttpFetcher* fetcher) override;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000105
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700106 DownloadActionDelegate* delegate() const { return delegate_; }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700107 void set_delegate(DownloadActionDelegate* delegate) {
108 delegate_ = delegate;
109 }
110
Darin Petkov9b230572010-10-08 10:20:09 -0700111 HttpFetcher* http_fetcher() { return http_fetcher_.get(); }
112
David Zeuthen8f191b22013-08-06 12:27:50 -0700113 // Returns the p2p file id for the file being written or the empty
114 // string if we're not writing to a p2p file.
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700115 std::string p2p_file_id() { return p2p_file_id_; }
David Zeuthen8f191b22013-08-06 12:27:50 -0700116
rspangler@google.com49fdf182009-10-10 00:57:34 +0000117 private:
David Zeuthen8f191b22013-08-06 12:27:50 -0700118 // Closes the file descriptor for the p2p file being written and
119 // clears |p2p_file_id_| to indicate that we're no longer sharing
120 // the file. If |delete_p2p_file| is True, also deletes the file.
121 // If there is no p2p file descriptor, this method does nothing.
122 void CloseP2PSharingFd(bool delete_p2p_file);
123
124 // Starts sharing the p2p file. Must be called before
125 // WriteToP2PFile(). Returns True if this worked.
126 bool SetupP2PSharingFd();
127
128 // Writes |length| bytes of payload from |data| into |file_offset|
129 // of the p2p file. Also does sanity checks; for example ensures we
130 // don't end up with a file with holes in it.
131 //
132 // This method does nothing if SetupP2PSharingFd() hasn't been
133 // called or if CloseP2PSharingFd() has been called.
Alex Deymo60ca1a72015-06-18 18:19:15 -0700134 void WriteToP2PFile(const void* data, size_t length, off_t file_offset);
David Zeuthen8f191b22013-08-06 12:27:50 -0700135
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700136 // The InstallPlan passed in
137 InstallPlan install_plan_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000138
Alex Deymo1b3556c2016-02-03 09:54:02 -0800139 // SystemState required pointers.
Darin Petkov73058b42010-10-06 16:32:19 -0700140 PrefsInterface* prefs_;
Alex Deymo1b3556c2016-02-03 09:54:02 -0800141 BootControlInterface* boot_control_;
142 HardwareInterface* hardware_;
Darin Petkov73058b42010-10-06 16:32:19 -0700143
Jay Srinivasanedce2832012-10-24 18:57:47 -0700144 // Global context for the system.
145 SystemState* system_state_;
146
147 // Pointer to the HttpFetcher that does the http work.
Ben Chan02f7c1d2014-10-18 15:18:02 -0700148 std::unique_ptr<HttpFetcher> http_fetcher_;
Jay Srinivasanedce2832012-10-24 18:57:47 -0700149
rspangler@google.com49fdf182009-10-10 00:57:34 +0000150 // The FileWriter that downloaded data should be written to. It will
Andrew de los Reyesf9185172010-05-03 11:07:05 -0700151 // either point to *decompressing_file_writer_ or *delta_performer_.
rspangler@google.com49fdf182009-10-10 00:57:34 +0000152 FileWriter* writer_;
153
Ben Chan02f7c1d2014-10-18 15:18:02 -0700154 std::unique_ptr<DeltaPerformer> delta_performer_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000155
Darin Petkov9ce452b2010-11-17 14:33:28 -0800156 // Used by TransferTerminated to figure if this action terminated itself or
157 // was terminated by the action processor.
David Zeuthena99981f2013-04-29 13:42:47 -0700158 ErrorCode code_;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800159
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700160 // For reporting status to outsiders
161 DownloadActionDelegate* delegate_;
162 uint64_t bytes_received_;
Alex Deymo22ad8612015-11-20 17:59:11 -0300163 bool download_active_{false};
Darin Petkov9d911fa2010-08-19 09:36:08 -0700164
David Zeuthen8f191b22013-08-06 12:27:50 -0700165 // The file-id for the file we're sharing or the empty string
166 // if we're not using p2p to share.
167 std::string p2p_file_id_;
168
169 // The file descriptor for the p2p file used for caching the payload or -1
170 // if we're not using p2p to share.
171 int p2p_sharing_fd_;
172
173 // Set to |false| if p2p file is not visible.
174 bool p2p_visible_;
175
rspangler@google.com49fdf182009-10-10 00:57:34 +0000176 DISALLOW_COPY_AND_ASSIGN(DownloadAction);
177};
178
179// We want to be sure that we're compiled with large file support on linux,
180// just in case we find ourselves downloading large images.
Alex Vakulenko0103c362016-01-20 07:56:15 -0800181static_assert(8 == sizeof(off_t), "off_t not 64 bit");
rspangler@google.com49fdf182009-10-10 00:57:34 +0000182
183} // namespace chromeos_update_engine
184
Alex Deymo39910dc2015-11-09 17:04:30 -0800185#endif // UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_