1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Copyright (c) 2013-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.
6 package org.xwalk.core.internal;
8 import android.app.Activity;
9 import android.content.Context;
10 import android.content.Intent;
11 import android.content.SharedPreferences;
12 import android.graphics.Rect;
13 import android.os.Build.VERSION;
14 import android.os.Build.VERSION_CODES;
15 import android.os.Bundle;
16 import android.view.View;
17 import android.view.WindowManager;
18 import android.text.TextUtils;
19 import android.util.AttributeSet;
20 import android.util.Log;
21 import android.view.ViewGroup;
22 import android.webkit.ValueCallback;
23 import android.webkit.WebResourceResponse;
24 import android.widget.FrameLayout;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.lang.annotation.Annotation;
30 import org.chromium.base.CalledByNative;
31 import org.chromium.base.JNINamespace;
32 import org.chromium.base.ThreadUtils;
33 import org.chromium.components.navigation_interception.InterceptNavigationDelegate;
34 import org.chromium.content.browser.ContentView;
35 import org.chromium.content.browser.ContentViewCore;
36 import org.chromium.content.browser.ContentViewRenderView;
37 import org.chromium.content.browser.ContentViewRenderView.CompositingSurfaceType;
38 import org.chromium.content.browser.ContentViewStatics;
39 import org.chromium.content.browser.LoadUrlParams;
40 import org.chromium.content.browser.NavigationHistory;
41 import org.chromium.content.common.CleanupReference;
42 import org.chromium.content_public.browser.JavaScriptCallback;
43 import org.chromium.media.MediaPlayerBridge;
44 import org.chromium.ui.base.ActivityWindowAndroid;
45 import org.chromium.ui.gfx.DeviceDisplayInfo;
47 @JNINamespace("xwalk")
49 * This class is the implementation class for XWalkViewInternal by calling internal
52 class XWalkContent extends FrameLayout implements XWalkPreferencesInternal.KeyValueChangeListener {
53 private static String TAG = "XWalkContent";
54 private static Class<? extends Annotation> javascriptInterfaceClass = null;
56 private ContentViewCore mContentViewCore;
57 private ContentView mContentView;
58 private ContentViewRenderView mContentViewRenderView;
59 private ActivityWindowAndroid mWindow;
60 private XWalkDevToolsServer mDevToolsServer;
61 private XWalkViewInternal mXWalkView;
62 private XWalkContentsClientBridge mContentsClientBridge;
63 private XWalkContentsIoThreadClient mIoThreadClient;
64 private XWalkWebContentsDelegateAdapter mXWalkContentsDelegateAdapter;
65 private XWalkSettings mSettings;
66 private XWalkGeolocationPermissions mGeolocationPermissions;
67 private XWalkLaunchScreenManager mLaunchScreenManager;
72 static void setJavascriptInterfaceClass(Class<? extends Annotation> clazz) {
73 assert(javascriptInterfaceClass == null);
74 javascriptInterfaceClass = clazz;
77 private static final class DestroyRunnable implements Runnable {
78 private final long mNativeContent;
79 private DestroyRunnable(long nativeXWalkContent) {
80 mNativeContent = nativeXWalkContent;
85 nativeDestroy(mNativeContent);
89 // Reference to the active mNativeContent pointer while it is active use
90 // (ie before it is destroyed).
91 private CleanupReference mCleanupReference;
93 public XWalkContent(Context context, AttributeSet attrs, XWalkViewInternal xwView) {
94 super(context, attrs);
96 // Initialize the WebContensDelegate.
98 mContentsClientBridge = new XWalkContentsClientBridge(mXWalkView);
99 mXWalkContentsDelegateAdapter = new XWalkWebContentsDelegateAdapter(
100 mContentsClientBridge);
101 mIoThreadClient = new XWalkIoThreadClientImpl();
103 // Initialize mWindow which is needed by content
104 mWindow = new ActivityWindowAndroid(xwView.getActivity());
106 SharedPreferences sharedPreferences = new InMemorySharedPreferences();
107 mGeolocationPermissions = new XWalkGeolocationPermissions(sharedPreferences);
109 MediaPlayerBridge.setResourceLoadingFilter(
110 new XWalkMediaPlayerResourceLoadingFilter());
112 XWalkPreferencesInternal.load(this);
114 setNativeContent(nativeInit());
117 private void setNativeContent(long newNativeContent) {
118 if (mNativeContent != 0) {
120 mContentViewCore = null;
123 assert mNativeContent == 0 && mCleanupReference == null && mContentViewCore == null;
125 // Initialize ContentViewRenderView
126 boolean animated = XWalkPreferencesInternal.getValue(
127 XWalkPreferencesInternal.ANIMATABLE_XWALK_VIEW);
128 CompositingSurfaceType surfaceType =
129 animated ? CompositingSurfaceType.TEXTURE_VIEW : CompositingSurfaceType.SURFACE_VIEW;
130 mContentViewRenderView = new ContentViewRenderView(getContext(), surfaceType) {
131 protected void onReadyToRender() {
132 // Anything depending on the underlying Surface readiness should
136 mContentViewRenderView.onNativeLibraryLoaded(mWindow);
137 mLaunchScreenManager = new XWalkLaunchScreenManager(getContext(), mXWalkView);
138 mContentViewRenderView.registerFirstRenderedFrameListener(mLaunchScreenManager);
139 addView(mContentViewRenderView, new FrameLayout.LayoutParams(
140 FrameLayout.LayoutParams.MATCH_PARENT,
141 FrameLayout.LayoutParams.MATCH_PARENT));
143 mNativeContent = newNativeContent;
145 // The native side object has been bound to this java instance, so now is the time to
146 // bind all the native->java relationships.
147 mCleanupReference = new CleanupReference(this, new DestroyRunnable(mNativeContent));
149 mWebContents = nativeGetWebContents(mNativeContent);
152 // Initialize ContentView.
153 mContentViewCore = new ContentViewCore(getContext());
154 mContentView = ContentView.newInstance(getContext(), mContentViewCore);
155 mContentViewCore.initialize(mContentView, mContentView, mWebContents, mWindow);
156 addView(mContentView, new FrameLayout.LayoutParams(
157 FrameLayout.LayoutParams.MATCH_PARENT,
158 FrameLayout.LayoutParams.MATCH_PARENT));
159 mContentViewCore.setContentViewClient(mContentsClientBridge);
160 mContentViewRenderView.setCurrentContentViewCore(mContentViewCore);
161 // For addJavascriptInterface
162 mContentsClientBridge.installWebContentsObserver(mContentViewCore.getWebContents());
165 mContentsClientBridge.setDIPScale(DeviceDisplayInfo.create(getContext()).getDIPScale());
167 mContentViewCore.setDownloadDelegate(mContentsClientBridge);
169 // Set the third argument isAccessFromFileURLsGrantedByDefault to false, so that
170 // the members mAllowUniversalAccessFromFileURLs and mAllowFileAccessFromFileURLs
171 // won't be changed from false to true at the same time in the constructor of
172 // XWalkSettings class.
173 mSettings = new XWalkSettings(getContext(), mWebContents, false);
174 // Enable AllowFileAccessFromFileURLs, so that files under file:// path could be
175 // loaded by XMLHttpRequest.
176 mSettings.setAllowFileAccessFromFileURLs(true);
177 // Enable this by default to suppport new window creation
178 mSettings.setSupportMultipleWindows(true);
180 nativeSetJavaPeers(mNativeContent, this, mXWalkContentsDelegateAdapter, mContentsClientBridge,
181 mIoThreadClient, mContentsClientBridge.getInterceptNavigationDelegate());
184 public void supplyContentsForPopup(XWalkContent newContents) {
185 long popupNativeXWalkContent = nativeReleasePopupXWalkContent(mNativeContent);
186 if (popupNativeXWalkContent == 0) {
187 Log.w(TAG, "Popup XWalkView bind failed: no pending content.");
188 if (newContents != null) newContents.destroy();
191 if (newContents == null) {
192 nativeDestroy(popupNativeXWalkContent);
196 newContents.receivePopupContents(popupNativeXWalkContent);
199 private void receivePopupContents(long popupNativeXWalkContents) {
200 setNativeContent(popupNativeXWalkContents);
202 mContentViewCore.onShow();
205 void doLoadUrl(String url, String content) {
206 // Handle the same url loading by parameters.
207 if (url != null && !url.isEmpty() &&
208 TextUtils.equals(url, mContentViewCore.getUrl())) {
209 mContentViewCore.reload(true);
211 LoadUrlParams params = null;
212 if (content == null || content.isEmpty()) {
213 params = new LoadUrlParams(url);
215 params = LoadUrlParams.createLoadDataParamsWithBaseUrl(
216 content, "text/html", false, url, null);
218 params.setOverrideUserAgent(LoadUrlParams.UA_OVERRIDE_TRUE);
219 mContentViewCore.loadUrl(params);
222 mContentView.requestFocus();
225 public void loadUrl(String url, String data) {
226 if ((url == null || url.isEmpty()) &&
227 (data == null || data.isEmpty())) {
231 doLoadUrl(url, data);
234 public void reload(int mode) {
236 case XWalkViewInternal.RELOAD_IGNORE_CACHE:
237 mContentViewCore.reloadIgnoringCache(true);
239 case XWalkViewInternal.RELOAD_NORMAL:
241 mContentViewCore.reload(true);
245 public String getUrl() {
246 String url = mContentViewCore.getUrl();
247 if (url == null || url.trim().isEmpty()) return null;
251 public String getTitle() {
252 String title = mContentViewCore.getTitle().trim();
253 if (title == null) title = "";
257 public void addJavascriptInterface(Object object, String name) {
258 mContentViewCore.addPossiblyUnsafeJavascriptInterface(object, name,
259 javascriptInterfaceClass);
262 public void evaluateJavascript(String script, ValueCallback<String> callback) {
263 final ValueCallback<String> fCallback = callback;
264 JavaScriptCallback coreCallback = null;
265 if (fCallback != null) {
266 coreCallback = new JavaScriptCallback() {
268 public void handleJavaScriptResult(String jsonResult) {
269 fCallback.onReceiveValue(jsonResult);
273 mContentViewCore.evaluateJavaScript(script, coreCallback);
276 public void setUIClient(XWalkUIClientInternal client) {
277 mContentsClientBridge.setUIClient(client);
280 public void setResourceClient(XWalkResourceClientInternal client) {
281 mContentsClientBridge.setResourceClient(client);
284 public void setXWalkWebChromeClient(XWalkWebChromeClient client) {
285 mContentsClientBridge.setXWalkWebChromeClient(client);
288 public XWalkWebChromeClient getXWalkWebChromeClient() {
289 return mContentsClientBridge.getXWalkWebChromeClient();
292 public void setXWalkClient(XWalkClient client) {
293 mContentsClientBridge.setXWalkClient(client);
296 public void setDownloadListener(DownloadListener listener) {
297 mContentsClientBridge.setDownloadListener(listener);
300 public void setNavigationHandler(XWalkNavigationHandler handler) {
301 mContentsClientBridge.setNavigationHandler(handler);
304 public void setNotificationService(XWalkNotificationService service) {
305 mContentsClientBridge.setNotificationService(service);
308 public void onPause() {
309 mContentViewCore.onHide();
312 public void onResume() {
313 mContentViewCore.onShow();
316 public void onActivityResult(int requestCode, int resultCode, Intent data) {
317 mWindow.onActivityResult(requestCode, resultCode, data);
320 public boolean onNewIntent(Intent intent) {
321 return mContentsClientBridge.onNewIntent(intent);
324 public void clearCache(boolean includeDiskFiles) {
325 if (mNativeContent == 0) return;
326 nativeClearCache(mNativeContent, includeDiskFiles);
329 public void clearHistory() {
330 mContentViewCore.clearHistory();
333 public boolean canGoBack() {
334 return mContentViewCore.canGoBack();
337 public void goBack() {
338 mContentViewCore.goBack();
341 public boolean canGoForward() {
342 return mContentViewCore.canGoForward();
345 public void goForward() {
346 mContentViewCore.goForward();
349 void navigateTo(int offset) {
350 mContentViewCore.goToOffset(offset);
353 public void stopLoading() {
354 mContentViewCore.stopLoading();
355 mContentsClientBridge.onStopLoading();
358 // Currently, timer pause/resume is actually
359 // a global setting. And multiple pause will fail the
360 // DCHECK in content (content_view_statics.cc:57).
361 // Here uses a static boolean to avoid this issue.
362 private static boolean timerPaused = false;
364 // TODO(Guangzhen): ContentViewStatics will be removed in upstream,
365 // details in content_view_statics.cc.
366 // We need follow up after upstream updates that.
367 public void pauseTimers() {
368 if (timerPaused) return;
369 ContentViewStatics.setWebKitSharedTimersSuspended(true);
373 public void resumeTimers() {
374 if (!timerPaused) return;
375 ContentViewStatics.setWebKitSharedTimersSuspended(false);
379 public String getOriginalUrl() {
380 NavigationHistory history = mContentViewCore.getNavigationHistory();
381 int currentIndex = history.getCurrentEntryIndex();
382 if (currentIndex >= 0 && currentIndex < history.getEntryCount()) {
383 return history.getEntryAtIndex(currentIndex).getOriginalUrl();
388 public String getXWalkVersion() {
389 if (mNativeContent == 0) return "";
390 return nativeGetVersion(mNativeContent);
393 public void setNetworkAvailable(boolean networkUp) {
394 if (mNativeContent == 0) return;
395 nativeSetJsOnlineProperty(mNativeContent, networkUp);
398 // For instrumentation test.
399 public ContentViewCore getContentViewCoreForTest() {
400 return mContentViewCore;
403 // For instrumentation test.
404 public void installWebContentsObserverForTest(XWalkContentsClient contentClient) {
405 contentClient.installWebContentsObserver(mContentViewCore.getWebContents());
408 public String devToolsAgentId() {
409 if (mNativeContent == 0) return "";
410 return nativeDevToolsAgentId(mNativeContent);
413 public XWalkSettings getSettings() {
417 public void loadAppFromManifest(String url, String data) {
418 if (mNativeContent == 0 ||
419 ((url == null || url.isEmpty()) &&
420 (data == null || data.isEmpty()))) {
424 String content = data;
425 // If the data of manifest.json is not set, try to load it.
426 if (data == null || data.isEmpty()) {
428 content = AndroidProtocolHandler.getUrlContent(mXWalkView.getActivity(), url);
429 } catch (IOException e) {
430 throw new RuntimeException("Failed to read the manifest: " + url);
434 // Calculate the base url of manifestUrl. Used by native side.
435 // TODO(yongsheng): It's from runtime side. Need to find a better way
437 String baseUrl = url;
438 int position = url.lastIndexOf("/");
439 if (position != -1) {
440 baseUrl = url.substring(0, position + 1);
442 Log.w(TAG, "The url of manifest.json is probably not set correctly.");
445 if (!nativeSetManifest(mNativeContent, baseUrl, content)) {
446 throw new RuntimeException("Failed to parse the manifest file: " + url);
450 public XWalkNavigationHistoryInternal getNavigationHistory() {
451 return new XWalkNavigationHistoryInternal(mXWalkView, mContentViewCore.getNavigationHistory());
454 public static final String SAVE_RESTORE_STATE_KEY = "XWALKVIEW_STATE";
456 public XWalkNavigationHistoryInternal saveState(Bundle outState) {
457 if (outState == null) return null;
459 byte[] state = nativeGetState(mNativeContent);
460 if (state == null) return null;
462 outState.putByteArray(SAVE_RESTORE_STATE_KEY, state);
463 return getNavigationHistory();
466 public XWalkNavigationHistoryInternal restoreState(Bundle inState) {
467 if (inState == null) return null;
469 byte[] state = inState.getByteArray(SAVE_RESTORE_STATE_KEY);
470 if (state == null) return null;
472 boolean result = nativeSetState(mNativeContent, state);
474 // The onUpdateTitle callback normally happens when a page is loaded,
475 // but is optimized out in the restoreState case because the title is
476 // already restored. See WebContentsImpl::UpdateTitleForEntry. So we
477 // call the callback explicitly here.
479 mContentsClientBridge.onUpdateTitle(mContentViewCore.getTitle());
482 return result ? getNavigationHistory() : null;
485 boolean hasEnteredFullscreen() {
486 return mContentsClientBridge.hasEnteredFullscreen();
489 void exitFullscreen() {
490 if (hasEnteredFullscreen()) {
491 mContentsClientBridge.exitFullscreen(mWebContents);
496 public void onGetUrlFromManifest(String url) {
497 if (url != null && !url.isEmpty()) {
503 public void onGetUrlAndLaunchScreenFromManifest(String url, String readyWhen, String imageBorder) {
504 if (url == null || url.isEmpty()) return;
505 mLaunchScreenManager.displayLaunchScreen(readyWhen, imageBorder);
506 mContentsClientBridge.registerPageLoadListener(mLaunchScreenManager);
511 public void onGetFullscreenFlagFromManifest(boolean enterFullscreen) {
512 if (enterFullscreen) {
513 if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
514 View decorView = mXWalkView.getActivity().getWindow().getDecorView();
515 decorView.setSystemUiVisibility(
516 View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
517 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
518 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
519 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
520 View.SYSTEM_UI_FLAG_FULLSCREEN |
521 View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
523 mXWalkView.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
528 public void destroy() {
529 if (mNativeContent == 0) return;
531 XWalkPreferencesInternal.unload(this);
532 // Reset existing notification service in order to destruct it.
533 setNotificationService(null);
534 // Remove its children used for page rendering from view hierarchy.
535 removeView(mContentView);
536 removeView(mContentViewRenderView);
537 mContentViewRenderView.setCurrentContentViewCore(null);
539 // Destroy the native resources.
540 mContentViewRenderView.destroy();
541 mContentViewCore.destroy();
543 mCleanupReference.cleanupNow();
544 mCleanupReference = null;
548 public int getRoutingID() {
549 return nativeGetRoutingID(mNativeContent);
552 //--------------------------------------------------------------------------------------------
553 private class XWalkIoThreadClientImpl implements XWalkContentsIoThreadClient {
554 // All methods are called on the IO thread.
557 public int getCacheMode() {
558 return mSettings.getCacheMode();
562 public InterceptedRequestData shouldInterceptRequest(final String url,
563 boolean isMainFrame) {
565 // Notify a resource load is started. This is not the best place to start the callback
566 // but it's a workable way.
567 mContentsClientBridge.getCallbackHelper().postOnResourceLoadStarted(url);
569 WebResourceResponse webResourceResponse = mContentsClientBridge.shouldInterceptRequest(url);
570 InterceptedRequestData interceptedRequestData = null;
572 if (webResourceResponse == null) {
573 mContentsClientBridge.getCallbackHelper().postOnLoadResource(url);
575 if (isMainFrame && webResourceResponse.getData() == null) {
576 mContentsClientBridge.getCallbackHelper().postOnReceivedError(
577 XWalkResourceClientInternal.ERROR_UNKNOWN, null, url);
579 interceptedRequestData = new InterceptedRequestData(webResourceResponse.getMimeType(),
580 webResourceResponse.getEncoding(),
581 webResourceResponse.getData());
583 return interceptedRequestData;
587 public boolean shouldBlockContentUrls() {
588 return !mSettings.getAllowContentAccess();
592 public boolean shouldBlockFileUrls() {
593 return !mSettings.getAllowFileAccess();
597 public boolean shouldBlockNetworkLoads() {
598 return mSettings.getBlockNetworkLoads();
602 public void onDownloadStart(String url,
604 String contentDisposition,
606 long contentLength) {
607 mContentsClientBridge.getCallbackHelper().postOnDownloadStart(url, userAgent,
608 contentDisposition, mimeType, contentLength);
612 public void newLoginRequest(String realm, String account, String args) {
613 mContentsClientBridge.getCallbackHelper().postOnReceivedLoginRequest(realm, account, args);
617 private class XWalkGeolocationCallback implements XWalkGeolocationPermissions.Callback {
619 public void invoke(final String origin, final boolean allow, final boolean retain) {
620 ThreadUtils.runOnUiThread(new Runnable() {
625 mGeolocationPermissions.allow(origin);
627 mGeolocationPermissions.deny(origin);
630 nativeInvokeGeolocationCallback(mNativeContent, allow, origin);
637 private void onGeolocationPermissionsShowPrompt(String origin) {
638 // Reject if geolocation is disabled, or the origin has a retained deny.
639 if (!mSettings.getGeolocationEnabled()) {
640 nativeInvokeGeolocationCallback(mNativeContent, false, origin);
643 // Allow if the origin has a retained allow.
644 if (mGeolocationPermissions.hasOrigin(origin)) {
645 nativeInvokeGeolocationCallback(mNativeContent,
646 mGeolocationPermissions.isOriginAllowed(origin),
650 mContentsClientBridge.onGeolocationPermissionsShowPrompt(
651 origin, new XWalkGeolocationCallback());
655 public void onGeolocationPermissionsHidePrompt() {
656 mContentsClientBridge.onGeolocationPermissionsHidePrompt();
659 public String enableRemoteDebugging(int allowedUid) {
660 // Chrome looks for "devtools_remote" pattern in the name of a unix domain socket
661 // to identify a debugging page
662 final String socketName = getContext().getApplicationContext().getPackageName() + "_devtools_remote";
663 if (mDevToolsServer == null) {
664 mDevToolsServer = new XWalkDevToolsServer(socketName);
665 mDevToolsServer.allowConnectionFromUid(allowedUid);
666 mDevToolsServer.setRemoteDebuggingEnabled(true);
668 // devtools/page is hardcoded in devtools_http_handler_impl.cc (kPageUrlPrefix)
669 return "ws://" + socketName + "/devtools/page/" + devToolsAgentId();
672 // Enables remote debugging and returns the URL at which the dev tools server is listening
673 // for commands. Only the current process is allowed to connect to the server.
674 String enableRemoteDebugging() {
675 return enableRemoteDebugging(getContext().getApplicationInfo().uid);
678 void disableRemoteDebugging() {
679 if (mDevToolsServer == null) return;
681 if (mDevToolsServer.isRemoteDebuggingEnabled()) {
682 mDevToolsServer.setRemoteDebuggingEnabled(false);
684 mDevToolsServer.destroy();
685 mDevToolsServer = null;
689 public void onKeyValueChanged(String key, XWalkPreferencesInternal.PreferenceValue value) {
690 if (key == null) return;
691 if (key.equals(XWalkPreferencesInternal.REMOTE_DEBUGGING)) {
692 if (value.getBooleanValue()) enableRemoteDebugging();
693 else disableRemoteDebugging();
694 } else if (key.equals(XWalkPreferencesInternal.ENABLE_JAVASCRIPT)) {
695 if (mSettings != null) {
696 mSettings.setJavaScriptEnabled(value.getBooleanValue());
698 } else if (key.equals(XWalkPreferencesInternal.JAVASCRIPT_CAN_OPEN_WINDOW)) {
699 if (mSettings != null) {
700 mSettings.setJavaScriptCanOpenWindowsAutomatically(value.getBooleanValue());
702 } else if (key.equals(XWalkPreferencesInternal.ALLOW_UNIVERSAL_ACCESS_FROM_FILE)) {
703 if (mSettings != null) {
704 mSettings.setAllowUniversalAccessFromFileURLs(value.getBooleanValue());
706 } else if (key.equals(XWalkPreferencesInternal.SUPPORT_MULTIPLE_WINDOWS)) {
707 if (mSettings != null) {
708 mSettings.setSupportMultipleWindows(value.getBooleanValue());
713 public void setOverlayVideoMode(boolean enabled) {
714 if (mContentViewRenderView != null) {
715 mContentViewRenderView.setOverlayVideoMode(enabled);
719 private native long nativeInit();
720 private static native void nativeDestroy(long nativeXWalkContent);
721 private native long nativeGetWebContents(long nativeXWalkContent);
722 private native long nativeReleasePopupXWalkContent(long nativeXWalkContent);
723 private native void nativeSetJavaPeers(
724 long nativeXWalkContent,
725 XWalkContent xwalkContent,
726 XWalkWebContentsDelegateAdapter xwalkContentsDelegate,
727 XWalkContentsClientBridge contentsClientBridge,
728 XWalkContentsIoThreadClient ioThreadClient,
729 InterceptNavigationDelegate navigationInterceptionDelegate);
730 private native void nativeClearCache(long nativeXWalkContent, boolean includeDiskFiles);
731 private native String nativeDevToolsAgentId(long nativeXWalkContent);
732 private native String nativeGetVersion(long nativeXWalkContent);
733 private native void nativeSetJsOnlineProperty(long nativeXWalkContent, boolean networkUp);
734 private native boolean nativeSetManifest(long nativeXWalkContent, String path, String manifest);
735 private native int nativeGetRoutingID(long nativeXWalkContent);
736 private native void nativeInvokeGeolocationCallback(
737 long nativeXWalkContent, boolean value, String requestingFrame);
738 private native byte[] nativeGetState(long nativeXWalkContent);
739 private native boolean nativeSetState(long nativeXWalkContent, byte[] state);