1/* 2 * Copyright (C) 2011, 2012 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 "WebPluginSiteDataManager.h" 28 29#if ENABLE(NETSCAPE_PLUGIN_API) 30 31#include "APIArray.h" 32#include "PluginProcessManager.h" 33#include "WebContext.h" 34#include "WebProcessMessages.h" 35 36using namespace WebCore; 37 38namespace WebKit { 39 40class WebPluginSiteDataManager::GetSitesWithDataState { 41public: 42 explicit GetSitesWithDataState(WebPluginSiteDataManager* webPluginSiteDataManager, uint64_t callbackID) 43 : m_webPluginSiteDataManager(webPluginSiteDataManager) 44 , m_callbackID(callbackID) 45 , m_plugins(webPluginSiteDataManager->m_webContext->pluginInfoStore().plugins()) 46 { 47 } 48 49 void getSitesWithDataForNextPlugin() 50 { 51 if (m_plugins.isEmpty()) { 52 Vector<String> sites; 53 copyToVector(m_sites, sites); 54 55 m_webPluginSiteDataManager->didGetSitesWithDataForAllPlugins(sites, m_callbackID); 56 return; 57 } 58 59 PluginProcessManager::shared().getSitesWithData(m_plugins.last(), m_webPluginSiteDataManager, m_callbackID); 60 m_plugins.removeLast(); 61 } 62 63 void didGetSitesWithDataForSinglePlugin(const Vector<String>& sites) 64 { 65 for (size_t i = 0; i < sites.size(); ++i) 66 m_sites.add(sites[i]); 67 68 getSitesWithDataForNextPlugin(); 69 } 70 71private: 72 WebPluginSiteDataManager* m_webPluginSiteDataManager; 73 uint64_t m_callbackID; 74 Vector<PluginModuleInfo> m_plugins; 75 HashSet<String> m_sites; 76}; 77 78class WebPluginSiteDataManager::ClearSiteDataState { 79public: 80 explicit ClearSiteDataState(WebPluginSiteDataManager* webPluginSiteDataManager, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) 81 : m_webPluginSiteDataManager(webPluginSiteDataManager) 82 , m_sites(sites) 83 , m_flags(flags) 84 , m_maxAgeInSeconds(maxAgeInSeconds) 85 , m_callbackID(callbackID) 86 , m_plugins(webPluginSiteDataManager->m_webContext->pluginInfoStore().plugins()) 87 { 88 } 89 90 void clearSiteDataForNextPlugin() 91 { 92 if (m_plugins.isEmpty()) { 93 m_webPluginSiteDataManager->didClearSiteDataForAllPlugins(m_callbackID); 94 return; 95 } 96 97 PluginProcessManager::shared().clearSiteData(m_plugins.last(), m_webPluginSiteDataManager, m_sites, m_flags, m_maxAgeInSeconds, m_callbackID); 98 m_plugins.removeLast(); 99 } 100 101 void didClearSiteDataForSinglePlugin() 102 { 103 clearSiteDataForNextPlugin(); 104 } 105 106private: 107 WebPluginSiteDataManager* m_webPluginSiteDataManager; 108 Vector<String> m_sites; 109 uint64_t m_flags; 110 uint64_t m_maxAgeInSeconds; 111 uint64_t m_callbackID; 112 Vector<PluginModuleInfo> m_plugins; 113}; 114 115PassRefPtr<WebPluginSiteDataManager> WebPluginSiteDataManager::create(WebContext* webContext) 116{ 117 return adoptRef(new WebPluginSiteDataManager(webContext)); 118} 119 120WebPluginSiteDataManager::WebPluginSiteDataManager(WebContext* webContext) 121 : m_webContext(webContext) 122{ 123} 124 125WebPluginSiteDataManager::~WebPluginSiteDataManager() 126{ 127 ASSERT(m_arrayCallbacks.isEmpty()); 128 ASSERT(m_voidCallbacks.isEmpty()); 129 ASSERT(m_pendingGetSitesWithData.isEmpty()); 130 ASSERT(m_pendingClearSiteData.isEmpty()); 131} 132 133void WebPluginSiteDataManager::invalidate() 134{ 135 invalidateCallbackMap(m_arrayCallbacks, CallbackBase::Error::OwnerWasInvalidated); 136 137 m_pendingGetSitesWithData.clear(); 138 m_pendingClearSiteData.clear(); 139} 140 141void WebPluginSiteDataManager::getSitesWithData(std::function<void (API::Array*, CallbackBase::Error)> callbackFunction) 142{ 143 RefPtr<ArrayCallback> callback = ArrayCallback::create(WTF::move(callbackFunction)); 144 145 if (!m_webContext) { 146 callback->invalidate(); 147 return; 148 } 149 150 uint64_t callbackID = callback->callbackID(); 151 m_arrayCallbacks.set(callbackID, callback.release()); 152 153 ASSERT(!m_pendingGetSitesWithData.contains(callbackID)); 154 155 GetSitesWithDataState* state = new GetSitesWithDataState(this, callbackID); 156 m_pendingGetSitesWithData.set(callbackID, std::unique_ptr<GetSitesWithDataState>(state)); 157 state->getSitesWithDataForNextPlugin(); 158} 159 160void WebPluginSiteDataManager::didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID) 161{ 162 RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID); 163 if (!callback) { 164 // FIXME: Log error or assert. 165 return; 166 } 167 168 callback->performCallbackWithReturnValue(API::Array::createStringArray(sites).get()); 169} 170 171void WebPluginSiteDataManager::clearSiteData(API::Array* sites, uint64_t flags, uint64_t maxAgeInSeconds, std::function<void (CallbackBase::Error)> callbackFunction) 172{ 173 RefPtr<VoidCallback> callback = VoidCallback::create(WTF::move(callbackFunction)); 174 if (!m_webContext) { 175 // FIXME: If the context is invalid we should not call the callback. It'd be better to just return false from clearSiteData. 176 callback->invalidate(CallbackBase::Error::OwnerWasInvalidated); 177 return; 178 } 179 180 Vector<String> sitesVector; 181 182 // If the array is empty, don't do anything. 183 if (sites) { 184 if (!sites->size()) { 185 callback->performCallback(); 186 return; 187 } 188 189 for (size_t i = 0; i < sites->size(); ++i) { 190 if (API::String* site = sites->at<API::String>(i)) 191 sitesVector.append(site->string()); 192 } 193 } 194 195 uint64_t callbackID = callback->callbackID(); 196 m_voidCallbacks.set(callbackID, callback.release()); 197 198 ASSERT(!m_pendingClearSiteData.contains(callbackID)); 199 200 ClearSiteDataState* state = new ClearSiteDataState(this, sitesVector, flags, maxAgeInSeconds, callbackID); 201 m_pendingClearSiteData.set(callbackID, std::unique_ptr<ClearSiteDataState>(state)); 202 state->clearSiteDataForNextPlugin(); 203} 204 205void WebPluginSiteDataManager::didClearSiteData(uint64_t callbackID) 206{ 207 RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID); 208 if (!callback) { 209 // FIXME: Log error or assert. 210 return; 211 } 212 213 callback->performCallback(); 214} 215 216void WebPluginSiteDataManager::didGetSitesWithDataForSinglePlugin(const Vector<String>& sites, uint64_t callbackID) 217{ 218 GetSitesWithDataState* state = m_pendingGetSitesWithData.get(callbackID); 219 ASSERT(state); 220 221 state->didGetSitesWithDataForSinglePlugin(sites); 222} 223 224void WebPluginSiteDataManager::didGetSitesWithDataForAllPlugins(const Vector<String>& sites, uint64_t callbackID) 225{ 226 std::unique_ptr<GetSitesWithDataState> state = m_pendingGetSitesWithData.take(callbackID); 227 ASSERT(state); 228 229 didGetSitesWithData(sites, callbackID); 230} 231 232void WebPluginSiteDataManager::didClearSiteDataForSinglePlugin(uint64_t callbackID) 233{ 234 ClearSiteDataState* state = m_pendingClearSiteData.get(callbackID); 235 ASSERT(state); 236 237 state->didClearSiteDataForSinglePlugin(); 238} 239 240void WebPluginSiteDataManager::didClearSiteDataForAllPlugins(uint64_t callbackID) 241{ 242 std::unique_ptr<ClearSiteDataState> state = m_pendingClearSiteData.take(callbackID); 243 ASSERT(state); 244 245 didClearSiteData(callbackID); 246} 247 248} // namespace WebKit 249 250#endif // ENABLE(NETSCAPE_PLUGIN_API) 251