Add support for handling WebGL load policies.
https://bugs.webkit.org/show_bug.cgi?id=126935
<rdar://problem/15790448>.

Reviewed by Brent Fulgham.

* WebCore.xcodeproj/project.pbxproj: Copy over HTMLCanvasElement.h to the private headers directory.
* html/HTMLCanvasElement.cpp: Show the policy dialog and retrieve policies as necessary.
(WebCore::HTMLCanvasElement::getContext): Make sure that WebGL is allowed on the site.
                                          If it isn't, be sure to notify the frame loader client that
                                          the site is trying to create a WebGL context.

Boiler plate code for sending messages to and from the UI and Web Process. 

* loader/FrameLoaderClient.h:
(WebCore::FrameLoaderClient::webGLPolicyForHost): Used to get the WebGL load policy for a site.
* loader/FrameLoaderTypes.h:
* page/ChromeClient.h:
(WebCore::ChromeClient::webGLContextCreated): Called when a site is creating a WebGL context.
* UIProcess/API/C/WKAPICast.h:
(WebKit::toWebGLLoadPolicy):
* UIProcess/API/C/WKPageLoaderClient.h:
* UIProcess/API/C/WKPageUIClient.h:
* UIProcess/WebLoaderClient.cpp:
(WebKit::WebLoaderClient::webGLLoadPolicy):
* UIProcess/WebLoaderClient.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::webGLContextCreated):
(WebKit::WebPageProxy::webGLPolicyForHost):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/WebUIClient.cpp:
(WebKit::WebUIClient::webGLContextCreated):
* UIProcess/WebUIClient.h:
* UIProcess/mac/WebInspectorProxyMac.mm:
(WebKit::WebInspectorProxy::platformCreateInspectorPage):
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::webGLContextCreated):
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::webGLPolicyForHost):
* WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
* WebProcess/WebPage/WebPage.cpp: A sendSync is used here to get the webGLPolicyForHost message sent between the Web and UI process.
                                  In the future this will be replaced with a strategy is non-blocking.
