Bug 1007523 - Add UI telemetry for managing search engines. r=liuche
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Tue, 19 Aug 2014 12:25:38 -0700
changeset 200322 c0b30ee8dca44b23f2f28ccb7a0d92214c1a08cf
parent 200321 5cfdd17fdca95c2cc47f9c02f24477394f2e4ab7
child 200323 89304862b06ee5f862e3a81d03b1f139f923c102
push id8281
push usermleibovic@mozilla.com
push dateTue, 19 Aug 2014 19:25:50 +0000
treeherderfx-team@f24fea3d1ab1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersliuche
bugs1007523
milestone34.0a1
Bug 1007523 - Add UI telemetry for managing search engines. r=liuche
mobile/android/base/TelemetryContract.java
mobile/android/base/preferences/GeckoPreferences.java
mobile/android/base/preferences/SearchEnginePreference.java
mobile/android/base/preferences/SearchPreferenceCategory.java
--- a/mobile/android/base/TelemetryContract.java
+++ b/mobile/android/base/TelemetryContract.java
@@ -62,16 +62,25 @@ public interface TelemetryContract {
         SANITIZE("sanitize.1"),
 
         // Saving a resource (reader, bookmark, etc) for viewing later.
         SAVE("save.1"),
 
         // Perform a search -- currently used when starting a search in the search activity.
         SEARCH("search.1"),
 
+        // Remove a search engine.
+        SEARCH_REMOVE("search.remove.1"),
+
+        // Restore default search engines.
+        SEARCH_RESTORE_DEFAULTS("search.restoredefaults.1"),
+
+        // Set default search engine.
+        SEARCH_SET_DEFAULT("search.setdefault.1"),
+
         // Sharing content.
         SHARE("share.1"),
 
         // Undoing a user action.
         // Note: Only used in JavaScript for now, but here for completeness.
         UNDO("undo.1"),
 
         // Unpinning an item.
--- a/mobile/android/base/preferences/GeckoPreferences.java
+++ b/mobile/android/base/preferences/GeckoPreferences.java
@@ -693,16 +693,17 @@ OnSharedPreferenceChangeListener
                     preferences.removePreference(pref);
                     i--;
                     continue;
                 } else if (PREFS_SEARCH_RESTORE_DEFAULTS.equals(key)) {
                     pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                         @Override
                         public boolean onPreferenceClick(Preference preference) {
                             GeckoPreferences.this.restoreDefaultSearchEngines();
+                            Telemetry.sendUIEvent(TelemetryContract.Event.SEARCH_RESTORE_DEFAULTS, Method.LIST_ITEM);
                             return true;
                         }
                     });
                 } else if (handlers.containsKey(key)) {
                     PrefHandler handler = handlers.get(key);
                     handler.setupPref(this, pref);
                 }
 
@@ -752,16 +753,17 @@ OnSharedPreferenceChangeListener
             case android.R.id.home:
                 finishChoosingTransition();
                 return true;
         }
 
         // Generated R.id.* apparently aren't constant expressions, so they can't be switched.
         if (itemId == R.id.restore_defaults) {
             restoreDefaultSearchEngines();
+            Telemetry.sendUIEvent(TelemetryContract.Event.SEARCH_RESTORE_DEFAULTS, Method.MENU);
             return true;
        }
 
         return super.onOptionsItemSelected(item);
     }
 
     final private int DIALOG_CREATE_MASTER_PASSWORD = 0;
     final private int DIALOG_REMOVE_MASTER_PASSWORD = 1;
--- a/mobile/android/base/preferences/SearchEnginePreference.java
+++ b/mobile/android/base/preferences/SearchEnginePreference.java
@@ -32,16 +32,20 @@ public class SearchEnginePreference exte
     // The icon to display in the prompt when clicked.
     private BitmapDrawable mPromptIcon;
 
     // The bitmap backing the drawable above - needed separately for the FaviconView.
     private Bitmap mIconBitmap;
 
     private FaviconView mFaviconView;
 
