summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Android (Google) Code Review <android-gerrit@google.com> 2009-06-09 12:45:35 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2009-06-09 12:45:35 -0700
commit9d19fdb231592904b6f8940355d89745719a1ea1 (patch)
tree43ef362cf9f8d739e0dc9d95733f449a669bef24
parent4ab3c00993bd7932e5262d325e6d9943074844ed (diff)
parentd4c98c4c450a95b67fe9746675984333b7653713 (diff)
Merge change 3576 into donut
* changes: Track clicks that occur after pivoting into an app from global search.
-rw-r--r--core/java/android/app/SearchDialog.java109
-rw-r--r--core/java/android/app/SearchManager.java35
2 files changed, 141 insertions, 3 deletions
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 0bb483b40d8b..7de657238bcb 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -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);
- // launch the intent
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
launchIntent(intent);
return true;
@@ -1214,6 +1229,94 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}
/**
+ * 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.
*/
private void launchIntent(Intent intent) {
@@ -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();
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index fc1481f2fa7f..3f0aa950e19c 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -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>
*/