(WebKit::WebPage::getWebGLPolicyForHost):
* WebProcess/WebPage/WebPage.h:
* MiniBrowser/mac/WK2BrowserWindowController.m:
(-[WK2BrowserWindowController awakeFromNib]):
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::createWebViewWithOptions):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@162000 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index d59fe84..c13d05c 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2014-01-09  Roger Fong  <roger_fong@apple.com>
+
+        Add support for handling WebGL load policies.
+        https://bugs.webkit.org/show_bug.cgi?id=126935
+        <rdar://problem/15790448>.
+
+        Reviewed by Brent Fulgham.
+
+        * WebCore.xcodeproj/project.pbxproj: Copy over HTMLCanvasElement.h to the private headers directory.
+        * html/HTMLCanvasElement.cpp: Show the policy dialog and retrieve policies as necessary.
+        (WebCore::HTMLCanvasElement::getContext): Make sure that WebGL is allowed on the site.
+                                                  If it isn't, be sure to notify the frame loader client that
+                                                  the site is trying to create a WebGL context.
+        * loader/FrameLoaderClient.h:
+        (WebCore::FrameLoaderClient::webGLPolicyForHost): Used to get the WebGL load policy for a site.
+        * loader/FrameLoaderTypes.h:
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::webGLContextCreated): Called when a site is creating a WebGL context.
+
 2014-01-14  Anders Carlsson  <andersca@apple.com>
 
         Get rid of ThreadRestrictionVerifier
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index 5dc9193..65e3913 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -3241,7 +3241,7 @@
 		93F199BB08245E59001E9ABC /* WebCoreKeyboardUIMode.h in Headers */ = {isa = PBXBuildFile; fileRef = BE983D95052A2E0A00892D85 /* WebCoreKeyboardUIMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		93F199BE08245E59001E9ABC /* BlockExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 65A640F00533BB1F0085E777 /* BlockExceptions.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		93F199DE08245E59001E9ABC /* Position.h in Headers */ = {isa = PBXBuildFile; fileRef = BE91FC8B06133666005E3790 /* Position.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		93F199E508245E59001E9ABC /* HTMLCanvasElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F6A3D60663BF04004D2919 /* HTMLCanvasElement.h */; };
+		93F199E508245E59001E9ABC /* HTMLCanvasElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F6A3D60663BF04004D2919 /* HTMLCanvasElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		93F199EC08245E59001E9ABC /* XSLStyleSheet.h in Headers */ = {isa = PBXBuildFile; fileRef = BC06F24A06D18A7E004A6FA3 /* XSLStyleSheet.h */; };
 		93F199ED08245E59001E9ABC /* XSLTProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC06F24C06D18A7E004A6FA3 /* XSLTProcessor.h */; };
 		93F199F008245E59001E9ABC /* WebCoreView.h in Headers */ = {isa = PBXBuildFile; fileRef = BE855F7F0701E83500239769 /* WebCoreView.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -23190,6 +23190,7 @@
 				E4B65A58132FA8E70070E7BE /* TileGrid.h in Headers */,
 				93F1992F08245E59001E9ABC /* Cursor.h in Headers */,
 				BC2272A20E82E87C00E7F975 /* CursorData.h in Headers */,
+				93F199E508245E59001E9ABC /* HTMLCanvasElement.h in Headers */,
 				868160D618766A130021E79D /* UserActivity.h in Headers */,
 				BC2272AD0E82E8F300E7F975 /* CursorList.h in Headers */,
 				62CD325A1157E57C0063B0A7 /* CustomEvent.h in Headers */,
@@ -23953,7 +23954,6 @@
 				A871DE2C0A152AC800B12A68 /* HTMLBodyElement.h in Headers */,
 				A8CFF7AA0A156978000A4234 /* HTMLBRElement.h in Headers */,
 				A81369D2097374F600D74463 /* HTMLButtonElement.h in Headers */,
-				93F199E508245E59001E9ABC /* HTMLCanvasElement.h in Headers */,
 				07969DC017D14151007FF842 /* JSRTCStatsCallback.h in Headers */,
 				A8DF3FD0097FA0FC0052981B /* HTMLCollection.h in Headers */,
 				977B3865122883E900B81FF8 /* HTMLConstructionSite.h in Headers */,
diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp
index 58dbdda..0bf46af 100644
--- a/Source/WebCore/html/HTMLCanvasElement.cpp
+++ b/Source/WebCore/html/HTMLCanvasElement.cpp
@@ -33,13 +33,16 @@
 #include "CanvasPattern.h"
 #include "CanvasRenderingContext2D.h"
 #include "Chrome.h"
+#include "ChromeClient.h"
 #include "Document.h"
 #include "ExceptionCode.h"
 #include "Frame.h"
+#include "FrameLoaderClient.h"
 #include "GraphicsContext.h"
 #include "HTMLNames.h"
 #include "ImageData.h"
 #include "MIMETypeRegistry.h"
+#include "MainFrame.h"
 #include "Page.h"
 #include "RenderHTMLCanvas.h"
 #include "ScriptController.h"
@@ -201,7 +204,7 @@
     // once it is created. https://bugs.webkit.org/show_bug.cgi?id=117095
     if (is2dType(type)) {
         if (m_context && !m_context->is2d())
-            return 0;
+            return nullptr;
         if (!m_context) {
             bool usesDashbardCompatibilityMode = false;
 #if ENABLE(DASHBOARD_SUPPORT)
@@ -223,6 +226,17 @@
             if (m_context && !m_context->is3d())
                 return 0;
             if (!m_context) {
+                Page* page = document().page();
+                if (page && !document().url().isLocalFile()) {
+                    WebGLLoadPolicy policy = page->mainFrame().loader().client().webGLPolicyForHost(document().url().host());
+
+                    if (policy == WebGLAsk) {
+                        page->chrome().client().webGLContextCreated(this);
+                        return nullptr;
+                    }
+                    if (policy == WebGLBlock)
+                        return nullptr;
+                }
                 m_context = WebGLRenderingContext::create(this, static_cast<WebGLContextAttributes*>(attrs));
                 if (m_context) {
                     // Need to make sure a RenderLayer and compositing layer get created for the Canvas
@@ -235,7 +249,7 @@
 #else
     UNUSED_PARAM(attrs);
 #endif
-    return 0;
+    return nullptr;
 }
     
 bool HTMLCanvasElement::probablySupportsContext(const String& type, CanvasContextAttributes*)
diff --git a/Source/WebCore/loader/FrameLoaderClient.h b/Source/WebCore/loader/FrameLoaderClient.h
index 8da6b43..3f203fb 100644
--- a/Source/WebCore/loader/FrameLoaderClient.h
+++ b/Source/WebCore/loader/FrameLoaderClient.h
@@ -331,6 +331,7 @@
         // Informs the embedder that a WebGL canvas inside this frame received a lost context
         // notification with the given GL_ARB_robustness guilt/innocence code (see Extensions3D.h).
         virtual void didLoseWebGLContext(int) { }
+        virtual WebGLLoadPolicy webGLPolicyForHost(const String&) const { return WebGLAsk; }
 #endif
 
         virtual void forcePageTransitionIfNeeded() { }
diff --git a/Source/WebCore/loader/FrameLoaderTypes.h b/Source/WebCore/loader/FrameLoaderTypes.h
index 9e1b6bc..9f9dff4 100644
--- a/Source/WebCore/loader/FrameLoaderTypes.h
+++ b/Source/WebCore/loader/FrameLoaderTypes.h
@@ -105,6 +105,12 @@
         AboutToInstantiatePlugin,
         NotAboutToInstantiatePlugin
     };
+    
+    enum WebGLLoadPolicy {
+        WebGLAsk = 0,
+        WebGLAllow,
+        WebGLBlock
+    };
 
 }
 
diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h
index 8498ac8..446e193 100644
--- a/Source/WebCore/page/ChromeClient.h
+++ b/Source/WebCore/page/ChromeClient.h
@@ -428,6 +428,10 @@
     // would likely want the page to remain running uninterrupted.
     virtual void incrementActivePageCount() { }
     virtual void decrementActivePageCount() { }
+    
+#if ENABLE(WEBGL)
+    virtual void webGLContextCreated(Element*) const { }
+#endif
 
 protected:
     virtual ~ChromeClient() { }
diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog
index 36ca0b0..d7f16ee 100644
--- a/Source/WebKit2/ChangeLog
+++ b/Source/WebKit2/ChangeLog
@@ -1,3 +1,41 @@
+2014-01-09  Roger Fong  <roger_fong@apple.com>
+
+        Add support for handling WebGL load policies.
+        https://bugs.webkit.org/show_bug.cgi?id=126935
+        <rdar://problem/15790448>.
+
+        Reviewed by Brent Fulgham.
+
+        Boiler plate code for sending messages to and from the UI and Web Process. 
+
+        * UIProcess/API/C/WKAPICast.h:
+        (WebKit::toWebGLLoadPolicy):
+        * UIProcess/API/C/WKPageLoaderClient.h:
+        * UIProcess/API/C/WKPageUIClient.h:
+        * UIProcess/WebLoaderClient.cpp:
+        (WebKit::WebLoaderClient::webGLLoadPolicy):
+        * UIProcess/WebLoaderClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::webGLContextCreated):
+        (WebKit::WebPageProxy::webGLPolicyForHost):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/WebUIClient.cpp:
+        (WebKit::WebUIClient::webGLContextCreated):
+        * UIProcess/WebUIClient.h:
+        * UIProcess/mac/WebInspectorProxyMac.mm:
+        (WebKit::WebInspectorProxy::platformCreateInspectorPage):
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::webGLContextCreated):
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::webGLPolicyForHost):
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.h:
+        * WebProcess/WebPage/WebPage.cpp: A sendSync is used here to get the webGLPolicyForHost message sent between the Web and UI process.
+                                          In the future this will be replaced with a strategy is non-blocking.
+        (WebKit::WebPage::getWebGLPolicyForHost):
+        * WebProcess/WebPage/WebPage.h:
+
 2014-01-14  Mark Rowe  <mrowe@apple.com>
 
         WebKit2 leaks sudden termination assertions when a page with unload handlers is closed.
