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 "applypatch/update_progress.h"
17#include <pthread.h>
18#include <thread>
19#include <mutex>
20#include <chrono>
21#include <atomic>
22#include <string>
23namespace Updater {
24static std::atomic<float> g_totalProgress(0.0f);
25static bool g_progressExitFlag = false;
26void FillUpdateProgress()
27{
28    g_totalProgress.store(1.001f); // ensure > 1.0f
29}
30
31void SetUpdateProgress(float step)
32{
33    float totalProgress = g_totalProgress.load();
34    totalProgress += step;
35    g_totalProgress.store(totalProgress);
36}
37
38float GetUpdateProress()
39{
40    return g_totalProgress.load();
41}
42
43void SetProgressExitFlag(pthread_t &thread)
44{
45    g_progressExitFlag = true;
46    pthread_join(thread, nullptr);
47}
48
49static void *OtaUpdateProgressThread(void *usEnv)
50{
51    Uscript::UScriptEnv *env = static_cast<Uscript::UScriptEnv *>(usEnv);
52    float totalProgress = 0.0f;
53    float curProgress = 0.0f;
54    while (true) {
55        totalProgress = GetUpdateProress();
56        if (totalProgress > 1.0f) {
57            g_totalProgress.store(0.0f);
58            totalProgress -= 1.0f;
59            curProgress = 0.0f;
60            std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 500ms
61            continue;
62        }
63        if (g_progressExitFlag == true) {
64            break;
65        }
66        if (curProgress < totalProgress && env != nullptr) {
67            env->PostMessage("set_progress", std::to_string(totalProgress));
68            curProgress = totalProgress;
69        }
70        std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 50ms
71    }
72    return nullptr;
73}
74
75int CreateProgressThread(Uscript::UScriptEnv *env, pthread_t &thread)
76{
77    std::string content = std::to_string(1.0f) + "," + std::to_string(0.0f); // set g_percentage 100
78    env->PostMessage("show_progress", content);
79    return pthread_create(&thread, nullptr, OtaUpdateProgressThread, env);
80}
81}