1 | /* |
2 | Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
3 | Copyright (C) 2015 Apple Inc. All rights reserved. |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2 of the License, or (at your option) any later version. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Library General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Library General Public License |
16 | along with this library; see the file COPYING.LIB. If not, write to |
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | #pragma once |
22 | |
23 | #include <wtf/HashMap.h> |
24 | #include <wtf/HashSet.h> |
25 | #include <wtf/RefCounted.h> |
26 | #include <wtf/URL.h> |
27 | #include <wtf/Vector.h> |
28 | #include <wtf/text/StringHash.h> |
29 | #include <wtf/text/WTFString.h> |
30 | |
31 | namespace WebCore { |
32 | |
33 | class Page; |
34 | struct PluginInfo; |
35 | |
36 | enum PluginLoadClientPolicy : uint8_t { |
37 | // No client-specific plug-in load policy has been defined. The plug-in should be visible in navigator.plugins and WebKit should synchronously |
38 | // ask the client whether the plug-in should be loaded. |
39 | PluginLoadClientPolicyUndefined = 0, |
40 | |
41 | // The plug-in module should be blocked from being instantiated. The plug-in should be hidden in navigator.plugins. |
42 | PluginLoadClientPolicyBlock, |
43 | |
44 | // WebKit should synchronously ask the client whether the plug-in should be loaded. The plug-in should be visible in navigator.plugins. |
45 | PluginLoadClientPolicyAsk, |
46 | |
47 | // The plug-in module may be loaded if WebKit is not blocking it. |
48 | PluginLoadClientPolicyAllow, |
49 | |
50 | // The plug-in module should be loaded irrespective of whether WebKit has asked it to be blocked. |
51 | PluginLoadClientPolicyAllowAlways, |
52 | |
53 | PluginLoadClientPolicyMaximum = PluginLoadClientPolicyAllowAlways |
54 | }; |
55 | |
56 | struct MimeClassInfo { |
57 | String type; |
58 | String desc; |
59 | Vector<String> extensions; |
60 | }; |
61 | |
62 | inline bool operator==(const MimeClassInfo& a, const MimeClassInfo& b) |
63 | { |
64 | return a.type == b.type && a.desc == b.desc && a.extensions == b.extensions; |
65 | } |
66 | |
67 | struct PluginInfo { |
68 | String name; |
69 | String file; |
70 | String desc; |
71 | Vector<MimeClassInfo> mimes; |
72 | bool isApplicationPlugin; |
73 | |
74 | PluginLoadClientPolicy clientLoadPolicy; |
75 | |
76 | String bundleIdentifier; |
77 | #if PLATFORM(MAC) |
78 | String versionString; |
79 | #endif |
80 | }; |
81 | |
82 | inline bool operator==(PluginInfo& a, PluginInfo& b) |
83 | { |
84 | bool result = a.name == b.name && a.file == b.file && a.desc == b.desc && a.mimes == b.mimes && a.isApplicationPlugin == b.isApplicationPlugin && a.clientLoadPolicy == b.clientLoadPolicy && a.bundleIdentifier == b.bundleIdentifier; |
85 | #if PLATFORM(MAC) |
86 | result = result && a.versionString == b.versionString; |
87 | #endif |
88 | return result; |
89 | } |
90 | |
91 | struct SupportedPluginIdentifier { |
92 | String matchingDomain; |
93 | String pluginIdentifier; |
94 | |
95 | template<class Encoder> void encode(Encoder&) const; |
96 | template<class Decoder> static Optional<SupportedPluginIdentifier> decode(Decoder&); |
97 | }; |
98 | |
99 | // FIXME: merge with PluginDatabase in the future |
100 | class PluginData : public RefCounted<PluginData> { |
101 | public: |
102 | static Ref<PluginData> create(Page& page) { return adoptRef(*new PluginData(page)); } |
103 | |
104 | const Vector<PluginInfo>& plugins() const { return m_plugins; } |
105 | WEBCORE_EXPORT const Vector<PluginInfo>& webVisiblePlugins() const; |
106 | Vector<PluginInfo> publiclyVisiblePlugins() const; |
107 | WEBCORE_EXPORT void getWebVisibleMimesAndPluginIndices(Vector<MimeClassInfo>&, Vector<size_t>&) const; |
108 | |
109 | enum AllowedPluginTypes { |
110 | AllPlugins, |
111 | OnlyApplicationPlugins |
112 | }; |
113 | |
114 | WEBCORE_EXPORT bool supportsWebVisibleMimeType(const String& mimeType, const AllowedPluginTypes) const; |
115 | String pluginFileForWebVisibleMimeType(const String& mimeType) const; |
116 | |
117 | WEBCORE_EXPORT bool supportsMimeType(const String& mimeType, const AllowedPluginTypes) const; |
118 | WEBCORE_EXPORT bool supportsWebVisibleMimeTypeForURL(const String& mimeType, const AllowedPluginTypes, const URL&) const; |
119 | |
120 | private: |
121 | explicit PluginData(Page&); |
122 | void initPlugins(); |
123 | bool getPluginInfoForWebVisibleMimeType(const String& mimeType, PluginInfo&) const; |
124 | void getMimesAndPluginIndices(Vector<MimeClassInfo>&, Vector<size_t>&) const; |
125 | void getMimesAndPluginIndiciesForPlugins(const Vector<PluginInfo>&, Vector<MimeClassInfo>&, Vector<size_t>&) const; |
126 | bool supportsWebVisibleMimeType(const String& mimeType, const AllowedPluginTypes, const Vector<PluginInfo>&) const; |
127 | |
128 | protected: |
129 | Page& m_page; |
130 | Vector<PluginInfo> m_plugins; |
131 | Optional<Vector<SupportedPluginIdentifier>> m_supportedPluginIdentifiers; |
132 | |
133 | struct CachedVisiblePlugins { |
134 | URL pageURL; |
135 | Optional<Vector<PluginInfo>> pluginList; |
136 | }; |
137 | mutable CachedVisiblePlugins m_cachedVisiblePlugins; |
138 | }; |
139 | |
140 | inline bool isSupportedPlugin(const Vector<SupportedPluginIdentifier>& pluginIdentifiers, const URL& pageURL, const String& pluginIdentifier) |
141 | { |
142 | return pluginIdentifiers.findMatching([&] (auto&& plugin) { |
143 | return pageURL.isMatchingDomain(plugin.matchingDomain) && plugin.pluginIdentifier == pluginIdentifier; |
144 | }) != notFound; |
145 | } |
146 | |
147 | template<class Decoder> inline Optional<SupportedPluginIdentifier> SupportedPluginIdentifier::decode(Decoder& decoder) |
148 | { |
149 | Optional<String> matchingDomain; |
150 | decoder >> matchingDomain; |
151 | if (!matchingDomain) |
152 | return WTF::nullopt; |
153 | |
154 | Optional<String> pluginIdentifier; |
155 | decoder >> pluginIdentifier; |
156 | if (!pluginIdentifier) |
157 | return WTF::nullopt; |
158 | |
159 | return SupportedPluginIdentifier { WTFMove(matchingDomain.value()), WTFMove(pluginIdentifier.value()) }; |
160 | } |
161 | |
162 | template<class Encoder> inline void SupportedPluginIdentifier::encode(Encoder& encoder) const |
163 | { |
164 | encoder << matchingDomain; |
165 | encoder << pluginIdentifier; |
166 | } |
167 | |
168 | } // namespace WebCore |
169 | |