1/*
2 * Copyright (C) 2014 Google Inc. 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 are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "core/loader/WorkerLoaderClientBridge.h"
33
34#include "core/dom/CrossThreadTask.h"
35#include "core/loader/ThreadableLoaderClientWrapper.h"
36#include "core/workers/WorkerGlobalScope.h"
37#include "core/workers/WorkerLoaderProxy.h"
38#include "wtf/PassOwnPtr.h"
39#include "wtf/PassRefPtr.h"
40
41namespace blink {
42
43PassOwnPtr<ThreadableLoaderClient> WorkerLoaderClientBridge::create(PassRefPtr<ThreadableLoaderClientWrapper> client, WorkerLoaderProxy& loaderProxy)
44{
45    return adoptPtr(new WorkerLoaderClientBridge(client, loaderProxy));
46}
47
48WorkerLoaderClientBridge::~WorkerLoaderClientBridge()
49{
50}
51
52static void workerGlobalScopeDidSendData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
53{
54    ASSERT_UNUSED(context, context->isWorkerGlobalScope());
55    workerClientWrapper->didSendData(bytesSent, totalBytesToBeSent);
56}
57
58void WorkerLoaderClientBridge::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
59{
60    m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidSendData, m_workerClientWrapper, bytesSent, totalBytesToBeSent));
61}
62
63static void workerGlobalScopeDidReceiveResponse(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier, PassOwnPtr<CrossThreadResourceResponseData> responseData)
64{
65    ASSERT_UNUSED(context, context->isWorkerGlobalScope());
66    OwnPtr<ResourceResponse> response(ResourceResponse::adopt(responseData));
67    workerClientWrapper->didReceiveResponse(identifier, *response);
68}
69
70void WorkerLoaderClientBridge::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
71{
72    m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidReceiveResponse, m_workerClientWrapper, identifier, response));
73}
74
75static void workerGlobalScopeDidReceiveData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData)
76{
77    ASSERT_UNUSED(context, context->isWorkerGlobalScope());
78    workerClientWrapper->didReceiveData(vectorData->data(), vectorData->size());
79}
80
81void WorkerLoaderClientBridge::didReceiveData(const char* data, int dataLength)
82{
83    OwnPtr<Vector<char> > vector = adoptPtr(new Vector<char>(dataLength)); // needs to be an OwnPtr for usage with createCrossThreadTask.
84    memcpy(vector->data(), data, dataLength);
85    m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidReceiveData, m_workerClientWrapper, vector.release()));
86}
87
88static void workerGlobalScopeDidDownloadData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, int dataLength)
89{
90    ASSERT_UNUSED(context, context->isWorkerGlobalScope());
91    workerClientWrapper->didDownloadData(dataLength);
92}
93
94void WorkerLoaderClientBridge::didDownloadData(int dataLength)
95{
96    m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidDownloadData, m_workerClientWrapper, dataLength));
97}
98
99static void workerGlobalScopeDidReceiveCachedMetadata(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData)
100{
101    ASSERT_UNUSED(context, context->isWorkerGlobalScope());
102    workerClientWrapper->didReceiveCachedMetadata(vectorData->data(), vectorData->size());
103}
104
105void WorkerLoaderClientBridge::didReceiveCachedMetadata(const char* data, int dataLength)
106{
107    OwnPtr<Vector<char> > vector = adoptPtr(new Vector<char>(dataLength)); // needs to be an OwnPtr for usage with createCrossThreadTask.
108    memcpy(vector->data(), data, dataLength);
109    m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidReceiveCachedMetadata, m_workerClientWrapper, vector.release()));
110}
111
112static void workerGlobalScopeDidFinishLoading(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier, double finishTime)
113{
114    ASSERT_UNUSED(context, context->isWorkerGlobalScope());
115    workerClientWrapper->didFinishLoading(identifier, finishTime);
116}
117
118void WorkerLoaderClientBridge::didFinishLoading(unsigned long identifier, double finishTime)
119{
120    m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidFinishLoading, m_workerClientWrapper, identifier, finishTime));
121}
122
123static void workerGlobalScopeDidFail(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error)
124{
125    ASSERT_UNUSED(context, context->isWorkerGlobalScope());
126    workerClientWrapper->didFail(error);
127}
128
129void WorkerLoaderClientBridge::didFail(const ResourceError& error)
130{
131    m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidFail, m_workerClientWrapper, error));
132}
133
134static void workerGlobalScopeDidFailAccessControlCheck(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error)
135{
136    ASSERT_UNUSED(context, context->isWorkerGlobalScope());
137    workerClientWrapper->didFailAccessControlCheck(error);
138}
139
140void WorkerLoaderClientBridge::didFailAccessControlCheck(const ResourceError& error)
141{
142    m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidFailAccessControlCheck, m_workerClientWrapper, error));
143}
144
145static void workerGlobalScopeDidFailRedirectCheck(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper)
146{
147    ASSERT_UNUSED(context, context->isWorkerGlobalScope());
148    workerClientWrapper->didFailRedirectCheck();
149}
150
151void WorkerLoaderClientBridge::didFailRedirectCheck()
152{
153    m_loaderProxy.postTaskToWorkerGlobalScope(createCrossThreadTask(&workerGlobalScopeDidFailRedirectCheck, m_workerClientWrapper));
154}
155
156WorkerLoaderClientBridge::WorkerLoaderClientBridge(PassRefPtr<ThreadableLoaderClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy)
157    : m_workerClientWrapper(clientWrapper)
158    , m_loaderProxy(loaderProxy)
159{
160}
161
162} // namespace blink
163