2011-01-24 Maciej Stachowiak <mjs@apple.com>
[WebKit.git] / Source / WebKit2 / WebProcess / WebCoreSupport / WebDatabaseManager.cpp
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 "WebDatabaseManager.h"
27
28 #include "Connection.h"
29 #include "MessageID.h"
30 #include "OriginAndDatabases.h"
31 #include "WebCoreArgumentCoders.h"
32 #include "WebDatabaseManagerProxyMessages.h"
33 #include "WebProcess.h"
34 #include <WebCore/DatabaseDetails.h>
35 #include <WebCore/DatabaseTracker.h>
36 #include <WebCore/SecurityOrigin.h>
37
38 using namespace WebCore;
39
40 namespace WebKit {
41
42 WebDatabaseManager& WebDatabaseManager::shared()
43 {
44     static WebDatabaseManager& shared = *new WebDatabaseManager;
45     return shared;
46 }
47
48 void WebDatabaseManager::initialize(const String& databaseDirectory)
49 {
50     DatabaseTracker::initializeTracker(databaseDirectory);
51 }
52
53 WebDatabaseManager::WebDatabaseManager()
54 {
55     DatabaseTracker::tracker().setClient(this);
56 }
57
58 WebDatabaseManager::~WebDatabaseManager()
59 {
60 }
61
62 void WebDatabaseManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
63 {
64     didReceiveWebDatabaseManagerMessage(connection, messageID, arguments);
65 }
66
67 void WebDatabaseManager::getDatabasesByOrigin(uint64_t callbackID) const
68 {
69     // FIXME: This could be made more efficient by adding a function to DatabaseTracker
70     // to get both the origins and the Vector of DatabaseDetails for each origin in one
71     // shot.  That would avoid taking the numerous locks this requires.
72
73     Vector<RefPtr<SecurityOrigin> > origins;
74     DatabaseTracker::tracker().origins(origins);
75
76     Vector<OriginAndDatabases> originAndDatabasesVector;
77     originAndDatabasesVector.reserveInitialCapacity(origins.size());
78
79     for (size_t i = 0; i < origins.size(); ++i) {
80         OriginAndDatabases originAndDatabases;
81
82         Vector<String> nameVector;
83         if (!DatabaseTracker::tracker().databaseNamesForOrigin(origins[i].get(), nameVector))
84             continue;
85
86         Vector<DatabaseDetails> detailsVector;
87         detailsVector.reserveInitialCapacity(nameVector.size());
88         for (size_t j = 0; j < nameVector.size(); j++) {
89             DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(nameVector[j], origins[i].get());
90             if (details.name().isNull())
91                 continue;
92
93             detailsVector.append(details);
94         }
95
96         if (detailsVector.isEmpty())
97             continue;
98
99         originAndDatabases.originIdentifier = origins[i]->databaseIdentifier();
100         originAndDatabases.originQuota = DatabaseTracker::tracker().quotaForOrigin(origins[i].get());
101         originAndDatabases.originUsage = DatabaseTracker::tracker().usageForOrigin(origins[i].get());
102         originAndDatabases.databases.swap(detailsVector); 
103         originAndDatabasesVector.append(originAndDatabases);
104     }
105
106     WebProcess::shared().connection()->send(Messages::WebDatabaseManagerProxy::DidGetDatabasesByOrigin(originAndDatabasesVector, callbackID), 0);
107 }
108
109 void WebDatabaseManager::getDatabaseOrigins(uint64_t callbackID) const
110 {
111     Vector<RefPtr<SecurityOrigin> > origins;
112     DatabaseTracker::tracker().origins(origins);
113
114     size_t numOrigins = origins.size();
115
116     Vector<String> identifiers(numOrigins);
117     for (size_t i = 0; i < numOrigins; ++i)
118         identifiers[i] = origins[i]->databaseIdentifier();
119     WebProcess::shared().connection()->send(Messages::WebDatabaseManagerProxy::DidGetDatabaseOrigins(identifiers, callbackID), 0);
120 }
121
122 void WebDatabaseManager::deleteDatabaseWithNameForOrigin(const String& databaseIdentifier, const String& originIdentifier) const
123 {
124     RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
125     if (!origin)
126         return;
127
128     DatabaseTracker::tracker().deleteDatabase(origin.get(), databaseIdentifier);
129 }
130
131 void WebDatabaseManager::deleteDatabasesForOrigin(const String& originIdentifier) const
132 {
133     RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
134     if (!origin)
135         return;
136
137     DatabaseTracker::tracker().deleteOrigin(origin.get());
138 }
139
140 void WebDatabaseManager::deleteAllDatabases() const
141 {
142     DatabaseTracker::tracker().deleteAllDatabases();
143 }
144
145 void WebDatabaseManager::setQuotaForOrigin(const String& originIdentifier, unsigned long long quota) const
146 {
147     // If the quota is set to a value lower than the current usage, that quota will
148     // "stick" but no data will be purged to meet the new quota. This will simply
149     // prevent new data from being added to databases in that origin.
150
151     RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
152     if (!origin)
153         return;
154
155     DatabaseTracker::tracker().setQuota(origin.get(), quota);
156 }
157
158 void WebDatabaseManager::dispatchDidModifyOrigin(SecurityOrigin* origin)
159 {
160     // NOTE: This may be called on a non-main thread.
161     WebProcess::shared().connection()->send(Messages::WebDatabaseManagerProxy::DidModifyOrigin(origin->databaseIdentifier()), 0);
162 }
163
164 void WebDatabaseManager::dispatchDidModifyDatabase(WebCore::SecurityOrigin* origin, const String& databaseIdentifier)
165 {
166     // NOTE: This may be called on a non-main thread.
167     WebProcess::shared().connection()->send(Messages::WebDatabaseManagerProxy::DidModifyDatabase(origin->databaseIdentifier(), databaseIdentifier), 0);
168 }
169
170 } // namespace WebKit