void NetworkProcess::createNetworkConnectionToWebProcess() { #if USE(UNIX_DOMAIN_SOCKETS) IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection(); RefPtr<NetworkConnectionToWebProcess> connection = NetworkConnectionToWebProcess::create(socketPair.server); m_webProcessConnections.append(connection.release()); IPC::Attachment clientSocket(socketPair.client); parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0); #elif OS(DARWIN) // Create the listening port. mach_port_t listeningPort; mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort); // Create a listening connection. RefPtr<NetworkConnectionToWebProcess> connection = NetworkConnectionToWebProcess::create(IPC::Connection::Identifier(listeningPort)); m_webProcessConnections.append(connection.release()); IPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND); parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientPort), 0); #else notImplemented(); #endif }
void WebProcess::removeWebFrame(uint64_t frameID) { m_frameMap.remove(frameID); // We can end up here after our connection has closed when WebCore's frame life-support timer // fires when the application is shutting down. There's no need (and no way) to update the UI // process in this case. if (!parentProcessConnection()) return; parentProcessConnection()->send(Messages::WebProcessProxy::DidDestroyFrame(frameID), 0); }
void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) { #if ENABLE(NETSCAPE_PLUGIN_API) for (size_t i = 0; i < pluginPaths.size(); ++i) { RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]); if (!netscapePluginModule) continue; if (sites.isEmpty()) { // Clear everything. netscapePluginModule->clearSiteData(String(), flags, maxAgeInSeconds); continue; } for (size_t i = 0; i < sites.size(); ++i) netscapePluginModule->clearSiteData(sites[i], flags, maxAgeInSeconds); } #else UNUSED_PARAM(pluginPaths); UNUSED_PARAM(sites); UNUSED_PARAM(flags); UNUSED_PARAM(maxAgeInSeconds); #endif parentProcessConnection()->send(Messages::WebProcessProxy::DidClearPluginSiteData(callbackID), 0); }
void NetworkProcess::logDiagnosticMessageWithResult(uint64_t webPageID, const String& message, const String& description, WebCore::DiagnosticLoggingResultType result, WebCore::ShouldSample shouldSample) { if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample)) return; parentProcessConnection()->send(Messages::NetworkProcessProxy::LogSampledDiagnosticMessageWithResult(webPageID, message, description, result), 0); }
void WebProcess::plugInDidReceiveUserInteraction(const String& pageOrigin, const String& pluginOrigin, const String& mimeType, SessionID sessionID) { if (pageOrigin.isEmpty()) return; unsigned plugInOriginHash = hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType); if (!plugInOriginHash) return; HashMap<WebCore::SessionID, HashMap<unsigned, double>>::const_iterator sessionIterator = m_plugInAutoStartOriginHashes.find(sessionID); HashMap<unsigned, double>::const_iterator it; bool contains = false; if (sessionIterator != m_plugInAutoStartOriginHashes.end()) { it = sessionIterator->value.find(plugInOriginHash); contains = it != sessionIterator->value.end(); } if (!contains) { sessionIterator = m_plugInAutoStartOriginHashes.find(SessionID::defaultSessionID()); it = sessionIterator->value.find(plugInOriginHash); if (it == sessionIterator->value.end()) return; } if (it->value - currentTime() > plugInAutoStartExpirationTimeUpdateThreshold) return; parentProcessConnection()->send(Messages::WebProcessPool::PlugInDidReceiveUserInteraction(plugInOriginHash, sessionID), 0); }
void WebProcess::ensureNetworkProcessConnection() { if (!m_usesNetworkProcess) return; if (m_networkProcessConnection) return; IPC::Attachment encodedConnectionIdentifier; if (!parentProcessConnection()->sendSync(Messages::WebProcessProxy::GetNetworkProcessConnection(), Messages::WebProcessProxy::GetNetworkProcessConnection::Reply(encodedConnectionIdentifier), 0)) return; #if OS(DARWIN) IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port()); #elif USE(UNIX_DOMAIN_SOCKETS) IPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.releaseFileDescriptor(); #else ASSERT_NOT_REACHED(); #endif if (IPC::Connection::identifierIsNull(connectionIdentifier)) return; m_networkProcessConnection = NetworkProcessConnection::create(connectionIdentifier); }
void DatabaseProcess::deleteWebsiteData(WebCore::SessionID, uint64_t websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID) { struct CallbackAggregator final : public ThreadSafeRefCounted<CallbackAggregator> { explicit CallbackAggregator(std::function<void ()> completionHandler) : m_completionHandler(WTFMove(completionHandler)) { } ~CallbackAggregator() { ASSERT(RunLoop::isMain()); RunLoop::main().dispatch(WTFMove(m_completionHandler)); } std::function<void ()> m_completionHandler; }; RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator([this, callbackID]() { parentProcessConnection()->send(Messages::DatabaseProcessProxy::DidDeleteWebsiteData(callbackID), 0); })); #if ENABLE(INDEXED_DATABASE) if (websiteDataTypes & WebsiteDataTypeIndexedDBDatabases) { postDatabaseTask(std::make_unique<CrossThreadTask>([this, callbackAggregator, modifiedSince] { deleteIndexedDatabaseEntriesModifiedSince(modifiedSince); RunLoop::main().dispatch([callbackAggregator] { }); })); } #endif }
void NetworkProcess::deleteWebsiteData(SessionID sessionID, uint64_t websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID) { #if PLATFORM(COCOA) if (websiteDataTypes & WebsiteDataTypeHSTSCache) { if (auto* networkStorageSession = SessionTracker::storageSession(sessionID)) clearHSTSCache(*networkStorageSession, modifiedSince); } #endif if (websiteDataTypes & WebsiteDataTypeCookies) { if (auto* networkStorageSession = SessionTracker::storageSession(sessionID)) deleteAllCookiesModifiedSince(*networkStorageSession, modifiedSince); } auto completionHandler = [this, callbackID] { parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteData(callbackID), 0); }; if ((websiteDataTypes & WebsiteDataTypeDiskCache) && !sessionID.isEphemeral()) { clearDiskCache(modifiedSince, WTFMove(completionHandler)); return; } completionHandler(); }
void NetworkProcess::logDiagnosticMessageWithValue(uint64_t webPageID, const String& message, const String& description, const String& value, ShouldSample shouldSample) { if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample)) return; parentProcessConnection()->send(Messages::NetworkProcessProxy::LogSampledDiagnosticMessageWithValue(webPageID, message, description, value), 0); }
void NetworkProcess::grantSandboxExtensionsToDatabaseProcessForBlobs(const Vector<String>& filenames, std::function<void ()> completionHandler) { static uint64_t lastRequestID; uint64_t requestID = ++lastRequestID; m_sandboxExtensionForBlobsCompletionHandlers.set(requestID, completionHandler); parentProcessConnection()->send(Messages::NetworkProcessProxy::GrantSandboxExtensionsToDatabaseProcessForBlobs(requestID, filenames), 0); }
void WebProcess::processSuspensionCleanupTimerFired() { if (!markAllLayersVolatileIfPossible()) return; m_processSuspensionCleanupTimer.stop(); if (m_shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) parentProcessConnection()->send(Messages::WebProcessProxy::ProcessReadyToSuspend(), 0); }
void PluginProcess::getSitesWithData(uint64_t callbackID) { Vector<String> sites; if (NetscapePluginModule* module = netscapePluginModule()) sites = module->sitesWithData(); parentProcessConnection()->send(Messages::PluginProcessProxy::DidGetSitesWithData(sites, callbackID), 0); }
void PluginProcess::createWebProcessConnection() { bool didHaveAnyWebProcessConnections = !m_webProcessConnections.isEmpty(); #if OS(DARWIN) // Create the listening port. mach_port_t listeningPort; mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort); // Create a listening connection. RefPtr<WebProcessConnection> connection = WebProcessConnection::create(IPC::Connection::Identifier(listeningPort)); if (m_audioHardwareListener) { if (m_audioHardwareListener->hardwareActivity() == WebCore::AudioHardwareActivityType::IsActive) connection->audioHardwareDidBecomeActive(); else if (m_audioHardwareListener->hardwareActivity() == WebCore::AudioHardwareActivityType::IsInactive) connection->audioHardwareDidBecomeInactive(); } m_webProcessConnections.append(connection.release()); IPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND); parentProcessConnection()->send(Messages::PluginProcessProxy::DidCreateWebProcessConnection(clientPort, m_supportsAsynchronousPluginInitialization), 0); #elif USE(UNIX_DOMAIN_SOCKETS) IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection(); RefPtr<WebProcessConnection> connection = WebProcessConnection::create(socketPair.server); m_webProcessConnections.append(connection.release()); IPC::Attachment clientSocket(socketPair.client); parentProcessConnection()->send(Messages::PluginProcessProxy::DidCreateWebProcessConnection(clientSocket, m_supportsAsynchronousPluginInitialization), 0); #else notImplemented(); #endif if (NetscapePluginModule* module = netscapePluginModule()) { if (!didHaveAnyWebProcessConnections) { // Increment the load count. This is matched by a call to decrementLoadCount in removeWebProcessConnection. // We do this so that the plug-in module's NP_Shutdown won't be called until right before exiting. module->incrementLoadCount(); } } disableTermination(); }
void PluginProcess::deleteWebsiteDataForHostNames(const Vector<String>& hostNames, uint64_t callbackID) { if (auto* module = netscapePluginModule()) { for (auto& hostName : hostNames) module->clearSiteData(hostName, NP_CLEAR_ALL, std::numeric_limits<uint64_t>::max()); } parentProcessConnection()->send(Messages::PluginProcessProxy::DidDeleteWebsiteDataForHostNames(callbackID), 0); }
void WebProcess::addPlugInAutoStartOrigin(const String& pageOrigin, unsigned plugInOriginHash) { if (isPlugInAutoStartOrigin(plugInOriginHash)) { LOG(Plugins, "Hash %x already exists as auto-start origin (request for %s)", plugInOriginHash, pageOrigin.utf8().data()); return; } parentProcessConnection()->send(Messages::WebContext::AddPlugInAutoStartOriginHash(pageOrigin, plugInOriginHash), 0); }
void NetworkProcess::getNetworkProcessStatistics(uint64_t callbackID) { StatisticsData data; auto& networkProcess = NetworkProcess::singleton(); data.statisticsNumbers.set("DownloadsActiveCount", networkProcess.downloadManager().activeDownloadCount()); data.statisticsNumbers.set("OutstandingAuthenticationChallengesCount", networkProcess.authenticationManager().outstandingAuthenticationChallengeCount()); parentProcessConnection()->send(Messages::WebProcessPool::DidGetStatistics(data, callbackID), 0); }
void WebProcess::fetchWebsiteData(WebCore::SessionID sessionID, uint64_t websiteDataTypes, uint64_t callbackID) { WebsiteData websiteData; if (websiteDataTypes & WebsiteDataTypeMemoryCache) { for (auto& origin : MemoryCache::singleton().originsWithCache(sessionID)) websiteData.entries.append(WebsiteData::Entry { origin, WebsiteDataTypeMemoryCache }); } parentProcessConnection()->send(Messages::WebProcessProxy::DidFetchWebsiteData(callbackID, websiteData), 0); }
void WebProcess::deleteWebsiteDataForOrigins(WebCore::SessionID sessionID, uint64_t websiteDataTypes, const Vector<WebKit::SecurityOriginData>& originDatas, uint64_t callbackID) { if (websiteDataTypes & WebsiteDataTypeMemoryCache) { HashSet<RefPtr<SecurityOrigin>> origins; for (auto& originData : originDatas) origins.add(originData.securityOrigin()); MemoryCache::singleton().removeResourcesWithOrigins(sessionID, origins); } parentProcessConnection()->send(Messages::WebProcessProxy::DidDeleteWebsiteDataForOrigins(callbackID), 0); }
void WebProcess::cancelPrepareToSuspend() { setAllLayerTreeStatesFrozen(false); // If we've already finished cleaning up and sent ProcessReadyToSuspend, we // shouldn't send DidCancelProcessSuspension; the UI process strictly expects one or the other. if (!m_processSuspensionCleanupTimer.isActive()) return; m_processSuspensionCleanupTimer.stop(); parentProcessConnection()->send(Messages::WebProcessProxy::DidCancelProcessSuspension(), 0); }
void WebProcess::actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shouldAcknowledgeWhenReadyToSuspend) { MemoryPressureHandler::singleton().releaseMemory(Critical::Yes, Synchronous::Yes); setAllLayerTreeStatesFrozen(true); if (markAllLayersVolatileIfPossible()) { if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) parentProcessConnection()->send(Messages::WebProcessProxy::ProcessReadyToSuspend(), 0); return; } m_shouldAcknowledgeWhenReadyToSuspend = shouldAcknowledgeWhenReadyToSuspend; m_processSuspensionCleanupTimer.startRepeating(std::chrono::milliseconds(20)); }
bool WebProcess::shouldTerminate() { ASSERT(m_pageMap.isEmpty()); ASSERT(usesNetworkProcess() || !downloadManager().isDownloading()); // FIXME: the ShouldTerminate message should also send termination parameters, such as any session cookies that need to be preserved. bool shouldTerminate = false; if (parentProcessConnection()->sendSync(Messages::WebProcessProxy::ShouldTerminate(), Messages::WebProcessProxy::ShouldTerminate::Reply(shouldTerminate), 0) && !shouldTerminate) return false; return true; }
void WebProcess::plugInDidReceiveUserInteraction(unsigned plugInOriginHash) { if (!plugInOriginHash) return; HashMap<unsigned, double>::iterator it = m_plugInAutoStartOrigins.find(plugInOriginHash); if (it == m_plugInAutoStartOrigins.end()) return; if (it->value - currentTime() > plugInAutoStartExpirationTimeUpdateThreshold) return; parentProcessConnection()->send(Messages::WebContext::PlugInDidReceiveUserInteraction(plugInOriginHash), 0); }
void WebProcess::deleteWebsiteData(SessionID sessionID, uint64_t websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID) { UNUSED_PARAM(modifiedSince); if (websiteDataTypes & WebsiteDataTypeMemoryCache) { PageCache::singleton().pruneToSizeNow(0, PruningReason::None); MemoryCache::singleton().evictResources(sessionID); CrossOriginPreflightResultCache::singleton().empty(); } parentProcessConnection()->send(Messages::WebProcessProxy::DidDeleteWebsiteData(callbackID), 0); }
void PluginProcess::clearSiteData(const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) { if (NetscapePluginModule* module = netscapePluginModule()) { if (sites.isEmpty()) { // Clear everything. module->clearSiteData(String(), flags, maxAgeInSeconds); } else { for (size_t i = 0; i < sites.size(); ++i) module->clearSiteData(sites[i], flags, maxAgeInSeconds); } } parentProcessConnection()->send(Messages::PluginProcessProxy::DidClearSiteData(callbackID), 0); }
void PluginProcess::deleteWebsiteData(std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID) { if (auto* module = netscapePluginModule()) { auto currentTime = std::chrono::system_clock::now(); if (currentTime > modifiedSince) { uint64_t maximumAge = std::chrono::duration_cast<std::chrono::seconds>(currentTime - modifiedSince).count(); module->clearSiteData(String(), NP_CLEAR_ALL, maximumAge); } } parentProcessConnection()->send(Messages::PluginProcessProxy::DidDeleteWebsiteData(callbackID), 0); }
void NetworkProcess::getNetworkProcessStatistics(uint64_t callbackID) { NetworkResourceLoadScheduler& scheduler = NetworkProcess::shared().networkResourceLoadScheduler(); StatisticsData data; data.statisticsNumbers.set("HostsPendingCount", scheduler.hostsPendingCount()); data.statisticsNumbers.set("HostsActiveCount", scheduler.hostsActiveCount()); data.statisticsNumbers.set("LoadsPendingCount", scheduler.loadsPendingCount()); data.statisticsNumbers.set("LoadsActiveCount", scheduler.loadsActiveCount()); data.statisticsNumbers.set("DownloadsActiveCount", shared().downloadManager().activeDownloadCount()); data.statisticsNumbers.set("OutstandingAuthenticationChallengesCount", shared().authenticationManager().outstandingAuthenticationChallengeCount()); parentProcessConnection()->send(Messages::WebContext::DidGetStatistics(data, callbackID), 0); }
void WebProcess::getWebCoreStatistics(uint64_t callbackID) { StatisticsData data; // Gather JavaScript statistics. { JSLockHolder lock(JSDOMWindow::commonVM()); data.statisticsNumbers.set(ASCIILiteral("JavaScriptObjectsCount"), JSDOMWindow::commonVM().heap.objectCount()); data.statisticsNumbers.set(ASCIILiteral("JavaScriptGlobalObjectsCount"), JSDOMWindow::commonVM().heap.globalObjectCount()); data.statisticsNumbers.set(ASCIILiteral("JavaScriptProtectedObjectsCount"), JSDOMWindow::commonVM().heap.protectedObjectCount()); data.statisticsNumbers.set(ASCIILiteral("JavaScriptProtectedGlobalObjectsCount"), JSDOMWindow::commonVM().heap.protectedGlobalObjectCount()); std::unique_ptr<TypeCountSet> protectedObjectTypeCounts(JSDOMWindow::commonVM().heap.protectedObjectTypeCounts()); fromCountedSetToHashMap(protectedObjectTypeCounts.get(), data.javaScriptProtectedObjectTypeCounts); std::unique_ptr<TypeCountSet> objectTypeCounts(JSDOMWindow::commonVM().heap.objectTypeCounts()); fromCountedSetToHashMap(objectTypeCounts.get(), data.javaScriptObjectTypeCounts); uint64_t javaScriptHeapSize = JSDOMWindow::commonVM().heap.size(); data.statisticsNumbers.set(ASCIILiteral("JavaScriptHeapSize"), javaScriptHeapSize); data.statisticsNumbers.set(ASCIILiteral("JavaScriptFreeSize"), JSDOMWindow::commonVM().heap.capacity() - javaScriptHeapSize); } WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics(); data.statisticsNumbers.set(ASCIILiteral("FastMallocReservedVMBytes"), fastMallocStatistics.reservedVMBytes); data.statisticsNumbers.set(ASCIILiteral("FastMallocCommittedVMBytes"), fastMallocStatistics.committedVMBytes); data.statisticsNumbers.set(ASCIILiteral("FastMallocFreeListBytes"), fastMallocStatistics.freeListBytes); // Gather icon statistics. data.statisticsNumbers.set(ASCIILiteral("IconPageURLMappingCount"), iconDatabase().pageURLMappingCount()); data.statisticsNumbers.set(ASCIILiteral("IconRetainedPageURLCount"), iconDatabase().retainedPageURLCount()); data.statisticsNumbers.set(ASCIILiteral("IconRecordCount"), iconDatabase().iconRecordCount()); data.statisticsNumbers.set(ASCIILiteral("IconsWithDataCount"), iconDatabase().iconRecordCountWithData()); // Gather font statistics. auto& fontCache = FontCache::singleton(); data.statisticsNumbers.set(ASCIILiteral("CachedFontDataCount"), fontCache.fontCount()); data.statisticsNumbers.set(ASCIILiteral("CachedFontDataInactiveCount"), fontCache.inactiveFontCount()); // Gather glyph page statistics. data.statisticsNumbers.set(ASCIILiteral("GlyphPageCount"), GlyphPage::count()); // Get WebCore memory cache statistics getWebCoreMemoryCacheStatistics(data.webCoreCacheStatistics); parentProcessConnection()->send(Messages::WebProcessPool::DidGetStatistics(data, callbackID), 0); }
void WebProcess::plugInDidReceiveUserInteraction(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) { if (pageOrigin.isEmpty()) return; unsigned plugInOriginHash = hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType); if (!plugInOriginHash) return; HashMap<unsigned, double>::iterator it = m_plugInAutoStartOriginHashes.find(plugInOriginHash); if (it == m_plugInAutoStartOriginHashes.end()) return; if (it->value - currentTime() > plugInAutoStartExpirationTimeUpdateThreshold) return; parentProcessConnection()->send(Messages::WebContext::PlugInDidReceiveUserInteraction(plugInOriginHash), 0); }
void NetworkProcess::deleteWebsiteDataForOrigins(SessionID sessionID, uint64_t websiteDataTypes, const Vector<SecurityOriginData>& origins, const Vector<String>& cookieHostNames, uint64_t callbackID) { if (websiteDataTypes & WebsiteDataTypeCookies) { if (auto* networkStorageSession = SessionTracker::storageSession(sessionID)) deleteCookiesForHostnames(*networkStorageSession, cookieHostNames); } auto completionHandler = [this, callbackID] { parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteDataForOrigins(callbackID), 0); }; if ((websiteDataTypes & WebsiteDataTypeDiskCache) && !sessionID.isEphemeral()) { clearDiskCacheEntries(origins, WTFMove(completionHandler)); return; } completionHandler(); }
void DatabaseProcess::fetchWebsiteData(SessionID, uint64_t websiteDataTypes, uint64_t callbackID) { struct CallbackAggregator final : public ThreadSafeRefCounted<CallbackAggregator> { explicit CallbackAggregator(std::function<void (WebsiteData)> completionHandler) : m_completionHandler(WTFMove(completionHandler)) { } ~CallbackAggregator() { ASSERT(RunLoop::isMain()); auto completionHandler = WTFMove(m_completionHandler); auto websiteData = WTFMove(m_websiteData); RunLoop::main().dispatch([completionHandler, websiteData] { completionHandler(websiteData); }); } std::function<void (WebsiteData)> m_completionHandler; WebsiteData m_websiteData; }; RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator([this, callbackID](WebsiteData websiteData) { parentProcessConnection()->send(Messages::DatabaseProcessProxy::DidFetchWebsiteData(callbackID, websiteData), 0); })); #if ENABLE(INDEXED_DATABASE) if (websiteDataTypes & WebsiteDataTypeIndexedDBDatabases) { // FIXME: Pick the right database store based on the session ID. postDatabaseTask(std::make_unique<CrossThreadTask>([callbackAggregator, websiteDataTypes, this] { Vector<RefPtr<SecurityOrigin>> securityOrigins = indexedDatabaseOrigins(); RunLoop::main().dispatch([callbackAggregator, securityOrigins] { for (const auto& securityOrigin : securityOrigins) callbackAggregator->m_websiteData.entries.append(WebsiteData::Entry { securityOrigin, WebsiteDataTypeIndexedDBDatabases }); }); })); } #endif }