diff --git a/Source/WebKit2/UIProcess/API/C/WKAPICast.h b/Source/WebKit2/UIProcess/API/C/WKAPICast.h
index 5683e65..670ce4f 100644
--- a/Source/WebKit2/UIProcess/API/C/WKAPICast.h
+++ b/Source/WebKit2/UIProcess/API/C/WKAPICast.h
@@ -473,6 +473,21 @@
     return PluginModuleBlocked;
 }
 
+inline WebCore::WebGLLoadPolicy toWebGLLoadPolicy(WKWebGLLoadPolicy webGLLoadPolicy)
+{
+    switch (webGLLoadPolicy) {
+    case kWKWebGLLoadPolicyInactive:
+        return WebCore::WebGLAsk;
+    case kWKWebGLLoadPolicyLoadNormally:
+        return WebCore::WebGLAllow;
+    case kWKWebGLLoadPolicyBlocked:
+        return WebCore::WebGLBlock;
+    }
+    
+    ASSERT_NOT_REACHED();
+    return WebCore::WebGLAsk;
+}
+
 inline ProxyingRefPtr<WebGrammarDetail> toAPI(const WebCore::GrammarDetail& grammarDetail)
 {
     return ProxyingRefPtr<WebGrammarDetail>(WebGrammarDetail::create(grammarDetail));
diff --git a/Source/WebKit2/UIProcess/API/C/WKPageLoaderClient.h b/Source/WebKit2/UIProcess/API/C/WKPageLoaderClient.h
index 147b22592..64d2184 100644
--- a/Source/WebKit2/UIProcess/API/C/WKPageLoaderClient.h
+++ b/Source/WebKit2/UIProcess/API/C/WKPageLoaderClient.h
@@ -42,6 +42,13 @@
 };
 typedef uint32_t WKPluginLoadPolicy;
 
