Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1228)

Unified Diff: android_webview/tools/WebViewShell/src/org/chromium/webview_shell/WebViewBrowserActivity.java

Issue 1785283005: [WebView] Reorganize all of the WebView Shell apks into their own dir. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/tools/WebViewShell/src/org/chromium/webview_shell/WebViewBrowserActivity.java
diff --git a/android_webview/tools/WebViewShell/src/org/chromium/webview_shell/WebViewBrowserActivity.java b/android_webview/tools/WebViewShell/src/org/chromium/webview_shell/WebViewBrowserActivity.java
deleted file mode 100644
index 2aee9e374658cd8f1a025b9e857d3605563b1c64..0000000000000000000000000000000000000000
--- a/android_webview/tools/WebViewShell/src/org/chromium/webview_shell/WebViewBrowserActivity.java
+++ /dev/null
@@ -1,527 +0,0 @@
-// 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.Manifest;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.provider.Browser;
-import android.util.SparseArray;
-
-import android.view.KeyEvent;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnKeyListener;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-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.PopupMenu;
-import android.widget.TextView;
-
-import org.chromium.base.Log;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-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 static final String TAG = "WebViewShell";
-
- // Our imaginary Android permission to associate with the WebKit geo permission
- private static final String RESOURCE_GEO = "RESOURCE_GEO";
- // Our imaginary WebKit permission to request when loading a file:// URL
- private static final String RESOURCE_FILE_URL = "RESOURCE_FILE_URL";
- // WebKit permissions with no corresponding Android permission can always be granted
- private static final String NO_ANDROID_PERMISSION = "NO_ANDROID_PERMISSION";
-
- // Map from WebKit permissions to Android permissions
- private static final HashMap<String, String> sPermissions;
- static {
- sPermissions = new HashMap<String, String>();
- sPermissions.put(RESOURCE_GEO, Manifest.permission.ACCESS_FINE_LOCATION);
- sPermissions.put(RESOURCE_FILE_URL, Manifest.permission.READ_EXTERNAL_STORAGE);
- sPermissions.put(PermissionRequest.RESOURCE_AUDIO_CAPTURE,
- Manifest.permission.RECORD_AUDIO);
- sPermissions.put(PermissionRequest.RESOURCE_MIDI_SYSEX, NO_ANDROID_PERMISSION);
- sPermissions.put(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID, NO_ANDROID_PERMISSION);
- sPermissions.put(PermissionRequest.RESOURCE_VIDEO_CAPTURE,
- Manifest.permission.CAMERA);
- }
-
- private static final Pattern WEBVIEW_VERSION_PATTERN =
- Pattern.compile("(Chrome/)([\\d\\.]+)\\s");
-
- private EditText mUrlBar;
- private WebView mWebView;
- private String mWebViewVersion;
-
- // Each time we make a request, store it here with an int key. onRequestPermissionsResult will
- // look up the request in order to grant the approprate permissions.
- private SparseArray<PermissionRequest> mPendingRequests = new SparseArray<PermissionRequest>();
- private int mNextRequestKey = 0;
-
- // Work around our wonky API by wrapping a geo permission prompt inside a regular
- // PermissionRequest.
- private static class GeoPermissionRequest extends PermissionRequest {
- private String mOrigin;
- private GeolocationPermissions.Callback mCallback;
-
- public GeoPermissionRequest(String origin, GeolocationPermissions.Callback callback) {
- mOrigin = origin;
- mCallback = callback;
- }
-
- public Uri getOrigin() {
- return Uri.parse(mOrigin);
- }
-
- public String[] getResources() {
- return new String[] { WebViewBrowserActivity.RESOURCE_GEO };
- }
-
- public void grant(String[] resources) {
- assert resources.length == 1;
- assert WebViewBrowserActivity.RESOURCE_GEO.equals(resources[0]);
- mCallback.invoke(mOrigin, true, false);
- }
-
- public void deny() {
- mCallback.invoke(mOrigin, false, false);
- }
- }
-
- // For simplicity, also treat the read access needed for file:// URLs as a regular
- // PermissionRequest.
- private class FilePermissionRequest extends PermissionRequest {
- private String mOrigin;
-
- public FilePermissionRequest(String origin) {
- mOrigin = origin;
- }
-
- public Uri getOrigin() {
- return Uri.parse(mOrigin);
- }
-
- public String[] getResources() {
- return new String[] { WebViewBrowserActivity.RESOURCE_FILE_URL };
- }
-
- public void grant(String[] resources) {
- assert resources.length == 1;
- assert WebViewBrowserActivity.RESOURCE_FILE_URL.equals(resources[0]);
- // Try again now that we have read access.
- WebViewBrowserActivity.this.mWebView.loadUrl(mOrigin);
- }
-
- public void deny() {
- // womp womp
- }
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- WebView.setWebContentsDebuggingEnabled(true);
- }
- setContentView(R.layout.activity_webview_browser);
- 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;
- }
- });
-
- createAndInitializeWebView();
-
- String url = getUrlFromIntent(getIntent());
- if (url != null) {
- setUrlBarText(url);
- setUrlFail(false);
- loadUrlFromUrlBar(mUrlBar);
- }
- }
-
- ViewGroup getContainer() {
- return (ViewGroup) findViewById(R.id.container);
- }
-
- private void createAndInitializeWebView() {
- WebView webview = new WebView(this);
- WebSettings settings = webview.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);
-
- webview.setWebViewClient(new WebViewClient() {
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- setUrlBarText(url);
- }
-
- @Override
- public void onPageFinished(WebView view, String url) {
- setUrlBarText(url);
- }
-
- @Override
- public boolean shouldOverrideUrlLoading(WebView webView, String url) {
- // "about:" and "chrome:" schemes are internal to Chromium;
- // don't want these to be dispatched to other apps.
- if (url.startsWith("about:") || url.startsWith("chrome:")) {
- return false;
- }
- return startBrowsingIntent(WebViewBrowserActivity.this, url);
- }
-
- @Override
- public void onReceivedError(WebView view, int errorCode, String description,
- String failingUrl) {
- setUrlFail(true);
- }
- });
-
- webview.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) {
- onPermissionRequest(new GeoPermissionRequest(origin, callback));
- }
-
- @Override
- public void onPermissionRequest(PermissionRequest request) {
- WebViewBrowserActivity.this.requestPermissionsForPage(request);
- }
- });
-
- mWebView = webview;
- getContainer().addView(
- webview, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
- setUrlBarText("");
- }
-
- // WebKit permissions which can be granted because either they have no associated Android
- // permission or the associated Android permission has been granted
- private boolean canGrant(String webkitPermission) {
- String androidPermission = sPermissions.get(webkitPermission);
- if (androidPermission == NO_ANDROID_PERMISSION) {
- return true;
- }
- return PackageManager.PERMISSION_GRANTED == checkSelfPermission(androidPermission);
- }
-
- private void requestPermissionsForPage(PermissionRequest request) {
- // Deny any unrecognized permissions.
- for (String webkitPermission : request.getResources()) {
- if (!sPermissions.containsKey(webkitPermission)) {
- Log.w(TAG, "Unrecognized WebKit permission: " + webkitPermission);
- request.deny();
- return;
- }
- }
-
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
- request.grant(request.getResources());
- return;
- }
-
- // Find what Android permissions we need before we can grant these WebKit permissions.
- ArrayList<String> androidPermissionsNeeded = new ArrayList<String>();
- for (String webkitPermission : request.getResources()) {
- if (!canGrant(webkitPermission)) {
- // We already checked for unrecognized permissions, and canGrant will skip over
- // NO_ANDROID_PERMISSION cases, so this is guaranteed to be a regular Android
- // permission.
- String androidPermission = sPermissions.get(webkitPermission);
- androidPermissionsNeeded.add(androidPermission);
- }
- }
-
- // If there are no such Android permissions, grant the WebKit permissions immediately.
- if (androidPermissionsNeeded.isEmpty()) {
- request.grant(request.getResources());
- return;
- }
-
- // Otherwise, file a new request
- if (mNextRequestKey == Integer.MAX_VALUE) {
- Log.e(TAG, "Too many permission requests");
- return;
- }
- int requestCode = mNextRequestKey;
- mNextRequestKey++;
- mPendingRequests.append(requestCode, request);
- requestPermissions(androidPermissionsNeeded.toArray(new String[0]), requestCode);
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode,
- String permissions[], int[] grantResults) {
- // Verify that we can now grant all the requested permissions. Note that although grant()
- // takes a list of permissions, grant() is actually all-or-nothing. If there are any
- // requested permissions not included in the granted permissions, all will be denied.
- PermissionRequest request = mPendingRequests.get(requestCode);
- for (String webkitPermission : request.getResources()) {
- if (!canGrant(webkitPermission)) {
- request.deny();
- return;
- }
- }
- request.grant(request.getResources());
- mPendingRequests.delete(requestCode);
- }
-
- 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_reset_webview:
- if (mWebView != null) {
- ViewGroup container = getContainer();
- container.removeView(mWebView);
- mWebView.destroy();
- mWebView = null;
- }
- createAndInitializeWebView();
- return true;
- case R.id.menu_clear_cache:
- if (mWebView != null) {
- mWebView.clearCache(true);
- }
- return true;
- 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) {
- // Request read access if necessary
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
- && "file".equals(Uri.parse(url).getScheme())
- && PackageManager.PERMISSION_DENIED
- == checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
- requestPermissionsForPage(new FilePermissionRequest(url));
- }
-
- // If it is file:// and we don't have permission, they'll get the "Webpage not available"
- // "net::ERR_ACCESS_DENIED" page. When we get permission, FilePermissionRequest.grant()
- // will reload.
- 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;
- }
-
- static final Pattern BROWSER_URI_SCHEMA = Pattern.compile(
- "(?i)" // switch on case insensitive matching
- + "(" // begin group for schema
- + "(?:http|https|file):\\/\\/"
- + "|(?:inline|data|about|chrome|javascript):"
- + ")"
- + "(.*)");
-
- private static boolean startBrowsingIntent(Context context, String url) {
- Intent intent;
- // Perform generic parsing of the URI to turn it into an Intent.
- try {
- intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
- } catch (Exception ex) {
- Log.w(TAG, "Bad URI %s", url, ex);
- return false;
- }
- // Check for regular URIs that WebView supports by itself, but also
- // check if there is a specialized app that had registered itself
- // for this kind of an intent.
- Matcher m = BROWSER_URI_SCHEMA.matcher(url);
- if (m.matches() && !isSpecializedHandlerAvailable(context, intent)) {
- return false;
- }
- // Sanitize the Intent, ensuring web pages can not bypass browser
- // security (only access to BROWSABLE activities).
- intent.addCategory(Intent.CATEGORY_BROWSABLE);
- intent.setComponent(null);
- Intent selector = intent.getSelector();
- if (selector != null) {
- selector.addCategory(Intent.CATEGORY_BROWSABLE);
- selector.setComponent(null);
- }
-
- // Pass the package name as application ID so that the intent from the
- // same application can be opened in the same tab.
- intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
- try {
- context.startActivity(intent);
- return true;
- } catch (ActivityNotFoundException ex) {
- Log.w(TAG, "No application can handle %s", url);
- }
- return false;
- }
-
- /**
- * Search for intent handlers that are specific to the scheme of the URL in the intent.
- */
- private static boolean isSpecializedHandlerAvailable(Context context, Intent intent) {
- PackageManager pm = context.getPackageManager();
- List<ResolveInfo> handlers = pm.queryIntentActivities(intent,
- PackageManager.GET_RESOLVED_FILTER);
- if (handlers == null || handlers.size() == 0) {
- return false;
- }
- for (ResolveInfo resolveInfo : handlers) {
- if (!isNullOrGenericHandler(resolveInfo.filter)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean isNullOrGenericHandler(IntentFilter filter) {
- return filter == null
- || (filter.countDataAuthorities() == 0 && filter.countDataPaths() == 0);
- }
-}

Powered by Google App Engine
This is Rietveld 408576698