Add API to allow WK2 clients to query the list of installed plug-ins.
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2013 22:08:26 +0000 (22:08 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2013 22:08:26 +0000 (22:08 +0000)
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

Source/WebKit2/ChangeLog
Source/WebKit2/Shared/APIClientTraits.cpp
Source/WebKit2/Shared/APIClientTraits.h
Source/WebKit2/UIProcess/API/C/WKContext.h
Source/WebKit2/UIProcess/Plugins/PluginInfoStore.cpp
Source/WebKit2/UIProcess/Plugins/PluginInfoStore.h
Source/WebKit2/UIProcess/WebContext.cpp
Source/WebKit2/UIProcess/WebContext.h
Source/WebKit2/UIProcess/WebContextClient.cpp
Source/WebKit2/UIProcess/WebContextClient.h

index b750cd3..dad4fa9 100644 (file)
@@ -1,3 +1,39 @@
+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
 2013-03-04  Tim Horton  <timothy_horton@apple.com>
 
         PDFPlugin: Hook up Services
index 5ecdab3..c997f3e 100644 (file)
@@ -87,6 +87,11 @@ const size_t APIClientTraits<WKBundlePageUIClient>::interfaceSizesByVersion[] =
     sizeof(WKBundlePageUIClient)
 };
 
     sizeof(WKBundlePageUIClient)
 };
 
+const size_t APIClientTraits<WKContextClient>::interfaceSizesByVersion[] = {
+    offsetof(WKContextClient, plugInInformationBecameAvailable),
+    sizeof(WKContextClient)
+};
+
 const size_t APIClientTraits<WKContextInjectedBundleClient>::interfaceSizesByVersion[] = {
     offsetof(WKContextInjectedBundleClient, getInjectedBundleInitializationUserData),
     sizeof(WKContextInjectedBundleClient)
 const size_t APIClientTraits<WKContextInjectedBundleClient>::interfaceSizesByVersion[] = {
     offsetof(WKContextInjectedBundleClient, getInjectedBundleInitializationUserData),
     sizeof(WKContextInjectedBundleClient)
index a062956..d3912c9 100644 (file)
@@ -79,6 +79,10 @@ template<> struct APIClientTraits<WKBundlePageEditorClient> {
     static const size_t interfaceSizesByVersion[2];
 };
 
     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];
 };
 template<> struct APIClientTraits<WKContextInjectedBundleClient> {
     static const size_t interfaceSizesByVersion[2];
 };
index fe7c208..18a78ee 100644 (file)
@@ -42,16 +42,22 @@ typedef uint32_t WKCacheModel;
 // Context Client
 typedef void (*WKContextPlugInAutoStartOriginHashesChangedCallback)(WKContextRef context, const void *clientInfo);
 typedef void (*WKContextNetworkProcessDidCrashCallback)(WKContextRef context, const void *clientInfo);
 // 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;
 
 struct WKContextClient {
     int                                                                 version;
     const void *                                                        clientInfo;
+
+    // Version 0.
     WKContextPlugInAutoStartOriginHashesChangedCallback                 plugInAutoStartOriginHashesChanged;
     WKContextNetworkProcessDidCrashCallback                             networkProcessDidCrash;
     WKContextPlugInAutoStartOriginHashesChangedCallback                 plugInAutoStartOriginHashesChanged;
     WKContextNetworkProcessDidCrashCallback                             networkProcessDidCrash;
+
+    // Version 1.
+    WKContextPlugInInformationBecameAvailableCallback                         plugInInformationBecameAvailable;
 };
 typedef struct WKContextClient WKContextClient;
 
 };
 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);
 
 // Injected Bundle Client
 typedef void (*WKContextDidReceiveMessageFromInjectedBundleCallback)(WKContextRef page, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo);
index b79b5af..6ac14b0 100644 (file)
@@ -42,6 +42,7 @@ namespace WebKit {
 
 PluginInfoStore::PluginInfoStore()
     : m_pluginListIsUpToDate(false)
 
 PluginInfoStore::PluginInfoStore()
     : m_pluginListIsUpToDate(false)
+    , m_client(0)
 {
 }
 
 {
 }
 
@@ -97,6 +98,9 @@ void PluginInfoStore::loadPluginsIfNecessary()
         loadPlugin(m_plugins, *it);
 
     m_pluginListIsUpToDate = true;
         loadPlugin(m_plugins, *it);
 
     m_pluginListIsUpToDate = true;
+
+    if (m_client)
+        m_client->pluginInfoStoreDidLoadPlugins(this);
 }
 
 void PluginInfoStore::loadPlugin(Vector<PluginModuleInfo>& plugins, const String& pluginPath)
 }
 
 void PluginInfoStore::loadPlugin(Vector<PluginModuleInfo>& plugins, const String& pluginPath)
