summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
authorLeon Scroggins <scroggo@google.com>2010-01-28 15:12:40 -0500
committerLeon Scroggins <scroggo@google.com>2010-01-29 17:17:22 -0500
commit58d56c6b5052faa86083965132cd51b1a9594d0e (patch)
treeff12588ede5a3ae4eda6b1ddfb548820dc80da42 /src/com/android
parente5073c271be740654469ea63b69bd4a505ca222c (diff)
downloadpackages_apps_Browser-58d56c6b5052faa86083965132cd51b1a9594d0e.tar.gz
packages_apps_Browser-58d56c6b5052faa86083965132cd51b1a9594d0e.tar.bz2
packages_apps_Browser-58d56c6b5052faa86083965132cd51b1a9594d0e.zip
Handle the voice search intent.
Once the voice search intent has been handled, the title bar background changes to green, and touching it displays other voice search possibilities. Fixes http://b/issue?id=2390686
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/browser/BrowserActivity.java98
-rw-r--r--src/com/android/browser/BrowserProvider.java94
-rw-r--r--src/com/android/browser/Tab.java121
-rw-r--r--src/com/android/browser/TitleBar.java37
4 files changed, 320 insertions, 30 deletions
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 90bacadd5..3f7c9e985 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -23,6 +23,8 @@ import android.app.SearchManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentProvider;
+import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -381,9 +383,11 @@ public class BrowserActivity extends Activity
// the tab will be close when exit.
UrlData urlData = getUrlDataFromIntent(intent);
+ String action = intent.getAction();
final Tab t = mTabControl.createNewTab(
- Intent.ACTION_VIEW.equals(intent.getAction()) &&
- intent.getData() != null,
+ (Intent.ACTION_VIEW.equals(action) &&
+ intent.getData() != null)
+ || Tab.VoiceSearchData.VOICE_SEARCH_RESULTS.equals(action),
intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
mTabControl.setCurrentTab(t);
attachTabToContentView(t);
@@ -410,7 +414,7 @@ public class BrowserActivity extends Activity
waitForCredentials();
}
} else {
- urlData.loadIn(webView);
+ urlData.loadIn(t);
}
} else {
// TabControl.restoreState() will create a new tab even if
@@ -425,6 +429,24 @@ public class BrowserActivity extends Activity
}
}
+ /**
+ * Feed the previously stored results strings to the BrowserProvider so that
+ * the SearchDialog will show them instead of the standard searches.
+ * @param result String to show on the editable line of the SearchDialog.
+ */
+ /* package */ void showVoiceSearchResults(String result) {
+ ContentProviderClient client = mResolver.acquireContentProviderClient(
+ Browser.BOOKMARKS_URI);
+ ContentProvider prov = client.getLocalContentProvider();
+ BrowserProvider bp = (BrowserProvider) prov;
+ bp.setQueryResults(mTabControl.getCurrentTab().getVoiceSearchResults());
+ client.release();
+
+ startSearch(result, false,
+ createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY),
+ false);
+ }
+
@Override
protected void onNewIntent(Intent intent) {
Tab current = mTabControl.getCurrentTab();
@@ -448,10 +470,13 @@ public class BrowserActivity extends Activity
// just resume the browser
return;
}
+ boolean activateVoiceSearch = Tab.VoiceSearchData.VOICE_SEARCH_RESULTS
+ .equals(action);
if (Intent.ACTION_VIEW.equals(action)
|| Intent.ACTION_SEARCH.equals(action)
|| MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
- || Intent.ACTION_WEB_SEARCH.equals(action)) {
+ || Intent.ACTION_WEB_SEARCH.equals(action)
+ || activateVoiceSearch) {
// If this was a search request (e.g. search query directly typed into the address bar),
// pass it on to the default web search provider.
if (handleWebSearchIntent(intent)) {
@@ -465,7 +490,7 @@ public class BrowserActivity extends Activity
final String appId = intent
.getStringExtra(Browser.EXTRA_APPLICATION_ID);
- if (Intent.ACTION_VIEW.equals(action)
+ if ((Intent.ACTION_VIEW.equals(action) || activateVoiceSearch)
&& !getPackageName().equals(appId)
&& (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
Tab appTab = mTabControl.getTabFromId(appId);
@@ -485,14 +510,14 @@ public class BrowserActivity extends Activity
if (current != appTab) {
switchToTab(mTabControl.getTabIndex(appTab));
if (needsLoad) {
- urlData.loadIn(appTab.getWebView());
+ urlData.loadIn(appTab);
}
} else {
// If the tab was the current tab, we have to attach
// it to the view system again.
attachTabToContentView(appTab);
if (needsLoad) {
- urlData.loadIn(appTab.getWebView());
+ urlData.loadIn(appTab);
}
}
return;
@@ -541,7 +566,7 @@ public class BrowserActivity extends Activity
}
// Get rid of the subwindow if it exists
dismissSubWindow(current);
- urlData.loadIn(current.getWebView());
+ urlData.loadIn(current);
}
}
}
@@ -571,6 +596,9 @@ public class BrowserActivity extends Activity
String url = null;
final String action = intent.getAction();
+ if (Tab.VoiceSearchData.VOICE_SEARCH_RESULTS.equals(action)) {
+ return false;
+ }
if (Intent.ACTION_VIEW.equals(action)) {
Uri data = intent.getData();
if (data != null) url = data.toString();
@@ -622,7 +650,7 @@ public class BrowserActivity extends Activity
}
private UrlData getUrlDataFromIntent(Intent intent) {
- String url = null;
+ String url = "";
Map<String, String> headers = null;
if (intent != null) {
final String action = intent.getAction();
@@ -673,9 +701,22 @@ public class BrowserActivity extends Activity
}
}
}
- return new UrlData(url, headers);
+ return new UrlData(url, headers, intent);
}
+ /* package */ void showVoiceTitleBar(String title) {
+ mTitleBar.setInVoiceMode(true);
+ mFakeTitleBar.setInVoiceMode(true);
+ mTitleBar.setDisplayTitle(title);
+ mFakeTitleBar.setDisplayTitle(title);
+ }
+ /* package */ void revertVoiceTitleBar() {
+ mTitleBar.setInVoiceMode(false);
+ mFakeTitleBar.setInVoiceMode(false);
+
+ mTitleBar.setDisplayTitle(mTitle);
+ mFakeTitleBar.setDisplayTitle(mTitle);
+ }
/* package */ static String fixUrl(String inUrl) {
// FIXME: Converting the url to lower case
// duplicates functionality in smartUrlFilter().
@@ -1742,6 +1783,11 @@ public class BrowserActivity extends Activity
WebView view = t.getWebView();
view.setEmbeddedTitleBar(mTitleBar);
+ if (t.isInVoiceSearchMode()) {
+ showVoiceTitleBar(t.getVoiceDisplayTitle());
+ } else {
+ revertVoiceTitleBar();
+ }
// Request focus on the top window.
t.getTopWindow().requestFocus();
}
@@ -1803,7 +1849,7 @@ public class BrowserActivity extends Activity
mTabControl.setCurrentTab(tab);
attachTabToContentView(tab);
if (!urlData.isEmpty()) {
- urlData.loadIn(webview);
+ urlData.loadIn(tab);
}
return tab;
} else {
@@ -1811,10 +1857,10 @@ public class BrowserActivity extends Activity
dismissSubWindow(currentTab);
if (!urlData.isEmpty()) {
// Load the given url.
- urlData.loadIn(currentTab.getWebView());
+ urlData.loadIn(currentTab);
}
+ return currentTab;
}
- return currentTab;
}
private Tab openTab(String url) {
@@ -1991,8 +2037,10 @@ public class BrowserActivity extends Activity
mUrl = url;
mTitle = title;
- mTitleBar.setTitleAndUrl(title, url);
- mFakeTitleBar.setTitleAndUrl(title, url);
+ // If we are in voice search mode, the title has already been set.
+ if (mTabControl.getCurrentTab().isInVoiceSearchMode()) return;
+ mTitleBar.setDisplayTitle(url);
+ mFakeTitleBar.setDisplayTitle(url);
}
/**
@@ -3891,23 +3939,35 @@ public class BrowserActivity extends Activity
private static class UrlData {
final String mUrl;
final Map<String, String> mHeaders;
+ final Intent mVoiceIntent;
UrlData(String url) {
this.mUrl = url;
this.mHeaders = null;
+ this.mVoiceIntent = null;
}
- UrlData(String url, Map<String, String> headers) {
+ UrlData(String url, Map<String, String> headers, Intent intent) {
this.mUrl = url;
this.mHeaders = headers;
+ if (Tab.VoiceSearchData.VOICE_SEARCH_RESULTS.equals(
+ intent.getAction())) {
+ this.mVoiceIntent = intent;
+ } else {
+ this.mVoiceIntent = null;
+ }
}
boolean isEmpty() {
- return mUrl == null || mUrl.length() == 0;
+ return mVoiceIntent == null && (mUrl == null || mUrl.length() == 0);
}
- public void loadIn(WebView webView) {
- webView.loadUrl(mUrl, mHeaders);
+ public void loadIn(Tab t) {
+ if (mVoiceIntent != null) {
+ t.activateVoiceSearchMode(mVoiceIntent);
+ } else {
+ t.getWebView().loadUrl(mUrl, mHeaders);
+ }
}
};
diff --git a/src/com/android/browser/BrowserProvider.java b/src/com/android/browser/BrowserProvider.java
index 47477217c..bd6a723c1 100644
--- a/src/com/android/browser/BrowserProvider.java
+++ b/src/com/android/browser/BrowserProvider.java
@@ -53,6 +53,7 @@ import com.google.android.providers.GoogleSettings.Partner;
import java.io.File;
import java.io.FilenameFilter;
+import java.util.ArrayList;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -718,16 +719,105 @@ public class BrowserProvider extends ContentProvider {
}
}
+ private static class ResultsCursor extends AbstractCursor {
+ // Array indices for RESULTS_COLUMNS
+ private static final int RESULT_ACTION_ID = 1;
+ private static final int RESULT_DATA_ID = 2;
+ private static final int RESULT_TEXT_ID = 3;
+ private static final int RESULT_ICON_ID = 4;
+ private static final int RESULT_EXTRA_ID = 5;
+
+ private static final String[] RESULTS_COLUMNS = new String[] {
+ "_id",
+ SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+ SearchManager.SUGGEST_COLUMN_INTENT_DATA,
+ SearchManager.SUGGEST_COLUMN_TEXT_1,
+ SearchManager.SUGGEST_COLUMN_ICON_1,
+ SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA
+ };
+ private final ArrayList<String> mResults;
+ public ResultsCursor(ArrayList<String> results) {
+ mResults = results;
+ }
+ public int getCount() { return mResults.size(); }
+
+ public String[] getColumnNames() {
+ return RESULTS_COLUMNS;
+ }
+
+ public String getString(int column) {
+ switch (column) {
+ case RESULT_ACTION_ID:
+ return Tab.VoiceSearchData.VOICE_SEARCH_RESULTS;
+ case RESULT_TEXT_ID:
+ // The data is used when the phone is in landscape mode. We
+ // still want to show the result string.
+ case RESULT_DATA_ID:
+ return mResults.get(mPos);
+ case RESULT_EXTRA_ID:
+ // The Intent's extra data will store the index into
+ // mResults so the BrowserActivity will know which result to
+ // use.
+ return Integer.toString(mPos);
+ case RESULT_ICON_ID:
+ return Integer.valueOf(R.drawable.magnifying_glass)
+ .toString();
+ default:
+ return null;
+ }
+ }
+ public short getShort(int column) {
+ throw new UnsupportedOperationException();
+ }
+ public int getInt(int column) {
+ throw new UnsupportedOperationException();
+ }
+ public long getLong(int column) {
+ if ((mPos != -1) && column == 0) {
+ return mPos; // use row# as the _id
+ }
+ throw new UnsupportedOperationException();
+ }
+ public float getFloat(int column) {
+ throw new UnsupportedOperationException();
+ }
+ public double getDouble(int column) {
+ throw new UnsupportedOperationException();
+ }
+ public boolean isNull(int column) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private ResultsCursor mResultsCursor;
+
+ /**
+ * Provide a set of results to be returned to query, intended to be used
+ * by the SearchDialog when the BrowserActivity is in voice search mode.
+ * @param results Strings to display in the dropdown from the SearchDialog
+ */
+ /* package */ void setQueryResults(ArrayList<String> results) {
+ if (results == null) {
+ mResultsCursor = null;
+ } else {
+ mResultsCursor = new ResultsCursor(results);
+ }
+ }
+
@Override
public Cursor query(Uri url, String[] projectionIn, String selection,
String[] selectionArgs, String sortOrder)
throws IllegalStateException {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-
int match = URI_MATCHER.match(url);
if (match == -1) {
throw new IllegalArgumentException("Unknown URL");
}
+ if (match == URI_MATCH_SUGGEST && mResultsCursor != null) {
+ Cursor results = mResultsCursor;
+ mResultsCursor = null;
+ return results;
+ }
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
if (match == URI_MATCH_SUGGEST || match == URI_MATCH_BOOKMARKS_SUGGEST) {
String suggestSelection;
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 22c828677..0a54eeef3 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -17,14 +17,17 @@
package com.android.browser;
import java.io.File;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Vector;
import android.app.AlertDialog;
+import android.app.SearchManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
+import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
@@ -133,6 +136,117 @@ class Tab {
// -------------------------------------------------------------------------
+ /**
+ * Private information regarding the latest voice search. If the Tab is not
+ * in voice search mode, this will be null.
+ */
+ private VoiceSearchData mVoiceSearchData;
+ /**
+ * Return whether the tab is in voice search mode.
+ */
+ public boolean isInVoiceSearchMode() {
+ return mVoiceSearchData != null;
+ }
+ /**
+ * Get the title to display for the current voice search page. If the Tab
+ * is not in voice search mode, return null.
+ */
+ public String getVoiceDisplayTitle() {
+ if (mVoiceSearchData == null) return null;
+ return mVoiceSearchData.mLastVoiceSearchTitle;
+ }
+ /**
+ * Get the latest array of voice search results, to be passed to the
+ * BrowserProvider. If the Tab is not in voice search mode, return null.
+ */
+ public ArrayList<String> getVoiceSearchResults() {
+ if (mVoiceSearchData == null) return null;
+ return mVoiceSearchData.mVoiceSearchResults;
+ }
+ /**
+ * Activate voice search mode.
+ * @param intent Intent which has the results to use, or an index into the
+ * results when reusing the old results.
+ */
+ /* package */ void activateVoiceSearchMode(Intent intent) {
+ ArrayList<String> results = intent.getStringArrayListExtra(
+ "result_strings");
+ ArrayList<String> urls = intent.getStringArrayListExtra(
+ "result_urls");
+ if (results != null) {
+ // This tab is now entering voice search mode for the first time, or
+ // a new voice search was done.
+ if (urls == null || results.size() != urls.size()) {
+ throw new AssertionError("improper extras passed in Intent");
+ }
+ mVoiceSearchData = new VoiceSearchData(results, urls);
+ } else {
+ String extraData = intent.getStringExtra(
+ SearchManager.EXTRA_DATA_KEY);
+ if (extraData != null) {
+ mVoiceSearchData.mLastVoiceSearchIndex
+ = Integer.parseInt(extraData);
+ if (mVoiceSearchData.mLastVoiceSearchIndex
+ >= mVoiceSearchData.mVoiceSearchResults.size()) {
+ throw new AssertionError("index must be less than "
+ + " size of mVoiceSearchResults");
+ }
+ }
+ }
+ mVoiceSearchData.mLastVoiceSearchTitle
+ = mVoiceSearchData.mVoiceSearchResults.get(mVoiceSearchData.
+ mLastVoiceSearchIndex);
+ if (mInForeground) {
+ mActivity.showVoiceTitleBar(mVoiceSearchData.mLastVoiceSearchTitle);
+ }
+ mVoiceSearchData.mLastVoiceSearchUrl
+ = mVoiceSearchData.mVoiceSearchUrls.get(mVoiceSearchData.
+ mLastVoiceSearchIndex);
+ mMainView.loadUrl(mVoiceSearchData.mLastVoiceSearchUrl);
+ }
+ /* package */ static class VoiceSearchData {
+ /**
+ * Intent action for a voice search. Will be replaced with a global
+ * variable.
+ */
+ public static final String VOICE_SEARCH_RESULTS
+ = "android.speech.action.VOICE_SEARCH_RESULTS";
+
+ public VoiceSearchData(ArrayList<String> results,
+ ArrayList<String> urls) {
+ mVoiceSearchResults = results;
+ mVoiceSearchUrls = urls;
+ mLastVoiceSearchIndex = 0;
+ }
+ /*
+ * ArrayList of suggestions to be displayed when opening the
+ * SearchManager
+ */
+ public ArrayList<String> mVoiceSearchResults;
+ /*
+ * ArrayList of urls, associated with the suggestions in
+ * mVoiceSearchResults.
+ */
+ public ArrayList<String> mVoiceSearchUrls;
+ /*
+ * The last url provided by voice search. Used for comparison to see if
+ * we are going to a page by some method besides voice search. Only
+ * meaningful in voice search mode.
+ */
+ public String mLastVoiceSearchUrl;
+ /**
+ * The last title used for voice search. Needed to update the title bar
+ * when switching tabs.
+ */
+ public String mLastVoiceSearchTitle;
+ /*
+ * The index into mVoiceSearchResults and mVoiceSearchUrls of the last
+ * voice search performed. Stored so it can be used to index into
+ * mVoiceSearchUrls to determine the url in getUrlDataFromIntent.
+ */
+ public int mLastVoiceSearchIndex;
+ }
+
// Container class for the next error dialog that needs to be displayed
private class ErrorDialog {
public final int mTitle;
@@ -209,6 +323,13 @@ class Tab {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
mInLoad = true;
+ if (mVoiceSearchData != null
+ && !url.equals(mVoiceSearchData.mLastVoiceSearchUrl)) {
+ mVoiceSearchData = null;
+ if (mInForeground) {
+ mActivity.revertVoiceTitleBar();
+ }
+ }
// We've started to load a new page. If there was a pending message
// to save a screenshot then we will now take the new page and save
diff --git a/src/com/android/browser/TitleBar.java b/src/com/android/browser/TitleBar.java
index a9da7c0e0..743af9b0c 100644
--- a/src/com/android/browser/TitleBar.java
+++ b/src/com/android/browser/TitleBar.java
@@ -67,6 +67,8 @@ public class TitleBar extends LinearLayout {
private MyHandler mHandler;
private Intent mVoiceSearchIntent;
private boolean mInVoiceMode;
+ private Drawable mVoiceModeBackground;
+ private Drawable mNormalBackground;
private static int LONG_PRESS = 1;
@@ -110,6 +112,9 @@ public class TitleBar extends LinearLayout {
}
mStopDrawable = resources.getDrawable(R.drawable.ic_btn_stop_v2);
mBookmarkDrawable = mRtButton.getDrawable();
+ mVoiceModeBackground = resources.getDrawable(
+ R.drawable.textfield_voice_search);
+ mNormalBackground = mTitleBg.getBackground();
}
private class MyHandler extends Handler {
@@ -186,7 +191,12 @@ public class TitleBar extends LinearLayout {
mRtButton.setPressed(false);
} else if (mTitleBg.isPressed()) {
mHandler.removeMessages(LONG_PRESS);
- mBrowserActivity.onSearchRequested();
+ if (mInVoiceMode) {
+ mBrowserActivity.showVoiceSearchResults(
+ mTitle.getText().toString());
+ } else {
+ mBrowserActivity.onSearchRequested();
+ }
mTitleBg.setPressed(false);
}
break;
@@ -222,13 +232,20 @@ public class TitleBar extends LinearLayout {
/* package */ void setInVoiceMode(boolean inVoiceMode) {
if (mInVoiceMode == inVoiceMode) return;
mInVoiceMode = inVoiceMode && mVoiceSearchIntent != null;
+ Drawable rightButtonDrawable, titleDrawable;
if (mInVoiceMode) {
- mRtButton.setImageDrawable(mVoiceDrawable);
- } else if (mInLoad) {
- mRtButton.setImageDrawable(mStopDrawable);
+ rightButtonDrawable = mVoiceDrawable;
+ titleDrawable = mVoiceModeBackground;
} else {
- mRtButton.setImageDrawable(mBookmarkDrawable);
+ titleDrawable = mNormalBackground;
+ if (mInLoad) {
+ rightButtonDrawable = mStopDrawable;
+ } else {
+ rightButtonDrawable = mBookmarkDrawable;
+ }
}
+ mTitleBg.setBackgroundDrawable(titleDrawable);
+ mRtButton.setImageDrawable(rightButtonDrawable);
}
/**
@@ -275,13 +292,15 @@ public class TitleBar extends LinearLayout {
}
/**
- * Update the title and url.
+ * Update the text displayed in the title bar.
+ * @param title String to display. If null, the loading string will be
+ * shown.
*/
- /* package */ void setTitleAndUrl(CharSequence title, CharSequence url) {
- if (url == null) {
+ /* package */ void setDisplayTitle(String title) {
+ if (title == null) {
mTitle.setText(R.string.title_bar_loading);
} else {
- mTitle.setText(url.toString());
+ mTitle.setText(title);
}
}