1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2011 The Android Open Source Project
3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License");
5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License.
6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at
7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//      http://www.apache.org/licenses/LICENSE-2.0
9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software
11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS,
12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and
14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License.
15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo//
1649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#ifndef UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
1839910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#define UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
1949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
2049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <fcntl.h>
2144cab30e0ee04b277e8463785ab069e9885a9f2dAlex Vakulenko#include <sys/stat.h>
2244cab30e0ee04b277e8463785ab069e9885a9f2dAlex Vakulenko#include <sys/types.h>
2349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
2402f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan#include <memory>
2549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com#include <string>
2649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
2739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/action.h"
281b3556cbe66b3f5be35f6117d4013ddc199b064cAlex Deymo#include "update_engine/common/boot_control_interface.h"
2939910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/http_fetcher.h"
3039910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/payload_consumer/delta_performer.h"
3139910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/payload_consumer/install_plan.h"
32f057205065339c54d3403263f049e2ea69417665Jay Srinivasan#include "update_engine/system_state.h"
337ed561bfe6019ed4b988142e97505d7c643e119cDarin Petkov
347ed561bfe6019ed4b988142e97505d7c643e119cDarin Petkov// The Download Action downloads a specified url to disk. The url should point
357ed561bfe6019ed4b988142e97505d7c643e119cDarin Petkov// to an update in a delta payload format. The payload will be piped into a
36f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes// DeltaPerformer that will apply the delta to the disk.
3749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
3849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.comnamespace chromeos_update_engine {
3949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
4063b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyesclass DownloadActionDelegate {
4163b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes public:
42e89487039d0eca8130d822cabf75a729609509e0Alex Deymo  virtual ~DownloadActionDelegate() = default;
43e89487039d0eca8130d822cabf75a729609509e0Alex Deymo
4422ad86121ba56c576bfcaa23e085dab881bd4ff5Alex Deymo  // Called periodically after bytes are received. This method will be invoked
45542c19bf271011913a9f352f58e140224c936736Alex Deymo  // only if the DownloadAction is running. |bytes_progressed| is the number of
46542c19bf271011913a9f352f58e140224c936736Alex Deymo  // bytes downloaded since the last call of this method, |bytes_received|
47542c19bf271011913a9f352f58e140224c936736Alex Deymo  // the number of bytes downloaded thus far and |total| is the number of bytes
48542c19bf271011913a9f352f58e140224c936736Alex Deymo  // expected.
49542c19bf271011913a9f352f58e140224c936736Alex Deymo  virtual void BytesReceived(uint64_t bytes_progressed,
50542c19bf271011913a9f352f58e140224c936736Alex Deymo                             uint64_t bytes_received,
51542c19bf271011913a9f352f58e140224c936736Alex Deymo                             uint64_t total) = 0;
52542c19bf271011913a9f352f58e140224c936736Alex Deymo
53542c19bf271011913a9f352f58e140224c936736Alex Deymo  // Returns whether the download should be canceled, in which case the
54542c19bf271011913a9f352f58e140224c936736Alex Deymo  // |cancel_reason| error should be set to the reason why the download was
55542c19bf271011913a9f352f58e140224c936736Alex Deymo  // canceled.
56542c19bf271011913a9f352f58e140224c936736Alex Deymo  virtual bool ShouldCancel(ErrorCode* cancel_reason) = 0;
57542c19bf271011913a9f352f58e140224c936736Alex Deymo
58542c19bf271011913a9f352f58e140224c936736Alex Deymo  // Called once the complete payload has been downloaded. Note that any errors
59542c19bf271011913a9f352f58e140224c936736Alex Deymo  // while applying or downloading the partial payload will result in this
60542c19bf271011913a9f352f58e140224c936736Alex Deymo  // method not being called.
61542c19bf271011913a9f352f58e140224c936736Alex Deymo  virtual void DownloadComplete() = 0;
6263b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes};
6363b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes
6473058b421f91e04cc605c2a113e0010009a63594Darin Petkovclass PrefsInterface;
6549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
66d317e40be46e1b69f624a8165472c99fe6346a1eChris Sosaclass DownloadAction : public InstallPlanAction,
6749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com                       public HttpFetcherDelegate {
6849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com public:
69f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  // Debugging/logging
70f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  static std::string StaticType() { return "DownloadAction"; }
71f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo
7249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // Takes ownership of the passed in HttpFetcher. Useful for testing.
7349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // A good calling pattern is:
741b3556cbe66b3f5be35f6117d4013ddc199b064cAlex Deymo  // DownloadAction(prefs, boot_contol, hardware, system_state,
751b3556cbe66b3f5be35f6117d4013ddc199b064cAlex Deymo  //                new WhateverHttpFetcher);
76f057205065339c54d3403263f049e2ea69417665Jay Srinivasan  DownloadAction(PrefsInterface* prefs,
771b3556cbe66b3f5be35f6117d4013ddc199b064cAlex Deymo                 BootControlInterface* boot_control,
781b3556cbe66b3f5be35f6117d4013ddc199b064cAlex Deymo                 HardwareInterface* hardware,
79f057205065339c54d3403263f049e2ea69417665Jay Srinivasan                 SystemState* system_state,
80f057205065339c54d3403263f049e2ea69417665Jay Srinivasan                 HttpFetcher* http_fetcher);
81610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  ~DownloadAction() override;
82f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo
83f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  // InstallPlanAction overrides.
84610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void PerformAction() override;
85f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  void SuspendAction() override;
86f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  void ResumeAction() override;
87610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void TerminateProcessing() override;
88f28585764e91b7c25a7c2856ff645c8bb22d64a9Alex Deymo  std::string Type() const override { return StaticType(); }
8949fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
90f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // Testing
91f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  void SetTestFileWriter(FileWriter* writer) {
92f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes    writer_ = writer;
93f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  }
94f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes
951023a6029771fb8dea867e14193df8e58a59a662Darin Petkov  int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); }
961023a6029771fb8dea867e14193df8e58a59a662Darin Petkov
9763b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  // HttpFetcherDelegate methods (see http_fetcher.h)
9860ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  void ReceivedBytes(HttpFetcher* fetcher,
99f68bbbc952aa9a71898e4939b5f36187fa564a50Alex Vakulenko                     const void* bytes, size_t length) override;
100610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo  void SeekToOffset(off_t offset) override;
10160ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  void TransferComplete(HttpFetcher* fetcher, bool successful) override;
10260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  void TransferTerminated(HttpFetcher* fetcher) override;
10349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
104f42cc1c604fe5b0be29847a24f9bd5acf42ba394Darin Petkov  DownloadActionDelegate* delegate() const { return delegate_; }
10563b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  void set_delegate(DownloadActionDelegate* delegate) {
10663b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes    delegate_ = delegate;
10763b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  }
10863b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes
1099b23057b7f9ad6c366d92a59fcffcc87375bae08Darin Petkov  HttpFetcher* http_fetcher() { return http_fetcher_.get(); }
1109b23057b7f9ad6c366d92a59fcffcc87375bae08Darin Petkov
1118f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // Returns the p2p file id for the file being written or the empty
1128f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // string if we're not writing to a p2p file.
113d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko  std::string p2p_file_id() { return p2p_file_id_; }
1148f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen
11549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com private:
1168f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // Closes the file descriptor for the p2p file being written and
1178f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // clears |p2p_file_id_| to indicate that we're no longer sharing
1188f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // the file. If |delete_p2p_file| is True, also deletes the file.
1198f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // If there is no p2p file descriptor, this method does nothing.
1208f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  void CloseP2PSharingFd(bool delete_p2p_file);
1218f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen
1228f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // Starts sharing the p2p file. Must be called before
1238f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // WriteToP2PFile(). Returns True if this worked.
1248f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  bool SetupP2PSharingFd();
1258f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen
1268f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // Writes |length| bytes of payload from |data| into |file_offset|
1278f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // of the p2p file. Also does sanity checks; for example ensures we
1288f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // don't end up with a file with holes in it.
1298f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  //
1308f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // This method does nothing if SetupP2PSharingFd() hasn't been
1318f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // called or if CloseP2PSharingFd() has been called.
13260ca1a7bca7cc804ec80b510483081ef894de4cdAlex Deymo  void WriteToP2PFile(const void* data, size_t length, off_t file_offset);
1338f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen
134f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // The InstallPlan passed in
135f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  InstallPlan install_plan_;
13649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1371b3556cbe66b3f5be35f6117d4013ddc199b064cAlex Deymo  // SystemState required pointers.
13873058b421f91e04cc605c2a113e0010009a63594Darin Petkov  PrefsInterface* prefs_;
1391b3556cbe66b3f5be35f6117d4013ddc199b064cAlex Deymo  BootControlInterface* boot_control_;
1401b3556cbe66b3f5be35f6117d4013ddc199b064cAlex Deymo  HardwareInterface* hardware_;
14173058b421f91e04cc605c2a113e0010009a63594Darin Petkov
142edce28385c15d953bd04f7bc715c45f02dc850f6Jay Srinivasan  // Global context for the system.
143edce28385c15d953bd04f7bc715c45f02dc850f6Jay Srinivasan  SystemState* system_state_;
144edce28385c15d953bd04f7bc715c45f02dc850f6Jay Srinivasan
145edce28385c15d953bd04f7bc715c45f02dc850f6Jay Srinivasan  // Pointer to the HttpFetcher that does the http work.
14602f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  std::unique_ptr<HttpFetcher> http_fetcher_;
147edce28385c15d953bd04f7bc715c45f02dc850f6Jay Srinivasan
14849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  // The FileWriter that downloaded data should be written to. It will
149f9185170a9763e493e77ffdc5b1f057c3bd3b11eAndrew de los Reyes  // either point to *decompressing_file_writer_ or *delta_performer_.
15049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  FileWriter* writer_;
15149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
15202f7c1dee242f490143791dbb73fa23fa3007cfaBen Chan  std::unique_ptr<DeltaPerformer> delta_performer_;
15349fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
1549ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov  // Used by TransferTerminated to figure if this action terminated itself or
1559ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov  // was terminated by the action processor.
156a99981fda75fe0b17e96c700e3ddc93eca1cebe5David Zeuthen  ErrorCode code_;
1579ce452b6acd95899e9adb17c2935012625163dc6Darin Petkov
15863b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  // For reporting status to outsiders
15963b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  DownloadActionDelegate* delegate_;
16063b96d74b2ffe5999243ab5c33f588030bcb42ceAndrew de los Reyes  uint64_t bytes_received_;
16122ad86121ba56c576bfcaa23e085dab881bd4ff5Alex Deymo  bool download_active_{false};
1629d911fa4ed05cb51319636a4b6ce94b0260156aeDarin Petkov
1638f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // The file-id for the file we're sharing or the empty string
1648f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // if we're not using p2p to share.
1658f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  std::string p2p_file_id_;
1668f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen
1678f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // The file descriptor for the p2p file used for caching the payload or -1
1688f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // if we're not using p2p to share.
1698f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  int p2p_sharing_fd_;
1708f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen
1718f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  // Set to |false| if p2p file is not visible.
1728f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen  bool p2p_visible_;
1738f191b22a1a1ab2b803d65ee488729206e648695David Zeuthen
17449fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com  DISALLOW_COPY_AND_ASSIGN(DownloadAction);
17549fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com};
17649fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
17749fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// We want to be sure that we're compiled with large file support on linux,
17849fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com// just in case we find ourselves downloading large images.
1790103c36caa2e38e034e0d22185736b9ccfb35c58Alex Vakulenkostatic_assert(8 == sizeof(off_t), "off_t not 64 bit");
18049fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
18149fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com}  // namespace chromeos_update_engine
18249fdf1889b965be25f929eeebc5b60cd40b9043rspangler@google.com
18339910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#endif  // UPDATE_ENGINE_PAYLOAD_CONSUMER_DOWNLOAD_ACTION_H_
184