1*5a923131SAndroid Build Coastguard Worker //
2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2016 The Android Open Source Project
3*5a923131SAndroid Build Coastguard Worker //
4*5a923131SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*5a923131SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*5a923131SAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*5a923131SAndroid Build Coastguard Worker //
8*5a923131SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
9*5a923131SAndroid Build Coastguard Worker //
10*5a923131SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*5a923131SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*5a923131SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5a923131SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*5a923131SAndroid Build Coastguard Worker // limitations under the License.
15*5a923131SAndroid Build Coastguard Worker //
16*5a923131SAndroid Build Coastguard Worker
17*5a923131SAndroid Build Coastguard Worker #include <xz.h>
18*5a923131SAndroid Build Coastguard Worker
19*5a923131SAndroid Build Coastguard Worker #include <string>
20*5a923131SAndroid Build Coastguard Worker #include <vector>
21*5a923131SAndroid Build Coastguard Worker
22*5a923131SAndroid Build Coastguard Worker #include <base/command_line.h>
23*5a923131SAndroid Build Coastguard Worker #include <base/strings/string_split.h>
24*5a923131SAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
25*5a923131SAndroid Build Coastguard Worker #include <brillo/asynchronous_signal_handler.h>
26*5a923131SAndroid Build Coastguard Worker #include <brillo/flag_helper.h>
27*5a923131SAndroid Build Coastguard Worker #include <brillo/message_loops/base_message_loop.h>
28*5a923131SAndroid Build Coastguard Worker #include <brillo/streams/file_stream.h>
29*5a923131SAndroid Build Coastguard Worker #include <brillo/streams/stream.h>
30*5a923131SAndroid Build Coastguard Worker
31*5a923131SAndroid Build Coastguard Worker #include "update_engine/aosp/update_attempter_android.h"
32*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/boot_control.h"
33*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/error_code_utils.h"
34*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/hardware.h"
35*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/logging.h"
36*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/prefs.h"
37*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/subprocess.h"
38*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/terminator.h"
39*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/utils.h"
40*5a923131SAndroid Build Coastguard Worker
41*5a923131SAndroid Build Coastguard Worker using std::string;
42*5a923131SAndroid Build Coastguard Worker using std::vector;
43*5a923131SAndroid Build Coastguard Worker using update_engine::UpdateEngineStatus;
44*5a923131SAndroid Build Coastguard Worker using update_engine::UpdateStatus;
45*5a923131SAndroid Build Coastguard Worker
46*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine {
47*5a923131SAndroid Build Coastguard Worker namespace {
48*5a923131SAndroid Build Coastguard Worker
49*5a923131SAndroid Build Coastguard Worker class SideloadDaemonState : public DaemonStateInterface,
50*5a923131SAndroid Build Coastguard Worker public ServiceObserverInterface {
51*5a923131SAndroid Build Coastguard Worker public:
SideloadDaemonState(brillo::StreamPtr status_stream)52*5a923131SAndroid Build Coastguard Worker explicit SideloadDaemonState(brillo::StreamPtr status_stream)
53*5a923131SAndroid Build Coastguard Worker : status_stream_(std::move(status_stream)) {
54*5a923131SAndroid Build Coastguard Worker // Add this class as the only observer.
55*5a923131SAndroid Build Coastguard Worker observers_.insert(this);
56*5a923131SAndroid Build Coastguard Worker }
57*5a923131SAndroid Build Coastguard Worker ~SideloadDaemonState() override = default;
58*5a923131SAndroid Build Coastguard Worker
59*5a923131SAndroid Build Coastguard Worker // DaemonStateInterface overrides.
StartUpdater()60*5a923131SAndroid Build Coastguard Worker bool StartUpdater() override { return true; }
AddObserver(ServiceObserverInterface * observer)61*5a923131SAndroid Build Coastguard Worker void AddObserver(ServiceObserverInterface* observer) override {}
RemoveObserver(ServiceObserverInterface * observer)62*5a923131SAndroid Build Coastguard Worker void RemoveObserver(ServiceObserverInterface* observer) override {}
service_observers()63*5a923131SAndroid Build Coastguard Worker const std::set<ServiceObserverInterface*>& service_observers() override {
64*5a923131SAndroid Build Coastguard Worker return observers_;
65*5a923131SAndroid Build Coastguard Worker }
66*5a923131SAndroid Build Coastguard Worker
67*5a923131SAndroid Build Coastguard Worker // ServiceObserverInterface overrides.
SendStatusUpdate(const UpdateEngineStatus & update_engine_status)68*5a923131SAndroid Build Coastguard Worker void SendStatusUpdate(
69*5a923131SAndroid Build Coastguard Worker const UpdateEngineStatus& update_engine_status) override {
70*5a923131SAndroid Build Coastguard Worker UpdateStatus status = update_engine_status.status;
71*5a923131SAndroid Build Coastguard Worker double progress = update_engine_status.progress;
72*5a923131SAndroid Build Coastguard Worker if (status_ != status && (status == UpdateStatus::DOWNLOADING ||
73*5a923131SAndroid Build Coastguard Worker status == UpdateStatus::FINALIZING)) {
74*5a923131SAndroid Build Coastguard Worker // Split the progress bar in two parts for the two stages DOWNLOADING and
75*5a923131SAndroid Build Coastguard Worker // FINALIZING.
76*5a923131SAndroid Build Coastguard Worker ReportStatus(android::base::StringPrintf(
77*5a923131SAndroid Build Coastguard Worker "ui_print Step %d/2", status == UpdateStatus::DOWNLOADING ? 1 : 2));
78*5a923131SAndroid Build Coastguard Worker ReportStatus(android::base::StringPrintf("progress 0.5 0"));
79*5a923131SAndroid Build Coastguard Worker }
80*5a923131SAndroid Build Coastguard Worker if (status_ != status || fabs(progress - progress_) > 0.005) {
81*5a923131SAndroid Build Coastguard Worker ReportStatus(android::base::StringPrintf("set_progress %.lf", progress));
82*5a923131SAndroid Build Coastguard Worker }
83*5a923131SAndroid Build Coastguard Worker progress_ = progress;
84*5a923131SAndroid Build Coastguard Worker status_ = status;
85*5a923131SAndroid Build Coastguard Worker }
86*5a923131SAndroid Build Coastguard Worker
SendPayloadApplicationComplete(ErrorCode error_code)87*5a923131SAndroid Build Coastguard Worker void SendPayloadApplicationComplete(ErrorCode error_code) override {
88*5a923131SAndroid Build Coastguard Worker if (error_code != ErrorCode::kSuccess) {
89*5a923131SAndroid Build Coastguard Worker ReportStatus(android::base::StringPrintf(
90*5a923131SAndroid Build Coastguard Worker "ui_print Error applying update: %d (%s)",
91*5a923131SAndroid Build Coastguard Worker error_code,
92*5a923131SAndroid Build Coastguard Worker utils::ErrorCodeToString(error_code).c_str()));
93*5a923131SAndroid Build Coastguard Worker }
94*5a923131SAndroid Build Coastguard Worker error_code_ = error_code;
95*5a923131SAndroid Build Coastguard Worker brillo::MessageLoop::current()->BreakLoop();
96*5a923131SAndroid Build Coastguard Worker }
97*5a923131SAndroid Build Coastguard Worker
98*5a923131SAndroid Build Coastguard Worker // Getters.
status()99*5a923131SAndroid Build Coastguard Worker UpdateStatus status() { return status_; }
error_code()100*5a923131SAndroid Build Coastguard Worker ErrorCode error_code() { return error_code_; }
101*5a923131SAndroid Build Coastguard Worker
102*5a923131SAndroid Build Coastguard Worker private:
103*5a923131SAndroid Build Coastguard Worker // Report a status message in the status_stream_, if any. These messages
104*5a923131SAndroid Build Coastguard Worker // should conform to the specification defined in the Android recovery.
ReportStatus(const string & message)105*5a923131SAndroid Build Coastguard Worker void ReportStatus(const string& message) {
106*5a923131SAndroid Build Coastguard Worker if (!status_stream_)
107*5a923131SAndroid Build Coastguard Worker return;
108*5a923131SAndroid Build Coastguard Worker string status_line = message + "\n";
109*5a923131SAndroid Build Coastguard Worker status_stream_->WriteAllBlocking(
110*5a923131SAndroid Build Coastguard Worker status_line.data(), status_line.size(), nullptr);
111*5a923131SAndroid Build Coastguard Worker }
112*5a923131SAndroid Build Coastguard Worker
113*5a923131SAndroid Build Coastguard Worker std::set<ServiceObserverInterface*> observers_;
114*5a923131SAndroid Build Coastguard Worker brillo::StreamPtr status_stream_;
115*5a923131SAndroid Build Coastguard Worker
116*5a923131SAndroid Build Coastguard Worker // The last status and error code reported.
117*5a923131SAndroid Build Coastguard Worker UpdateStatus status_{UpdateStatus::IDLE};
118*5a923131SAndroid Build Coastguard Worker ErrorCode error_code_{ErrorCode::kSuccess};
119*5a923131SAndroid Build Coastguard Worker double progress_{-1.};
120*5a923131SAndroid Build Coastguard Worker };
121*5a923131SAndroid Build Coastguard Worker
122*5a923131SAndroid Build Coastguard Worker // Apply an update payload directly from the given payload URI.
ApplyUpdatePayload(const string & payload,int64_t payload_offset,int64_t payload_size,const vector<string> & headers,int64_t status_fd)123*5a923131SAndroid Build Coastguard Worker bool ApplyUpdatePayload(const string& payload,
124*5a923131SAndroid Build Coastguard Worker int64_t payload_offset,
125*5a923131SAndroid Build Coastguard Worker int64_t payload_size,
126*5a923131SAndroid Build Coastguard Worker const vector<string>& headers,
127*5a923131SAndroid Build Coastguard Worker int64_t status_fd) {
128*5a923131SAndroid Build Coastguard Worker brillo::BaseMessageLoop loop;
129*5a923131SAndroid Build Coastguard Worker loop.SetAsCurrent();
130*5a923131SAndroid Build Coastguard Worker
131*5a923131SAndroid Build Coastguard Worker // Setup the subprocess handler.
132*5a923131SAndroid Build Coastguard Worker brillo::AsynchronousSignalHandler handler;
133*5a923131SAndroid Build Coastguard Worker handler.Init();
134*5a923131SAndroid Build Coastguard Worker Subprocess subprocess;
135*5a923131SAndroid Build Coastguard Worker subprocess.Init(&handler);
136*5a923131SAndroid Build Coastguard Worker
137*5a923131SAndroid Build Coastguard Worker SideloadDaemonState sideload_daemon_state(
138*5a923131SAndroid Build Coastguard Worker brillo::FileStream::FromFileDescriptor(status_fd, true, nullptr));
139*5a923131SAndroid Build Coastguard Worker
140*5a923131SAndroid Build Coastguard Worker // During the sideload we don't access the prefs persisted on disk but instead
141*5a923131SAndroid Build Coastguard Worker // use a temporary memory storage.
142*5a923131SAndroid Build Coastguard Worker MemoryPrefs prefs;
143*5a923131SAndroid Build Coastguard Worker
144*5a923131SAndroid Build Coastguard Worker std::unique_ptr<BootControlInterface> boot_control =
145*5a923131SAndroid Build Coastguard Worker boot_control::CreateBootControl();
146*5a923131SAndroid Build Coastguard Worker if (!boot_control) {
147*5a923131SAndroid Build Coastguard Worker LOG(ERROR) << "Error initializing the BootControlInterface.";
148*5a923131SAndroid Build Coastguard Worker return false;
149*5a923131SAndroid Build Coastguard Worker }
150*5a923131SAndroid Build Coastguard Worker
151*5a923131SAndroid Build Coastguard Worker std::unique_ptr<HardwareInterface> hardware = hardware::CreateHardware();
152*5a923131SAndroid Build Coastguard Worker if (!hardware) {
153*5a923131SAndroid Build Coastguard Worker LOG(ERROR) << "Error initializing the HardwareInterface.";
154*5a923131SAndroid Build Coastguard Worker return false;
155*5a923131SAndroid Build Coastguard Worker }
156*5a923131SAndroid Build Coastguard Worker
157*5a923131SAndroid Build Coastguard Worker UpdateAttempterAndroid update_attempter(&sideload_daemon_state,
158*5a923131SAndroid Build Coastguard Worker &prefs,
159*5a923131SAndroid Build Coastguard Worker boot_control.get(),
160*5a923131SAndroid Build Coastguard Worker hardware.get(),
161*5a923131SAndroid Build Coastguard Worker nullptr);
162*5a923131SAndroid Build Coastguard Worker update_attempter.Init();
163*5a923131SAndroid Build Coastguard Worker
164*5a923131SAndroid Build Coastguard Worker TEST_AND_RETURN_FALSE(update_attempter.ApplyPayload(
165*5a923131SAndroid Build Coastguard Worker payload, payload_offset, payload_size, headers, nullptr));
166*5a923131SAndroid Build Coastguard Worker
167*5a923131SAndroid Build Coastguard Worker loop.Run();
168*5a923131SAndroid Build Coastguard Worker return sideload_daemon_state.status() == UpdateStatus::UPDATED_NEED_REBOOT;
169*5a923131SAndroid Build Coastguard Worker }
170*5a923131SAndroid Build Coastguard Worker
171*5a923131SAndroid Build Coastguard Worker } // namespace
172*5a923131SAndroid Build Coastguard Worker } // namespace chromeos_update_engine
173*5a923131SAndroid Build Coastguard Worker
main(int argc,char ** argv)174*5a923131SAndroid Build Coastguard Worker int main(int argc, char** argv) {
175*5a923131SAndroid Build Coastguard Worker DEFINE_string(payload,
176*5a923131SAndroid Build Coastguard Worker "file:///data/payload.bin",
177*5a923131SAndroid Build Coastguard Worker "The URI to the update payload to use.");
178*5a923131SAndroid Build Coastguard Worker DEFINE_int64(
179*5a923131SAndroid Build Coastguard Worker offset, 0, "The offset in the payload where the CrAU update starts. ");
180*5a923131SAndroid Build Coastguard Worker DEFINE_int64(size,
181*5a923131SAndroid Build Coastguard Worker 0,
182*5a923131SAndroid Build Coastguard Worker "The size of the CrAU part of the payload. If 0 is passed, it "
183*5a923131SAndroid Build Coastguard Worker "will be autodetected.");
184*5a923131SAndroid Build Coastguard Worker DEFINE_string(headers,
185*5a923131SAndroid Build Coastguard Worker "",
186*5a923131SAndroid Build Coastguard Worker "A list of key-value pairs, one element of the list per line.");
187*5a923131SAndroid Build Coastguard Worker DEFINE_int64(status_fd, -1, "A file descriptor to notify the update status.");
188*5a923131SAndroid Build Coastguard Worker
189*5a923131SAndroid Build Coastguard Worker chromeos_update_engine::Terminator::Init();
190*5a923131SAndroid Build Coastguard Worker chromeos_update_engine::SetupLogging(true /* stderr */, false /* file */);
191*5a923131SAndroid Build Coastguard Worker brillo::FlagHelper::Init(argc, argv, "Update Engine Sideload");
192*5a923131SAndroid Build Coastguard Worker
193*5a923131SAndroid Build Coastguard Worker LOG(INFO) << "Update Engine Sideloading starting";
194*5a923131SAndroid Build Coastguard Worker
195*5a923131SAndroid Build Coastguard Worker // xz-embedded requires to initialize its CRC-32 table once on startup.
196*5a923131SAndroid Build Coastguard Worker xz_crc32_init();
197*5a923131SAndroid Build Coastguard Worker
198*5a923131SAndroid Build Coastguard Worker vector<string> headers = base::SplitString(
199*5a923131SAndroid Build Coastguard Worker FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
200*5a923131SAndroid Build Coastguard Worker
201*5a923131SAndroid Build Coastguard Worker if (!chromeos_update_engine::ApplyUpdatePayload(
202*5a923131SAndroid Build Coastguard Worker FLAGS_payload, FLAGS_offset, FLAGS_size, headers, FLAGS_status_fd))
203*5a923131SAndroid Build Coastguard Worker return 1;
204*5a923131SAndroid Build Coastguard Worker
205*5a923131SAndroid Build Coastguard Worker return 0;
206*5a923131SAndroid Build Coastguard Worker }
207