+    // Search engine identifier specified by the gecko search service. This will be null
+    // for engines that are not shipped with the app.
+    private String mIdentifier;
+
     public SearchEnginePreference(Context context, SearchPreferenceCategory parentCategory) {
         super(context, parentCategory);
     }
 
     /**
      * Called by Android when we're bound to the custom view. Allows us to set the custom properties
      * of our custom view elements as we desire (We can now use findViewById on them).
      *
@@ -108,24 +112,33 @@ public class SearchEnginePreference exte
             case INDEX_REMOVE_BUTTON:
                 mParentCategory.uninstall(this);
                 break;
 
             default:
                 Log.w(LOGTAG, "Selected index out of range.");
                 break;
         }
-     }
+    }
+
+    /**
+     * @return Identifier of built-in search engine, or "other" if engine is not built-in.
+     */
+    public String getIdentifier() {
+        return (mIdentifier == null) ? "other" : mIdentifier;
+    }
 
     /**
      * Configure this Preference object from the Gecko search engine JSON object.
      * @param geckoEngineJSON The Gecko-formatted JSON object representing the search engine.
      * @throws JSONException If the JSONObject is invalid.
      */
     public void setSearchEngineFromJSON(JSONObject geckoEngineJSON) throws JSONException {
+        mIdentifier = geckoEngineJSON.getString("identifier");
+
         final String engineName = geckoEngineJSON.getString("name");
         final SpannableString titleSpannable = new SpannableString(engineName);
 
         setTitle(titleSpannable);
 
         final String iconURI = geckoEngineJSON.getString("iconURI");
         // Keep a reference to the bitmap - we'll need it later in onBindView.
         try {
--- a/mobile/android/base/preferences/SearchPreferenceCategory.java
+++ b/mobile/android/base/preferences/SearchPreferenceCategory.java
@@ -11,16 +11,19 @@ import android.util.Log;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoEvent;
+import org.mozilla.gecko.Telemetry;
+import org.mozilla.gecko.TelemetryContract;
+import org.mozilla.gecko.TelemetryContract.Method;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.ThreadUtils;
 
 public class SearchPreferenceCategory extends CustomListCategory implements GeckoEventListener {
     public static final String LOGTAG = "SearchPrefCategory";
 
     public SearchPreferenceCategory(Context context) {
         super(context);
@@ -40,31 +43,39 @@ public class SearchPreferenceCategory ex
 
         // Register for SearchEngines messages and request list of search engines from Gecko.
         EventDispatcher.getInstance().registerGeckoThreadListener(this, "SearchEngines:Data");
         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("SearchEngines:GetVisible", null));
     }
 
     @Override
     protected void onPrepareForRemoval() {
+        super.onPrepareForRemoval();
+
         EventDispatcher.getInstance().unregisterGeckoThreadListener(this, "SearchEngines:Data");
     }
 
     @Override
     public void setDefault(CustomListPreference item) {
         super.setDefault(item);
 
         sendGeckoEngineEvent("SearchEngines:SetDefault", item.getTitle().toString());
+
+        final String identifier = ((SearchEnginePreference) item).getIdentifier();
+        Telemetry.sendUIEvent(TelemetryContract.Event.SEARCH_SET_DEFAULT, Method.DIALOG, identifier);
     }
 
     @Override
     public void uninstall(CustomListPreference item) {
         super.uninstall(item);
 
         sendGeckoEngineEvent("SearchEngines:Remove", item.getTitle().toString());
+
+        final String identifier = ((SearchEnginePreference) item).getIdentifier();
+        Telemetry.sendUIEvent(TelemetryContract.Event.SEARCH_REMOVE, Method.DIALOG, identifier);
     }
 
     @Override
     public void handleMessage(String event, final JSONObject data) {
         if (event.equals("SearchEngines:Data")) {
             // Parse engines array from JSON.
             JSONArray engines;
             try {
@@ -75,18 +86,17 @@ public class SearchPreferenceCategory ex
             }
 
             // Clear the preferences category from this thread.
             this.removeAll();
 
             // Create an element in this PreferenceCategory for each engine.
             for (int i = 0; i < engines.length(); i++) {
                 try {
-                    JSONObject engineJSON = engines.getJSONObject(i);
-                    final String engineName = engineJSON.getString("name");
+                    final JSONObject engineJSON = engines.getJSONObject(i);
 
                     final SearchEnginePreference enginePreference = new SearchEnginePreference(getContext(), this);
                     enginePreference.setSearchEngineFromJSON(engineJSON);
                     enginePreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                         @Override
                         public boolean onPreferenceClick(Preference preference) {
                             SearchEnginePreference sPref = (SearchEnginePreference) preference;
                             // Display the configuration dialog associated with the tapped engine.