1 /* 2 * Copyright (C) 2011 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 */ 16 package com.android.browser; 17 18 import android.net.Uri; 19 import android.text.TextUtils; 20 import android.util.Log; 21 import android.webkit.SearchBox; 22 23 import java.util.Map; 24 import java.util.regex.Pattern; 25 26 /** 27 * Class to manage the controlling of preloaded tab. 28 */ 29 public class PreloadedTabControl { 30 private static final boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED; 31 private static final String LOGTAG = "PreloadedTabControl"; 32 33 final Tab mTab; 34 private String mLastQuery; 35 private boolean mDestroyed; 36 37 public PreloadedTabControl(Tab t) { 38 if (LOGD_ENABLED) Log.d(LOGTAG, "PreloadedTabControl.<init>"); 39 mTab = t; 40 } 41 42 private void maybeSetQuery(final String query, SearchBox sb) { 43 if (!TextUtils.equals(mLastQuery, query)) { 44 if (sb != null) { 45 if (LOGD_ENABLED) Log.d(LOGTAG, "Changing searchbox query to " + query); 46 sb.setVerbatim(true); 47 sb.setQuery(query); 48 sb.onchange(new SearchBox.SearchBoxListener() { 49 @Override 50 public void onChangeComplete(boolean called) { 51 if (mDestroyed) return; 52 if (LOGD_ENABLED) Log.d(LOGTAG, "Changed searchbox query: " + called); 53 if (called) { 54 mLastQuery = query; 55 } 56 } 57 }); 58 } else { 59 if (LOGD_ENABLED) Log.d(LOGTAG, "Cannot set query: no searchbox interface"); 60 } 61 } 62 } 63 64 public void setQuery(String query) { 65 maybeSetQuery(query, mTab.getWebView().getSearchBox()); 66 } 67 68 public boolean searchBoxSubmit(final String query, 69 final String fallbackUrl, final Map<String, String> fallbackHeaders) { 70 final SearchBox sb = mTab.getWebView().getSearchBox(); 71 if (sb == null) { 72 // no searchbox, cannot submit. Fallback to regular tab creation 73 if (LOGD_ENABLED) Log.d(LOGTAG, "No searchbox, cannot submit query"); 74 return false; 75 } 76 maybeSetQuery(query, sb); 77 if (LOGD_ENABLED) Log.d(LOGTAG, "Submitting query " + query); 78 final String currentUrl = mTab.getUrl(); 79 sb.onsubmit(new SearchBox.SearchBoxListener() { 80 @Override 81 public void onSubmitComplete(boolean called) { 82 if (mDestroyed) return; 83 if (LOGD_ENABLED) Log.d(LOGTAG, "Query submitted: " + called); 84 if (!called) { 85 if (LOGD_ENABLED) Log.d(LOGTAG, "Query not submitted; falling back"); 86 loadUrl(fallbackUrl, fallbackHeaders); 87 // make sure that the failed, preloaded URL is cleared from the back stack 88 mTab.clearBackStackWhenItemAdded(Pattern.compile( 89 "^" + Pattern.quote(fallbackUrl) + "$")); 90 } else { 91 // ignore the next fragment change, to avoid leaving a blank page in the browser 92 // after the query has been submitted. 93 String currentWithoutFragment = Uri.parse(currentUrl) 94 .buildUpon() 95 .fragment(null) 96 .toString(); 97 mTab.clearBackStackWhenItemAdded( 98 Pattern.compile( 99 "^" + 100 Pattern.quote(currentWithoutFragment) + 101 "(\\#.*)?" + 102 "$")); 103 } 104 }}); 105 return true; 106 } 107 108 public void searchBoxCancel() { 109 SearchBox sb = mTab.getWebView().getSearchBox(); 110 if (sb != null) { 111 mLastQuery = null; 112 sb.oncancel(new SearchBox.SearchBoxListener(){ 113 @Override 114 public void onCancelComplete(boolean called) { 115 if (LOGD_ENABLED) Log.d(LOGTAG, "Query cancelled: " + called); 116 } 117 }); 118 } 119 } 120 121 public void loadUrlIfChanged(String url, Map<String, String> headers) { 122 String currentUrl = mTab.getUrl(); 123 if (!TextUtils.isEmpty(currentUrl)) { 124 try { 125 // remove fragment: 126 currentUrl = Uri.parse(currentUrl).buildUpon().fragment(null).build().toString(); 127 } catch (UnsupportedOperationException e) { 128 // carry on 129 } 130 } 131 if (LOGD_ENABLED) Log.d(LOGTAG, "loadUrlIfChanged\nnew: " + url + "\nold: " +currentUrl); 132 if (!TextUtils.equals(url, currentUrl)) { 133 loadUrl(url, headers); 134 } 135 } 136 137 public void loadUrl(String url, Map<String, String> headers) { 138 if (LOGD_ENABLED) Log.d(LOGTAG, "Preloading " + url); 139 mTab.loadUrl(url, headers); 140 } 141 142 public void destroy() { 143 if (LOGD_ENABLED) Log.d(LOGTAG, "PreloadedTabControl.destroy"); 144 mDestroyed = true; 145 mTab.destroy(); 146 } 147 148 public Tab getTab() { 149 return mTab; 150 } 151 152 } 153