PreloadedTabControl.java revision a829d55e8af65d08d998b8166e42420dda8cf2ff
129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood/* 229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * Copyright (C) 2011 The Android Open Source Project 329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * 429721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * Licensed under the Apache License, Version 2.0 (the "License"); 529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * you may not use this file except in compliance with the License. 629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * You may obtain a copy of the License at 729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * 829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * http://www.apache.org/licenses/LICENSE-2.0 929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * 1029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * Unless required by applicable law or agreed to in writing, software 1129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * distributed under the License is distributed on an "AS IS" BASIS, 1229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * See the License for the specific language governing permissions and 1429721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * limitations under the License. 1529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood */ 1629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwoodpackage com.android.browser; 1729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 18e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwoodimport android.net.Uri; 1929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwoodimport android.text.TextUtils; 2029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwoodimport android.util.Log; 2129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwoodimport android.webkit.SearchBox; 2229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 2329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwoodimport java.util.Map; 24a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwoodimport java.util.regex.Pattern; 2529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 2629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood/** 2729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood * Class to manage the controlling of preloaded tab. 2829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood */ 2929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwoodpublic class PreloadedTabControl { 30e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood private static final boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED; 3129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood private static final String LOGTAG = "PreloadedTabControl"; 3229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 3329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood final Tab mTab; 3429721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood private String mLastQuery; 3529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood private boolean mDestroyed; 3629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 3729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood public PreloadedTabControl(Tab t) { 38e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "PreloadedTabControl.<init>"); 3929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood mTab = t; 4029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 4129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 42e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood private void maybeSetQuery(final String query, SearchBox sb) { 4329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood if (!TextUtils.equals(mLastQuery, query)) { 4429721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood if (sb != null) { 4529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "Changing searchbox query to " + query); 4629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood sb.setVerbatim(true); 4729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood sb.setQuery(query); 48e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood sb.onchange(new SearchBox.SearchBoxListener() { 49e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood @Override 50e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood public void onChangeComplete(boolean called) { 51e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (mDestroyed) return; 52e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "Changed searchbox query: " + called); 53e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (called) { 54e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood mLastQuery = query; 55e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood } 56e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood } 57e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood }); 5829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } else { 5929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "Cannot set query: no searchbox interface"); 6029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 6129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 6229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 6329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 6429721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood public void setQuery(String query) { 6529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood maybeSetQuery(query, mTab.getWebView().getSearchBox()); 6629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 6729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 6829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood public boolean searchBoxSubmit(final String query, 6929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood final String fallbackUrl, final Map<String, String> fallbackHeaders) { 7029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood final SearchBox sb = mTab.getWebView().getSearchBox(); 7129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood if (sb == null) { 7229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood // no searchbox, cannot submit. Fallback to regular tab creation 7329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "No searchbox, cannot submit query"); 7429721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood return false; 7529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 76e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood maybeSetQuery(query, sb); 77e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "Submitting query " + query); 78a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood final String currentUrl = mTab.getUrl(); 79e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood sb.onsubmit(new SearchBox.SearchBoxListener() { 8029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood @Override 81e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood public void onSubmitComplete(boolean called) { 82e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (mDestroyed) return; 83e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "Query submitted: " + called); 84e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (!called) { 85e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "Query not submitted; falling back"); 8629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood loadUrl(fallbackUrl, fallbackHeaders); 871dd8e82b74b1055fcd572e820a724997550edd33Mathew Inwood // make sure that the failed, preloaded URL is cleared from the back stack 88a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood mTab.clearBackStackWhenItemAdded(Pattern.compile( 89a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood "^" + Pattern.quote(fallbackUrl) + "$")); 90a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood } else { 91a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood // ignore the next fragment change, to avoid leaving a blank page in the browser 92a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood // after the query has been submitted. 93a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood String currentWithoutFragment = Uri.parse(currentUrl) 94a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood .buildUpon() 95a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood .fragment(null) 96a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood .toString(); 97a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood mTab.clearBackStackWhenItemAdded( 98a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood Pattern.compile( 99a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood "^" + 100a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood Pattern.quote(currentWithoutFragment) + 101a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood "(\\#.*)?" + 102a829d55e8af65d08d998b8166e42420dda8cf2ffMathew Inwood "$")); 10329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 104e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood }}); 10529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood return true; 10629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 10729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 108dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood public void searchBoxCancel() { 109dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood SearchBox sb = mTab.getWebView().getSearchBox(); 110dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood if (sb != null) { 111dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood mLastQuery = null; 112dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood sb.oncancel(new SearchBox.SearchBoxListener(){ 113dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood @Override 114dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood public void onCancelComplete(boolean called) { 115dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "Query cancelled: " + called); 116dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood } 117dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood }); 118dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood } 119dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood } 120dffa72f926d051c089981adf52a44d2c933a0de4Mathew Inwood 12129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood public void loadUrlIfChanged(String url, Map<String, String> headers) { 122e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood String currentUrl = mTab.getUrl(); 123e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (!TextUtils.isEmpty(currentUrl)) { 124e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood try { 125e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood // remove fragment: 126e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood currentUrl = Uri.parse(currentUrl).buildUpon().fragment(null).build().toString(); 127e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood } catch (UnsupportedOperationException e) { 128e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood // carry on 129e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood } 130e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood } 131e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "loadUrlIfChanged\nnew: " + url + "\nold: " +currentUrl); 132e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (!TextUtils.equals(url, currentUrl)) { 13329721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood loadUrl(url, headers); 13429721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 13529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 13629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 13729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood public void loadUrl(String url, Map<String, String> headers) { 13829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "Preloading " + url); 13929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood mTab.loadUrl(url, headers); 14029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 14129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 14229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood public void destroy() { 143e1dbb956d762c3f07033f247c05270a9882a79a7Mathew Inwood if (LOGD_ENABLED) Log.d(LOGTAG, "PreloadedTabControl.destroy"); 14429721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood mDestroyed = true; 14529721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood mTab.destroy(); 14629721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 14729721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 14829721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood public Tab getTab() { 14929721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood return mTab; 15029721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood } 15129721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood 15229721c2c6cc7f79a52962556c4431b71bb3ce46eMathew Inwood} 153