1/* 2 * Copyright (C) 2012 Intel Corporation. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "DownloadManagerEfl.h" 28 29#include "EwkView.h" 30#include "WKContext.h" 31#include "WKDownload.h" 32#include "WKString.h" 33#include "ewk_context_private.h" 34#include "ewk_error_private.h" 35#include "ewk_view.h" 36 37using namespace EwkViewCallbacks; 38 39namespace WebKit { 40 41static inline DownloadManagerEfl* toDownloadManagerEfl(const void* clientInfo) 42{ 43 return static_cast<DownloadManagerEfl*>(const_cast<void*>(clientInfo)); 44} 45 46WKStringRef DownloadManagerEfl::decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef wkDownload, WKStringRef filename, bool* /*allowOverwrite*/, const void* clientInfo) 47{ 48 EwkDownloadJob* download = toDownloadManagerEfl(clientInfo)->ewkDownloadJob(wkDownload); 49 ASSERT(download); 50 51 download->setSuggestedFileName(toImpl(filename)->string().utf8().data()); 52 53 // We send the new download signal on the Ewk_View only once we have received the response 54 // and the suggested file name. 55 download->view()->smartCallback<DownloadJobRequested>().call(download); 56 57 // DownloadSoup expects the destination to be a URL. 58 String destination = ASCIILiteral("file://") + String::fromUTF8(download->destination()); 59 60 return WKStringCreateWithUTF8CString(destination.utf8().data()); 61} 62 63void DownloadManagerEfl::didReceiveResponse(WKContextRef, WKDownloadRef wkDownload, WKURLResponseRef wkResponse, const void* clientInfo) 64{ 65 EwkDownloadJob* download = toDownloadManagerEfl(clientInfo)->ewkDownloadJob(wkDownload); 66 ASSERT(download); 67 download->setResponse(EwkUrlResponse::create(wkResponse)); 68} 69 70void DownloadManagerEfl::didCreateDestination(WKContextRef, WKDownloadRef wkDownload, WKStringRef /*path*/, const void* clientInfo) 71{ 72 EwkDownloadJob* download = toDownloadManagerEfl(clientInfo)->ewkDownloadJob(wkDownload); 73 ASSERT(download); 74 75 download->setState(EWK_DOWNLOAD_JOB_STATE_DOWNLOADING); 76} 77 78void DownloadManagerEfl::didReceiveData(WKContextRef, WKDownloadRef wkDownload, uint64_t length, const void* clientInfo) 79{ 80 EwkDownloadJob* download = toDownloadManagerEfl(clientInfo)->ewkDownloadJob(wkDownload); 81 ASSERT(download); 82 download->incrementReceivedData(length); 83} 84 85void DownloadManagerEfl::didFail(WKContextRef, WKDownloadRef wkDownload, WKErrorRef error, const void* clientInfo) 86{ 87 DownloadManagerEfl* downloadManager = toDownloadManagerEfl(clientInfo); 88 EwkDownloadJob* download = downloadManager->ewkDownloadJob(wkDownload); 89 ASSERT(download); 90 91 auto ewkError = std::make_unique<EwkError>(error); 92 download->setState(EWK_DOWNLOAD_JOB_STATE_FAILED); 93 Ewk_Download_Job_Error downloadError = { download, ewkError.get() }; 94 download->view()->smartCallback<DownloadJobFailed>().call(&downloadError); 95 downloadManager->unregisterDownloadJob(wkDownload); 96} 97 98void DownloadManagerEfl::didCancel(WKContextRef, WKDownloadRef wkDownload, const void* clientInfo) 99{ 100 DownloadManagerEfl* downloadManager = toDownloadManagerEfl(clientInfo); 101 EwkDownloadJob* download = downloadManager->ewkDownloadJob(wkDownload); 102 ASSERT(download); 103 104 download->setState(EWK_DOWNLOAD_JOB_STATE_CANCELLED); 105 download->view()->smartCallback<DownloadJobCancelled>().call(download); 106 downloadManager->unregisterDownloadJob(wkDownload); 107} 108 109void DownloadManagerEfl::didFinish(WKContextRef, WKDownloadRef wkDownload, const void* clientInfo) 110{ 111 DownloadManagerEfl* downloadManager = toDownloadManagerEfl(clientInfo); 112 EwkDownloadJob* download = downloadManager->ewkDownloadJob(wkDownload); 113 ASSERT(download); 114 115 download->setState(EWK_DOWNLOAD_JOB_STATE_FINISHED); 116 download->view()->smartCallback<DownloadJobFinished>().call(download); 117 downloadManager->unregisterDownloadJob(wkDownload); 118} 119 120DownloadManagerEfl::DownloadManagerEfl(WKContextRef context) 121 : m_context(context) 122{ 123 WKContextDownloadClientV0 wkDownloadClient; 124 memset(&wkDownloadClient, 0, sizeof(WKContextDownloadClient)); 125 126 wkDownloadClient.base.version = 0; 127 wkDownloadClient.base.clientInfo = this; 128 wkDownloadClient.didCancel = didCancel; 129 wkDownloadClient.decideDestinationWithSuggestedFilename = decideDestinationWithSuggestedFilename; 130 wkDownloadClient.didCreateDestination = didCreateDestination; 131 wkDownloadClient.didReceiveResponse = didReceiveResponse; 132 wkDownloadClient.didReceiveData = didReceiveData; 133 wkDownloadClient.didFail = didFail; 134 wkDownloadClient.didFinish = didFinish; 135 136 WKContextSetDownloadClient(m_context.get(), &wkDownloadClient.base); 137} 138 139DownloadManagerEfl::~DownloadManagerEfl() 140{ 141 WKContextSetDownloadClient(m_context.get(), 0); 142} 143 144void DownloadManagerEfl::registerDownloadJob(WKDownloadRef download, EwkView* viewImpl) 145{ 146 uint64_t downloadId = WKDownloadGetID(download); 147 if (m_downloadJobs.contains(downloadId)) 148 return; 149 150 RefPtr<EwkDownloadJob> ewkDownload = EwkDownloadJob::create(download, viewImpl); 151 m_downloadJobs.add(downloadId, ewkDownload); 152} 153 154EwkDownloadJob* DownloadManagerEfl::ewkDownloadJob(WKDownloadRef wkDownload) 155{ 156 return m_downloadJobs.get(WKDownloadGetID(wkDownload)); 157} 158 159void DownloadManagerEfl::unregisterDownloadJob(WKDownloadRef wkDownload) 160{ 161 m_downloadJobs.remove(WKDownloadGetID(wkDownload)); 162} 163 164} // namespace WebKit 165