1/*
2 * Copyright (C) 2012, 2013 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 "ImmutableArray.h"
30#include "ImmutableDictionary.h"
31#include "WebContext.h"
32#include "WebContextClient.h"
33#include "WebProcessMessages.h"
34#include <wtf/CurrentTime.h>
35
36using namespace WebCore;
37
38static const double plugInAutoStartExpirationTimeThreshold = 30 * 24 * 60 * 60;
39
40namespace WebKit {
41
42PlugInAutoStartProvider::PlugInAutoStartProvider(WebContext* context)
43    : m_context(context)
44{
45}
46
47static double expirationTimeFromNow()
48{
49    return currentTime() + plugInAutoStartExpirationTimeThreshold;
50}
51
52void PlugInAutoStartProvider::addAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash)
53{
54    if (m_hashToOriginMap.contains(plugInOriginHash))
55        return;
56
57    AutoStartTable::iterator it = m_autoStartTable.find(pageOrigin);
58    if (it == m_autoStartTable.end())
59        it = m_autoStartTable.add(pageOrigin, PlugInAutoStartOriginHash()).iterator;
60
61    double expirationTime = expirationTimeFromNow();
62    it->value.set(plugInOriginHash, expirationTime);
63    m_hashToOriginMap.set(plugInOriginHash, pageOrigin);
64
65    m_context->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, expirationTime));
66    m_context->client().plugInAutoStartOriginHashesChanged(m_context);
67}
68
69PlugInAutoStartOriginHash PlugInAutoStartProvider::autoStartOriginHashesCopy() const
70{
71    PlugInAutoStartOriginHash copyMap;
72    AutoStartTable::const_iterator end = m_autoStartTable.end();
73    for (AutoStartTable::const_iterator it = m_autoStartTable.begin(); it != end; ++it) {
74        PlugInAutoStartOriginHash::const_iterator mapEnd = it->value.end();
75        for (PlugInAutoStartOriginHash::const_iterator mapIt = it->value.begin(); mapIt != mapEnd; ++mapIt)
76            copyMap.set(mapIt->key, mapIt->value);
77    }
78    return copyMap;
79}
80
81PassRefPtr<ImmutableDictionary> PlugInAutoStartProvider::autoStartOriginsTableCopy() const
82{
83    ImmutableDictionary::MapType map;
84    AutoStartTable::const_iterator end = m_autoStartTable.end();
85    double now = currentTime();
86    for (AutoStartTable::const_iterator it = m_autoStartTable.begin(); it != end; ++it) {
87        ImmutableDictionary::MapType hashMap;
88        PlugInAutoStartOriginHash::const_iterator valueEnd = it->value.end();
89        for (PlugInAutoStartOriginHash::const_iterator valueIt = it->value.begin(); valueIt != valueEnd; ++valueIt) {
90            if (now > valueIt->value)
91                continue;
92            hashMap.set(String::number(valueIt->key), WebDouble::create(valueIt->value));
93        }
94
95        if (hashMap.size())
96            map.set(it->key, ImmutableDictionary::adopt(hashMap));
97    }
98
99    return ImmutableDictionary::adopt(map);
100}
101
102void PlugInAutoStartProvider::setAutoStartOriginsTable(ImmutableDictionary& table)
103{
104    m_hashToOriginMap.clear();
105    m_autoStartTable.clear();
106    HashMap<unsigned, double> hashMap;
107
108    ImmutableDictionary::MapType::const_iterator end = table.map().end();
109    for (ImmutableDictionary::MapType::const_iterator it = table.map().begin(); it != end; ++it) {
110        PlugInAutoStartOriginHash hashes;
111        ImmutableDictionary* hashesForPage = static_cast<ImmutableDictionary*>(it->value.get());
112        ImmutableDictionary::MapType::const_iterator hashEnd = hashesForPage->map().end();
113        for (ImmutableDictionary::MapType::const_iterator hashIt = hashesForPage->map().begin(); hashIt != hashEnd; ++hashIt) {
114            bool ok;
115            unsigned hash = hashIt->key.toUInt(&ok);
116            if (!ok)
117                continue;
118
119            if (hashIt->value->type() != WebDouble::APIType)
120                continue;
121
122            double expirationTime = static_cast<WebDouble*>(hashIt->value.get())->value();
123            hashes.set(hash, expirationTime);
124            hashMap.set(hash, expirationTime);
125            m_hashToOriginMap.set(hash, it->key);
126        }
127
128        m_autoStartTable.set(it->key, hashes);
129    }
130
131    m_context->sendToAllProcesses(Messages::WebProcess::ResetPlugInAutoStartOriginHashes(hashMap));
132}
133
134void PlugInAutoStartProvider::setAutoStartOriginsArray(ImmutableArray& originList)
135{
136    m_autoStartOrigins.clear();
137    for (size_t i = 0, length = originList.size(); i < length; ++i) {
138        if (originList.at(i)->type() != WebString::APIType)
139            continue;
140        m_autoStartOrigins.append(static_cast<WebString*>(originList.at(i))->string());
141    }
142}
143
144void PlugInAutoStartProvider::didReceiveUserInteraction(unsigned plugInOriginHash)
145{
146    HashMap<unsigned, String>::const_iterator it = m_hashToOriginMap.find(plugInOriginHash);
147    if (it == m_hashToOriginMap.end()) {
148        ASSERT_NOT_REACHED();
149        return;
150    }
151
152    double newExpirationTime = expirationTimeFromNow();
153    m_autoStartTable.find(it->value)->value.set(plugInOriginHash, newExpirationTime);
154    m_context->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, newExpirationTime));
155    m_context->client().plugInAutoStartOriginHashesChanged(m_context);
156}
157
158} // namespace WebKit
159