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