Changeset 245328 in webkit


Ignore:
Timestamp:
May 15, 2019 10:40:01 AM (5 years ago)
Author:
youenn@apple.com
Message:

Reuse existing WebPageProxy quota handler for NetworkProcessProxy quota requests
https://bugs.webkit.org/show_bug.cgi?id=197463
<rdar://problem/47403621>

Reviewed by Alex Christensen.

Source/WebKit:

Add a getter to know whether websitedatastore client implements the quota delegate.
If not, find the most visible page that is the same origin as the quota request
and reuse the existing exceededDatabasQuota delegate.
This approach allows to call the delegate even if the quota request comes from a service worker.
If no such page is found, the quota will not be increased.

Refactoring to make sure we are calling the delegate once a previous call to that delegate is completed.
Covered by API test.

  • UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
  • UIProcess/Network/NetworkProcessProxy.cpp:

(WebKit::NetworkProcessProxy::requestStorageSpace):

  • UIProcess/WebPageProxy.cpp:

(WebKit::StorageRequests::add):
(WebKit::StorageRequests::processNext):
(WebKit::StorageRequests::areBeingProcessed const):
(WebKit::StorageRequests::setAreBeingProcessed):
(WebKit::StorageRequests::StorageRequests):
(WebKit::StorageRequests::~StorageRequests):
(WebKit::StorageRequests::singleton):
(WebKit::WebPageProxy::forMostVisibleWebPageIfAny):
(WebKit::WebPageProxy::didChangeMainDocument):
(WebKit::WebPageProxy::exceededDatabaseQuota):
(WebKit::WebPageProxy::requestStorageSpace):
(WebKit::WebPageProxy::makeStorageSpaceRequest):

  • UIProcess/WebPageProxy.h:
  • UIProcess/WebProcessProxy.cpp:

(WebKit::WebProcessProxy::forWebPages):

  • UIProcess/WebProcessProxy.h:
  • UIProcess/WebsiteData/WebsiteDataStoreClient.h:

(WebKit::WebsiteDataStoreClient::implementsRequestStorageSpaceHandler const):

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/StorageQuota.mm: Added.

(-[QuotaDelegate init]):
(-[QuotaDelegate _webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:]):
(-[QuotaDelegate quotaDelegateCalled]):
(-[QuotaDelegate grantQuota]):
(-[StorageSchemes webView:startURLSchemeTask:]):
(-[StorageSchemes webView:stopURLSchemeTask:]):
(-[QuotaMessageHandler userContentController:didReceiveScriptMessage:]):
(doTest):

