• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_THREAD_H
17 #define UPDATER_THREAD_H
18 
19 #include <atomic>
20 #include <functional>
21 #include <thread>
22 #include <file_utils.h>
23 #include "curl/curl.h"
24 
25 #include "progress.h"
26 
27 namespace OHOS {
28 namespace UpdateService {
29 #define ENGINE_CHECK_NO_LOG(retCode, exper) \
30     if (!(retCode)) {                     \
31         exper;                            \
32     }
33 
34 constexpr uint32_t DOWNLOAD_FINISH_PERCENT = 100;
35 constexpr uint32_t DOWNLOAD_PERIOD_PERCENT = 1;
36 constexpr int32_t TIMEOUT_FOR_DOWNLOAD = 600;
37 constexpr int32_t TIMEOUT_FOR_STREAM_DOWNLOAD = 3600;
38 #ifndef UPDATER_UT
39 constexpr int32_t TIMEOUT_FOR_CONNECT = 10;
40 #else
41 constexpr int32_t TIMEOUT_FOR_CONNECT = 1;
42 #endif
43 
44 class ProgressThread {
45 public:
46     ProgressThread() = default;
47     virtual ~ProgressThread();
48     static bool isNoNet_;
49     static bool isCancel_;
50 protected:
51     int32_t StartProgress();
52     void StopProgress();
53     void QuitDownloadThread();
54     void ExecuteThreadFunc();
55 
56     virtual bool ProcessThreadExecute() = 0;
57     virtual void ProcessThreadExit() = 0;
58 
59 private:
60     std::thread *pDealThread_ { nullptr };
61     std::mutex mutex_;
62     std::condition_variable condition_;
63     bool isWake_ = false;
64     bool isExitThread_ = false;
65 };
66 
67 class DownloadThread : public ProgressThread {
68 public:
69     using ProgressCallback = std::function<void (const std::string serverUrl, const std::string &fileName,
70         const Progress &progress)>;
DownloadThread(ProgressCallback callback)71     explicit DownloadThread(ProgressCallback callback) : ProgressThread(), callback_(callback) {}
~DownloadThread()72     ~DownloadThread() override
73     {
74         ProgressThread::QuitDownloadThread();
75     }
76 
77     int32_t StartDownload(const std::string &fileName, const std::string &url);
78     void StopDownload();
79 
80     static size_t GetLocalFileLength(const std::string &fileName);
81     static size_t WriteFunc(void *ptr, size_t size, size_t nmemb, const void *stream);
82     static int32_t DownloadProgress(const void *localData,
83         double dlTotal, double dlNow, double ulTotal, double ulNow);
84 
GetPackageSize()85     double GetPackageSize()
86     {
87         packageSize_ = GetLocalFileLength(downloadFileName_);
88         return static_cast<double>(packageSize_);
89     };
90 
91 protected:
92     bool ProcessThreadExecute() override;
93     void ProcessThreadExit() override;
94     int32_t DownloadCallback(uint32_t percent, UpgradeStatus status, const std::string &error);
95     static FILE* FileOpen(const std::string &fileName, const std::string &mode);
96 
97 private:
98     Progress downloadProgress_ {};
99     ProgressCallback callback_;
100     CURL *downloadHandle_ { nullptr };
101     FILE *downloadFile_ { nullptr };
102     std::string serverUrl_;
103     std::atomic<bool> exitDownload_ { false };
104     size_t packageSize_ { 1 };
105     std::string downloadFileName_;
106     bool DealAbnormal(uint32_t percent);
107 };
108 
109 // 缓冲区大小50KB
110 constexpr size_t BUFFER_SIZE = 50 * 1024;
111 
112 class StreamProgressThread : public ProgressThread {
113 public:
114     using ProgressCallback = std::function<void (const Progress &progress)>;
StreamProgressThread(ProgressCallback callback)115     explicit StreamProgressThread(ProgressCallback callback) : ProgressThread(), callback_(callback) {}
~StreamProgressThread()116     ~StreamProgressThread() override
117     {
118         ProgressThread::QuitDownloadThread();
119     }
120 
121     int32_t StartDownload(const std::string &url, const int64_t size, const int64_t recordPoint);
122     void StopDownload();
123 
124     static size_t WriteFunc(uint8_t *ptr, size_t size, size_t nmemb, void *localData);
125     static int32_t DownloadProgress(const void *localData,
126         double dlTotal, double dlNow, double ulTotal, double ulNow);
127 
128 protected:
129     bool ProcessThreadExecute() override;
130     void ProcessThreadExit() override;
131     int32_t DownloadCallback(uint32_t percent, UpgradeStatus status, const std::string &error);
132 
133 private:
134     bool DealExitOrCancel();
135     bool CheckFileSize();
136     bool DownloadFile();
137 
138 private:
139     Progress downloadProgress_ {};
140     ProgressCallback callback_;
141     CURL *downloadHandle_ { nullptr };
142     uint8_t buffer_[BUFFER_SIZE] = {0};
143     size_t bufferPos_ = 0; // 缓冲区中的当前位置
144     std::string serverUrl_;
145     int64_t totalFileSize_ = 0; // 总文件大小
146     int64_t downloadedSize_ = 0; // 已下载大小
147     std::atomic<bool> exitDownload_ { false };
148 };
149 } // namespace UpdateService
150 } // namespace OHOS
151 #endif // UPDATER_THREAD_H
152