1 | /* |
2 | * Copyright (C) 2010-2017 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 "VisitedLinkStore.h" |
28 | |
29 | #include "VisitedLinkStoreMessages.h" |
30 | #include "VisitedLinkTableControllerMessages.h" |
31 | #include "WebProcessMessages.h" |
32 | #include "WebProcessPool.h" |
33 | #include "WebProcessProxy.h" |
34 | |
35 | namespace WebKit { |
36 | using namespace WebCore; |
37 | |
38 | Ref<VisitedLinkStore> VisitedLinkStore::create() |
39 | { |
40 | return adoptRef(*new VisitedLinkStore); |
41 | } |
42 | |
43 | VisitedLinkStore::~VisitedLinkStore() |
44 | { |
45 | RELEASE_ASSERT(m_processes.isEmpty()); |
46 | } |
47 | |
48 | VisitedLinkStore::VisitedLinkStore() |
49 | : m_linkHashStore(*this) |
50 | { |
51 | } |
52 | |
53 | void VisitedLinkStore::addProcess(WebProcessProxy& process) |
54 | { |
55 | ASSERT(process.state() == WebProcessProxy::State::Running); |
56 | ASSERT(!m_processes.contains(&process)); |
57 | |
58 | if (!m_processes.add(&process).isNewEntry) |
59 | return; |
60 | |
61 | process.addMessageReceiver(Messages::VisitedLinkStore::messageReceiverName(), identifier(), *this); |
62 | |
63 | if (m_linkHashStore.isEmpty()) |
64 | return; |
65 | |
66 | sendStoreHandleToProcess(process); |
67 | } |
68 | |
69 | void VisitedLinkStore::removeProcess(WebProcessProxy& process) |
70 | { |
71 | if (!m_processes.remove(&process)) |
72 | return; |
73 | |
74 | process.removeMessageReceiver(Messages::VisitedLinkStore::messageReceiverName(), identifier()); |
75 | } |
76 | |
77 | void VisitedLinkStore::addVisitedLinkHash(SharedStringHash linkHash) |
78 | { |
79 | m_linkHashStore.scheduleAddition(linkHash); |
80 | } |
81 | |
82 | bool VisitedLinkStore::containsVisitedLinkHash(WebCore::SharedStringHash linkHash) |
83 | { |
84 | return m_linkHashStore.contains(linkHash); |
85 | } |
86 | |
87 | void VisitedLinkStore::removeVisitedLinkHash(WebCore::SharedStringHash linkHash) |
88 | { |
89 | m_linkHashStore.scheduleRemoval(linkHash); |
90 | } |
91 | |
92 | void VisitedLinkStore::removeAll() |
93 | { |
94 | m_linkHashStore.clear(); |
95 | |
96 | for (WebProcessProxy* process : m_processes) { |
97 | ASSERT(process->processPool().processes().contains(process)); |
98 | process->send(Messages::VisitedLinkTableController::RemoveAllVisitedLinks(), identifier()); |
99 | } |
100 | } |
101 | |
102 | void VisitedLinkStore::webProcessWillOpenConnection(WebProcessProxy&, IPC::Connection&) |
103 | { |
104 | // FIXME: Implement. |
105 | } |
106 | |
107 | void VisitedLinkStore::webProcessDidCloseConnection(WebProcessProxy&, IPC::Connection&) |
108 | { |
109 | // FIXME: Implement. |
110 | } |
111 | |
112 | void VisitedLinkStore::addVisitedLinkHashFromPage(PageIdentifier pageID, SharedStringHash linkHash) |
113 | { |
114 | if (auto* webPageProxy = WebProcessProxy::webPage(pageID)) { |
115 | if (!webPageProxy->addsVisitedLinks()) |
116 | return; |
117 | } |
118 | |
119 | addVisitedLinkHash(linkHash); |
120 | } |
121 | |
122 | void VisitedLinkStore::sendStoreHandleToProcess(WebProcessProxy& process) |
123 | { |
124 | ASSERT(process.processPool().processes().contains(&process)); |
125 | |
126 | SharedMemory::Handle handle; |
127 | if (!m_linkHashStore.createSharedMemoryHandle(handle)) |
128 | return; |
129 | |
130 | process.send(Messages::VisitedLinkTableController::SetVisitedLinkTable(handle), identifier()); |
131 | } |
132 | |
133 | void VisitedLinkStore::didInvalidateSharedMemory() |
134 | { |
135 | for (WebProcessProxy* process : m_processes) |
136 | sendStoreHandleToProcess(*process); |
137 | } |
138 | |
139 | void VisitedLinkStore::didUpdateSharedStringHashes(const Vector<WebCore::SharedStringHash>& addedHashes, const Vector<WebCore::SharedStringHash>& removedHashes) |
140 | { |
141 | ASSERT(!addedHashes.isEmpty() || !removedHashes.isEmpty()); |
142 | |
143 | for (auto* process : m_processes) { |
144 | ASSERT(process->processPool().processes().contains(process)); |
145 | |
146 | if (addedHashes.size() > 20 || !removedHashes.isEmpty()) |
147 | process->send(Messages::VisitedLinkTableController::AllVisitedLinkStateChanged(), identifier()); |
148 | else |
149 | process->send(Messages::VisitedLinkTableController::VisitedLinkStateChanged(addedHashes), identifier()); |
150 | } |
151 | } |
152 | |
153 | } // namespace WebKit |
154 | |