Upstream version 5.34.97.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / core / src / org / xwalk / core / XWalkContentsClientBridge.java
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Copyright (c) 2013 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;
7
8 import android.content.Intent;
9 import android.graphics.Bitmap;
10 import android.graphics.Picture;
11 import android.net.http.SslCertificate;
12 import android.net.http.SslError;
13 import android.os.Message;
14 import android.util.Log;
15 import android.view.KeyEvent;
16 import android.view.View;
17 import android.webkit.ConsoleMessage;
18 import android.webkit.ValueCallback;
19 import android.webkit.WebResourceResponse;
20
21 import org.chromium.base.CalledByNative;
22 import org.chromium.base.JNINamespace;
23 import org.chromium.base.ThreadUtils;
24 import org.chromium.components.navigation_interception.InterceptNavigationDelegate;
25 import org.chromium.components.navigation_interception.NavigationParams;
26 import org.chromium.content.browser.ContentVideoViewClient;
27 import org.chromium.content.browser.ContentViewDownloadDelegate;
28 import org.chromium.content.browser.DownloadInfo;
29
30 // Help bridge callback in XWalkContentsClient to XWalkViewClient and
31 // WebChromeClient; Also handle the JNI conmmunication logic.
32 @JNINamespace("xwalk")
33 public class XWalkContentsClientBridge extends XWalkContentsClient
34         implements ContentViewDownloadDelegate {
35
36     private XWalkView mXWalkView;
37     private XWalkClient mXWalkClient;
38     private XWalkWebChromeClient mXWalkWebChromeClient;
39     private Bitmap mFavicon;
40     private DownloadListener mDownloadListener;
41     private InterceptNavigationDelegate mInterceptNavigationDelegate;
42     private PageLoadListener mPageLoadListener;
43     private XWalkNavigationHandler mNavigationHandler;
44     private XWalkNotificationService mNotificationService;
45
46     // The native peer of the object
47     private int mNativeContentsClientBridge;
48
49     private class InterceptNavigationDelegateImpl implements InterceptNavigationDelegate {
50         private XWalkContentsClient mContentsClient;
51
52         public InterceptNavigationDelegateImpl(XWalkContentsClient client) {
53             mContentsClient = client;
54         }
55
56         public boolean shouldIgnoreNavigation(NavigationParams navigationParams) {
57             final String url = navigationParams.url;
58             boolean ignoreNavigation = shouldOverrideUrlLoading(url) ||
59                      (mNavigationHandler != null &&
60                       mNavigationHandler.handleNavigation(navigationParams));
61
62             if (!ignoreNavigation) {
63                 // Post a message to UI thread to notify the page is starting to load.
64                 mContentsClient.getCallbackHelper().postOnPageStarted(url);
65             }
66
67             return ignoreNavigation;
68         }
69     }
70
71     public XWalkContentsClientBridge(XWalkView xwView) {
72         mXWalkView = xwView;
73
74         mInterceptNavigationDelegate = new InterceptNavigationDelegateImpl(this);
75     }
76
77     public void setXWalkWebChromeClient(XWalkWebChromeClient client) {
78         mXWalkWebChromeClient = client;
79     }
80
81     public XWalkWebChromeClient getXWalkWebChromeClient() {
82         return mXWalkWebChromeClient;
83     }
84
85     public void setXWalkClient(XWalkClient client) {
86         mXWalkClient = client;
87     }
88
89     public void setNavigationHandler(XWalkNavigationHandler handler) {
90         mNavigationHandler = handler;
91     }
92
93     void registerPageLoadListener(PageLoadListener listener) {
94         mPageLoadListener = listener;
95     }
96
97     public void setNotificationService(XWalkNotificationService service) {
98         if (mNotificationService != null) mNotificationService.shutdown();
99         mNotificationService = service;
100         if (mNotificationService != null) mNotificationService.setBridge(this);
101     }
102
103     public boolean onNewIntent(Intent intent) {
104         return mNotificationService.maybeHandleIntent(intent);
105     }
106
107     public InterceptNavigationDelegate getInterceptNavigationDelegate() {
108         return mInterceptNavigationDelegate;
109     }
110
111     // TODO(Xingnan): All the empty functions need to be implemented.
112     @Override
113     public boolean shouldOverrideUrlLoading(String url) {
114         if (mXWalkClient != null && mXWalkView != null)
115             return mXWalkClient.shouldOverrideUrlLoading(mXWalkView, url);
116         return false;
117     }
118
119     @Override
120     public void onUnhandledKeyEvent(KeyEvent event) {
121     }
122
123     @Override
124     public void getVisitedHistory(ValueCallback<String[]> callback) {
125     }
126
127     @Override
128     public void doUpdateVisitedHistory(String url, boolean isReload) {
129     }
130
131     @Override
132     public void onProgressChanged(int progress) {
133         if (mXWalkWebChromeClient != null && mXWalkView != null)
134             mXWalkWebChromeClient.onProgressChanged(mXWalkView, progress);
135     }
136
137     @Override
138     public WebResourceResponse shouldInterceptRequest(String url) {
139         if (mXWalkClient != null && mXWalkView != null)
140             return mXWalkClient.shouldInterceptRequest(mXWalkView, url);
141         return null;
142     }
143
144     @Override
145     public void onLoadResource(String url) {
146         if (mXWalkClient != null && mXWalkView != null)
147             mXWalkClient.onLoadResource(mXWalkView, url);
148     }
149
150     @Override
151     public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
152         return false;
153     }
154
155     @CalledByNative
156     public void onReceivedHttpAuthRequest(XWalkHttpAuthHandler handler, String host, String realm) {
157         if (mXWalkClient != null && mXWalkView != null)
158             mXWalkClient.onReceivedHttpAuthRequest(mXWalkView, handler, host, realm);
159     }
160     @Override
161     public void onReceivedSslError(SslErrorHandler handler, SslError error) {
162         if (mXWalkClient != null && mXWalkView != null)
163             mXWalkClient.onReceivedSslError(mXWalkView, handler, error);
164     }
165
166     @Override
167     public void onReceivedLoginRequest(String realm, String account, String args) {
168     }
169
170     @Override
171     public void onGeolocationPermissionsShowPrompt(String origin,
172             XWalkGeolocationPermissions.Callback callback) {
173         if (mXWalkWebChromeClient != null) {
174             mXWalkWebChromeClient.onGeolocationPermissionsShowPrompt(origin, callback);
175         }
176     }
177
178     @Override
179     public void onGeolocationPermissionsHidePrompt() {
180         if (mXWalkWebChromeClient != null) {
181             mXWalkWebChromeClient.onGeolocationPermissionsHidePrompt();
182         }
183     }
184
185     @Override
186     public void handleJsAlert(String url, String message, JsResult result) {
187         if (mXWalkWebChromeClient != null && mXWalkView != null) {
188             mXWalkWebChromeClient.onJsAlert(mXWalkView, url, message, result);
189         }
190     }
191
192     @Override
193     public void handleJsBeforeUnload(String url, String message, JsResult result) {
194         if (mXWalkWebChromeClient != null && mXWalkView != null) {
195             mXWalkWebChromeClient.onJsBeforeUnload(mXWalkView, url, message, result);
196         }
197     }
198
199     @Override
200     public void handleJsConfirm(String url, String message, JsResult result) {
201         if (mXWalkWebChromeClient != null && mXWalkView != null) {
202             mXWalkWebChromeClient.onJsConfirm(mXWalkView, url, message, result);
203         }
204     }
205
206     @Override
207     public void handleJsPrompt(
208             String url, String message, String defaultValue, JsPromptResult result) {
209         if (mXWalkWebChromeClient != null && mXWalkView != null) {
210             mXWalkWebChromeClient.onJsPrompt(mXWalkView, url, message, defaultValue, result);
211         }
212     }
213
214     @Override
215     public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
216             boolean isDoneCounting) {
217     }
218
219     @Override
220     public void onNewPicture(Picture picture) {
221     }
222
223     @Override
224     public void onPageStarted(String url) {
225         if (mXWalkClient != null && mXWalkView != null) {
226             mXWalkClient.onPageStarted(mXWalkView, url, mFavicon);
227         }
228     }
229
230     @Override
231     public void onPageFinished(String url) {
232         if (mPageLoadListener != null) mPageLoadListener.onPageFinished(url);
233         if (mXWalkClient != null && mXWalkView != null) {
234             mXWalkClient.onPageFinished(mXWalkView, url);
235         }
236     }
237
238     @Override
239     public void onReceivedError(int errorCode, String description, String failingUrl) {
240         if (mXWalkClient != null && mXWalkView != null) {
241             mXWalkClient.onReceivedError(mXWalkView, errorCode, description, failingUrl);
242         }
243     }
244
245     @Override
246     public void onRendererUnresponsive() {
247         if (mXWalkClient != null && mXWalkView != null) {
248             mXWalkClient.onRendererUnresponsive(mXWalkView);
249         }
250     }
251
252     @Override
253     public void onRendererResponsive() {
254         if (mXWalkClient != null && mXWalkView != null) {
255             mXWalkClient.onRendererResponsive(mXWalkView);
256         }
257     }
258
259     @Override
260     public void onFormResubmission(Message dontResend, Message resend) {
261         dontResend.sendToTarget();
262     }
263
264     @Override
265     public void onDownloadStart(String url,
266                                 String userAgent,
267                                 String contentDisposition,
268                                 String mimeType,
269                                 long contentLength) {
270     }
271
272     @Override
273     public boolean onCreateWindow(boolean isDialog, boolean isUserGesture) {
274         return false;
275     }
276
277     @Override
278     public void onCloseWindow() {
279         if (mXWalkClient != null) {
280             mXWalkClient.onCloseWindow(mXWalkView);
281         }
282     }
283
284     @Override
285     public void onRequestFocus() {
286     }
287
288     @Override
289     public void onReceivedTouchIconUrl(String url, boolean precomposed) {
290         if (mXWalkWebChromeClient != null && mXWalkView != null) {
291             mXWalkWebChromeClient.onReceivedTouchIconUrl(mXWalkView, url, precomposed);
292         }
293     }
294
295     @Override
296     public void onReceivedIcon(Bitmap bitmap) {
297         if (mXWalkWebChromeClient != null && mXWalkView != null) {
298             mXWalkWebChromeClient.onReceivedIcon(mXWalkView, bitmap);
299         }
300         mFavicon = bitmap;
301     }
302
303     @Override
304     public void onShowCustomView(View view, XWalkWebChromeClient.CustomViewCallback callback) {
305         if (mXWalkWebChromeClient != null) {
306             mXWalkWebChromeClient.onShowCustomView(view, callback);
307         }
308     }
309
310     @Override
311     public void onHideCustomView() {
312         if (mXWalkWebChromeClient != null) {
313             mXWalkWebChromeClient.onHideCustomView();
314         }
315     }
316
317     @Override
318     public void onScaleChangedScaled(float oldScale, float newScale) {
319     }
320
321     @Override
322     protected View getVideoLoadingProgressView() {
323         if (mXWalkWebChromeClient != null)
324             return mXWalkWebChromeClient.getVideoLoadingProgressView();
325         return null;
326     }
327
328     @Override
329     public Bitmap getDefaultVideoPoster() {
330         return null;
331     }
332
333     @Override
334     public void didFinishLoad(String url) {
335     }
336
337     @Override
338     public void onTitleChanged(String title) {
339         if (mXWalkWebChromeClient != null && mXWalkView != null) {
340             mXWalkWebChromeClient.onReceivedTitle(mXWalkView, title);
341         }
342     }
343
344     @Override
345     public void onToggleFullscreen(boolean enterFullscreen) {
346         if (mXWalkWebChromeClient != null) {
347             mXWalkWebChromeClient.onToggleFullscreen(enterFullscreen);
348         }
349     }
350
351     @Override
352     public boolean isFullscreen() {
353         if (mXWalkWebChromeClient != null) return mXWalkWebChromeClient.isFullscreen();
354
355         return false;
356     }
357
358     @Override
359     public ContentVideoViewClient getContentVideoViewClient() {
360         return new XWalkContentVideoViewClient(this, mXWalkView.getActivity());
361     }
362
363     // Used by the native peer to set/reset a weak ref to the native peer.
364     @CalledByNative
365     private void setNativeContentsClientBridge(int nativeContentsClientBridge) {
366         mNativeContentsClientBridge = nativeContentsClientBridge;
367     }
368
369     // If returns false, the request is immediately canceled, and any call to proceedSslError
370     // has no effect. If returns true, the request should be canceled or proceeded using
371     // proceedSslError().
372     // Unlike the webview classic, we do not keep keep a database of certificates that
373     // are allowed by the user, because this functionality is already handled via
374     // ssl_policy in native layers.
375     @CalledByNative
376     private boolean allowCertificateError(int certError, byte[] derBytes, final String url,
377             final int id) {
378         // TODO(yongsheng): Implement this.
379         return false;
380     }
381
382     private void proceedSslError(boolean proceed, int id) {
383         if (mNativeContentsClientBridge == 0) return;
384         nativeProceedSslError(mNativeContentsClientBridge, proceed, id);
385     }
386
387     @CalledByNative
388     private void handleJsAlert(String url, String message, int id) {
389         JsResultHandler handler = new JsResultHandler(this, id);
390         handleJsAlert(url, message, handler);
391     }
392
393     @CalledByNative
394     private void handleJsConfirm(String url, String message, int id) {
395         JsResultHandler handler = new JsResultHandler(this, id);
396         handleJsConfirm(url, message, handler);
397     }
398
399     @CalledByNative
400     private void handleJsPrompt(String url, String message, String defaultValue, int id) {
401         JsResultHandler handler = new JsResultHandler(this, id);
402         handleJsPrompt(url, message, defaultValue, handler);
403     }
404
405     @CalledByNative
406     private void handleJsBeforeUnload(String url, String message, int id) {
407         JsResultHandler handler = new JsResultHandler(this, id);
408         handleJsBeforeUnload(url, message, handler);
409     }
410
411     @CalledByNative
412     private void updateNotificationIcon(int notificationId, Bitmap icon) {
413         mNotificationService.updateNotificationIcon(notificationId, icon);
414     }
415
416     @CalledByNative
417     private void showNotification(String title, String message, String replaceId,
418             int notificationId, int processId, int routeId) {
419         // FIXME(wang16): use replaceId to replace exist notification. It happens when
420         //                a notification with same name and tag fires.
421         mNotificationService.showNotification(
422                 title, message, notificationId, processId, routeId);
423     }
424
425     @CalledByNative
426     private void cancelNotification(int notificationId, int processId, int routeId) {
427         mNotificationService.cancelNotification(notificationId, processId, routeId);
428     }
429
430     void confirmJsResult(int id, String prompt) {
431         if (mNativeContentsClientBridge == 0) return;
432         nativeConfirmJsResult(mNativeContentsClientBridge, id, prompt);
433     }
434
435     void cancelJsResult(int id) {
436         if (mNativeContentsClientBridge == 0) return;
437         nativeCancelJsResult(mNativeContentsClientBridge, id);
438     }
439
440     void exitFullscreen(int nativeWebContents) {
441         if (mNativeContentsClientBridge == 0) return;
442         nativeExitFullscreen(mNativeContentsClientBridge, nativeWebContents);
443     }
444
445     public void notificationDisplayed(int id, int processId, int routeId) {
446         if (mNativeContentsClientBridge == 0) return;
447         nativeNotificationDisplayed(mNativeContentsClientBridge, id, processId, routeId);
448     }
449
450     public void notificationError(int id, String error, int processId, int routeId) {
451         if (mNativeContentsClientBridge == 0) return;
452         nativeNotificationError(mNativeContentsClientBridge, id, error, processId, routeId);
453     }
454
455     public void notificationClicked(int id, int processId, int routeId) {
456         if (mNativeContentsClientBridge == 0) return;
457         nativeNotificationClicked(mNativeContentsClientBridge, id, processId, routeId);
458     }
459
460     public void notificationClosed(int id, boolean byUser, int processId, int routeId) {
461         if (mNativeContentsClientBridge == 0) return;
462         nativeNotificationClosed(mNativeContentsClientBridge, id, byUser, processId, routeId);
463     }
464
465     void setDownloadListener(DownloadListener listener) {
466         mDownloadListener = listener;
467     }
468
469     // Implement ContentViewDownloadDelegate methods.
470     public void requestHttpGetDownload(DownloadInfo downloadInfo) {
471         if (mDownloadListener != null) {
472             mDownloadListener.onDownloadStart(downloadInfo.getUrl(), downloadInfo.getUserAgent(),
473             downloadInfo.getContentDisposition(), downloadInfo.getMimeType(), downloadInfo.getContentLength());
474         }
475     }
476
477     public void onDownloadStarted(String filename, String mimeType) {
478     }
479
480     public void onDangerousDownload(String filename, int downloadId) {
481     }
482
483     //--------------------------------------------------------------------------------------------
484     //  Native methods
485     //--------------------------------------------------------------------------------------------
486     private native void nativeProceedSslError(int nativeXWalkContentsClientBridge,
487             boolean proceed, int id);
488
489     private native void nativeConfirmJsResult(int nativeXWalkContentsClientBridge, int id,
490             String prompt);
491     private native void nativeCancelJsResult(int nativeXWalkContentsClientBridge, int id);
492     private native void nativeExitFullscreen(int nativeXWalkContentsClientBridge, int nativeWebContents);
493     private native void nativeNotificationDisplayed(int nativeXWalkContentsClientBridge, int id,
494             int processId, int routeId);
495     private native void nativeNotificationError(int nativeXWalkContentsClientBridge, int id,
496             String error, int processId, int routeId);
497     private native void nativeNotificationClicked(int nativeXWalkContentsClientBridge, int id,
498             int processId, int routeId);
499     private native void nativeNotificationClosed(int nativeXWalkContentsClientBridge, int id,
500             boolean byUser, int processId, int routeId);
501 }