1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.android_webview.test; 6 7import android.test.suitebuilder.annotation.SmallTest; 8 9import org.chromium.android_webview.AwContents; 10import org.chromium.android_webview.permission.AwPermissionRequest; 11import org.chromium.android_webview.test.util.CommonResources; 12import org.chromium.base.test.util.Feature; 13import org.chromium.content.browser.test.util.CallbackHelper; 14import org.chromium.net.test.util.TestWebServer; 15 16import java.util.concurrent.Callable; 17 18/** 19 * Test MediaAccessPermissionRequest. 20 */ 21public class MediaAccessPermissionRequestTest extends AwTestBase { 22 private static class OnPermissionRequestHelper extends CallbackHelper { 23 private boolean mCanceled; 24 25 public void notifyCanceled() { 26 mCanceled = true; 27 notifyCalled(); 28 } 29 30 public boolean canceled() { 31 return mCanceled; 32 } 33 } 34 35 private static final String mData = "<html> <script> " + 36 "var constraints = {audio: true, video: true};" + 37 "var video = document.querySelector('video');" + 38 "function successCallback(stream) {" + 39 "window.document.title = 'grant';" + 40 "if (window.URL) {" + 41 "video.src = window.URL.createObjectURL(stream);" + 42 "} else {" + 43 "video.src = stream;" + 44 "}" + 45 "}" + 46 "function errorCallback(error){" + 47 "window.document.title = 'deny';" + 48 "console.log('navigator.getUserMedia error: ', error);" + 49 "}" + 50 "navigator.webkitGetUserMedia(constraints, successCallback, errorCallback)" + 51 " </script><body>" + 52 "<video autoplay></video>" + 53 "</body></html>"; 54 55 private TestWebServer mTestWebServer; 56 private String mWebRTCPage; 57 58 @Override 59 protected void setUp() throws Exception { 60 super.setUp(); 61 mTestWebServer = new TestWebServer(false); 62 mWebRTCPage = mTestWebServer.setResponse("/WebRTC", mData, 63 CommonResources.getTextHtmlHeaders(true)); 64 } 65 66 @Override 67 protected void tearDown() throws Exception { 68 mTestWebServer.shutdown(); 69 mTestWebServer = null; 70 super.tearDown(); 71 } 72 73 @Feature({"AndroidWebView"}) 74 @SmallTest 75 public void testGrantAccess() throws Throwable { 76 final OnPermissionRequestHelper helper = new OnPermissionRequestHelper(); 77 TestAwContentsClient contentsClient = 78 new TestAwContentsClient() { 79 @Override 80 public void onPermissionRequest(AwPermissionRequest awPermissionRequest) { 81 awPermissionRequest.grant(); 82 helper.notifyCalled(); 83 } 84 }; 85 final AwTestContainerView testContainerView = 86 createAwTestContainerViewOnMainSync(contentsClient); 87 final AwContents awContents = testContainerView.getAwContents(); 88 enableJavaScriptOnUiThread(awContents); 89 int callCount = helper.getCallCount(); 90 loadUrlAsync(awContents, mWebRTCPage, null); 91 helper.waitForCallback(callCount); 92 pollTitleAs("grant", awContents); 93 } 94 95 @Feature({"AndroidWebView"}) 96 @SmallTest 97 public void testDenyAccess() throws Throwable { 98 final OnPermissionRequestHelper helper = new OnPermissionRequestHelper(); 99 TestAwContentsClient contentsClient = 100 new TestAwContentsClient() { 101 @Override 102 public void onPermissionRequest(AwPermissionRequest awPermissionRequest) { 103 awPermissionRequest.deny(); 104 helper.notifyCalled(); 105 } 106 }; 107 final AwTestContainerView testContainerView = 108 createAwTestContainerViewOnMainSync(contentsClient); 109 final AwContents awContents = testContainerView.getAwContents(); 110 enableJavaScriptOnUiThread(awContents); 111 int callCount = helper.getCallCount(); 112 loadUrlAsync(awContents, mWebRTCPage, null); 113 helper.waitForCallback(callCount); 114 pollTitleAs("deny", awContents); 115 } 116 117 private void pollTitleAs(final String title, final AwContents awContents) 118 throws Exception { 119 poll(new Callable<Boolean>() { 120 @Override 121 public Boolean call() throws Exception { 122 return title.equals(getTitleOnUiThread(awContents)); 123 } 124 }); 125 } 126 127 @Feature({"AndroidWebView"}) 128 @SmallTest 129 public void testCancelPermission() throws Throwable { 130 final OnPermissionRequestHelper helper = new OnPermissionRequestHelper(); 131 TestAwContentsClient contentsClient = 132 new TestAwContentsClient() { 133 private AwPermissionRequest mRequest; 134 @Override 135 public void onPermissionRequest(AwPermissionRequest awPermissionRequest) { 136 assertNull(mRequest); 137 mRequest = awPermissionRequest; 138 // Don't respond and wait for the request canceled. 139 helper.notifyCalled(); 140 } 141 @Override 142 public void onPermissionRequestCanceled( 143 AwPermissionRequest awPermissionRequest) { 144 assertNotNull(mRequest); 145 if (mRequest == awPermissionRequest) helper.notifyCanceled(); 146 mRequest = null; 147 } 148 }; 149 final AwTestContainerView testContainerView = 150 createAwTestContainerViewOnMainSync(contentsClient); 151 final AwContents awContents = testContainerView.getAwContents(); 152 enableJavaScriptOnUiThread(awContents); 153 int callCount = helper.getCallCount(); 154 loadUrlAsync(awContents, mWebRTCPage, null); 155 helper.waitForCallback(callCount); 156 callCount = helper.getCallCount(); 157 // Load the same page again, the previous request should be canceled. 158 loadUrlAsync(awContents, mWebRTCPage, null); 159 helper.waitForCallback(callCount); 160 assertTrue(helper.canceled()); 161 } 162} 163