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
;
37 import java
.net
.URISyntaxException
;
39 import java
.util
.regex
.Matcher
;
40 import java
.util
.regex
.Pattern
;
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" };
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());
71 mWebViewVersion
= matcher
.group(2);
73 mWebViewVersion
= "-";
75 setTitle(getResources().getString(R
.string
.title_activity_browser
) + " " + mWebViewVersion
);
77 mWebView
.setWebViewClient(new WebViewClient() {
79 public boolean shouldOverrideUrlLoading(WebView webView
, String url
) {
84 public void onReceivedError(WebView view
, int errorCode
, String description
,
90 mWebView
.setWebChromeClient(new WebChromeClient() {
92 public Bitmap
getDefaultVideoPoster() {
93 return Bitmap
.createBitmap(
94 new int[] {Color
.TRANSPARENT
}, 1, 1, Bitmap
.Config
.ARGB_8888
);
98 public void onGeolocationPermissionsShowPrompt(String origin
,
99 GeolocationPermissions
.Callback callback
) {
100 callback
.invoke(origin
, true, false);
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
);
120 String url
= getUrlFromIntent(getIntent());
124 loadUrlFromUrlBar(mUrlBar
);
128 public void loadUrlFromUrlBar(View view
) {
129 String url
= mUrlBar
.getText().toString();
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");
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
);
154 public boolean onMenuItemClick(MenuItem item
) {
155 switch(item
.getItemId()) {
156 case R
.id
.menu_about
:
158 hideKeyboard(mUrlBar
);
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;
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
))
195 .setPositiveButton("OK", null)
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;