blob: fbe41e3991d1ea8eadc07337a2366aa24e202324 [file] [log] [blame]
// Copyright 2015 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.webview_shell;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.webkit.GeolocationPermissions;
import android.webkit.PermissionRequest;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.LinearLayout.LayoutParams;
import android.widget.PopupMenu;
import android.widget.TextView;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This activity is designed for starting a "mini-browser" for manual testing of WebView.
* It takes an optional URL as an argument, and displays the page. There is a URL bar
* on top of the webview for manually specifying URLs to load.
*/
public class WebViewBrowserActivity extends Activity implements PopupMenu.OnMenuItemClickListener {
private EditText mUrlBar;
private WebView mWebView;
private String mWebViewVersion;
private static final Pattern WEBVIEW_VERSION_PATTERN =
Pattern.compile("(Chrome/)([\\d\\.]+)\\s");
// TODO(michaelbai) : Replace "android.webkit.resoruce.MIDI_SYSEX" with
// PermissionRequest.RESOURCE_MIDI_SYSEX once Android M SDK is used.
private static final String[] AUTOMATICALLY_GRANT =
{ PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOURCE_AUDIO_CAPTURE,
"android.webkit.resource.MIDI_SYSEX" };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview_browser);
mWebView = (WebView) findViewById(R.id.webview);
WebSettings settings = mWebView.getSettings();
initializeSettings(settings);
Matcher matcher = WEBVIEW_VERSION_PATTERN.matcher(settings.getUserAgentString());
if (matcher.find()) {
mWebViewVersion = matcher.group(2);
} else {
mWebViewVersion = "-";
}
setTitle(getResources().getString(R.string.title_activity_browser) + " " + mWebViewVersion);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
return false;
}
@Override
public void onReceivedError(WebView view, int errorCode, String description,
String failingUrl) {
setUrlFail(true);
}
});
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public Bitmap getDefaultVideoPoster() {
return Bitmap.createBitmap(
new int[] {Color.TRANSPARENT}, 1, 1, Bitmap.Config.ARGB_8888);
}
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
@Override
public void onPermissionRequest(PermissionRequest request) {
request.grant(AUTOMATICALLY_GRANT);
}
});
mUrlBar = (EditText) findViewById(R.id.url_field);
mUrlBar.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View view, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
loadUrlFromUrlBar(view);
return true;
}
return false;
}
});
String url = getUrlFromIntent(getIntent());
if (url != null) {
setUrlBarText(url);
setUrlFail(false);
loadUrlFromUrlBar(mUrlBar);
}
}
public void loadUrlFromUrlBar(View view) {
String url = mUrlBar.getText().toString();
try {
URI uri = new URI(url);
url = (uri.getScheme() == null) ? "http://" + uri.toString() : uri.toString();
} catch (URISyntaxException e) {
String message = "<html><body>URISyntaxException: " + e.getMessage() + "</body></html>";
mWebView.loadData(message, "text/html", "UTF-8");
setUrlFail(true);
return;
}
setUrlBarText(url);
setUrlFail(false);
loadUrl(url);
hideKeyboard(mUrlBar);
}
public void showPopup(View v) {
PopupMenu popup = new PopupMenu(this, v);
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.main_menu);
popup.show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_about:
about();
hideKeyboard(mUrlBar);
return true;
default:
return false;
}
}
private void initializeSettings(WebSettings settings) {
settings.setJavaScriptEnabled(true);
// configure local storage apis and their database paths.
settings.setAppCachePath(getDir("appcache", 0).getPath());
settings.setGeolocationDatabasePath(getDir("geolocation", 0).getPath());
settings.setDatabasePath(getDir("databases", 0).getPath());
settings.setAppCacheEnabled(true);
settings.setGeolocationEnabled(true);
settings.setDatabaseEnabled(true);
settings.setDomStorageEnabled(true);
}
private void about() {
WebSettings settings = mWebView.getSettings();
StringBuilder summary = new StringBuilder();
summary.append("WebView version : " + mWebViewVersion + "\n");
for (Method method : settings.getClass().getMethods()) {
if (!methodIsSimpleInspector(method)) continue;
try {
summary.append(method.getName() + " : " + method.invoke(settings) + "\n");
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) { }
}
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle(getResources().getString(R.string.menu_about))
.setMessage(summary)
.setPositiveButton("OK", null)
.create();
dialog.show();
dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
}
// Returns true is a method has no arguments and returns either a boolean or a String.
private boolean methodIsSimpleInspector(Method method) {
Class<?> returnType = method.getReturnType();
return ((returnType.equals(boolean.class) || returnType.equals(String.class))
&& method.getParameterTypes().length == 0);
}
private void loadUrl(String url) {
mWebView.loadUrl(url);
mWebView.requestFocus();
}
private void setUrlBarText(String url) {
mUrlBar.setText(url, TextView.BufferType.EDITABLE);
}
private void setUrlFail(boolean fail) {
mUrlBar.setTextColor(fail ? Color.RED : Color.BLACK);
}
/**
* Hides the keyboard.
* @param view The {@link View} that is currently accepting input.
* @return Whether the keyboard was visible before.
*/
private static boolean hideKeyboard(View view) {
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
return imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
private static String getUrlFromIntent(Intent intent) {
return intent != null ? intent.getDataString() : null;
}
}