1 | /* |
2 | * Copyright (C) 2012-2014 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 "PlugInAutoStartProvider.h" |
28 | |
29 | #include "APIArray.h" |
30 | #include "APIDictionary.h" |
31 | #include "WebContextClient.h" |
32 | #include "WebProcessMessages.h" |
33 | #include "WebProcessPool.h" |
34 | #include <wtf/WallTime.h> |
35 | |
36 | namespace WebKit { |
37 | using namespace WebCore; |
38 | |
39 | static const Seconds plugInAutoStartExpirationTimeThreshold { 30 * 24 * 60 * 60 }; |
40 | |
41 | PlugInAutoStartProvider::PlugInAutoStartProvider(WebProcessPool* processPool) |
42 | : m_processPool(processPool) |
43 | { |
44 | m_hashToOriginMap.add(PAL::SessionID::defaultSessionID(), HashMap<unsigned, String>()); |
45 | m_autoStartTable.add(PAL::SessionID::defaultSessionID(), AutoStartTable()); |
46 | } |
47 | |
48 | static WallTime expirationTimeFromNow() |
49 | { |
50 | return WallTime::now() + plugInAutoStartExpirationTimeThreshold; |
51 | } |
52 | |
53 | void PlugInAutoStartProvider::addAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, PAL::SessionID sessionID) |
54 | { |
55 | auto sessionIterator = m_hashToOriginMap.find(sessionID); |
56 | if (sessionIterator == m_hashToOriginMap.end()) { |
57 | if (m_hashToOriginMap.get(PAL::SessionID::defaultSessionID()).contains(plugInOriginHash)) |
58 | return; |
59 | sessionIterator = m_hashToOriginMap.set(sessionID, HashMap<unsigned, String>()).iterator; |
60 | } else if (sessionIterator->value.contains(plugInOriginHash) || m_hashToOriginMap.get(PAL::SessionID::defaultSessionID()).contains(plugInOriginHash)) |
61 | return; |
62 | |
63 | AutoStartTable::iterator it = m_autoStartTable.add(sessionID, AutoStartTable()).iterator->value.add(pageOrigin, PlugInAutoStartOriginMap()).iterator; |
64 | |
65 | WallTime expirationTime = expirationTimeFromNow(); |
66 | it->value.set(plugInOriginHash, expirationTime); |
67 | sessionIterator->value.set(plugInOriginHash, pageOrigin); |
68 | |
69 | m_processPool->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, expirationTime, sessionID)); |
70 | |
71 | if (!sessionID.isEphemeral()) |
72 | m_processPool->client().plugInAutoStartOriginHashesChanged(m_processPool); |
73 | } |
74 | |
75 | SessionPlugInAutoStartOriginMap PlugInAutoStartProvider::autoStartOriginHashesCopy() const |
76 | { |
77 | SessionPlugInAutoStartOriginMap sessionMap; |
78 | |
79 | for (const auto& sessionKeyOriginHash : m_autoStartTable) { |
80 | PlugInAutoStartOriginMap& map = sessionMap.add(sessionKeyOriginHash.key, PlugInAutoStartOriginMap()).iterator->value; |
81 | for (const auto& keyOriginHash : sessionKeyOriginHash.value) { |
82 | for (const auto& originHash : keyOriginHash.value) |
83 | map.set(originHash.key, originHash.value); |
84 | } |
85 | } |
86 | return sessionMap; |
87 | } |
88 | |
89 | Ref<API::Dictionary> PlugInAutoStartProvider::autoStartOriginsTableCopy() const |
90 | { |
91 | API::Dictionary::MapType map; |
92 | |
93 | WallTime now = WallTime::now(); |
94 | for (const auto& stringOriginHash : m_autoStartTable.get(PAL::SessionID::defaultSessionID())) { |
95 | API::Dictionary::MapType hashMap; |
96 | for (const auto& originHash : stringOriginHash.value) { |
97 | if (now <= originHash.value) |
98 | hashMap.set(String::number(originHash.key), API::Double::create(originHash.value.secondsSinceEpoch().seconds())); |
99 | } |
100 | if (hashMap.size()) |
101 | map.set(stringOriginHash.key, API::Dictionary::create(WTFMove(hashMap))); |
102 | } |
103 | |
104 | return API::Dictionary::create(WTFMove(map)); |
105 | } |
106 | |
107 | void PlugInAutoStartProvider::setAutoStartOriginsTable(API::Dictionary& table) |
108 | { |
109 | setAutoStartOriginsTableWithItemsPassingTest(table, [](WallTime) { |
110 | return true; |
111 | }); |
112 | } |
113 | |
114 | void PlugInAutoStartProvider::setAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary& table, WallTime time) |
115 | { |
116 | WallTime adjustedTimestamp = time + plugInAutoStartExpirationTimeThreshold; |
117 | setAutoStartOriginsTableWithItemsPassingTest(table, [adjustedTimestamp](WallTime expirationTimestamp) { |
118 | return adjustedTimestamp > expirationTimestamp; |
119 | }); |
120 | } |
121 | |
122 | void PlugInAutoStartProvider::setAutoStartOriginsTableWithItemsPassingTest(API::Dictionary& table, WTF::Function<bool(WallTime expirationTimestamp)>&& isExpirationTimeAcceptable) |
123 | { |
124 | ASSERT(isExpirationTimeAcceptable); |
125 | |
126 | m_hashToOriginMap.clear(); |
127 | m_autoStartTable.clear(); |
128 | HashMap<unsigned, WallTime> hashMap; |
129 | HashMap<unsigned, String>& hashToOriginMap = m_hashToOriginMap.add(PAL::SessionID::defaultSessionID(), HashMap<unsigned, String>()).iterator->value; |
130 | AutoStartTable& ast = m_autoStartTable.add(PAL::SessionID::defaultSessionID(), AutoStartTable()).iterator->value; |
131 | |
132 | for (auto& strDict : table.map()) { |
133 | PlugInAutoStartOriginMap hashes; |
134 | for (auto& hashTime : static_cast<API::Dictionary*>(strDict.value.get())->map()) { |
135 | bool ok; |
136 | unsigned hash = hashTime.key.toUInt(&ok); |
137 | if (!ok) |
138 | continue; |
139 | |
140 | if (hashTime.value->type() != API::Double::APIType) |
141 | continue; |
142 | |
143 | WallTime expirationTime = WallTime::fromRawSeconds(static_cast<API::Double*>(hashTime.value.get())->value()); |
144 | if (!isExpirationTimeAcceptable(expirationTime)) |
145 | continue; |
146 | |
147 | hashes.set(hash, expirationTime); |
148 | hashMap.set(hash, expirationTime); |
149 | hashToOriginMap.set(hash, strDict.key); |
150 | } |
151 | |
152 | if (!hashes.isEmpty()) |
153 | ast.set(strDict.key, hashes); |
154 | } |
155 | |
156 | m_processPool->sendToAllProcesses(Messages::WebProcess::ResetPlugInAutoStartOriginDefaultHashes(hashMap)); |
157 | } |
158 | |
159 | void PlugInAutoStartProvider::setAutoStartOriginsArray(API::Array& originList) |
160 | { |
161 | m_autoStartOrigins.clear(); |
162 | for (auto string : originList.elementsOfType<API::String>()) |
163 | m_autoStartOrigins.append(string->string()); |
164 | } |
165 | |
166 | void PlugInAutoStartProvider::didReceiveUserInteraction(unsigned plugInOriginHash, PAL::SessionID sessionID) |
167 | { |
168 | HashMap<PAL::SessionID, HashMap<unsigned, String>>::const_iterator sessionIterator = m_hashToOriginMap.find(sessionID); |
169 | HashMap<unsigned, String>::const_iterator it; |
170 | bool contains = false; |
171 | if (sessionIterator != m_hashToOriginMap.end()) { |
172 | it = sessionIterator->value.find(plugInOriginHash); |
173 | contains = it != sessionIterator->value.end(); |
174 | } |
175 | if (!contains) { |
176 | sessionIterator = m_hashToOriginMap.find(PAL::SessionID::defaultSessionID()); |
177 | it = sessionIterator->value.find(plugInOriginHash); |
178 | if (it == sessionIterator->value.end()) { |
179 | ASSERT_NOT_REACHED(); |
180 | return; |
181 | } |
182 | } |
183 | |
184 | WallTime newExpirationTime = expirationTimeFromNow(); |
185 | m_autoStartTable.add(sessionID, AutoStartTable()).iterator->value.add(it->value, PlugInAutoStartOriginMap()).iterator->value.set(plugInOriginHash, newExpirationTime); |
186 | m_processPool->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, newExpirationTime, sessionID)); |
187 | m_processPool->client().plugInAutoStartOriginHashesChanged(m_processPool); |
188 | } |
189 | |
190 | } // namespace WebKit |
191 | |