+enum {
+    kWKWebGLLoadPolicyInactive = 0,
+    kWKWebGLLoadPolicyLoadNormally,
+    kWKWebGLLoadPolicyBlocked
+};
+typedef uint32_t WKWebGLLoadPolicy;
+
 typedef void (*WKPageLoaderClientCallback)(WKPageRef page, const void* clientInfo);
 typedef void (*WKPageDidStartProvisionalLoadForFrameCallback)(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo);
 typedef void (*WKPageDidReceiveServerRedirectForProvisionalLoadForFrameCallback)(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo);
@@ -66,6 +73,7 @@
 typedef void (*WKPageDidLayoutCallback)(WKPageRef page, WKLayoutMilestones milestones, WKTypeRef userData, const void *clientInfo);
 typedef WKPluginLoadPolicy (*WKPagePluginLoadPolicyCallback)(WKPageRef page, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInfoDictionary, WKStringRef* unavailabilityDescription, const void* clientInfo);
 typedef void (*WKPagePluginDidFailCallback)(WKPageRef page, WKErrorCode errorCode, WKDictionaryRef pluginInfoDictionary, const void* clientInfo);
+typedef WKWebGLLoadPolicy (*WKPageWebGLLoadPolicyCallback)(WKPageRef page, WKStringRef host, const void* clientInfo);
 
 // Deprecated
 typedef void (*WKPageDidFailToInitializePluginCallback_deprecatedForUseWithV0)(WKPageRef page, WKStringRef mimeType, const void* clientInfo);
