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.
5 package org.xwalk.core.xwview.shell;
7 import java.util.HashMap;
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;
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;
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";
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;
68 private Runnable mClearProgressRunnable = new Runnable() {
71 mProgressDrawable.setLevel(0);
75 TracingControllerAndroid getTracingController() {
76 if (mTracingController == null) {
77 mTracingController = new TracingControllerAndroid(this);
79 return mTracingController;
82 private void registerTracingReceiverWhenIdle() {
83 // Delay tracing receiver registration until the main loop is idle.
84 Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
86 public boolean queueIdle() {
87 // Will retry if the native library is not initialized yet.
88 if (!LibraryLoader.isInitialized()) return true;
90 getTracingController().registerReceiver(XWalkViewShellActivity.this);
91 } catch (SecurityException e) {
92 Log.w(TAG, "failed to register tracing receiver: " + e.getMessage());
99 private void unregisterTracingReceiver() {
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());
110 public void onCreate(Bundle savedInstanceState) {
111 super.onCreate(savedInstanceState);
113 registerTracingReceiverWhenIdle();
115 if (!CommandLine.isInitialized()) {
116 CommandLine.initFromFile(COMMAND_LINE_FILE);
117 String[] commandLineParams = getCommandLineParamsFromIntent(getIntent());
118 if (commandLineParams != null) {
119 CommandLine.getInstance().appendSwitchesAndArguments(commandLineParams);
123 waitForDebuggerIfNeeded();
125 setContentView(R.layout.testshell_activity);
127 mActionBar = getActionBar();
128 mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
129 mSectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager(), mActionBar);
131 mViewPager = (ViewPager) findViewById(R.id.pager);
132 mViewPager.setAdapter(mSectionsPagerAdapter);
133 mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
135 public void onPageSelected(int position) {
136 mActionBar.setSelectedNavigationItem(position);
140 mProgressMap = new HashMap<XWalkView, Integer>();
144 .setText(mSectionsPagerAdapter.getPageTitle(0))
145 .setTabListener(this));
148 .setText(mSectionsPagerAdapter.getPageTitle(1))
149 .setTabListener(this));
151 mToolbar = (LinearLayout) findViewById(R.id.toolbar);
152 mProgressDrawable = (ClipDrawable) findViewById(R.id.toolbar).getBackground();
154 IntentFilter intentFilter = new IntentFilter(ACTION_LAUNCH_URL);
155 mReceiver = new BroadcastReceiver() {
157 public void onReceive(Context context, Intent intent) {
158 Bundle bundle = intent.getExtras();
162 if (bundle.containsKey("url")) {
163 String extra = bundle.getString("url");
164 if (mActiveView != null)
165 mActiveView.load(sanitizeUrl(extra), null);
169 registerReceiver(mReceiver, intentFilter);
173 public void onPause() {
175 mSectionsPagerAdapter.onPause();
179 public void onResume() {
181 mSectionsPagerAdapter.onResume();
185 public void onDestroy() {
187 unregisterReceiver(mReceiver);
188 unregisterTracingReceiver();
189 mSectionsPagerAdapter.onDestroy();
193 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
194 if (mActiveView != null) mActiveView.onActivityResult(requestCode, resultCode, data);
198 public boolean onKeyUp(int keyCode, KeyEvent event) {
199 if (mActiveView != null) {
200 return mActiveView.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
202 return super.onKeyUp(keyCode, event);
206 public void onNewIntent(Intent intent) {
207 if (mActiveView != null) {
208 if (!mActiveView.onNewIntent(intent)) super.onNewIntent(intent);
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.");
220 private static String[] getCommandLineParamsFromIntent(Intent intent) {
221 return intent != null ? intent.getStringArrayExtra(COMMAND_LINE_ARGS_KEY) : null;
224 private static String sanitizeUrl(String url) {
225 if (url == null) return url;
226 if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" + url;
230 private void initializeUrlField() {
231 mUrlTextView = (EditText) findViewById(R.id.url);
232 mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() {
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)) {
241 if (mActiveView == null) return true;
242 mActiveView.load(sanitizeUrl(mUrlTextView.getText().toString()), null);
243 mUrlTextView.clearFocus();
244 setKeyboardVisibilityForUrl(false);
248 mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
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);
257 if (mActiveView == null) return;
258 mUrlTextView.setText(mActiveView.getUrl());
264 private void initializeButtons() {
265 mPrevButton = (ImageButton) findViewById(R.id.prev);
266 mPrevButton.setOnClickListener(new OnClickListener() {
268 public void onClick(View v) {
269 if (mActiveView != null &&
270 mActiveView.getNavigationHistory().canGoBack()) {
271 mActiveView.getNavigationHistory().navigate(
272 XWalkNavigationHistory.Direction.BACKWARD, 1);
277 mNextButton = (ImageButton) findViewById(R.id.next);
278 mNextButton.setOnClickListener(new OnClickListener() {
280 public void onClick(View v) {
281 if (mActiveView != null &&
282 mActiveView.getNavigationHistory().canGoForward()) {
283 mActiveView.getNavigationHistory().navigate(
284 XWalkNavigationHistory.Direction.FORWARD, 1);
289 mStopButton = (ImageButton) findViewById(R.id.stop);
290 mStopButton.setOnClickListener(new OnClickListener() {
292 public void onClick(View v) {
293 if (mActiveView != null) mActiveView.stopLoading();
297 mReloadButton = (ImageButton) findViewById(R.id.reload);
298 mReloadButton.setOnClickListener(new OnClickListener() {
300 public void onClick(View v) {
301 if (mActiveView != null) mActiveView.reload(XWalkView.RELOAD_NORMAL);
306 private void initializeXWalkViewClients(XWalkView xwalkView) {
307 xwalkView.setResourceClient(new XWalkResourceClient(xwalkView) {
309 public void onProgressChanged(XWalkView view, int newProgress) {
310 if (view != mActiveView) return;
311 mToolbar.removeCallbacks(mClearProgressRunnable);
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);
319 mUrlTextView.setText(mActiveView.getUrl());
323 xwalkView.setXWalkWebChromeClient(new XWalkWebChromeClient(xwalkView) {
325 public void onReceivedTitle(XWalkView view, String title) {
326 mSectionsPagerAdapter.setPageTitle(view, title);
331 private void setKeyboardVisibilityForUrl(boolean visible) {
332 InputMethodManager imm = (InputMethodManager) getSystemService(
333 Context.INPUT_METHOD_SERVICE);
335 imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT);
337 imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0);
342 public void onTabReselected(Tab tab, FragmentTransaction ft) {
343 // Do nothing here currently, just make compiler happy.
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();
355 if (mActiveView != null) {
356 mUrlTextView.setText(mActiveView.getUrl());
357 if (mProgressMap.containsKey(mActiveView)) {
358 mProgressDrawable.setLevel(mProgressMap.get(mActiveView));
360 mProgressDrawable.setLevel(0);
366 public void onTabUnselected(Tab tab, FragmentTransaction ft) {
367 // Do nothing here currently, just make compiler happy.
371 public void onXWalkViewCreated(XWalkView view) {
372 if (mActiveView == null) {
374 initializeUrlField();
376 mUrlTextView.setText("");
377 mProgressDrawable.setLevel(0);
379 initializeXWalkViewClients(view);
380 mProgressMap.put(view, 0);
381 XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, true);