progress towards impression and click stats on all sources, plus some internal cleanup

(framework portion)

suggestionCursor has new callbacks for impressions and clicks
- impressions now used to trigger "more" UI, cleanup apis around that

search dialog reports which position was clicked on via cursor#respond
- can now detect when sources under "more results" are clicked
- also used to simplify existing stuff:
  - can detect when "more results" entry is clicked and toggle base on that (no longer need INTENT_ACTION_CURSOR_RESPOND one off)
  - use response from click reporting to instruct which position should be selected
This commit is contained in:
Karl Rosaen
2009-06-01 23:11:44 +01:00
parent b3c3778edb
commit a058f02b59
3 changed files with 92 additions and 66 deletions

View File

@@ -1202,8 +1202,21 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
protected boolean launchSuggestion(int position, int actionKey, String actionMsg) { protected boolean launchSuggestion(int position, int actionKey, String actionMsg) {
Cursor c = mSuggestionsAdapter.getCursor(); Cursor c = mSuggestionsAdapter.getCursor();
if ((c != null) && c.moveToPosition(position)) { if ((c != null) && c.moveToPosition(position)) {
// let the cursor know which position was clicked
final Bundle clickResponse = new Bundle(1);
clickResponse.putInt(SearchManager.RESPOND_EXTRA_POSITION_CLICKED, position);
final Bundle response = c.respond(clickResponse);
// the convention is to send a position to select in response to a click (if applicable)
final int posToSelect = response.getInt(
SearchManager.RESPOND_EXTRA_POSITION_SELECTED,
SuggestionsAdapter.NO_ITEM_TO_SELECT);
mSuggestionsAdapter.setListItemToSelect(posToSelect);
// launch the intent
Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg); Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg);
launchIntent(intent); launchIntent(intent);
return true; return true;
} }
return false; return false;
@@ -1235,9 +1248,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
if (SearchManager.INTENT_ACTION_CHANGE_SEARCH_SOURCE.equals(action)) { if (SearchManager.INTENT_ACTION_CHANGE_SEARCH_SOURCE.equals(action)) {
handleChangeSourceIntent(intent); handleChangeSourceIntent(intent);
return true; return true;
} else if (SearchManager.INTENT_ACTION_CURSOR_RESPOND.equals(action)) {
handleCursorRespondIntent(intent);
return true;
} }
return false; return false;
} }
@@ -1269,26 +1279,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
setUserQuery(query); setUserQuery(query);
} }
/**
* Handles {@link SearchManager#INTENT_ACTION_CURSOR_RESPOND}.
*/
private void handleCursorRespondIntent(Intent intent) {
Cursor c = mSuggestionsAdapter.getCursor();
if (c != null) {
Bundle response = c.respond(intent.getExtras());
// The SHOW_CORPUS_SELECTORS command to the cursor also returns a value in
// its bundle, keyed by the same command string, which contains the index
// of the "More results..." list item, which we use to instruct the
// AutoCompleteTextView's list to scroll to that item when the item is
// clicked.
if (response.containsKey(SuggestionsAdapter.SHOW_CORPUS_SELECTORS)) {
int indexOfMore = response.getInt(SuggestionsAdapter.SHOW_CORPUS_SELECTORS);
mSuggestionsAdapter.setListItemToSelect(indexOfMore);
}
}
}
/** /**
* Sets the list item selection in the AutoCompleteTextView's ListView. * Sets the list item selection in the AutoCompleteTextView's ListView.
*/ */
@@ -1365,6 +1355,12 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
try { try {
// use specific action if supplied, or default action if supplied, or fixed default // use specific action if supplied, or default action if supplied, or fixed default
String action = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_ACTION); String action = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_ACTION);
// some items are display only, or have effect via the cursor respond click reporting.
if (SearchManager.INTENT_ACTION_NONE.equals(action)) {
return null;
}
if (action == null) { if (action == null) {
action = mSearchable.getSuggestIntentAction(); action = mSearchable.getSuggestIntentAction();
} }

