Add a new SPI for controlling getUserMedia
[WebKit-https.git] / Source / WebKit / UIProcess / API / glib / WebKitUIClient.cpp
1 /*
2  * Copyright (C) 2011, 2012 Igalia S.L.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21 #include "WebKitUIClient.h"
22
23 #include "APIUIClient.h"
24 #include "DrawingAreaProxy.h"
25 #include "WebKitDeviceInfoPermissionRequestPrivate.h"
26 #include "WebKitFileChooserRequestPrivate.h"
27 #include "WebKitGeolocationPermissionRequestPrivate.h"
28 #include "WebKitNavigationActionPrivate.h"
29 #include "WebKitNotificationPermissionRequestPrivate.h"
30 #include "WebKitURIRequestPrivate.h"
31 #include "WebKitUserMediaPermissionRequestPrivate.h"
32 #include "WebKitWebViewPrivate.h"
33 #include "WebKitWindowPropertiesPrivate.h"
34 #include "WebPageProxy.h"
35 #include "WebProcessProxy.h"
36 #include "WebsiteDataStore.h"
37 #include <wtf/glib/GRefPtr.h>
38
39 #if PLATFORM(GTK)
40 #include <WebCore/GtkUtilities.h>
41 #endif
42
43 using namespace WebKit;
44
45 class UIClient : public API::UIClient {
46 public:
47     explicit UIClient(WebKitWebView* webView)
48         : m_webView(webView)
49     {
50     }
51
52 private:
53     void createNewPage(WebPageProxy& page, Ref<API::FrameInfo>&& frameInfo, WebCore::ResourceRequest&& resourceRequest, WebCore::WindowFeatures&& windowFeatures, NavigationActionData&& navigationActionData, CompletionHandler<void(RefPtr<WebPageProxy>&&)>&& completionHandler) final
54     {
55         auto userInitiatedActivity = page.process().userInitiatedActivity(navigationActionData.userGestureTokenIdentifier);
56         WebKitNavigationAction navigationAction(API::NavigationAction::create(WTFMove(navigationActionData), frameInfo.ptr(), nullptr, WTF::nullopt, WTFMove(resourceRequest), URL { }, false, WTFMove(userInitiatedActivity)));
57         completionHandler(webkitWebViewCreateNewPage(m_webView, windowFeatures, &navigationAction));
58     }
59
60     void showPage(WebPageProxy*) final
61     {
62         webkitWebViewReadyToShowPage(m_webView);
63     }
64
65     void close(WebPageProxy*) final
66     {
67         webkitWebViewClosePage(m_webView);
68     }
69
70     void runJavaScriptAlert(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void()>&& completionHandler) final
71     {
72         webkitWebViewRunJavaScriptAlert(m_webView, message.utf8(), WTFMove(completionHandler));
73     }
74
75     void runJavaScriptConfirm(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void(bool)>&& completionHandler) final
76     {
77         webkitWebViewRunJavaScriptConfirm(m_webView, message.utf8(), WTFMove(completionHandler));
78     }
79
80     void runJavaScriptPrompt(WebPageProxy*, const String& message, const String& defaultValue, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void(const String&)>&& completionHandler) final
81     {
82         webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8(), WTFMove(completionHandler));
83     }
84
85     bool canRunBeforeUnloadConfirmPanel() const final { return true; }
86
87     void runBeforeUnloadConfirmPanel(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void(bool)>&& completionHandler) final
88     {
89         webkitWebViewRunJavaScriptBeforeUnloadConfirm(m_webView, message.utf8(), WTFMove(completionHandler));
90     }
91
92     void mouseDidMoveOverElement(WebPageProxy&, const WebHitTestResultData& data, WebEvent::Modifiers modifiers, API::Object*) final
93     {
94         webkitWebViewMouseTargetChanged(m_webView, data, modifiers);
95     }
96
97     void toolbarsAreVisible(WebPageProxy&, Function<void(bool)>&& completionHandler) final
98     {
99         completionHandler(webkit_window_properties_get_toolbar_visible(webkit_web_view_get_window_properties(m_webView)));
100     }
101
102     void setToolbarsAreVisible(WebPageProxy&, bool visible) final
103     {
104         webkitWindowPropertiesSetToolbarVisible(webkit_web_view_get_window_properties(m_webView), visible);
105     }
106
107     void menuBarIsVisible(WebPageProxy&, Function<void(bool)>&& completionHandler) final
108     {
109         completionHandler(webkit_window_properties_get_menubar_visible(webkit_web_view_get_window_properties(m_webView)));
110     }
111
112     void setMenuBarIsVisible(WebPageProxy&, bool visible) final
113     {
114         webkitWindowPropertiesSetToolbarVisible(webkit_web_view_get_window_properties(m_webView), visible);
115     }
116
117     void statusBarIsVisible(WebPageProxy&, Function<void(bool)>&& completionHandler) final
118     {
119         completionHandler(webkit_window_properties_get_statusbar_visible(webkit_web_view_get_window_properties(m_webView)));
120     }
121
122     void setStatusBarIsVisible(WebPageProxy&, bool visible) final
123     {
124         webkitWindowPropertiesSetStatusbarVisible(webkit_web_view_get_window_properties(m_webView), visible);
125     }
126
127     void setIsResizable(WebPageProxy&, bool resizable) final
128     {
129         webkitWindowPropertiesSetResizable(webkit_web_view_get_window_properties(m_webView), resizable);
130     }
131
132     void setWindowFrame(WebPageProxy&, const WebCore::FloatRect& frame) final
133     {
134 #if PLATFORM(GTK)
135         GdkRectangle geometry = WebCore::IntRect(frame);
136         GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView));
137         if (webkit_web_view_is_controlled_by_automation(m_webView) && WebCore::widgetIsOnscreenToplevelWindow(window) && gtk_widget_get_visible(window)) {
138             if (geometry.x >= 0 && geometry.y >= 0)
139                 gtk_window_move(GTK_WINDOW(window), geometry.x, geometry.y);
140             if (geometry.width > 0 && geometry.height > 0)
141                 gtk_window_resize(GTK_WINDOW(window), geometry.width, geometry.height);
142         } else
143             webkitWindowPropertiesSetGeometry(webkit_web_view_get_window_properties(m_webView), &geometry);
144 #endif
145     }
146
147     void windowFrame(WebPageProxy&, Function<void(WebCore::FloatRect)>&& completionHandler) final
148     {
149 #if PLATFORM(GTK)
150         GdkRectangle geometry = { 0, 0, 0, 0 };
151         GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView));
152         if (WebCore::widgetIsOnscreenToplevelWindow(window) && gtk_widget_get_visible(window)) {
153             gtk_window_get_position(GTK_WINDOW(window), &geometry.x, &geometry.y);
154             gtk_window_get_size(GTK_WINDOW(window), &geometry.width, &geometry.height);
155         }
156         completionHandler(WebCore::FloatRect(geometry));
157 #elif PLATFORM(WPE)
158         // FIXME: I guess this is actually the view size in WPE. We need more refactoring here.
159         WebCore::FloatRect rect;
160         auto& page = webkitWebViewGetPage(m_webView);
161         if (page.drawingArea())
162             rect.setSize(page.drawingArea()->size());
163         completionHandler(WTFMove(rect));
164 #endif
165     }
166
167     void exceededDatabaseQuota(WebPageProxy*, WebFrameProxy*, API::SecurityOrigin*, const String&, const String&, unsigned long long /*currentQuota*/, unsigned long long /*currentOriginUsage*/, unsigned long long /*currentDatabaseUsage*/, unsigned long long /*expectedUsage*/, Function<void(unsigned long long)>&& completionHandler) final
168     {
169         static const unsigned long long defaultQuota = 5 * 1024 * 1204; // 5 MB
170         // FIXME: Provide API for this.
171         completionHandler(defaultQuota);
172     }
173
174     bool runOpenPanel(WebPageProxy*, WebFrameProxy*, const WebCore::SecurityOriginData&, API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) final
175     {
176         GRefPtr<WebKitFileChooserRequest> request = adoptGRef(webkitFileChooserRequestCreate(parameters, listener));
177         webkitWebViewRunFileChooserRequest(m_webView, request.get());
178         return true;
179     }
180
181     void decidePolicyForGeolocationPermissionRequest(WebPageProxy&, WebFrameProxy&, API::SecurityOrigin&, Function<void(bool)>& completionHandler) final
182     {
183         GRefPtr<WebKitGeolocationPermissionRequest> geolocationPermissionRequest = adoptGRef(webkitGeolocationPermissionRequestCreate(GeolocationPermissionRequest::create(std::exchange(completionHandler, nullptr)).ptr()));
184         webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(geolocationPermissionRequest.get()));
185     }
186
187     void decidePolicyForUserMediaPermissionRequest(WebPageProxy&, WebFrameProxy&, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionRequestProxy& permissionRequest) final
188     {
189         GRefPtr<WebKitUserMediaPermissionRequest> userMediaPermissionRequest = adoptGRef(webkitUserMediaPermissionRequestCreate(permissionRequest, userMediaDocumentOrigin, topLevelDocumentOrigin));
190         webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(userMediaPermissionRequest.get()));
191     }
192
193     void checkUserMediaPermissionForOrigin(WebPageProxy& page, WebFrameProxy&, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionCheckProxy& permissionRequest) override
194     {
195         auto deviceInfoPermissionRequest = adoptGRef(webkitDeviceInfoPermissionRequestCreate(permissionRequest, &page.websiteDataStore().deviceIdHashSaltStorage()));
196         webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(deviceInfoPermissionRequest.get()));
197     }
198
199     void decidePolicyForNotificationPermissionRequest(WebPageProxy&, API::SecurityOrigin&, Function<void(bool)>&& completionHandler) final
200     {
201         GRefPtr<WebKitNotificationPermissionRequest> notificationPermissionRequest = adoptGRef(webkitNotificationPermissionRequestCreate(NotificationPermissionRequest::create(WTFMove(completionHandler)).ptr()));
202         webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(notificationPermissionRequest.get()));
203     }
204
205 #if PLATFORM(GTK)
206     void printFrame(WebPageProxy&, WebFrameProxy& frame) final
207     {
208         webkitWebViewPrintFrame(m_webView, &frame);
209     }
210 #endif
211
212     bool canRunModal() const final { return true; }
213
214     void runModal(WebPageProxy&) final
215     {
216         webkitWebViewRunAsModal(m_webView);
217     }
218
219     void isPlayingMediaDidChange(WebPageProxy&) final
220     {
221         webkitWebViewIsPlayingAudioChanged(m_webView);
222     }
223
224     WebKitWebView* m_webView;
225 };
226
227 void attachUIClientToView(WebKitWebView* webView)
228 {
229     webkitWebViewGetPage(webView).setUIClient(std::make_unique<UIClient>(webView));
230 }
231