OSDN Git Service

Allow going back to a voice search to work when choosing from n-best.
[android-x86/packages-apps-Browser.git] / src / com / android / browser / Tab.java
index a313269..535e8e7 100644 (file)
@@ -18,7 +18,10 @@ package com.android.browser;
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.Map;
 import java.util.Vector;
 
 import android.app.AlertDialog;
@@ -55,6 +58,7 @@ import android.webkit.SslErrorHandler;
 import android.webkit.URLUtil;
 import android.webkit.ValueCallback;
 import android.webkit.WebBackForwardList;
+import android.webkit.WebBackForwardListClient;
 import android.webkit.WebChromeClient;
 import android.webkit.WebHistoryItem;
 import android.webkit.WebIconDatabase;
@@ -127,6 +131,8 @@ class Tab {
     // The listener that gets invoked when a download is started from the
     // mMainView
     private final DownloadListener mDownloadListener;
+    // Listener used to know when we move forward or back in the history list.
+    private final WebBackForwardListClient mWebBackForwardListClient;
 
     // AsyncTask for downloading touch icons
     DownloadTouchIcon mTouchIconLoader;
@@ -218,27 +224,37 @@ class Tab {
             }
             mVoiceSearchData = new VoiceSearchData(results, urls, htmls,
                     baseUrls);
+            mVoiceSearchData.mHeaders = intent.getParcelableArrayListExtra(
+                    RecognizerResultsIntent
+                    .EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS);
             mVoiceSearchData.mSourceIsGoogle = intent.getBooleanExtra(
                     VoiceSearchData.SOURCE_IS_GOOGLE, false);
-        } else {
-            String extraData = intent.getStringExtra(
-                    SearchManager.EXTRA_DATA_KEY);
-            if (extraData != null) {
-                index = Integer.parseInt(extraData);
-                if (index >= mVoiceSearchData.mVoiceSearchResults.size()) {
-                    throw new AssertionError("index must be less than "
-                            + " size of mVoiceSearchResults");
-                }
-                if (mVoiceSearchData.mSourceIsGoogle) {
-                    Intent logIntent = new Intent(
-                            LoggingEvents.ACTION_LOG_EVENT);
-                    logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
-                            LoggingEvents.VoiceSearch.N_BEST_CHOOSE);
-                    logIntent.putExtra(
-                            LoggingEvents.VoiceSearch.EXTRA_N_BEST_CHOOSE_INDEX,
-                            index);
-                    mActivity.sendBroadcast(logIntent);
-                }
+            mVoiceSearchData.mVoiceSearchIntent = new Intent(intent);
+        }
+        String extraData = intent.getStringExtra(
+                SearchManager.EXTRA_DATA_KEY);
+        if (extraData != null) {
+            index = Integer.parseInt(extraData);
+            if (index >= mVoiceSearchData.mVoiceSearchResults.size()) {
+                throw new AssertionError("index must be less than "
+                        + "size of mVoiceSearchResults");
+            }
+            if (mVoiceSearchData.mSourceIsGoogle) {
+                Intent logIntent = new Intent(
+                        LoggingEvents.ACTION_LOG_EVENT);
+                logIntent.putExtra(LoggingEvents.EXTRA_EVENT,
+                        LoggingEvents.VoiceSearch.N_BEST_CHOOSE);
+                logIntent.putExtra(
+                        LoggingEvents.VoiceSearch.EXTRA_N_BEST_CHOOSE_INDEX,
+                        index);
+                mActivity.sendBroadcast(logIntent);
+            }
+            if (mVoiceSearchData.mVoiceSearchIntent != null) {
+                // Copy the Intent, so that each history item will have its own
+                // Intent, with different (or none) extra data.
+                Intent latest = new Intent(mVoiceSearchData.mVoiceSearchIntent);
+                latest.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
+                mVoiceSearchData.mVoiceSearchIntent = latest;
             }
         }
         mVoiceSearchData.mLastVoiceSearchTitle
@@ -274,7 +290,21 @@ class Tab {
             mVoiceSearchData.mLastVoiceSearchUrl = mActivity.smartUrlFilter(
                     mVoiceSearchData.mLastVoiceSearchTitle);
         }
