Process Swap on Navigation causes many webpages to hang due to attempted process...
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKitCocoa / UserMediaDisabled.mm
1 /*
2  * Copyright (C) 2016 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 #import "config.h"
27
28 #import "PlatformUtilities.h"
29 #import "Test.h"
30 #import "TestWKWebView.h"
31
32 #import <WebKit/WKPreferencesPrivate.h>
33 #import <WebKit/WKUserContentControllerPrivate.h>
34 #import <WebKit/WKWebViewConfigurationPrivate.h>
35 #import <WebKit/WKWebViewPrivate.h>
36 #import <WebKit/WebKit.h>
37 #import <WebKit/_WKProcessPoolConfiguration.h>
38 #import <wtf/RetainPtr.h>
39
40 #if WK_API_ENABLED
41
42 static bool refuseRequest = false;
43 static bool wasPrompted = false;
44
45 static bool receivedScriptMessage = false;
46 static RetainPtr<WKScriptMessage> lastScriptMessage;
47
48 @interface UserMediaMessageHandler : NSObject <WKScriptMessageHandler>
49 @end
50
51 @implementation UserMediaMessageHandler
52
53 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
54 {
55     lastScriptMessage = message;
56     receivedScriptMessage = true;
57 }
58 @end
59
60 @interface UserMediaUIDelegate : NSObject <WKUIDelegate>
61 @end
62
63 @implementation UserMediaUIDelegate
64
65 - (void)_webView:(WKWebView *)webView requestUserMediaAuthorizationForDevices:(NSUInteger)devices url:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL decisionHandler:(void (^)(BOOL))decisionHandler
66 {
67     wasPrompted = true;
68
69     if (refuseRequest) {
70         decisionHandler(NO);
71         return;
72     }
73
74     BOOL needsMicrophoneAuthorized = devices & _WKCaptureDeviceMicrophone;
75     BOOL needsCameraAuthorized = devices & _WKCaptureDeviceCamera;
76     if (!needsMicrophoneAuthorized && !needsCameraAuthorized) {
77         decisionHandler(NO);
78         return;
79     }
80
81     decisionHandler(YES);
82 }
83
84 - (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *, BOOL))decisionHandler
85 {
86     if (refuseRequest) {
87         decisionHandler(nil, NO);
88         return;
89     }
90
91     decisionHandler(@"0x987654321", NO);
92 }
93 @end
94
95 class MediaCaptureDisabledTest : public testing::Test {
96 public:
97     virtual void SetUp()
98     {
99         m_configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
100
101         RetainPtr<UserMediaMessageHandler> handler = adoptNS([[UserMediaMessageHandler alloc] init]);
102         [[m_configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
103
104         m_webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:m_configuration.get()]);
105
106         auto preferences = [m_webView configuration].preferences;
107         preferences._mediaDevicesEnabled = YES;
108         preferences._mockCaptureDevicesEnabled = YES;
109         preferences._mediaCaptureRequiresSecureConnection = NO;
110
111         m_uiDelegate = adoptNS([[UserMediaUIDelegate alloc] init]);
112         [m_webView setUIDelegate:m_uiDelegate.get()];
113     }
114
115     void loadTestAndWaitForMessage(const char* message)
116     {
117         wasPrompted = false;
118         receivedScriptMessage = false;
119         [m_webView loadTestPageNamed:@"disableGetUserMedia"];
120         TestWebKitAPI::Util::run(&receivedScriptMessage);
121         EXPECT_STREQ([(NSString *)[lastScriptMessage body] UTF8String], message);
122     }
123
124     RetainPtr<WKWebViewConfiguration> m_configuration;
125     RetainPtr<UserMediaUIDelegate> m_uiDelegate;
126     RetainPtr<TestWKWebView> m_webView;
127 };
128
129 TEST_F(MediaCaptureDisabledTest, EnableAndDisable)
130 {
131     EXPECT_TRUE(m_webView.get()._mediaCaptureEnabled);
132     loadTestAndWaitForMessage("allowed");
133     EXPECT_TRUE(wasPrompted);
134
135     m_webView.get()._mediaCaptureEnabled = NO;
136     EXPECT_FALSE(m_webView.get()._mediaCaptureEnabled);
137     loadTestAndWaitForMessage("denied");
138     EXPECT_FALSE(wasPrompted);
139
140     m_webView.get()._mediaCaptureEnabled = YES;
141     EXPECT_TRUE(m_webView.get()._mediaCaptureEnabled);
142     loadTestAndWaitForMessage("allowed");
143     EXPECT_TRUE(wasPrompted);
144 }
145 #endif