https://bugs.webkit.org/show_bug.cgi?id=111245
Reviewed by Alexey Proskuryakov.
Add API in WKContext, implemented by WebContext, that allows callers to register a callback
retrieve an array containing installed plugin information. This API is exposed through WebContext
because it owns the PluginInfoStore used to fulfill the request.
Bump the WKContextClient API by 1:
* Shared/APIClientTraits.cpp:
* Shared/APIClientTraits.h:
* UIProcess/API/C/WKContext.h:
Add a client protocol to PluginInfoStore to notify the client when plugIn information has been
successfully loaded:
* UIProcess/Plugins/PluginInfoStore.cpp:
(WebKit::PluginInfoStore::PluginInfoStore): Initialize m_client to 0.
(WebKit::PluginInfoStore::loadPluginsIfNecessary): If the client is present, notify after loading the plugin store.
* UIProcess/Plugins/PluginInfoStore.h:
(WebKit::PluginInfoStoreClient::~PluginInfoStoreClient): Default destructor.
(WebKit::PluginInfoStoreClient::PluginInfoStoreClient): Default constructor.
(WebKit::PluginInfoStore::setClient): Simple setter.
(WebKit::PluginInfoStore::client): Simple getter.
* UIProcess/WebContext.cpp:
(WebKit::WebContext::WebContext): Set self as the client of PluginInfoStore.
(WebKit::WebContext::~WebContext): Clear the client of PluginInfoStore.
(WebKit::WebContext::pluginInfoStoreDidLoadPlugins): Pass the callback to own client.
* UIProcess/WebContext.h:
* UIProcess/WebContextClient.cpp:
(WebKit::WebContextClient::plugInInformationBecameAvailable): Pass the callback to the registered WK callback, if present.
* UIProcess/WebContextClient.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@144672
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2013-03-04 Jer Noble <jer.noble@apple.com>
+
+ Add API to allow WK2 clients to query the list of installed plug-ins.
+ https://bugs.webkit.org/show_bug.cgi?id=111245
+
+ Reviewed by Alexey Proskuryakov.
+
+ Add API in WKContext, implemented by WebContext, that allows callers to register a callback
+ retrieve an array containing installed plugin information. This API is exposed through WebContext
+ because it owns the PluginInfoStore used to fulfill the request.
+
+ Bump the WKContextClient API by 1:
+ * Shared/APIClientTraits.cpp:
+ * Shared/APIClientTraits.h:
+ * UIProcess/API/C/WKContext.h:
+
+ Add a client protocol to PluginInfoStore to notify the client when plugIn information has been
+ successfully loaded:
+ * UIProcess/Plugins/PluginInfoStore.cpp:
+ (WebKit::PluginInfoStore::PluginInfoStore): Initialize m_client to 0.
+ (WebKit::PluginInfoStore::loadPluginsIfNecessary): If the client is present, notify after loading the plugin store.
+ * UIProcess/Plugins/PluginInfoStore.h:
+ (WebKit::PluginInfoStoreClient::~PluginInfoStoreClient): Default destructor.
+ (WebKit::PluginInfoStoreClient::PluginInfoStoreClient): Default constructor.
+ (WebKit::PluginInfoStore::setClient): Simple setter.
+ (WebKit::PluginInfoStore::client): Simple getter.
+
+ * UIProcess/WebContext.cpp:
+ (WebKit::WebContext::WebContext): Set self as the client of PluginInfoStore.
+ (WebKit::WebContext::~WebContext): Clear the client of PluginInfoStore.
+ (WebKit::WebContext::pluginInfoStoreDidLoadPlugins): Pass the callback to own client.
+ * UIProcess/WebContext.h:
+ * UIProcess/WebContextClient.cpp:
+ (WebKit::WebContextClient::plugInInformationBecameAvailable): Pass the callback to the registered WK callback, if present.
+ * UIProcess/WebContextClient.h:
+
2013-03-04 Tim Horton <timothy_horton@apple.com>
PDFPlugin: Hook up Services
sizeof(WKBundlePageUIClient)
};
+const size_t APIClientTraits<WKContextClient>::interfaceSizesByVersion[] = {
+ offsetof(WKContextClient, plugInInformationBecameAvailable),
+ sizeof(WKContextClient)
+};
+
const size_t APIClientTraits<WKContextInjectedBundleClient>::interfaceSizesByVersion[] = {
offsetof(WKContextInjectedBundleClient, getInjectedBundleInitializationUserData),
sizeof(WKContextInjectedBundleClient)
static const size_t interfaceSizesByVersion[2];
};
+template<> struct APIClientTraits<WKContextClient> {
+ static const size_t interfaceSizesByVersion[2];
+};
+
template<> struct APIClientTraits<WKContextInjectedBundleClient> {
static const size_t interfaceSizesByVersion[2];
};
// Context Client
typedef void (*WKContextPlugInAutoStartOriginHashesChangedCallback)(WKContextRef context, const void *clientInfo);
typedef void (*WKContextNetworkProcessDidCrashCallback)(WKContextRef context, const void *clientInfo);
+typedef void (*WKContextPlugInInformationBecameAvailableCallback)(WKContextRef context, WKArrayRef plugIn, const void *clientInfo);
struct WKContextClient {
int version;
const void * clientInfo;
+
+ // Version 0.
WKContextPlugInAutoStartOriginHashesChangedCallback plugInAutoStartOriginHashesChanged;
WKContextNetworkProcessDidCrashCallback networkProcessDidCrash;
+
+ // Version 1.
+ WKContextPlugInInformationBecameAvailableCallback plugInInformationBecameAvailable;
};
typedef struct WKContextClient WKContextClient;
-enum { kWKContextClientCurrentVersion = 0 };
+enum { kWKContextClientCurrentVersion = 1 };
// Injected Bundle Client
typedef void (*WKContextDidReceiveMessageFromInjectedBundleCallback)(WKContextRef page, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo);
PluginInfoStore::PluginInfoStore()
: m_pluginListIsUpToDate(false)
+ , m_client(0)
{
}
loadPlugin(m_plugins, *it);
m_pluginListIsUpToDate = true;
+
+ if (m_client)
+ m_client->pluginInfoStoreDidLoadPlugins(this);
}
void PluginInfoStore::loadPlugin(Vector<PluginModuleInfo>& plugins, const String& pluginPath)
namespace WebKit {
+class PluginInfoStore;
+
+class PluginInfoStoreClient {
+ WTF_MAKE_NONCOPYABLE(PluginInfoStoreClient);
+public:
+ virtual ~PluginInfoStoreClient() { }
+ virtual void pluginInfoStoreDidLoadPlugins(PluginInfoStore*) = 0;
+protected:
+ PluginInfoStoreClient() { }
+};
+
class PluginInfoStore {
WTF_MAKE_NONCOPYABLE(PluginInfoStore);
static PluginModuleLoadPolicy policyForPlugin(const PluginModuleInfo&);
static bool reactivateInactivePlugin(const PluginModuleInfo&);
+ void setClient(PluginInfoStoreClient* client) { m_client = client; }
+ PluginInfoStoreClient* client() const { return m_client; }
+
private:
PluginModuleInfo findPluginForMIMEType(const String& mimeType) const;
PluginModuleInfo findPluginForExtension(const String& extension, String& mimeType) const;
Vector<String> m_additionalPluginsDirectories;
Vector<PluginModuleInfo> m_plugins;
bool m_pluginListIsUpToDate;
+ PluginInfoStoreClient* m_client;
};
} // namespace WebKit
WebKit::initializeLogChannelsIfNecessary();
#endif // !LOG_DISABLED
+ m_pluginInfoStore.setClient(this);
+
#ifndef NDEBUG
webContextCounter.increment();
#endif
invalidateCallbackMap(m_dictionaryCallbacks);
platformInvalidateContext();
-
+
+ m_pluginInfoStore.setClient(0);
+
#ifndef NDEBUG
webContextCounter.decrement();
#endif
}
#endif
+void WebContext::pluginInfoStoreDidLoadPlugins(PluginInfoStore* store)
+{
+ ASSERT(store == &m_pluginInfoStore);
+
+ Vector<RefPtr<APIObject> > pluginArray;
+
+ Vector<PluginModuleInfo> plugins = m_pluginInfoStore.plugins();
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ PluginModuleInfo& plugin = plugins[i];
+ ImmutableDictionary::MapType map;
+ map.set(ASCIILiteral("path"), WebString::create(plugin.path));
+ map.set(ASCIILiteral("name"), WebString::create(plugin.info.name));
+ map.set(ASCIILiteral("file"), WebString::create(plugin.info.file));
+ map.set(ASCIILiteral("desc"), WebString::create(plugin.info.desc));
+ Vector<RefPtr<APIObject> > mimeArray;
+ for (size_t j = 0; j < plugin.info.mimes.size(); ++j)
+ mimeArray.append(WebString::create(plugin.info.mimes[j].type));
+ map.set(ASCIILiteral("mimes"), ImmutableArray::adopt(mimeArray));
+#if PLATFORM(MAC)
+ map.set(ASCIILiteral("bundleId"), WebString::create(plugin.bundleIdentifier));
+ map.set(ASCIILiteral("version"), WebString::create(plugin.versionString));
+#endif
+
+ pluginArray.append(ImmutableDictionary::adopt(map));
+ }
+
+ m_client.plugInInformationBecameAvailable(this, ImmutableArray::adopt(pluginArray).leakRef());
+}
+
} // namespace WebKit
extern NSString *SchemeForCustomProtocolUnregisteredNotificationName;
#endif
-class WebContext : public APIObject, private CoreIPC::MessageReceiver {
+class WebContext : public APIObject, private PluginInfoStoreClient, private CoreIPC::MessageReceiver {
public:
static const Type APIType = TypeContext;
void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash);
void plugInDidReceiveUserInteraction(unsigned plugInOriginHash);
+ // PluginInfoStoreClient:
+ virtual void pluginInfoStoreDidLoadPlugins(PluginInfoStore*) OVERRIDE;
+
CoreIPC::MessageReceiverMap m_messageReceiverMap;
ProcessModel m_processModel;
m_client.networkProcessDidCrash(toAPI(context), m_client.clientInfo);
}
+void WebContextClient::plugInInformationBecameAvailable(WebContext* context, ImmutableArray* plugInInfo)
+{
+ if (!m_client.plugInInformationBecameAvailable)
+ return;
+
+ m_client.plugInInformationBecameAvailable(toAPI(context), toAPI(plugInInfo), m_client.clientInfo);
+}
+
} // namespace WebKit
namespace WebKit {
+class ImmutableArray;
class WebContext;
class WebContextClient : public APIClient<WKContextClient, kWKContextClientCurrentVersion> {
public:
void plugInAutoStartOriginHashesChanged(WebContext*);
void networkProcessDidCrash(WebContext*);
+ void plugInInformationBecameAvailable(WebContext*, ImmutableArray*);
};
} // namespace WebKit