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