• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.webkit.cts;
18 
19 import android.cts.util.NullWebViewUtils;
20 import android.cts.util.PollingCheck;
21 import android.graphics.Bitmap;
22 import android.os.Message;
23 import android.test.ActivityInstrumentationTestCase2;
24 import android.view.ViewGroup;
25 import android.webkit.JsPromptResult;
26 import android.webkit.JsResult;
27 import android.webkit.WebIconDatabase;
28 import android.webkit.WebSettings;
29 import android.webkit.WebView;
30 import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
31 
32 public class WebChromeClientTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
33     private static final long TEST_TIMEOUT = 5000L;
34 
35     private CtsTestServer mWebServer;
36     private WebIconDatabase mIconDb;
37     private WebViewOnUiThread mOnUiThread;
38     private boolean mBlockWindowCreationSync;
39     private boolean mBlockWindowCreationAsync;
40 
WebChromeClientTest()41     public WebChromeClientTest() {
42         super(WebViewCtsActivity.class);
43     }
44 
45     @Override
setUp()46     protected void setUp() throws Exception {
47         super.setUp();
48         WebView webview = getActivity().getWebView();
49         if (webview != null) {
50             mOnUiThread = new WebViewOnUiThread(this, webview);
51         }
52         mWebServer = new CtsTestServer(getActivity());
53     }
54 
55     @Override
tearDown()56     protected void tearDown() throws Exception {
57         if (mOnUiThread != null) {
58             mOnUiThread.cleanUp();
59         }
60         if (mWebServer != null) {
61             mWebServer.shutdown();
62         }
63         if (mIconDb != null) {
64             mIconDb.removeAllIcons();
65             mIconDb.close();
66         }
67         super.tearDown();
68     }
69 
testOnProgressChanged()70     public void testOnProgressChanged() {
71         if (!NullWebViewUtils.isWebViewAvailable()) {
72             return;
73         }
74         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
75         mOnUiThread.setWebChromeClient(webChromeClient);
76 
77         assertFalse(webChromeClient.hadOnProgressChanged());
78         String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
79         mOnUiThread.loadUrlAndWaitForCompletion(url);
80 
81         new PollingCheck(TEST_TIMEOUT) {
82             @Override
83             protected boolean check() {
84                 return webChromeClient.hadOnProgressChanged();
85             }
86         }.run();
87     }
88 
testOnReceivedTitle()89     public void testOnReceivedTitle() throws Exception {
90         if (!NullWebViewUtils.isWebViewAvailable()) {
91             return;
92         }
93         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
94         mOnUiThread.setWebChromeClient(webChromeClient);
95 
96         assertFalse(webChromeClient.hadOnReceivedTitle());
97         String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
98         mOnUiThread.loadUrlAndWaitForCompletion(url);
99 
100         new PollingCheck(TEST_TIMEOUT) {
101             @Override
102             protected boolean check() {
103                 return webChromeClient.hadOnReceivedTitle();
104             }
105         }.run();
106         assertTrue(webChromeClient.hadOnReceivedTitle());
107         assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, webChromeClient.getPageTitle());
108     }
109 
testOnReceivedIcon()110     public void testOnReceivedIcon() throws Throwable {
111         if (!NullWebViewUtils.isWebViewAvailable()) {
112             return;
113         }
114         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
115         mOnUiThread.setWebChromeClient(webChromeClient);
116 
117         runTestOnUiThread(new Runnable() {
118             @Override
119             public void run() {
120                 // getInstance must run on the UI thread
121                 mIconDb = WebIconDatabase.getInstance();
122                 String dbPath = getActivity().getFilesDir().toString() + "/icons";
123                 mIconDb.open(dbPath);
124             }
125         });
126         getInstrumentation().waitForIdleSync();
127         Thread.sleep(100); // Wait for open to be received on the icon db thread.
128 
129         assertFalse(webChromeClient.hadOnReceivedIcon());
130         assertNull(mOnUiThread.getFavicon());
131 
132         String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
133         mOnUiThread.loadUrlAndWaitForCompletion(url);
134 
135         new PollingCheck(TEST_TIMEOUT) {
136             @Override
137             protected boolean check() {
138                 return webChromeClient.hadOnReceivedIcon();
139             }
140         }.run();
141         assertNotNull(mOnUiThread.getFavicon());
142     }
143 
runWindowTest(boolean expectWindowClose)144     public void runWindowTest(boolean expectWindowClose) throws Exception {
145         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
146         mOnUiThread.setWebChromeClient(webChromeClient);
147 
148         final WebSettings settings = mOnUiThread.getSettings();
149         settings.setJavaScriptEnabled(true);
150         settings.setJavaScriptCanOpenWindowsAutomatically(true);
151         settings.setSupportMultipleWindows(true);
152 
153         assertFalse(webChromeClient.hadOnCreateWindow());
154 
155         // Load a page that opens a child window and sets a timeout after which the child
156         // will be closed.
157         mOnUiThread.loadUrlAndWaitForCompletion(mWebServer.
158                 getAssetUrl(TestHtmlConstants.JS_WINDOW_URL));
159 
160         new PollingCheck(TEST_TIMEOUT) {
161             @Override
162             protected boolean check() {
163                 return webChromeClient.hadOnCreateWindow();
164             }
165         }.run();
166 
167         if (expectWindowClose) {
168             new PollingCheck(TEST_TIMEOUT) {
169                 @Override
170                 protected boolean check() {
171                     return webChromeClient.hadOnCloseWindow();
172                 }
173             }.run();
174         } else {
175             assertFalse(webChromeClient.hadOnCloseWindow());
176         }
177     }
testWindows()178     public void testWindows() throws Exception {
179         if (!NullWebViewUtils.isWebViewAvailable()) {
180             return;
181         }
182         runWindowTest(true);
183     }
184 
testBlockWindowsSync()185     public void testBlockWindowsSync() throws Exception {
186         if (!NullWebViewUtils.isWebViewAvailable()) {
187             return;
188         }
189         mBlockWindowCreationSync = true;
190         runWindowTest(false);
191     }
192 
testBlockWindowsAsync()193     public void testBlockWindowsAsync() throws Exception {
194         if (!NullWebViewUtils.isWebViewAvailable()) {
195             return;
196         }
197         mBlockWindowCreationAsync = true;
198         runWindowTest(false);
199     }
200 
testOnJsBeforeUnload()201     public void testOnJsBeforeUnload() throws Exception {
202         if (!NullWebViewUtils.isWebViewAvailable()) {
203             return;
204         }
205         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
206         mOnUiThread.setWebChromeClient(webChromeClient);
207 
208         final WebSettings settings = mOnUiThread.getSettings();
209         settings.setJavaScriptEnabled(true);
210         settings.setJavaScriptCanOpenWindowsAutomatically(true);
211 
212         assertFalse(webChromeClient.hadOnJsBeforeUnload());
213 
214         mOnUiThread.loadUrlAndWaitForCompletion(mWebServer.getAssetUrl(TestHtmlConstants.JS_UNLOAD_URL));
215         // unload should trigger when we try to navigate away
216         mOnUiThread.loadUrlAndWaitForCompletion(mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
217 
218         new PollingCheck(TEST_TIMEOUT) {
219             @Override
220             protected boolean check() {
221                 return webChromeClient.hadOnJsBeforeUnload();
222             }
223         }.run();
224         assertEquals(webChromeClient.getMessage(), "testOnJsBeforeUnload");
225     }
226 
testOnJsAlert()227     public void testOnJsAlert() throws Exception {
228         if (!NullWebViewUtils.isWebViewAvailable()) {
229             return;
230         }
231         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
232         mOnUiThread.setWebChromeClient(webChromeClient);
233 
234         final WebSettings settings = mOnUiThread.getSettings();
235         settings.setJavaScriptEnabled(true);
236         settings.setJavaScriptCanOpenWindowsAutomatically(true);
237 
238         assertFalse(webChromeClient.hadOnJsAlert());
239 
240         String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_ALERT_URL);
241         mOnUiThread.loadUrlAndWaitForCompletion(url);
242 
243         new PollingCheck(TEST_TIMEOUT) {
244             @Override
245             protected boolean check() {
246                 return webChromeClient.hadOnJsAlert();
247             }
248         }.run();
249         assertEquals(webChromeClient.getMessage(), "testOnJsAlert");
250     }
251 
testOnJsConfirm()252     public void testOnJsConfirm() throws Exception {
253         if (!NullWebViewUtils.isWebViewAvailable()) {
254             return;
255         }
256         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
257         mOnUiThread.setWebChromeClient(webChromeClient);
258 
259         final WebSettings settings = mOnUiThread.getSettings();
260         settings.setJavaScriptEnabled(true);
261         settings.setJavaScriptCanOpenWindowsAutomatically(true);
262 
263         assertFalse(webChromeClient.hadOnJsConfirm());
264 
265         String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_CONFIRM_URL);
266         mOnUiThread.loadUrlAndWaitForCompletion(url);
267 
268         new PollingCheck(TEST_TIMEOUT) {
269             @Override
270             protected boolean check() {
271                 return webChromeClient.hadOnJsConfirm();
272             }
273         }.run();
274         assertEquals(webChromeClient.getMessage(), "testOnJsConfirm");
275     }
276 
testOnJsPrompt()277     public void testOnJsPrompt() throws Exception {
278         if (!NullWebViewUtils.isWebViewAvailable()) {
279             return;
280         }
281         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
282         mOnUiThread.setWebChromeClient(webChromeClient);
283 
284         final WebSettings settings = mOnUiThread.getSettings();
285         settings.setJavaScriptEnabled(true);
286         settings.setJavaScriptCanOpenWindowsAutomatically(true);
287 
288         assertFalse(webChromeClient.hadOnJsPrompt());
289 
290         final String promptResult = "CTS";
291         webChromeClient.setPromptResult(promptResult);
292         String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_PROMPT_URL);
293         mOnUiThread.loadUrlAndWaitForCompletion(url);
294 
295         new PollingCheck(TEST_TIMEOUT) {
296             @Override
297             protected boolean check() {
298                 return webChromeClient.hadOnJsPrompt();
299             }
300         }.run();
301         // the result returned by the client gets set as the page title
302         new PollingCheck(TEST_TIMEOUT) {
303             @Override
304             protected boolean check() {
305                 return mOnUiThread.getTitle().equals(promptResult);
306             }
307         }.run();
308         assertEquals(webChromeClient.getMessage(), "testOnJsPrompt");
309     }
310 
311     private class MockWebChromeClient extends WaitForProgressClient {
312         private boolean mHadOnProgressChanged;
313         private boolean mHadOnReceivedTitle;
314         private String mPageTitle;
315         private boolean mHadOnJsAlert;
316         private boolean mHadOnJsConfirm;
317         private boolean mHadOnJsPrompt;
318         private boolean mHadOnJsBeforeUnload;
319         private String mMessage;
320         private String mPromptResult;
321         private boolean mHadOnCloseWindow;
322         private boolean mHadOnCreateWindow;
323         private boolean mHadOnRequestFocus;
324         private boolean mHadOnReceivedIcon;
325 
MockWebChromeClient()326         public MockWebChromeClient() {
327             super(mOnUiThread);
328         }
329 
setPromptResult(String promptResult)330         public void setPromptResult(String promptResult) {
331             mPromptResult = promptResult;
332         }
333 
hadOnProgressChanged()334         public boolean hadOnProgressChanged() {
335             return mHadOnProgressChanged;
336         }
337 
hadOnReceivedTitle()338         public boolean hadOnReceivedTitle() {
339             return mHadOnReceivedTitle;
340         }
341 
getPageTitle()342         public String getPageTitle() {
343             return mPageTitle;
344         }
345 
hadOnJsAlert()346         public boolean hadOnJsAlert() {
347             return mHadOnJsAlert;
348         }
349 
hadOnJsConfirm()350         public boolean hadOnJsConfirm() {
351             return mHadOnJsConfirm;
352         }
353 
hadOnJsPrompt()354         public boolean hadOnJsPrompt() {
355             return mHadOnJsPrompt;
356         }
357 
hadOnJsBeforeUnload()358         public boolean hadOnJsBeforeUnload() {
359             return mHadOnJsBeforeUnload;
360         }
361 
hadOnCreateWindow()362         public boolean hadOnCreateWindow() {
363             return mHadOnCreateWindow;
364         }
365 
hadOnCloseWindow()366         public boolean hadOnCloseWindow() {
367             return mHadOnCloseWindow;
368         }
369 
hadOnRequestFocus()370         public boolean hadOnRequestFocus() {
371             return mHadOnRequestFocus;
372         }
373 
hadOnReceivedIcon()374         public boolean hadOnReceivedIcon() {
375             return mHadOnReceivedIcon;
376         }
377 
getMessage()378         public String getMessage() {
379             return mMessage;
380         }
381 
382         @Override
onProgressChanged(WebView view, int newProgress)383         public void onProgressChanged(WebView view, int newProgress) {
384             super.onProgressChanged(view, newProgress);
385             mHadOnProgressChanged = true;
386         }
387 
388         @Override
onReceivedTitle(WebView view, String title)389         public void onReceivedTitle(WebView view, String title) {
390             super.onReceivedTitle(view, title);
391             mPageTitle = title;
392             mHadOnReceivedTitle = true;
393         }
394 
395         @Override
onJsAlert(WebView view, String url, String message, JsResult result)396         public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
397             super.onJsAlert(view, url, message, result);
398             mHadOnJsAlert = true;
399             mMessage = message;
400             result.confirm();
401             return true;
402         }
403 
404         @Override
onJsConfirm(WebView view, String url, String message, JsResult result)405         public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
406             super.onJsConfirm(view, url, message, result);
407             mHadOnJsConfirm = true;
408             mMessage = message;
409             result.confirm();
410             return true;
411         }
412 
413         @Override
onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)414         public boolean onJsPrompt(WebView view, String url, String message,
415                 String defaultValue, JsPromptResult result) {
416             super.onJsPrompt(view, url, message, defaultValue, result);
417             mHadOnJsPrompt = true;
418             mMessage = message;
419             result.confirm(mPromptResult);
420             return true;
421         }
422 
423         @Override
onJsBeforeUnload(WebView view, String url, String message, JsResult result)424         public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
425             super.onJsBeforeUnload(view, url, message, result);
426             mHadOnJsBeforeUnload = true;
427             mMessage = message;
428             result.confirm();
429             return true;
430         }
431 
432         @Override
onCloseWindow(WebView window)433         public void onCloseWindow(WebView window) {
434             super.onCloseWindow(window);
435             mHadOnCloseWindow = true;
436         }
437 
438         @Override
onCreateWindow(WebView view, boolean dialog, boolean userGesture, Message resultMsg)439         public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture,
440                 Message resultMsg) {
441             mHadOnCreateWindow = true;
442             if (mBlockWindowCreationSync) {
443                 return false;
444             }
445             WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
446             if (mBlockWindowCreationAsync) {
447                 transport.setWebView(null);
448             } else {
449                 WebView childView = new WebView(getActivity());
450                 final WebSettings settings = childView.getSettings();
451                 settings.setJavaScriptEnabled(true);
452                 childView.setWebChromeClient(this);
453                 transport.setWebView(childView);
454                 getActivity().addContentView(childView, new ViewGroup.LayoutParams(
455                         ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
456             }
457             resultMsg.sendToTarget();
458             return true;
459         }
460 
461         @Override
onRequestFocus(WebView view)462         public void onRequestFocus(WebView view) {
463             mHadOnRequestFocus = true;
464         }
465 
466         @Override
onReceivedIcon(WebView view, Bitmap icon)467         public void onReceivedIcon(WebView view, Bitmap icon) {
468             mHadOnReceivedIcon = true;
469         }
470     }
471 }
472