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