1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.xwalk.core;
7 import android.app.Activity;
8 import android.content.Context;
9 import android.content.Intent;
10 import android.graphics.Rect;
11 import android.os.Bundle;
12 import android.os.Looper;
13 import android.util.AttributeSet;
14 import android.view.KeyEvent;
15 import android.view.ViewGroup;
16 import android.webkit.WebSettings;
17 import android.widget.FrameLayout;
19 import org.xwalk.core.client.XWalkDefaultClient;
20 import org.xwalk.core.client.XWalkDefaultDownloadListener;
21 import org.xwalk.core.client.XWalkDefaultNavigationHandler;
22 import org.xwalk.core.client.XWalkDefaultNotificationService;
23 import org.xwalk.core.client.XWalkDefaultWebChromeClient;
24 import org.xwalk.core.extension.XWalkExtensionManager;
26 public class XWalkView extends FrameLayout {
28 private XWalkContent mContent;
29 private XWalkDevToolsServer mDevToolsServer;
30 private Activity mActivity;
31 private Context mContext;
32 private XWalkExtensionManager mExtensionManager;
34 public XWalkView(Context context, Activity activity) {
38 // Make sure mActivity is initialized before calling 'init' method.
44 public Activity getActivity() {
45 if (mActivity != null) {
47 } else if (getContext() instanceof Activity) {
48 return (Activity)getContext();
51 // Never achieve here.
56 public Context getViewContext() {
61 * Constructors for inflating via XML.
63 public XWalkView(Context context, AttributeSet attrs) {
64 super(context, attrs);
71 private void init(Context context, AttributeSet attrs) {
72 // Initialize chromium resources. Assign them the correct ids in
74 XWalkInternalResources.resetIds(context);
76 // Intialize library, paks and others.
77 XWalkViewDelegate.init(this);
79 initXWalkContent(context, attrs);
82 private void initXWalkContent(Context context, AttributeSet attrs) {
83 mContent = new XWalkContent(context, attrs, this);
85 new FrameLayout.LayoutParams(
86 FrameLayout.LayoutParams.MATCH_PARENT,
87 FrameLayout.LayoutParams.MATCH_PARENT));
90 // Set default XWalkDefaultClient.
91 setXWalkClient(new XWalkDefaultClient(context, this));
92 // Set default XWalkWebChromeClient and DownloadListener. The default actions
93 // are provided via the following clients if special actions are not needed.
94 setXWalkWebChromeClient(new XWalkDefaultWebChromeClient(context, this));
95 setDownloadListener(new XWalkDefaultDownloadListener(context));
96 setNavigationHandler(new XWalkDefaultNavigationHandler(context));
97 setNotificationService(new XWalkDefaultNotificationService(context, this));
99 // Enable xwalk extension mechanism and start load extensions here.
100 // Note that it has to be after above initialization.
101 mExtensionManager = new XWalkExtensionManager(context, getActivity());
102 mExtensionManager.loadExtensions();
105 public void loadUrl(String url) {
107 mContent.loadUrl(url);
110 public void loadAppFromManifest(String path, String manifest) {
111 mContent.loadAppFromManifest(path, manifest);
114 public void reload() {
119 public void addJavascriptInterface(Object object, String name) {
121 mContent.addJavascriptInterface(object, name);
124 public String getUrl() {
126 return mContent.getUrl();
129 public String getTitle() {
131 return mContent.getTitle();
134 public void clearCache(boolean includeDiskFiles) {
136 mContent.clearCache(includeDiskFiles);
139 public void clearHistory() {
141 mContent.clearHistory();
144 public boolean canGoBack() {
146 return mContent.canGoBack();
149 public void goBack() {
154 public boolean canGoForward() {
156 return mContent.canGoForward();
159 public void goForward() {
161 mContent.goForward();
164 public boolean isFullscreen() {
166 return mContent.isFullscreen();
169 public void exitFullscreen() {
171 mContent.exitFullscreen();
174 public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
179 public void setLayoutParams(ViewGroup.LayoutParams params) {
181 super.setLayoutParams(params);
184 public XWalkSettings getSettings() {
186 return mContent.getSettings();
189 public String getOriginalUrl() {
191 return mContent.getOriginalUrl();
194 public void setNetworkAvailable(boolean networkUp) {
196 mContent.setNetworkAvailable(networkUp);
199 public void setInitialScale(int scaleInPercent) {
203 public void setXWalkWebChromeClient(XWalkWebChromeClient client) {
205 mContent.setXWalkWebChromeClient(client);
208 public void setXWalkClient(XWalkClient client) {
210 mContent.setXWalkClient(client);
213 public void stopLoading() {
215 mContent.stopLoading();
218 public void pauseTimers() {
220 mContent.pauseTimers();
223 public void resumeTimers() {
225 mContent.resumeTimers();
228 public void setDownloadListener(DownloadListener listener) {
230 mContent.setDownloadListener(listener);
233 public void setNavigationHandler(XWalkNavigationHandler handler) {
235 mContent.setNavigationHandler(handler);
238 public void setNotificationService(XWalkNotificationService service) {
240 mContent.setNotificationService(service);
243 // Enables remote debugging and returns the URL at which the dev tools server is listening
244 // for commands. The allowedUid argument can be used to specify the uid of the process that is
245 // permitted to connect.
246 public String enableRemoteDebugging(int allowedUid) {
248 // Chrome looks for "devtools_remote" pattern in the name of a unix domain socket
249 // to identify a debugging page
250 final String socketName = getContext().getApplicationContext().getPackageName() + "_devtools_remote";
251 if (mDevToolsServer == null) {
252 mDevToolsServer = new XWalkDevToolsServer(socketName);
253 mDevToolsServer.allowConnectionFromUid(allowedUid);
254 mDevToolsServer.setRemoteDebuggingEnabled(true);
256 // devtools/page is hardcoded in devtools_http_handler_impl.cc (kPageUrlPrefix)
257 return "ws://" + socketName + "/devtools/page/" + mContent.devToolsAgentId();
260 // Enables remote debugging and returns the URL at which the dev tools server is listening
261 // for commands. Only the current process is allowed to connect to the server.
262 public String enableRemoteDebugging() {
263 return enableRemoteDebugging(mContext.getApplicationInfo().uid);
266 public void disableRemoteDebugging() {
268 if (mDevToolsServer == null) return;
270 if (mDevToolsServer.isRemoteDebuggingEnabled()) {
271 mDevToolsServer.setRemoteDebuggingEnabled(false);
273 mDevToolsServer.destroy();
274 mDevToolsServer = null;
277 public void onPause() {
278 mExtensionManager.onPause();
282 public void onResume() {
283 mExtensionManager.onResume();
287 public boolean onKeyUp(int keyCode, KeyEvent event) {
288 if (keyCode == KeyEvent.KEYCODE_BACK) {
289 // If there's navigation happens when app is fullscreen,
290 // the content will still be fullscreen after navigation.
291 // In such case, the back key will exit fullscreen first.
292 if (isFullscreen()) {
295 } else if (canGoBack()) {
303 public void onDestroy() {
307 public void destroy() {
308 mExtensionManager.onDestroy();
310 disableRemoteDebugging();
313 public void onActivityResult(int requestCode, int resultCode, Intent data) {
314 mExtensionManager.onActivityResult(requestCode, resultCode, data);
315 mContent.onActivityResult(requestCode, resultCode, data);
318 public boolean onNewIntent(Intent intent) {
319 return mContent.onNewIntent(intent);
322 public String getVersion() {
323 return mContent.getVersion();
326 public int getContentID() {
327 return mContent.getRoutingID();
330 // TODO(shouqun): requestFocusFromTouch, setVerticalScrollBarEnabled are
331 // from android.view.View;
333 // For instrumentation test.
334 public XWalkContent getXWalkViewContentForTest() {
339 public XWalkWebChromeClient getXWalkWebChromeClientForTest() {
340 return mContent.getXWalkWebChromeClient();
343 public WebBackForwardList copyBackForwardList() {
344 return mContent.copyBackForwardList();
347 public WebBackForwardList saveState(Bundle outState) {
348 return mContent.saveState(outState);
351 public WebBackForwardList restoreState(Bundle inState) {
352 return mContent.restoreState(inState);
355 private static void checkThreadSafety() {
356 if (Looper.myLooper() != Looper.getMainLooper()) {
357 Throwable throwable = new Throwable(
358 "Warning: A XWalkView method was called on thread '" +
359 Thread.currentThread().getName() + "'. " +
360 "All XWalkView methods must be called on the UI thread. ");
361 throw new RuntimeException(throwable);