| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 package org.chromium.webview_shell; | |
| 6 | |
| 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.Build; | |
| 14 import android.os.Bundle; | |
| 15 | |
| 16 import android.view.KeyEvent; | |
| 17 import android.view.MenuItem; | |
| 18 import android.view.View; | |
| 19 import android.view.View.OnKeyListener; | |
| 20 import android.view.inputmethod.InputMethodManager; | |
| 21 | |
| 22 import android.webkit.GeolocationPermissions; | |
| 23 import android.webkit.PermissionRequest; | |
| 24 import android.webkit.WebChromeClient; | |
| 25 import android.webkit.WebSettings; | |
| 26 import android.webkit.WebView; | |
| 27 import android.webkit.WebViewClient; | |
| 28 | |
| 29 import android.widget.EditText; | |
| 30 import android.widget.LinearLayout.LayoutParams; | |
| 31 import android.widget.PopupMenu; | |
| 32 import android.widget.TextView; | |
| 33 | |
| 34 import java.lang.reflect.InvocationTargetException; | |
| 35 import java.lang.reflect.Method; | |
| 36 | |
| 37 import java.net.URI; | |
| 38 import java.net.URISyntaxException; | |
| 39 | |
| 40 import java.util.regex.Matcher; | |
| 41 import java.util.regex.Pattern; | |
| 42 | |
| 43 /** | |
| 44 * This activity is designed for starting a "mini-browser" for manual testing of
WebView. | |
| 45 * It takes an optional URL as an argument, and displays the page. There is a UR
L bar | |
| 46 * on top of the webview for manually specifying URLs to load. | |
| 47 */ | |
| 48 public class WebViewBrowserActivity extends Activity implements PopupMenu.OnMenu
ItemClickListener { | |
| 49 private EditText mUrlBar; | |
| 50 private WebView mWebView; | |
| 51 private String mWebViewVersion; | |
| 52 | |
| 53 private static final Pattern WEBVIEW_VERSION_PATTERN = | |
| 54 Pattern.compile("(Chrome/)([\\d\\.]+)\\s"); | |
| 55 | |
| 56 // TODO(michaelbai) : Replace "android.webkit.resource.MIDI_SYSEX" with | |
| 57 // PermissionRequest.RESOURCE_MIDI_SYSEX once Android M SDK is used. | |
| 58 private static final String[] AUTOMATICALLY_GRANT = | |
| 59 { PermissionRequest.RESOURCE_VIDEO_CAPTURE, PermissionRequest.RESOUR
CE_AUDIO_CAPTURE, | |
| 60 "android.webkit.resource.MIDI_SYSEX" }; | |
| 61 | |
| 62 @Override | |
| 63 public void onCreate(Bundle savedInstanceState) { | |
| 64 super.onCreate(savedInstanceState); | |
| 65 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
| 66 WebView.setWebContentsDebuggingEnabled(true); | |
| 67 } | |
| 68 setContentView(R.layout.activity_webview_browser); | |
| 69 mWebView = (WebView) findViewById(R.id.webview); | |
| 70 WebSettings settings = mWebView.getSettings(); | |
| 71 initializeSettings(settings); | |
| 72 | |
| 73 Matcher matcher = WEBVIEW_VERSION_PATTERN.matcher(settings.getUserAgentS
tring()); | |
| 74 if (matcher.find()) { | |
| 75 mWebViewVersion = matcher.group(2); | |
| 76 } else { | |
| 77 mWebViewVersion = "-"; | |
| 78 } | |
| 79 setTitle(getResources().getString(R.string.title_activity_browser) + " "
+ mWebViewVersion); | |
| 80 | |
| 81 mWebView.setWebViewClient(new WebViewClient() { | |
| 82 @Override | |
| 83 public boolean shouldOverrideUrlLoading(WebView webView, String url)
{ | |
| 84 return false; | |
| 85 } | |
| 86 | |
| 87 @Override | |
| 88 public void onReceivedError(WebView view, int errorCode, String desc
ription, | |
| 89 String failingUrl) { | |
| 90 setUrlFail(true); | |
| 91 } | |
| 92 }); | |
| 93 | |
| 94 mWebView.setWebChromeClient(new WebChromeClient() { | |
| 95 @Override | |
| 96 public Bitmap getDefaultVideoPoster() { | |
| 97 return Bitmap.createBitmap( | |
| 98 new int[] {Color.TRANSPARENT}, 1, 1, Bitmap.Config.ARGB_
8888); | |
| 99 } | |
| 100 | |
| 101 @Override | |
| 102 public void onGeolocationPermissionsShowPrompt(String origin, | |
| 103 GeolocationPermissions.Callback callback) { | |
| 104 callback.invoke(origin, true, false); | |
| 105 } | |
| 106 | |
| 107 @Override | |
| 108 public void onPermissionRequest(PermissionRequest request) { | |
| 109 request.grant(AUTOMATICALLY_GRANT); | |
| 110 } | |
| 111 }); | |
| 112 | |
| 113 mUrlBar = (EditText) findViewById(R.id.url_field); | |
| 114 mUrlBar.setOnKeyListener(new OnKeyListener() { | |
| 115 public boolean onKey(View view, int keyCode, KeyEvent event) { | |
| 116 if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == Ke
yEvent.ACTION_UP) { | |
| 117 loadUrlFromUrlBar(view); | |
| 118 return true; | |
| 119 } | |
| 120 return false; | |
| 121 } | |
| 122 }); | |
| 123 | |
| 124 String url = getUrlFromIntent(getIntent()); | |
| 125 if (url != null) { | |
| 126 setUrlBarText(url); | |
| 127 setUrlFail(false); | |
| 128 loadUrlFromUrlBar(mUrlBar); | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 public void loadUrlFromUrlBar(View view) { | |
| 133 String url = mUrlBar.getText().toString(); | |
| 134 try { | |
| 135 URI uri = new URI(url); | |
| 136 url = (uri.getScheme() == null) ? "http://" + uri.toString() : uri.t
oString(); | |
| 137 } catch (URISyntaxException e) { | |
| 138 String message = "<html><body>URISyntaxException: " + e.getMessage()
+ "</body></html>"; | |
| 139 mWebView.loadData(message, "text/html", "UTF-8"); | |
| 140 setUrlFail(true); | |
| 141 return; | |
| 142 } | |
| 143 | |
| 144 setUrlBarText(url); | |
| 145 setUrlFail(false); | |
| 146 loadUrl(url); | |
| 147 hideKeyboard(mUrlBar); | |
| 148 } | |
| 149 | |
| 150 public void showPopup(View v) { | |
| 151 PopupMenu popup = new PopupMenu(this, v); | |
| 152 popup.setOnMenuItemClickListener(this); | |
| 153 popup.inflate(R.menu.main_menu); | |
| 154 popup.show(); | |
| 155 } | |
| 156 | |
| 157 @Override | |
| 158 public boolean onMenuItemClick(MenuItem item) { | |
| 159 switch(item.getItemId()) { | |
| 160 case R.id.menu_about: | |
| 161 about(); | |
| 162 hideKeyboard(mUrlBar); | |
| 163 return true; | |
| 164 default: | |
| 165 return false; | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 private void initializeSettings(WebSettings settings) { | |
| 170 settings.setJavaScriptEnabled(true); | |
| 171 | |
| 172 // configure local storage apis and their database paths. | |
| 173 settings.setAppCachePath(getDir("appcache", 0).getPath()); | |
| 174 settings.setGeolocationDatabasePath(getDir("geolocation", 0).getPath()); | |
| 175 settings.setDatabasePath(getDir("databases", 0).getPath()); | |
| 176 | |
| 177 settings.setAppCacheEnabled(true); | |
| 178 settings.setGeolocationEnabled(true); | |
| 179 settings.setDatabaseEnabled(true); | |
| 180 settings.setDomStorageEnabled(true); | |
| 181 } | |
| 182 | |
| 183 private void about() { | |
| 184 WebSettings settings = mWebView.getSettings(); | |
| 185 StringBuilder summary = new StringBuilder(); | |
| 186 summary.append("WebView version : " + mWebViewVersion + "\n"); | |
| 187 | |
| 188 for (Method method : settings.getClass().getMethods()) { | |
| 189 if (!methodIsSimpleInspector(method)) continue; | |
| 190 try { | |
| 191 summary.append(method.getName() + " : " + method.invoke(settings
) + "\n"); | |
| 192 } catch (IllegalAccessException e) { | |
| 193 } catch (InvocationTargetException e) { } | |
| 194 } | |
| 195 | |
| 196 AlertDialog dialog = new AlertDialog.Builder(this) | |
| 197 .setTitle(getResources().getString(R.string.menu_about)) | |
| 198 .setMessage(summary) | |
| 199 .setPositiveButton("OK", null) | |
| 200 .create(); | |
| 201 dialog.show(); | |
| 202 dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL
_PARENT); | |
| 203 } | |
| 204 | |
| 205 // Returns true is a method has no arguments and returns either a boolean or
a String. | |
| 206 private boolean methodIsSimpleInspector(Method method) { | |
| 207 Class<?> returnType = method.getReturnType(); | |
| 208 return ((returnType.equals(boolean.class) || returnType.equals(String.cl
ass)) | |
| 209 && method.getParameterTypes().length == 0); | |
| 210 } | |
| 211 | |
| 212 private void loadUrl(String url) { | |
| 213 mWebView.loadUrl(url); | |
| 214 mWebView.requestFocus(); | |
| 215 } | |
| 216 | |
| 217 private void setUrlBarText(String url) { | |
| 218 mUrlBar.setText(url, TextView.BufferType.EDITABLE); | |
| 219 } | |
| 220 | |
| 221 private void setUrlFail(boolean fail) { | |
| 222 mUrlBar.setTextColor(fail ? Color.RED : Color.BLACK); | |
| 223 } | |
| 224 | |
| 225 /** | |
| 226 * Hides the keyboard. | |
| 227 * @param view The {@link View} that is currently accepting input. | |
| 228 * @return Whether the keyboard was visible before. | |
| 229 */ | |
| 230 private static boolean hideKeyboard(View view) { | |
| 231 InputMethodManager imm = (InputMethodManager) view.getContext().getSyste
mService( | |
| 232 Context.INPUT_METHOD_SERVICE); | |
| 233 return imm.hideSoftInputFromWindow(view.getWindowToken(), 0); | |
| 234 } | |
| 235 | |
| 236 private static String getUrlFromIntent(Intent intent) { | |
| 237 return intent != null ? intent.getDataString() : null; | |
| 238 } | |
| 239 } | |
| OLD | NEW |