@@ -264,6 +272,7 @@
 
     // Version 3.
     WKPagePluginLoadPolicyCallback                                      pluginLoadPolicy;
+    WKPageWebGLLoadPolicyCallback                                       webGLLoadPolicy;
 } WKPageLoaderClientV3;
 
 // FIXME: These should be deprecated.
diff --git a/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h b/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h
index 1d84170..bbac85f 100644
--- a/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h
+++ b/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h
@@ -85,6 +85,7 @@
 typedef void (*WKPageShowColorPickerCallback)(WKPageRef page, WKStringRef initialColor, WKColorPickerResultListenerRef listener, const void* clientInfo);
 typedef void (*WKPageHideColorPickerCallback)(WKPageRef page, const void* clientInfo);
 typedef void (*WKPageUnavailablePluginButtonClickedCallback)(WKPageRef page, WKPluginUnavailabilityReason pluginUnavailabilityReason, WKDictionaryRef pluginInfoDictionary, const void* clientInfo);
+typedef void (*WKPageWebGLContextCreatedCallback)(WKPageRef page, WKStringRef, const void* clientInfo);
 
 // Deprecated    
 typedef WKPageRef (*WKPageCreateNewPageCallback_deprecatedForUseWithV0)(WKPageRef page, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void *clientInfo);
@@ -247,6 +248,7 @@
     WKPageShowColorPickerCallback                                       showColorPicker;
     WKPageHideColorPickerCallback                                       hideColorPicker;
     WKPageUnavailablePluginButtonClickedCallback                        unavailablePluginButtonClicked;
+    WKPageWebGLContextCreatedCallback                                   webGLContextCreated;
 } WKPageUIClientV2;
 
 enum { kWKPageUIClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 2 };
diff --git a/Source/WebKit2/UIProcess/WebLoaderClient.cpp b/Source/WebKit2/UIProcess/WebLoaderClient.cpp
index 4fbd338..efaefea 100644
--- a/Source/WebKit2/UIProcess/WebLoaderClient.cpp
+++ b/Source/WebKit2/UIProcess/WebLoaderClient.cpp
@@ -333,4 +333,12 @@
 
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
 
+#if ENABLE(WEBGL)
+void WebLoaderClient::webGLLoadPolicy(WebPageProxy* page, WebCore::WebGLLoadPolicy& loadPolicy, const String& host)
+{
+    if (m_client.webGLLoadPolicy)
+        loadPolicy = toWebGLLoadPolicy(m_client.webGLLoadPolicy(toAPI(page), toAPI(host.impl()), m_client.base.clientInfo));
+}
+#endif // ENABLE(WEBGL)
+
 } // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/WebLoaderClient.h b/Source/WebKit2/UIProcess/WebLoaderClient.h
index 98b21c9..374ec6e 100644
--- a/Source/WebKit2/UIProcess/WebLoaderClient.h
+++ b/Source/WebKit2/UIProcess/WebLoaderClient.h
@@ -30,6 +30,7 @@
 #include "PluginModuleInfo.h"
 #include "SameDocumentNavigationType.h"
 #include "WKPage.h"
+#include <WebCore/FrameLoaderTypes.h>
 #include <WebCore/LayoutMilestones.h>
 #include <wtf/Forward.h>
 #include <wtf/RefPtr.h>
@@ -102,6 +103,10 @@
     void didFailToInitializePlugin(WebPageProxy*, ImmutableDictionary*);
     void didBlockInsecurePluginVersion(WebPageProxy*, ImmutableDictionary*);
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
+
+#if ENABLE(WEBGL)
+    void webGLLoadPolicy(WebPageProxy*, WebCore::WebGLLoadPolicy&, const String&);
+#endif // ENABLE(WEBGL)
 };
 
 } // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.cpp b/Source/WebKit2/UIProcess/WebPageProxy.cpp
index 758ee4f..7d60506 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit2/UIProcess/WebPageProxy.cpp
@@ -2680,6 +2680,20 @@
 }
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
 
