download_action.h revision f42cc1c604fe5b0be29847a24f9bd5acf42ba394
149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// Use of this source code is governed by a BSD-style license that can be
349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// found in the LICENSE file.
449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_DOWNLOAD_ACTION_H__
6c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#define CHROMEOS_PLATFORM_UPDATE_ENGINE_DOWNLOAD_ACTION_H__
749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <sys/types.h>
949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <sys/stat.h>
1049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <fcntl.h>
1149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <string>
1349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <curl/curl.h>
1549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "base/scoped_ptr.h"
1749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/action.h"
1849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/decompressing_file_writer.h"
19f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes#include "update_engine/delta_performer.h"
2049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/file_writer.h"
2149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/http_fetcher.h"
22c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#include "update_engine/install_plan.h"
2349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include "update_engine/omaha_hash_calculator.h"
24f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes#include "update_engine/split_file_writer.h"
2549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
26f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// The Download Action downloads a specified url to disk. The url should
27f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// point to either a full or delta update. If a full update, the file will
28f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// be piped into a SplitFileWriter, which will direct it to the kernel
29f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// and rootfs partitions. If it's a delta update, the destination kernel
30f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// and rootfs should already contain the source-version that this delta
31f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// update goes from. In this case, the update will be piped into a
32f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// DeltaPerformer that will apply the delta to the disk.
3349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
3449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine {
3549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
3663b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyesclass DownloadActionDelegate {
3763b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes public:
389d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov  // Called right before starting the download with |active| set to
399d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov  // true. Called after completing the download with |active| set to
409d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov  // false.
419d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov  virtual void SetDownloadStatus(bool active) = 0;
429d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov
439d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov  // Called periodically after bytes are received. This method will be
449d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov  // invoked only if the download is active. |bytes_received| is the
459d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov  // number of bytes downloaded thus far. |total| is the number of
469d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov  // bytes expected.
4763b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  virtual void BytesReceived(uint64_t bytes_received, uint64_t total) = 0;
4863b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes};
4963b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes
5049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass DownloadAction;
5149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass NoneType;
5249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<>
5449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass ActionTraits<DownloadAction> {
5549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
56c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  // Takes and returns an InstallPlan
57c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef InstallPlan InputObjectType;
58c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef InstallPlan OutputObjectType;
5949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
6049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
6149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass DownloadAction : public Action<DownloadAction>,
6249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com                       public HttpFetcherDelegate {
6349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
6449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Takes ownership of the passed in HttpFetcher. Useful for testing.
6549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // A good calling pattern is:
66c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  // DownloadAction(new WhateverHttpFetcher);
67c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  DownloadAction(HttpFetcher* http_fetcher);
6849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  virtual ~DownloadAction();
6949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  typedef ActionTraits<DownloadAction>::InputObjectType InputObjectType;
7049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  typedef ActionTraits<DownloadAction>::OutputObjectType OutputObjectType;
7149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  void PerformAction();
7249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  void TerminateProcessing();
7349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
74f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // Testing
75f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  void SetTestFileWriter(FileWriter* writer) {
76f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes    writer_ = writer;
77f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  }
78f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes
791023a6029771fb8dea867e14193df8e58a59a662Darin Petkov  int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); }
801023a6029771fb8dea867e14193df8e58a59a662Darin Petkov
8149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Debugging/logging
82c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  static std::string StaticType() { return "DownloadAction"; }
83c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  std::string Type() const { return StaticType(); }
8449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
8563b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  // HttpFetcherDelegate methods (see http_fetcher.h)
8649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  virtual void ReceivedBytes(HttpFetcher *fetcher,
8749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com                             const char* bytes, int length);
8849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  virtual void TransferComplete(HttpFetcher *fetcher, bool successful);
8949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
90f42cc1c604fe5b0be29847a24f9bd5acf42ba394Darin Petkov  DownloadActionDelegate* delegate() const { return delegate_; }
9163b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  void set_delegate(DownloadActionDelegate* delegate) {
9263b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes    delegate_ = delegate;
9363b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  }
9463b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes
9549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com private:
96f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // The InstallPlan passed in
97f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  InstallPlan install_plan_;
9849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
9949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // The FileWriter that downloaded data should be written to. It will
100f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // either point to *decompressing_file_writer_ or *delta_performer_.
10149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  FileWriter* writer_;
10249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
103f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // These are used for full updates:
10449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  scoped_ptr<GzipDecompressingFileWriter> decompressing_file_writer_;
105f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  scoped_ptr<SplitFileWriter> split_file_writer_;
106f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  scoped_ptr<DirectFileWriter> kernel_file_writer_;
107f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  scoped_ptr<DirectFileWriter> rootfs_file_writer_;
10849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
109f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // Used to apply a delta update:
110f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  scoped_ptr<DeltaPerformer> delta_performer_;
11149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
112f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // Pointer to the HttpFetcher that does the http work.
11349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  scoped_ptr<HttpFetcher> http_fetcher_;
11449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
11549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Used to find the hash of the bytes downloaded
11649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  OmahaHashCalculator omaha_hash_calculator_;
1179d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov
11863b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  // For reporting status to outsiders
11963b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  DownloadActionDelegate* delegate_;
12063b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  uint64_t bytes_received_;
1219d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov
12249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  DISALLOW_COPY_AND_ASSIGN(DownloadAction);
12349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
12449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
12549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// We want to be sure that we're compiled with large file support on linux,
12649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// just in case we find ourselves downloading large images.
12749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comCOMPILE_ASSERT(8 == sizeof(off_t), off_t_not_64_bit);
12849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
12949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}  // namespace chromeos_update_engine
13049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
131c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_DOWNLOAD_ACTION_H__
132