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.common.CleanupReference;
40 import org.chromium.content_public.browser.JavaScriptCallback;
41 import org.chromium.content_public.browser.LoadUrlParams;
42 import org.chromium.content_public.browser.NavigationHistory;
43 import org.chromium.content_public.browser.NavigationController;
44 import org.chromium.content_public.browser.WebContents;
45 import org.chromium.media.MediaPlayerBridge;
46 import org.chromium.ui.base.ActivityWindowAndroid;
47 import org.chromium.ui.gfx.DeviceDisplayInfo;
49 @JNINamespace("xwalk")
51 * This class is the implementation class for XWalkViewInternal by calling internal
54 class XWalkContent extends FrameLayout implements XWalkPreferencesInternal.KeyValueChangeListener {
55 private static String TAG = "XWalkContent";
56 private static Class<? extends Annotation> javascriptInterfaceClass = null;
58 private ContentViewCore mContentViewCore;
59 private ContentView mContentView;
60 private ContentViewRenderView mContentViewRenderView;
61 private ActivityWindowAndroid mWindow;
62 private XWalkDevToolsServer mDevToolsServer;
63 private XWalkViewInternal mXWalkView;
64 private XWalkContentsClientBridge mContentsClientBridge;
65 private XWalkContentsIoThreadClient mIoThreadClient;
66 private XWalkWebContentsDelegateAdapter mXWalkContentsDelegateAdapter;
67 private XWalkSettings mSettings;
68 private XWalkGeolocationPermissions mGeolocationPermissions;
69 private XWalkLaunchScreenManager mLaunchScreenManager;
70 private NavigationController mNavigationController;
71 private WebContents mWebContents;
74 long mNativeWebContents;
76 static void setJavascriptInterfaceClass(Class<? extends Annotation> clazz) {
77 assert(javascriptInterfaceClass == null);
78 javascriptInterfaceClass = clazz;
81 private static final class DestroyRunnable implements Runnable {
82 private final long mNativeContent;
83 private DestroyRunnable(long nativeXWalkContent) {
84 mNativeContent = nativeXWalkContent;
89 nativeDestroy(mNativeContent);
93 // Reference to the active mNativeContent pointer while it is active use
94 // (ie before it is destroyed).
95 private CleanupReference mCleanupReference;
97 public XWalkContent(Context context, AttributeSet attrs, XWalkViewInternal xwView) {
98 super(context, attrs);
100 // Initialize the WebContensDelegate.
102 mContentsClientBridge = new XWalkContentsClientBridge(mXWalkView);
103 mXWalkContentsDelegateAdapter = new XWalkWebContentsDelegateAdapter(
104 mContentsClientBridge);
105 mIoThreadClient = new XWalkIoThreadClientImpl();
107 // Initialize mWindow which is needed by content
108 mWindow = new ActivityWindowAndroid(xwView.getActivity());
110 SharedPreferences sharedPreferences = new InMemorySharedPreferences();
111 mGeolocationPermissions = new XWalkGeolocationPermissions(sharedPreferences);
113 MediaPlayerBridge.setResourceLoadingFilter(
114 new XWalkMediaPlayerResourceLoadingFilter());
116 setNativeContent(nativeInit());
118 XWalkPreferencesInternal.load(this);
121 private void setNativeContent(long newNativeContent) {
122 if (mNativeContent != 0) {
124 mContentViewCore = null;
127 assert mNativeContent == 0 && mCleanupReference == null && mContentViewCore == null;
129 // Initialize ContentViewRenderView
130 boolean animated = XWalkPreferencesInternal.getValue(
131 XWalkPreferencesInternal.ANIMATABLE_XWALK_VIEW);
132 CompositingSurfaceType surfaceType =
133 animated ? CompositingSurfaceType.TEXTURE_VIEW : CompositingSurfaceType.SURFACE_VIEW;
134 mContentViewRenderView = new ContentViewRenderView(getContext(), surfaceType) {
135 protected void onReadyToRender() {
136 // Anything depending on the underlying Surface readiness should
140 mContentViewRenderView.onNativeLibraryLoaded(mWindow);
141 mLaunchScreenManager = new XWalkLaunchScreenManager(getContext(), mXWalkView);
142 mContentViewRenderView.registerFirstRenderedFrameListener(mLaunchScreenManager);
143 addView(mContentViewRenderView, new FrameLayout.LayoutParams(
144 FrameLayout.LayoutParams.MATCH_PARENT,
145 FrameLayout.LayoutParams.MATCH_PARENT));
147 mNativeContent = newNativeContent;
149 // The native side object has been bound to this java instance, so now is the time to
150 // bind all the native->java relationships.
151 mCleanupReference = new CleanupReference(this, new DestroyRunnable(mNativeContent));
153 mNativeWebContents = nativeGetWebContents(mNativeContent);
156 // Initialize ContentView.
157 mContentViewCore = new ContentViewCore(getContext());
158 mContentView = ContentView.newInstance(getContext(), mContentViewCore);
159 mContentViewCore.initialize(mContentView, mContentView, mNativeWebContents, mWindow);
160 mWebContents = mContentViewCore.getWebContents();
161 mNavigationController = mWebContents.getNavigationController();
162 addView(mContentView, new FrameLayout.LayoutParams(
163 FrameLayout.LayoutParams.MATCH_PARENT,
164 FrameLayout.LayoutParams.MATCH_PARENT));
165 mContentViewCore.setContentViewClient(mContentsClientBridge);
166 mContentViewRenderView.setCurrentContentViewCore(mContentViewCore);
167 // For addJavascriptInterface
168 mContentsClientBridge.installWebContentsObserver(mWebContents);
171 mContentsClientBridge.setDIPScale(DeviceDisplayInfo.create(getContext()).getDIPScale());
173 mContentViewCore.setDownloadDelegate(mContentsClientBridge);
175 // Set the third argument isAccessFromFileURLsGrantedByDefault to false, so that
176 // the members mAllowUniversalAccessFromFileURLs and mAllowFileAccessFromFileURLs
177 // won't be changed from false to true at the same time in the constructor of
178 // XWalkSettings class.
179 mSettings = new XWalkSettings(getContext(), mNativeWebContents, false);
180 // Enable AllowFileAccessFromFileURLs, so that files under file:// path could be
181 // loaded by XMLHttpRequest.
182 mSettings.setAllowFileAccessFromFileURLs(true);
183 // Enable this by default to suppport new window creation
184 mSettings.setSupportMultipleWindows(true);
186 nativeSetJavaPeers(mNativeContent, this, mXWalkContentsDelegateAdapter, mContentsClientBridge,
187 mIoThreadClient, mContentsClientBridge.getInterceptNavigationDelegate());
190 public void supplyContentsForPopup(XWalkContent newContents) {
191 if (mNativeContent == 0) return;
193 long popupNativeXWalkContent = nativeReleasePopupXWalkContent(mNativeContent);
194 if (popupNativeXWalkContent == 0) {
195 Log.w(TAG, "Popup XWalkView bind failed: no pending content.");
196 if (newContents != null) newContents.destroy();
199 if (newContents == null) {
200 nativeDestroy(popupNativeXWalkContent);
204 newContents.receivePopupContents(popupNativeXWalkContent);
207 private void receivePopupContents(long popupNativeXWalkContents) {
208 setNativeContent(popupNativeXWalkContents);
210 mContentViewCore.onShow();
213 void doLoadUrl(String url, String content) {
214 // Handle the same url loading by parameters.
215 if (url != null && !url.isEmpty() &&
216 TextUtils.equals(url, mWebContents.getUrl())) {
217 mNavigationController.reload(true);
219 LoadUrlParams params = null;
220 if (content == null || content.isEmpty()) {
221 params = new LoadUrlParams(url);
223 params = LoadUrlParams.createLoadDataParamsWithBaseUrl(
224 content, "text/html", false, url, null);
226 params.setOverrideUserAgent(LoadUrlParams.UA_OVERRIDE_TRUE);
227 mNavigationController.loadUrl(params);
230 mContentView.requestFocus();
233 public void loadUrl(String url, String data) {
234 if (mNativeContent == 0) return;
236 if ((url == null || url.isEmpty()) &&
237 (data == null || data.isEmpty())) {
241 doLoadUrl(url, data);
244 public void reload(int mode) {
245 if (mNativeContent == 0) return;
248 case XWalkViewInternal.RELOAD_IGNORE_CACHE:
249 mNavigationController.reloadIgnoringCache(true);
251 case XWalkViewInternal.RELOAD_NORMAL:
253 mNavigationController.reload(true);
257 public String getUrl() {
258 if (mNativeContent == 0) return null;
259 String url = mWebContents.getUrl();
260 if (url == null || url.trim().isEmpty()) return null;
264 public String getTitle() {
265 if (mNativeContent == 0) return null;
266 String title = mWebContents.getTitle().trim();
267 if (title == null) title = "";
271 public void addJavascriptInterface(Object object, String name) {
272 if (mNativeContent == 0) return;
273 mContentViewCore.addPossiblyUnsafeJavascriptInterface(object, name,
274 javascriptInterfaceClass);
277 public void evaluateJavascript(String script, ValueCallback<String> callback) {
278 if (mNativeContent == 0) return;
279 final ValueCallback<String> fCallback = callback;
280 JavaScriptCallback coreCallback = null;
281 if (fCallback != null) {
282 coreCallback = new JavaScriptCallback() {
284 public void handleJavaScriptResult(String jsonResult) {
285 fCallback.onReceiveValue(jsonResult);
289 mContentViewCore.getWebContents().evaluateJavaScript(script, coreCallback);
292 public void setUIClient(XWalkUIClientInternal client) {
293 if (mNativeContent == 0) return;
294 mContentsClientBridge.setUIClient(client);
297 public void setResourceClient(XWalkResourceClientInternal client) {
298 if (mNativeContent == 0) return;
299 mContentsClientBridge.setResourceClient(client);
302 public void setXWalkWebChromeClient(XWalkWebChromeClient client) {
303 if (mNativeContent == 0) return;
304 mContentsClientBridge.setXWalkWebChromeClient(client);
307 public XWalkWebChromeClient getXWalkWebChromeClient() {
308 if (mNativeContent == 0) return null;
309 return mContentsClientBridge.getXWalkWebChromeClient();
312 public void setXWalkClient(XWalkClient client) {
313 if (mNativeContent == 0) return;
314 mContentsClientBridge.setXWalkClient(client);
317 public void setDownloadListener(DownloadListener listener) {
318 if (mNativeContent == 0) return;
319 mContentsClientBridge.setDownloadListener(listener);
322 public void setNavigationHandler(XWalkNavigationHandler handler) {
323 if (mNativeContent == 0) return;
324 mContentsClientBridge.setNavigationHandler(handler);
327 public void setNotificationService(XWalkNotificationService service) {
328 if (mNativeContent == 0) return;
329 mContentsClientBridge.setNotificationService(service);
332 public void onPause() {
333 if (mNativeContent == 0) return;
334 mContentViewCore.onHide();
337 public void onResume() {
338 if (mNativeContent == 0) return;
339 mContentViewCore.onShow();
342 public void onActivityResult(int requestCode, int resultCode, Intent data) {
343 if (mNativeContent == 0) return;
344 mWindow.onActivityResult(requestCode, resultCode, data);
347 public boolean onNewIntent(Intent intent) {
348 if (mNativeContent == 0) return false;
349 return mContentsClientBridge.onNewIntent(intent);
352 public void clearCache(boolean includeDiskFiles) {
353 if (mNativeContent == 0) return;
354 nativeClearCache(mNativeContent, includeDiskFiles);
357 public void clearHistory() {
358 if (mNativeContent == 0) return;
359 mNavigationController.clearHistory();
362 public boolean canGoBack() {
363 return (mNativeContent == 0) ? false : mNavigationController.canGoBack();
366 public void goBack() {
367 if (mNativeContent == 0) return;
368 mNavigationController.goBack();
371 public boolean canGoForward() {
372 return (mNativeContent == 0) ? false : mNavigationController.canGoForward();
375 public void goForward() {
376 if (mNativeContent == 0) return;
377 mNavigationController.goForward();
380 void navigateTo(int offset) {
381 mNavigationController.goToOffset(offset);
384 public void stopLoading() {
385 if (mNativeContent == 0) return;
387 mContentsClientBridge.onStopLoading();
390 // Currently, timer pause/resume is actually
391 // a global setting. And multiple pause will fail the
392 // DCHECK in content (content_view_statics.cc:57).
393 // Here uses a static boolean to avoid this issue.
394 private static boolean timerPaused = false;
396 // TODO(Guangzhen): ContentViewStatics will be removed in upstream,
397 // details in content_view_statics.cc.
398 // We need follow up after upstream updates that.
399 public void pauseTimers() {
400 if (timerPaused || (mNativeContent == 0)) return;
401 ContentViewStatics.setWebKitSharedTimersSuspended(true);
405 public void resumeTimers() {
406 if (!timerPaused || (mNativeContent == 0)) return;
407 ContentViewStatics.setWebKitSharedTimersSuspended(false);
411 public String getOriginalUrl() {
412 if (mNativeContent == 0) return null;
413 NavigationHistory history = mNavigationController.getNavigationHistory();
414 int currentIndex = history.getCurrentEntryIndex();
415 if (currentIndex >= 0 && currentIndex < history.getEntryCount()) {
416 return history.getEntryAtIndex(currentIndex).getOriginalUrl();
421 public String getXWalkVersion() {
422 if (mNativeContent == 0) return "";
423 return nativeGetVersion(mNativeContent);
426 public void setBackgroundColor(int color) {
427 if (mNativeContent == 0) return;
428 nativeSetBackgroundColor(mNativeContent, color);
431 public void setNetworkAvailable(boolean networkUp) {
432 if (mNativeContent == 0) return;
433 nativeSetJsOnlineProperty(mNativeContent, networkUp);
436 // For instrumentation test.
437 public ContentViewCore getContentViewCoreForTest() {
438 return mContentViewCore;
441 // For instrumentation test.
442 public void installWebContentsObserverForTest(XWalkContentsClient contentClient) {
443 if (mNativeContent == 0) return;
444 contentClient.installWebContentsObserver(mContentViewCore.getWebContents());
447 public String devToolsAgentId() {
448 if (mNativeContent == 0) return "";
449 return nativeDevToolsAgentId(mNativeContent);
452 public XWalkSettings getSettings() {
456 public void loadAppFromManifest(String url, String data) {
457 if (mNativeContent == 0 ||
458 ((url == null || url.isEmpty()) &&
459 (data == null || data.isEmpty()))) {
463 String content = data;
464 // If the data of manifest.json is not set, try to load it.
465 if (data == null || data.isEmpty()) {
467 content = AndroidProtocolHandler.getUrlContent(mXWalkView.getActivity(), url);
468 } catch (IOException e) {
469 throw new RuntimeException("Failed to read the manifest: " + url);
473 // Calculate the base url of manifestUrl. Used by native side.
474 // TODO(yongsheng): It's from runtime side. Need to find a better way
476 String baseUrl = url;
477 int position = url.lastIndexOf("/");
478 if (position != -1) {
479 baseUrl = url.substring(0, position + 1);
481 Log.w(TAG, "The url of manifest.json is probably not set correctly.");
484 if (!nativeSetManifest(mNativeContent, baseUrl, content)) {
485 throw new RuntimeException("Failed to parse the manifest file: " + url);
489 public XWalkNavigationHistoryInternal getNavigationHistory() {
490 if (mNativeContent == 0) return null;
492 return new XWalkNavigationHistoryInternal(mXWalkView, mNavigationController.getNavigationHistory());
495 public static final String SAVE_RESTORE_STATE_KEY = "XWALKVIEW_STATE";
497 public XWalkNavigationHistoryInternal saveState(Bundle outState) {
498 if (mNativeContent == 0 || outState == null) return null;
500 byte[] state = nativeGetState(mNativeContent);
501 if (state == null) return null;
503 outState.putByteArray(SAVE_RESTORE_STATE_KEY, state);
504 return getNavigationHistory();
507 public XWalkNavigationHistoryInternal restoreState(Bundle inState) {
508 if (mNativeContent == 0 || inState == null) return null;
510 byte[] state = inState.getByteArray(SAVE_RESTORE_STATE_KEY);
511 if (state == null) return null;
513 boolean result = nativeSetState(mNativeContent, state);
515 // The onUpdateTitle callback normally happens when a page is loaded,
516 // but is optimized out in the restoreState case because the title is
517 // already restored. See WebContentsImpl::UpdateTitleForEntry. So we
518 // call the callback explicitly here.
520 mContentsClientBridge.onUpdateTitle(mWebContents.getTitle());
523 return result ? getNavigationHistory() : null;
526 boolean hasEnteredFullscreen() {
527 return mContentsClientBridge.hasEnteredFullscreen();
530 void exitFullscreen() {
531 if (hasEnteredFullscreen()) {
532 mContentsClientBridge.exitFullscreen(mNativeWebContents);
537 public void onGetUrlFromManifest(String url) {
538 if (url != null && !url.isEmpty()) {
544 public void onGetUrlAndLaunchScreenFromManifest(String url, String readyWhen, String imageBorder) {
545 if (url == null || url.isEmpty()) return;
546 mLaunchScreenManager.displayLaunchScreen(readyWhen, imageBorder);
547 mContentsClientBridge.registerPageLoadListener(mLaunchScreenManager);
552 public void onGetFullscreenFlagFromManifest(boolean enterFullscreen) {
553 if (enterFullscreen) {
554 if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
555 View decorView = mXWalkView.getActivity().getWindow().getDecorView();
556 decorView.setSystemUiVisibility(
557 View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
558 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
559 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
560 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
561 View.SYSTEM_UI_FLAG_FULLSCREEN |
562 View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
564 mXWalkView.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
569 public void destroy() {
570 if (mNativeContent == 0) return;
572 XWalkPreferencesInternal.unload(this);
573 // Reset existing notification service in order to destruct it.
574 setNotificationService(null);
575 // Remove its children used for page rendering from view hierarchy.
576 removeView(mContentView);
577 removeView(mContentViewRenderView);
578 mContentViewRenderView.setCurrentContentViewCore(null);
580 // Destroy the native resources.
581 mContentViewRenderView.destroy();
582 mContentViewCore.destroy();
584 mCleanupReference.cleanupNow();
585 mCleanupReference = null;
589 public int getRoutingID() {
590 return nativeGetRoutingID(mNativeContent);
593 //--------------------------------------------------------------------------------------------
594 private class XWalkIoThreadClientImpl implements XWalkContentsIoThreadClient {
595 // All methods are called on the IO thread.
598 public int getCacheMode() {
599 return mSettings.getCacheMode();
603 public InterceptedRequestData shouldInterceptRequest(final String url,
604 boolean isMainFrame) {
606 // Notify a resource load is started. This is not the best place to start the callback
607 // but it's a workable way.
608 mContentsClientBridge.getCallbackHelper().postOnResourceLoadStarted(url);
610 WebResourceResponse webResourceResponse = mContentsClientBridge.shouldInterceptRequest(url);
611 InterceptedRequestData interceptedRequestData = null;
613 if (webResourceResponse == null) {
614 mContentsClientBridge.getCallbackHelper().postOnLoadResource(url);
616 if (isMainFrame && webResourceResponse.getData() == null) {
617 mContentsClientBridge.getCallbackHelper().postOnReceivedError(
618 XWalkResourceClientInternal.ERROR_UNKNOWN, null, url);
620 interceptedRequestData = new InterceptedRequestData(webResourceResponse.getMimeType(),
621 webResourceResponse.getEncoding(),
622 webResourceResponse.getData());
624 return interceptedRequestData;
628 public boolean shouldBlockContentUrls() {
629 return !mSettings.getAllowContentAccess();
633 public boolean shouldBlockFileUrls() {
634 return !mSettings.getAllowFileAccess();
638 public boolean shouldBlockNetworkLoads() {
639 return mSettings.getBlockNetworkLoads();
643 public void onDownloadStart(String url,
645 String contentDisposition,
647 long contentLength) {
648 mContentsClientBridge.getCallbackHelper().postOnDownloadStart(url, userAgent,
649 contentDisposition, mimeType, contentLength);
653 public void newLoginRequest(String realm, String account, String args) {
654 mContentsClientBridge.getCallbackHelper().postOnReceivedLoginRequest(realm, account, args);
658 private class XWalkGeolocationCallback implements XWalkGeolocationPermissions.Callback {
660 public void invoke(final String origin, final boolean allow, final boolean retain) {
661 ThreadUtils.runOnUiThread(new Runnable() {
666 mGeolocationPermissions.allow(origin);
668 mGeolocationPermissions.deny(origin);
671 nativeInvokeGeolocationCallback(mNativeContent, allow, origin);
678 private void onGeolocationPermissionsShowPrompt(String origin) {
679 if (mNativeContent == 0) return;
680 // Reject if geolocation is disabled, or the origin has a retained deny.
681 if (!mSettings.getGeolocationEnabled()) {
682 nativeInvokeGeolocationCallback(mNativeContent, false, origin);
685 // Allow if the origin has a retained allow.
686 if (mGeolocationPermissions.hasOrigin(origin)) {
687 nativeInvokeGeolocationCallback(mNativeContent,
688 mGeolocationPermissions.isOriginAllowed(origin),
692 mContentsClientBridge.onGeolocationPermissionsShowPrompt(
693 origin, new XWalkGeolocationCallback());
697 public void onGeolocationPermissionsHidePrompt() {
698 mContentsClientBridge.onGeolocationPermissionsHidePrompt();
701 public void enableRemoteDebugging() {
702 // Chrome looks for "devtools_remote" pattern in the name of a unix domain socket
703 // to identify a debugging page
704 final String socketName = getContext().getApplicationContext().getPackageName() + "_devtools_remote";
705 if (mDevToolsServer == null) {
706 mDevToolsServer = new XWalkDevToolsServer(socketName);
707 mDevToolsServer.setRemoteDebuggingEnabled(
708 true, XWalkDevToolsServer.Security.ALLOW_SOCKET_ACCESS);
712 void disableRemoteDebugging() {
713 if (mDevToolsServer == null) return;
715 if (mDevToolsServer.isRemoteDebuggingEnabled()) {
716 mDevToolsServer.setRemoteDebuggingEnabled(false);
718 mDevToolsServer.destroy();
719 mDevToolsServer = null;
722 public String getRemoteDebuggingUrl() {
723 if (mDevToolsServer == null) return "";
724 // devtools/page is hardcoded in devtools_http_handler_impl.cc (kPageUrlPrefix)
725 return "ws://" + mDevToolsServer.getSocketName() + "/devtools/page/" + devToolsAgentId();
729 public void onKeyValueChanged(String key, XWalkPreferencesInternal.PreferenceValue value) {
730 if (key == null) return;
731 if (key.equals(XWalkPreferencesInternal.REMOTE_DEBUGGING)) {
732 if (value.getBooleanValue()) enableRemoteDebugging();
733 else disableRemoteDebugging();
734 } else if (key.equals(XWalkPreferencesInternal.ENABLE_JAVASCRIPT)) {
735 if (mSettings != null) {
736 mSettings.setJavaScriptEnabled(value.getBooleanValue());
738 } else if (key.equals(XWalkPreferencesInternal.JAVASCRIPT_CAN_OPEN_WINDOW)) {
739 if (mSettings != null) {
740 mSettings.setJavaScriptCanOpenWindowsAutomatically(value.getBooleanValue());
742 } else if (key.equals(XWalkPreferencesInternal.ALLOW_UNIVERSAL_ACCESS_FROM_FILE)) {
743 if (mSettings != null) {
744 mSettings.setAllowUniversalAccessFromFileURLs(value.getBooleanValue());
746 } else if (key.equals(XWalkPreferencesInternal.SUPPORT_MULTIPLE_WINDOWS)) {
747 if (mSettings != null) {
748 mSettings.setSupportMultipleWindows(value.getBooleanValue());
753 public void setOverlayVideoMode(boolean enabled) {
754 if (mContentViewRenderView != null) {
755 mContentViewRenderView.setOverlayVideoMode(enabled);
759 private native long nativeInit();
760 private static native void nativeDestroy(long nativeXWalkContent);
761 private native long nativeGetWebContents(long nativeXWalkContent);
762 private native long nativeReleasePopupXWalkContent(long nativeXWalkContent);
763 private native void nativeSetJavaPeers(
764 long nativeXWalkContent,
765 XWalkContent xwalkContent,
766 XWalkWebContentsDelegateAdapter xwalkContentsDelegate,
767 XWalkContentsClientBridge contentsClientBridge,
768 XWalkContentsIoThreadClient ioThreadClient,
769 InterceptNavigationDelegate navigationInterceptionDelegate);
770 private native void nativeClearCache(long nativeXWalkContent, boolean includeDiskFiles);
771 private native String nativeDevToolsAgentId(long nativeXWalkContent);
772 private native String nativeGetVersion(long nativeXWalkContent);
773 private native void nativeSetJsOnlineProperty(long nativeXWalkContent, boolean networkUp);
774 private native boolean nativeSetManifest(long nativeXWalkContent, String path, String manifest);
775 private native int nativeGetRoutingID(long nativeXWalkContent);
776 private native void nativeInvokeGeolocationCallback(
777 long nativeXWalkContent, boolean value, String requestingFrame);
778 private native byte[] nativeGetState(long nativeXWalkContent);
779 private native boolean nativeSetState(long nativeXWalkContent, byte[] state);
780 private native void nativeSetBackgroundColor(long nativeXWalkContent, int color);