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