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#include "log/log.h"
17#include "ptable_manager.h"
18#include "ptable_process.h"
19#include "utils.h"
20
21using namespace Hpackage;
22namespace Updater {
23extern "C" __attribute__((constructor)) void RegisterPtableHelper(void)
24{
25    PtablePreProcess::GetInstance().RegisterPtableHelper(PtableProcess);
26}
27
28void PtablePreProcess::RegisterPtableHelper(PtablePreProcessFunc ptr)
29{
30    helper_ = std::move(ptr);
31}
32
33bool PtablePreProcess::DoPtableProcess(UpdaterParams &upParams)
34{
35    if (helper_ == nullptr) {
36        LOG(INFO) << "PtablePreProcess helper_ is null";
37        return false;
38    }
39    return helper_(upParams);
40}
41
42bool PtableProcess(UpdaterParams &upParams)
43{
44    for (auto &path : upParams.updatePackage) {
45        Hpackage::PkgManager::PkgManagerPtr pkgManager = Hpackage::PkgManager::CreatePackageInstance();
46        std::vector<std::string> components;
47        if (pkgManager == nullptr) {
48            LOG(ERROR) << "Fail to CreatePackageInstance";
49            return false;
50        }
51        int32_t ret = pkgManager->LoadPackage(path, Utils::GetCertName(), components);
52        if (ret != Hpackage::PKG_SUCCESS) {
53            LOG(ERROR) << "LoadPackage fail ret:" << ret;
54            Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
55            return false;
56        }
57        DevicePtable& devicePtb = DevicePtable::GetInstance();
58        devicePtb.LoadPartitionInfo();
59        PackagePtable& packagePtb = PackagePtable::GetInstance();
60        packagePtb.LoadPartitionInfo(pkgManager);
61        if (!devicePtb.ComparePtable(packagePtb)) {
62            LOG(INFO) << "Ptable NOT changed, no need to process!";
63            Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
64            continue;
65        }
66        if (upParams.updateMode != SDCARD_UPDATE) {
67            if (devicePtb.ComparePartition(packagePtb, "USERDATA")) {
68                LOG(ERROR) << "Hota update not allow userdata partition change!";
69                Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
70                return false;
71            }
72        }
73        if (!packagePtb.WritePtableToDevice()) {
74            LOG(ERROR) << "Ptable changed, write new ptable failed!";
75            Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
76            return false;
77        }
78        Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
79    }
80    return true;
81}
82}