blob: e110160553c7c14487f5e49657a961ae8c734e18 [file] [log] [blame]
John Reckfb3017f2010-10-26 19:01:24 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Michael Kolb8233fac2010-10-26 16:08:53 -070016
Bijan Amirzada41242f22014-03-21 12:12:18 -070017package com.android.browser;
John Reckfb3017f2010-10-26 19:01:24 -070018
Michael Kolb8233fac2010-10-26 16:08:53 -070019import android.net.Uri;
Sagar Dhawanef06f562015-09-07 15:23:22 +020020import android.text.TextUtils;
Michael Kolb8233fac2010-10-26 16:08:53 -070021import android.util.Patterns;
22import android.webkit.URLUtil;
23
Sagar Dhawanef06f562015-09-07 15:23:22 +020024import org.codeaurora.swe.util.SWEUrlUtils;
25
John Reckfb3017f2010-10-26 19:01:24 -070026import java.util.regex.Matcher;
27import java.util.regex.Pattern;
Vivek Sekharcc4bc5e2014-05-13 12:46:37 -070028import java.util.HashSet;
29import java.util.Arrays;
Tarun Nainani8eb00912014-07-17 12:28:32 -070030import java.net.URI;
John Reckfb3017f2010-10-26 19:01:24 -070031
Michael Kolb8233fac2010-10-26 16:08:53 -070032/**
33 * Utility methods for Url manipulation
34 */
John Reckfb3017f2010-10-26 19:01:24 -070035public class UrlUtils {
Sagar Dhawanef06f562015-09-07 15:23:22 +020036 // Urls defined by the browser should not be "fixedup" via the engine
37 // Urls are only handled by the browser
38 private static final String BROWSER_URLS[] = {
39 "about:debug",
40 };
Vivek Sekharcc4bc5e2014-05-13 12:46:37 -070041 public static final String[] DOWNLOADABLE_SCHEMES_VALUES = new String[]
42 { "data", "filesystem", "http", "https" };
43
44 private static final HashSet<String> DOWNLOADABLE_SCHEMES =
45 new HashSet<String>(Arrays.asList(DOWNLOADABLE_SCHEMES_VALUES));
John Reckfb3017f2010-10-26 19:01:24 -070046
Tarun Nainani8eb00912014-07-17 12:28:32 -070047 // Schemes for which the LIVE_MENU items defined in res/menu/browser.xml
48 // should be enabled
49 public static final String[] LIVE_SCHEMES_VALUES = new String[]
50 { "http", "https" };
51
52 private static final HashSet<String> LIVE_SCHEMES =
53 new HashSet<String>(Arrays.asList(LIVE_SCHEMES_VALUES));
54
Michael Kolb8233fac2010-10-26 16:08:53 -070055 static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
56 "(?i)" + // switch on case insensitive matching
57 "(" + // begin group for schema
Axesh R. Ajmera6fc73692015-08-11 16:32:10 -070058 "(?:http|https|file|chrome):\\/\\/" +
Patrick Scottb92bbb42011-01-05 11:38:58 -050059 "|(?:inline|data|about|javascript):" +
Michael Kolb8233fac2010-10-26 16:08:53 -070060 ")" +
61 "(.*)" );
62
63 // Google search
64 private final static String QUICKSEARCH_G = "http://www.google.com/m?q=%s";
65 private final static String QUERY_PLACE_HOLDER = "%s";
66
John Reckfe5b94d2011-09-06 10:21:29 -070067 // Regular expression to strip http:// and optionally
John Reck434e9f82011-08-10 18:16:52 -070068 // the trailing slash
69 private static final Pattern STRIP_URL_PATTERN =
John Reckfe5b94d2011-09-06 10:21:29 -070070 Pattern.compile("^http://(.*?)/?$");
John Reckfb3017f2010-10-26 19:01:24 -070071
72 private UrlUtils() { /* cannot be instantiated */ }
73
74 /**
John Reckfe5b94d2011-09-06 10:21:29 -070075 * Strips the provided url of preceding "http://" and any trailing "/". Does not
John Reckfb3017f2010-10-26 19:01:24 -070076 * strip "https://". If the provided string cannot be stripped, the original string
77 * is returned.
78 *
79 * TODO: Put this in TextUtils to be used by other packages doing something similar.
80 *
81 * @param url a url to strip, like "http://www.google.com/"
John Reckfe5b94d2011-09-06 10:21:29 -070082 * @return a stripped url like "www.google.com", or the original string if it could
John Reckfb3017f2010-10-26 19:01:24 -070083 * not be stripped
84 */
John Reck2cb9dc22011-05-11 16:12:27 -070085 public static String stripUrl(String url) {
John Reckfb3017f2010-10-26 19:01:24 -070086 if (url == null) return null;
87 Matcher m = STRIP_URL_PATTERN.matcher(url);
John Reck434e9f82011-08-10 18:16:52 -070088 if (m.matches()) {
89 return m.group(1);
John Reckfb3017f2010-10-26 19:01:24 -070090 } else {
91 return url;
92 }
93 }
Michael Kolb8233fac2010-10-26 16:08:53 -070094
95 protected static String smartUrlFilter(Uri inUri) {
96 if (inUri != null) {
97 return smartUrlFilter(inUri.toString());
98 }
99 return null;
100 }
101
102 /**
103 * Attempts to determine whether user input is a URL or search
104 * terms. Anything with a space is passed to search.
105 *
106 * Converts to lowercase any mistakenly uppercased schema (i.e.,
107 * "Http://" converts to "http://"
108 *
109 * @return Original or modified URL
110 *
111 */
John Reck961d35d2011-06-23 09:45:54 -0700112 public static String smartUrlFilter(String url) {
John Reck71e51422011-07-01 16:49:28 -0700113 return smartUrlFilter(url, true);
114 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700115
Vivek Sekharcc4bc5e2014-05-13 12:46:37 -0700116 public static boolean isDownloadableScheme(Uri uri) {
117 return DOWNLOADABLE_SCHEMES.contains(uri.getScheme());
118 }
119
120 public static boolean isDownloadableScheme(String uri) {
121 try {
Tarun Nainani8eb00912014-07-17 12:28:32 -0700122 URI uriObj = new URI(uri);
123 return isDownloadableScheme(Uri.parse(uriObj.toString()));
124 } catch (Exception e) {
125 return false;
126 }
127 }
128
129 public static boolean isLiveScheme(Uri uri) {
130 return LIVE_SCHEMES.contains(uri.getScheme());
131 }
132
133 public static boolean isLiveScheme(String uri) {
134 try {
135 return isLiveScheme(Uri.parse(uri));
Vivek Sekharcc4bc5e2014-05-13 12:46:37 -0700136 } catch (Exception e) {
137 return false;
138 }
139 }
140
John Reck71e51422011-07-01 16:49:28 -0700141 /**
142 * Attempts to determine whether user input is a URL or search
143 * terms. Anything with a space is passed to search if canBeSearch is true.
144 *
145 * Converts to lowercase any mistakenly uppercased schema (i.e.,
146 * "Http://" converts to "http://"
147 *
148 * @param canBeSearch If true, will return a search url if it isn't a valid
149 * URL. If false, invalid URLs will return null
150 * @return Original or modified URL
151 *
152 */
153 public static String smartUrlFilter(String url, boolean canBeSearch) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700154 String inUrl = url.trim();
155 boolean hasSpace = inUrl.indexOf(' ') != -1;
156
157 Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
158 if (matcher.matches()) {
159 // force scheme to lowercase
160 String scheme = matcher.group(1);
161 String lcScheme = scheme.toLowerCase();
162 if (!lcScheme.equals(scheme)) {
163 inUrl = lcScheme + matcher.group(2);
164 }
John Reck71e51422011-07-01 16:49:28 -0700165 if (hasSpace && Patterns.WEB_URL.matcher(inUrl).matches()) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700166 inUrl = inUrl.replace(" ", "%20");
167 }
168 return inUrl;
169 }
170 if (!hasSpace) {
171 if (Patterns.WEB_URL.matcher(inUrl).matches()) {
172 return URLUtil.guessUrl(inUrl);
173 }
174 }
John Reck71e51422011-07-01 16:49:28 -0700175 if (canBeSearch) {
176 return URLUtil.composeSearchUrl(inUrl,
177 QUICKSEARCH_G, QUERY_PLACE_HOLDER);
178 }
179 return null;
Michael Kolb8233fac2010-10-26 16:08:53 -0700180 }
181
Sagar Dhawanef06f562015-09-07 15:23:22 +0200182 public static String fixUpUrl(String url){
183 if (TextUtils.isEmpty(url))
184 return url;
185
186 for (String preDefined: BROWSER_URLS){
187 if (url.contains(preDefined)) {
188 return url;
189 }
190 }
191 return SWEUrlUtils.fixUpUrl(url);
192 }
193
194 @Deprecated // Use fixUpUrl instead
kaiyiz6e5b3e02013-08-19 20:02:01 +0800195 public static String fixUrl(String inUrl) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700196 // FIXME: Converting the url to lower case
197 // duplicates functionality in smartUrlFilter().
198 // However, changing all current callers of fixUrl to
199 // call smartUrlFilter in addition may have unwanted
200 // consequences, and is deferred for now.
201 int colon = inUrl.indexOf(':');
202 boolean allLower = true;
203 for (int index = 0; index < colon; index++) {
204 char ch = inUrl.charAt(index);
205 if (!Character.isLetter(ch)) {
206 break;
207 }
208 allLower &= Character.isLowerCase(ch);
209 if (index == colon - 1 && !allLower) {
210 inUrl = inUrl.substring(0, colon).toLowerCase()
211 + inUrl.substring(colon);
212 }
213 }
214 if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
215 return inUrl;
216 if (inUrl.startsWith("http:") ||
217 inUrl.startsWith("https:")) {
218 if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
219 inUrl = inUrl.replaceFirst("/", "//");
220 } else inUrl = inUrl.replaceFirst(":", "://");
221 }
222 return inUrl;
223 }
224
John Reck324d4402011-01-11 16:56:42 -0800225 // Returns the filtered URL. Cannot return null, but can return an empty string
226 /* package */ static String filteredUrl(String inUrl) {
227 if (inUrl == null) {
228 return "";
229 }
Axesh R. Ajmera6fc73692015-08-11 16:32:10 -0700230 if (inUrl.startsWith("content:")
231 || inUrl.startsWith("browser:")) {
John Reck324d4402011-01-11 16:56:42 -0800232 return "";
233 }
234 return inUrl;
235 }
236
John Reckfb3017f2010-10-26 19:01:24 -0700237}