Location:
trunk
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r245327 r245328  
     12019-05-15  Youenn Fablet  <youenn@apple.com>
     2
     3        Reuse existing WebPageProxy quota handler for NetworkProcessProxy quota requests
     4        https://bugs.webkit.org/show_bug.cgi?id=197463
     5        <rdar://problem/47403621>
     6
     7        Reviewed by Alex Christensen.
     8
     9        Add a getter to know whether websitedatastore client implements the quota delegate.
     10        If not, find the most visible page that is the same origin as the quota request
     11        and reuse the existing exceededDatabasQuota delegate.
     12        This approach allows to call the delegate even if the quota request comes from a service worker.
     13        If no such page is found, the quota will not be increased.
     14
     15        Refactoring to make sure we are calling the delegate once a previous call to that delegate is completed.
     16        Covered by API test.
     17
     18        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
     19        * UIProcess/Network/NetworkProcessProxy.cpp:
     20        (WebKit::NetworkProcessProxy::requestStorageSpace):
     21        * UIProcess/WebPageProxy.cpp:
     22        (WebKit::StorageRequests::add):
     23        (WebKit::StorageRequests::processNext):
     24        (WebKit::StorageRequests::areBeingProcessed const):
     25        (WebKit::StorageRequests::setAreBeingProcessed):
     26        (WebKit::StorageRequests::StorageRequests):
     27        (WebKit::StorageRequests::~StorageRequests):
     28        (WebKit::StorageRequests::singleton):
     29        (WebKit::WebPageProxy::forMostVisibleWebPageIfAny):
     30        (WebKit::WebPageProxy::didChangeMainDocument):
     31        (WebKit::WebPageProxy::exceededDatabaseQuota):
     32        (WebKit::WebPageProxy::requestStorageSpace):
     33        (WebKit::WebPageProxy::makeStorageSpaceRequest):
     34        * UIProcess/WebPageProxy.h:
     35        * UIProcess/WebProcessProxy.cpp:
     36        (WebKit::WebProcessProxy::forWebPages):
     37        * UIProcess/WebProcessProxy.h:
     38        * UIProcess/WebsiteData/WebsiteDataStoreClient.h:
     39        (WebKit::WebsiteDataStoreClient::implementsRequestStorageSpaceHandler const):
     40
    1412019-05-15  Youenn Fablet  <youenn@apple.com>
    242
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm

    r244572 r245328  
    4444#import <wtf/WeakObjCPtr.h>
    4545
    46 class WebsiteDataStoreClient : public WebKit::WebsiteDataStoreClient {
     46class WebsiteDataStoreClient final : public WebKit::WebsiteDataStoreClient {
    4747public:
    4848    explicit WebsiteDataStoreClient(id <_WKWebsiteDataStoreDelegate> delegate)
  • trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp

    r245025 r245328  
    11421142#endif
    11431143
    1144 void NetworkProcessProxy::requestStorageSpace(PAL::SessionID sessionID, const WebCore::ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&& completionHandler)
     1144void NetworkProcessProxy::requestStorageSpace(PAL::SessionID sessionID, const WebCore::ClientOrigin& origin, uint64_t currentQuota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&& completionHandler)
    11451145{
    11461146    auto* store = websiteDataStoreFromSessionID(sessionID);
     
    11511151    }
    11521152
    1153     store->client().requestStorageSpace(origin.topOrigin, origin.clientOrigin, quota, currentSize, spaceRequired, WTFMove(completionHandler));
     1153    store->client().requestStorageSpace(origin.topOrigin, origin.clientOrigin, currentQuota, currentSize, spaceRequired, [sessionID, origin, currentQuota, currentSize, spaceRequired, completionHandler = WTFMove(completionHandler)](auto quota) mutable {
     1154        if (quota) {
     1155            completionHandler(quota);
     1156            return;
     1157        }
     1158
     1159        if (origin.topOrigin != origin.clientOrigin) {
     1160            completionHandler({ });
     1161            return;
     1162        }
     1163
     1164        WebPageProxy::forMostVisibleWebPageIfAny(sessionID, origin.topOrigin, [completionHandler = WTFMove(completionHandler), origin, currentQuota, currentSize, spaceRequired](auto* page) mutable {
     1165            if (!page) {
     1166                completionHandler({ });
     1167                return;
     1168            }
     1169            String name = makeString(FileSystem::encodeForFileName(origin.topOrigin.host), " content");
     1170            page->requestStorageSpace(page->mainFrame()->frameID(), origin.topOrigin.databaseIdentifier(), name, name, currentQuota, currentSize, currentSize, spaceRequired, [completionHandler = WTFMove(completionHandler)](auto quota) mutable {
     1171                completionHandler(quota);
     1172            });
     1173        });
     1174    });
    11541175}
    11551176
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r245255 r245328  
    265265DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
    266266
    267 class ExceededDatabaseQuotaRecords {
    268     WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
    269     friend NeverDestroyed<ExceededDatabaseQuotaRecords>;
     267class StorageRequests {
     268    WTF_MAKE_NONCOPYABLE(StorageRequests); WTF_MAKE_FAST_ALLOCATED;
     269    friend NeverDestroyed<StorageRequests>;
    270270public:
    271     struct Record {
    272         uint64_t frameID;
    273         String originIdentifier;
    274         String databaseName;
    275         String displayName;
    276         uint64_t currentQuota;
    277         uint64_t currentOriginUsage;
    278         uint64_t currentDatabaseUsage;
    279         uint64_t expectedUsage;
    280         Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply reply;
    281     };
    282 
    283     static ExceededDatabaseQuotaRecords& singleton();
    284 
    285     std::unique_ptr<Record> createRecord(uint64_t frameID, String originIdentifier,
    286         String databaseName, String displayName, uint64_t currentQuota,
    287         uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage,
    288         Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply&&);
    289 
    290     void add(std::unique_ptr<Record>);
    291     bool areBeingProcessed() const { return !!m_currentRecord; }
    292     Record* next();
     271    static StorageRequests& singleton();
     272
     273    void processOrAppend(CompletionHandler<void()>&& completionHandler)
     274    {
     275        if (m_requestsAreBeingProcessed) {
     276            m_requests.append(WTFMove(completionHandler));
     277            return;
     278        }
     279        m_requestsAreBeingProcessed = true;
     280        completionHandler();
     281    }
     282
     283    void processNextIfAny()
     284    {
     285        if (m_requests.isEmpty()) {
     286            m_requestsAreBeingProcessed = false;
     287            return;
     288        }
     289        m_requests.takeFirst()();
     290    }
    293291
    294292private:
    295     ExceededDatabaseQuotaRecords() { }
    296     ~ExceededDatabaseQuotaRecords() { }
    297 
    298     Deque<std::unique_ptr<Record>> m_records;
    299     std::unique_ptr<Record> m_currentRecord;
     293    StorageRequests() { }
     294    ~StorageRequests() { }
     295
     296    Deque<CompletionHandler<void()>> m_requests;
     297    bool m_requestsAreBeingProcessed { false };
    300298};
    301299
    302 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::singleton()
    303 {
    304     static NeverDestroyed<ExceededDatabaseQuotaRecords> records;
    305     return records;
    306 }
    307 
    308 std::unique_ptr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
    309     uint64_t frameID, String originIdentifier, String databaseName, String displayName,
    310     uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
    311     uint64_t expectedUsage, Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply&& reply)
    312 {
    313     auto record = std::make_unique<Record>();
    314     record->frameID = frameID;
    315     record->originIdentifier = originIdentifier;
    316     record->databaseName = databaseName;
    317     record->displayName = displayName;
    318     record->currentQuota = currentQuota;
    319     record->currentOriginUsage = currentOriginUsage;
    320     record->currentDatabaseUsage = currentDatabaseUsage;
    321     record->expectedUsage = expectedUsage;
    322     record->reply = WTFMove(reply);
    323     return record;
    324 }
    325 
    326 void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record)
    327 {
    328     m_records.append(WTFMove(record));
    329 }
    330 
    331 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
    332 {
    333     m_currentRecord = nullptr;
    334     if (!m_records.isEmpty())
    335         m_currentRecord = m_records.takeFirst();
    336     return m_currentRecord.get();
     300StorageRequests& StorageRequests::singleton()
     301{
     302    static NeverDestroyed<StorageRequests> requests;
     303    return requests;
    337304}
    338305
     
    395362    WeakPtr<PageClient> m_pageClient;
    396363};
     364
     365void WebPageProxy::forMostVisibleWebPageIfAny(PAL::SessionID sessionID, const SecurityOriginData& origin, CompletionHandler<void(WebPageProxy*)>&& completionHandler)
     366{
     367    // FIXME: If not finding right away a visible page, we might want to try again for a given period of time when there is a change of visibility.
     368    WebPageProxy* selectedPage = nullptr;
     369    WebProcessProxy::forWebPagesWithOrigin(sessionID, origin, [&](auto& page) {
     370        if (!page.mainFrame())
     371            return;
     372        if (page.isViewVisible() && (!selectedPage || !selectedPage->isViewVisible())) {
     373            selectedPage = &page;
     374            return;
     375        }
     376        if (page.isViewFocused() && (!selectedPage || !selectedPage->isViewFocused())) {
     377            selectedPage = &page;
     378            return;
     379        }
     380    });
     381    completionHandler(selectedPage);
     382}
    397383
    398384Ref<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, Ref<API::PageConfiguration>&& configuration)
     
    44164402    UNUSED_PARAM(frameID);
    44174403#endif
     4404    m_isQuotaIncreaseDenied = false;
    44184405}
    44194406
     
    72647251void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply&& reply)
    72657252{
    7266     ExceededDatabaseQuotaRecords& records = ExceededDatabaseQuotaRecords::singleton();
    7267     std::unique_ptr<ExceededDatabaseQuotaRecords::Record> newRecord = records.createRecord(frameID,
    7268         originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage,
    7269         currentDatabaseUsage, expectedUsage, WTFMove(reply));
    7270     records.add(WTFMove(newRecord));
    7271 
    7272     if (records.areBeingProcessed())
    7273         return;
    7274 
    7275     ExceededDatabaseQuotaRecords::Record* record = records.next();
    7276     while (record) {
    7277         WebFrameProxy* frame = m_process->webFrame(record->frameID);
    7278         MESSAGE_CHECK(m_process, frame);
    7279 
    7280         auto origin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(record->originIdentifier)->securityOrigin());
    7281         m_uiClient->exceededDatabaseQuota(this, frame, origin.ptr(), record->databaseName, record->displayName, record->currentQuota, record->currentOriginUsage, record->currentDatabaseUsage, record->expectedUsage, WTFMove(record->reply));
    7282         record = records.next();
    7283     }
     7253    requestStorageSpace(frameID, originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, [reply = WTFMove(reply)](auto quota) mutable {
     7254        reply(quota);
     7255    });
     7256}
     7257
     7258void WebPageProxy::requestStorageSpace(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, CompletionHandler<void(uint64_t)>&& completionHandler)
     7259{
     7260    StorageRequests::singleton().processOrAppend([this, protectedThis = makeRef(*this), pageURL = currentURL(), frameID, originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, completionHandler = WTFMove(completionHandler)]() mutable {
     7261        this->makeStorageSpaceRequest(frameID, originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, [this, protectedThis = WTFMove(protectedThis), pageURL = WTFMove(pageURL), completionHandler = WTFMove(completionHandler), currentQuota](auto quota) mutable {
     7262            if (quota <= currentQuota && this->currentURL() == pageURL)
     7263                m_isQuotaIncreaseDenied =  true;
     7264            completionHandler(quota);
     7265            StorageRequests::singleton().processNextIfAny();
     7266        });
     7267    });
     7268}
     7269
     7270void WebPageProxy::makeStorageSpaceRequest(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, CompletionHandler<void(uint64_t)>&& completionHandler)
     7271{
     7272    if (m_isQuotaIncreaseDenied) {
     7273        completionHandler(currentQuota);
     7274        return;
     7275    }
     7276
     7277    WebFrameProxy* frame = m_process->webFrame(frameID);
     7278    MESSAGE_CHECK(m_process, frame);
     7279
     7280    auto originData = SecurityOriginData::fromDatabaseIdentifier(originIdentifier);
     7281    if (originData != SecurityOriginData::fromURL(URL { { }, currentURL() })) {
     7282        completionHandler(currentQuota);
     7283        return;
     7284    }
     7285
     7286    auto origin = API::SecurityOrigin::create(originData->securityOrigin());
     7287    m_uiClient->exceededDatabaseQuota(this, frame, origin.ptr(), databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, WTFMove(completionHandler));
    72847288}
    72857289
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r245243 r245328  
    386386    virtual ~WebPageProxy();
    387387
     388    static void forMostVisibleWebPageIfAny(PAL::SessionID, const WebCore::SecurityOriginData&, CompletionHandler<void(WebPageProxy*)>&&);
     389
    388390    const API::PageConfiguration& configuration() const;
    389391
     
    15431545    void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override;
    15441546
     1547    void requestStorageSpace(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, WTF::CompletionHandler<void(uint64_t)>&&);
     1548
    15451549private:
    15461550    WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&);
     
    20772081#endif
    20782082
     2083    void makeStorageSpaceRequest(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, CompletionHandler<void(uint64_t)>&&);
     2084
    20792085    WeakPtr<PageClient> m_pageClient;
    20802086    Ref<API::PageConfiguration> m_configuration;
     
    25062512    Optional<SpeechSynthesisData> m_speechSynthesisData;
    25072513#endif
     2514    bool m_isQuotaIncreaseDenied { false };
    25082515};
    25092516
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp

    r245301 r245328  
    124124}
    125125
     126void WebProcessProxy::forWebPagesWithOrigin(PAL::SessionID sessionID, const SecurityOriginData& origin, const Function<void(WebPageProxy&)>& callback)
     127{
     128    for (auto* page : globalPageMap().values()) {
     129        if (page->sessionID() != sessionID || SecurityOriginData::fromURL(URL { { }, page->currentURL() }) != origin)
     130            continue;
     131        callback(*page);
     132    }
     133}
     134
    126135Ref<WebProcessProxy> WebProcessProxy::create(WebProcessPool& processPool, WebsiteDataStore* websiteDataStore, IsPrewarmed isPrewarmed, ShouldLaunchProcess shouldLaunchProcess)
    127136{
  • trunk/Source/WebKit/UIProcess/WebProcessProxy.h

    r245255 r245328  
    111111    ~WebProcessProxy();
    112112
     113    static void forWebPagesWithOrigin(PAL::SessionID, const WebCore::SecurityOriginData&, const Function<void(WebPageProxy&)>&);
     114
    113115    WebConnection* webConnection() const { return m_webConnection.get(); }
    114116
  • trunk/Tools/ChangeLog

    r245327 r245328  
     12019-05-15  Youenn Fablet  <youenn@apple.com>
     2
     3        Reuse existing WebPageProxy quota handler for NetworkProcessProxy quota requests
     4        https://bugs.webkit.org/show_bug.cgi?id=197463
     5        <rdar://problem/47403621>
     6
     7        Reviewed by Alex Christensen.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/StorageQuota.mm: Added.
     10        (-[QuotaDelegate init]):
     11        (-[QuotaDelegate _webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:]):
     12        (-[QuotaDelegate quotaDelegateCalled]):
     13        (-[QuotaDelegate grantQuota]):
     14        (-[StorageSchemes webView:startURLSchemeTask:]):
     15        (-[StorageSchemes webView:stopURLSchemeTask:]):
     16        (-[QuotaMessageHandler userContentController:didReceiveScriptMessage:]):
     17        (doTest):
     18
    1192019-05-15  Youenn Fablet  <youenn@apple.com>
    220
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r245214 r245328  
    181181                4135FB842011FAA700332139 /* InjectInternals_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4135FB832011FAA300332139 /* InjectInternals_Bundle.cpp */; };
    182182                4135FB852011FABF00332139 /* libWebCoreTestSupport.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4135FB862011FABF00332139 /* libWebCoreTestSupport.dylib */; };
     183                414AD6862285D1C000777F2D /* StorageQuota.mm in Sources */ = {isa = PBXBuildFile; fileRef = 414AD6852285D1B000777F2D /* StorageQuota.mm */; };
    183184                41882F0321010C0D002FF288 /* ProcessPreWarming.mm in Sources */ = {isa = PBXBuildFile; fileRef = 41882F0221010A70002FF288 /* ProcessPreWarming.mm */; };
    184185                4433A396208044140091ED57 /* SynchronousTimeoutTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4433A395208044130091ED57 /* SynchronousTimeoutTests.mm */; };
     
    15801581                4135FB832011FAA300332139 /* InjectInternals_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InjectInternals_Bundle.cpp; path = Tests/InjectInternals_Bundle.cpp; sourceTree = SOURCE_ROOT; };
    15811582                4135FB862011FABF00332139 /* libWebCoreTestSupport.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; path = libWebCoreTestSupport.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
     1583                414AD6852285D1B000777F2D /* StorageQuota.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = StorageQuota.mm; sourceTree = "<group>"; };
    15821584                41882F0221010A70002FF288 /* ProcessPreWarming.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ProcessPreWarming.mm; sourceTree = "<group>"; };
    15831585                41973B5C1AF22875006C7B36 /* SharedBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedBuffer.cpp; sourceTree = "<group>"; };
     
    26892691                                2DFF7B6C1DA487AF00814614 /* SnapshotStore.mm */,
    26902692                                CDC0932D21C993440030C4B0 /* StopSuspendResumeAllMedia.mm */,
     2693                                414AD6852285D1B000777F2D /* StorageQuota.mm */,
    26912694                                515BE1701D428BD100DD7C68 /* StoreBlobThenDelete.mm */,
    26922695                                1C734B5220788C4800F430EA /* SystemColors.mm */,
     
    43704373                                7CCE7ECF1A411A7E00447C4C /* StopLoadingFromDidReceiveResponse.mm in Sources */,
    43714374                                CDC0932E21C993440030C4B0 /* StopSuspendResumeAllMedia.mm in Sources */,
     4375                                414AD6862285D1C000777F2D /* StorageQuota.mm in Sources */,
    43724376                                515BE1711D428E4B00DD7C68 /* StoreBlobThenDelete.mm in Sources */,
    43734377                                7CCE7ED01A411A7E00447C4C /* StringByEvaluatingJavaScriptFromString.mm in Sources */,
Note: See TracChangeset for help on using the changeset viewer.