Upstream version 8.36.171.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.XWalkUIClient;
43 import org.xwalk.core.XWalkView;
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 onDestroy() {
174         super.onDestroy();
175         unregisterReceiver(mReceiver);
176         unregisterTracingReceiver();
177     }
178
179     @Override
180     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
181         if (mActiveView != null) mActiveView.onActivityResult(requestCode, resultCode, data);
182     }
183
184     @Override
185     public void onNewIntent(Intent intent) {
186         if (mActiveView != null) {
187             if (!mActiveView.onNewIntent(intent)) super.onNewIntent(intent);
188         }
189     }
190
191     private void waitForDebuggerIfNeeded() {
192         if (CommandLine.getInstance().hasSwitch(BaseSwitches.WAIT_FOR_JAVA_DEBUGGER)) {
193             Log.e(TAG, "Waiting for Java debugger to connect...");
194             android.os.Debug.waitForDebugger();
195             Log.e(TAG, "Java debugger connected. Resuming execution.");
196         }
197     }
198
199     private static String[] getCommandLineParamsFromIntent(Intent intent) {
200         return intent != null ? intent.getStringArrayExtra(COMMAND_LINE_ARGS_KEY) : null;
201     }
202
203     private static String sanitizeUrl(String url) {
204         if (url == null) return url;
205         if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" + url;
206         return url;
207     }
208
209     private void initializeUrlField() {
210         mUrlTextView = (EditText) findViewById(R.id.url);
211         mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() {
212             @Override
213             public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
214                 if ((actionId != EditorInfo.IME_ACTION_GO) && (event == null ||
215                         event.getKeyCode() != KeyEvent.KEYCODE_ENTER ||
216                         event.getAction() != KeyEvent.ACTION_DOWN)) {
217                     return false;
218                 }
219
220                 if (mActiveView == null) return true;
221                 mActiveView.load(sanitizeUrl(mUrlTextView.getText().toString()), null);
222                 mUrlTextView.clearFocus();
223                 setKeyboardVisibilityForUrl(false);
224                 return true;
225             }
226         });
227         mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
228             @Override
229             public void onFocusChange(View v, boolean hasFocus) {
230                 setKeyboardVisibilityForUrl(hasFocus);
231                 mNextButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
232                 mPrevButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
233                 mStopButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
234                 mReloadButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
235                 if (!hasFocus) {
236                     if (mActiveView == null) return;
237                     mUrlTextView.setText(mActiveView.getUrl());
238                 }
239             }
240         });
241     }
242
243     private void initializeButtons() {
244         mPrevButton = (ImageButton) findViewById(R.id.prev);
245         mPrevButton.setOnClickListener(new OnClickListener() {
246             @Override
247             public void onClick(View v) {
248                 if (mActiveView != null &&
249                         mActiveView.getNavigationHistory().canGoBack()) {
250                     mActiveView.getNavigationHistory().navigate(
251                             XWalkNavigationHistory.Direction.BACKWARD, 1);
252                 }
253             }
254         });
255
256         mNextButton = (ImageButton) findViewById(R.id.next);
257         mNextButton.setOnClickListener(new OnClickListener() {
258             @Override
259             public void onClick(View v) {
260                 if (mActiveView != null &&
261                         mActiveView.getNavigationHistory().canGoForward()) {
262                     mActiveView.getNavigationHistory().navigate(
263                             XWalkNavigationHistory.Direction.FORWARD, 1);
264                 }
265             }
266         });
267
268         mStopButton = (ImageButton) findViewById(R.id.stop);
269         mStopButton.setOnClickListener(new OnClickListener() {
270             @Override
271             public void onClick(View v) {
272                 if (mActiveView != null) mActiveView.stopLoading();
273             }
274         });
275
276         mReloadButton = (ImageButton) findViewById(R.id.reload);
277         mReloadButton.setOnClickListener(new OnClickListener() {
278             @Override
279             public void onClick(View v) {
280                 if (mActiveView != null) mActiveView.reload(XWalkView.RELOAD_NORMAL);
281             }
282         });
283     }
284
285     private void initializeXWalkViewClients(XWalkView xwalkView) {
286         xwalkView.setResourceClient(new XWalkResourceClient(xwalkView) {
287             @Override
288             public void onProgressChanged(XWalkView view, int newProgress) {
289                 if (view != mActiveView) return;
290                 mToolbar.removeCallbacks(mClearProgressRunnable);
291
292                 mProgressDrawable.setLevel((int) (100.0 * newProgress));
293                 mProgressMap.put(view, (int) (100.0 * newProgress));
294                 if (newProgress == 100) {
295                     mToolbar.postDelayed(mClearProgressRunnable, COMPLETED_PROGRESS_TIMEOUT_MS);
296                     mProgressMap.put(view, 0);
297                 }
298                 mUrlTextView.setText(mActiveView.getUrl());
299             }
300         });
301
302         xwalkView.setUIClient(new XWalkUIClient(xwalkView) {
303             @Override
304             public void onReceivedTitle(XWalkView view, String title) {
305                 mSectionsPagerAdapter.setPageTitle(view, title);
306             }
307         });
308     }
309
310     private void setKeyboardVisibilityForUrl(boolean visible) {
311         InputMethodManager imm = (InputMethodManager) getSystemService(
312                 Context.INPUT_METHOD_SERVICE);
313         if (visible) {
314             imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT);
315         } else {
316             imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0);
317         }
318     }
319
320     @Override
321     public void onTabReselected(Tab tab, FragmentTransaction ft) {
322         // Do nothing here currently, just make compiler happy.
323     }
324
325     @Override
326     public void onTabSelected(Tab tab, FragmentTransaction ft) {
327         mViewPager.setCurrentItem(tab.getPosition());
328         android.support.v4.app.Fragment fragment = mSectionsPagerAdapter.getItem(tab.getPosition());
329         if (fragment!= null && fragment instanceof XWalkViewSectionFragment) {
330             mActiveView = ((XWalkViewSectionFragment)fragment).getXWalkView();
331         } else {
332             mActiveView = null;
333         }
334         if (mActiveView != null) {
335             mUrlTextView.setText(mActiveView.getUrl());
336             if (mProgressMap.containsKey(mActiveView)) {
337                 mProgressDrawable.setLevel(mProgressMap.get(mActiveView));
338             } else {
339                 mProgressDrawable.setLevel(0);
340             }
341         }
342     }
343
344     @Override
345     public void onTabUnselected(Tab tab, FragmentTransaction ft) {
346         // Do nothing here currently, just make compiler happy.
347     }
348
349     @Override
350     public void onXWalkViewCreated(XWalkView view) {
351         if (mActiveView == null) {
352             mActiveView = view;
353             initializeUrlField();
354             initializeButtons();
355             mUrlTextView.setText("");
356             mProgressDrawable.setLevel(0);
357         }
358         initializeXWalkViewClients(view);
359         mProgressMap.put(view, 0);
360         XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);
361     }
362 }