download_action.h revision 73058b421f91e04cc605c2a113e0010009a63594
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
14e971f339579a8797b3728551c5e1c53272634102Darin Petkov#include <base/scoped_ptr.h>
1549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <curl/curl.h>
1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
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"
20e971f339579a8797b3728551c5e1c53272634102Darin Petkov#include "update_engine/buffered_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;
5273058b421f91e04cc605c2a113e0010009a63594Darin Petkovclass PrefsInterface;
5349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
5449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comtemplate<>
5549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass ActionTraits<DownloadAction> {
5649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
57c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  // Takes and returns an InstallPlan
58c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef InstallPlan InputObjectType;
59c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  typedef InstallPlan OutputObjectType;
6049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
6149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
6249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comclass DownloadAction : public Action<DownloadAction>,
6349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com                       public HttpFetcherDelegate {
6449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
6549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Takes ownership of the passed in HttpFetcher. Useful for testing.
6649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // A good calling pattern is:
67c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  // DownloadAction(new WhateverHttpFetcher);
6873058b421f91e04cc605c2a113e0010009a63594Darin Petkov  DownloadAction(PrefsInterface* prefs, HttpFetcher* http_fetcher);
6949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  virtual ~DownloadAction();
7049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  typedef ActionTraits<DownloadAction>::InputObjectType InputObjectType;
7149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  typedef ActionTraits<DownloadAction>::OutputObjectType OutputObjectType;
7249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  void PerformAction();
7349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  void TerminateProcessing();
7449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
75f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // Testing
76f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  void SetTestFileWriter(FileWriter* writer) {
77f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes    writer_ = writer;
78f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  }
79f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes
801023a6029771fb8dea867e14193df8e58a59a662Darin Petkov  int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); }
811023a6029771fb8dea867e14193df8e58a59a662Darin Petkov
8249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Debugging/logging
83c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  static std::string StaticType() { return "DownloadAction"; }
84c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com  std::string Type() const { return StaticType(); }
8549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
8663b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  // HttpFetcherDelegate methods (see http_fetcher.h)
8749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  virtual void ReceivedBytes(HttpFetcher *fetcher,
8849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com                             const char* bytes, int length);
8949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  virtual void TransferComplete(HttpFetcher *fetcher, bool successful);
9049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
91f42cc1c604fe5b0be29847a24f9bd5acf42ba394Darin Petkov  DownloadActionDelegate* delegate() const { return delegate_; }
9263b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  void set_delegate(DownloadActionDelegate* delegate) {
9363b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes    delegate_ = delegate;
9463b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  }
9563b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes
9649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com private:
97f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // The InstallPlan passed in
98f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  InstallPlan install_plan_;
9949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
10073058b421f91e04cc605c2a113e0010009a63594Darin Petkov  // Update Engine preference store.
10173058b421f91e04cc605c2a113e0010009a63594Darin Petkov  PrefsInterface* prefs_;
10273058b421f91e04cc605c2a113e0010009a63594Darin Petkov
10349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // The FileWriter that downloaded data should be written to. It will
104f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // either point to *decompressing_file_writer_ or *delta_performer_.
10549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  FileWriter* writer_;
10649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
107f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // These are used for full updates:
10849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  scoped_ptr<GzipDecompressingFileWriter> decompressing_file_writer_;
109f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  scoped_ptr<SplitFileWriter> split_file_writer_;
110f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  scoped_ptr<DirectFileWriter> kernel_file_writer_;
111f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  scoped_ptr<DirectFileWriter> rootfs_file_writer_;
112e971f339579a8797b3728551c5e1c53272634102Darin Petkov  scoped_ptr<BufferedFileWriter> kernel_buffered_file_writer_;
113e971f339579a8797b3728551c5e1c53272634102Darin Petkov  scoped_ptr<BufferedFileWriter> rootfs_buffered_file_writer_;
11449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
115f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // Used to apply a delta update:
116f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  scoped_ptr<DeltaPerformer> delta_performer_;
11749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
118f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // Pointer to the HttpFetcher that does the http work.
11949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  scoped_ptr<HttpFetcher> http_fetcher_;
12049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
12149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Used to find the hash of the bytes downloaded
12249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  OmahaHashCalculator omaha_hash_calculator_;
1239d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov
12463b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  // For reporting status to outsiders
12563b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  DownloadActionDelegate* delegate_;
12663b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  uint64_t bytes_received_;
1279d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov
12849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  DISALLOW_COPY_AND_ASSIGN(DownloadAction);
12949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
13049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
13149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// We want to be sure that we're compiled with large file support on linux,
13249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// just in case we find ourselves downloading large images.
13349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comCOMPILE_ASSERT(8 == sizeof(off_t), off_t_not_64_bit);
13449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
13549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}  // namespace chromeos_update_engine
13649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
137c98a7edf648aad88b3f66df3b5a7d43d6a6d7fa9adlr@google.com#endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_DOWNLOAD_ACTION_H__
138