+#if ENABLE(WEBGL)
+void WebPageProxy::webGLContextCreated(const String& pageURLString)
+{
+    m_uiClient.webGLContextCreated(this, pageURLString);
+}
+
+void WebPageProxy::webGLPolicyForHost(const String& host, uint32_t& loadPolicy)
+{
+    WebCore::WebGLLoadPolicy policy;
+    m_loaderClient.webGLLoadPolicy(this, policy, host);
+    loadPolicy = static_cast<uint32_t>(policy);
+}
+#endif // ENABLE(WEBGL)
+
 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
 {
     m_uiClient.setToolbarsAreVisible(this, toolbarsAreVisible);
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h
index bf50fc2..0d50773 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.h
+++ b/Source/WebKit2/UIProcess/WebPageProxy.h
@@ -929,6 +929,10 @@
 #if ENABLE(NETSCAPE_PLUGIN_API)
     void unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginsPageURLString, const String& frameURLString, const String& pageURLString);
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
+#if ENABLE(WEBGL)
+    void webGLContextCreated(const String& pageURLString);
+    void webGLPolicyForHost(const String& host, uint32_t& loadPolicy);
+#endif // ENABLE(WEBGL)
     void setToolbarsAreVisible(bool toolbarsAreVisible);
     void getToolbarsAreVisible(bool& toolbarsAreVisible);
     void setMenuBarIsVisible(bool menuBarIsVisible);
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.messages.in b/Source/WebKit2/UIProcess/WebPageProxy.messages.in
index 2db0792..e5bc318 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.messages.in
+++ b/Source/WebKit2/UIProcess/WebPageProxy.messages.in
@@ -33,6 +33,10 @@
 #if ENABLE(NETSCAPE_PLUGIN_API)
     UnavailablePluginButtonClicked(uint32_t pluginUnavailabilityReason, String mimeType, String pluginURLString, String pluginspageAttributeURLString, String frameURLString, String pageURLString)
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
+#if ENABLE(WEBGL)
+    WebGLContextCreated(String pageURLString)
+    WebGLPolicyForHost(String host) -> (uint32_t loadPolicy)
+#endif // ENABLE(WEBGL)
     DidChangeViewportProperties(WebCore::ViewportAttributes attributes)
     DidReceiveEvent(uint32_t type, bool handled)
     StopResponsivenessTimer()
diff --git a/Source/WebKit2/UIProcess/WebUIClient.cpp b/Source/WebKit2/UIProcess/WebUIClient.cpp
index 513889c..51ae2b6 100644
--- a/Source/WebKit2/UIProcess/WebUIClient.cpp
+++ b/Source/WebKit2/UIProcess/WebUIClient.cpp
@@ -207,6 +207,14 @@
 }
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
 
+#if ENABLE(WEBGL)
+void WebUIClient::webGLContextCreated(WebPageProxy* page, const String& originatingURL)
+{
+    if (m_client.webGLContextCreated)
+        m_client.webGLContextCreated(toAPI(page), toAPI(originatingURL.impl()), m_client.base.clientInfo);
+}
+#endif // ENABLE(WEBGL)
+
 bool WebUIClient::implementsDidNotHandleKeyEvent() const
 {
     return m_client.didNotHandleKeyEvent;
diff --git a/Source/WebKit2/UIProcess/WebUIClient.h b/Source/WebKit2/UIProcess/WebUIClient.h
index 27c6bde..891c8bd 100644
--- a/Source/WebKit2/UIProcess/WebUIClient.h
+++ b/Source/WebKit2/UIProcess/WebUIClient.h
@@ -81,7 +81,9 @@
 #if ENABLE(NETSCAPE_PLUGIN_API)
     void unavailablePluginButtonClicked(WebPageProxy*, WKPluginUnavailabilityReason, ImmutableDictionary*);
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
-
+#if ENABLE(WEBGL)
+    void webGLContextCreated(WebPageProxy*, const String&);
+#endif // ENABLE(WEBGL)
     bool implementsDidNotHandleKeyEvent() const;
     void didNotHandleKeyEvent(WebPageProxy*, const NativeWebKeyboardEvent&);
 
diff --git a/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm
index abb46f8..57c1453 100644
--- a/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm
+++ b/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm
@@ -447,6 +447,7 @@
         0, // showColorPicker
         0, // hideColorPicker
         0, // unavailablePluginButtonClicked
+        0, // webGLContextCreated
     };
 
     inspectorPage->initializeUIClient(reinterpret_cast<const WKPageUIClientBase*>(&uiClient));
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
index 10a911d..812dbdb 100644
--- a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
+++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp
@@ -58,6 +58,7 @@
 #include <WebCore/FrameLoadRequest.h>
 #include <WebCore/FrameLoader.h>
 #include <WebCore/FrameView.h>
