• 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_ffi.h"
17 
18 #include "cj_lambda.h"
19 #include "nweb_helper.h"
20 #include "nweb_init_params.h"
21 #include "web_download.pb.h"
22 #include "web_download_delegate_impl.h"
23 #include "web_download_item_impl.h"
24 #include "web_download_manager_impl.h"
25 #include "web_errors.h"
26 #include "webview_controller_impl.h"
27 #include "webview_log.h"
28 #include "webview_utils.h"
29 
30 using namespace OHOS::FFI;
31 using namespace OHOS::NWeb;
32 
33 namespace OHOS {
34 namespace Webview {
35 extern "C" {
36 // WebDownloadItemImpl
FfiOHOSWebDownloadItemImplConstructor()37 int64_t FfiOHOSWebDownloadItemImplConstructor()
38 {
39     auto nativeWebDownloadItemImpl = FFIData::Create<WebDownloadItemImpl>();
40     if (nativeWebDownloadItemImpl == nullptr) {
41         WEBVIEWLOGE("new web download item failed");
42         return -1;
43     }
44     return nativeWebDownloadItemImpl->GetID();
45 }
46 
FfiOHOSWebDownloadItemImplGetGuid(int64_t id)47 RetDataCString FfiOHOSWebDownloadItemImplGetGuid(int64_t id)
48 {
49     RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr };
50     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
51     if (!nativeWebDownloadItemImpl) {
52         return ret;
53     }
54     std::string guid = nativeWebDownloadItemImpl->guid;
55     ret.code = NWebError::NO_ERROR;
56     ret.data = MallocCString(guid);
57     return ret;
58 }
59 
FfiOHOSWebDownloadItemImplGetCurrentSpeed(int64_t id,int32_t * errCode)60 int64_t FfiOHOSWebDownloadItemImplGetCurrentSpeed(int64_t id, int32_t* errCode)
61 {
62     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
63     if (!nativeWebDownloadItemImpl) {
64         *errCode = NWebError::INIT_ERROR;
65         return -1;
66     }
67     *errCode = NWebError::NO_ERROR;
68     return static_cast<int64_t>(nativeWebDownloadItemImpl->currentSpeed);
69 }
70 
FfiOHOSWebDownloadItemImplGetPercentComplete(int64_t id,int32_t * errCode)71 int64_t FfiOHOSWebDownloadItemImplGetPercentComplete(int64_t id, int32_t* errCode)
72 {
73     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
74     if (!nativeWebDownloadItemImpl) {
75         *errCode = NWebError::INIT_ERROR;
76         return -1;
77     }
78     *errCode = NWebError::NO_ERROR;
79     return static_cast<int64_t>(nativeWebDownloadItemImpl->percentComplete);
80 }
81 
FfiOHOSWebDownloadItemImplGetTotalBytes(int64_t id,int32_t * errCode)82 int64_t FfiOHOSWebDownloadItemImplGetTotalBytes(int64_t id, int32_t* errCode)
83 {
84     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
85     if (!nativeWebDownloadItemImpl) {
86         *errCode = NWebError::INIT_ERROR;
87         return -1;
88     }
89     *errCode = NWebError::NO_ERROR;
90     return static_cast<int64_t>(nativeWebDownloadItemImpl->totalBytes);
91 }
92 
FfiOHOSWebDownloadItemImplGetReceivedBytes(int64_t id,int32_t * errCode)93 int64_t FfiOHOSWebDownloadItemImplGetReceivedBytes(int64_t id, int32_t* errCode)
94 {
95     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
96     if (!nativeWebDownloadItemImpl) {
97         *errCode = NWebError::INIT_ERROR;
98         return -1;
99     }
100     *errCode = NWebError::NO_ERROR;
101     return static_cast<int64_t>(nativeWebDownloadItemImpl->receivedBytes);
102 }
103 
FfiOHOSWebDownloadItemImplGetState(int64_t id,int32_t * errCode)104 int32_t FfiOHOSWebDownloadItemImplGetState(int64_t id, int32_t* errCode)
105 {
106     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
107     if (!nativeWebDownloadItemImpl) {
108         *errCode = NWebError::INIT_ERROR;
109         return -1;
110     }
111     *errCode = NWebError::NO_ERROR;
112     return static_cast<int32_t>(nativeWebDownloadItemImpl->state);
113 }
114 
FfiOHOSWebDownloadItemImplGetLastErrorCode(int64_t id,int32_t * errCode)115 int32_t FfiOHOSWebDownloadItemImplGetLastErrorCode(int64_t id, int32_t* errCode)
116 {
117     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
118     if (!nativeWebDownloadItemImpl) {
119         *errCode = NWebError::INIT_ERROR;
120         return -1;
121     }
122     *errCode = NWebError::NO_ERROR;
123     return static_cast<int32_t>(nativeWebDownloadItemImpl->lastErrorCode);
124 }
125 
FfiOHOSWebDownloadItemImplGetMethod(int64_t id)126 RetDataCString FfiOHOSWebDownloadItemImplGetMethod(int64_t id)
127 {
128     RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr };
129     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
130     if (!nativeWebDownloadItemImpl) {
131         return ret;
132     }
133     std::string methodValue = nativeWebDownloadItemImpl->method;
134     ret.code = NWebError::NO_ERROR;
135     ret.data = MallocCString(methodValue);
136     return ret;
137 }
138 
FfiOHOSWebDownloadItemImplGetMimeType(int64_t id)139 RetDataCString FfiOHOSWebDownloadItemImplGetMimeType(int64_t id)
140 {
141     RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr };
142     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
143     if (!nativeWebDownloadItemImpl) {
144         return ret;
145     }
146     std::string mimeTypeValue = nativeWebDownloadItemImpl->mimeType;
147     ret.code = NWebError::NO_ERROR;
148     ret.data = MallocCString(mimeTypeValue);
149     return ret;
150 }
151 
FfiOHOSWebDownloadItemImplGetUrl(int64_t id)152 RetDataCString FfiOHOSWebDownloadItemImplGetUrl(int64_t id)
153 {
154     RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr };
155     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
156     if (!nativeWebDownloadItemImpl) {
157         return ret;
158     }
159     std::string urlValue = nativeWebDownloadItemImpl->url;
160     ret.code = NWebError::NO_ERROR;
161     ret.data = MallocCString(urlValue);
162     return ret;
163 }
164 
FfiOHOSWebDownloadItemImplGetSuggestedFileName(int64_t id)165 RetDataCString FfiOHOSWebDownloadItemImplGetSuggestedFileName(int64_t id)
166 {
167     RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr };
168     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
169     if (!nativeWebDownloadItemImpl) {
170         return ret;
171     }
172     std::string fileNameValue = nativeWebDownloadItemImpl->suggestedFileName;
173     ret.code = NWebError::NO_ERROR;
174     ret.data = MallocCString(fileNameValue);
175     return ret;
176 }
177 
FfiOHOSWebDownloadItemImplGetFullPath(int64_t id)178 RetDataCString FfiOHOSWebDownloadItemImplGetFullPath(int64_t id)
179 {
180     RetDataCString ret = { .code = NWebError::INIT_ERROR, .data = nullptr };
181     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
182     if (!nativeWebDownloadItemImpl) {
183         return ret;
184     }
185     std::string fullPath = nativeWebDownloadItemImpl->fullPath;
186     ret.code = NWebError::NO_ERROR;
187     ret.data = MallocCString(fullPath);
188     return ret;
189 }
190 
FfiOHOSWebDownloadItemImplStart(int64_t id,char * downloadPath)191 int32_t FfiOHOSWebDownloadItemImplStart(int64_t id, char* downloadPath)
192 {
193     std::string sDownloadPath = downloadPath;
194     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
195     if (!nativeWebDownloadItemImpl) {
196         return NWebError::INIT_ERROR;
197     }
198     nativeWebDownloadItemImpl->downloadPath = sDownloadPath;
199     WebDownload_Continue(
200         nativeWebDownloadItemImpl->before_download_callback, nativeWebDownloadItemImpl->downloadPath.c_str());
201     return NWebError::NO_ERROR;
202 }
203 
FfiOHOSWebDownloadItemImplCancel(int64_t id)204 int32_t FfiOHOSWebDownloadItemImplCancel(int64_t id)
205 {
206     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
207     if (!nativeWebDownloadItemImpl) {
208         return NWebError::INIT_ERROR;
209     }
210     if (nativeWebDownloadItemImpl->download_item_callback) {
211         WebDownload_Cancel(nativeWebDownloadItemImpl->download_item_callback);
212     } else if (nativeWebDownloadItemImpl->before_download_callback) {
213         WebDownload_CancelBeforeDownload(nativeWebDownloadItemImpl->before_download_callback);
214     } else {
215         WEBVIEWLOGE("[DOWNLOAD] WebDownloadItem::Cancel failed for callback nullptr");
216     }
217     return NWebError::NO_ERROR;
218 }
219 
FfiOHOSWebDownloadItemImplPause(int64_t id)220 int32_t FfiOHOSWebDownloadItemImplPause(int64_t id)
221 {
222     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
223     if (!nativeWebDownloadItemImpl) {
224         return NWebError::INIT_ERROR;
225     }
226     NWebDownloadItemState state =
227         WebDownload_GetItemState(nativeWebDownloadItemImpl->nwebId, nativeWebDownloadItemImpl->webDownloadId);
228     if (state != NWebDownloadItemState::IN_PROGRESS && state != NWebDownloadItemState::PENDING) {
229         return NWebError::DOWNLOAD_NOT_START;
230     }
231     if (nativeWebDownloadItemImpl->download_item_callback) {
232         WebDownload_Pause(nativeWebDownloadItemImpl->download_item_callback);
233     } else if (nativeWebDownloadItemImpl->before_download_callback) {
234         WebDownload_PauseBeforeDownload(nativeWebDownloadItemImpl->before_download_callback);
235     } else {
236         WEBVIEWLOGE("[DOWNLOAD] WebDownloadItem::Pause failed for callback nullptr");
237     }
238     return NWebError::NO_ERROR;
239 }
240 
FfiOHOSWebDownloadItemImplResume(int64_t id)241 int32_t FfiOHOSWebDownloadItemImplResume(int64_t id)
242 {
243     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
244     if (!nativeWebDownloadItemImpl) {
245         return NWebError::INIT_ERROR;
246     }
247     NWebDownloadItemState state =
248         WebDownload_GetItemState(nativeWebDownloadItemImpl->nwebId, nativeWebDownloadItemImpl->webDownloadId);
249     if (state != NWebDownloadItemState::PAUSED) {
250         return NWebError::DOWNLOAD_NOT_PAUSED;
251     }
252 
253     if (nativeWebDownloadItemImpl->download_item_callback) {
254         WebDownload_Resume(nativeWebDownloadItemImpl->download_item_callback);
255     } else if (nativeWebDownloadItemImpl->before_download_callback) {
256         WebDownload_ResumeBeforeDownload(nativeWebDownloadItemImpl->before_download_callback);
257     } else {
258         WEBVIEWLOGE("[DOWNLOAD] WebDownloadItem::Resume failed for callback nullptr");
259     }
260     return NWebError::NO_ERROR;
261 }
262 
FfiOHOSWebDownloadItemImplSerialize(int64_t id,int32_t * errCode)263 CArrUI8 FfiOHOSWebDownloadItemImplSerialize(int64_t id, int32_t* errCode)
264 {
265     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(id);
266     if (!nativeWebDownloadItemImpl) {
267         *errCode = NWebError::INIT_ERROR;
268         return CArrUI8 { nullptr, 0 };
269     }
270 
271     browser_service::WebDownload webDownloadPb;
272     webDownloadPb.set_web_download_id(nativeWebDownloadItemImpl->webDownloadId);
273     webDownloadPb.set_current_speed(nativeWebDownloadItemImpl->currentSpeed);
274     webDownloadPb.set_percent_complete(nativeWebDownloadItemImpl->percentComplete);
275     webDownloadPb.set_total_bytes(nativeWebDownloadItemImpl->totalBytes);
276     webDownloadPb.set_received_bytes(nativeWebDownloadItemImpl->receivedBytes);
277     webDownloadPb.set_guid(nativeWebDownloadItemImpl->guid);
278     webDownloadPb.set_full_path(nativeWebDownloadItemImpl->fullPath);
279     webDownloadPb.set_url(nativeWebDownloadItemImpl->url);
280     webDownloadPb.set_etag(nativeWebDownloadItemImpl->etag);
281     webDownloadPb.set_original_url(nativeWebDownloadItemImpl->originalUrl);
282     webDownloadPb.set_suggested_file_name(nativeWebDownloadItemImpl->suggestedFileName);
283     webDownloadPb.set_content_disposition(nativeWebDownloadItemImpl->contentDisposition);
284     webDownloadPb.set_mime_type(nativeWebDownloadItemImpl->mimeType);
285     webDownloadPb.set_last_modified(nativeWebDownloadItemImpl->lastModified);
286     webDownloadPb.set_state(
287         static_cast<browser_service::WebDownload::WebDownloadState>(nativeWebDownloadItemImpl->state));
288     webDownloadPb.set_method(nativeWebDownloadItemImpl->method);
289     webDownloadPb.set_last_error_code(nativeWebDownloadItemImpl->lastErrorCode);
290     webDownloadPb.set_received_slices(nativeWebDownloadItemImpl->receivedSlices);
291     webDownloadPb.set_download_path(nativeWebDownloadItemImpl->downloadPath);
292 
293     std::string webDownloadValue;
294     webDownloadPb.SerializeToString(&webDownloadValue);
295     uint8_t* result = MallocUInt8(webDownloadValue);
296     if (result == nullptr) {
297         WEBVIEWLOGE("[DOWNLOAD] malloc failed");
298         *errCode = NWebError::NEW_OOM;
299         return CArrUI8 { nullptr, 0 };
300     }
301     *errCode = NWebError::NO_ERROR;
302     return CArrUI8 { result, webDownloadValue.length() };
303 }
304 
FfiOHOSWebDownloadItemImplDeserialize(CArrUI8 serializedData,int32_t * errCode)305 int64_t FfiOHOSWebDownloadItemImplDeserialize(CArrUI8 serializedData, int32_t* errCode)
306 {
307     char* buffer = reinterpret_cast<char*>(serializedData.head);
308     browser_service::WebDownload webDownloadPb;
309     bool result = webDownloadPb.ParseFromArray(buffer, serializedData.size);
310     if (!result) {
311         *errCode = NWebError::INIT_ERROR;
312         return -1;
313     }
314     WebDownloadItemImpl* webDownloadItem = FFIData::Create<WebDownloadItemImpl>();
315     if (webDownloadItem == nullptr) {
316         WEBVIEWLOGE("new web download item failed");
317         *errCode = NWebError::INIT_ERROR;
318         return -1;
319     }
320     webDownloadItem->webDownloadId = webDownloadPb.web_download_id();
321     webDownloadItem->currentSpeed = webDownloadPb.current_speed();
322     webDownloadItem->percentComplete = webDownloadPb.percent_complete();
323     webDownloadItem->totalBytes = webDownloadPb.total_bytes();
324     webDownloadItem->receivedBytes = webDownloadPb.received_bytes();
325     webDownloadItem->guid = webDownloadPb.guid();
326     webDownloadItem->fullPath = webDownloadPb.full_path();
327     webDownloadItem->url = webDownloadPb.url();
328     webDownloadItem->etag = webDownloadPb.etag();
329     webDownloadItem->originalUrl = webDownloadPb.original_url();
330     webDownloadItem->suggestedFileName = webDownloadPb.suggested_file_name();
331     webDownloadItem->contentDisposition = webDownloadPb.content_disposition();
332     webDownloadItem->mimeType = webDownloadPb.mime_type();
333     webDownloadItem->lastModified = webDownloadPb.last_modified();
334     webDownloadItem->state = static_cast<NWebDownloadItemState>(webDownloadPb.state());
335     webDownloadItem->method = webDownloadPb.method();
336     webDownloadItem->lastErrorCode = webDownloadPb.last_error_code();
337     webDownloadItem->receivedSlices = webDownloadPb.received_slices();
338     webDownloadItem->downloadPath = webDownloadPb.download_path();
339     *errCode = NWebError::NO_ERROR;
340     return webDownloadItem->GetID();
341 }
342 
343 // WebDownloadDelegateImpl
FfiOHOSWebDownloadDelegateImplConstructor()344 int64_t FfiOHOSWebDownloadDelegateImplConstructor()
345 {
346     auto nativeWebDownloadDelegateImpl = FFIData::Create<WebDownloadDelegateImpl>();
347     if (nativeWebDownloadDelegateImpl == nullptr) {
348         WEBVIEWLOGE("new web download delegate failed");
349         return -1;
350     }
351     return nativeWebDownloadDelegateImpl->GetID();
352 }
353 
FfiOHOSWebDownloadDelegateImplOnBeforeDownload(int64_t id,void (* callback)(int64_t))354 void FfiOHOSWebDownloadDelegateImplOnBeforeDownload(int64_t id, void (*callback)(int64_t))
355 {
356     auto nativeWebDownloadDelegateImpl = FFIData::GetData<WebDownloadDelegateImpl>(id);
357     if (!nativeWebDownloadDelegateImpl) {
358         WEBVIEWLOGE("[DOWNLOAD] webDownloadDelegate is null");
359         return;
360     }
361     nativeWebDownloadDelegateImpl->PutDownloadBeforeStart(CJLambda::Create(callback));
362 }
363 
FfiOHOSWebDownloadDelegateImplOnDownloadUpdated(int64_t id,void (* callback)(int64_t))364 void FfiOHOSWebDownloadDelegateImplOnDownloadUpdated(int64_t id, void (*callback)(int64_t))
365 {
366     auto nativeWebDownloadDelegateImpl = FFIData::GetData<WebDownloadDelegateImpl>(id);
367     if (!nativeWebDownloadDelegateImpl) {
368         WEBVIEWLOGE("[DOWNLOAD] webDownloadDelegate is null");
369         return;
370     }
371     nativeWebDownloadDelegateImpl->PutDownloadDidUpdate(CJLambda::Create(callback));
372 }
373 
FfiOHOSWebDownloadDelegateImplOnDownloadFinish(int64_t id,void (* callback)(int64_t))374 void FfiOHOSWebDownloadDelegateImplOnDownloadFinish(int64_t id, void (*callback)(int64_t))
375 {
376     auto nativeWebDownloadDelegateImpl = FFIData::GetData<WebDownloadDelegateImpl>(id);
377     if (!nativeWebDownloadDelegateImpl) {
378         WEBVIEWLOGE("[DOWNLOAD] webDownloadDelegate is null");
379         return;
380     }
381     nativeWebDownloadDelegateImpl->PutDownloadDidFinish(CJLambda::Create(callback));
382 }
383 
FfiOHOSWebDownloadDelegateImplOnDownloadFailed(int64_t id,void (* callback)(int64_t))384 void FfiOHOSWebDownloadDelegateImplOnDownloadFailed(int64_t id, void (*callback)(int64_t))
385 {
386     auto nativeWebDownloadDelegateImpl = FFIData::GetData<WebDownloadDelegateImpl>(id);
387     if (!nativeWebDownloadDelegateImpl) {
388         WEBVIEWLOGE("[DOWNLOAD] webDownloadDelegate is null");
389         return;
390     }
391     nativeWebDownloadDelegateImpl->PutDownloadDidFail(CJLambda::Create(callback));
392 }
393 
394 // WebDownloadManagerImpl
FfiOHOSWebDownloadManagerImplSetDownloadDelegate(int64_t delegateId)395 void FfiOHOSWebDownloadManagerImplSetDownloadDelegate(int64_t delegateId)
396 {
397     auto nativeWebDownloadDelegateImpl = FFIData::GetData<WebDownloadDelegateImpl>(delegateId);
398     if (!nativeWebDownloadDelegateImpl) {
399         WEBVIEWLOGE("[DOWNLOAD] webDownloadDelegate is null");
400         return;
401     }
402     WebDownloadManagerImpl::SetDownloadDelegate(nativeWebDownloadDelegateImpl);
403 }
404 
FfiOHOSWebDownloadManagerImplResumeDownload(int64_t itemId)405 int32_t FfiOHOSWebDownloadManagerImplResumeDownload(int64_t itemId)
406 {
407     if (!WebDownloadManagerImpl::HasValidDelegate()) {
408         return NWebError::NO_DOWNLOAD_DELEGATE_SET;
409     }
410     auto nativeWebDownloadItemImpl = FFIData::GetData<WebDownloadItemImpl>(itemId);
411     if (!nativeWebDownloadItemImpl) {
412         WEBVIEWLOGE("[DOWNLOAD] webDownloadDelegate is null");
413         return NWebError::INIT_ERROR;
414     }
415     WebDownloadManagerImpl::ResumeDownload(nativeWebDownloadItemImpl);
416     return NWebError::NO_ERROR;
417 }
418 }
419 } // namespace Webview
420 } // namespace OHOS