Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / xwalk / test / android / core_internal / javatests / src / org / xwalk / core / internal / xwview / test / XWalkViewInternalTestBase.java
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Copyright (c) 2014 Intel Corporation. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 package org.xwalk.core.internal.xwview.test;
7
8 import android.app.Activity;
9 import android.content.Context;
10 import android.test.ActivityInstrumentationTestCase2;
11 import android.util.Log;
12 import android.view.Gravity;
13 import android.view.View;
14 import android.view.ViewGroup;
15 import android.view.WindowManager;
16 import android.webkit.WebResourceResponse;
17 import android.widget.FrameLayout;
18
19 import java.io.InputStream;
20 import java.io.IOException;
21 import java.util.concurrent.atomic.AtomicReference;
22 import java.util.concurrent.Callable;
23 import java.util.concurrent.FutureTask;
24 import java.util.concurrent.TimeoutException;
25 import java.util.concurrent.TimeUnit;
26
27 import junit.framework.Assert;
28
29 import org.chromium.content.browser.ContentViewCore;
30 import org.chromium.content.browser.test.util.CallbackHelper;
31 import org.chromium.content.browser.test.util.Criteria;
32 import org.chromium.content.browser.test.util.CriteriaHelper;
33
34 import org.xwalk.core.internal.XWalkNavigationHistoryInternal;
35 import org.xwalk.core.internal.XWalkNavigationItemInternal;
36 import org.xwalk.core.internal.XWalkResourceClientInternal;
37 import org.xwalk.core.internal.XWalkSettings;
38 import org.xwalk.core.internal.XWalkUIClientInternal;
39 import org.xwalk.core.internal.XWalkViewInternal;
40 import org.xwalk.core.internal.XWalkWebChromeClient;
41
42 public class XWalkViewInternalTestBase
43        extends ActivityInstrumentationTestCase2<XWalkViewInternalTestRunnerActivity> {
44     protected final static int WAIT_TIMEOUT_SECONDS = 15;
45     private final static String TAG = "XWalkViewInternalTestBase";
46     private XWalkViewInternal mXWalkViewInternal;
47     final TestHelperBridge mTestHelperBridge = new TestHelperBridge();
48
49     class TestXWalkUIClientInternalBase extends XWalkUIClientInternal {
50         TestHelperBridge mInnerContentsClient;
51         public TestXWalkUIClientInternalBase(TestHelperBridge client) {
52             super(getXWalkView());
53             mInnerContentsClient = client;
54         }
55
56         @Override
57         public void onPageLoadStarted(XWalkViewInternal view, String url) {
58             mInnerContentsClient.onPageStarted(url);
59         }
60
61         @Override
62         public void onPageLoadStopped(XWalkViewInternal view, String url, LoadStatusInternal status) {
63             mInnerContentsClient.onPageFinished(url);
64         }
65
66         @Override
67         public void onReceivedTitle(XWalkViewInternal view, String title) {
68             mInnerContentsClient.onTitleChanged(title);
69         }
70     }
71
72     class TestXWalkUIClientInternal extends TestXWalkUIClientInternalBase {
73         public TestXWalkUIClientInternal() {
74             super(mTestHelperBridge);
75         }
76     }
77
78     class TestXWalkResourceClientBase extends XWalkResourceClientInternal {
79         TestHelperBridge mInnerContentsClient;
80         public TestXWalkResourceClientBase(TestHelperBridge client) {
81             super(mXWalkViewInternal);
82             mInnerContentsClient = client;
83         }
84
85         @Override
86         public void onLoadStarted(XWalkViewInternal view, String url) {
87             mInnerContentsClient.onLoadStarted(url);
88         }
89
90         @Override
91         public void onReceivedLoadError(XWalkViewInternal view, int errorCode,
92                 String description, String failingUrl) {
93             mInnerContentsClient.onReceivedLoadError(errorCode, description, failingUrl);
94         }
95
96         @Override
97         public WebResourceResponse shouldInterceptLoadRequest(XWalkViewInternal view,
98                 String url) {
99             return mInnerContentsClient.shouldInterceptLoadRequest(url);
100         }
101     }
102
103     class TestXWalkResourceClient extends TestXWalkResourceClientBase {
104         public TestXWalkResourceClient() {
105             super(mTestHelperBridge);
106         }
107     }
108
109     class TestXWalkWebChromeClientBase extends XWalkWebChromeClient {
110         private CallbackHelper mOnShowCustomViewCallbackHelper = new CallbackHelper();
111         private CallbackHelper mOnHideCustomViewCallbackHelper = new CallbackHelper();
112
113         private Activity mActivity = getActivity();
114         private View mCustomView;
115         private XWalkWebChromeClient.CustomViewCallback mExitCallback;
116
117         public TestXWalkWebChromeClientBase() {
118             super(mXWalkViewInternal);
119         }
120
121         @Override
122         public void onShowCustomView(View view, XWalkWebChromeClient.CustomViewCallback callback) {
123             mCustomView = view;
124             mExitCallback = callback;
125             mActivity.getWindow().setFlags(
126                     WindowManager.LayoutParams.FLAG_FULLSCREEN,
127                     WindowManager.LayoutParams.FLAG_FULLSCREEN);
128
129             mActivity.getWindow().addContentView(view,
130                     new FrameLayout.LayoutParams(
131                             ViewGroup.LayoutParams.MATCH_PARENT,
132                             ViewGroup.LayoutParams.MATCH_PARENT,
133                             Gravity.CENTER));
134             mOnShowCustomViewCallbackHelper.notifyCalled();
135         }
136
137         @Override
138         public void onHideCustomView() {
139             mActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
140             mOnHideCustomViewCallbackHelper.notifyCalled();
141         }
142
143         public XWalkWebChromeClient.CustomViewCallback getExitCallback() {
144             return mExitCallback;
145         }
146
147         public View getCustomView() {
148             return mCustomView;
149         }
150
151         public boolean wasCustomViewShownCalled() {
152             return mOnShowCustomViewCallbackHelper.getCallCount() > 0;
153         }
154
155         public void waitForCustomViewShown() throws TimeoutException, InterruptedException {
156             mOnShowCustomViewCallbackHelper.waitForCallback(0, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
157         }
158
159         public void waitForCustomViewHidden() throws InterruptedException, TimeoutException {
160             mOnHideCustomViewCallbackHelper.waitForCallback(0, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
161         }
162     }
163
164     void setUIClient(final XWalkUIClientInternal client) {
165         getInstrumentation().runOnMainSync(new Runnable() {
166             @Override
167             public void run() {
168                 getXWalkView().setUIClient(client);
169             }
170         });
171     }
172
173     void setResourceClient(final XWalkResourceClientInternal client) {
174         getInstrumentation().runOnMainSync(new Runnable() {
175             @Override
176             public void run() {
177                 getXWalkView().setResourceClient(client);
178             }
179         });
180     }
181
182     void setXWalkWebChromeClient(final TestXWalkWebChromeClientBase client) {
183         getInstrumentation().runOnMainSync(new Runnable() {
184             @Override
185             public void run() {
186                 mXWalkViewInternal.setXWalkWebChromeClient(client);
187             }
188         });
189     }
190
191     static class ViewPair {
192         private final XWalkViewInternal view0;
193         private final TestHelperBridge client0;
194         private final XWalkViewInternal view1;
195         private final TestHelperBridge client1;
196
197         ViewPair(XWalkViewInternal view0, TestHelperBridge client0,
198                 XWalkViewInternal view1, TestHelperBridge client1) {
199             this.view0 = view0;
200             this.client0 = client0;
201             this.view1 = view1;
202             this.client1 = client1;
203         }
204
205         XWalkViewInternal getView0() {
206             return view0;
207         }
208
209         TestHelperBridge getClient0() {
210             return client0;
211         }
212
213         XWalkViewInternal getView1() {
214             return view1;
215         }
216
217         TestHelperBridge getClient1() {
218             return client1;
219         }
220     }
221
222     public XWalkViewInternalTestBase() {
223         super(XWalkViewInternalTestRunnerActivity.class);
224     }
225
226     @Override
227     protected void setUp() throws Exception {
228         super.setUp();
229
230         // Must call getActivity() here but not in main thread.
231         final Activity activity = getActivity();
232         getInstrumentation().runOnMainSync(new Runnable() {
233             @Override
234             public void run() {
235                 mXWalkViewInternal = new XWalkViewInternal(activity, activity);
236                 getActivity().addView(mXWalkViewInternal);
237                 mXWalkViewInternal.setUIClient(new TestXWalkUIClientInternal());
238                 mXWalkViewInternal.setResourceClient(new TestXWalkResourceClient());
239             }
240         });
241     }
242
243     protected boolean pollOnUiThread(final Callable<Boolean> callable) throws Exception {
244         return CriteriaHelper.pollForCriteria(new Criteria() {
245             @Override
246             public boolean isSatisfied() {
247                 try {
248                     return runTestOnUiThreadAndGetResult(callable);
249                 } catch (Throwable e) {
250                     return false;
251                 }
252             }
253         });
254     }
255
256     protected void loadJavaScriptUrl(final String url) throws Exception {
257         if (!url.startsWith("javascript:")) {
258             Log.w(TAG, "loadJavascriptUrl only accepts javascript: url");
259             return;
260         }
261         loadUrlAsync(url);
262     }
263
264     protected void loadUrlSync(final String url) throws Exception {
265         CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
266         int currentCallCount = pageFinishedHelper.getCallCount();
267         loadUrlAsync(url);
268
269         pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
270                 TimeUnit.SECONDS);
271     }
272
273     protected void loadUrlAsync(final String url) throws Exception {
274         getInstrumentation().runOnMainSync(new Runnable() {
275             @Override
276             public void run() {
277                 mXWalkViewInternal.load(url, null);
278             }
279         });
280     }
281
282     protected void loadDataSync(final String url, final String data, final String mimeType,
283             final boolean isBase64Encoded) throws Exception {
284         CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
285         int currentCallCount = pageFinishedHelper.getCallCount();
286         loadDataAsync(url, data, mimeType, isBase64Encoded);
287         pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
288                 TimeUnit.SECONDS);
289     }
290
291     protected void loadDataAsync(final String url, final String data, final String mimeType,
292              final boolean isBase64Encoded) throws Exception {
293         getInstrumentation().runOnMainSync(new Runnable() {
294             @Override
295             public void run() {
296                 mXWalkViewInternal.load(url, data);
297             }
298         });
299     }
300
301     protected void loadUrlSyncByContent(final XWalkViewInternal xWalkViewInternal,
302             final TestHelperBridge contentsClient,
303             final String url) throws Exception {
304         CallbackHelper pageFinishedHelper = contentsClient.getOnPageFinishedHelper();
305         int currentCallCount = pageFinishedHelper.getCallCount();
306         loadUrlAsyncByContent(xWalkViewInternal, url);
307
308         pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
309                 TimeUnit.SECONDS);
310     }
311
312     protected void loadUrlAsyncByContent(final XWalkViewInternal xWalkViewInternal,
313             final String url) throws Exception {
314         getInstrumentation().runOnMainSync(new Runnable() {
315             @Override
316             public void run() {
317                 xWalkViewInternal.load(url, null);
318             }
319         });
320     }
321
322     protected String getTitleOnUiThread() throws Exception {
323         return runTestOnUiThreadAndGetResult(new Callable<String>() {
324             @Override
325             public String call() throws Exception {
326                 return mXWalkViewInternal.getTitle();
327             }
328         });
329     }
330
331     protected <R> R runTestOnUiThreadAndGetResult(Callable<R> callable)
332             throws Exception {
333         FutureTask<R> task = new FutureTask<R>(callable);
334         getInstrumentation().waitForIdleSync();
335         getInstrumentation().runOnMainSync(task);
336         return task.get();
337     }
338
339     protected String getFileContent(String fileName) {
340         try {
341             Context context = getInstrumentation().getContext();
342             InputStream inputStream = context.getAssets().open(fileName);
343             int size = inputStream.available();
344             byte buffer[] = new byte[size];
345             inputStream.read(buffer);
346             inputStream.close();
347
348             String fileContent = new String(buffer);
349             return fileContent;
350         } catch (IOException e) {
351             throw new RuntimeException(e);
352         }
353     }
354
355     protected String getTitleOnUiThreadByContent(final XWalkViewInternal xWalkViewInternal) throws Exception {
356         return runTestOnUiThreadAndGetResult(new Callable<String>() {
357             @Override
358             public String call() throws Exception {
359                 String title = xWalkViewInternal.getTitle();
360                 return title;
361             }
362         });
363     }
364
365     protected XWalkSettings getXWalkSettingsOnUiThreadByContent(
366             final XWalkViewInternal xWalkViewInternal) throws Exception {
367         return runTestOnUiThreadAndGetResult(new Callable<XWalkSettings>() {
368             @Override
369             public XWalkSettings call() throws Exception {
370                 return xWalkViewInternal.getSettings();
371             }
372         });
373     }
374
375     protected XWalkViewInternal createXWalkViewContainerOnMainSync(
376             final Context context,
377             final XWalkUIClientInternal uiClient,
378             final XWalkResourceClientInternal resourceClient) throws Exception {
379         final AtomicReference<XWalkViewInternal> xWalkViewContainer =
380                 new AtomicReference<XWalkViewInternal>();
381         getInstrumentation().runOnMainSync(new Runnable() {
382             @Override
383             public void run() {
384                 xWalkViewContainer.set(new XWalkViewInternal(context, getActivity()));
385                 getActivity().addView(xWalkViewContainer.get());
386                 xWalkViewContainer.get().setUIClient(uiClient);
387                 xWalkViewContainer.get().setResourceClient(resourceClient);
388             }
389         });
390
391         return xWalkViewContainer.get();
392     }
393
394     protected ViewPair createViewsOnMainSync(final TestHelperBridge helperBridge0,
395                                              final TestHelperBridge helperBridge1,
396                                              final XWalkUIClientInternal uiClient0,
397                                              final XWalkUIClientInternal uiClient1,
398                                              final XWalkResourceClientInternal resourceClient0,
399                                              final XWalkResourceClientInternal resourceClient1,
400                                              final Context context) throws Throwable {
401         final XWalkViewInternal walkView0 = createXWalkViewContainerOnMainSync(context,
402                 uiClient0, resourceClient0);
403         final XWalkViewInternal walkView1 = createXWalkViewContainerOnMainSync(context,
404                 uiClient1, resourceClient1);
405         final AtomicReference<ViewPair> viewPair = new AtomicReference<ViewPair>();
406
407         getInstrumentation().runOnMainSync(new Runnable() {
408             @Override
409             public void run() {
410                 viewPair.set(new ViewPair(walkView0, helperBridge0, walkView1, helperBridge1));
411             }
412         });
413
414         return viewPair.get();
415     }
416
417     protected void loadAssetFile(String fileName) throws Exception {
418         String fileContent = getFileContent(fileName);
419         loadDataSync(fileName, fileContent, "text/html", false);
420     }
421
422     public void loadAssetFileAndWaitForTitle(String fileName) throws Exception {
423         CallbackHelper getTitleHelper = mTestHelperBridge.getOnTitleUpdatedHelper();
424         int currentCallCount = getTitleHelper.getCallCount();
425         String fileContent = getFileContent(fileName);
426
427         loadDataSync(fileName, fileContent, "text/html", false);
428
429         getTitleHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
430                 TimeUnit.SECONDS);
431     }
432
433     protected XWalkViewInternal getXWalkView() {
434         return mXWalkViewInternal;
435     }
436
437     protected void runTestWaitPageFinished(Runnable runnable) throws Exception{
438         CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
439         int currentCallCount = pageFinishedHelper.getCallCount();
440         runnable.run();
441         pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
442                 TimeUnit.SECONDS);
443     }
444
445     protected void reloadSync(final int mode) throws Exception {
446         runTestWaitPageFinished(new Runnable(){
447             @Override
448             public void run() {
449                 getInstrumentation().runOnMainSync(new Runnable() {
450                     @Override
451                     public void run() {
452                         mXWalkViewInternal.reload(mode);
453                     }
454                 });
455             }
456         });
457     }
458
459     protected void goBackSync() throws Throwable {
460         runTestWaitPageFinished(new Runnable(){
461             @Override
462             public void run() {
463                 getInstrumentation().runOnMainSync(new Runnable() {
464                     @Override
465                     public void run() {
466                         mXWalkViewInternal.getNavigationHistory().navigate(
467                             XWalkNavigationHistoryInternal.DirectionInternal.BACKWARD, 1);
468                     }
469                 });
470             }
471         });
472     }
473
474     protected void goForwardSync() throws Throwable {
475         runTestWaitPageFinished(new Runnable(){
476             @Override
477             public void run() {
478                 getInstrumentation().runOnMainSync(new Runnable() {
479                     @Override
480                     public void run() {
481                         mXWalkViewInternal.getNavigationHistory().navigate(
482                             XWalkNavigationHistoryInternal.DirectionInternal.FORWARD, 1);
483                     }
484                 });
485             }
486         });
487     }
488
489     protected void clearHistoryOnUiThread() throws Exception {
490         getInstrumentation().runOnMainSync(new Runnable() {
491             @Override
492             public void run() {
493                 mXWalkViewInternal.getNavigationHistory().clear();
494             }
495         });
496     }
497
498     protected boolean canGoBackOnUiThread() throws Throwable {
499         return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
500             @Override
501             public Boolean call() {
502                 return mXWalkViewInternal.getNavigationHistory().canGoBack();
503             }
504         });
505     }
506
507     protected boolean canGoForwardOnUiThread() throws Throwable {
508         return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
509             @Override
510             public Boolean call() {
511                 return mXWalkViewInternal.getNavigationHistory().canGoForward();
512             }
513         });
514     }
515
516     protected int historySizeOnUiThread() throws Throwable {
517         return runTestOnUiThreadAndGetResult(new Callable<Integer>() {
518             @Override
519             public Integer call() {
520                 return mXWalkViewInternal.getNavigationHistory().size();
521             }
522         });
523     }
524
525     protected boolean hasItemAtOnUiThread(final int index) throws Throwable {
526         return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
527             @Override
528             public Boolean call() {
529                 return mXWalkViewInternal.getNavigationHistory().hasItemAt(index);
530             }
531         });
532     }
533
534     protected XWalkNavigationItemInternal getItemAtOnUiThread(final int index) throws Throwable {
535         return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItemInternal>() {
536             @Override
537             public XWalkNavigationItemInternal call() {
538                 return mXWalkViewInternal.getNavigationHistory().getItemAt(index);
539             }
540         });
541     }
542
543     protected XWalkNavigationItemInternal getCurrentItemOnUiThread() throws Throwable {
544         return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItemInternal>() {
545             @Override
546             public XWalkNavigationItemInternal call() {
547                 return mXWalkViewInternal.getNavigationHistory().getCurrentItem();
548             }
549         });
550     }
551
552     protected String executeJavaScriptAndWaitForResult(final String code) throws Exception {
553         final TestHelperBridge.OnEvaluateJavaScriptResultHelper helper =
554                 mTestHelperBridge.getOnEvaluateJavaScriptResultHelper();
555         getInstrumentation().runOnMainSync(new Runnable() {
556             @Override
557             public void run() {
558                 helper.evaluateJavascript(mXWalkViewInternal, code);
559             }
560         });
561         helper.waitUntilHasValue();
562         Assert.assertTrue("Failed to retrieve JavaScript evaluation results.", helper.hasValue());
563         return helper.getJsonResultAndClear();
564     }
565
566     protected ViewPair createViews() throws Throwable {
567         TestHelperBridge helperBridge0 = new TestHelperBridge();
568         TestHelperBridge helperBridge1 = new TestHelperBridge();
569         TestXWalkUIClientInternalBase uiClient0 = new TestXWalkUIClientInternalBase(helperBridge0);
570         TestXWalkUIClientInternalBase uiClient1 = new TestXWalkUIClientInternalBase(helperBridge1);
571         TestXWalkResourceClientBase resourceClient0 =
572                 new TestXWalkResourceClientBase(helperBridge0);
573         TestXWalkResourceClientBase resourceClient1 =
574                 new TestXWalkResourceClientBase(helperBridge1);
575         ViewPair viewPair =
576                 createViewsOnMainSync(helperBridge0, helperBridge1, uiClient0, uiClient1,
577                         resourceClient0, resourceClient1, getActivity());
578
579         return viewPair;
580     }
581
582     protected String getUrlOnUiThread() throws Exception {
583         return runTestOnUiThreadAndGetResult(new Callable<String>() {
584             @Override
585             public String call() throws Exception {
586                 return mXWalkViewInternal.getUrl();
587             }
588         });
589     }
590
591     protected void clearCacheOnUiThread(final boolean includeDiskFiles) throws Exception {
592         getInstrumentation().runOnMainSync(new Runnable() {
593             @Override
594             public void run() {
595                 mXWalkViewInternal.clearCache(includeDiskFiles);
596             }
597         });
598     }
599
600     protected String getAPIVersionOnUiThread() throws Exception {
601         return runTestOnUiThreadAndGetResult(new Callable<String>() {
602             @Override
603             public String call() throws Exception {
604                 return mXWalkViewInternal.getAPIVersion();
605             }
606         });
607     }
608
609     protected String getXWalkVersionOnUiThread() throws Exception {
610         return runTestOnUiThreadAndGetResult(new Callable<String>() {
611             @Override
612             public String call() throws Exception {
613                 return mXWalkViewInternal.getXWalkVersion();
614             }
615         });
616     }
617
618     protected ContentViewCore getContentViewCore() throws Exception {
619         return runTestOnUiThreadAndGetResult(new Callable<ContentViewCore>() {
620             @Override
621             public ContentViewCore call() throws Exception {
622                 return mXWalkViewInternal.getXWalkContentForTest();
623             }
624         });
625     }
626 }