1/*
2 * Copyright (C) 2010, 2013 Apple 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
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 "WebDatabaseManagerProxy.h"
28
29#if ENABLE(SQL_DATABASE)
30
31#include "APIArray.h"
32#include "ImmutableDictionary.h"
33#include "WebContext.h"
34#include "WebDatabaseManagerMessages.h"
35#include "WebDatabaseManagerProxyMessages.h"
36#include "WebSecurityOrigin.h"
37#include <wtf/NeverDestroyed.h>
38
39using namespace WebCore;
40
41namespace WebKit {
42
43const char* WebDatabaseManagerProxy::supplementName()
44{
45    return "WebDatabaseManagerProxy";
46}
47
48String WebDatabaseManagerProxy::originKey()
49{
50    static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerOriginKey"));
51    return key;
52}
53
54String WebDatabaseManagerProxy::originQuotaKey()
55{
56    static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerOriginQuotaKey"));
57    return key;
58}
59
60String WebDatabaseManagerProxy::originUsageKey()
61{
62    static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerOriginUsageKey"));
63    return key;
64}
65
66String WebDatabaseManagerProxy::databaseDetailsKey()
67{
68    static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsKey"));
69    return key;
70}
71
72String WebDatabaseManagerProxy::databaseDetailsNameKey()
73{
74    static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsNameKey"));
75    return key;
76}
77
78String WebDatabaseManagerProxy::databaseDetailsDisplayNameKey()
79{
80    static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsDisplayNameKey"));
81    return key;
82}
83
84String WebDatabaseManagerProxy::databaseDetailsExpectedUsageKey()
85{
86    static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsExpectedUsageKey"));
87    return key;
88}
89
90String WebDatabaseManagerProxy::databaseDetailsCurrentUsageKey()
91{
92    static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsCurrentUsageKey"));
93    return key;
94}
95
96String WebDatabaseManagerProxy::databaseDetailsCreationTimeKey()
97{
98    static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsCreationTimeKey"));
99    return key;
100}
101
102String WebDatabaseManagerProxy::databaseDetailsModificationTimeKey()
103{
104    static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsModificationTimeKey"));
105    return key;
106}
107
108PassRefPtr<WebDatabaseManagerProxy> WebDatabaseManagerProxy::create(WebContext* webContext)
109{
110    return adoptRef(new WebDatabaseManagerProxy(webContext));
111}
112
113WebDatabaseManagerProxy::WebDatabaseManagerProxy(WebContext* webContext)
114    : WebContextSupplement(webContext)
115{
116    WebContextSupplement::context()->addMessageReceiver(Messages::WebDatabaseManagerProxy::messageReceiverName(), *this);
117}
118
119WebDatabaseManagerProxy::~WebDatabaseManagerProxy()
120{
121}
122
123void WebDatabaseManagerProxy::initializeClient(const WKDatabaseManagerClientBase* client)
124{
125    m_client.initialize(client);
126}
127
128// WebContextSupplement
129
130void WebDatabaseManagerProxy::contextDestroyed()
131{
132    invalidateCallbackMap(m_arrayCallbacks, CallbackBase::Error::OwnerWasInvalidated);
133}
134
135void WebDatabaseManagerProxy::processDidClose(WebProcessProxy*)
136{
137    invalidateCallbackMap(m_arrayCallbacks, CallbackBase::Error::ProcessExited);
138}
139
140bool WebDatabaseManagerProxy::shouldTerminate(WebProcessProxy*) const
141{
142    return m_arrayCallbacks.isEmpty();
143}
144
145void WebDatabaseManagerProxy::refWebContextSupplement()
146{
147    API::Object::ref();
148}
149
150void WebDatabaseManagerProxy::derefWebContextSupplement()
151{
152    API::Object::deref();
153}
154
155void WebDatabaseManagerProxy::getDatabasesByOrigin(std::function<void (API::Array*, CallbackBase::Error)> callbackFunction)
156{
157    RefPtr<ArrayCallback> callback = ArrayCallback::create(WTF::move(callbackFunction));
158    uint64_t callbackID = callback->callbackID();
159    m_arrayCallbacks.set(callbackID, callback.release());
160
161    context()->sendToOneProcess(Messages::WebDatabaseManager::GetDatabasesByOrigin(callbackID));
162}
163
164void WebDatabaseManagerProxy::didGetDatabasesByOrigin(const Vector<OriginAndDatabases>& originAndDatabasesVector, uint64_t callbackID)
165{
166    RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID);
167    if (!callback) {
168        // FIXME: Log error or assert.
169        return;
170    }
171
172    Vector<RefPtr<API::Object>> result;
173    result.reserveInitialCapacity(originAndDatabasesVector.size());
174
175    for (const auto& originAndDatabases : originAndDatabasesVector) {
176        RefPtr<API::Object> origin = WebSecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(originAndDatabases.originIdentifier));
177
178        Vector<RefPtr<API::Object>> databases;
179        databases.reserveInitialCapacity(originAndDatabases.databases.size());
180
181        for (const auto& databaseDetails : originAndDatabases.databases) {
182            HashMap<String, RefPtr<API::Object>> detailsMap;
183
184            detailsMap.set(databaseDetailsNameKey(), API::String::create(databaseDetails.name()));
185            detailsMap.set(databaseDetailsDisplayNameKey(), API::String::create(databaseDetails.displayName()));
186            detailsMap.set(databaseDetailsExpectedUsageKey(), API::UInt64::create(databaseDetails.expectedUsage()));
187            detailsMap.set(databaseDetailsCurrentUsageKey(), API::UInt64::create(databaseDetails.currentUsage()));
188            if (databaseDetails.creationTime())
189                detailsMap.set(databaseDetailsCreationTimeKey(), API::Double::create(databaseDetails.creationTime()));
190            if (databaseDetails.modificationTime())
191                detailsMap.set(databaseDetailsModificationTimeKey(), API::Double::create(databaseDetails.modificationTime()));
192
193            databases.uncheckedAppend(ImmutableDictionary::create(WTF::move(detailsMap)));
194        }
195
196        HashMap<String, RefPtr<API::Object>> originAndDatabasesMap;
197        originAndDatabasesMap.set(originKey(), origin);
198        originAndDatabasesMap.set(originQuotaKey(), API::UInt64::create(originAndDatabases.originQuota));
199        originAndDatabasesMap.set(originUsageKey(), API::UInt64::create(originAndDatabases.originUsage));
200        originAndDatabasesMap.set(databaseDetailsKey(), API::Array::create(WTF::move(databases)));
201
202        result.uncheckedAppend(ImmutableDictionary::create(WTF::move(originAndDatabasesMap)));
203    }
204
205    callback->performCallbackWithReturnValue(API::Array::create(WTF::move(result)).get());
206}
207
208void WebDatabaseManagerProxy::getDatabaseOrigins(std::function<void (API::Array*, CallbackBase::Error)> callbackFunction)
209{
210    RefPtr<ArrayCallback> callback = ArrayCallback::create(WTF::move(callbackFunction));
211    uint64_t callbackID = callback->callbackID();
212    m_arrayCallbacks.set(callbackID, callback.release());
213
214    context()->sendToOneProcess(Messages::WebDatabaseManager::GetDatabaseOrigins(callbackID));
215}
216
217void WebDatabaseManagerProxy::didGetDatabaseOrigins(const Vector<String>& originIdentifiers, uint64_t callbackID)
218{
219    RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID);
220    if (!callback) {
221        // FIXME: Log error or assert.
222        return;
223    }
224
225    Vector<RefPtr<API::Object>> securityOrigins;
226    securityOrigins.reserveInitialCapacity(originIdentifiers.size());
227
228    for (const auto& originIdentifier : originIdentifiers)
229        securityOrigins.uncheckedAppend(WebSecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(originIdentifier)));
230
231    callback->performCallbackWithReturnValue(API::Array::create(WTF::move(securityOrigins)).get());
232}
233
234void WebDatabaseManagerProxy::deleteDatabaseWithNameForOrigin(const String& databaseIdentifier, WebSecurityOrigin* origin)
235{
236    context()->sendToOneProcess(Messages::WebDatabaseManager::DeleteDatabaseWithNameForOrigin(databaseIdentifier, origin->securityOrigin().databaseIdentifier()));
237}
238
239void WebDatabaseManagerProxy::deleteDatabasesForOrigin(WebSecurityOrigin* origin)
240{
241    context()->sendToOneProcess(Messages::WebDatabaseManager::DeleteDatabasesForOrigin(origin->securityOrigin().databaseIdentifier()));
242}
243
244void WebDatabaseManagerProxy::deleteAllDatabases()
245{
246    context()->sendToOneProcess(Messages::WebDatabaseManager::DeleteAllDatabases());
247}
248
249void WebDatabaseManagerProxy::setQuotaForOrigin(WebSecurityOrigin* origin, uint64_t quota)
250{
251    context()->sendToOneProcess(Messages::WebDatabaseManager::SetQuotaForOrigin(origin->securityOrigin().databaseIdentifier(), quota));
252}
253
254void WebDatabaseManagerProxy::didModifyOrigin(const String& originIdentifier)
255{
256    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(originIdentifier));
257    m_client.didModifyOrigin(this, origin.get());
258}
259
260void WebDatabaseManagerProxy::didModifyDatabase(const String& originIdentifier, const String& databaseIdentifier)
261{
262    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(SecurityOrigin::createFromDatabaseIdentifier(originIdentifier));
263    m_client.didModifyDatabase(this, origin.get(), databaseIdentifier);
264}
265
266} // namespace WebKit
267
268#endif // ENABLE(SQL_DATABASE)
269