e964fbc06b0f2b66f28043f14b75abd413e46b03
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / java / src / org / xwalk / core / XWalkView.java
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.
4
5 package org.xwalk.core;
6
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;
18
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
25 public class XWalkView extends FrameLayout {
26
27     private XWalkContent mContent;
28     private XWalkDevToolsServer mDevToolsServer;
29     private Activity mActivity;
30     private Context mContext;
31
32     public XWalkView(Context context, Activity activity) {
33         super(context, null);
34
35         checkThreadSafety();
36         // Make sure mActivity is initialized before calling 'init' method.
37         mActivity = activity;
38         mContext = context;
39         init(context, null);
40     }
41
42     public Activity getActivity() {
43         if (mActivity != null) {
44             return mActivity;
45         } else if (getContext() instanceof Activity) {
46             return (Activity)getContext();
47         }
48
49         // Never achieve here.
50         assert(false);
51         return null;
52     }
53
54     public Context getViewContext() {
55         return mContext;
56     }
57
58     /**
59      * Constructors for inflating via XML.
60      */
61     public XWalkView(Context context, AttributeSet attrs) {
62         super(context, attrs);
63
64         checkThreadSafety();
65         mContext = context;
66         init(context, attrs);
67     }
68
69     private void init(Context context, AttributeSet attrs) {
70         // Initialize chromium resources. Assign them the correct ids in
71         // xwalk core.
72         XWalkInternalResources.resetIds(context);
73
74         // Intialize library, paks and others.
75         XWalkViewDelegate.init(this);
76
77         initXWalkContent(context, attrs);
78     }
79
80     private void initXWalkContent(Context context, AttributeSet attrs) {
81         mContent = new XWalkContent(context, attrs, this);
82         addView(mContent,
83                 new FrameLayout.LayoutParams(
84                         FrameLayout.LayoutParams.MATCH_PARENT,
85                         FrameLayout.LayoutParams.MATCH_PARENT));
86
87
88         // Set default XWalkDefaultClient.
89         setXWalkClient(new XWalkDefaultClient(context, this));
90         // Set default XWalkWebChromeClient and DownloadListener. The default actions
91         // are provided via the following clients if special actions are not needed.
92         setXWalkWebChromeClient(new XWalkDefaultWebChromeClient(context, this));
93         setDownloadListener(new XWalkDefaultDownloadListener(context));
94         setNavigationHandler(new XWalkDefaultNavigationHandler(context));
95         setNotificationService(new XWalkDefaultNotificationService(context, this));
96     }
97
98     public void loadUrl(String url) {
99         checkThreadSafety();
100         mContent.loadUrl(url);
101     }
102
103     public void loadAppFromManifest(String path, String manifest) {
104         mContent.loadAppFromManifest(path, manifest);
105     }
106
107     public void reload() {
108         checkThreadSafety();
109         mContent.reload();
110     }
111
112     public void addJavascriptInterface(Object object, String name) {
113         checkThreadSafety();
114         mContent.addJavascriptInterface(object, name);
115     }
116
117     public String getUrl() {
118         checkThreadSafety();
119         return mContent.getUrl();
120     }
121
122     public String getTitle() {
123         checkThreadSafety();
124         return mContent.getTitle();
125     }
126
127     public void clearCache(boolean includeDiskFiles) {
128         checkThreadSafety();
129         mContent.clearCache(includeDiskFiles);
130     }
131
132     public void clearHistory() {
133         checkThreadSafety();
134         mContent.clearHistory();
135     }
136
137     public boolean canGoBack() {
138         checkThreadSafety();
139         return mContent.canGoBack();
140     }
141
142     public void goBack() {
143         checkThreadSafety();
144         mContent.goBack();
145     }
146
147     public boolean canGoForward() {
148         checkThreadSafety();
149         return mContent.canGoForward();
150     }
151
152     public void goForward() {
153         checkThreadSafety();
154         mContent.goForward();
155     }
156
157     public boolean isFullscreen() {
158         checkThreadSafety();
159         return mContent.isFullscreen();
160     }
161
162     public void exitFullscreen() {
163         checkThreadSafety();
164         mContent.exitFullscreen();
165     }
166
167     public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
168         checkThreadSafety();
169         return false;
170     }
171
172     public void setLayoutParams(ViewGroup.LayoutParams params) {
173         checkThreadSafety();
174         super.setLayoutParams(params);
175     }
176
177     public XWalkSettings getSettings() {
178         checkThreadSafety();
179         return mContent.getSettings();
180     }
181
182     public String getOriginalUrl() {
183         checkThreadSafety();
184         return mContent.getOriginalUrl();
185     }
186
187     public void setNetworkAvailable(boolean networkUp) {
188         checkThreadSafety();
189         mContent.setNetworkAvailable(networkUp);
190     }
191
192     public void setInitialScale(int scaleInPercent) {
193         checkThreadSafety();
194     }
195
196     public void setXWalkWebChromeClient(XWalkWebChromeClient client) {
197         checkThreadSafety();
198         mContent.setXWalkWebChromeClient(client);
199     }
200
201     public void setXWalkClient(XWalkClient client) {
202         checkThreadSafety();
203         mContent.setXWalkClient(client);
204     }
205
206     public void stopLoading() {
207         checkThreadSafety();
208         mContent.stopLoading();
209     }
210
211     public void pauseTimers() {
212         checkThreadSafety();
213         mContent.pauseTimers();
214     }
215
216     public void resumeTimers() {
217         checkThreadSafety();
218         mContent.resumeTimers();
219     }
220
221     public void setDownloadListener(DownloadListener listener) {
222         checkThreadSafety();
223         mContent.setDownloadListener(listener);
224     }
225
226     public void setNavigationHandler(XWalkNavigationHandler handler) {
227         checkThreadSafety();
228         mContent.setNavigationHandler(handler);
229     }
230
231     public void setNotificationService(XWalkNotificationService service) {
232         checkThreadSafety();
233         mContent.setNotificationService(service);
234     }
235
236     // Enables remote debugging and returns the URL at which the dev tools server is listening
237     // for commands. The allowedUid argument can be used to specify the uid of the process that is
238     // permitted to connect.
239     public String enableRemoteDebugging(int allowedUid) {
240         checkThreadSafety();
241         // Chrome looks for "devtools_remote" pattern in the name of a unix domain socket
242         // to identify a debugging page
243         final String socketName = getContext().getApplicationContext().getPackageName() + "_devtools_remote";
244         if (mDevToolsServer == null) {
245             mDevToolsServer = new XWalkDevToolsServer(socketName);
246             mDevToolsServer.allowConnectionFromUid(allowedUid);
247             mDevToolsServer.setRemoteDebuggingEnabled(true);
248         }
249         // devtools/page is hardcoded in devtools_http_handler_impl.cc (kPageUrlPrefix)
250         return "ws://" + socketName + "/devtools/page/" + mContent.devToolsAgentId();
251     }
252
253     // Enables remote debugging and returns the URL at which the dev tools server is listening
254     // for commands. Only the current process is allowed to connect to the server.
255     public String enableRemoteDebugging() {
256         return enableRemoteDebugging(mContext.getApplicationInfo().uid);
257     }
258
259     public void disableRemoteDebugging() {
260         checkThreadSafety();
261         if (mDevToolsServer ==  null) return;
262
263         if (mDevToolsServer.isRemoteDebuggingEnabled()) {
264             mDevToolsServer.setRemoteDebuggingEnabled(false);
265         }
266         mDevToolsServer.destroy();
267         mDevToolsServer = null;
268     }
269
270     public void onPause() {
271         mContent.onPause();
272     }
273
274     public void onResume() {
275         mContent.onResume();
276     }
277
278     public boolean onKeyUp(int keyCode, KeyEvent event) {
279         if (keyCode == KeyEvent.KEYCODE_BACK) {
280             // If there's navigation happens when app is fullscreen,
281             // the content will still be fullscreen after navigation.
282             // In such case, the back key will exit fullscreen first.
283             if (isFullscreen()) {
284                 exitFullscreen();
285                 return true;
286             } else if (canGoBack()) {
287                 goBack();
288                 return true;
289             }
290         }
291         return false;
292     }
293
294     public void onDestroy() {
295         destroy();
296     }
297
298     public void destroy() {
299         mContent.destroy();
300         disableRemoteDebugging();
301     }
302
303     public void onActivityResult(int requestCode, int resultCode, Intent data) {
304         mContent.onActivityResult(requestCode, resultCode, data);
305     }
306
307     public boolean onNewIntent(Intent intent) {
308         return mContent.onNewIntent(intent);
309     }
310
311     public String getVersion() {
312         return mContent.getVersion();
313     }
314
315     public int getContentID() {
316         return mContent.getRoutingID();
317     }
318
319     // TODO(shouqun): requestFocusFromTouch, setVerticalScrollBarEnabled are
320     // from android.view.View;
321
322     // For instrumentation test.
323     public XWalkContent getXWalkViewContentForTest() {
324         checkThreadSafety();
325         return mContent;
326     }
327
328     public XWalkWebChromeClient getXWalkWebChromeClientForTest() {
329         return mContent.getXWalkWebChromeClient();
330     }
331
332     public WebBackForwardList copyBackForwardList() {
333         return mContent.copyBackForwardList();
334     }
335
336     public WebBackForwardList saveState(Bundle outState) {
337         return mContent.saveState(outState);
338     }
339
340     public WebBackForwardList restoreState(Bundle inState) {
341         return mContent.restoreState(inState);
342     }
343
344     private static void checkThreadSafety() {
345         if (Looper.myLooper() != Looper.getMainLooper()) {
346             Throwable throwable = new Throwable(
347                 "Warning: A XWalkView method was called on thread '" +
348                 Thread.currentThread().getName() + "'. " +
349                 "All XWalkView methods must be called on the UI thread. ");
350             throw new RuntimeException(throwable);
351         }
352     }
353 }