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.
5 package org.xwalk.core.xwview.shell;
7 import android.app.Activity;
8 import android.content.BroadcastReceiver;
9 import android.content.Intent;
10 import android.content.Context;
11 import android.content.IntentFilter;
12 import android.graphics.drawable.ClipDrawable;
13 import android.os.Bundle;
14 import android.os.Looper;
15 import android.os.MessageQueue;
16 import android.util.Log;
17 import android.view.KeyEvent;
18 import android.view.View;
19 import android.view.View.OnClickListener;
20 import android.view.View.OnFocusChangeListener;
21 import android.view.inputmethod.EditorInfo;
22 import android.view.inputmethod.InputMethodManager;
23 import android.widget.EditText;
24 import android.widget.ImageButton;
25 import android.widget.LinearLayout;
26 import android.widget.TextView;
27 import android.widget.TextView.OnEditorActionListener;
29 import org.chromium.base.BaseSwitches;
30 import org.chromium.base.CommandLine;
31 import org.chromium.content.app.LibraryLoader;
32 import org.chromium.content.browser.TracingControllerAndroid;
33 import org.xwalk.core.client.XWalkDefaultWebChromeClient;
34 import org.xwalk.core.XWalkView;
36 public class XWalkViewShellActivity extends Activity {
37 public static final String COMMAND_LINE_FILE = "/data/local/tmp/xwview-shell-command-line";
38 private static final String TAG = XWalkViewShellActivity.class.getName();
39 public static final String COMMAND_LINE_ARGS_KEY = "commandLineArgs";
40 private static final long COMPLETED_PROGRESS_TIMEOUT_MS = 200;
41 private static final String ACTION_LAUNCH_URL = "org.xwalk.core.xwview.shell.launch";
43 private LinearLayout mToolbar;
44 private EditText mUrlTextView;
45 private ImageButton mPrevButton;
46 private ImageButton mNextButton;
47 private ImageButton mStopButton;
48 private ImageButton mReloadButton;
49 private ClipDrawable mProgressDrawable;
50 private XWalkView mView;
51 private TracingControllerAndroid mTracingController;
52 private BroadcastReceiver mReceiver;
54 private Runnable mClearProgressRunnable = new Runnable() {
57 mProgressDrawable.setLevel(0);
61 TracingControllerAndroid getTracingController() {
62 if (mTracingController == null) {
63 mTracingController = new TracingControllerAndroid(this);
65 return mTracingController;
68 private void registerTracingReceiverWhenIdle() {
69 // Delay tracing receiver registration until the main loop is idle.
70 Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
72 public boolean queueIdle() {
73 // Will retry if the native library is not initialized yet.
74 if (!LibraryLoader.isInitialized()) return true;
76 getTracingController().registerReceiver(XWalkViewShellActivity.this);
77 } catch (SecurityException e) {
78 Log.w(TAG, "failed to register tracing receiver: " + e.getMessage());
85 private void unregisterTracingReceiver() {
87 getTracingController().unregisterReceiver(this);
88 } catch (SecurityException e) {
89 Log.w(TAG, "failed to unregister tracing receiver: " + e.getMessage());
94 public void onCreate(Bundle savedInstanceState) {
95 super.onCreate(savedInstanceState);
97 registerTracingReceiverWhenIdle();
99 if (!CommandLine.isInitialized()) {
100 CommandLine.initFromFile(COMMAND_LINE_FILE);
101 String[] commandLineParams = getCommandLineParamsFromIntent(getIntent());
102 if (commandLineParams != null) {
103 CommandLine.getInstance().appendSwitchesAndArguments(commandLineParams);
107 waitForDebuggerIfNeeded();
109 setContentView(R.layout.testshell_activity);
111 mView = (XWalkView) findViewById(R.id.content_container);
112 mToolbar = (LinearLayout) findViewById(R.id.toolbar);
113 mProgressDrawable = (ClipDrawable) findViewById(R.id.toolbar).getBackground();
115 initializeUrlField();
117 initializeXWalkViewClients();
119 IntentFilter intentFilter = new IntentFilter(ACTION_LAUNCH_URL);
120 mReceiver = new BroadcastReceiver() {
122 public void onReceive(Context context, Intent intent) {
123 Bundle bundle = intent.getExtras();
127 if (bundle.containsKey("url")) {
128 String extra = bundle.getString("url");
129 mView.loadUrl(sanitizeUrl(extra));
133 registerReceiver(mReceiver, intentFilter);
134 mView.enableRemoteDebugging();
138 public void onPause() {
144 public void onResume() {
150 public void onDestroy() {
152 unregisterReceiver(mReceiver);
153 unregisterTracingReceiver();
158 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
159 mView.onActivityResult(requestCode, resultCode, data);
163 public boolean onKeyUp(int keyCode, KeyEvent event) {
164 return mView.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
168 public void onNewIntent(Intent intent) {
169 if (!mView.onNewIntent(intent)) super.onNewIntent(intent);
172 private void waitForDebuggerIfNeeded() {
173 if (CommandLine.getInstance().hasSwitch(BaseSwitches.WAIT_FOR_JAVA_DEBUGGER)) {
174 Log.e(TAG, "Waiting for Java debugger to connect...");
175 android.os.Debug.waitForDebugger();
176 Log.e(TAG, "Java debugger connected. Resuming execution.");
180 private static String[] getCommandLineParamsFromIntent(Intent intent) {
181 return intent != null ? intent.getStringArrayExtra(COMMAND_LINE_ARGS_KEY) : null;
184 private static String sanitizeUrl(String url) {
185 if (url == null) return url;
186 if (url.startsWith("www.") || url.indexOf(":") == -1) url = "http://" + url;
190 private void initializeUrlField() {
191 mUrlTextView = (EditText) findViewById(R.id.url);
192 mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() {
194 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
195 if ((actionId != EditorInfo.IME_ACTION_GO) && (event == null ||
196 event.getKeyCode() != KeyEvent.KEYCODE_ENTER ||
197 event.getAction() != KeyEvent.ACTION_DOWN)) {
201 mView.loadUrl(sanitizeUrl(mUrlTextView.getText().toString()));
202 mUrlTextView.clearFocus();
203 setKeyboardVisibilityForUrl(false);
207 mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
209 public void onFocusChange(View v, boolean hasFocus) {
210 setKeyboardVisibilityForUrl(hasFocus);
211 mNextButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
212 mPrevButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
213 mStopButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
214 mReloadButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
216 mUrlTextView.setText(mView.getUrl());
223 private void initializeButtons() {
224 mPrevButton = (ImageButton) findViewById(R.id.prev);
225 mPrevButton.setOnClickListener(new OnClickListener() {
227 public void onClick(View v) {
228 if (mView.canGoBack()) mView.goBack();
232 mNextButton = (ImageButton) findViewById(R.id.next);
233 mNextButton.setOnClickListener(new OnClickListener() {
235 public void onClick(View v) {
236 if (mView.canGoForward()) mView.goForward();
240 mStopButton = (ImageButton) findViewById(R.id.stop);
241 mStopButton.setOnClickListener(new OnClickListener() {
243 public void onClick(View v) {
248 mReloadButton = (ImageButton) findViewById(R.id.reload);
249 mReloadButton.setOnClickListener(new OnClickListener() {
251 public void onClick(View v) {
257 private void initializeXWalkViewClients() {
258 mView.setXWalkWebChromeClient(new XWalkDefaultWebChromeClient(this, mView) {
259 public void onProgressChanged(XWalkView view, int newProgress) {
260 mToolbar.removeCallbacks(mClearProgressRunnable);
262 mProgressDrawable.setLevel((int) (100.0 * newProgress));
263 if (newProgress == 100)
264 mToolbar.postDelayed(mClearProgressRunnable, COMPLETED_PROGRESS_TIMEOUT_MS);
265 mUrlTextView.setText(mView.getUrl());
269 private void setKeyboardVisibilityForUrl(boolean visible) {
270 InputMethodManager imm = (InputMethodManager) getSystemService(
271 Context.INPUT_METHOD_SERVICE);
273 imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT);
275 imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0);