Update fullsdk to 4575844
/google/data/ro/projects/android/fetch_artifact \
--bid 4575844 \
--target sdk_phone_x86_64-sdk \
sdk-repo-linux-sources-4575844.zip
Test: TreeHugger
Change-Id: I81e0eb157b4ac3b38408d0ef86f9d6286471f87a
diff --git a/android/webkit/FindAddress.java b/android/webkit/FindAddress.java
new file mode 100644
index 0000000..31b2427
--- /dev/null
+++ b/android/webkit/FindAddress.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import java.util.Locale;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Java implementation of legacy WebView.findAddress algorithm.
+ *
+ * @hide
+ */
+class FindAddress {
+ static class ZipRange {
+ int mLow;
+ int mHigh;
+ int mException1;
+ int mException2;
+ ZipRange(int low, int high, int exception1, int exception2) {
+ mLow = low;
+ mHigh = high;
+ mException1 = exception1;
+ mException2 = exception1;
+ }
+ boolean matches(String zipCode) {
+ int prefix = Integer.parseInt(zipCode.substring(0, 2));
+ return (mLow <= prefix && prefix <= mHigh) || prefix == mException1
+ || prefix == mException2;
+ }
+ }
+
+ // Addresses consist of at least this many words, not including state and zip code.
+ private static final int MIN_ADDRESS_WORDS = 4;
+
+ // Adddresses consist of at most this many words, not including state and zip code.
+ private static final int MAX_ADDRESS_WORDS = 14;
+
+ // Addresses consist of at most this many lines.
+ private static final int MAX_ADDRESS_LINES = 5;
+
+ // No words in an address are longer than this many characters.
+ private static final int kMaxAddressNameWordLength = 25;
+
+ // Location name should be in the first MAX_LOCATION_NAME_DISTANCE words
+ private static final int MAX_LOCATION_NAME_DISTANCE = 5;
+
+ private static final ZipRange[] sStateZipCodeRanges = {
+ new ZipRange(99, 99, -1, -1), // AK Alaska.
+ new ZipRange(35, 36, -1, -1), // AL Alabama.
+ new ZipRange(71, 72, -1, -1), // AR Arkansas.
+ new ZipRange(96, 96, -1, -1), // AS American Samoa.
+ new ZipRange(85, 86, -1, -1), // AZ Arizona.
+ new ZipRange(90, 96, -1, -1), // CA California.
+ new ZipRange(80, 81, -1, -1), // CO Colorado.
+ new ZipRange(6, 6, -1, -1), // CT Connecticut.
+ new ZipRange(20, 20, -1, -1), // DC District of Columbia.
+ new ZipRange(19, 19, -1, -1), // DE Delaware.
+ new ZipRange(32, 34, -1, -1), // FL Florida.
+ new ZipRange(96, 96, -1, -1), // FM Federated States of Micronesia.
+ new ZipRange(30, 31, -1, -1), // GA Georgia.
+ new ZipRange(96, 96, -1, -1), // GU Guam.
+ new ZipRange(96, 96, -1, -1), // HI Hawaii.
+ new ZipRange(50, 52, -1, -1), // IA Iowa.
+ new ZipRange(83, 83, -1, -1), // ID Idaho.
+ new ZipRange(60, 62, -1, -1), // IL Illinois.
+ new ZipRange(46, 47, -1, -1), // IN Indiana.
+ new ZipRange(66, 67, 73, -1), // KS Kansas.
+ new ZipRange(40, 42, -1, -1), // KY Kentucky.
+ new ZipRange(70, 71, -1, -1), // LA Louisiana.
+ new ZipRange(1, 2, -1, -1), // MA Massachusetts.
+ new ZipRange(20, 21, -1, -1), // MD Maryland.
+ new ZipRange(3, 4, -1, -1), // ME Maine.
+ new ZipRange(96, 96, -1, -1), // MH Marshall Islands.
+ new ZipRange(48, 49, -1, -1), // MI Michigan.
+ new ZipRange(55, 56, -1, -1), // MN Minnesota.
+ new ZipRange(63, 65, -1, -1), // MO Missouri.
+ new ZipRange(96, 96, -1, -1), // MP Northern Mariana Islands.
+ new ZipRange(38, 39, -1, -1), // MS Mississippi.
+ new ZipRange(55, 56, -1, -1), // MT Montana.
+ new ZipRange(27, 28, -1, -1), // NC North Carolina.
+ new ZipRange(58, 58, -1, -1), // ND North Dakota.
+ new ZipRange(68, 69, -1, -1), // NE Nebraska.
+ new ZipRange(3, 4, -1, -1), // NH New Hampshire.
+ new ZipRange(7, 8, -1, -1), // NJ New Jersey.
+ new ZipRange(87, 88, 86, -1), // NM New Mexico.
+ new ZipRange(88, 89, 96, -1), // NV Nevada.
+ new ZipRange(10, 14, 0, 6), // NY New York.
+ new ZipRange(43, 45, -1, -1), // OH Ohio.
+ new ZipRange(73, 74, -1, -1), // OK Oklahoma.
+ new ZipRange(97, 97, -1, -1), // OR Oregon.
+ new ZipRange(15, 19, -1, -1), // PA Pennsylvania.
+ new ZipRange(6, 6, 0, 9), // PR Puerto Rico.
+ new ZipRange(96, 96, -1, -1), // PW Palau.
+ new ZipRange(2, 2, -1, -1), // RI Rhode Island.
+ new ZipRange(29, 29, -1, -1), // SC South Carolina.
+ new ZipRange(57, 57, -1, -1), // SD South Dakota.
+ new ZipRange(37, 38, -1, -1), // TN Tennessee.
+ new ZipRange(75, 79, 87, 88), // TX Texas.
+ new ZipRange(84, 84, -1, -1), // UT Utah.
+ new ZipRange(22, 24, 20, -1), // VA Virginia.
+ new ZipRange(6, 9, -1, -1), // VI Virgin Islands.
+ new ZipRange(5, 5, -1, -1), // VT Vermont.
+ new ZipRange(98, 99, -1, -1), // WA Washington.
+ new ZipRange(53, 54, -1, -1), // WI Wisconsin.
+ new ZipRange(24, 26, -1, -1), // WV West Virginia.
+ new ZipRange(82, 83, -1, -1) // WY Wyoming.
+ };
+
+ // Newlines
+ private static final String NL = "\n\u000B\u000C\r\u0085\u2028\u2029";
+
+ // Space characters
+ private static final String SP = "\u0009\u0020\u00A0\u1680\u2000\u2001"
+ + "\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F"
+ + "\u205F\u3000";
+
+ // Whitespace
+ private static final String WS = SP + NL;
+
+ // Characters that are considered word delimiters.
+ private static final String WORD_DELIM = ",*\u2022" + WS;
+
+ // Lookahead for word end.
+ private static final String WORD_END = "(?=[" + WORD_DELIM + "]|$)";
+
+ // Address words are a sequence of non-delimiter characters.
+ private static final Pattern sWordRe =
+ Pattern.compile("[^" + WORD_DELIM + "]+" + WORD_END, Pattern.CASE_INSENSITIVE);
+
+ // Characters that are considered suffix delimiters for house numbers.
+ private static final String HOUSE_POST_DELIM = ",\"'" + WS;
+
+ // Lookahead for house end.
+ private static final String HOUSE_END = "(?=[" + HOUSE_POST_DELIM + "]|$)";
+
+ // Characters that are considered prefix delimiters for house numbers.
+ private static final String HOUSE_PRE_DELIM = ":" + HOUSE_POST_DELIM;
+
+ // A house number component is "one" or a number, optionally
+ // followed by a single alphabetic character, or
+ private static final String HOUSE_COMPONENT = "(?:one|\\d+([a-z](?=[^a-z]|$)|st|nd|rd|th)?)";
+
+ // House numbers are a repetition of |HOUSE_COMPONENT|, separated by -, and followed by
+ // a delimiter character.
+ private static final Pattern sHouseNumberRe =
+ Pattern.compile(HOUSE_COMPONENT + "(?:-" + HOUSE_COMPONENT + ")*" + HOUSE_END,
+ Pattern.CASE_INSENSITIVE);
+
+ // XXX: do we want to accept whitespace other than 0x20 in state names?
+ private static final Pattern sStateRe = Pattern.compile("(?:"
+ + "(ak|alaska)|"
+ + "(al|alabama)|"
+ + "(ar|arkansas)|"
+ + "(as|american[" + SP + "]+samoa)|"
+ + "(az|arizona)|"
+ + "(ca|california)|"
+ + "(co|colorado)|"
+ + "(ct|connecticut)|"
+ + "(dc|district[" + SP + "]+of[" + SP + "]+columbia)|"
+ + "(de|delaware)|"
+ + "(fl|florida)|"
+ + "(fm|federated[" + SP + "]+states[" + SP + "]+of[" + SP + "]+micronesia)|"
+ + "(ga|georgia)|"
+ + "(gu|guam)|"
+ + "(hi|hawaii)|"
+ + "(ia|iowa)|"
+ + "(id|idaho)|"
+ + "(il|illinois)|"
+ + "(in|indiana)|"
+ + "(ks|kansas)|"
+ + "(ky|kentucky)|"
+ + "(la|louisiana)|"
+ + "(ma|massachusetts)|"
+ + "(md|maryland)|"
+ + "(me|maine)|"
+ + "(mh|marshall[" + SP + "]+islands)|"
+ + "(mi|michigan)|"
+ + "(mn|minnesota)|"
+ + "(mo|missouri)|"
+ + "(mp|northern[" + SP + "]+mariana[" + SP + "]+islands)|"
+ + "(ms|mississippi)|"
+ + "(mt|montana)|"
+ + "(nc|north[" + SP + "]+carolina)|"
+ + "(nd|north[" + SP + "]+dakota)|"
+ + "(ne|nebraska)|"
+ + "(nh|new[" + SP + "]+hampshire)|"
+ + "(nj|new[" + SP + "]+jersey)|"
+ + "(nm|new[" + SP + "]+mexico)|"
+ + "(nv|nevada)|"
+ + "(ny|new[" + SP + "]+york)|"
+ + "(oh|ohio)|"
+ + "(ok|oklahoma)|"
+ + "(or|oregon)|"
+ + "(pa|pennsylvania)|"
+ + "(pr|puerto[" + SP + "]+rico)|"
+ + "(pw|palau)|"
+ + "(ri|rhode[" + SP + "]+island)|"
+ + "(sc|south[" + SP + "]+carolina)|"
+ + "(sd|south[" + SP + "]+dakota)|"
+ + "(tn|tennessee)|"
+ + "(tx|texas)|"
+ + "(ut|utah)|"
+ + "(va|virginia)|"
+ + "(vi|virgin[" + SP + "]+islands)|"
+ + "(vt|vermont)|"
+ + "(wa|washington)|"
+ + "(wi|wisconsin)|"
+ + "(wv|west[" + SP + "]+virginia)|"
+ + "(wy|wyoming)"
+ + ")" + WORD_END,
+ Pattern.CASE_INSENSITIVE);
+
+ private static final Pattern sLocationNameRe = Pattern.compile("(?:"
+ + "alley|annex|arcade|ave[.]?|avenue|alameda|bayou|"
+ + "beach|bend|bluffs?|bottom|boulevard|branch|bridge|"
+ + "brooks?|burgs?|bypass|broadway|camino|camp|canyon|"
+ + "cape|causeway|centers?|circles?|cliffs?|club|common|"
+ + "corners?|course|courts?|coves?|creek|crescent|crest|"
+ + "crossing|crossroad|curve|circulo|dale|dam|divide|"
+ + "drives?|estates?|expressway|extensions?|falls?|ferry|"
+ + "fields?|flats?|fords?|forest|forges?|forks?|fort|"
+ + "freeway|gardens?|gateway|glens?|greens?|groves?|"
+ + "harbors?|haven|heights|highway|hills?|hollow|inlet|"
+ + "islands?|isle|junctions?|keys?|knolls?|lakes?|land|"
+ + "landing|lane|lights?|loaf|locks?|lodge|loop|mall|"
+ + "manors?|meadows?|mews|mills?|mission|motorway|mount|"
+ + "mountains?|neck|orchard|oval|overpass|parks?|"
+ + "parkways?|pass|passage|path|pike|pines?|plains?|"
+ + "plaza|points?|ports?|prairie|privada|radial|ramp|"
+ + "ranch|rapids?|rd[.]?|rest|ridges?|river|roads?|route|"
+ + "row|rue|run|shoals?|shores?|skyway|springs?|spurs?|"
+ + "squares?|station|stravenue|stream|st[.]?|streets?|"
+ + "summit|speedway|terrace|throughway|trace|track|"
+ + "trafficway|trail|tunnel|turnpike|underpass|unions?|"
+ + "valleys?|viaduct|views?|villages?|ville|vista|walks?|"
+ + "wall|ways?|wells?|xing|xrd)" + WORD_END,
+ Pattern.CASE_INSENSITIVE);
+
+ private static final Pattern sSuffixedNumberRe =
+ Pattern.compile("(\\d+)(st|nd|rd|th)", Pattern.CASE_INSENSITIVE);
+
+ private static final Pattern sZipCodeRe =
+ Pattern.compile("(?:\\d{5}(?:-\\d{4})?)" + WORD_END, Pattern.CASE_INSENSITIVE);
+
+ private static boolean checkHouseNumber(String houseNumber) {
+ // Make sure that there are at most 5 digits.
+ int digitCount = 0;
+ for (int i = 0; i < houseNumber.length(); ++i) {
+ if (Character.isDigit(houseNumber.charAt(i))) ++digitCount;
+ }
+ if (digitCount > 5) return false;
+
+ // Make sure that any ordinals are valid.
+ Matcher suffixMatcher = sSuffixedNumberRe.matcher(houseNumber);
+ while (suffixMatcher.find()) {
+ int num = Integer.parseInt(suffixMatcher.group(1));
+ if (num == 0) {
+ return false; // 0th is invalid.
+ }
+ String suffix = suffixMatcher.group(2).toLowerCase(Locale.getDefault());
+ switch (num % 10) {
+ case 1:
+ return suffix.equals(num % 100 == 11 ? "th" : "st");
+ case 2:
+ return suffix.equals(num % 100 == 12 ? "th" : "nd");
+ case 3:
+ return suffix.equals(num % 100 == 13 ? "th" : "rd");
+ default:
+ return suffix.equals("th");
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Attempt to match a house number beginnning at position offset
+ * in content. The house number must be followed by a word
+ * delimiter or the end of the string, and if offset is non-zero,
+ * then it must also be preceded by a word delimiter.
+ *
+ * @return a MatchResult if a valid house number was found.
+ */
+ private static MatchResult matchHouseNumber(String content, int offset) {
+ if (offset > 0 && HOUSE_PRE_DELIM.indexOf(content.charAt(offset - 1)) == -1) return null;
+ Matcher matcher = sHouseNumberRe.matcher(content).region(offset, content.length());
+ if (matcher.lookingAt()) {
+ MatchResult matchResult = matcher.toMatchResult();
+ if (checkHouseNumber(matchResult.group(0))) return matchResult;
+ }
+ return null;
+ }
+
+ /**
+ * Attempt to match a US state beginnning at position offset in
+ * content. The matching state must be followed by a word
+ * delimiter or the end of the string, and if offset is non-zero,
+ * then it must also be preceded by a word delimiter.
+ *
+ * @return a MatchResult if a valid US state (or two letter code)
+ * was found.
+ */
+ private static MatchResult matchState(String content, int offset) {
+ if (offset > 0 && WORD_DELIM.indexOf(content.charAt(offset - 1)) == -1) return null;
+ Matcher stateMatcher = sStateRe.matcher(content).region(offset, content.length());
+ return stateMatcher.lookingAt() ? stateMatcher.toMatchResult() : null;
+ }
+
+ /**
+ * Test whether zipCode matches the U.S. zip code format (ddddd or
+ * ddddd-dddd) and is within the expected range, given that
+ * stateMatch is a match of sStateRe.
+ *
+ * @return true if zipCode is a valid zip code, is legal for the
+ * matched state, and is followed by a word delimiter or the end
+ * of the string.
+ */
+ private static boolean isValidZipCode(String zipCode, MatchResult stateMatch) {
+ if (stateMatch == null) return false;
+ // Work out the index of the state, based on which group matched.
+ int stateIndex = stateMatch.groupCount();
+ while (stateIndex > 0) {
+ if (stateMatch.group(stateIndex--) != null) break;
+ }
+ return sZipCodeRe.matcher(zipCode).matches()
+ && sStateZipCodeRanges[stateIndex].matches(zipCode);
+ }
+
+ /**
+ * Test whether location is one of the valid locations.
+ *
+ * @return true if location starts with a valid location name
+ * followed by a word delimiter or the end of the string.
+ */
+ private static boolean isValidLocationName(String location) {
+ return sLocationNameRe.matcher(location).matches();
+ }
+
+ /**
+ * Attempt to match a complete address in content, starting with
+ * houseNumberMatch.
+ *
+ * @param content The string to search.
+ * @param houseNumberMatch A matching house number to start extending.
+ * @return +ve: the end of the match
+ * +ve: the position to restart searching for house numbers, negated.
+ */
+ private static int attemptMatch(String content, MatchResult houseNumberMatch) {
+ int restartPos = -1;
+ int nonZipMatch = -1;
+ int it = houseNumberMatch.end();
+ int numLines = 1;
+ boolean consecutiveHouseNumbers = true;
+ boolean foundLocationName = false;
+ int wordCount = 1;
+ String lastWord = "";
+
+ Matcher matcher = sWordRe.matcher(content);
+
+ for (; it < content.length(); lastWord = matcher.group(0), it = matcher.end()) {
+ if (!matcher.find(it)) {
+ // No more words in the input sequence.
+ return -content.length();
+ }
+ if (matcher.end() - matcher.start() > kMaxAddressNameWordLength) {
+ // Word is too long to be part of an address. Fail.
+ return -matcher.end();
+ }
+
+ // Count the number of newlines we just consumed.
+ while (it < matcher.start()) {
+ if (NL.indexOf(content.charAt(it++)) != -1) ++numLines;
+ }
+
+ // Consumed too many lines. Fail.
+ if (numLines > MAX_ADDRESS_LINES) break;
+
+ // Consumed too many words. Fail.
+ if (++wordCount > MAX_ADDRESS_WORDS) break;
+
+ if (matchHouseNumber(content, it) != null) {
+ if (consecutiveHouseNumbers && numLines > 1) {
+ // Last line ended with a number, and this this line starts with one.
+ // Restart at this number.
+ return -it;
+ }
+ // Remember the position of this match as the restart position.
+ if (restartPos == -1) restartPos = it;
+ continue;
+ }
+
+ consecutiveHouseNumbers = false;
+
+ if (isValidLocationName(matcher.group(0))) {
+ foundLocationName = true;
+ continue;
+ }
+
+ if (wordCount == MAX_LOCATION_NAME_DISTANCE && !foundLocationName) {
+ // Didn't find a location name in time. Fail.
+ it = matcher.end();
+ break;
+ }
+
+ if (foundLocationName && wordCount > MIN_ADDRESS_WORDS) {
+ // We can now attempt to match a state.
+ MatchResult stateMatch = matchState(content, it);
+ if (stateMatch != null) {
+ if (lastWord.equals("et") && stateMatch.group(0).equals("al")) {
+ // Reject "et al" as a false postitive.
+ it = stateMatch.end();
+ break;
+ }
+
+ // At this point we've matched a state; try to match a zip code after it.
+ Matcher zipMatcher = sWordRe.matcher(content);
+ if (zipMatcher.find(stateMatch.end())
+ && isValidZipCode(zipMatcher.group(0), stateMatch)) {
+ return zipMatcher.end();
+ }
+ // The content ends with a state but no zip
+ // code. This is a legal match according to the
+ // documentation. N.B. This differs from the
+ // original c++ implementation, which only allowed
+ // the zip code to be optional at the end of the
+ // string, which presumably is a bug. Now we
+ // prefer to find a match with a zip code, but
+ // remember non-zip matches and return them if
+ // necessary.
+ nonZipMatch = stateMatch.end();
+ }
+ }
+ }
+
+ if (nonZipMatch > 0) return nonZipMatch;
+
+ return -(restartPos > 0 ? restartPos : it);
+ }
+
+ /**
+ * Return the first matching address in content.
+ *
+ * @param content The string to search.
+ * @return The first valid address, or null if no address was matched.
+ */
+ static String findAddress(String content) {
+ Matcher houseNumberMatcher = sHouseNumberRe.matcher(content);
+ int start = 0;
+ while (houseNumberMatcher.find(start)) {
+ if (checkHouseNumber(houseNumberMatcher.group(0))) {
+ start = houseNumberMatcher.start();
+ int end = attemptMatch(content, houseNumberMatcher);
+ if (end > 0) {
+ return content.substring(start, end);
+ }
+ start = -end;
+ } else {
+ start = houseNumberMatcher.end();
+ }
+ }
+ return null;
+ }
+}
diff --git a/android/webkit/SafeBrowsingResponse.java b/android/webkit/SafeBrowsingResponse.java
index 960b56b..1d3a617 100644
--- a/android/webkit/SafeBrowsingResponse.java
+++ b/android/webkit/SafeBrowsingResponse.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,5 +16,36 @@
package android.webkit;
-public class SafeBrowsingResponse {
+/**
+ * Used to indicate an action to take when hitting a malicious URL. Instances of this class are
+ * created by the WebView and passed to {@link android.webkit.WebViewClient#onSafeBrowsingHit}. The
+ * host application must call {@link #showInterstitial(boolean)}, {@link #proceed(boolean)}, or
+ * {@link #backToSafety(boolean)} to set the WebView's response to the Safe Browsing hit.
+ *
+ * <p>
+ * If reporting is enabled, all reports will be sent according to the privacy policy referenced by
+ * {@link android.webkit.WebView#getSafeBrowsingPrivacyPolicyUrl()}.
+ */
+public abstract class SafeBrowsingResponse {
+
+ /**
+ * Display the default interstitial.
+ *
+ * @param allowReporting {@code true} if the interstitial should show a reporting checkbox.
+ */
+ public abstract void showInterstitial(boolean allowReporting);
+
+ /**
+ * Act as if the user clicked "visit this unsafe site."
+ *
+ * @param report {@code true} to enable Safe Browsing reporting.
+ */
+ public abstract void proceed(boolean report);
+
+ /**
+ * Act as if the user clicked "back to safety."
+ *
+ * @param report {@code true} to enable Safe Browsing reporting.
+ */
+ public abstract void backToSafety(boolean report);
}
diff --git a/android/webkit/WebViewClient.java b/android/webkit/WebViewClient.java
index f5d220c..d0f9eee 100644
--- a/android/webkit/WebViewClient.java
+++ b/android/webkit/WebViewClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,545 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.webkit;
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.graphics.Bitmap;
+import android.net.http.SslError;
+import android.os.Message;
+import android.view.InputEvent;
+import android.view.KeyEvent;
+import android.view.ViewRootImpl;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
public class WebViewClient {
+
+ /**
+ * Give the host application a chance to take over the control when a new
+ * url is about to be loaded in the current WebView. If WebViewClient is not
+ * provided, by default WebView will ask Activity Manager to choose the
+ * proper handler for the url. If WebViewClient is provided, return {@code true}
+ * means the host application handles the url, while return {@code false} means the
+ * current WebView handles the url.
+ * This method is not called for requests using the POST "method".
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param url The url to be loaded.
+ * @return {@code true} if the host application wants to leave the current WebView
+ * and handle the url itself, otherwise return {@code false}.
+ * @deprecated Use {@link #shouldOverrideUrlLoading(WebView, WebResourceRequest)
+ * shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead.
+ */
+ @Deprecated
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ return false;
+ }
+
+ /**
+ * Give the host application a chance to take over the control when a new
+ * url is about to be loaded in the current WebView. If WebViewClient is not
+ * provided, by default WebView will ask Activity Manager to choose the
+ * proper handler for the url. If WebViewClient is provided, return {@code true}
+ * means the host application handles the url, while return {@code false} means the
+ * current WebView handles the url.
+ *
+ * <p>Notes:
+ * <ul>
+ * <li>This method is not called for requests using the POST "method".</li>
+ * <li>This method is also called for subframes with non-http schemes, thus it is
+ * strongly disadvised to unconditionally call {@link WebView#loadUrl(String)}
+ * with the request's url from inside the method and then return {@code true},
+ * as this will make WebView to attempt loading a non-http url, and thus fail.</li>
+ * </ul>
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param request Object containing the details of the request.
+ * @return {@code true} if the host application wants to leave the current WebView
+ * and handle the url itself, otherwise return {@code false}.
+ */
+ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
+ return shouldOverrideUrlLoading(view, request.getUrl().toString());
+ }
+
+ /**
+ * Notify the host application that a page has started loading. This method
+ * is called once for each main frame load so a page with iframes or
+ * framesets will call onPageStarted one time for the main frame. This also
+ * means that onPageStarted will not be called when the contents of an
+ * embedded frame changes, i.e. clicking a link whose target is an iframe,
+ * it will also not be called for fragment navigations (navigations to
+ * #fragment_id).
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param url The url to be loaded.
+ * @param favicon The favicon for this page if it already exists in the
+ * database.
+ */
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ }
+
+ /**
+ * Notify the host application that a page has finished loading. This method
+ * is called only for main frame. When onPageFinished() is called, the
+ * rendering picture may not be updated yet. To get the notification for the
+ * new Picture, use {@link WebView.PictureListener#onNewPicture}.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param url The url of the page.
+ */
+ public void onPageFinished(WebView view, String url) {
+ }
+
+ /**
+ * Notify the host application that the WebView will load the resource
+ * specified by the given url.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param url The url of the resource the WebView will load.
+ */
+ public void onLoadResource(WebView view, String url) {
+ }
+
+ /**
+ * Notify the host application that {@link android.webkit.WebView} content left over from
+ * previous page navigations will no longer be drawn.
+ *
+ * <p>This callback can be used to determine the point at which it is safe to make a recycled
+ * {@link android.webkit.WebView} visible, ensuring that no stale content is shown. It is called
+ * at the earliest point at which it can be guaranteed that {@link WebView#onDraw} will no
+ * longer draw any content from previous navigations. The next draw will display either the
+ * {@link WebView#setBackgroundColor background color} of the {@link WebView}, or some of the
+ * contents of the newly loaded page.
+ *
+ * <p>This method is called when the body of the HTTP response has started loading, is reflected
+ * in the DOM, and will be visible in subsequent draws. This callback occurs early in the
+ * document loading process, and as such you should expect that linked resources (for example,
+ * CSS and images) may not be available.
+ *
+ * <p>For more fine-grained notification of visual state updates, see {@link
+ * WebView#postVisualStateCallback}.
+ *
+ * <p>Please note that all the conditions and recommendations applicable to
+ * {@link WebView#postVisualStateCallback} also apply to this API.
+ *
+ * <p>This callback is only called for main frame navigations.
+ *
+ * @param view The {@link android.webkit.WebView} for which the navigation occurred.
+ * @param url The URL corresponding to the page navigation that triggered this callback.
+ */
+ public void onPageCommitVisible(WebView view, String url) {
+ }
+
+ /**
+ * Notify the host application of a resource request and allow the
+ * application to return the data. If the return value is {@code null}, the WebView
+ * will continue to load the resource as usual. Otherwise, the return
+ * response and data will be used.
+ *
+ * <p class="note"><b>Note:</b> This method is called on a thread
+ * other than the UI thread so clients should exercise caution
+ * when accessing private data or the view system.
+ *
+ * <p class="note"><b>Note:</b> When Safe Browsing is enabled, these URLs still undergo Safe
+ * Browsing checks. If this is undesired, whitelist the URL with {@link
+ * WebView#setSafeBrowsingWhitelist} or ignore the warning with {@link #onSafeBrowsingHit}.
+ *
+ * @param view The {@link android.webkit.WebView} that is requesting the
+ * resource.
+ * @param url The raw url of the resource.
+ * @return A {@link android.webkit.WebResourceResponse} containing the
+ * response information or {@code null} if the WebView should load the
+ * resource itself.
+ * @deprecated Use {@link #shouldInterceptRequest(WebView, WebResourceRequest)
+ * shouldInterceptRequest(WebView, WebResourceRequest)} instead.
+ */
+ @Deprecated
+ @Nullable
+ public WebResourceResponse shouldInterceptRequest(WebView view,
+ String url) {
+ return null;
+ }
+
+ /**
+ * Notify the host application of a resource request and allow the
+ * application to return the data. If the return value is {@code null}, the WebView
+ * will continue to load the resource as usual. Otherwise, the return
+ * response and data will be used.
+ *
+ * <p class="note"><b>Note:</b> This method is called on a thread
+ * other than the UI thread so clients should exercise caution
+ * when accessing private data or the view system.
+ *
+ * <p class="note"><b>Note:</b> When Safe Browsing is enabled, these URLs still undergo Safe
+ * Browsing checks. If this is undesired, whitelist the URL with {@link
+ * WebView#setSafeBrowsingWhitelist} or ignore the warning with {@link #onSafeBrowsingHit}.
+ *
+ * @param view The {@link android.webkit.WebView} that is requesting the
+ * resource.
+ * @param request Object containing the details of the request.
+ * @return A {@link android.webkit.WebResourceResponse} containing the
+ * response information or {@code null} if the WebView should load the
+ * resource itself.
+ */
+ @Nullable
+ public WebResourceResponse shouldInterceptRequest(WebView view,
+ WebResourceRequest request) {
+ return shouldInterceptRequest(view, request.getUrl().toString());
+ }
+
+ /**
+ * Notify the host application that there have been an excessive number of
+ * HTTP redirects. As the host application if it would like to continue
+ * trying to load the resource. The default behavior is to send the cancel
+ * message.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param cancelMsg The message to send if the host wants to cancel
+ * @param continueMsg The message to send if the host wants to continue
+ * @deprecated This method is no longer called. When the WebView encounters
+ * a redirect loop, it will cancel the load.
+ */
+ @Deprecated
+ public void onTooManyRedirects(WebView view, Message cancelMsg,
+ Message continueMsg) {
+ cancelMsg.sendToTarget();
+ }
+
+ // These ints must match up to the hidden values in EventHandler.
+ /** Generic error */
+ public static final int ERROR_UNKNOWN = -1;
+ /** Server or proxy hostname lookup failed */
+ public static final int ERROR_HOST_LOOKUP = -2;
+ /** Unsupported authentication scheme (not basic or digest) */
+ public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3;
+ /** User authentication failed on server */
+ public static final int ERROR_AUTHENTICATION = -4;
+ /** User authentication failed on proxy */
+ public static final int ERROR_PROXY_AUTHENTICATION = -5;
+ /** Failed to connect to the server */
+ public static final int ERROR_CONNECT = -6;
+ /** Failed to read or write to the server */
+ public static final int ERROR_IO = -7;
+ /** Connection timed out */
+ public static final int ERROR_TIMEOUT = -8;
+ /** Too many redirects */
+ public static final int ERROR_REDIRECT_LOOP = -9;
+ /** Unsupported URI scheme */
+ public static final int ERROR_UNSUPPORTED_SCHEME = -10;
+ /** Failed to perform SSL handshake */
+ public static final int ERROR_FAILED_SSL_HANDSHAKE = -11;
+ /** Malformed URL */
+ public static final int ERROR_BAD_URL = -12;
+ /** Generic file error */
+ public static final int ERROR_FILE = -13;
+ /** File not found */
+ public static final int ERROR_FILE_NOT_FOUND = -14;
+ /** Too many requests during this load */
+ public static final int ERROR_TOO_MANY_REQUESTS = -15;
+ /** Resource load was canceled by Safe Browsing */
+ public static final int ERROR_UNSAFE_RESOURCE = -16;
+
+ /** @hide */
+ @IntDef(prefix = { "SAFE_BROWSING_THREAT_" }, value = {
+ SAFE_BROWSING_THREAT_UNKNOWN,
+ SAFE_BROWSING_THREAT_MALWARE,
+ SAFE_BROWSING_THREAT_PHISHING,
+ SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SafeBrowsingThreat {}
+
+ /** The resource was blocked for an unknown reason */
+ public static final int SAFE_BROWSING_THREAT_UNKNOWN = 0;
+ /** The resource was blocked because it contains malware */
+ public static final int SAFE_BROWSING_THREAT_MALWARE = 1;
+ /** The resource was blocked because it contains deceptive content */
+ public static final int SAFE_BROWSING_THREAT_PHISHING = 2;
+ /** The resource was blocked because it contains unwanted software */
+ public static final int SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE = 3;
+
+ /**
+ * Report an error to the host application. These errors are unrecoverable
+ * (i.e. the main resource is unavailable). The {@code errorCode} parameter
+ * corresponds to one of the {@code ERROR_*} constants.
+ * @param view The WebView that is initiating the callback.
+ * @param errorCode The error code corresponding to an ERROR_* value.
+ * @param description A String describing the error.
+ * @param failingUrl The url that failed to load.
+ * @deprecated Use {@link #onReceivedError(WebView, WebResourceRequest, WebResourceError)
+ * onReceivedError(WebView, WebResourceRequest, WebResourceError)} instead.
+ */
+ @Deprecated
+ public void onReceivedError(WebView view, int errorCode,
+ String description, String failingUrl) {
+ }
+
+ /**
+ * Report web resource loading error to the host application. These errors usually indicate
+ * inability to connect to the server. Note that unlike the deprecated version of the callback,
+ * the new version will be called for any resource (iframe, image, etc.), not just for the main
+ * page. Thus, it is recommended to perform minimum required work in this callback.
+ * @param view The WebView that is initiating the callback.
+ * @param request The originating request.
+ * @param error Information about the error occurred.
+ */
+ public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
+ if (request.isForMainFrame()) {
+ onReceivedError(view,
+ error.getErrorCode(), error.getDescription().toString(),
+ request.getUrl().toString());
+ }
+ }
+
+ /**
+ * Notify the host application that an HTTP error has been received from the server while
+ * loading a resource. HTTP errors have status codes >= 400. This callback will be called
+ * for any resource (iframe, image, etc.), not just for the main page. Thus, it is recommended
+ * to perform minimum required work in this callback. Note that the content of the server
+ * response may not be provided within the {@code errorResponse} parameter.
+ * @param view The WebView that is initiating the callback.
+ * @param request The originating request.
+ * @param errorResponse Information about the error occurred.
+ */
+ public void onReceivedHttpError(
+ WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
+ }
+
+ /**
+ * As the host application if the browser should resend data as the
+ * requested page was a result of a POST. The default is to not resend the
+ * data.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param dontResend The message to send if the browser should not resend
+ * @param resend The message to send if the browser should resend data
+ */
+ public void onFormResubmission(WebView view, Message dontResend,
+ Message resend) {
+ dontResend.sendToTarget();
+ }
+
+ /**
+ * Notify the host application to update its visited links database.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param url The url being visited.
+ * @param isReload {@code true} if this url is being reloaded.
+ */
+ public void doUpdateVisitedHistory(WebView view, String url,
+ boolean isReload) {
+ }
+
+ /**
+ * Notify the host application that an SSL error occurred while loading a
+ * resource. The host application must call either handler.cancel() or
+ * handler.proceed(). Note that the decision may be retained for use in
+ * response to future SSL errors. The default behavior is to cancel the
+ * load.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param handler An SslErrorHandler object that will handle the user's
+ * response.
+ * @param error The SSL error object.
+ */
+ public void onReceivedSslError(WebView view, SslErrorHandler handler,
+ SslError error) {
+ handler.cancel();
+ }
+
+ /**
+ * Notify the host application to handle a SSL client certificate request. The host application
+ * is responsible for showing the UI if desired and providing the keys. There are three ways to
+ * respond: {@link ClientCertRequest#proceed}, {@link ClientCertRequest#cancel}, or {@link
+ * ClientCertRequest#ignore}. Webview stores the response in memory (for the life of the
+ * application) if {@link ClientCertRequest#proceed} or {@link ClientCertRequest#cancel} is
+ * called and does not call {@code onReceivedClientCertRequest()} again for the same host and
+ * port pair. Webview does not store the response if {@link ClientCertRequest#ignore}
+ * is called. Note that, multiple layers in chromium network stack might be
+ * caching the responses, so the behavior for ignore is only a best case
+ * effort.
+ *
+ * This method is called on the UI thread. During the callback, the
+ * connection is suspended.
+ *
+ * For most use cases, the application program should implement the
+ * {@link android.security.KeyChainAliasCallback} interface and pass it to
+ * {@link android.security.KeyChain#choosePrivateKeyAlias} to start an
+ * activity for the user to choose the proper alias. The keychain activity will
+ * provide the alias through the callback method in the implemented interface. Next
+ * the application should create an async task to call
+ * {@link android.security.KeyChain#getPrivateKey} to receive the key.
+ *
+ * An example implementation of client certificates can be seen at
+ * <A href="https://android.googlesource.com/platform/packages/apps/Browser/+/android-5.1.1_r1/src/com/android/browser/Tab.java">
+ * AOSP Browser</a>
+ *
+ * The default behavior is to cancel, returning no client certificate.
+ *
+ * @param view The WebView that is initiating the callback
+ * @param request An instance of a {@link ClientCertRequest}
+ *
+ */
+ public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
+ request.cancel();
+ }
+
+ /**
+ * Notifies the host application that the WebView received an HTTP
+ * authentication request. The host application can use the supplied
+ * {@link HttpAuthHandler} to set the WebView's response to the request.
+ * The default behavior is to cancel the request.
+ *
+ * @param view the WebView that is initiating the callback
+ * @param handler the HttpAuthHandler used to set the WebView's response
+ * @param host the host requiring authentication
+ * @param realm the realm for which authentication is required
+ * @see WebView#getHttpAuthUsernamePassword
+ */
+ public void onReceivedHttpAuthRequest(WebView view,
+ HttpAuthHandler handler, String host, String realm) {
+ handler.cancel();
+ }
+
+ /**
+ * Give the host application a chance to handle the key event synchronously.
+ * e.g. menu shortcut key events need to be filtered this way. If return
+ * true, WebView will not handle the key event. If return {@code false}, WebView
+ * will always handle the key event, so none of the super in the view chain
+ * will see the key event. The default behavior returns {@code false}.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param event The key event.
+ * @return {@code true} if the host application wants to handle the key event
+ * itself, otherwise return {@code false}
+ */
+ public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
+ return false;
+ }
+
+ /**
+ * Notify the host application that a key was not handled by the WebView.
+ * Except system keys, WebView always consumes the keys in the normal flow
+ * or if {@link #shouldOverrideKeyEvent} returns {@code true}. This is called asynchronously
+ * from where the key is dispatched. It gives the host application a chance
+ * to handle the unhandled key events.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param event The key event.
+ */
+ public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
+ onUnhandledInputEventInternal(view, event);
+ }
+
+ /**
+ * Notify the host application that a input event was not handled by the WebView.
+ * Except system keys, WebView always consumes input events in the normal flow
+ * or if {@link #shouldOverrideKeyEvent} returns {@code true}. This is called asynchronously
+ * from where the event is dispatched. It gives the host application a chance
+ * to handle the unhandled input events.
+ *
+ * Note that if the event is a {@link android.view.MotionEvent}, then it's lifetime is only
+ * that of the function call. If the WebViewClient wishes to use the event beyond that, then it
+ * <i>must</i> create a copy of the event.
+ *
+ * It is the responsibility of overriders of this method to call
+ * {@link #onUnhandledKeyEvent(WebView, KeyEvent)}
+ * when appropriate if they wish to continue receiving events through it.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param event The input event.
+ * @removed
+ */
+ public void onUnhandledInputEvent(WebView view, InputEvent event) {
+ if (event instanceof KeyEvent) {
+ onUnhandledKeyEvent(view, (KeyEvent) event);
+ return;
+ }
+ onUnhandledInputEventInternal(view, event);
+ }
+
+ private void onUnhandledInputEventInternal(WebView view, InputEvent event) {
+ ViewRootImpl root = view.getViewRootImpl();
+ if (root != null) {
+ root.dispatchUnhandledInputEvent(event);
+ }
+ }
+
+ /**
+ * Notify the host application that the scale applied to the WebView has
+ * changed.
+ *
+ * @param view The WebView that is initiating the callback.
+ * @param oldScale The old scale factor
+ * @param newScale The new scale factor
+ */
+ public void onScaleChanged(WebView view, float oldScale, float newScale) {
+ }
+
+ /**
+ * Notify the host application that a request to automatically log in the
+ * user has been processed.
+ * @param view The WebView requesting the login.
+ * @param realm The account realm used to look up accounts.
+ * @param account An optional account. If not {@code null}, the account should be
+ * checked against accounts on the device. If it is a valid
+ * account, it should be used to log in the user.
+ * @param args Authenticator specific arguments used to log in the user.
+ */
+ public void onReceivedLoginRequest(WebView view, String realm,
+ @Nullable String account, String args) {
+ }
+
+ /**
+ * Notify host application that the given WebView's render process has exited.
+ *
+ * Multiple WebView instances may be associated with a single render process;
+ * onRenderProcessGone will be called for each WebView that was affected.
+ * The application's implementation of this callback should only attempt to
+ * clean up the specific WebView given as a parameter, and should not assume
+ * that other WebView instances are affected.
+ *
+ * The given WebView can't be used, and should be removed from the view hierarchy,
+ * all references to it should be cleaned up, e.g any references in the Activity
+ * or other classes saved using {@link android.view.View#findViewById} and similar calls, etc.
+ *
+ * To cause an render process crash for test purpose, the application can
+ * call {@code loadUrl("chrome://crash")} on the WebView. Note that multiple WebView
+ * instances may be affected if they share a render process, not just the
+ * specific WebView which loaded chrome://crash.
+ *
+ * @param view The WebView which needs to be cleaned up.
+ * @param detail the reason why it exited.
+ * @return {@code true} if the host application handled the situation that process has
+ * exited, otherwise, application will crash if render process crashed,
+ * or be killed if render process was killed by the system.
+ */
+ public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail) {
+ return false;
+ }
+
+ /**
+ * Notify the host application that a loading URL has been flagged by Safe Browsing.
+ *
+ * The application must invoke the callback to indicate the preferred response. The default
+ * behavior is to show an interstitial to the user, with the reporting checkbox visible.
+ *
+ * If the application needs to show its own custom interstitial UI, the callback can be invoked
+ * asynchronously with {@link SafeBrowsingResponse#backToSafety} or {@link
+ * SafeBrowsingResponse#proceed}, depending on user response.
+ *
+ * @param view The WebView that hit the malicious resource.
+ * @param request Object containing the details of the request.
+ * @param threatType The reason the resource was caught by Safe Browsing, corresponding to a
+ * {@code SAFE_BROWSING_THREAT_*} value.
+ * @param callback Applications must invoke one of the callback methods.
+ */
+ public void onSafeBrowsingHit(WebView view, WebResourceRequest request,
+ @SafeBrowsingThreat int threatType, SafeBrowsingResponse callback) {
+ callback.showInterstitial(/* allowReporting */ true);
+ }
}
diff --git a/android/webkit/WebViewFactory.java b/android/webkit/WebViewFactory.java
index b3522ec..e9fe481 100644
--- a/android/webkit/WebViewFactory.java
+++ b/android/webkit/WebViewFactory.java
@@ -27,7 +27,6 @@
import android.content.pm.Signature;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.StrictMode;
import android.os.Trace;
import android.util.AndroidRuntimeException;
import android.util.ArraySet;
@@ -251,7 +250,6 @@
"WebView.disableWebView() was called: WebView is disabled");
}
- StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getProvider()");
try {
Class<WebViewFactoryProvider> providerClass = getProviderClass();
@@ -279,7 +277,6 @@
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
- StrictMode.setThreadPolicy(oldPolicy);
}
}
}
diff --git a/android/webkit/WebViewFactoryProvider.java b/android/webkit/WebViewFactoryProvider.java
index 3ced6a5..4f7cdab 100644
--- a/android/webkit/WebViewFactoryProvider.java
+++ b/android/webkit/WebViewFactoryProvider.java
@@ -172,4 +172,10 @@
* @return the singleton WebViewDatabase instance
*/
WebViewDatabase getWebViewDatabase(Context context);
+
+ /**
+ * Gets the classloader used to load internal WebView implementation classes. This interface
+ * should only be used by the WebView Support Library.
+ */
+ ClassLoader getWebViewClassLoader();
}