Bug 1369685 - Add 'region' to switchboard. r?sebastian draft
authorNevin Chen <cnevinchen@gmail.com>
Fri, 02 Jun 2017 18:08:20 +0800
changeset 590777 1dee6ca782a0912525facafa4457306ff553bf57
parent 586536 39d5cc0fda5e16c49a59d29d4ca186a5534cc88b
child 632303 be3e73143e49f2a868e2a9400f8ff407e56d7365
push id62825
push userbmo:cnevinchen@gmail.com
push dateThu, 08 Jun 2017 03:02:30 +0000
reviewerssebastian
bugs1369685
milestone55.0a1
Bug 1369685 - Add 'region' to switchboard. r?sebastian MozReview-Commit-ID: EWlx3bkpTwj
mobile/android/base/java/org/mozilla/gecko/search/SearchEngineManager.java
mobile/android/base/java/org/mozilla/gecko/switchboard/SwitchBoard.java
--- a/mobile/android/base/java/org/mozilla/gecko/search/SearchEngineManager.java
+++ b/mobile/android/base/java/org/mozilla/gecko/search/SearchEngineManager.java
@@ -60,17 +60,17 @@ public class SearchEngineManager impleme
 
     // Gecko pref that defines the name of the default searchplugin locale.
     private static final String PREF_GECKO_DEFAULT_LOCALE = "distribution.searchplugins.defaultLocale";
 
     // Key for shared preference that stores default engine name.
     private static final String PREF_DEFAULT_ENGINE_KEY = "search.engines.defaultname";
 
     // Key for shared preference that stores search region.
-    private static final String PREF_REGION_KEY = "search.region";
+    public static final String PREF_REGION_KEY = "search.region";
 
     // URL for the geo-ip location service. Keep in sync with "browser.search.geoip.url" perference in Gecko.
     private static final String GEOIP_LOCATION_URL = "https://location.services.mozilla.com/v1/country?key=" + AppConstants.MOZ_MOZILLA_API_KEY;
 
     // The API we're using requires a file size, so set an arbitrarily large one
     public static final int MAX_LISTJSON_SIZE = 8192;
 
     // This should go through GeckoInterface to get the UA, but the search activity
--- a/mobile/android/base/java/org/mozilla/gecko/switchboard/SwitchBoard.java
+++ b/mobile/android/base/java/org/mozilla/gecko/switchboard/SwitchBoard.java
@@ -28,16 +28,18 @@ import java.util.List;
 import java.util.Locale;
 import java.util.MissingResourceException;
 import java.util.zip.CRC32;
 
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.json.JSONArray;
 import org.mozilla.gecko.AppConstants;
+import org.mozilla.gecko.GeckoSharedPrefs;
+import org.mozilla.gecko.search.SearchEngineManager;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.IOUtils;
 import org.mozilla.gecko.util.ProxySelector;
 
 import android.content.Context;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Build;
 import android.support.annotation.NonNull;
@@ -75,16 +77,17 @@ public class SwitchBoard {
     private static final String KEY_NAME = "name";
     private static final String KEY_MATCH = "match";
     private static final String KEY_BUCKETS = "buckets";
     private static final String KEY_VALUES = "values";
 
     // Match keys.
     private static final String KEY_APP_ID = "appId";
     private static final String KEY_COUNTRY = "country";
+    private static final String KEY_REGION = "regions";
     private static final String KEY_DEVICE = "device";
     private static final String KEY_LANG = "lang";
     private static final String KEY_MANUFACTURER = "manufacturer";
     private static final String KEY_VERSION = "version";
 
     // Bucket keys.
     private static final String KEY_MIN = "min";
     private static final String KEY_MAX = "max";
@@ -170,16 +173,30 @@ public class SwitchBoard {
         } catch (JSONException e) {
             // If the experiment name is not found in the JSON, just return false.
             // There is no need to log an error, since we don't really care if an
             // inactive experiment is missing from the config.
             return false;
         }
     }
 
+    private static boolean isTargetRegion(JSONArray regions, String region) throws JSONException {
+        if (regions == null || region == null) {
+            return false;
+        }
+        for (int i = 0; i < regions.length(); i++) {
+
+            final String checkingRegion = regions.getString(i);
+            if (checkingRegion.equalsIgnoreCase(region)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private static List<String> getExperimentNames(Context c) throws JSONException {
         // TODO: cache the array into a mapping so we don't do a loop everytime we are looking for a experiment key
         final List<String> returnList = new ArrayList<>();
         final String config = Preferences.getDynamicConfigJson(c);
         final JSONArray experiments = new JSONObject(config).getJSONArray(KEY_DATA);
 
         for (int i = 0; i < experiments.length(); i++) {
             JSONObject entry = experiments.getJSONObject(i);
@@ -293,16 +310,35 @@ public class SwitchBoard {
                         && !version.matches(expectedVersionPattern)) {
                     return false;
                 }
             } catch (NameNotFoundException | JSONException e) {
                 Log.e(TAG, "Exception matching version", e);
             }
         }
 
+        if (matchKeys.has(KEY_REGION)) {
+            try {
+                final JSONArray regions = matchKeys.getJSONArray(KEY_REGION);
+                if (regions.length() <= 0) {
+                    return true; // If the array is empty then I guess this means there are no region restrictions
+                }
+                final String region = GeckoSharedPrefs.forApp(context).getString(SearchEngineManager.PREF_REGION_KEY, null);
+
+                if (!isTargetRegion(regions, region)) {
+                    return false;
+                }
+            } catch (JSONException e) {
+                // If the JSON is somehow broken (or this version doesn't understand a different format),
+                // just log and continue
+                Log.e(TAG, "Exception matching region", e);
+            }
+        }
+
+
         // Default to return true if no matches failed.
         return true;
     }
 
     /**
      * @return a list of all active experiments.
      */
     public static List<String> getActiveExperiments(Context c) {