Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / core_shell / src / org / xwalk / core / xwview / shell / XWalkViewShellActivity.java
1 // Copyright (c) 2013-2014 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.xwview.shell;
6
7 import java.util.HashMap;
8
9 import android.app.ActionBar;
10 import android.app.ActionBar.Tab;
11 import android.app.FragmentTransaction;
12 import android.content.BroadcastReceiver;
13 import android.content.Intent;
14 import android.content.Context;
15 import android.content.IntentFilter;
16 import android.graphics.drawable.ClipDrawable;
17 import android.os.Bundle;
18 import android.os.Looper;
19 import android.os.MessageQueue;
20 import android.support.v4.app.FragmentActivity;
21 import android.support.v4.view.ViewPager;
22 import android.util.Log;
23 import android.view.KeyEvent;
24 import android.view.View;
25 import android.view.View.OnClickListener;
26 import android.view.View.OnFocusChangeListener;
27 import android.view.inputmethod.EditorInfo;
28 import android.view.inputmethod.InputMethodManager;
29 import android.widget.EditText;
30 import android.widget.ImageButton;
31 import android.widget.LinearLayout;
32 import android.widget.TextView;
33 import android.widget.TextView.OnEditorActionListener;
34
35 import org.chromium.base.BaseSwitches;
36 import org.chromium.base.CommandLine;
37 import org.chromium.base.library_loader.LibraryLoader;
38 import org.chromium.content.browser.TracingControllerAndroid;
39 import org.xwalk.core.XWalkDefaultWebChromeClient;
40 import org.xwalk.core.XWalkView;
41
42 public class XWalkViewShellActivity extends FragmentActivity
43         implements ActionBar.TabListener, XWalkViewSectionFragment.OnXWalkViewCreatedListener{
44     public static final String COMMAND_LINE_FILE = "/data/local/tmp/xwview-shell-command-line";
45     private static final String TAG = XWalkViewShellActivity.class.getName();
46     public static final String COMMAND_LINE_ARGS_KEY = "commandLineArgs";
47     private static final long COMPLETED_PROGRESS_TIMEOUT_MS = 200;
48     private static final String ACTION_LAUNCH_URL = "org.xwalk.core.xwview.shell.launch";
49
50     private LinearLayout mToolbar;
51     private EditText mUrlTextView;
52     private ImageButton mPrevButton;
53     private ImageButton mNextButton;
54     private ImageButton mStopButton;
55     private ImageButton mReloadButton;
56     private ClipDrawable mProgressDrawable;
57     private XWalkView mActiveView;
58     private TracingControllerAndroid mTracingController;
59     private BroadcastReceiver mReceiver;
60     private ActionBar mActionBar;
61     private SectionsPagerAdapter mSectionsPagerAdapter;
62     private ViewPager mViewPager;
63     private HashMap<XWalkView, Integer> mProgressMap;
64
65     private Runnable mClearProgressRunnable = new Runnable() {
66         @Override
67         public void run() {
68             mProgressDrawable.setLevel(0);
69         }
70     };
71
72     TracingControllerAndroid getTracingController() {
73         if (mTracingController == null) {
74             mTracingController = new TracingControllerAndroid(this);
75         }
76         return mTracingController;
77     }
78
79     private void registerTracingReceiverWhenIdle() {
80         // Delay tracing receiver registration until the main loop is idle.
81         Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
82             @Override
83             public boolean queueIdle() {
84                 // Will retry if the native library is not initialized yet.
85                 if (!LibraryLoader.isInitialized()) return true;
86                 try {
87                     getTracingController().registerReceiver(XWalkViewShellActivity.this);
88                 } catch (SecurityException e) {
89                     Log.w(TAG, "failed to register tracing receiver: " + e.getMessage());
90                 }
91                 return false;
92             }
93         });
94     }
95
96     private void unregisterTracingReceiver() {
97         try {
98             getTracingController().unregisterReceiver(this);
99         } catch (SecurityException e) {
100             Log.w(TAG, "failed to unregister tracing receiver: " + e.getMessage());
101         }
102     }
103
104     @Override
105     public void onCreate(Bundle savedInstanceState) {
106         super.onCreate(savedInstanceState);
107
108         registerTracingReceiverWhenIdle();
109
110         if (!CommandLine.isInitialized()) {
111             CommandLine.initFromFile(COMMAND_LINE_FILE);
112             String[] commandLineParams = getCommandLineParamsFromIntent(getIntent());
113             if (commandLineParams != null) {
114                 CommandLine.getInstance().appendSwitchesAndArguments(commandLineParams);
115             }
116         }
117
118         waitForDebuggerIfNeeded();
119
120         setContentView(R.layout.testshell_activity);
121
122         mActionBar = getActionBar();
123         mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
124         mSectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager(), mActionBar);
125
126         mViewPager = (ViewPager) findViewById(R.id.pager);
127         mViewPager.setAdapter(mSectionsPagerAdapter);
128         mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
129             @Override
130             public void onPageSelected(int position) {
131                 mActionBar.setSelectedNavigationItem(position);
132             }
133         });
134
135         mProgressMap = new HashMap<XWalkView, Integer>();
136         // Add two tabs.
137         mActionBar.addTab(
138                 mActionBar.newTab()
139                         .setText(mSectionsPagerAdapter.getPageTitle(0))
140                         .setTabListener(this));
141         mActionBar.addTab(
142                 mActionBar.newTab()
143                         .setText(mSectionsPagerAdapter.getPageTitle(1))
144                         .setTabListener(this));
145
146         mToolbar = (LinearLayout) findViewById(R.id.toolbar);
147         mProgressDrawable = (ClipDrawable) findViewById(R.id.toolbar).getBackground();
148
149         IntentFilter intentFilter = new IntentFilter(ACTION_LAUNCH_URL);
150         mReceiver = new BroadcastReceiver() {
151             @Override
152             public void onReceive(Context context, Intent intent) {
153                 Bundle bundle = intent.getExtras();
154                 if (bundle == null)
155                     return;
156
157                 if (bundle.containsKey("url")) {
158                     String extra = bundle.getString("url");
159                     if (mActiveView != null)
160                         mActiveView.loadUrl(sanitizeUrl(extra));
161                 }
162             }
163         };
164         registerReceiver(mReceiver, intentFilter);
165     }
166
167     @Override
168     public void onPause() {
169         super.onPause();
170         mSectionsPagerAdapter.onPause();
171     }
172
173     @Override
174     public void onResume() {
175         super.onResume();
176         mSectionsPagerAdapter.onResume();
177     }
178
179     @Override
180     public void onDestroy() {
181         super.onDestroy();
182         unregisterReceiver(mReceiver);
183         unregisterTracingReceiver();
184         mSectionsPagerAdapter.onDestroy();
185     }
186
187     @Override
188     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
189         if (mActiveView != null) mActiveView.onActivityResult(requestCode, resultCode, data);
190     }
191
192     @Override
193     public boolean onKeyUp(int keyCode, KeyEvent event) {
194         if (mActiveView != null) {
195             return mActiveView.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
196         }
197         return super.onKeyUp(keyCode, event);
198     }
199
200     @Override
201     public void onNewIntent(Intent intent) {
202         if (mActiveView != null) {
203             if (!mActiveView.onNewIntent(intent)) super.onNewIntent(intent);
204         }
205     }
206
207     private void waitForDebuggerIfNeeded() {
208         if (CommandLine.getInstance().hasSwitch(BaseSwitches.WAIT_FOR_JAVA_DEBUGGER)) {
209             Log.e(TAG, "Waiting for Java debugger to connect...");
210             android.os.Debug.waitForDebugger();
211             Log.e(TAG, "Java debugger connected. Resuming execution.");
212         }
213     }
214
215     private static String[] getCommandLineParamsFromIntent(Intent intent) {
216         return intent != null ? intent.getStringArrayExtra(COMMAND_LINE_ARGS_KEY) : null;
217     }
218
219     private static String sanitizeUrl(String url) {
220         if (url == null) return url;
221         if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" + url;
222         return url;
223     }
224
225     private void initializeUrlField() {
226         mUrlTextView = (EditText) findViewById(R.id.url);
227         mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() {
228             @Override
229             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
230                 if ((actionId != EditorInfo.IME_ACTION_GO) && (event == null ||
231                         event.getKeyCode() != KeyEvent.KEYCODE_ENTER ||
232                         event.getAction() != KeyEvent.ACTION_DOWN)) {
233                     return false;
234                 }
235
236                 if (mActiveView == null) return true;
237                 mActiveView.loadUrl(sanitizeUrl(mUrlTextView.getText().toString()));
238                 mUrlTextView.clearFocus();
239                 setKeyboardVisibilityForUrl(false);
240                 return true;
241             }
242         });
243         mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
244             @Override
245             public void onFocusChange(View v, boolean hasFocus) {
246                 setKeyboardVisibilityForUrl(hasFocus);
247                 mNextButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
248                 mPrevButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
249                 mStopButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
250                 mReloadButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
251                 if (!hasFocus) {
252                     if (mActiveView == null) return;
253                     mUrlTextView.setText(mActiveView.getUrl());
254                 }
255             }
256         });
257     }
258
259     private void initializeButtons() {
260         mPrevButton = (ImageButton) findViewById(R.id.prev);
261         mPrevButton.setOnClickListener(new OnClickListener() {
262             @Override
263             public void onClick(View v) {
264                 if (mActiveView == null) return;
265                 if (mActiveView.canGoBack()) mActiveView.goBack();
266             }
267         });
268
269         mNextButton = (ImageButton) findViewById(R.id.next);
270         mNextButton.setOnClickListener(new OnClickListener() {
271             @Override
272             public void onClick(View v) {
273                 if (mActiveView == null) return;
274                 if (mActiveView.canGoForward()) mActiveView.goForward();
275             }
276         });
277
278         mStopButton = (ImageButton) findViewById(R.id.stop);
279         mStopButton.setOnClickListener(new OnClickListener() {
280             @Override
281             public void onClick(View v) {
282                 if (mActiveView == null) return;
283                 mActiveView.stopLoading();
284             }
285         });
286
287         mReloadButton = (ImageButton) findViewById(R.id.reload);
288         mReloadButton.setOnClickListener(new OnClickListener() {
289             @Override
290             public void onClick(View v) {
291                 if (mActiveView == null) return;
292                 mActiveView.reload();
293             }
294         });
295     }
296
297     private void initializeXWalkViewClients(XWalkView xwalkView) {
298         xwalkView.setXWalkWebChromeClient(new XWalkDefaultWebChromeClient(this, xwalkView) {
299             public void onProgressChanged(XWalkView view, int newProgress) {
300                 if (view != mActiveView) return;
301                 mToolbar.removeCallbacks(mClearProgressRunnable);
302
303                 mProgressDrawable.setLevel((int) (100.0 * newProgress));
304                 mProgressMap.put(view, (int) (100.0 * newProgress));
305                 if (newProgress == 100) {
306                     mToolbar.postDelayed(mClearProgressRunnable, COMPLETED_PROGRESS_TIMEOUT_MS);
307                     mProgressMap.put(view, 0);
308                 }
309                 mUrlTextView.setText(mActiveView.getUrl());
310             }
311             public void onReceivedTitle(XWalkView view, String title) {
312                 mSectionsPagerAdapter.setPageTitle(view, title);
313             }
314         });
315     }
316
317     private void setKeyboardVisibilityForUrl(boolean visible) {
318         InputMethodManager imm = (InputMethodManager) getSystemService(
319                 Context.INPUT_METHOD_SERVICE);
320         if (visible) {
321             imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT);
322         } else {
323             imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0);
324         }
325     }
326
327     @Override
328     public void onTabReselected(Tab tab, FragmentTransaction ft) {
329         // Do nothing here currently, just make compiler happy.
330     }
331
332     @Override
333     public void onTabSelected(Tab tab, FragmentTransaction ft) {
334         mViewPager.setCurrentItem(tab.getPosition());
335         android.support.v4.app.Fragment fragment = mSectionsPagerAdapter.getItem(tab.getPosition());
336         if (fragment!= null && fragment instanceof XWalkViewSectionFragment) {
337             mActiveView = ((XWalkViewSectionFragment)fragment).getXWalkView();
338         } else {
339             mActiveView = null;
340         }
341         if (mActiveView != null) {
342             mUrlTextView.setText(mActiveView.getUrl());
343             if (mProgressMap.containsKey(mActiveView)) {
344                 mProgressDrawable.setLevel(mProgressMap.get(mActiveView));
345             } else {
346                 mProgressDrawable.setLevel(0);
347             }
348         }
349     }
350
351     @Override
352     public void onTabUnselected(Tab tab, FragmentTransaction ft) {
353         // Do nothing here currently, just make compiler happy.
354     }
355
356     @Override
357     public void onXWalkViewCreated(XWalkView view) {
358         if (mActiveView == null) {
359             mActiveView = view;
360             initializeUrlField();
361             initializeButtons();
362             mUrlTextView.setText("");
363             mProgressDrawable.setLevel(0);
364         }
365         initializeXWalkViewClients(view);
366         mProgressMap.put(view, 0);
367         view.enableRemoteDebugging();
368     }
369 }