View File

@@ -1162,10 +1162,44 @@ public class SearchManager
/** /**
* Intent extra data key: This key will be used for the extra populated by the * Intent extra data key: This key will be used for the extra populated by the
* {@link #SUGGEST_COLUMN_INTENT_EXTRA_DATA} column. * {@link #SUGGEST_COLUMN_INTENT_EXTRA_DATA} column.
*
* {@hide} * {@hide}
*/ */
public final static String EXTRA_DATA_KEY = "intent_extra_data_key"; public final static String EXTRA_DATA_KEY = "intent_extra_data_key";
/**
* Used by the search dialog to ask the global search provider whether there are any pending
* sources that have yet to respond. Specifically, the search dialog will call
* {@link Cursor#respond} with a bundle containing this extra as a key, and expect the same key
* to be in the response, with a boolean value indicating whether there are pending sources.
*
* {@hide}
*/
public final static String RESPOND_EXTRA_PENDING_SOURCES = "respond_extra_pending_sources";
/**
* Used by the search dialog to tell the cursor that supplied suggestions which item was clicked
* before launching the intent. The search dialog will call {@link Cursor#respond} with a
* bundle containing this extra as a key and the position that was clicked as the value.
*
* The response bundle will use {@link #RESPOND_EXTRA_POSITION_SELECTED} to return an int value
* of the index that should be selected, if applicable.
*
* {@hide}
*/
public final static String RESPOND_EXTRA_POSITION_CLICKED = "respond_extra_position_clicked";
/**
* Used as a key in the response bundle from a call to {@link Cursor#respond} that sends the
* position that is clicked.
*
* @see #RESPOND_EXTRA_POSITION_CLICKED
*
* {@hide}
*/
public final static String RESPOND_EXTRA_POSITION_SELECTED = "respond_extra_position_selected";
/** /**
* Intent extra data key: Use this key with Intent.ACTION_SEARCH and * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
* {@link android.content.Intent#getStringExtra content.Intent.getStringExtra()} * {@link android.content.Intent#getStringExtra content.Intent.getStringExtra()}
@@ -1364,20 +1398,6 @@ public class SearchManager
public final static String INTENT_ACTION_CHANGE_SEARCH_SOURCE public final static String INTENT_ACTION_CHANGE_SEARCH_SOURCE
= "android.search.action.CHANGE_SEARCH_SOURCE"; = "android.search.action.CHANGE_SEARCH_SOURCE";
/**
* If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION},
* the search dialog will call {@link Cursor#respond(Bundle)} when the
* suggestion is clicked.
*
* The {@link Bundle} argument will be constructed
* in the same way as the "extra" bundle included in an Intent constructed
* from the suggestion.
*
* @hide Pending API council approval.
*/
public final static String INTENT_ACTION_CURSOR_RESPOND
= "android.search.action.CURSOR_RESPOND";
/** /**
* Intent action for finding the global search activity. * Intent action for finding the global search activity.
* The global search provider should handle this intent. * The global search provider should handle this intent.
@@ -1396,6 +1416,14 @@ public class SearchManager
public final static String INTENT_ACTION_SEARCH_SETTINGS public final static String INTENT_ACTION_SEARCH_SETTINGS
= "android.search.action.SEARCH_SETTINGS"; = "android.search.action.SEARCH_SETTINGS";
/**
* If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION},
* the search dialog will take no action.
*
* @hide
*/
public final static String INTENT_ACTION_NONE = "android.search.action.ZILCH";
/** /**
* Reference to the shared system search service. * Reference to the shared system search service.
*/ */
@@ -1506,25 +1534,27 @@ public class SearchManager
} }
/** /**
* See {@link #setOnDismissListener} for configuring your activity to monitor search UI state. * See {@link SearchManager#setOnDismissListener} for configuring your activity to monitor
* search UI state.
*/ */
public interface OnDismissListener { public interface OnDismissListener {
/** /**
* This method will be called when the search UI is dismissed. To make use if it, you must * This method will be called when the search UI is dismissed. To make use of it, you must
* implement this method in your activity, and call {@link #setOnDismissListener} to * implement this method in your activity, and call
* register it. * {@link SearchManager#setOnDismissListener} to register it.
*/ */
public void onDismiss(); public void onDismiss();
} }
/** /**
* See {@link #setOnCancelListener} for configuring your activity to monitor search UI state. * See {@link SearchManager#setOnCancelListener} for configuring your activity to monitor
* search UI state.
*/ */
public interface OnCancelListener { public interface OnCancelListener {
/** /**
* This method will be called when the search UI is canceled. To make use if it, you must * This method will be called when the search UI is canceled. To make use if it, you must
* implement this method in your activity, and call {@link #setOnCancelListener} to * implement this method in your activity, and call
* register it. * {@link SearchManager#setOnCancelListener} to register it.
*/ */
public void onCancel(); public void onCancel();
} }

