1/*
2 * Copyright (C) 2010 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#include "ImmutableArray.h"
30#include "ImmutableDictionary.h"
31#include "WebDatabaseManagerMessages.h"
32#include "WebContext.h"
33#include "WebSecurityOrigin.h"
34
35using namespace WebCore;
36
37namespace WebKit {
38
39String WebDatabaseManagerProxy::originKey()
40{
41    DEFINE_STATIC_LOCAL(String, key, ("WebDatabaseManagerOriginKey"));
42    return key;
43}
44
45String WebDatabaseManagerProxy::originQuotaKey()
46{
47    DEFINE_STATIC_LOCAL(String, key, ("WebDatabaseManagerOriginQuotaKey"));
48    return key;
49}
50
51String WebDatabaseManagerProxy::originUsageKey()
52{
53    DEFINE_STATIC_LOCAL(String, key, ("WebDatabaseManagerOriginUsageKey"));
54    return key;
55}
56
57String WebDatabaseManagerProxy::databaseDetailsKey()
58{
59    DEFINE_STATIC_LOCAL(String, key, ("WebDatabaseManagerDatabaseDetailsKey"));
60    return key;
61}
62
63String WebDatabaseManagerProxy::databaseDetailsNameKey()
64{
65    DEFINE_STATIC_LOCAL(String, key, ("WebDatabaseManagerDatabaseDetailsNameKey"));
66    return key;
67}
68
69String WebDatabaseManagerProxy::databaseDetailsDisplayNameKey()
70{
71    DEFINE_STATIC_LOCAL(String, key, ("WebDatabaseManagerDatabaseDetailsDisplayNameKey"));
72    return key;
73}
74
75String WebDatabaseManagerProxy::databaseDetailsExpectedUsageKey()
76{
77    DEFINE_STATIC_LOCAL(String, key, ("WebDatabaseManagerDatabaseDetailsExpectedUsageKey"));
78    return key;
79}
80
81String WebDatabaseManagerProxy::databaseDetailsCurrentUsageKey()
82{
83    DEFINE_STATIC_LOCAL(String, key, ("WebDatabaseManagerDatabaseDetailsCurrentUsageKey"));
84    return key;
85}
86
87PassRefPtr<WebDatabaseManagerProxy> WebDatabaseManagerProxy::create(WebContext* webContext)
88{
89    return adoptRef(new WebDatabaseManagerProxy(webContext));
90}
91
92WebDatabaseManagerProxy::WebDatabaseManagerProxy(WebContext* webContext)
93    : m_webContext(webContext)
94{
95}
96
97WebDatabaseManagerProxy::~WebDatabaseManagerProxy()
98{
99}
100
101void WebDatabaseManagerProxy::invalidate()
102{
103    invalidateCallbackMap(m_arrayCallbacks);
104}
105
106bool WebDatabaseManagerProxy::shouldTerminate(WebProcessProxy*) const
107{
108    return m_arrayCallbacks.isEmpty();
109}
110
111void WebDatabaseManagerProxy::initializeClient(const WKDatabaseManagerClient* client)
112{
113    m_client.initialize(client);
114}
115
116void WebDatabaseManagerProxy::getDatabasesByOrigin(PassRefPtr<ArrayCallback> prpCallback)
117{
118    RefPtr<ArrayCallback> callback = prpCallback;
119    uint64_t callbackID = callback->callbackID();
120    m_arrayCallbacks.set(callbackID, callback.release());
121
122    // FIXME (Multi-WebProcess): Databases shouldn't be stored in the web process.
123    m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebDatabaseManager::GetDatabasesByOrigin(callbackID));
124}
125
126void WebDatabaseManagerProxy::didGetDatabasesByOrigin(const Vector<OriginAndDatabases>& originAndDatabasesVector, uint64_t callbackID)
127{
128    RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID);
129    if (!callback) {
130        // FIXME: Log error or assert.
131        return;
132    }
133
134    size_t originAndDatabasesCount = originAndDatabasesVector.size();
135    Vector<RefPtr<APIObject> > result(originAndDatabasesCount);
136
137    for (size_t i = 0; i < originAndDatabasesCount; ++i) {
138        const OriginAndDatabases& originAndDatabases = originAndDatabasesVector[i];
139
140        RefPtr<APIObject> origin = WebSecurityOrigin::create(originAndDatabases.originIdentifier);
141
142        size_t databasesCount = originAndDatabases.databases.size();
143        Vector<RefPtr<APIObject> > databases(databasesCount);
144
145        for (size_t j = 0; j < databasesCount; ++j) {
146            const DatabaseDetails& details = originAndDatabases.databases[i];
147            HashMap<String, RefPtr<APIObject> > detailsMap;
148
149            detailsMap.set(databaseDetailsNameKey(), WebString::create(details.name()));
150            detailsMap.set(databaseDetailsDisplayNameKey(), WebString::create(details.displayName()));
151            detailsMap.set(databaseDetailsExpectedUsageKey(), WebUInt64::create(details.expectedUsage()));
152            detailsMap.set(databaseDetailsCurrentUsageKey(), WebUInt64::create(details.currentUsage()));
153            databases.append(ImmutableDictionary::adopt(detailsMap));
154        }
155
156        HashMap<String, RefPtr<APIObject> > originAndDatabasesMap;
157        originAndDatabasesMap.set(originKey(), origin);
158        originAndDatabasesMap.set(originQuotaKey(), WebUInt64::create(originAndDatabases.originQuota));
159        originAndDatabasesMap.set(originUsageKey(), WebUInt64::create(originAndDatabases.originUsage));
160        originAndDatabasesMap.set(databaseDetailsKey(), ImmutableArray::adopt(databases));
161
162        result.append(ImmutableDictionary::adopt(originAndDatabasesMap));
163    }
164
165    RefPtr<ImmutableArray> resultArray = ImmutableArray::adopt(result);
166    callback->performCallbackWithReturnValue(resultArray.get());
167}
168
169void WebDatabaseManagerProxy::getDatabaseOrigins(PassRefPtr<ArrayCallback> prpCallback)
170{
171    RefPtr<ArrayCallback> callback = prpCallback;
172    uint64_t callbackID = callback->callbackID();
173    m_arrayCallbacks.set(callbackID, callback.release());
174
175    // FIXME (Multi-WebProcess): Databases shouldn't be stored in the web process.
176    m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebDatabaseManager::GetDatabaseOrigins(callbackID));
177}
178
179void WebDatabaseManagerProxy::didGetDatabaseOrigins(const Vector<String>& originIdentifiers, uint64_t callbackID)
180{
181    RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID);
182    if (!callback) {
183        // FIXME: Log error or assert.
184        return;
185    }
186
187    size_t originIdentifiersCount = originIdentifiers.size();
188    Vector<RefPtr<APIObject> > securityOrigins(originIdentifiersCount);
189
190    for (size_t i = 0; i < originIdentifiersCount; ++i)
191        securityOrigins[i] = WebSecurityOrigin::create(originIdentifiers[i]);
192
193    callback->performCallbackWithReturnValue(ImmutableArray::adopt(securityOrigins).get());
194}
195
196void WebDatabaseManagerProxy::deleteDatabaseWithNameForOrigin(const String& databaseIdentifier, WebSecurityOrigin* origin)
197{
198    // FIXME (Multi-WebProcess): Databases shouldn't be stored in the web process.
199    m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebDatabaseManager::DeleteDatabaseWithNameForOrigin(databaseIdentifier, origin->databaseIdentifier()));
200}
201
202void WebDatabaseManagerProxy::deleteDatabasesForOrigin(WebSecurityOrigin* origin)
203{
204    // FIXME (Multi-WebProcess): Databases shouldn't be stored in the web process.
205    m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebDatabaseManager::DeleteDatabasesForOrigin(origin->databaseIdentifier()));
206}
207
208void WebDatabaseManagerProxy::deleteAllDatabases()
209{
210    // FIXME (Multi-WebProcess): Databases shouldn't be stored in the web process.
211    m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebDatabaseManager::DeleteAllDatabases());
212}
213
214void WebDatabaseManagerProxy::setQuotaForOrigin(WebSecurityOrigin* origin, uint64_t quota)
215{
216    // FIXME (Multi-WebProcess): Databases shouldn't be stored in the web process.
217    m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebDatabaseManager::SetQuotaForOrigin(origin->databaseIdentifier(), quota));
218}
219
220void WebDatabaseManagerProxy::didModifyOrigin(const String& originIdentifier)
221{
222    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
223    m_client.didModifyOrigin(this, origin.get());
224}
225
226void WebDatabaseManagerProxy::didModifyDatabase(const String& originIdentifier, const String& databaseIdentifier)
227{
228    RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::create(originIdentifier);
229    m_client.didModifyDatabase(this, origin.get(), databaseIdentifier);
230}
231
232} // namespace WebKit
233
234