WebProcessProxy* WebProcessProxy::fromConnection(CoreIPC::Connection* connection) { ASSERT(connection); WebConnectionToWebProcess* webConnection = static_cast<WebConnectionToWebProcess*>(connection->client()); WebProcessProxy* webProcessProxy = webConnection->webProcessProxy(); ASSERT(webProcessProxy->connection() == connection); return webProcessProxy; }
void VisitedLinkProvider::sendTable(WebProcessProxy& process) { ASSERT(process.processPool().processes().contains(&process)); SharedMemory::Handle handle; if (!m_table.sharedMemory()->createHandle(handle, SharedMemory::ReadOnly)) return; process.connection()->send(Messages::VisitedLinkTableController::SetVisitedLinkTable(handle), m_identifier); }
void WebUserContentControllerProxy::removeProcess(WebProcessProxy& webProcessProxy) { ASSERT(m_processes.contains(&webProcessProxy)); m_processes.remove(&webProcessProxy); webProcessProxy.removeMessageReceiver(Messages::WebUserContentControllerProxy::messageReceiverName(), m_identifier); }
void VisitedLinkProvider::removeProcess(WebProcessProxy& process) { ASSERT(m_processes.contains(&process)); if (m_processes.remove(&process)) process.removeMessageReceiver(Messages::VisitedLinkProvider::messageReceiverName(), m_identifier); }
void WebUserContentControllerProxy::addProcess(WebProcessProxy& webProcessProxy) { ASSERT(webProcessProxy.state() == WebProcessProxy::State::Running); if (!m_processes.add(&webProcessProxy).isNewEntry) return; webProcessProxy.addMessageReceiver(Messages::WebUserContentControllerProxy::messageReceiverName(), m_identifier, *this); webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserScripts(m_userScripts), m_identifier); webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserStyleSheets(m_userStyleSheets), m_identifier); Vector<WebScriptMessageHandlerHandle> messageHandlerHandles; for (auto& handler : m_scriptMessageHandlers.values()) messageHandlerHandles.append(handler->handle()); webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers(messageHandlerHandles), m_identifier); }
void WebUserContentControllerProxy::addProcess(WebProcessProxy& webProcessProxy) { ASSERT(webProcessProxy.state() == WebProcessProxy::State::Running); if (!m_processes.add(&webProcessProxy).isNewEntry) return; webProcessProxy.addMessageReceiver(Messages::WebUserContentControllerProxy::messageReceiverName(), m_identifier, *this); Vector<WebCore::UserScript> userScripts; for (const auto& userScript : m_userScripts->elementsOfType<API::UserScript>()) userScripts.append(userScript->userScript()); webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserScripts(userScripts), m_identifier); webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserStyleSheets(m_userStyleSheets), m_identifier); Vector<WebScriptMessageHandlerHandle> messageHandlerHandles; for (auto& handler : m_scriptMessageHandlers.values()) messageHandlerHandles.append(handler->handle()); webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers(messageHandlerHandles), m_identifier); #if ENABLE(CONTENT_EXTENSIONS) Vector<std::pair<String, WebCompiledContentExtensionData>> userContentExtensions; for (const auto& userContentExtension : m_userContentExtensions.values()) userContentExtensions.append(std::make_pair(userContentExtension->name(), userContentExtension->compiledExtension().data())); webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserContentExtensions(userContentExtensions), m_identifier); #endif }
void WebUserContentControllerProxy::didPostMessage(IPC::Connection& connection, uint64_t pageID, uint64_t frameID, const WebCore::SecurityOriginData& securityOrigin, uint64_t messageHandlerID, const IPC::DataReference& dataReference) { WebPageProxy* page = WebProcessProxy::webPage(pageID); if (!page) return; WebProcessProxy* webProcess = WebProcessProxy::fromConnection(&connection); WebFrameProxy* frame = webProcess->webFrame(frameID); if (!frame) return; if (!HashMap<uint64_t, RefPtr<WebScriptMessageHandler>>::isValidKey(messageHandlerID)) return; RefPtr<WebScriptMessageHandler> handler = m_scriptMessageHandlers.get(messageHandlerID); if (!handler) return; auto buffer = dataReference.vector(); RefPtr<WebCore::SerializedScriptValue> value = WebCore::SerializedScriptValue::adopt(buffer); handler->client().didPostMessage(*page, *frame, securityOrigin, *value); }
void VisitedLinkProvider::pendingVisitedLinksTimerFired() { Vector<WebCore::LinkHash> pendingVisitedLinks; copyToVector(m_pendingVisitedLinks, pendingVisitedLinks); m_pendingVisitedLinks.clear(); unsigned currentTableSize = m_tableSize; // Upper bound on needed size - some of the links may be duplicates, in which case we could have done with less. unsigned newTableSize = tableSizeForKeyCount(m_keyCount + pendingVisitedLinks.size()); // Never decrease table size when adding to it, to avoid unneeded churn. newTableSize = std::max(currentTableSize, newTableSize); // Links that were added. Vector<WebCore::LinkHash> addedVisitedLinks; // VisitedLinkTable remains internally consistent when adding, so it's OK to modify it in place // even if a web process is accessing it at the same time. if (currentTableSize != newTableSize) { RefPtr<SharedMemory> newTableMemory = SharedMemory::create(newTableSize * sizeof(LinkHash)); // We failed to create the shared memory. if (!newTableMemory) { LOG_ERROR("Could not allocate shared memory for visited link table"); return; } memset(newTableMemory->data(), 0, newTableMemory->size()); RefPtr<SharedMemory> currentTableMemory = m_table.sharedMemory(); m_table.setSharedMemory(newTableMemory); m_tableSize = newTableSize; if (currentTableMemory) { ASSERT(currentTableMemory->size() == currentTableSize * sizeof(LinkHash)); // Go through the current hash table and re-add all entries to the new hash table. const LinkHash* currentLinkHashes = static_cast<const LinkHash*>(currentTableMemory->data()); for (unsigned i = 0; i < currentTableSize; ++i) { LinkHash linkHash = currentLinkHashes[i]; if (!linkHash) continue; // It should always be possible to add the link hash to a new table. if (!m_table.addLinkHash(linkHash)) ASSERT_NOT_REACHED(); } } } for (size_t i = 0; i < pendingVisitedLinks.size(); ++i) { if (m_table.addLinkHash(pendingVisitedLinks[i])) addedVisitedLinks.append(pendingVisitedLinks[i]); } m_keyCount += pendingVisitedLinks.size(); for (HashSet<WebProcessProxy*>::iterator iter = m_processesWithVisitedLinkState.begin(); iter != m_processesWithVisitedLinkState.end(); ++iter) { WebProcessProxy* process = *iter; if (currentTableSize != newTableSize) { // In the rare case of needing to resize the table, we'll bypass the VisitedLinkStateChanged optimization, // and unconditionally use AllVisitedLinkStateChanged for the process. m_processesWithoutVisitedLinkState.add(process); continue; } if (addedVisitedLinks.size() <= 20) process->send(Messages::WebProcess::VisitedLinkStateChanged(addedVisitedLinks), 0); else process->send(Messages::WebProcess::AllVisitedLinkStateChanged(), 0); } for (HashSet<WebProcessProxy*>::iterator iter = m_processesWithoutVisitedLinkState.begin(); iter != m_processesWithoutVisitedLinkState.end(); ++iter) { WebProcessProxy* process = *iter; SharedMemory::Handle handle; if (!m_table.sharedMemory()->createHandle(handle, SharedMemory::ReadOnly)) return; process->send(Messages::WebProcess::SetVisitedLinkTable(handle), 0); process->send(Messages::WebProcess::AllVisitedLinkStateChanged(), 0); m_processesWithVisitedLinkState.add(process); } m_processesWithoutVisitedLinkState.clear(); }