• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 "WebIconDatabase.h"
28 
29 #include "DataReference.h"
30 #include "Logging.h"
31 #include "WebContext.h"
32 #include "WebIconDatabaseProxyMessages.h"
33 #include <WebCore/FileSystem.h>
34 #include <WebCore/IconDatabase.h>
35 #include <WebCore/IconDatabaseBase.h>
36 #include <wtf/text/WTFString.h>
37 
38 using namespace WebCore;
39 
40 namespace WebKit {
41 
create(WebContext * context)42 PassRefPtr<WebIconDatabase> WebIconDatabase::create(WebContext* context)
43 {
44     return adoptRef(new WebIconDatabase(context));
45 }
46 
~WebIconDatabase()47 WebIconDatabase::~WebIconDatabase()
48 {
49 }
50 
WebIconDatabase(WebContext * context)51 WebIconDatabase::WebIconDatabase(WebContext* context)
52     : m_webContext(context)
53     , m_urlImportCompleted(false)
54     , m_databaseCleanupDisabled(false)
55 {
56 }
57 
invalidate()58 void WebIconDatabase::invalidate()
59 {
60 }
61 
setDatabasePath(const String & path)62 void WebIconDatabase::setDatabasePath(const String& path)
63 {
64     if (m_iconDatabaseImpl && m_iconDatabaseImpl->isOpen()) {
65         LOG_ERROR("Icon database already has a path and is already open. We don't currently support changing its path and reopening.");
66         return;
67     }
68 
69     m_iconDatabaseImpl =  IconDatabase::create();
70     m_iconDatabaseImpl->setClient(this);
71     IconDatabase::delayDatabaseCleanup();
72     m_databaseCleanupDisabled = true;
73     m_iconDatabaseImpl->setEnabled(true);
74     if (!m_iconDatabaseImpl->open(directoryName(path), pathGetFileName(path))) {
75         LOG_ERROR("Unable to open WebKit2 icon database on disk");
76         m_iconDatabaseImpl.clear();
77         setGlobalIconDatabase(0);
78         IconDatabase::allowDatabaseCleanup();
79         m_databaseCleanupDisabled = false;
80     }
81     setGlobalIconDatabase(m_iconDatabaseImpl.get());
82 }
83 
enableDatabaseCleanup()84 void WebIconDatabase::enableDatabaseCleanup()
85 {
86     if (!m_iconDatabaseImpl) {
87         LOG_ERROR("Cannot enabled Icon Database cleanup - it hasn't been opened yet.");
88         return;
89     }
90 
91     if (!m_databaseCleanupDisabled) {
92         LOG_ERROR("Attempt to enable database cleanup, but it's already enabled.");
93         ASSERT_NOT_REACHED();
94         return;
95     }
96 
97     IconDatabase::allowDatabaseCleanup();
98     m_databaseCleanupDisabled = false;
99 }
100 
retainIconForPageURL(const String & pageURL)101 void WebIconDatabase::retainIconForPageURL(const String& pageURL)
102 {
103     if (m_iconDatabaseImpl)
104         m_iconDatabaseImpl->retainIconForPageURL(pageURL);
105 }
106 
releaseIconForPageURL(const String & pageURL)107 void WebIconDatabase::releaseIconForPageURL(const String& pageURL)
108 {
109     if (m_iconDatabaseImpl)
110         m_iconDatabaseImpl->releaseIconForPageURL(pageURL);
111 }
112 
setIconURLForPageURL(const String & iconURL,const String & pageURL)113 void WebIconDatabase::setIconURLForPageURL(const String& iconURL, const String& pageURL)
114 {
115     LOG(IconDatabase, "WK2 UIProcess setting icon URL %s for page URL %s", iconURL.ascii().data(), pageURL.ascii().data());
116     if (m_iconDatabaseImpl)
117         m_iconDatabaseImpl->setIconURLForPageURL(iconURL, pageURL);
118 }
119 
setIconDataForIconURL(const CoreIPC::DataReference & iconData,const String & iconURL)120 void WebIconDatabase::setIconDataForIconURL(const CoreIPC::DataReference& iconData, const String& iconURL)
121 {
122     LOG(IconDatabase, "WK2 UIProcess setting icon data (%i bytes) for page URL %s", (int)iconData.size(), iconURL.ascii().data());
123     if (!m_iconDatabaseImpl)
124         return;
125 
126     RefPtr<SharedBuffer> buffer = SharedBuffer::create(iconData.data(), iconData.size());
127     m_iconDatabaseImpl->setIconDataForIconURL(buffer.release(), iconURL);
128 }
129 
synchronousIconDataForPageURL(const String &,CoreIPC::DataReference & iconData)130 void WebIconDatabase::synchronousIconDataForPageURL(const String&, CoreIPC::DataReference& iconData)
131 {
132     iconData = CoreIPC::DataReference();
133 }
134 
synchronousIconURLForPageURL(const String &,String & iconURL)135 void WebIconDatabase::synchronousIconURLForPageURL(const String&, String& iconURL)
136 {
137     iconURL = String();
138 }
139 
synchronousIconDataKnownForIconURL(const String &,bool & iconDataKnown) const140 void WebIconDatabase::synchronousIconDataKnownForIconURL(const String&, bool& iconDataKnown) const
141 {
142     iconDataKnown = false;
143 }
144 
synchronousLoadDecisionForIconURL(const String &,int & loadDecision) const145 void WebIconDatabase::synchronousLoadDecisionForIconURL(const String&, int& loadDecision) const
146 {
147     loadDecision = static_cast<int>(IconLoadNo);
148 }
149 
getLoadDecisionForIconURL(const String & iconURL,uint64_t callbackID)150 void WebIconDatabase::getLoadDecisionForIconURL(const String& iconURL, uint64_t callbackID)
151 {
152     LOG(IconDatabase, "WK2 UIProcess getting load decision for icon URL %s with callback ID %lli", iconURL.ascii().data(), static_cast<long long>(callbackID));
153 
154     if (!m_webContext)
155         return;
156 
157     if (!m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || iconURL.isEmpty()) {
158         // FIXME (Multi-WebProcess): We need to know which connection to send this message to.
159         m_webContext->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision(static_cast<int>(IconLoadNo), callbackID));
160         return;
161     }
162 
163     // If the decision hasn't been read from disk yet, set this url and callback ID aside to be notifed later
164     IconLoadDecision decision = m_iconDatabaseImpl->synchronousLoadDecisionForIconURL(iconURL, 0);
165     if (decision == IconLoadUnknown) {
166         // We should never get an unknown load decision after the URL import has completed.
167         ASSERT(!m_urlImportCompleted);
168 
169         m_pendingLoadDecisionURLMap.set(callbackID, iconURL);
170         return;
171     }
172 
173     // FIXME (Multi-WebProcess): We need to know which connection to send this message to.
174     m_webContext->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision((int)decision, callbackID));
175 }
176 
imageForPageURL(const String & pageURL)177 Image* WebIconDatabase::imageForPageURL(const String& pageURL)
178 {
179     if (!m_webContext || !m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || pageURL.isEmpty())
180         return 0;
181 
182     // The WebCore IconDatabase ignores the passed in size parameter.
183     // If that changes we'll need to rethink how this API is exposed.
184     return m_iconDatabaseImpl->synchronousIconForPageURL(pageURL, WebCore::IntSize(32, 32));
185 }
186 
removeAllIcons()187 void WebIconDatabase::removeAllIcons()
188 {
189     m_iconDatabaseImpl->removeAllIcons();
190 }
191 
checkIntegrityBeforeOpening()192 void WebIconDatabase::checkIntegrityBeforeOpening()
193 {
194     IconDatabase::checkIntegrityBeforeOpening();
195 }
196 
close()197 void WebIconDatabase::close()
198 {
199     m_iconDatabaseImpl->close();
200 }
201 
initializeIconDatabaseClient(const WKIconDatabaseClient * client)202 void WebIconDatabase::initializeIconDatabaseClient(const WKIconDatabaseClient* client)
203 {
204     m_iconDatabaseClient.initialize(client);
205 }
206 
207 // WebCore::IconDatabaseClient
performImport()208 bool WebIconDatabase::performImport()
209 {
210     // WebKit2 icon database doesn't currently support importing any old icon database formats.
211     return true;
212 }
213 
didImportIconURLForPageURL(const String & pageURL)214 void WebIconDatabase::didImportIconURLForPageURL(const String& pageURL)
215 {
216     didChangeIconForPageURL(pageURL);
217 }
218 
didImportIconDataForPageURL(const String & pageURL)219 void WebIconDatabase::didImportIconDataForPageURL(const String& pageURL)
220 {
221     didChangeIconForPageURL(pageURL);
222 }
223 
didChangeIconForPageURL(const String & pageURL)224 void WebIconDatabase::didChangeIconForPageURL(const String& pageURL)
225 {
226     m_iconDatabaseClient.didChangeIconForPageURL(this, WebURL::create(pageURL).get());
227 }
228 
didRemoveAllIcons()229 void WebIconDatabase::didRemoveAllIcons()
230 {
231     m_iconDatabaseClient.didRemoveAllIcons(this);
232 }
233 
didFinishURLImport()234 void WebIconDatabase::didFinishURLImport()
235 {
236     if (!m_webContext)
237         return;
238 
239     ASSERT(!m_urlImportCompleted);
240 
241     LOG(IconDatabase, "WK2 UIProcess URL import complete, notifying all %i pending page URL load decisions", m_pendingLoadDecisionURLMap.size());
242 
243     HashMap<uint64_t, String>::iterator i = m_pendingLoadDecisionURLMap.begin();
244     HashMap<uint64_t, String>::iterator end = m_pendingLoadDecisionURLMap.end();
245 
246     for (; i != end; ++i) {
247         LOG(IconDatabase, "WK2 UIProcess performing delayed callback on callback ID %i for page url %s", (int)i->first, i->second.ascii().data());
248         IconLoadDecision decision = m_iconDatabaseImpl->synchronousLoadDecisionForIconURL(i->second, 0);
249 
250         // Decisions should never be unknown after the inital import is complete
251         ASSERT(decision != IconLoadUnknown);
252 
253         // FIXME (Multi-WebProcess): We need to know which connection to send this message to.
254         m_webContext->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision(static_cast<int>(decision), i->first));
255     }
256 
257     m_pendingLoadDecisionURLMap.clear();
258 
259     m_urlImportCompleted = true;
260 }
261 
didReceiveMessage(CoreIPC::Connection * connection,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * decoder)262 void WebIconDatabase::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* decoder)
263 {
264     didReceiveWebIconDatabaseMessage(connection, messageID, decoder);
265 }
266 
didReceiveSyncMessage(CoreIPC::Connection * connection,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * decoder,CoreIPC::ArgumentEncoder * reply)267 CoreIPC::SyncReplyMode WebIconDatabase::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* decoder, CoreIPC::ArgumentEncoder* reply)
268 {
269     return didReceiveSyncWebIconDatabaseMessage(connection, messageID, decoder, reply);
270 }
271 
272 } // namespace WebKit
273