1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef UPDATER_COMPONENT_PROCESSOR
17 #define UPDATER_COMPONENT_PROCESSOR
18 
19 #include <cstdio>
20 #include <map>
21 #include <string>
22 #include <sys/wait.h>
23 #include <unistd.h>
24 #include "applypatch/data_writer.h"
25 #include "applypatch/update_progress.h"
26 #include "macros_updater.h"
27 #include "pkg_manager.h"
28 #include "script_instruction.h"
29 #include "script_manager.h"
30 #include "utils.h"
31 
32 namespace Updater {
33 class ComponentProcessor {
34 public:
ComponentProcessor(const std::string & name,const size_t len)35     ComponentProcessor(const std::string &name, const size_t len)
36         : name_(name), totalSize_(len) {}
~ComponentProcessor()37     virtual ~ComponentProcessor() {}
PreProcess(Uscript::UScriptEnv & env)38     virtual int32_t PreProcess(Uscript::UScriptEnv &env)
39     {
40         return Uscript::USCRIPT_SUCCESS;
41     }
DoProcess(Uscript::UScriptEnv & env)42     virtual int32_t DoProcess(Uscript::UScriptEnv &env)
43     {
44         return Uscript::USCRIPT_SUCCESS;
45     }
PostProcess(Uscript::UScriptEnv & env)46     virtual int32_t PostProcess(Uscript::UScriptEnv &env)
47     {
48         return Uscript::USCRIPT_SUCCESS;
49     }
50 
SetPkgFileSize(const size_t offset,const size_t fileSize)51     virtual void SetPkgFileSize(const size_t offset, const size_t fileSize)
52     {
53         readOffset_ = offset;
54         pkgFileSize_ = fileSize;
55     }
56 
SetPkgFileInfo(size_t offset,size_t fileSize,float proportion)57     void SetPkgFileInfo(size_t offset, size_t fileSize, float proportion)
58     {
59         readOffset_ = offset;
60         pkgFileSize_ = fileSize;
61         proportion_ = proportion;
62     }
63 
UpdateProgress(size_t writeSize)64     void UpdateProgress(size_t writeSize)
65     {
66         if (pkgFileSize_ != 0) {
67             readOffset_ += writeSize;
68             SetUpdateProgress(static_cast<float>(writeSize) / pkgFileSize_ * proportion_);
69         }
70     }
71 protected:
72     std::string name_;
73     size_t totalSize_ {};
74     size_t readOffset_ {};
75     size_t pkgFileSize_ {};
76     float proportion_ {};
77 };
78 
79 class ComponentProcessorFactory {
80     DISALLOW_COPY_MOVE(ComponentProcessorFactory);
81 public:
82     typedef std::unique_ptr<ComponentProcessor> (*Constructor)(const std::string &name, const uint8_t len);
83     using ClassMap = std::map<std::string, Constructor>;
84     void RegisterProcessor(Constructor constructor, std::vector<std::string> &nameList);
85     std::unique_ptr<ComponentProcessor> GetProcessor(const std::string &name, const uint8_t len) const;
86     static ComponentProcessorFactory &GetInstance();
87 
88 private:
ComponentProcessorFactory()89     ComponentProcessorFactory() {}
~ComponentProcessorFactory()90     ~ComponentProcessorFactory() {}
91     ClassMap m_constructorMap;
92 };
93 
94 template <typename SubClassName>
NewObject(const std::string & name,const uint8_t len)95 std::unique_ptr<ComponentProcessor> NewObject(const std::string &name, const uint8_t len)
96 {
97     return std::make_unique<SubClassName>(name, len);
98 }
99 
100 #undef REGISTER_PROCESSOR
101 #define REGISTER_PROCESSOR(subClassName, ...)                                                  \
102     extern "C" __attribute__((constructor)) void subClassName##_RegisterClass()   \
103     {                                                                                 \
104         std::vector<std::string> nameList {__VA_ARGS__};                                   \
105         ComponentProcessorFactory::GetInstance().RegisterProcessor(NewObject<subClassName>,     \
106             nameList);                                                 \
107     }
108 
109 class VersionCheckProcessor : public ComponentProcessor {
110     DISALLOW_COPY_MOVE(VersionCheckProcessor);
111 public:
VersionCheckProcessor(const std::string & name,const size_t len)112     VersionCheckProcessor(const std::string &name, const size_t len)
113         : ComponentProcessor(name, len) {}
~VersionCheckProcessor()114     ~VersionCheckProcessor() override {}
115     int32_t DoProcess(Uscript::UScriptEnv &env) override;
116 };
117 
118 class BoardIdCheckProcessor : public ComponentProcessor {
119     DISALLOW_COPY_MOVE(BoardIdCheckProcessor);
120 public:
BoardIdCheckProcessor(const std::string & name,const size_t len)121     BoardIdCheckProcessor(const std::string &name, const size_t len)
122         : ComponentProcessor(name, len) {}
~BoardIdCheckProcessor()123     ~BoardIdCheckProcessor() override {}
124     int32_t DoProcess(Uscript::UScriptEnv &env) override;
125 };
126 
127 class RawImgProcessor : public ComponentProcessor {
128     DISALLOW_COPY_MOVE(RawImgProcessor);
129 public:
RawImgProcessor(const std::string & name,const size_t len)130     RawImgProcessor(const std::string &name, const size_t len)
131         : ComponentProcessor(name, len) {}
~RawImgProcessor()132     ~RawImgProcessor() override {}
133     int32_t PreProcess(Uscript::UScriptEnv &env) override;
134     int32_t DoProcess(Uscript::UScriptEnv &env) override;
135     int32_t PostProcess(Uscript::UScriptEnv &env) override;
136 private:
137     int GetWritePathAndOffset(const std::string &partitionName, std::string &writePath, uint64_t &offset,
138                               uint64_t &partitionSize);
139     virtual int RawImageWriteProcessor(const Hpackage::PkgBuffer &buffer, size_t size, size_t start,
140                                bool isFinish, const void* context);
141     std::unique_ptr<DataWriter> writer_ = nullptr;
142 };
143 
144 class SkipImgProcessor : public ComponentProcessor {
145     DISALLOW_COPY_MOVE(SkipImgProcessor);
146 public:
SkipImgProcessor(const std::string & name,const size_t len)147     SkipImgProcessor(const std::string &name, const size_t len)
148         : ComponentProcessor(name, len) {}
~SkipImgProcessor()149     ~SkipImgProcessor() override {}
150     int32_t PreProcess(Uscript::UScriptEnv &env) override;
151     int32_t DoProcess(Uscript::UScriptEnv &env) override;
152     int32_t PostProcess(Uscript::UScriptEnv &env) override;
153 private:
154     int SkipImageWriteProcessor(const Hpackage::PkgBuffer &buffer, size_t size, [[maybe_unused]]size_t start,
155                                 [[maybe_unused]]bool isFinish, [[maybe_unused]]const void* context);
156     std::unique_ptr<DataWriter> writer_ = nullptr;
157 };
158 } // namespace Updater
159 #endif // UPDATER_COMPONENT_PROCESSOR
160