1*5a923131SAndroid Build Coastguard Worker // 2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2011 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_DOWNLOAD_ACTION_H_ 18*5a923131SAndroid Build Coastguard Worker #define UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_H_ 19*5a923131SAndroid Build Coastguard Worker 20*5a923131SAndroid Build Coastguard Worker #include <fcntl.h> 21*5a923131SAndroid Build Coastguard Worker #include <sys/stat.h> 22*5a923131SAndroid Build Coastguard Worker #include <sys/types.h> 23*5a923131SAndroid Build Coastguard Worker 24*5a923131SAndroid Build Coastguard Worker #include <memory> 25*5a923131SAndroid Build Coastguard Worker #include <string> 26*5a923131SAndroid Build Coastguard Worker #include <utility> 27*5a923131SAndroid Build Coastguard Worker 28*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/boot_control_interface.h" 29*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/http_fetcher.h" 30*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/multi_range_http_fetcher.h" 31*5a923131SAndroid Build Coastguard Worker #include "update_engine/payload_consumer/delta_performer.h" 32*5a923131SAndroid Build Coastguard Worker #include "update_engine/payload_consumer/install_plan.h" 33*5a923131SAndroid Build Coastguard Worker 34*5a923131SAndroid Build Coastguard Worker // The Download Action downloads a specified url to disk. The url should point 35*5a923131SAndroid Build Coastguard Worker // to an update in a delta payload format. The payload will be piped into a 36*5a923131SAndroid Build Coastguard Worker // DeltaPerformer that will apply the delta to the disk. 37*5a923131SAndroid Build Coastguard Worker 38*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine { 39*5a923131SAndroid Build Coastguard Worker 40*5a923131SAndroid Build Coastguard Worker class DownloadActionDelegate { 41*5a923131SAndroid Build Coastguard Worker public: 42*5a923131SAndroid Build Coastguard Worker virtual ~DownloadActionDelegate() = default; 43*5a923131SAndroid Build Coastguard Worker 44*5a923131SAndroid Build Coastguard Worker // Called periodically after bytes are received. This method will be invoked 45*5a923131SAndroid Build Coastguard Worker // only if the DownloadAction is running. |bytes_progressed| is the number of 46*5a923131SAndroid Build Coastguard Worker // bytes downloaded since the last call of this method, |bytes_received| 47*5a923131SAndroid Build Coastguard Worker // the number of bytes downloaded thus far and |total| is the number of bytes 48*5a923131SAndroid Build Coastguard Worker // expected. 49*5a923131SAndroid Build Coastguard Worker virtual void BytesReceived(uint64_t bytes_progressed, 50*5a923131SAndroid Build Coastguard Worker uint64_t bytes_received, 51*5a923131SAndroid Build Coastguard Worker uint64_t total) = 0; 52*5a923131SAndroid Build Coastguard Worker 53*5a923131SAndroid Build Coastguard Worker // Returns whether the download should be canceled, in which case the 54*5a923131SAndroid Build Coastguard Worker // |cancel_reason| error should be set to the reason why the download was 55*5a923131SAndroid Build Coastguard Worker // canceled. 56*5a923131SAndroid Build Coastguard Worker virtual bool ShouldCancel(ErrorCode* cancel_reason) = 0; 57*5a923131SAndroid Build Coastguard Worker 58*5a923131SAndroid Build Coastguard Worker // Called once the complete payload has been downloaded. Note that any errors 59*5a923131SAndroid Build Coastguard Worker // while applying or downloading the partial payload will result in this 60*5a923131SAndroid Build Coastguard Worker // method not being called. 61*5a923131SAndroid Build Coastguard Worker virtual void DownloadComplete() = 0; 62*5a923131SAndroid Build Coastguard Worker }; 63*5a923131SAndroid Build Coastguard Worker 64*5a923131SAndroid Build Coastguard Worker class PrefsInterface; 65*5a923131SAndroid Build Coastguard Worker 66*5a923131SAndroid Build Coastguard Worker class DownloadAction : public InstallPlanAction, public HttpFetcherDelegate { 67*5a923131SAndroid Build Coastguard Worker public: 68*5a923131SAndroid Build Coastguard Worker // Debugging/logging StaticType()69*5a923131SAndroid Build Coastguard Worker static std::string StaticType() { return "DownloadAction"; } 70*5a923131SAndroid Build Coastguard Worker 71*5a923131SAndroid Build Coastguard Worker // Takes ownership of the passed in HttpFetcher. Useful for testing. 72*5a923131SAndroid Build Coastguard Worker // A good calling pattern is: 73*5a923131SAndroid Build Coastguard Worker // DownloadAction(prefs, boot_contol, hardware, 74*5a923131SAndroid Build Coastguard Worker // new WhateverHttpFetcher, false); 75*5a923131SAndroid Build Coastguard Worker DownloadAction( 76*5a923131SAndroid Build Coastguard Worker PrefsInterface* prefs, 77*5a923131SAndroid Build Coastguard Worker BootControlInterface* boot_control, 78*5a923131SAndroid Build Coastguard Worker HardwareInterface* hardware, 79*5a923131SAndroid Build Coastguard Worker HttpFetcher* http_fetcher, 80*5a923131SAndroid Build Coastguard Worker bool interactive, 81*5a923131SAndroid Build Coastguard Worker std::string update_certs_path = constants::kUpdateCertificatesPath); 82*5a923131SAndroid Build Coastguard Worker ~DownloadAction() override; 83*5a923131SAndroid Build Coastguard Worker 84*5a923131SAndroid Build Coastguard Worker // InstallPlanAction overrides. 85*5a923131SAndroid Build Coastguard Worker void PerformAction() override; 86*5a923131SAndroid Build Coastguard Worker void SuspendAction() override; 87*5a923131SAndroid Build Coastguard Worker void ResumeAction() override; 88*5a923131SAndroid Build Coastguard Worker void TerminateProcessing() override; Type()89*5a923131SAndroid Build Coastguard Worker std::string Type() const override { return StaticType(); } 90*5a923131SAndroid Build Coastguard Worker 91*5a923131SAndroid Build Coastguard Worker // Testing SetTestFileWriter(std::unique_ptr<DeltaPerformer> writer)92*5a923131SAndroid Build Coastguard Worker void SetTestFileWriter(std::unique_ptr<DeltaPerformer> writer) { 93*5a923131SAndroid Build Coastguard Worker delta_performer_ = std::move(writer); 94*5a923131SAndroid Build Coastguard Worker } 95*5a923131SAndroid Build Coastguard Worker GetHTTPResponseCode()96*5a923131SAndroid Build Coastguard Worker int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); } 97*5a923131SAndroid Build Coastguard Worker 98*5a923131SAndroid Build Coastguard Worker // HttpFetcherDelegate methods (see http_fetcher.h) 99*5a923131SAndroid Build Coastguard Worker bool ReceivedBytes(HttpFetcher* fetcher, 100*5a923131SAndroid Build Coastguard Worker const void* bytes, 101*5a923131SAndroid Build Coastguard Worker size_t length) override; 102*5a923131SAndroid Build Coastguard Worker void SeekToOffset(off_t offset) override; 103*5a923131SAndroid Build Coastguard Worker void TransferComplete(HttpFetcher* fetcher, bool successful) override; 104*5a923131SAndroid Build Coastguard Worker void TransferTerminated(HttpFetcher* fetcher) override; 105*5a923131SAndroid Build Coastguard Worker delegate()106*5a923131SAndroid Build Coastguard Worker DownloadActionDelegate* delegate() const { return delegate_; } set_delegate(DownloadActionDelegate * delegate)107*5a923131SAndroid Build Coastguard Worker void set_delegate(DownloadActionDelegate* delegate) { delegate_ = delegate; } 108*5a923131SAndroid Build Coastguard Worker set_base_offset(int64_t base_offset)109*5a923131SAndroid Build Coastguard Worker void set_base_offset(int64_t base_offset) { base_offset_ = base_offset; } 110*5a923131SAndroid Build Coastguard Worker http_fetcher()111*5a923131SAndroid Build Coastguard Worker HttpFetcher* http_fetcher() { return http_fetcher_.get(); } 112*5a923131SAndroid Build Coastguard Worker 113*5a923131SAndroid Build Coastguard Worker private: 114*5a923131SAndroid Build Coastguard Worker // Attempt to load cached manifest data from prefs 115*5a923131SAndroid Build Coastguard Worker // return true on success, false otherwise. 116*5a923131SAndroid Build Coastguard Worker bool LoadCachedManifest(int64_t manifest_size); 117*5a923131SAndroid Build Coastguard Worker 118*5a923131SAndroid Build Coastguard Worker // Start downloading the current payload using delta_performer. 119*5a923131SAndroid Build Coastguard Worker void StartDownloading(); 120*5a923131SAndroid Build Coastguard Worker 121*5a923131SAndroid Build Coastguard Worker // Pointer to the current payload in install_plan_.payloads. 122*5a923131SAndroid Build Coastguard Worker InstallPlan::Payload* payload_{nullptr}; 123*5a923131SAndroid Build Coastguard Worker 124*5a923131SAndroid Build Coastguard Worker // Required pointers. 125*5a923131SAndroid Build Coastguard Worker PrefsInterface* prefs_; 126*5a923131SAndroid Build Coastguard Worker BootControlInterface* boot_control_; 127*5a923131SAndroid Build Coastguard Worker HardwareInterface* hardware_; 128*5a923131SAndroid Build Coastguard Worker 129*5a923131SAndroid Build Coastguard Worker // Pointer to the MultiRangeHttpFetcher that does the http work. 130*5a923131SAndroid Build Coastguard Worker std::unique_ptr<MultiRangeHttpFetcher> http_fetcher_; 131*5a923131SAndroid Build Coastguard Worker 132*5a923131SAndroid Build Coastguard Worker // If |true|, the update is user initiated (vs. periodic update checks). Hence 133*5a923131SAndroid Build Coastguard Worker // the |delta_performer_| can decide not to use O_DSYNC flag for faster 134*5a923131SAndroid Build Coastguard Worker // update. 135*5a923131SAndroid Build Coastguard Worker bool interactive_; 136*5a923131SAndroid Build Coastguard Worker 137*5a923131SAndroid Build Coastguard Worker std::unique_ptr<DeltaPerformer> delta_performer_; 138*5a923131SAndroid Build Coastguard Worker 139*5a923131SAndroid Build Coastguard Worker // Used by TransferTerminated to figure if this action terminated itself or 140*5a923131SAndroid Build Coastguard Worker // was terminated by the action processor. 141*5a923131SAndroid Build Coastguard Worker ErrorCode code_; 142*5a923131SAndroid Build Coastguard Worker 143*5a923131SAndroid Build Coastguard Worker // For reporting status to outsiders 144*5a923131SAndroid Build Coastguard Worker DownloadActionDelegate* delegate_; 145*5a923131SAndroid Build Coastguard Worker uint64_t bytes_received_{0}; // per file/range 146*5a923131SAndroid Build Coastguard Worker uint64_t bytes_received_previous_payloads_{0}; 147*5a923131SAndroid Build Coastguard Worker uint64_t bytes_total_{0}; 148*5a923131SAndroid Build Coastguard Worker bool download_active_{false}; 149*5a923131SAndroid Build Coastguard Worker 150*5a923131SAndroid Build Coastguard Worker // Loaded from prefs before downloading any payload. 151*5a923131SAndroid Build Coastguard Worker size_t resume_payload_index_{0}; 152*5a923131SAndroid Build Coastguard Worker 153*5a923131SAndroid Build Coastguard Worker // Offset of the payload in the download URL, used by UpdateAttempterAndroid. 154*5a923131SAndroid Build Coastguard Worker int64_t base_offset_{0}; 155*5a923131SAndroid Build Coastguard Worker 156*5a923131SAndroid Build Coastguard Worker // The path to the zip file with X509 certificates. 157*5a923131SAndroid Build Coastguard Worker const std::string update_certificates_path_; 158*5a923131SAndroid Build Coastguard Worker 159*5a923131SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(DownloadAction); 160*5a923131SAndroid Build Coastguard Worker }; 161*5a923131SAndroid Build Coastguard Worker 162*5a923131SAndroid Build Coastguard Worker // We want to be sure that we're compiled with large file support on linux, 163*5a923131SAndroid Build Coastguard Worker // just in case we find ourselves downloading large images. 164*5a923131SAndroid Build Coastguard Worker static_assert(8 == sizeof(off_t), "off_t not 64 bit"); 165*5a923131SAndroid Build Coastguard Worker 166*5a923131SAndroid Build Coastguard Worker } // namespace chromeos_update_engine 167*5a923131SAndroid Build Coastguard Worker 168*5a923131SAndroid Build Coastguard Worker #endif // UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_H_ 169