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 38using namespace WebCore; 39 40namespace WebKit { 41 42PassRefPtr<WebIconDatabase> WebIconDatabase::create(WebContext* context) 43{ 44 return adoptRef(new WebIconDatabase(context)); 45} 46 47WebIconDatabase::~WebIconDatabase() 48{ 49} 50 51WebIconDatabase::WebIconDatabase(WebContext* context) 52 : m_webContext(context) 53 , m_urlImportCompleted(false) 54 , m_databaseCleanupDisabled(false) 55{ 56} 57 58void WebIconDatabase::invalidate() 59{ 60} 61 62void 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 84void 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 101void WebIconDatabase::retainIconForPageURL(const String& pageURL) 102{ 103 if (m_iconDatabaseImpl) 104 m_iconDatabaseImpl->retainIconForPageURL(pageURL); 105} 106 107void WebIconDatabase::releaseIconForPageURL(const String& pageURL) 108{ 109 if (m_iconDatabaseImpl) 110 m_iconDatabaseImpl->releaseIconForPageURL(pageURL); 111} 112 113void 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 120void 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 130void WebIconDatabase::synchronousIconDataForPageURL(const String&, CoreIPC::DataReference& iconData) 131{ 132 iconData = CoreIPC::DataReference(); 133} 134 135void WebIconDatabase::synchronousIconURLForPageURL(const String&, String& iconURL) 136{ 137 iconURL = String(); 138} 139 140void WebIconDatabase::synchronousIconDataKnownForIconURL(const String&, bool& iconDataKnown) const 141{ 142 iconDataKnown = false; 143} 144 145void WebIconDatabase::synchronousLoadDecisionForIconURL(const String&, int& loadDecision) const 146{ 147 loadDecision = static_cast<int>(IconLoadNo); 148} 149 150void 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 177Image* 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 187void WebIconDatabase::removeAllIcons() 188{ 189 m_iconDatabaseImpl->removeAllIcons(); 190} 191 192void WebIconDatabase::checkIntegrityBeforeOpening() 193{ 194 IconDatabase::checkIntegrityBeforeOpening(); 195} 196 197void WebIconDatabase::close() 198{ 199 m_iconDatabaseImpl->close(); 200} 201 202void WebIconDatabase::initializeIconDatabaseClient(const WKIconDatabaseClient* client) 203{ 204 m_iconDatabaseClient.initialize(client); 205} 206 207// WebCore::IconDatabaseClient 208bool WebIconDatabase::performImport() 209{ 210 // WebKit2 icon database doesn't currently support importing any old icon database formats. 211 return true; 212} 213 214void WebIconDatabase::didImportIconURLForPageURL(const String& pageURL) 215{ 216 didChangeIconForPageURL(pageURL); 217} 218 219void WebIconDatabase::didImportIconDataForPageURL(const String& pageURL) 220{ 221 didChangeIconForPageURL(pageURL); 222} 223 224void WebIconDatabase::didChangeIconForPageURL(const String& pageURL) 225{ 226 m_iconDatabaseClient.didChangeIconForPageURL(this, WebURL::create(pageURL).get()); 227} 228 229void WebIconDatabase::didRemoveAllIcons() 230{ 231 m_iconDatabaseClient.didRemoveAllIcons(this); 232} 233 234void 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 262void WebIconDatabase::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* decoder) 263{ 264 didReceiveWebIconDatabaseMessage(connection, messageID, decoder); 265} 266 267CoreIPC::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