// // Copyright (C) 2016 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef UPDATE_ENGINE_COMMON_FILE_FETCHER_H_ #define UPDATE_ENGINE_COMMON_FILE_FETCHER_H_ #include <memory> #include <string> #include <utility> #include <base/logging.h> #include <base/macros.h> #include <brillo/message_loops/message_loop.h> #include <brillo/streams/stream.h> #include "update_engine/common/http_fetcher.h" // This is a concrete implementation of HttpFetcher that reads files // asynchronously. namespace chromeos_update_engine { class FileFetcher : public HttpFetcher { public: // Returns whether the passed url is supported. static bool SupportedUrl(const std::string& url); FileFetcher() : HttpFetcher(nullptr) {} // Cleans up all internal state. Does not notify delegate. ~FileFetcher() override; // HttpFetcher overrides. void SetOffset(off_t offset) override { offset_ = offset; } void SetLength(size_t length) override { data_length_ = length; } void UnsetLength() override { SetLength(0); } // Begins the transfer if it hasn't already begun. void BeginTransfer(const std::string& url) override; // If the transfer is in progress, aborts the transfer early. The transfer // cannot be resumed. void TerminateTransfer() override; // Ignore all extra headers for files. void SetHeader(const std::string& header_name, const std::string& header_value) override {}; // Suspend the asynchronous file read. void Pause() override; // Resume the suspended file read. void Unpause() override; size_t GetBytesDownloaded() override { return static_cast<size_t>(bytes_copied_); } // Ignore all the time limits for files. void set_low_speed_limit(int low_speed_bps, int low_speed_sec) override {} void set_connect_timeout(int connect_timeout_seconds) override {} void set_max_retry_count(int max_retry_count) override {} private: // Cleans up the fetcher, resetting its status to a newly constructed one. void CleanUp(); // Schedule a new asynchronous read if the stream is not paused and no other // read is in process. This method can be called at any point. void ScheduleRead(); // Called from the main loop when a single read from |stream_| succeeds or // fails, calling OnReadDoneCallback() and OnReadErrorCallback() respectively. void OnReadDoneCallback(size_t bytes_read); void OnReadErrorCallback(const brillo::Error* error); // Whether the transfer was started and didn't finish yet. bool transfer_in_progress_{false}; // Whether the transfer is paused. bool transfer_paused_{false}; // Whether there's an ongoing asynchronous read. When this value is true, the // the |buffer_| is being used by the |stream_|. bool ongoing_read_{false}; // Total number of bytes copied. uint64_t bytes_copied_{0}; // The offset inside the file where the read should start. uint64_t offset_{0}; // The length of the data or -1 if unknown (will read until EOF). int64_t data_length_{-1}; brillo::StreamPtr stream_; // The buffer used for reading from the stream. brillo::Blob buffer_; DISALLOW_COPY_AND_ASSIGN(FileFetcher); }; } // namespace chromeos_update_engine #endif // UPDATE_ENGINE_COMMON_FILE_FETCHER_H_