1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
//
// Copyright (C) 2011 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_H_
#define UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_H_
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <memory>
#include <string>
#include <utility>
#include "update_engine/common/action.h"
#include "update_engine/common/boot_control_interface.h"
#include "update_engine/common/http_fetcher.h"
#include "update_engine/common/multi_range_http_fetcher.h"
#include "update_engine/payload_consumer/delta_performer.h"
#include "update_engine/payload_consumer/install_plan.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:
virtual ~DownloadActionDelegate() = default;
// Called periodically after bytes are received. This method will be invoked
// only if the DownloadAction is running. |bytes_progressed| is the number of
// bytes downloaded since the last call of this method, |bytes_received|
// the number of bytes downloaded thus far and |total| is the number of bytes
// expected.
virtual void BytesReceived(uint64_t bytes_progressed,
uint64_t bytes_received,
uint64_t total) = 0;
// Returns whether the download should be canceled, in which case the
// |cancel_reason| error should be set to the reason why the download was
// canceled.
virtual bool ShouldCancel(ErrorCode* cancel_reason) = 0;
// Called once the complete payload has been downloaded. Note that any errors
// while applying or downloading the partial payload will result in this
// method not being called.
virtual void DownloadComplete() = 0;
};
class PrefsInterface;
class DownloadAction : public InstallPlanAction, public HttpFetcherDelegate {
public:
// Debugging/logging
static std::string StaticType() { return "DownloadAction"; }
// Takes ownership of the passed in HttpFetcher. Useful for testing.
// A good calling pattern is:
// DownloadAction(prefs, boot_contol, hardware,
// new WhateverHttpFetcher, false);
DownloadAction(PrefsInterface* prefs,
BootControlInterface* boot_control,
HardwareInterface* hardware,
HttpFetcher* http_fetcher,
bool interactive);
~DownloadAction() override;
// InstallPlanAction overrides.
void PerformAction() override;
void SuspendAction() override;
void ResumeAction() override;
void TerminateProcessing() override;
std::string Type() const override { return StaticType(); }
// Testing
void SetTestFileWriter(std::unique_ptr<DeltaPerformer> writer) {
delta_performer_ = std::move(writer);
}
int GetHTTPResponseCode() { return http_fetcher_->http_response_code(); }
// HttpFetcherDelegate methods (see http_fetcher.h)
bool ReceivedBytes(HttpFetcher* fetcher,
const void* bytes,
size_t length) override;
void SeekToOffset(off_t offset) override;
void TransferComplete(HttpFetcher* fetcher, bool successful) override;
void TransferTerminated(HttpFetcher* fetcher) override;
DownloadActionDelegate* delegate() const { return delegate_; }
void set_delegate(DownloadActionDelegate* delegate) { delegate_ = delegate; }
void set_base_offset(int64_t base_offset) { base_offset_ = base_offset; }
HttpFetcher* http_fetcher() { return http_fetcher_.get(); }
private:
// Attempt to load cached manifest data from prefs
// return true on success, false otherwise.
bool LoadCachedManifest(int64_t manifest_size);
// Start downloading the current payload using delta_performer.
void StartDownloading();
// Pointer to the current payload in install_plan_.payloads.
InstallPlan::Payload* payload_{nullptr};
// Required pointers.
PrefsInterface* prefs_;
BootControlInterface* boot_control_;
HardwareInterface* hardware_;
// Pointer to the MultiRangeHttpFetcher that does the http work.
std::unique_ptr<MultiRangeHttpFetcher> http_fetcher_;
// If |true|, the update is user initiated (vs. periodic update checks). Hence
// the |delta_performer_| can decide not to use O_DSYNC flag for faster
// update.
bool interactive_;
std::unique_ptr<DeltaPerformer> delta_performer_;
// Used by TransferTerminated to figure if this action terminated itself or
// was terminated by the action processor.
ErrorCode code_;
// For reporting status to outsiders
DownloadActionDelegate* delegate_;
uint64_t bytes_received_{0}; // per file/range
uint64_t bytes_received_previous_payloads_{0};
uint64_t bytes_total_{0};
bool download_active_{false};
// Loaded from prefs before downloading any payload.
size_t resume_payload_index_{0};
// Offset of the payload in the download URL, used by UpdateAttempterAndroid.
int64_t base_offset_{0};
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.
static_assert(8 == sizeof(off_t), "off_t not 64 bit");
} // namespace chromeos_update_engine
#endif // UPDATE_ENGINE_COMMON_DOWNLOAD_ACTION_H_
|