1/* 2 * Copyright (c) 2022 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 "web_download_manager.h" 17 18#include <cstring> 19 20#include "nweb_c_api.h" 21#include "nweb_helper.h" 22#include "nweb_log.h" 23#include "web_download_delegate.h" 24 25namespace OHOS { 26namespace NWeb { 27namespace { 28static std::unique_ptr<OHOS::NWeb::WebDownloadDelegate> g_default_delegate; 29static std::unordered_map<int32_t, WebDownloadDelegate *> g_web_download_delegate_map; 30static WebDownloadDelegateCallback *g_download_callback; 31 32WebDownloadDelegate *GetWebDownloadDelegate(int32_t nwebId) 33{ 34 auto it = g_web_download_delegate_map.find(nwebId); 35 if (it != g_web_download_delegate_map.end()) { 36 return it->second; 37 } 38 return nullptr; 39} 40 41void DownloadBeforeStart(NWebDownloadItem *downloadItem, WebBeforeDownloadCallbackWrapper *wrapper) 42{ 43 WVLOG_D("[DOWNLOAD] DownloadBeforeStart."); 44 if (wrapper == nullptr) { 45 WVLOG_E("[DOWNLOAD] WebBeforeDownloadCallbackWrapper is null"); 46 return; 47 } 48 int32_t nwebId = WebDownloadItem_NWebId(downloadItem); 49 WebDownloadDelegate *webDownloadDelegate = GetWebDownloadDelegate(nwebId); 50 if (!webDownloadDelegate) { 51 WVLOG_D("[DOWNLOAD] donn't found delegate for nweb."); 52 webDownloadDelegate = g_default_delegate.get(); 53 } 54 55 if (!webDownloadDelegate) { 56 WVLOG_E("[DOWNLOAD] webDownloadDelegate is null"); 57 return; 58 } 59 60 WebDownloadItem *webDownloadItem = new WebDownloadItem(webDownloadDelegate->GetEnv(), downloadItem); 61 // destroy download_item since copied content from download_item. 62 WebDownloadItem_Destroy(downloadItem); 63 webDownloadItem->before_download_callback = wrapper; 64 webDownloadDelegate->DownloadBeforeStart(webDownloadItem); 65} 66 67void DownloadDidUpdate(NWebDownloadItem *downloadItem, WebDownloadItemCallbackWrapper *wrapper) 68{ 69 WVLOG_D("DownloadDidUpdate."); 70 if (wrapper == nullptr) { 71 WVLOG_E("[DOWNLOAD] WebBeforeDownloadCallbackWrapper is null"); 72 return; 73 } 74 75 int32_t nwebId = WebDownloadItem_NWebId(downloadItem); 76 77 WebDownloadDelegate *webDownloadDelegate = GetWebDownloadDelegate(nwebId); 78 if (!webDownloadDelegate) { 79 WVLOG_D("[DOWNLOAD] donn't found delegate for nweb."); 80 webDownloadDelegate = g_default_delegate.get(); 81 } 82 83 if (!webDownloadDelegate) { 84 WVLOG_E("[DOWNLOAD] webDownloadDelegate is null"); 85 return; 86 } 87 WebDownloadItem *webDownloadItem = new WebDownloadItem(webDownloadDelegate->GetEnv(), downloadItem); 88 // destroy download_item since copied content from download_item. 89 WebDownloadItem_Destroy(downloadItem); 90 webDownloadItem->download_item_callback = wrapper; 91 switch (webDownloadItem->state) { 92 case NWebDownloadItemState::PENDING: 93 // When in PENDING state, chromium call downloadDidUpdate 94 // while file path is temporary file, just stop calling ui. 95 delete webDownloadItem; 96 webDownloadItem = nullptr; 97 break; 98 case NWebDownloadItemState::IN_PROGRESS: 99 case NWebDownloadItemState::PAUSED: 100 webDownloadDelegate->DownloadDidUpdate(webDownloadItem); 101 break; 102 case NWebDownloadItemState::INTERRUPTED: 103 case NWebDownloadItemState::CANCELED: 104 webDownloadDelegate->DownloadDidFail(webDownloadItem); 105 break; 106 case NWebDownloadItemState::COMPLETE: 107 webDownloadDelegate->DownloadDidFinish(webDownloadItem); 108 break; 109 case NWebDownloadItemState::MAX_DOWNLOAD_STATE: 110 default: 111 delete webDownloadItem; 112 webDownloadItem = nullptr; 113 break; 114 } 115} 116} // namespace 117 118// static 119void WebDownloadManager::RegisterDownloadCallback() 120{ 121 // Only regist once. 122 if (g_download_callback == nullptr) { 123 WVLOG_I("RegisterDownloadCallback."); 124 WebDownloader_CreateDownloadDelegateCallback(&g_download_callback); 125 WebDownloader_SetDownloadBeforeStart(g_download_callback, &DownloadBeforeStart); 126 WebDownloader_SetDownloadDidUpdate(g_download_callback, &DownloadDidUpdate); 127 WebDownloadManager_PutDownloadCallback(g_download_callback); 128 } else { 129 WVLOG_I("[DOWNLOAD] had RegisterDownloadCallback."); 130 } 131} 132 133// static 134void WebDownloadManager::RemoveDownloadDelegate(WebDownloadDelegate *delegate) 135{ 136 auto iterator = g_web_download_delegate_map.begin(); 137 while (iterator != g_web_download_delegate_map.end()) { 138 if (iterator->second == delegate) { 139 g_web_download_delegate_map.erase(iterator++); 140 } else { 141 iterator++; 142 } 143 } 144} 145 146// static 147void WebDownloadManager::AddDownloadDelegateForWeb(int32_t nwebId, WebDownloadDelegate *delegate) 148{ 149 NWebHelper::Instance().LoadNWebSDK(); 150 g_web_download_delegate_map.insert_or_assign(nwebId, delegate); 151 RegisterDownloadCallback(); 152} 153 154// static 155void WebDownloadManager::RemoveDownloadDelegateRef(int32_t nwebId) 156{ 157 auto iter = g_web_download_delegate_map.find(nwebId); 158 if (iter != g_web_download_delegate_map.end()) { 159 iter->second->RemoveSelfRef(); 160 } 161} 162 163// static 164void WebDownloadManager::SetDownloadDelegate(WebDownloadDelegate *delegate) 165{ 166 NWebHelper::Instance().LoadNWebSDK(); 167 if (!g_default_delegate) { 168 g_default_delegate = std::make_unique<WebDownloadDelegate>(*delegate); 169 RegisterDownloadCallback(); 170 } 171} 172 173// static 174bool WebDownloadManager::HasValidDelegate() 175{ 176 if (!g_default_delegate) { 177 return false; 178 } 179 180 return true; 181} 182 183// static 184void WebDownloadManager::ResumeDownload(const WebDownloadItem *webDownload) 185{ 186 WVLOG_D("[DOWNLOAD] WebDownloadManager::ResumeDownload"); 187 if (!webDownload) { 188 WVLOG_E("webDownload is nullptr"); 189 return; 190 } 191 NWebHelper::Instance().LoadNWebSDK(); 192 NWebDownloadItem *downloadItem = nullptr; 193 WebDownloadItem_CreateWebDownloadItem(&downloadItem); 194 WebDownloadItem_SetGuid(downloadItem, webDownload->guid.c_str()); 195 WebDownloadItem_SetUrl(downloadItem, webDownload->url.c_str()); 196 WebDownloadItem_SetFullPath(downloadItem, webDownload->fullPath.c_str()); 197 WebDownloadItem_SetETag(downloadItem, webDownload->etag.c_str()); 198 WebDownloadItem_SetMimeType(downloadItem, webDownload->mimeType.c_str()); 199 WebDownloadItem_SetReceivedBytes(downloadItem, webDownload->receivedBytes); 200 WebDownloadItem_SetTotalBytes(downloadItem, webDownload->totalBytes); 201 WebDownloadItem_SetReceivedSlices(downloadItem, webDownload->receivedSlices.c_str()); 202 WebDownloadItem_SetLastModified(downloadItem, webDownload->lastModified.c_str()); 203 WebDownloader_ResumeDownloadStatic(downloadItem); 204 return; 205} 206} // namespace NWeb 207} // namespace OHOS 208