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