-        mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl);
+        Map<String, String> headers = null;
+        if (mVoiceSearchData.mHeaders != null) {
+            int bundleIndex = mVoiceSearchData.mHeaders.size() == 1 ? 0
+                    : index;
+            Bundle bundle = mVoiceSearchData.mHeaders.get(bundleIndex);
+            if (bundle != null && !bundle.isEmpty()) {
+                Iterator<String> iter = bundle.keySet().iterator();
+                headers = new HashMap<String, String>();
+                while (iter.hasNext()) {
+                    String key = iter.next();
+                    headers.put(key, bundle.getString(key));
+                }
+            }
+        }
+        mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl, headers);
     }
     /* package */ static class VoiceSearchData {
         public VoiceSearchData(ArrayList<String> results,
@@ -323,6 +353,17 @@ class Tab {
          */
         public boolean mSourceIsGoogle;
         /**
+         * List of headers to be passed into the WebView containing location
+         * information
+         */
+        public ArrayList<Bundle> mHeaders;
+        /**
+         * The Intent used to invoke voice search.  Placed on the
+         * WebHistoryItem so that when coming back to a previous voice search
+         * page we can again activate voice search.
+         */
+        public Intent mVoiceSearchIntent;
+        /**
          * String used to identify Google as the source of voice search.
          */
         public static String SOURCE_IS_GOOGLE
@@ -893,45 +934,60 @@ class Tab {
         }
 
         @Override
-        public void onReceivedTitle(WebView view, String title) {
-            String url = view.getUrl();
+        public void onReceivedTitle(WebView view, final String title) {
+            final String pageUrl = view.getUrl();
             if (mInForeground) {
                 // here, if url is null, we want to reset the title
-                mActivity.setUrlTitle(url, title);
+                mActivity.setUrlTitle(pageUrl, title);
             }
-            if (url == null ||
-                url.length() >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
+            if (pageUrl == null || pageUrl.length()
+                    >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
                 return;
             }
-            // See if we can find the current url in our history database and
-            // add the new title to it.
-            if (url.startsWith("http://www.")) {
-                url = url.substring(11);
-            } else if (url.startsWith("http://")) {
-                url = url.substring(4);
-            }
-            try {
-                final ContentResolver cr = mActivity.getContentResolver();
-                url = "%" + url;
-                String [] selArgs = new String[] { url };
-                String where = Browser.BookmarkColumns.URL + " LIKE ? AND "
-                        + Browser.BookmarkColumns.BOOKMARK + " = 0";
-                Cursor c = cr.query(Browser.BOOKMARKS_URI,
-                        Browser.HISTORY_PROJECTION, where, selArgs, null);
-                if (c.moveToFirst()) {
-                    // Current implementation of database only has one entry per
-                    // url.
-                    ContentValues map = new ContentValues();
-                    map.put(Browser.BookmarkColumns.TITLE, title);
-                    cr.update(Browser.BOOKMARKS_URI, map, "_id = "
-                            + c.getInt(0), null);
+            new AsyncTask<Void, Void, Void>() {
+                protected Void doInBackground(Void... unused) {
+                    // See if we can find the current url in our history
+                    // database and add the new title to it.
+                    String url = pageUrl;
+                    if (url.startsWith("http://www.")) {
+                        url = url.substring(11);
+                    } else if (url.startsWith("http://")) {
+                        url = url.substring(4);
+                    }
+                    Cursor c = null;
+                    try {
+                        final ContentResolver cr
+                                = mActivity.getContentResolver();
+                        url = "%" + url;
+                        String [] selArgs = new String[] { url };
+                        String where = Browser.BookmarkColumns.URL
+                                + " LIKE ? AND "
+                                + Browser.BookmarkColumns.BOOKMARK + " = 0";
+                        c = cr.query(Browser.BOOKMARKS_URI, new String[]
+                                { Browser.BookmarkColumns._ID }, where, selArgs,
+                                null);
+                        if (c.moveToFirst()) {
+                            // Current implementation of database only has one
+                            // entry per url.
+                            ContentValues map = new ContentValues();
+                            map.put(Browser.BookmarkColumns.TITLE, title);
+                            String[] projection = new String[]
+                                    { Integer.valueOf(c.getInt(0)).toString() };
+                            cr.update(Browser.BOOKMARKS_URI, map, "_id = ?",
+                                    projection);
+                        }
+                    } catch (IllegalStateException e) {
+                        Log.e(LOGTAG, "Tab onReceived title", e);
+                    } catch (SQLiteException ex) {
+                        Log.e(LOGTAG,
+                                "onReceivedTitle() caught SQLiteException: ",
+                                ex);
+                    } finally {
+                        if (c != null) c.close();
+                    }
+                    return null;
                 }
-                c.close();
-            } catch (IllegalStateException e) {
-                Log.e(LOGTAG, "Tab onReceived title", e);
-            } catch (SQLiteException ex) {
-                Log.e(LOGTAG, "onReceivedTitle() caught SQLiteException: ", ex);
-            }
+            }.execute();
         }
 
         @Override
@@ -965,6 +1021,8 @@ class Tab {
                         mTouchIconLoader = new DownloadTouchIcon(Tab.this, cr,
                                 c, view);
                         mTouchIconLoader.execute(url);
+                    } else {
+                        c.close();
                     }
                 } else {
                     c.close();
@@ -1270,6 +1328,21 @@ class Tab {
                 }
             }
         };
+        mWebBackForwardListClient = new WebBackForwardListClient() {
+            @Override
+            public void onNewHistoryItem(WebHistoryItem item) {
+                if (isInVoiceSearchMode()) {
+                    item.setCustomData(mVoiceSearchData.mVoiceSearchIntent);
+                }
+            }
+            @Override
+            public void onIndexChanged(WebHistoryItem item, int index) {
+                Object data = item.getCustomData();
+                if (data != null && data instanceof Intent) {
+                    activateVoiceSearchMode((Intent) data);
+                }
+            }
+        };
 
         setWebView(w);
     }
@@ -1302,6 +1375,7 @@ class Tab {
             // does a redirect after a period of time. The user could have
             // switched to another tab while waiting for the download to start.
             mMainView.setDownloadListener(mDownloadListener);
+            mMainView.setWebBackForwardListClient(mWebBackForwardListClient);
         }
     }
 
@@ -1774,6 +1848,10 @@ class Tab {
                     mMainView.hashCode() + "_pic.save");
             if (mMainView.savePicture(mSavedState, f)) {
                 mSavedState.putString(CURRPICTURE, f.getPath());
+            } else {
+                // if savePicture returned false, we can't trust the contents,
+                // and it may be large, so we delete it right away
+                f.delete();
             }
         }