18233facddcc51865d612a919d450db6954aa48e3Michael Kolb/* 28233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Copyright (C) 2010 The Android Open Source Project 38233facddcc51865d612a919d450db6954aa48e3Michael Kolb * 48233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License"); 58233facddcc51865d612a919d450db6954aa48e3Michael Kolb * you may not use this file except in compliance with the License. 68233facddcc51865d612a919d450db6954aa48e3Michael Kolb * You may obtain a copy of the License at 78233facddcc51865d612a919d450db6954aa48e3Michael Kolb * 88233facddcc51865d612a919d450db6954aa48e3Michael Kolb * http://www.apache.org/licenses/LICENSE-2.0 98233facddcc51865d612a919d450db6954aa48e3Michael Kolb * 108233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Unless required by applicable law or agreed to in writing, software 118233facddcc51865d612a919d450db6954aa48e3Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS, 128233facddcc51865d612a919d450db6954aa48e3Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138233facddcc51865d612a919d450db6954aa48e3Michael Kolb * See the License for the specific language governing permissions and 148233facddcc51865d612a919d450db6954aa48e3Michael Kolb * limitations under the License. 158233facddcc51865d612a919d450db6954aa48e3Michael Kolb */ 168233facddcc51865d612a919d450db6954aa48e3Michael Kolb 178233facddcc51865d612a919d450db6954aa48e3Michael Kolb 188233facddcc51865d612a919d450db6954aa48e3Michael Kolbpackage com.android.browser; 198233facddcc51865d612a919d450db6954aa48e3Michael Kolb 208233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.Activity; 218233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.SearchManager; 228233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.ContentResolver; 238233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.Context; 248233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.Intent; 258233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.net.Uri; 26fd77aaaa6b1b79ba0438a78e357aa877552830b1Jeff Hamiltonimport android.nfc.NfcAdapter; 278233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.os.AsyncTask; 288233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.os.Bundle; 298233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.provider.Browser; 308233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.provider.MediaStore; 318233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.text.TextUtils; 328233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.util.Patterns; 338233facddcc51865d612a919d450db6954aa48e3Michael Kolb 34315d502edce27bb4e93e53134f1a43b8f5c45588Michael Kolbimport com.android.browser.UI.ComboViews; 35e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolbimport com.android.browser.search.SearchEngine; 36e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolbimport com.android.common.Search; 37e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb 388233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport java.util.HashMap; 398233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport java.util.Iterator; 408233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport java.util.Map; 418233facddcc51865d612a919d450db6954aa48e3Michael Kolb 428233facddcc51865d612a919d450db6954aa48e3Michael Kolb/** 438233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Handle all browser related intents 448233facddcc51865d612a919d450db6954aa48e3Michael Kolb */ 458233facddcc51865d612a919d450db6954aa48e3Michael Kolbpublic class IntentHandler { 468233facddcc51865d612a919d450db6954aa48e3Michael Kolb 478233facddcc51865d612a919d450db6954aa48e3Michael Kolb // "source" parameter for Google search suggested by the browser 488233facddcc51865d612a919d450db6954aa48e3Michael Kolb final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest"; 498233facddcc51865d612a919d450db6954aa48e3Michael Kolb // "source" parameter for Google search from unknown source 508233facddcc51865d612a919d450db6954aa48e3Michael Kolb final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown"; 518233facddcc51865d612a919d450db6954aa48e3Michael Kolb 528233facddcc51865d612a919d450db6954aa48e3Michael Kolb /* package */ static final UrlData EMPTY_URL_DATA = new UrlData(null); 538233facddcc51865d612a919d450db6954aa48e3Michael Kolb 548233facddcc51865d612a919d450db6954aa48e3Michael Kolb private Activity mActivity; 558233facddcc51865d612a919d450db6954aa48e3Michael Kolb private Controller mController; 568233facddcc51865d612a919d450db6954aa48e3Michael Kolb private TabControl mTabControl; 578233facddcc51865d612a919d450db6954aa48e3Michael Kolb private BrowserSettings mSettings; 588233facddcc51865d612a919d450db6954aa48e3Michael Kolb 598233facddcc51865d612a919d450db6954aa48e3Michael Kolb public IntentHandler(Activity browser, Controller controller) { 608233facddcc51865d612a919d450db6954aa48e3Michael Kolb mActivity = browser; 618233facddcc51865d612a919d450db6954aa48e3Michael Kolb mController = controller; 628233facddcc51865d612a919d450db6954aa48e3Michael Kolb mTabControl = mController.getTabControl(); 638233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSettings = controller.getSettings(); 648233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 658233facddcc51865d612a919d450db6954aa48e3Michael Kolb 668233facddcc51865d612a919d450db6954aa48e3Michael Kolb void onNewIntent(Intent intent) { 678233facddcc51865d612a919d450db6954aa48e3Michael Kolb Tab current = mTabControl.getCurrentTab(); 688233facddcc51865d612a919d450db6954aa48e3Michael Kolb // When a tab is closed on exit, the current tab index is set to -1. 698233facddcc51865d612a919d450db6954aa48e3Michael Kolb // Reset before proceed as Browser requires the current tab to be set. 708233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (current == null) { 718233facddcc51865d612a919d450db6954aa48e3Michael Kolb // Try to reset the tab in case the index was incorrect. 728233facddcc51865d612a919d450db6954aa48e3Michael Kolb current = mTabControl.getTab(0); 738233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (current == null) { 748233facddcc51865d612a919d450db6954aa48e3Michael Kolb // No tabs at all so just ignore this intent. 758233facddcc51865d612a919d450db6954aa48e3Michael Kolb return; 768233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 778233facddcc51865d612a919d450db6954aa48e3Michael Kolb mController.setActiveTab(current); 788233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 798233facddcc51865d612a919d450db6954aa48e3Michael Kolb final String action = intent.getAction(); 808233facddcc51865d612a919d450db6954aa48e3Michael Kolb final int flags = intent.getFlags(); 818233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (Intent.ACTION_MAIN.equals(action) || 828233facddcc51865d612a919d450db6954aa48e3Michael Kolb (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) { 838233facddcc51865d612a919d450db6954aa48e3Michael Kolb // just resume the browser 848233facddcc51865d612a919d450db6954aa48e3Michael Kolb return; 858233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 86439c9a58765aa6aab95d55422ee61ea8360e912dJohn Reck if (BrowserActivity.ACTION_SHOW_BOOKMARKS.equals(action)) { 87315d502edce27bb4e93e53134f1a43b8f5c45588Michael Kolb mController.bookmarksOrHistoryPicker(ComboViews.Bookmarks); 88439c9a58765aa6aab95d55422ee61ea8360e912dJohn Reck return; 89439c9a58765aa6aab95d55422ee61ea8360e912dJohn Reck } 9007af2b8ae04c6e4385e41e0c559280a995eb8035John Reck 918233facddcc51865d612a919d450db6954aa48e3Michael Kolb // In case the SearchDialog is open. 928233facddcc51865d612a919d450db6954aa48e3Michael Kolb ((SearchManager) mActivity.getSystemService(Context.SEARCH_SERVICE)) 938233facddcc51865d612a919d450db6954aa48e3Michael Kolb .stopSearch(); 948233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (Intent.ACTION_VIEW.equals(action) 95fd77aaaa6b1b79ba0438a78e357aa877552830b1Jeff Hamilton || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action) 968233facddcc51865d612a919d450db6954aa48e3Michael Kolb || Intent.ACTION_SEARCH.equals(action) 978233facddcc51865d612a919d450db6954aa48e3Michael Kolb || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action) 985ff5c8b88968fa794eab4b7a263cae25f05bd4d3Michael Kolb || Intent.ACTION_WEB_SEARCH.equals(action)) { 998233facddcc51865d612a919d450db6954aa48e3Michael Kolb // If this was a search request (e.g. search query directly typed into the address bar), 1008233facddcc51865d612a919d450db6954aa48e3Michael Kolb // pass it on to the default web search provider. 1018233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (handleWebSearchIntent(mActivity, mController, intent)) { 1028233facddcc51865d612a919d450db6954aa48e3Michael Kolb return; 1038233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1048233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1058233facddcc51865d612a919d450db6954aa48e3Michael Kolb UrlData urlData = getUrlDataFromIntent(intent); 1068233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (urlData.isEmpty()) { 1078233facddcc51865d612a919d450db6954aa48e3Michael Kolb urlData = new UrlData(mSettings.getHomePage()); 1088233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1098233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1101461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb if (intent.getBooleanExtra(Browser.EXTRA_CREATE_NEW_TAB, false) 1111461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb || urlData.isPreloaded()) { 1121461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb Tab t = mController.openTab(urlData); 1132ed6e31fc7224313d668f8edcb4c9473f4710801Leon Scroggins return; 1142ed6e31fc7224313d668f8edcb4c9473f4710801Leon Scroggins } 115db22ec4ee014900988062d910bc810172a07df56John Reck /* 116db22ec4ee014900988062d910bc810172a07df56John Reck * TODO: Don't allow javascript URIs 117db22ec4ee014900988062d910bc810172a07df56John Reck * 0) If this is a javascript: URI, *always* open a new tab 1185ff5c8b88968fa794eab4b7a263cae25f05bd4d3Michael Kolb * 1) If the URL is already opened, switch to that tab 1195ff5c8b88968fa794eab4b7a263cae25f05bd4d3Michael Kolb * 2-phone) Reuse tab with same appId 1205ff5c8b88968fa794eab4b7a263cae25f05bd4d3Michael Kolb * 2-tablet) Open new tab 121db22ec4ee014900988062d910bc810172a07df56John Reck */ 1228233facddcc51865d612a919d450db6954aa48e3Michael Kolb final String appId = intent 1238233facddcc51865d612a919d450db6954aa48e3Michael Kolb .getStringExtra(Browser.EXTRA_APPLICATION_ID); 12426b183292dc087b16af10f482744c3bb30e1f163John Reck if (!TextUtils.isEmpty(urlData.mUrl) && 12526b183292dc087b16af10f482744c3bb30e1f163John Reck urlData.mUrl.startsWith("javascript:")) { 12626b183292dc087b16af10f482744c3bb30e1f163John Reck // Always open javascript: URIs in new tabs 12726b183292dc087b16af10f482744c3bb30e1f163John Reck mController.openTab(urlData); 12826b183292dc087b16af10f482744c3bb30e1f163John Reck return; 12926b183292dc087b16af10f482744c3bb30e1f163John Reck } 130f1286a455eeacd02dfcca1335e6a7a9f87433c1bMichael Kolb if (Intent.ACTION_VIEW.equals(action) 131f1286a455eeacd02dfcca1335e6a7a9f87433c1bMichael Kolb && (appId != null) 132f1286a455eeacd02dfcca1335e6a7a9f87433c1bMichael Kolb && appId.startsWith(mActivity.getPackageName())) { 133f1286a455eeacd02dfcca1335e6a7a9f87433c1bMichael Kolb Tab appTab = mTabControl.getTabFromAppId(appId); 134f1286a455eeacd02dfcca1335e6a7a9f87433c1bMichael Kolb if ((appTab != null) && (appTab == mController.getCurrentTab())) { 135f1286a455eeacd02dfcca1335e6a7a9f87433c1bMichael Kolb mController.switchToTab(appTab); 136f1286a455eeacd02dfcca1335e6a7a9f87433c1bMichael Kolb mController.loadUrlDataIn(appTab, urlData); 137f1286a455eeacd02dfcca1335e6a7a9f87433c1bMichael Kolb return; 138f1286a455eeacd02dfcca1335e6a7a9f87433c1bMichael Kolb } 139f1286a455eeacd02dfcca1335e6a7a9f87433c1bMichael Kolb } 1405ff5c8b88968fa794eab4b7a263cae25f05bd4d3Michael Kolb if (Intent.ACTION_VIEW.equals(action) 1415ff5c8b88968fa794eab4b7a263cae25f05bd4d3Michael Kolb && !mActivity.getPackageName().equals(appId)) { 1428d772b03fcfd83cea6ec81c9e826f700fac88b61Michael Kolb if (!BrowserActivity.isTablet(mActivity) 1438d772b03fcfd83cea6ec81c9e826f700fac88b61Michael Kolb && !mSettings.allowAppTabs()) { 144c831b63308dd1f8ef71808db8344ca2566ba4ed4Michael Kolb Tab appTab = mTabControl.getTabFromAppId(appId); 145af0d334f54395798d44e300c5f4733af7d477bbeMichael Kolb if (appTab != null) { 14626b183292dc087b16af10f482744c3bb30e1f163John Reck mController.reuseTab(appTab, urlData); 147af0d334f54395798d44e300c5f4733af7d477bbeMichael Kolb return; 148af0d334f54395798d44e300c5f4733af7d477bbeMichael Kolb } 149db22ec4ee014900988062d910bc810172a07df56John Reck } 150db22ec4ee014900988062d910bc810172a07df56John Reck // No matching application tab, try to find a regular tab 151db22ec4ee014900988062d910bc810172a07df56John Reck // with a matching url. 152db22ec4ee014900988062d910bc810172a07df56John Reck Tab appTab = mTabControl.findTabWithUrl(urlData.mUrl); 153db22ec4ee014900988062d910bc810172a07df56John Reck if (appTab != null) { 154db22ec4ee014900988062d910bc810172a07df56John Reck // Transfer ownership 155db22ec4ee014900988062d910bc810172a07df56John Reck appTab.setAppId(appId); 156db22ec4ee014900988062d910bc810172a07df56John Reck if (current != appTab) { 157db22ec4ee014900988062d910bc810172a07df56John Reck mController.switchToTab(appTab); 158db22ec4ee014900988062d910bc810172a07df56John Reck } 159db22ec4ee014900988062d910bc810172a07df56John Reck // Otherwise, we are already viewing the correct tab. 1608233facddcc51865d612a919d450db6954aa48e3Michael Kolb } else { 161db22ec4ee014900988062d910bc810172a07df56John Reck // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url 162db22ec4ee014900988062d910bc810172a07df56John Reck // will be opened in a new tab unless we have reached 163db22ec4ee014900988062d910bc810172a07df56John Reck // MAX_TABS. Then the url will be opened in the current 164db22ec4ee014900988062d910bc810172a07df56John Reck // tab. If a new tab is created, it will have "true" for 165db22ec4ee014900988062d910bc810172a07df56John Reck // exit on close. 166db22ec4ee014900988062d910bc810172a07df56John Reck Tab tab = mController.openTab(urlData); 167db22ec4ee014900988062d910bc810172a07df56John Reck if (tab != null) { 168db22ec4ee014900988062d910bc810172a07df56John Reck tab.setAppId(appId); 169e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb if ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) { 170e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb tab.setCloseOnBack(true); 171e28b347fcc1df6e6bd41cb294d521a4f1e7c5c75Michael Kolb } 1728233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1738233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1748233facddcc51865d612a919d450db6954aa48e3Michael Kolb } else { 1758233facddcc51865d612a919d450db6954aa48e3Michael Kolb // Get rid of the subwindow if it exists 1768233facddcc51865d612a919d450db6954aa48e3Michael Kolb mController.dismissSubWindow(current); 1778233facddcc51865d612a919d450db6954aa48e3Michael Kolb // If the current Tab is being used as an application tab, 1788233facddcc51865d612a919d450db6954aa48e3Michael Kolb // remove the association, since the new Intent means that it is 1798233facddcc51865d612a919d450db6954aa48e3Michael Kolb // no longer associated with that application. 1808233facddcc51865d612a919d450db6954aa48e3Michael Kolb current.setAppId(null); 1818233facddcc51865d612a919d450db6954aa48e3Michael Kolb mController.loadUrlDataIn(current, urlData); 1828233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1838233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1848233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1858233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1861461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb protected static UrlData getUrlDataFromIntent(Intent intent) { 1878233facddcc51865d612a919d450db6954aa48e3Michael Kolb String url = ""; 1888233facddcc51865d612a919d450db6954aa48e3Michael Kolb Map<String, String> headers = null; 18929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood PreloadedTabControl preloaded = null; 19029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood String preloadedSearchBoxQuery = null; 191e1cab10c8690fbafa7765271621cce2b3961b9e8Leon Scroggins if (intent != null 192e1cab10c8690fbafa7765271621cce2b3961b9e8Leon Scroggins && (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) { 1938233facddcc51865d612a919d450db6954aa48e3Michael Kolb final String action = intent.getAction(); 194fd77aaaa6b1b79ba0438a78e357aa877552830b1Jeff Hamilton if (Intent.ACTION_VIEW.equals(action) || 195fd77aaaa6b1b79ba0438a78e357aa877552830b1Jeff Hamilton NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) { 1968233facddcc51865d612a919d450db6954aa48e3Michael Kolb url = UrlUtils.smartUrlFilter(intent.getData()); 1978233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (url != null && url.startsWith("http")) { 1988233facddcc51865d612a919d450db6954aa48e3Michael Kolb final Bundle pairs = intent 1998233facddcc51865d612a919d450db6954aa48e3Michael Kolb .getBundleExtra(Browser.EXTRA_HEADERS); 2008233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (pairs != null && !pairs.isEmpty()) { 2018233facddcc51865d612a919d450db6954aa48e3Michael Kolb Iterator<String> iter = pairs.keySet().iterator(); 2028233facddcc51865d612a919d450db6954aa48e3Michael Kolb headers = new HashMap<String, String>(); 2038233facddcc51865d612a919d450db6954aa48e3Michael Kolb while (iter.hasNext()) { 2048233facddcc51865d612a919d450db6954aa48e3Michael Kolb String key = iter.next(); 2058233facddcc51865d612a919d450db6954aa48e3Michael Kolb headers.put(key, pairs.getString(key)); 2068233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2078233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2088233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2091461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb if (intent.hasExtra(PreloadRequestReceiver.EXTRA_PRELOAD_ID)) { 2101461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb String id = intent.getStringExtra(PreloadRequestReceiver.EXTRA_PRELOAD_ID); 21129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood preloadedSearchBoxQuery = intent.getStringExtra( 21229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood PreloadRequestReceiver.EXTRA_SEARCHBOX_SETQUERY); 2131461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb preloaded = Preloader.getInstance().getPreloadedTab(id); 2141461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb } 2158233facddcc51865d612a919d450db6954aa48e3Michael Kolb } else if (Intent.ACTION_SEARCH.equals(action) 2168233facddcc51865d612a919d450db6954aa48e3Michael Kolb || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action) 2178233facddcc51865d612a919d450db6954aa48e3Michael Kolb || Intent.ACTION_WEB_SEARCH.equals(action)) { 2188233facddcc51865d612a919d450db6954aa48e3Michael Kolb url = intent.getStringExtra(SearchManager.QUERY); 2198233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (url != null) { 2208233facddcc51865d612a919d450db6954aa48e3Michael Kolb // In general, we shouldn't modify URL from Intent. 2218233facddcc51865d612a919d450db6954aa48e3Michael Kolb // But currently, we get the user-typed URL from search box as well. 2228233facddcc51865d612a919d450db6954aa48e3Michael Kolb url = UrlUtils.fixUrl(url); 2238233facddcc51865d612a919d450db6954aa48e3Michael Kolb url = UrlUtils.smartUrlFilter(url); 2248233facddcc51865d612a919d450db6954aa48e3Michael Kolb String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&"; 2258233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (url.contains(searchSource)) { 2268233facddcc51865d612a919d450db6954aa48e3Michael Kolb String source = null; 2278233facddcc51865d612a919d450db6954aa48e3Michael Kolb final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA); 2288233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (appData != null) { 2298233facddcc51865d612a919d450db6954aa48e3Michael Kolb source = appData.getString(Search.SOURCE); 2308233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2318233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (TextUtils.isEmpty(source)) { 2328233facddcc51865d612a919d450db6954aa48e3Michael Kolb source = GOOGLE_SEARCH_SOURCE_UNKNOWN; 2338233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2348233facddcc51865d612a919d450db6954aa48e3Michael Kolb url = url.replace(searchSource, "&source=android-"+source+"&"); 2358233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2368233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2378233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2388233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2399ad1eac377ffa6ffd34afae4c6580b7ba7508c31Mathew Inwood return new UrlData(url, headers, intent, preloaded, preloadedSearchBoxQuery); 2408233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2418233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2428233facddcc51865d612a919d450db6954aa48e3Michael Kolb /** 2438233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Launches the default web search activity with the query parameters if the given intent's data 2448233facddcc51865d612a919d450db6954aa48e3Michael Kolb * are identified as plain search terms and not URLs/shortcuts. 2458233facddcc51865d612a919d450db6954aa48e3Michael Kolb * @return true if the intent was handled and web search activity was launched, false if not. 2468233facddcc51865d612a919d450db6954aa48e3Michael Kolb */ 2478233facddcc51865d612a919d450db6954aa48e3Michael Kolb static boolean handleWebSearchIntent(Activity activity, 2488233facddcc51865d612a919d450db6954aa48e3Michael Kolb Controller controller, Intent intent) { 2498233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (intent == null) return false; 2508233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2518233facddcc51865d612a919d450db6954aa48e3Michael Kolb String url = null; 2528233facddcc51865d612a919d450db6954aa48e3Michael Kolb final String action = intent.getAction(); 2538233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (Intent.ACTION_VIEW.equals(action)) { 2548233facddcc51865d612a919d450db6954aa48e3Michael Kolb Uri data = intent.getData(); 2558233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (data != null) url = data.toString(); 2568233facddcc51865d612a919d450db6954aa48e3Michael Kolb } else if (Intent.ACTION_SEARCH.equals(action) 2578233facddcc51865d612a919d450db6954aa48e3Michael Kolb || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action) 2588233facddcc51865d612a919d450db6954aa48e3Michael Kolb || Intent.ACTION_WEB_SEARCH.equals(action)) { 2598233facddcc51865d612a919d450db6954aa48e3Michael Kolb url = intent.getStringExtra(SearchManager.QUERY); 2608233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2618233facddcc51865d612a919d450db6954aa48e3Michael Kolb return handleWebSearchRequest(activity, controller, url, 2628233facddcc51865d612a919d450db6954aa48e3Michael Kolb intent.getBundleExtra(SearchManager.APP_DATA), 2638233facddcc51865d612a919d450db6954aa48e3Michael Kolb intent.getStringExtra(SearchManager.EXTRA_DATA_KEY)); 2648233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2658233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2668233facddcc51865d612a919d450db6954aa48e3Michael Kolb /** 2678233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Launches the default web search activity with the query parameters if the given url string 2688233facddcc51865d612a919d450db6954aa48e3Michael Kolb * was identified as plain search terms and not URL/shortcut. 2698233facddcc51865d612a919d450db6954aa48e3Michael Kolb * @return true if the request was handled and web search activity was launched, false if not. 2708233facddcc51865d612a919d450db6954aa48e3Michael Kolb */ 2718233facddcc51865d612a919d450db6954aa48e3Michael Kolb private static boolean handleWebSearchRequest(Activity activity, 2728233facddcc51865d612a919d450db6954aa48e3Michael Kolb Controller controller, String inUrl, Bundle appData, 2738233facddcc51865d612a919d450db6954aa48e3Michael Kolb String extraData) { 274991412749b1e0837ab602d77a2264a2186741a05John Reck if (inUrl == null) return false; 2758233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2768233facddcc51865d612a919d450db6954aa48e3Michael Kolb // In general, we shouldn't modify URL from Intent. 2778233facddcc51865d612a919d450db6954aa48e3Michael Kolb // But currently, we get the user-typed URL from search box as well. 2788233facddcc51865d612a919d450db6954aa48e3Michael Kolb String url = UrlUtils.fixUrl(inUrl).trim(); 279991412749b1e0837ab602d77a2264a2186741a05John Reck if (TextUtils.isEmpty(url)) return false; 2808233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2818233facddcc51865d612a919d450db6954aa48e3Michael Kolb // URLs are handled by the regular flow of control, so 2828233facddcc51865d612a919d450db6954aa48e3Michael Kolb // return early. 2838233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (Patterns.WEB_URL.matcher(url).matches() 2848233facddcc51865d612a919d450db6954aa48e3Michael Kolb || UrlUtils.ACCEPTED_URI_SCHEMA.matcher(url).matches()) { 2858233facddcc51865d612a919d450db6954aa48e3Michael Kolb return false; 2868233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2878233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2888233facddcc51865d612a919d450db6954aa48e3Michael Kolb final ContentResolver cr = activity.getContentResolver(); 2898233facddcc51865d612a919d450db6954aa48e3Michael Kolb final String newUrl = url; 2908233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (controller == null || controller.getTabControl() == null 2918233facddcc51865d612a919d450db6954aa48e3Michael Kolb || controller.getTabControl().getCurrentWebView() == null 2928233facddcc51865d612a919d450db6954aa48e3Michael Kolb || !controller.getTabControl().getCurrentWebView() 2938233facddcc51865d612a919d450db6954aa48e3Michael Kolb .isPrivateBrowsingEnabled()) { 2948233facddcc51865d612a919d450db6954aa48e3Michael Kolb new AsyncTask<Void, Void, Void>() { 2958233facddcc51865d612a919d450db6954aa48e3Michael Kolb @Override 2968233facddcc51865d612a919d450db6954aa48e3Michael Kolb protected Void doInBackground(Void... unused) { 2978233facddcc51865d612a919d450db6954aa48e3Michael Kolb Browser.addSearchUrl(cr, newUrl); 2988233facddcc51865d612a919d450db6954aa48e3Michael Kolb return null; 2998233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 3008233facddcc51865d612a919d450db6954aa48e3Michael Kolb }.execute(); 3018233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 3028233facddcc51865d612a919d450db6954aa48e3Michael Kolb 3038233facddcc51865d612a919d450db6954aa48e3Michael Kolb SearchEngine searchEngine = BrowserSettings.getInstance().getSearchEngine(); 3048233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (searchEngine == null) return false; 3058233facddcc51865d612a919d450db6954aa48e3Michael Kolb searchEngine.startSearch(activity, url, appData, extraData); 3068233facddcc51865d612a919d450db6954aa48e3Michael Kolb 3078233facddcc51865d612a919d450db6954aa48e3Michael Kolb return true; 3088233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 3098233facddcc51865d612a919d450db6954aa48e3Michael Kolb 3108233facddcc51865d612a919d450db6954aa48e3Michael Kolb /** 3118233facddcc51865d612a919d450db6954aa48e3Michael Kolb * A UrlData class to abstract how the content will be set to WebView. 3128233facddcc51865d612a919d450db6954aa48e3Michael Kolb * This base class uses loadUrl to show the content. 3138233facddcc51865d612a919d450db6954aa48e3Michael Kolb */ 3148233facddcc51865d612a919d450db6954aa48e3Michael Kolb static class UrlData { 3158233facddcc51865d612a919d450db6954aa48e3Michael Kolb final String mUrl; 3168233facddcc51865d612a919d450db6954aa48e3Michael Kolb final Map<String, String> mHeaders; 31729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood final PreloadedTabControl mPreloadedTab; 31829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood final String mSearchBoxQueryToSubmit; 31938b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck final boolean mDisableUrlOverride; 3208233facddcc51865d612a919d450db6954aa48e3Michael Kolb 3218233facddcc51865d612a919d450db6954aa48e3Michael Kolb UrlData(String url) { 3228233facddcc51865d612a919d450db6954aa48e3Michael Kolb this.mUrl = url; 3238233facddcc51865d612a919d450db6954aa48e3Michael Kolb this.mHeaders = null; 3241461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb this.mPreloadedTab = null; 32529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood this.mSearchBoxQueryToSubmit = null; 32638b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck this.mDisableUrlOverride = false; 3278233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 3288233facddcc51865d612a919d450db6954aa48e3Michael Kolb 3298233facddcc51865d612a919d450db6954aa48e3Michael Kolb UrlData(String url, Map<String, String> headers, Intent intent) { 3309ad1eac377ffa6ffd34afae4c6580b7ba7508c31Mathew Inwood this(url, headers, intent, null, null); 3311461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb } 3321461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb 33329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood UrlData(String url, Map<String, String> headers, Intent intent, 3349ad1eac377ffa6ffd34afae4c6580b7ba7508c31Mathew Inwood PreloadedTabControl preloaded, String searchBoxQueryToSubmit) { 3358233facddcc51865d612a919d450db6954aa48e3Michael Kolb this.mUrl = url; 3368233facddcc51865d612a919d450db6954aa48e3Michael Kolb this.mHeaders = headers; 33729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood this.mPreloadedTab = preloaded; 33829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood this.mSearchBoxQueryToSubmit = searchBoxQueryToSubmit; 33938b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck if (intent != null) { 34038b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck mDisableUrlOverride = intent.getBooleanExtra( 34138b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck BrowserActivity.EXTRA_DISABLE_URL_OVERRIDE, false); 34238b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck } else { 34338b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck mDisableUrlOverride = false; 34438b3965028e4ac433de9d43c02d3167ff0ef208cJohn Reck } 3458233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 3468233facddcc51865d612a919d450db6954aa48e3Michael Kolb 3478233facddcc51865d612a919d450db6954aa48e3Michael Kolb boolean isEmpty() { 3485ff5c8b88968fa794eab4b7a263cae25f05bd4d3Michael Kolb return (mUrl == null || mUrl.length() == 0); 3498233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 3501461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb 3511461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb boolean isPreloaded() { 3521461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb return mPreloadedTab != null; 3531461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb } 3541461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb 35529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood PreloadedTabControl getPreloadedTab() { 3561461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb return mPreloadedTab; 3571461244018a225006a8d4c203f9dfe294ffe94faMichael Kolb } 35829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 35929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood String getSearchBoxQueryToSubmit() { 36029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood return mSearchBoxQueryToSubmit; 36129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 3628233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 3638233facddcc51865d612a919d450db6954aa48e3Michael Kolb 3648233facddcc51865d612a919d450db6954aa48e3Michael Kolb} 365