1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <stdint.h>
20 #include <stdio.h>
21 
22 #include <memory>
23 #include <string>
24 #include <string_view>
25 
26 #include <ziparchive/zip_archive.h>
27 
28 #include "edify/expr.h"
29 #include "edify/updater_interface.h"
30 #include "otautil/error_code.h"
31 #include "otautil/sysutil.h"
32 
33 class Updater : public UpdaterInterface {
34  public:
Updater(std::unique_ptr<UpdaterRuntimeInterface> run_time)35   explicit Updater(std::unique_ptr<UpdaterRuntimeInterface> run_time)
36       : runtime_(std::move(run_time)) {}
37 
38   ~Updater() override;
39 
40   // Memory-maps the OTA package and opens it as a zip file. Also sets up the command pipe and
41   // UpdaterRuntime.
42   bool Init(int fd, const std::string_view package_filename, bool is_retry);
43 
44   // Parses and evaluates the updater-script in the OTA package. Reports the error code if the
45   // evaluation fails.
46   bool RunUpdate();
47 
48   // Writes the message to command pipe, adds a new line in the end.
49   void WriteToCommandPipe(const std::string_view message, bool flush = false) const override;
50 
51   // Sends over the message to recovery to print it on the screen.
52   void UiPrint(const std::string_view message) const override;
53 
54   std::string FindBlockDeviceName(const std::string_view name) const override;
55 
GetRuntime()56   UpdaterRuntimeInterface* GetRuntime() const override {
57     return runtime_.get();
58   }
GetPackageHandle()59   ZipArchiveHandle GetPackageHandle() const override {
60     return package_handle_;
61   }
GetResult()62   std::string GetResult() const override {
63     return result_;
64   }
GetMappedPackageAddress()65   uint8_t* GetMappedPackageAddress() const override {
66     return mapped_package_.addr;
67   }
GetMappedPackageLength()68   size_t GetMappedPackageLength() const override {
69     return mapped_package_.length;
70   }
71 
72  private:
73   friend class UpdaterTestBase;
74   friend class UpdaterTest;
75   // Where in the package we expect to find the edify script to execute.
76   // (Note it's "updateR-script", not the older "update-script".)
77   static constexpr const char* SCRIPT_NAME = "META-INF/com/google/android/updater-script";
78 
79   // Reads the entry |name| in the zip archive and put the result in |content|.
80   bool ReadEntryToString(ZipArchiveHandle za, const std::string& entry_name, std::string* content);
81 
82   // Parses the error code embedded in state->errmsg; and reports the error code and cause code.
83   void ParseAndReportErrorCode(State* state);
84 
85   std::unique_ptr<UpdaterRuntimeInterface> runtime_;
86 
87   MemMapping mapped_package_;
88   ZipArchiveHandle package_handle_{ nullptr };
89   std::string updater_script_;
90 
91   bool is_retry_{ false };
92   std::unique_ptr<FILE, decltype(&fclose)> cmd_pipe_{ nullptr, fclose };
93 
94   std::string result_;
95   std::vector<std::string> skipped_functions_;
96 };
97