index 17cf2c4..18a3d41 100644 (file)
@@ -36,6 +36,17 @@ namespace WebCore {
 
 namespace WebKit {
 
 
 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);
 
 class PluginInfoStore {
     WTF_MAKE_NONCOPYABLE(PluginInfoStore);
 
@@ -58,6 +69,9 @@ public:
     static PluginModuleLoadPolicy policyForPlugin(const PluginModuleInfo&);
     static bool reactivateInactivePlugin(const PluginModuleInfo&);
 
     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;
 private:
     PluginModuleInfo findPluginForMIMEType(const String& mimeType) const;
     PluginModuleInfo findPluginForExtension(const String& extension, String& mimeType) const;
@@ -88,6 +102,7 @@ private:
     Vector<String> m_additionalPluginsDirectories;
     Vector<PluginModuleInfo> m_plugins;
     bool m_pluginListIsUpToDate;
     Vector<String> m_additionalPluginsDirectories;
     Vector<PluginModuleInfo> m_plugins;
     bool m_pluginListIsUpToDate;
+    PluginInfoStoreClient* m_client;
 };
     
 } // namespace WebKit
 };
     
 } // namespace WebKit
index bc78bf4..4f889e4 100644 (file)
@@ -189,6 +189,8 @@ WebContext::WebContext(ProcessModel processModel, const String& injectedBundlePa
     WebKit::initializeLogChannelsIfNecessary();
 #endif // !LOG_DISABLED
 
     WebKit::initializeLogChannelsIfNecessary();
 #endif // !LOG_DISABLED
 
+    m_pluginInfoStore.setClient(this);
+
 #ifndef NDEBUG
     webContextCounter.increment();
 #endif
 #ifndef NDEBUG
     webContextCounter.increment();
 #endif
@@ -237,7 +239,9 @@ WebContext::~WebContext()
     invalidateCallbackMap(m_dictionaryCallbacks);
 
     platformInvalidateContext();
     invalidateCallbackMap(m_dictionaryCallbacks);
 
     platformInvalidateContext();
-    
+
+    m_pluginInfoStore.setClient(0);
+
 #ifndef NDEBUG
     webContextCounter.decrement();
 #endif
 #ifndef NDEBUG
     webContextCounter.decrement();
 #endif
@@ -1187,4 +1191,33 @@ void WebContext::unregisterSchemeForCustomProtocol(const String& scheme)
 }
 #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
 } // namespace WebKit
index ef3bc26..5eef9a6 100644 (file)
@@ -84,7 +84,7 @@ extern NSString *SchemeForCustomProtocolRegisteredNotificationName;
 extern NSString *SchemeForCustomProtocolUnregisteredNotificationName;
 #endif
 
 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;
 
 public:
     static const Type APIType = TypeContext;
 
@@ -371,6 +371,9 @@ private:
     void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash);
     void plugInDidReceiveUserInteraction(unsigned plugInOriginHash);
 
     void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash);
     void plugInDidReceiveUserInteraction(unsigned plugInOriginHash);
 
+    // PluginInfoStoreClient:
+    virtual void pluginInfoStoreDidLoadPlugins(PluginInfoStore*) OVERRIDE;
+
     CoreIPC::MessageReceiverMap m_messageReceiverMap;
 
     ProcessModel m_processModel;
     CoreIPC::MessageReceiverMap m_messageReceiverMap;
 
     ProcessModel m_processModel;
index 2bc9428..3da2bdb 100644 (file)
@@ -46,4 +46,12 @@ void WebContextClient::networkProcessDidCrash(WebContext* context)
     m_client.networkProcessDidCrash(toAPI(context), m_client.clientInfo);
 }
 
     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
index 8b3a737..698607c 100644 (file)
 
 namespace WebKit {
 
 
 namespace WebKit {
 
+class ImmutableArray;
 class WebContext;
 
 class WebContextClient : public APIClient<WKContextClient, kWKContextClientCurrentVersion> {
 public:
     void plugInAutoStartOriginHashesChanged(WebContext*);
     void networkProcessDidCrash(WebContext*);
 class WebContext;
 
 class WebContextClient : public APIClient<WKContextClient, kWKContextClientCurrentVersion> {
 public:
     void plugInAutoStartOriginHashesChanged(WebContext*);
     void networkProcessDidCrash(WebContext*);
+    void plugInInformationBecameAvailable(WebContext*, ImmutableArray*);
 };
 
 } // namespace WebKit
 };
 
 } // namespace WebKit