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