[Android WebViewShell] Add inclusion test for webview exposed stable interfaces.
[chromium-blink-merge.git] / android_webview / tools / WebViewShell / src / org / chromium / webview_shell / WebViewBrowserActivity.java
blobfbe41e3991d1ea8eadc07337a2366aa24e202324
1 // Copyright 2015 The Chromium Authors. 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.chromium.webview_shell;
7 import android.app.Activity;
8 import android.app.AlertDialog;
9 import android.content.Context;
10 import android.content.Intent;
11 import android.graphics.Bitmap;
12 import android.graphics.Color;
13 import android.os.Bundle;
15 import android.view.KeyEvent;
16 import android.view.MenuItem;
17 import android.view.View;
18 import android.view.View.OnKeyListener;
19 import android.view.inputmethod.InputMethodManager;
21 import android.webkit.GeolocationPermissions;
22 import android.webkit.PermissionRequest;
23 import android.webkit.WebChromeClient;
24 import android.webkit.WebSettings;
25 import android.webkit.WebView;
26 import android.webkit.WebViewClient;
28 import android.widget.EditText;
29 import android.widget.LinearLayout.LayoutParams;
30 import android.widget.PopupMenu;
31 import android.widget.TextView;
33 import java.lang.reflect.InvocationTargetException;
34 import java.lang.reflect.Method;
36 import java.net.URI;
37 import java.net.URISyntaxException;
39 import java.util.regex.Matcher;
40 import java.util.regex.Pattern;
42 /**
43 * This activity is designed for starting a "mini-browser" for manual testing of WebView.
44 * It takes an optional URL as an argument, and displays the page. There is a URL bar
45 * on top of the webview for manually specifying URLs to load.
47 public class WebViewBrowserActivity extends Activity implements PopupMenu.OnMenuItemClickListener {
48 private EditText mUrlBar;
49 private WebView mWebView;
50 private String mWebViewVersion;
52 private static final Pattern WEBVIEW_VERSION_PATTERN =
53 Pattern.compile("(Chrome/)([\\d\\.]+)\\s");
55 // TODO(michaelbai) : Replace "android.webkit.resoruce.MIDI_SYSEX" with
56 // PermissionRequest.RESOURCE_MIDI_SYSEX once Android M SDK is used.
57 private static final String[] AUTOMATICALLY_GRANT =
58 { PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOURCE_AUDIO_CAPTURE,
59 "android.webkit.resource.MIDI_SYSEX" };
61 @Override
62 public void onCreate(Bundle savedInstanceState) {
63 super.onCreate(savedInstanceState);
64 setContentView(R.layout.activity_webview_browser);
65 mWebView = (WebView) findViewById(R.id.webview);
66 WebSettings settings = mWebView.getSettings();
67 initializeSettings(settings);
69 Matcher matcher = WEBVIEW_VERSION_PATTERN.matcher(settings.getUserAgentString());
70 if (matcher.find()) {
71 mWebViewVersion = matcher.group(2);
72 } else {
73 mWebViewVersion = "-";
75 setTitle(getResources().getString(R.string.title_activity_browser) + " " + mWebViewVersion);
77 mWebView.setWebViewClient(new WebViewClient() {
78 @Override
79 public boolean shouldOverrideUrlLoading(WebView webView, String url) {
80 return false;
83 @Override
84 public void onReceivedError(WebView view, int errorCode, String description,
85 String failingUrl) {
86 setUrlFail(true);
88 });
90 mWebView.setWebChromeClient(new WebChromeClient() {
91 @Override
92 public Bitmap getDefaultVideoPoster() {
93 return Bitmap.createBitmap(
94 new int[] {Color.TRANSPARENT}, 1, 1, Bitmap.Config.ARGB_8888);
97 @Override
98 public void onGeolocationPermissionsShowPrompt(String origin,
99 GeolocationPermissions.Callback callback) {
100 callback.invoke(origin, true, false);
103 @Override
104 public void onPermissionRequest(PermissionRequest request) {
105 request.grant(AUTOMATICALLY_GRANT);
109 mUrlBar = (EditText) findViewById(R.id.url_field);
110 mUrlBar.setOnKeyListener(new OnKeyListener() {
111 public boolean onKey(View view, int keyCode, KeyEvent event) {
112 if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
113 loadUrlFromUrlBar(view);
114 return true;
116 return false;
120 String url = getUrlFromIntent(getIntent());
121 if (url != null) {
122 setUrlBarText(url);
123 setUrlFail(false);
124 loadUrlFromUrlBar(mUrlBar);
128 public void loadUrlFromUrlBar(View view) {
129 String url = mUrlBar.getText().toString();
130 try {
131 URI uri = new URI(url);
132 url = (uri.getScheme() == null) ? "http://" + uri.toString() : uri.toString();
133 } catch (URISyntaxException e) {
134 String message = "<html><body>URISyntaxException: " + e.getMessage() + "</body></html>";
135 mWebView.loadData(message, "text/html", "UTF-8");
136 setUrlFail(true);
137 return;
140 setUrlBarText(url);
141 setUrlFail(false);
142 loadUrl(url);
143 hideKeyboard(mUrlBar);
146 public void showPopup(View v) {
147 PopupMenu popup = new PopupMenu(this, v);
148 popup.setOnMenuItemClickListener(this);
149 popup.inflate(R.menu.main_menu);
150 popup.show();
153 @Override
154 public boolean onMenuItemClick(MenuItem item) {
155 switch(item.getItemId()) {
156 case R.id.menu_about:
157 about();
158 hideKeyboard(mUrlBar);
159 return true;
160 default:
161 return false;
165 private void initializeSettings(WebSettings settings) {
166 settings.setJavaScriptEnabled(true);
168 // configure local storage apis and their database paths.
169 settings.setAppCachePath(getDir("appcache", 0).getPath());
170 settings.setGeolocationDatabasePath(getDir("geolocation", 0).getPath());
171 settings.setDatabasePath(getDir("databases", 0).getPath());
173 settings.setAppCacheEnabled(true);
174 settings.setGeolocationEnabled(true);
175 settings.setDatabaseEnabled(true);
176 settings.setDomStorageEnabled(true);
179 private void about() {
180 WebSettings settings = mWebView.getSettings();
181 StringBuilder summary = new StringBuilder();
182 summary.append("WebView version : " + mWebViewVersion + "\n");
184 for (Method method : settings.getClass().getMethods()) {
185 if (!methodIsSimpleInspector(method)) continue;
186 try {
187 summary.append(method.getName() + " : " + method.invoke(settings) + "\n");
188 } catch (IllegalAccessException e) {
189 } catch (InvocationTargetException e) { }
192 AlertDialog dialog = new AlertDialog.Builder(this)
193 .setTitle(getResources().getString(R.string.menu_about))
194 .setMessage(summary)
195 .setPositiveButton("OK", null)
196 .create();
197 dialog.show();
198 dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
201 // Returns true is a method has no arguments and returns either a boolean or a String.
202 private boolean methodIsSimpleInspector(Method method) {
203 Class<?> returnType = method.getReturnType();
204 return ((returnType.equals(boolean.class) || returnType.equals(String.class))
205 && method.getParameterTypes().length == 0);
208 private void loadUrl(String url) {
209 mWebView.loadUrl(url);
210 mWebView.requestFocus();
213 private void setUrlBarText(String url) {
214 mUrlBar.setText(url, TextView.BufferType.EDITABLE);
217 private void setUrlFail(boolean fail) {
218 mUrlBar.setTextColor(fail ? Color.RED : Color.BLACK);
222 * Hides the keyboard.
223 * @param view The {@link View} that is currently accepting input.
224 * @return Whether the keyboard was visible before.
226 private static boolean hideKeyboard(View view) {
227 InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(
228 Context.INPUT_METHOD_SERVICE);
229 return imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
232 private static String getUrlFromIntent(Intent intent) {
233 return intent != null ? intent.getDataString() : null;