10826e83eSopenharmony_ci/*
20826e83eSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
30826e83eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
40826e83eSopenharmony_ci * you may not use this file except in compliance with the License.
50826e83eSopenharmony_ci * You may obtain a copy of the License at
60826e83eSopenharmony_ci *
70826e83eSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
80826e83eSopenharmony_ci *
90826e83eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
100826e83eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
110826e83eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120826e83eSopenharmony_ci * See the License for the specific language governing permissions and
130826e83eSopenharmony_ci * limitations under the License.
140826e83eSopenharmony_ci */
150826e83eSopenharmony_ci
160826e83eSopenharmony_ci#include "web_download_manager.h"
170826e83eSopenharmony_ci
180826e83eSopenharmony_ci#include <cstring>
190826e83eSopenharmony_ci
200826e83eSopenharmony_ci#include "nweb_c_api.h"
210826e83eSopenharmony_ci#include "nweb_helper.h"
220826e83eSopenharmony_ci#include "nweb_log.h"
230826e83eSopenharmony_ci#include "web_download_delegate.h"
240826e83eSopenharmony_ci
250826e83eSopenharmony_cinamespace OHOS {
260826e83eSopenharmony_cinamespace NWeb {
270826e83eSopenharmony_cinamespace {
280826e83eSopenharmony_cistatic std::unique_ptr<OHOS::NWeb::WebDownloadDelegate> g_default_delegate;
290826e83eSopenharmony_cistatic std::unordered_map<int32_t, WebDownloadDelegate *> g_web_download_delegate_map;
300826e83eSopenharmony_cistatic WebDownloadDelegateCallback *g_download_callback;
310826e83eSopenharmony_ci
320826e83eSopenharmony_ciWebDownloadDelegate *GetWebDownloadDelegate(int32_t nwebId)
330826e83eSopenharmony_ci{
340826e83eSopenharmony_ci    auto it = g_web_download_delegate_map.find(nwebId);
350826e83eSopenharmony_ci    if (it != g_web_download_delegate_map.end()) {
360826e83eSopenharmony_ci        return it->second;
370826e83eSopenharmony_ci    }
380826e83eSopenharmony_ci    return nullptr;
390826e83eSopenharmony_ci}
400826e83eSopenharmony_ci
410826e83eSopenharmony_civoid DownloadBeforeStart(NWebDownloadItem *downloadItem, WebBeforeDownloadCallbackWrapper *wrapper)
420826e83eSopenharmony_ci{
430826e83eSopenharmony_ci    WVLOG_D("[DOWNLOAD] DownloadBeforeStart.");
440826e83eSopenharmony_ci    if (wrapper == nullptr) {
450826e83eSopenharmony_ci        WVLOG_E("[DOWNLOAD] WebBeforeDownloadCallbackWrapper is null");
460826e83eSopenharmony_ci        return;
470826e83eSopenharmony_ci    }
480826e83eSopenharmony_ci    int32_t nwebId = WebDownloadItem_NWebId(downloadItem);
490826e83eSopenharmony_ci    WebDownloadDelegate *webDownloadDelegate = GetWebDownloadDelegate(nwebId);
500826e83eSopenharmony_ci    if (!webDownloadDelegate) {
510826e83eSopenharmony_ci        WVLOG_D("[DOWNLOAD] donn't found delegate for nweb.");
520826e83eSopenharmony_ci        webDownloadDelegate = g_default_delegate.get();
530826e83eSopenharmony_ci    }
540826e83eSopenharmony_ci
550826e83eSopenharmony_ci    if (!webDownloadDelegate) {
560826e83eSopenharmony_ci        WVLOG_E("[DOWNLOAD] webDownloadDelegate is null");
570826e83eSopenharmony_ci        return;
580826e83eSopenharmony_ci    }
590826e83eSopenharmony_ci
600826e83eSopenharmony_ci    WebDownloadItem *webDownloadItem = new WebDownloadItem(webDownloadDelegate->GetEnv(), downloadItem);
610826e83eSopenharmony_ci    // destroy download_item since copied content from download_item.
620826e83eSopenharmony_ci    WebDownloadItem_Destroy(downloadItem);
630826e83eSopenharmony_ci    webDownloadItem->before_download_callback = wrapper;
640826e83eSopenharmony_ci    webDownloadDelegate->DownloadBeforeStart(webDownloadItem);
650826e83eSopenharmony_ci}
660826e83eSopenharmony_ci
670826e83eSopenharmony_civoid DownloadDidUpdate(NWebDownloadItem *downloadItem, WebDownloadItemCallbackWrapper *wrapper)
680826e83eSopenharmony_ci{
690826e83eSopenharmony_ci    WVLOG_D("DownloadDidUpdate.");
700826e83eSopenharmony_ci    if (wrapper == nullptr) {
710826e83eSopenharmony_ci        WVLOG_E("[DOWNLOAD] WebBeforeDownloadCallbackWrapper is null");
720826e83eSopenharmony_ci        return;
730826e83eSopenharmony_ci    }
740826e83eSopenharmony_ci
750826e83eSopenharmony_ci    int32_t nwebId = WebDownloadItem_NWebId(downloadItem);
760826e83eSopenharmony_ci
770826e83eSopenharmony_ci    WebDownloadDelegate *webDownloadDelegate = GetWebDownloadDelegate(nwebId);
780826e83eSopenharmony_ci    if (!webDownloadDelegate) {
790826e83eSopenharmony_ci        WVLOG_D("[DOWNLOAD] donn't found delegate for nweb.");
800826e83eSopenharmony_ci        webDownloadDelegate = g_default_delegate.get();
810826e83eSopenharmony_ci    }
820826e83eSopenharmony_ci
830826e83eSopenharmony_ci    if (!webDownloadDelegate) {
840826e83eSopenharmony_ci        WVLOG_E("[DOWNLOAD] webDownloadDelegate is null");
850826e83eSopenharmony_ci        return;
860826e83eSopenharmony_ci    }
870826e83eSopenharmony_ci    WebDownloadItem *webDownloadItem = new WebDownloadItem(webDownloadDelegate->GetEnv(), downloadItem);
880826e83eSopenharmony_ci    // destroy download_item since copied content from download_item.
890826e83eSopenharmony_ci    WebDownloadItem_Destroy(downloadItem);
900826e83eSopenharmony_ci    webDownloadItem->download_item_callback = wrapper;
910826e83eSopenharmony_ci    switch (webDownloadItem->state) {
920826e83eSopenharmony_ci        case NWebDownloadItemState::PENDING:
930826e83eSopenharmony_ci            //  When in PENDING state, chromium call downloadDidUpdate
940826e83eSopenharmony_ci            //  while file path is temporary file, just stop calling ui.
950826e83eSopenharmony_ci            delete webDownloadItem;
960826e83eSopenharmony_ci            webDownloadItem = nullptr;
970826e83eSopenharmony_ci            break;
980826e83eSopenharmony_ci        case NWebDownloadItemState::IN_PROGRESS:
990826e83eSopenharmony_ci        case NWebDownloadItemState::PAUSED:
1000826e83eSopenharmony_ci            webDownloadDelegate->DownloadDidUpdate(webDownloadItem);
1010826e83eSopenharmony_ci            break;
1020826e83eSopenharmony_ci        case NWebDownloadItemState::INTERRUPTED:
1030826e83eSopenharmony_ci        case NWebDownloadItemState::CANCELED:
1040826e83eSopenharmony_ci            webDownloadDelegate->DownloadDidFail(webDownloadItem);
1050826e83eSopenharmony_ci            break;
1060826e83eSopenharmony_ci        case NWebDownloadItemState::COMPLETE:
1070826e83eSopenharmony_ci            webDownloadDelegate->DownloadDidFinish(webDownloadItem);
1080826e83eSopenharmony_ci            break;
1090826e83eSopenharmony_ci        case NWebDownloadItemState::MAX_DOWNLOAD_STATE:
1100826e83eSopenharmony_ci        default:
1110826e83eSopenharmony_ci            delete webDownloadItem;
1120826e83eSopenharmony_ci            webDownloadItem = nullptr;
1130826e83eSopenharmony_ci            break;
1140826e83eSopenharmony_ci    }
1150826e83eSopenharmony_ci}
1160826e83eSopenharmony_ci} // namespace
1170826e83eSopenharmony_ci
1180826e83eSopenharmony_ci// static
1190826e83eSopenharmony_civoid WebDownloadManager::RegisterDownloadCallback()
1200826e83eSopenharmony_ci{
1210826e83eSopenharmony_ci    // Only regist once.
1220826e83eSopenharmony_ci    if (g_download_callback == nullptr) {
1230826e83eSopenharmony_ci        WVLOG_I("RegisterDownloadCallback.");
1240826e83eSopenharmony_ci        WebDownloader_CreateDownloadDelegateCallback(&g_download_callback);
1250826e83eSopenharmony_ci        WebDownloader_SetDownloadBeforeStart(g_download_callback, &DownloadBeforeStart);
1260826e83eSopenharmony_ci        WebDownloader_SetDownloadDidUpdate(g_download_callback, &DownloadDidUpdate);
1270826e83eSopenharmony_ci        WebDownloadManager_PutDownloadCallback(g_download_callback);
1280826e83eSopenharmony_ci    } else {
1290826e83eSopenharmony_ci        WVLOG_I("[DOWNLOAD] had RegisterDownloadCallback.");
1300826e83eSopenharmony_ci    }
1310826e83eSopenharmony_ci}
1320826e83eSopenharmony_ci
1330826e83eSopenharmony_ci// static
1340826e83eSopenharmony_civoid WebDownloadManager::RemoveDownloadDelegate(WebDownloadDelegate *delegate)
1350826e83eSopenharmony_ci{
1360826e83eSopenharmony_ci    auto iterator = g_web_download_delegate_map.begin();
1370826e83eSopenharmony_ci    while (iterator != g_web_download_delegate_map.end()) {
1380826e83eSopenharmony_ci        if (iterator->second == delegate) {
1390826e83eSopenharmony_ci            g_web_download_delegate_map.erase(iterator++);
1400826e83eSopenharmony_ci        } else {
1410826e83eSopenharmony_ci            iterator++;
1420826e83eSopenharmony_ci        }
1430826e83eSopenharmony_ci    }
1440826e83eSopenharmony_ci}
1450826e83eSopenharmony_ci
1460826e83eSopenharmony_ci// static
1470826e83eSopenharmony_civoid WebDownloadManager::AddDownloadDelegateForWeb(int32_t nwebId, WebDownloadDelegate *delegate)
1480826e83eSopenharmony_ci{
1490826e83eSopenharmony_ci    NWebHelper::Instance().LoadNWebSDK();
1500826e83eSopenharmony_ci    g_web_download_delegate_map.insert_or_assign(nwebId, delegate);
1510826e83eSopenharmony_ci    RegisterDownloadCallback();
1520826e83eSopenharmony_ci}
1530826e83eSopenharmony_ci
1540826e83eSopenharmony_ci// static
1550826e83eSopenharmony_civoid WebDownloadManager::RemoveDownloadDelegateRef(int32_t nwebId)
1560826e83eSopenharmony_ci{
1570826e83eSopenharmony_ci    auto iter = g_web_download_delegate_map.find(nwebId);
1580826e83eSopenharmony_ci    if (iter != g_web_download_delegate_map.end()) {
1590826e83eSopenharmony_ci        iter->second->RemoveSelfRef();
1600826e83eSopenharmony_ci    }
1610826e83eSopenharmony_ci}
1620826e83eSopenharmony_ci
1630826e83eSopenharmony_ci// static
1640826e83eSopenharmony_civoid WebDownloadManager::SetDownloadDelegate(WebDownloadDelegate *delegate)
1650826e83eSopenharmony_ci{
1660826e83eSopenharmony_ci    NWebHelper::Instance().LoadNWebSDK();
1670826e83eSopenharmony_ci    if (!g_default_delegate) {
1680826e83eSopenharmony_ci        g_default_delegate = std::make_unique<WebDownloadDelegate>(*delegate);
1690826e83eSopenharmony_ci        RegisterDownloadCallback();
1700826e83eSopenharmony_ci    }
1710826e83eSopenharmony_ci}
1720826e83eSopenharmony_ci
1730826e83eSopenharmony_ci// static
1740826e83eSopenharmony_cibool WebDownloadManager::HasValidDelegate()
1750826e83eSopenharmony_ci{
1760826e83eSopenharmony_ci    if (!g_default_delegate) {
1770826e83eSopenharmony_ci        return false;
1780826e83eSopenharmony_ci    }
1790826e83eSopenharmony_ci
1800826e83eSopenharmony_ci    return true;
1810826e83eSopenharmony_ci}
1820826e83eSopenharmony_ci
1830826e83eSopenharmony_ci// static
1840826e83eSopenharmony_civoid WebDownloadManager::ResumeDownload(const WebDownloadItem *webDownload)
1850826e83eSopenharmony_ci{
1860826e83eSopenharmony_ci    WVLOG_D("[DOWNLOAD] WebDownloadManager::ResumeDownload");
1870826e83eSopenharmony_ci    if (!webDownload) {
1880826e83eSopenharmony_ci        WVLOG_E("webDownload is nullptr");
1890826e83eSopenharmony_ci        return;
1900826e83eSopenharmony_ci    }
1910826e83eSopenharmony_ci    NWebHelper::Instance().LoadNWebSDK();
1920826e83eSopenharmony_ci    NWebDownloadItem *downloadItem = nullptr;
1930826e83eSopenharmony_ci    WebDownloadItem_CreateWebDownloadItem(&downloadItem);
1940826e83eSopenharmony_ci    WebDownloadItem_SetGuid(downloadItem, webDownload->guid.c_str());
1950826e83eSopenharmony_ci    WebDownloadItem_SetUrl(downloadItem, webDownload->url.c_str());
1960826e83eSopenharmony_ci    WebDownloadItem_SetFullPath(downloadItem, webDownload->fullPath.c_str());
1970826e83eSopenharmony_ci    WebDownloadItem_SetETag(downloadItem, webDownload->etag.c_str());
1980826e83eSopenharmony_ci    WebDownloadItem_SetMimeType(downloadItem, webDownload->mimeType.c_str());
1990826e83eSopenharmony_ci    WebDownloadItem_SetReceivedBytes(downloadItem, webDownload->receivedBytes);
2000826e83eSopenharmony_ci    WebDownloadItem_SetTotalBytes(downloadItem, webDownload->totalBytes);
2010826e83eSopenharmony_ci    WebDownloadItem_SetReceivedSlices(downloadItem, webDownload->receivedSlices.c_str());
2020826e83eSopenharmony_ci    WebDownloadItem_SetLastModified(downloadItem, webDownload->lastModified.c_str());
2030826e83eSopenharmony_ci    WebDownloader_ResumeDownloadStatic(downloadItem);
2040826e83eSopenharmony_ci    return;
2050826e83eSopenharmony_ci}
2060826e83eSopenharmony_ci} // namespace NWeb
2070826e83eSopenharmony_ci} // namespace OHOS
208