+#include <WebCore/HTMLCanvasElement.h>
 #include <WebCore/HTMLInputElement.h>
 #include <WebCore/HTMLNames.h>
 #include <WebCore/HTMLParserIdioms.h>
@@ -562,6 +563,14 @@
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
 }
 
+#if ENABLE(WEBGL)
+void WebChromeClient::webGLContextCreated(Element* element) const
+{
+    String pageURLString = m_page->mainFrame()->loader().documentLoader()->responseURL().string();
+    m_page->send(Messages::WebPageProxy::WebGLContextCreated(pageURLString));
+}
+#endif // ENABLE(WEBGL)
+
 void WebChromeClient::scrollbarsModeDidChange() const
 {
     notImplemented();
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h
index bf81d4d..fd2834b 100644
--- a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h
+++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.h
@@ -123,6 +123,9 @@
 
     virtual bool shouldUnavailablePluginMessageBeButton(WebCore::RenderEmbeddedObject::PluginUnavailabilityReason) const OVERRIDE;
     virtual void unavailablePluginButtonClicked(WebCore::Element*, WebCore::RenderEmbeddedObject::PluginUnavailabilityReason) const OVERRIDE;
+#if ENABLE(WEBGL)
+    virtual void webGLContextCreated(WebCore::Element*) const OVERRIDE;
+#endif // ENABLE(WEBGL)
 
     virtual void scrollbarsModeDidChange() const OVERRIDE;
     virtual void mouseDidMoveOverElement(const WebCore::HitTestResult&, unsigned modifierFlags) OVERRIDE;
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
index b1baf67..ecd7c75 100644
--- a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
+++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
@@ -1378,6 +1378,15 @@
         m_pluginView = static_cast<PluginView*>(pluginWidget);
 }
 
