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>
23 namespace Updater {
24 static std::atomic<float> g_totalProgress(0.0f);
25 static bool g_progressExitFlag = false;
FillUpdateProgress()26 void FillUpdateProgress()
27 {
28     g_totalProgress.store(1.001f); // ensure > 1.0f
29 }
30 
SetUpdateProgress(float step)31 void SetUpdateProgress(float step)
32 {
33     float totalProgress = g_totalProgress.load();
34     totalProgress += step;
35     g_totalProgress.store(totalProgress);
36 }
37 
GetUpdateProress()38 float GetUpdateProress()
39 {
40     return g_totalProgress.load();
41 }
42 
SetProgressExitFlag(pthread_t & thread)43 void SetProgressExitFlag(pthread_t &thread)
44 {
45     g_progressExitFlag = true;
46     pthread_join(thread, nullptr);
47 }
48 
OtaUpdateProgressThread(void * usEnv)49 static 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 
CreateProgressThread(Uscript::UScriptEnv * env,pthread_t & thread)75 int 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 }