| // Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_DOWNLOAD_ACTION_H__ | 
 | #define CHROMEOS_PLATFORM_UPDATE_ENGINE_DOWNLOAD_ACTION_H__ | 
 |  | 
 | #include <sys/types.h> | 
 | #include <sys/stat.h> | 
 | #include <fcntl.h> | 
 |  | 
 | #include <string> | 
 |  | 
 | #include <base/memory/scoped_ptr.h> | 
 | #include <curl/curl.h> | 
 | #include <google/protobuf/stubs/common.h> | 
 |  | 
 | #include "update_engine/action.h" | 
 | #include "update_engine/delta_performer.h" | 
 | #include "update_engine/http_fetcher.h" | 
 | #include "update_engine/install_plan.h" | 
 | #include "update_engine/system_state.h" | 
 |  | 
 | // The Download Action downloads a specified url to disk. The url should point | 
 | // to an update in a delta payload format. The payload will be piped into a | 
 | // DeltaPerformer that will apply the delta to the disk. | 
 |  | 
 | namespace chromeos_update_engine { | 
 |  | 
 | class DownloadActionDelegate { | 
 |  public: | 
 |   // Called right before starting the download with |active| set to | 
 |   // true. Called after completing the download with |active| set to | 
 |   // false. | 
 |   virtual void SetDownloadStatus(bool active) = 0; | 
 |  | 
 |   // Called periodically after bytes are received. This method will be | 
 |   // invoked only if the download is active. |bytes_received| is the | 
 |   // number of bytes downloaded thus far. |total| is the number of | 
 |   // bytes expected. | 
 |   virtual void BytesReceived(uint64_t bytes_received, uint64_t total) = 0; | 
 | }; | 
 |  | 
 | class DownloadAction; | 
 | class NoneType; | 
 | class PrefsInterface; | 
 |  | 
 | template<> | 
 | class ActionTraits<DownloadAction> { | 
 |  public: | 
 |   // Takes and returns an InstallPlan | 
 |   typedef InstallPlan InputObjectType; | 
 |   typedef InstallPlan OutputObjectType; | 
 | }; | 
 |  | 
 | class DownloadAction : public Action<DownloadAction>, | 
 |                        public HttpFetcherDelegate { | 
 |  public: | 
 |   // Takes ownership of the passed in HttpFetcher. Useful for testing. | 
 |   // A good calling pattern is: | 
 |   // DownloadAction(prefs, system_state, new WhateverHttpFetcher); | 
 |   DownloadAction(PrefsInterface* prefs, | 
 |                  SystemState* system_state, | 
 |                  HttpFetcher* http_fetcher); | 
 |   virtual ~DownloadAction(); | 
 |   typedef ActionTraits<DownloadAction>::InputObjectType InputObjectType; | 
 |   typedef ActionTraits<DownloadAction>::OutputObjectType OutputObjectType; | 
 |   void PerformAction(); | 
 |   void TerminateProcessing(); | 
 |  | 
 |   // Testing | 
 |   void SetTestFileWriter(FileWriter* writer) { | 
 |     writer_ = writer; | 
 |   } | 
 |  | 
 |   int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); } | 
 |  | 
 |   // Debugging/logging | 
 |   static std::string StaticType() { return "DownloadAction"; } | 
 |   std::string Type() const { return StaticType(); } | 
 |  | 
 |   // HttpFetcherDelegate methods (see http_fetcher.h) | 
 |   virtual void ReceivedBytes(HttpFetcher *fetcher, | 
 |                              const char* bytes, int length); | 
 |   virtual void SeekToOffset(off_t offset); | 
 |   virtual void TransferComplete(HttpFetcher *fetcher, bool successful); | 
 |   virtual void TransferTerminated(HttpFetcher *fetcher); | 
 |  | 
 |   DownloadActionDelegate* delegate() const { return delegate_; } | 
 |   void set_delegate(DownloadActionDelegate* delegate) { | 
 |     delegate_ = delegate; | 
 |   } | 
 |  | 
 |   HttpFetcher* http_fetcher() { return http_fetcher_.get(); } | 
 |  | 
 |  private: | 
 |   // The InstallPlan passed in | 
 |   InstallPlan install_plan_; | 
 |  | 
 |   // Update Engine preference store. | 
 |   PrefsInterface* prefs_; | 
 |  | 
 |   // Global context for the system. | 
 |   SystemState* system_state_; | 
 |  | 
 |   // Pointer to the HttpFetcher that does the http work. | 
 |   scoped_ptr<HttpFetcher> http_fetcher_; | 
 |  | 
 |   // The FileWriter that downloaded data should be written to. It will | 
 |   // either point to *decompressing_file_writer_ or *delta_performer_. | 
 |   FileWriter* writer_; | 
 |  | 
 |   scoped_ptr<DeltaPerformer> delta_performer_; | 
 |  | 
 |   // Used by TransferTerminated to figure if this action terminated itself or | 
 |   // was terminated by the action processor. | 
 |   ActionExitCode code_; | 
 |  | 
 |   // For reporting status to outsiders | 
 |   DownloadActionDelegate* delegate_; | 
 |   uint64_t bytes_received_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(DownloadAction); | 
 | }; | 
 |  | 
 | // We want to be sure that we're compiled with large file support on linux, | 
 | // just in case we find ourselves downloading large images. | 
 | COMPILE_ASSERT(8 == sizeof(off_t), off_t_not_64_bit); | 
 |  | 
 | }  // namespace chromeos_update_engine | 
 |  | 
 | #endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_DOWNLOAD_ACTION_H__ |