+#if ENABLE(WEBGL)
+WebCore::WebGLLoadPolicy WebFrameLoaderClient::webGLPolicyForHost(const String& host) const
+{
+    if (WebPage* webPage = m_frame->page())
+        return webPage->getWebGLPolicyForHost(m_frame, host);
+    return WebGLAsk;
+}
+#endif // ENABLE(WEBGL)
+
 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const URL&, const Vector<String>& paramNames, const Vector<String>& paramValues)
 {
 #if ENABLE(NETSCAPE_PLUGIN_API)
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h
index dbd3fad..cfec790 100644
--- a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h
+++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h
@@ -194,6 +194,10 @@
     virtual void recreatePlugin(WebCore::Widget*) OVERRIDE;
     virtual void redirectDataToPlugin(WebCore::Widget* pluginWidget) OVERRIDE;
     
+#if ENABLE(WEBGL)
+    virtual WebCore::WebGLLoadPolicy webGLPolicyForHost(const String&) const OVERRIDE;
+#endif // ENABLE(WEBGL)
+
     virtual PassRefPtr<WebCore::Widget> createJavaAppletWidget(const WebCore::IntSize&, WebCore::HTMLAppletElement*, const WebCore::URL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) OVERRIDE;
     
 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
index ab7d12e..a866a7e 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -590,6 +590,19 @@
 
 #endif // ENABLE(NETSCAPE_PLUGIN_API)
 
+#if ENABLE(WEBGL)
+WebCore::WebGLLoadPolicy WebPage::getWebGLPolicyForHost(WebFrame* frame, const String& url)
+{
+    WebGLLoadPolicy defaultPolicy = WebGLAsk;
+    uint32_t policyResult = 0;
+    // FIXME: Get rid of sendSync in favor of a non-blocking strategy.
+    sendSync(Messages::WebPageProxy::WebGLPolicyForHost(url), Messages::WebPageProxy::WebGLPolicyForHost::Reply(policyResult));
+    if (policyResult)
+        return static_cast<WebGLLoadPolicy>(policyResult);
+    return defaultPolicy;
+}
+#endif // ENABLE(WEBGL)
+
 EditorState WebPage::editorState() const
 {
     Frame& frame = m_page->focusController().focusedOrMainFrame();
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h
index a558917..65471b6 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h
@@ -287,6 +287,10 @@
     PassRefPtr<Plugin> createPlugin(WebFrame*, WebCore::HTMLPlugInElement*, const Plugin::Parameters&, String& newMIMEType);
 #endif
 
+#if ENABLE(WEBGL)
+    WebCore::WebGLLoadPolicy getWebGLPolicyForHost(WebFrame*, const String&);
+#endif // ENABLE(WEBGL)
+    
     EditorState editorState() const;
 
     String renderTreeExternalRepresentation() const;
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index e9d04b3..894a482 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,16 @@
+2014-01-13  Roger Fong  <roger_fong@apple.com>
+
+        Add support for handling WebGL load policies.
+        https://bugs.webkit.org/show_bug.cgi?id=126935
+        <rdar://problem/15790448>.
+
+        Reviewed by Brent Fulgham.
+
+        * MiniBrowser/mac/WK2BrowserWindowController.m:
+        (-[WK2BrowserWindowController awakeFromNib]):
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::createWebViewWithOptions):
+
 2014-01-14  Zan Dobersek  <zdobersek@igalia.com>
 
         [GTK] Skip FontConfig initialization in WebKitTestRunner if requested
diff --git a/Tools/MiniBrowser/mac/WK2BrowserWindowController.m b/Tools/MiniBrowser/mac/WK2BrowserWindowController.m
index 5b37be6..7badb1b 100644
--- a/Tools/MiniBrowser/mac/WK2BrowserWindowController.m
+++ b/Tools/MiniBrowser/mac/WK2BrowserWindowController.m
@@ -581,6 +581,7 @@
         0, // showColorPicker
         0, // hideColorPicker
         0, // unavailablePluginButtonClicked
+        0, // webGLContextCreated
     };
     WKPageSetPageUIClient(_webView.pageRef, &uiClient.base);
 }
diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp
index 2b973c1..3cbdb53 100644
--- a/Tools/WebKitTestRunner/TestController.cpp
+++ b/Tools/WebKitTestRunner/TestController.cpp
@@ -242,6 +242,7 @@
         0, // showColorPicker
         0, // hideColorPicker
         0, // unavailablePluginButtonClicked
+        0, // webGLContextCreated
     };
     WKPageSetPageUIClient(newPage, &otherPageUIClient.base);
 
@@ -419,6 +420,7 @@
         0, // showColorPicker
         0, // hideColorPicker
         unavailablePluginButtonClicked,
+        0, // webGLContextCreated
     };
     WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient.base);
 
@@ -460,6 +462,7 @@
         0, // pluginLoadPolicy_deprecatedForUseWithV2
         0, // pluginDidFail
         pluginLoadPolicy, // pluginLoadPolicy
+        0, // webGLLoadPolicy
     };
     WKPageSetPageLoaderClient(m_mainWebView->page(), &pageLoaderClient.base);