View File

@@ -77,8 +77,10 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
// a particular list item should be selected upon the next call to notifyDataSetChanged. // a particular list item should be selected upon the next call to notifyDataSetChanged.
// This is used to indicate the index of the "More results..." list item so that when // This is used to indicate the index of the "More results..." list item so that when
// the data set changes after a click of "More results...", we can correctly tell the // the data set changes after a click of "More results...", we can correctly tell the
// ListView to scroll to the right line item. It gets reset to -1 every time it is consumed. // ListView to scroll to the right line item. It gets reset to NO_ITEM_TO_SELECT every time it
private int mListItemToSelect = -1; // is consumed.
private int mListItemToSelect = NO_ITEM_TO_SELECT;
static final int NO_ITEM_TO_SELECT = -1;
public SuggestionsAdapter(Context context, SearchDialog searchDialog, SearchableInfo searchable, public SuggestionsAdapter(Context context, SearchDialog searchDialog, SearchableInfo searchable,
WeakHashMap<String, Drawable> outsideDrawablesCache, boolean globalSearchMode) { WeakHashMap<String, Drawable> outsideDrawablesCache, boolean globalSearchMode) {
@@ -146,9 +148,9 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
public void notifyDataSetChanged() { public void notifyDataSetChanged() {
super.notifyDataSetChanged(); super.notifyDataSetChanged();
updateWorking(); updateWorking();
if (mListItemToSelect != -1) { if (mListItemToSelect != NO_ITEM_TO_SELECT) {
mSearchDialog.setListSelection(mListItemToSelect); mSearchDialog.setListSelection(mListItemToSelect);
mListItemToSelect = -1; mListItemToSelect = NO_ITEM_TO_SELECT;
} }
} }
@@ -168,12 +170,10 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
if (!mGlobalSearchMode || mCursor == null) return; if (!mGlobalSearchMode || mCursor == null) return;
Bundle request = new Bundle(); Bundle request = new Bundle();
request.putString(SearchManager.EXTRA_DATA_KEY, IS_WORKING); request.putString(SearchManager.RESPOND_EXTRA_PENDING_SOURCES, "DUMMY");
Bundle response = mCursor.respond(request); Bundle response = mCursor.respond(request);
if (response.containsKey(IS_WORKING)) {
boolean isWorking = response.getBoolean(IS_WORKING); mSearchDialog.setWorking(response.getBoolean(SearchManager.RESPOND_EXTRA_PENDING_SOURCES));
mSearchDialog.setWorking(isWorking);
}
} }
/** /**
@@ -408,7 +408,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
*/ */
public static String getColumnString(Cursor cursor, String columnName) { public static String getColumnString(Cursor cursor, String columnName) {
int col = cursor.getColumnIndex(columnName); int col = cursor.getColumnIndex(columnName);
if (col == -1) { if (col == NO_ITEM_TO_SELECT) {
return null; return null;
} }
return cursor.getString(col); return cursor.getString(col);