Merge change 3576 into donut

* changes:
  Track clicks that occur after pivoting into an app from global search.
This commit is contained in:
Android (Google) Code Review
2009-06-09 12:45:35 -07:00
2 changed files with 141 additions and 3 deletions

View File

@@ -24,6 +24,8 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -1202,10 +1204,23 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
protected boolean launchSuggestion(int position, int actionKey, String actionMsg) {
Cursor c = mSuggestionsAdapter.getCursor();
if ((c != null) && c.moveToPosition(position)) {
mSuggestionsAdapter.callCursorOnClick(c, position);
Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg);
// report back about the click
if (mGlobalSearchMode) {
// in global search mode, do it via cursor
mSuggestionsAdapter.callCursorOnClick(c, position);
} else if (intent != null
&& mPreviousComponents != null
&& !mPreviousComponents.isEmpty()) {
// in-app search (and we have pivoted in as told by mPreviousComponents,
// which is used for keeping track of what we pop back to when we are pivoting into
// in app search.)
reportInAppClickToGlobalSearch(c, intent);
}
// launch the intent
Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg);
launchIntent(intent);
return true;
@@ -1213,6 +1228,94 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
return false;
}
/**
* Report a click from an in app search result back to global search for shortcutting porpoises.
*
* @param c The cursor that is pointing to the clicked position.
* @param intent The intent that will be launched for the click.
*/
private void reportInAppClickToGlobalSearch(Cursor c, Intent intent) {
// for in app search, still tell global search via content provider
Uri uri = getClickReportingUri();
final ContentValues cv = new ContentValues();
cv.put(SearchManager.SEARCH_CLICK_REPORT_COLUMN_QUERY, mUserQuery);
final ComponentName source = mSearchable.getSearchActivity();
cv.put(SearchManager.SEARCH_CLICK_REPORT_COLUMN_COMPONENT, source.flattenToShortString());
// grab the intent columns from the intent we created since it has additional
// logic for falling back on the searchable default
cv.put(SearchManager.SUGGEST_COLUMN_INTENT_ACTION, intent.getAction());
cv.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, intent.getDataString());
cv.put(SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA,
intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
// ensure the icons will work for global search
cv.put(SearchManager.SUGGEST_COLUMN_ICON_1,
wrapIconForPackage(
source,
getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_1)));
cv.put(SearchManager.SUGGEST_COLUMN_ICON_2,
wrapIconForPackage(
source,
getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_2)));
// the rest can be passed through directly
cv.put(SearchManager.SUGGEST_COLUMN_FORMAT,
getColumnString(c, SearchManager.SUGGEST_COLUMN_FORMAT));
cv.put(SearchManager.SUGGEST_COLUMN_TEXT_1,
getColumnString(c, SearchManager.SUGGEST_COLUMN_TEXT_1));
cv.put(SearchManager.SUGGEST_COLUMN_TEXT_2,
getColumnString(c, SearchManager.SUGGEST_COLUMN_TEXT_2));
cv.put(SearchManager.SUGGEST_COLUMN_QUERY,
getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY));
cv.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
getColumnString(c, SearchManager.SUGGEST_COLUMN_SHORTCUT_ID));
// note: deliberately omitting background color since it is only for global search
// "more results" entries
mContext.getContentResolver().insert(uri, cv);
}
/**
* @return A URI appropriate for reporting a click.
*/
private Uri getClickReportingUri() {
Uri.Builder uriBuilder = new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(SearchManager.SEARCH_CLICK_REPORT_AUTHORITY);
uriBuilder.appendPath(SearchManager.SEARCH_CLICK_REPORT_URI_PATH);
return uriBuilder
.query("") // TODO: Remove, workaround for a bug in Uri.writeToParcel()
.fragment("") // TODO: Remove, workaround for a bug in Uri.writeToParcel()
.build();
}
/**
* Wraps an icon for a particular package. If the icon is a resource id, it is converted into
* an android.resource:// URI.
*
* @param source The source of the icon
* @param icon The icon retrieved from a suggestion column
* @return An icon string appropriate for the package.
*/
private String wrapIconForPackage(ComponentName source, String icon) {
if (icon == null || icon.length() == 0 || "0".equals(icon)) {
// SearchManager specifies that null or zero can be returned to indicate
// no icon. We also allow empty string.
return null;
} else if (!Character.isDigit(icon.charAt(0))){
return icon;
} else {
String packageName = source.getPackageName();
return new Uri.Builder()
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(packageName)
.encodedPath(icon)
.toString();
}
}
/**
* Launches an intent. Also dismisses the search dialog if not in global search mode.
*/
@@ -1244,7 +1347,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}
/**
* Handles SearchManager#INTENT_ACTION_CHANGE_SOURCE.
* Handles {@link SearchManager#INTENT_ACTION_CHANGE_SEARCH_SOURCE}.
*/
private void handleChangeSourceIntent(Intent intent) {
Uri dataUri = intent.getData();

View File

@@ -1256,6 +1256,41 @@ public class SearchManager
*/
public final static String SHORTCUT_MIME_TYPE =
"vnd.android.cursor.item/vnd.android.search.suggest";
/**
* The authority of the provider to report clicks to when a click is detected after pivoting
* into a specific app's search from global search.
*
* In addition to the columns below, the suggestion columns are used to pass along the full
* suggestion so it can be shortcutted.
*
* @hide
*/
public final static String SEARCH_CLICK_REPORT_AUTHORITY =
"com.android.globalsearch.stats";
/**
* The path the write goes to.
*
* @hide
*/
public final static String SEARCH_CLICK_REPORT_URI_PATH = "click";
/**
* The column storing the query for the click.
*
* @hide
*/
public final static String SEARCH_CLICK_REPORT_COLUMN_QUERY = "query";
/**
* The column storing the component name of the application that was pivoted into.
*
* @hide
*/
public final static String SEARCH_CLICK_REPORT_COLUMN_COMPONENT = "component";
/**
* Column name for suggestions cursor. <i>Unused - can be null or column can be omitted.</i>
*/