Home | History | Annotate | Download | only in web
      1 /*
      2  * Copyright (C) 2010 Google 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 are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "modules/webdatabase/DatabaseObserver.h"
     33 
     34 #include "WebCommonWorkerClient.h"
     35 #include "WebDatabase.h"
     36 #include "WebDatabaseObserver.h"
     37 #include "WebFrameClient.h"
     38 #include "WebFrameImpl.h"
     39 #include "WebPermissionClient.h"
     40 #include "WebSecurityOrigin.h"
     41 #include "WebViewImpl.h"
     42 #include "WebWorkerBase.h"
     43 #include "WorkerAllowMainThreadBridgeBase.h"
     44 #include "bindings/v8/WorkerScriptController.h"
     45 #include "core/dom/CrossThreadTask.h"
     46 #include "core/dom/Document.h"
     47 #include "core/dom/ScriptExecutionContext.h"
     48 #include "core/platform/CrossThreadCopier.h"
     49 #include "core/workers/WorkerGlobalScope.h"
     50 #include "core/workers/WorkerLoaderProxy.h"
     51 #include "core/workers/WorkerThread.h"
     52 #include "modules/webdatabase/DatabaseBackendBase.h"
     53 #include "modules/webdatabase/DatabaseBackendContext.h"
     54 
     55 using namespace WebKit;
     56 
     57 namespace {
     58 
     59 static const char allowDatabaseMode[] = "allowDatabaseMode";
     60 
     61 // This class is used to route the result of the WebWorkerBase::allowDatabase
     62 // call back to the worker context.
     63 class AllowDatabaseMainThreadBridge : public WorkerAllowMainThreadBridgeBase {
     64 public:
     65     static PassRefPtr<AllowDatabaseMainThreadBridge> create(WebCore::WorkerGlobalScope* workerGlobalScope, WebWorkerBase* webWorkerBase, const String& mode, WebFrame* frame, const String& name, const String& displayName, unsigned long estimatedSize)
     66     {
     67         return adoptRef(new AllowDatabaseMainThreadBridge(workerGlobalScope, webWorkerBase, mode, frame, name, displayName, estimatedSize));
     68     }
     69 
     70 private:
     71     class AllowDatabaseParams : public AllowParams
     72     {
     73     public:
     74         AllowDatabaseParams(const String& mode, WebFrame* frame, const String& name, const String& displayName, unsigned long estimatedSize)
     75             : AllowParams(mode)
     76             , m_frame(WebCore::AllowCrossThreadAccess(frame))
     77             , m_name(name.isolatedCopy())
     78             , m_displayName(displayName.isolatedCopy())
     79             , m_estimatedSize(estimatedSize)
     80         {
     81         }
     82         WebCore::AllowCrossThreadAccessWrapper<WebFrame> m_frame;
     83         String m_name;
     84         String m_displayName;
     85         unsigned long m_estimatedSize;
     86     };
     87 
     88     AllowDatabaseMainThreadBridge(WebCore::WorkerGlobalScope* workerGlobalScope, WebWorkerBase* webWorkerBase, const String& mode, WebFrame* frame, const String& name, const String& displayName, unsigned long estimatedSize)
     89         : WorkerAllowMainThreadBridgeBase(workerGlobalScope, webWorkerBase)
     90     {
     91         postTaskToMainThread(
     92             adoptPtr(new AllowDatabaseParams(mode, frame, name, displayName, estimatedSize)));
     93     }
     94 
     95     virtual bool allowOnMainThread(WebCommonWorkerClient* commonClient, AllowParams* params)
     96     {
     97         ASSERT(isMainThread());
     98         AllowDatabaseParams* allowDBParams = static_cast<AllowDatabaseParams*>(params);
     99         return commonClient->allowDatabase(
    100             allowDBParams->m_frame.value(), allowDBParams->m_name, allowDBParams->m_displayName, allowDBParams->m_estimatedSize);
    101     }
    102 };
    103 
    104 bool allowDatabaseForWorker(WebFrame* frame, const WebString& name, const WebString& displayName, unsigned long estimatedSize)
    105 {
    106     WebCore::WorkerScriptController* controller = WebCore::WorkerScriptController::controllerForContext();
    107     WebCore::WorkerGlobalScope* workerGlobalScope = controller->workerGlobalScope();
    108     WebCore::WorkerThread* workerThread = workerGlobalScope->thread();
    109     WebCore::WorkerRunLoop& runLoop = workerThread->runLoop();
    110     WebCore::WorkerLoaderProxy* workerLoaderProxy = &workerThread->workerLoaderProxy();
    111 
    112     // Create a unique mode just for this synchronous call.
    113     String mode = allowDatabaseMode;
    114     mode.append(String::number(runLoop.createUniqueId()));
    115 
    116     RefPtr<AllowDatabaseMainThreadBridge> bridge = AllowDatabaseMainThreadBridge::create(workerGlobalScope, workerLoaderProxy->toWebWorkerBase(), mode, frame, name, displayName, estimatedSize);
    117 
    118     // Either the bridge returns, or the queue gets terminated.
    119     if (runLoop.runInMode(workerGlobalScope, mode) == MessageQueueTerminated) {
    120         bridge->cancel();
    121         return false;
    122     }
    123 
    124     return bridge->result();
    125 }
    126 
    127 }
    128 
    129 namespace WebCore {
    130 
    131 bool DatabaseObserver::canEstablishDatabase(ScriptExecutionContext* scriptExecutionContext, const String& name, const String& displayName, unsigned long estimatedSize)
    132 {
    133     ASSERT(scriptExecutionContext->isContextThread());
    134     ASSERT(scriptExecutionContext->isDocument() || scriptExecutionContext->isWorkerGlobalScope());
    135     if (scriptExecutionContext->isDocument()) {
    136         Document* document = toDocument(scriptExecutionContext);
    137         WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
    138         if (!webFrame)
    139             return false;
    140         WebViewImpl* webView = webFrame->viewImpl();
    141         if (!webView)
    142             return false;
    143         if (webView->permissionClient())
    144             return webView->permissionClient()->allowDatabase(webFrame, name, displayName, estimatedSize);
    145     } else {
    146         WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(scriptExecutionContext);
    147         WebWorkerBase* webWorker = static_cast<WebWorkerBase*>(workerGlobalScope->thread()->workerLoaderProxy().toWebWorkerBase());
    148         WebView* view = webWorker->view();
    149         if (!view)
    150             return false;
    151         return allowDatabaseForWorker(view->mainFrame(), name, displayName, estimatedSize);
    152     }
    153 
    154     return true;
    155 }
    156 
    157 void DatabaseObserver::databaseOpened(DatabaseBackendBase* database)
    158 {
    159     ASSERT(database->databaseContext()->scriptExecutionContext()->isContextThread());
    160     WebDatabase::observer()->databaseOpened(WebDatabase(database));
    161 }
    162 
    163 void DatabaseObserver::databaseModified(DatabaseBackendBase* database)
    164 {
    165     ASSERT(database->databaseContext()->scriptExecutionContext()->isContextThread());
    166     WebDatabase::observer()->databaseModified(WebDatabase(database));
    167 }
    168 
    169 void DatabaseObserver::databaseClosed(DatabaseBackendBase* database)
    170 {
    171     ASSERT(database->databaseContext()->scriptExecutionContext()->isContextThread());
    172     WebDatabase::observer()->databaseClosed(WebDatabase(database));
    173 }
    174 
    175 void DatabaseObserver::reportOpenDatabaseResult(DatabaseBackendBase* database, int errorSite, int webSqlErrorCode, int sqliteErrorCode)
    176 {
    177     WebDatabase::observer()->reportOpenDatabaseResult(WebDatabase(database), errorSite, webSqlErrorCode, sqliteErrorCode);
    178 }
    179 
    180 void DatabaseObserver::reportChangeVersionResult(DatabaseBackendBase* database, int errorSite, int webSqlErrorCode, int sqliteErrorCode)
    181 {
    182     WebDatabase::observer()->reportChangeVersionResult(WebDatabase(database), errorSite, webSqlErrorCode, sqliteErrorCode);
    183 }
    184 
    185 void DatabaseObserver::reportStartTransactionResult(DatabaseBackendBase* database, int errorSite, int webSqlErrorCode, int sqliteErrorCode)
    186 {
    187     WebDatabase::observer()->reportStartTransactionResult(WebDatabase(database), errorSite, webSqlErrorCode, sqliteErrorCode);
    188 }
    189 
    190 void DatabaseObserver::reportCommitTransactionResult(DatabaseBackendBase* database, int errorSite, int webSqlErrorCode, int sqliteErrorCode)
    191 {
    192     WebDatabase::observer()->reportCommitTransactionResult(WebDatabase(database), errorSite, webSqlErrorCode, sqliteErrorCode);
    193 }
    194 
    195 void DatabaseObserver::reportExecuteStatementResult(DatabaseBackendBase* database, int errorSite, int webSqlErrorCode, int sqliteErrorCode)
    196 {
    197     WebDatabase::observer()->reportExecuteStatementResult(WebDatabase(database), errorSite, webSqlErrorCode, sqliteErrorCode);
    198 }
    199 
    200 void DatabaseObserver::reportVacuumDatabaseResult(DatabaseBackendBase* database, int sqliteErrorCode)
    201 {
    202     WebDatabase::observer()->reportVacuumDatabaseResult(WebDatabase(database), sqliteErrorCode);
    203 }
    204 
    205 } // namespace WebCore
    206