Home | History | Annotate | Download | only in browser
      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.getWebViewClassic().getSearchBox());
     66     }
     67 
     68     public boolean searchBoxSubmit(final String query,
     69             final String fallbackUrl, final Map<String, String> fallbackHeaders) {
     70         final SearchBox sb = mTab.getWebViewClassic().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.getWebViewClassic().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