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