blob: 2459198fb7c37f0109932723a1b906cfd78029e6 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.android_webview.shell;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import org.chromium.android_webview.AwBrowserContext;
import org.chromium.android_webview.AwBrowserProcess;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwContentsStatics;
import org.chromium.android_webview.AwDevToolsServer;
import org.chromium.android_webview.AwSettings;
import org.chromium.android_webview.test.AwTestContainerView;
import org.chromium.android_webview.test.NullContentsClient;
import org.chromium.base.BaseSwitches;
import org.chromium.base.CommandLine;
import org.chromium.base.Log;
import org.chromium.base.TraceEvent;
import org.chromium.content.app.ContentApplication;
import org.chromium.content_public.browser.NavigationController;
import org.chromium.content_public.browser.WebContents;
import java.net.URI;
import java.net.URISyntaxException;
/**
* This is a lightweight activity for tests that only require WebView functionality.
*/
public class AwShellActivity extends Activity {
private static final String TAG = "cr.AwShellActivity";
private static final String PREFERENCES_NAME = "AwShellPrefs";
private static final String INITIAL_URL = "about:blank";
private AwBrowserContext mBrowserContext;
private AwDevToolsServer mDevToolsServer;
private AwTestContainerView mAwTestContainerView;
private WebContents mWebContents;
private NavigationController mNavigationController;
private EditText mUrlTextView;
private ImageButton mPrevButton;
private ImageButton mNextButton;
// This is the same as data_reduction_proxy::switches::kEnableDataReductionProxy.
private static final String ENABLE_DATA_REDUCTION_PROXY = "enable-spdy-proxy-auth";
// This is the same as data_reduction_proxy::switches::kDataReductionProxyKey.
private static final String DATA_REDUCTION_PROXY_KEY = "spdy-proxy-auth-value";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AwShellResourceProvider.registerResources(this);
ContentApplication.initCommandLine(this);
waitForDebuggerIfNeeded();
AwBrowserProcess.loadLibrary(this);
if (CommandLine.getInstance().hasSwitch(AwShellSwitches.ENABLE_ATRACE)) {
Log.e(TAG, "Enabling Android trace.");
TraceEvent.setATraceEnabled(true);
}
setContentView(R.layout.testshell_activity);
mAwTestContainerView = createAwTestContainerView();
mWebContents = mAwTestContainerView.getContentViewCore().getWebContents();
mNavigationController = mWebContents.getNavigationController();
LinearLayout contentContainer = (LinearLayout) findViewById(R.id.content_container);
mAwTestContainerView.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1f));
contentContainer.addView(mAwTestContainerView);
mAwTestContainerView.requestFocus();
initializeUrlField();
initializeNavigationButtons();
String startupUrl = getUrlFromIntent(getIntent());
if (TextUtils.isEmpty(startupUrl)) {
startupUrl = INITIAL_URL;
}
mAwTestContainerView.getAwContents().loadUrl(startupUrl);
AwContents.setShouldDownloadFavicons();
mUrlTextView.setText(startupUrl);
if (CommandLine.getInstance().hasSwitch(ENABLE_DATA_REDUCTION_PROXY)) {
String key = CommandLine.getInstance().getSwitchValue(DATA_REDUCTION_PROXY_KEY);
if (key != null && !key.isEmpty()) {
AwContentsStatics.setDataReductionProxyKey(key);
AwContentsStatics.setDataReductionProxyEnabled(true);
}
}
}
@Override
public void onDestroy() {
if (mDevToolsServer != null) {
mDevToolsServer.destroy();
mDevToolsServer = null;
}
super.onDestroy();
}
private AwTestContainerView createAwTestContainerView() {
AwBrowserProcess.start(this);
AwTestContainerView testContainerView = new AwTestContainerView(this, true);
AwContentsClient awContentsClient = new NullContentsClient() {
private View mCustomView;
@Override
public void onPageStarted(String url) {
if (mUrlTextView != null) {
mUrlTextView.setText(url);
}
}
@Override
public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addContentView(view,
new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
Gravity.CENTER));
mCustomView = view;
}
@Override
public void onHideCustomView() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
FrameLayout decorView = (FrameLayout) getWindow().getDecorView();
decorView.removeView(mCustomView);
mCustomView = null;
}
@Override
public boolean shouldOverrideKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
return true;
}
return false;
}
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
callback.invoke(origin, false, false);
}
};
SharedPreferences sharedPreferences =
getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
if (mBrowserContext == null) {
mBrowserContext = new AwBrowserContext(sharedPreferences, getApplicationContext());
}
final AwSettings awSettings = new AwSettings(this /* context */,
false /* isAccessFromFileURLsGrantedByDefault */, false /* supportsLegacyQuirks */,
false /* allowEmptyDocumentPersistence */,
true /* allowGeolocationOnInsecureOrigins */);
// Required for WebGL conformance tests.
awSettings.setMediaPlaybackRequiresUserGesture(false);
// Allow zoom and fit contents to screen
awSettings.setBuiltInZoomControls(true);
awSettings.setDisplayZoomControls(false);
awSettings.setUseWideViewPort(true);
awSettings.setLoadWithOverviewMode(true);
awSettings.setLayoutAlgorithm(android.webkit.WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);
testContainerView.initialize(new AwContents(mBrowserContext, testContainerView,
testContainerView.getContext(), testContainerView.getInternalAccessDelegate(),
testContainerView.getNativeGLDelegate(), awContentsClient, awSettings));
testContainerView.getAwContents().getSettings().setJavaScriptEnabled(true);
if (mDevToolsServer == null) {
mDevToolsServer = new AwDevToolsServer();
mDevToolsServer.setRemoteDebuggingEnabled(true);
}
return testContainerView;
}
private static String getUrlFromIntent(Intent intent) {
return intent != null ? intent.getDataString() : null;
}
private void setKeyboardVisibilityForUrl(boolean visible) {
InputMethodManager imm = (InputMethodManager) getSystemService(
Context.INPUT_METHOD_SERVICE);
if (visible) {
imm.showSoftInput(mUrlTextView, InputMethodManager.SHOW_IMPLICIT);
} else {
imm.hideSoftInputFromWindow(mUrlTextView.getWindowToken(), 0);
}
}
private void initializeUrlField() {
mUrlTextView = (EditText) findViewById(R.id.url);
mUrlTextView.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((actionId != EditorInfo.IME_ACTION_GO) && (event == null
|| event.getKeyCode() != KeyEvent.KEYCODE_ENTER
|| event.getAction() != KeyEvent.ACTION_DOWN)) {
return false;
}
String url = mUrlTextView.getText().toString();
try {
URI uri = new URI(url);
if (uri.getScheme() == null) {
url = "http://" + uri.toString();
} else {
url = uri.toString();
}
} catch (URISyntaxException e) {
// Ignore syntax errors.
}
mAwTestContainerView.getAwContents().loadUrl(url);
mUrlTextView.clearFocus();
setKeyboardVisibilityForUrl(false);
mAwTestContainerView.requestFocus();
return true;
}
});
mUrlTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
setKeyboardVisibilityForUrl(hasFocus);
mNextButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
mPrevButton.setVisibility(hasFocus ? View.GONE : View.VISIBLE);
if (!hasFocus) {
mUrlTextView.setText(mWebContents.getUrl());
}
}
});
}
private void initializeNavigationButtons() {
mPrevButton = (ImageButton) findViewById(R.id.prev);
mPrevButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mNavigationController.canGoBack()) {
mNavigationController.goBack();
}
}
});
mNextButton = (ImageButton) findViewById(R.id.next);
mNextButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mNavigationController.canGoForward()) {
mNavigationController.goForward();
}
}
});
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (mNavigationController.canGoBack()) {
mNavigationController.goBack();
return true;
}
}
return super.onKeyUp(keyCode, event);
}
private void waitForDebuggerIfNeeded() {
if (CommandLine.getInstance().hasSwitch(BaseSwitches.WAIT_FOR_JAVA_DEBUGGER)) {
Log.e(TAG, "Waiting for Java debugger to connect...");
android.os.Debug.waitForDebugger();
Log.e(TAG, "Java debugger connected. Resuming execution.");
}
}
}