Chromium Code Reviews| Index: components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java |
| diff --git a/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java b/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java |
| index b02c6f1adf8d27000ab71e6a0838fbf1c3162402..16f5fbd16ce431bd381d6de1b3a1d9d9ff048a94 100644 |
| --- a/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java |
| +++ b/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java |
| @@ -4,7 +4,6 @@ |
| package org.chromium.components.variations.firstrun; |
| -import android.content.Context; |
| import android.content.SharedPreferences; |
| import android.os.SystemClock; |
| @@ -30,8 +29,11 @@ import java.util.concurrent.TimeUnit; |
| */ |
| public class VariationsSeedFetcher { |
| private static final String TAG = "VariationsSeedFetch"; |
| + |
| + public enum VariationsPlatform { ANDROID, ANDROID_WEBVIEW } |
| + |
| private static final String VARIATIONS_SERVER_URL = |
| - "https://clientservices.googleapis.com/chrome-variations/seed?osname=android"; |
| + "https://clientservices.googleapis.com/chrome-variations/seed?osname="; |
| private static final int BUFFER_SIZE = 4096; |
| private static final int READ_TIMEOUT = 3000; // time in ms |
| @@ -47,7 +49,7 @@ public class VariationsSeedFetcher { |
| @VisibleForTesting |
| static final String VARIATIONS_INITIALIZED_PREF = "variations_initialized"; |
| - // Synchronization lock |
| + // Synchronization lock to make singleton thread-safe |
| private static final Object sLock = new Object(); |
| private static VariationsSeedFetcher sInstance; |
| @@ -77,9 +79,19 @@ public class VariationsSeedFetcher { |
| } |
| @VisibleForTesting |
| - protected HttpURLConnection getServerConnection(String restrictMode) |
| - throws MalformedURLException, IOException { |
| + protected HttpURLConnection getServerConnection(VariationsPlatform platform, |
| + String restrictMode) throws MalformedURLException, IOException { |
| String urlString = VARIATIONS_SERVER_URL; |
| + switch (platform) { |
| + case ANDROID: |
| + urlString += "android"; |
| + break; |
| + case ANDROID_WEBVIEW: |
| + urlString += "android_webview"; |
| + break; |
| + default: |
| + assert false; |
| + } |
| if (restrictMode != null && !restrictMode.isEmpty()) { |
| urlString += "&restrict=" + restrictMode; |
| } |
| @@ -87,6 +99,17 @@ public class VariationsSeedFetcher { |
| return (HttpURLConnection) url.openConnection(); |
| } |
| + /** |
| + * Store the seed and its related header fields. |
|
Alexei Svitkine (slow)
2017/07/12 15:52:50
Nit: Don't use the word "Store" because that's amb
yiyuny
2017/07/12 18:31:30
Done.
|
| + */ |
| + public static class SeedInfo { |
| + public String signature; |
| + public String country; |
| + public String date; |
| + public boolean isGzipCompressed; |
| + public byte[] rawSeed; |
|
Alexei Svitkine (slow)
2017/07/12 15:52:50
Nit: Maybe seedData?
yiyuny
2017/07/12 18:31:30
Done.
|
| + } |
| + |
| /** |
| * Fetch the first run variations seed. |
| * @param restrictMode The restrict mode parameter to pass to the server via a URL param. |
| @@ -95,7 +118,6 @@ public class VariationsSeedFetcher { |
| assert !ThreadUtils.runningOnUiThread(); |
| // Prevent multiple simultaneous fetches |
| synchronized (sLock) { |
| - Context context = ContextUtils.getApplicationContext(); |
| SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); |
| // Early return if an attempt has already been made to fetch the seed, even if it |
| // failed. Only attempt to get the initial Java seed once, since a failure probably |
| @@ -106,7 +128,17 @@ public class VariationsSeedFetcher { |
| || VariationsSeedBridge.hasNativePref()) { |
| return; |
| } |
| - downloadContent(context, restrictMode); |
| + |
| + try { |
| + SeedInfo info = downloadContent(VariationsPlatform.ANDROID, restrictMode); |
| + VariationsSeedBridge.setVariationsFirstRunSeed(info.rawSeed, info.signature, |
| + info.country, info.date, info.isGzipCompressed); |
| + } catch (IOException e) { |
| + // Exceptions are handled in the downloadContent function and rethrowing the |
| + // exception is to stop the normal logic flow after it, so no error-handling here. |
| + // Not explicitly handing SocketTimeoutException and UnknownHostException for they |
| + // are both subclasses of IOException. |
| + } |
| prefs.edit().putBoolean(VARIATIONS_INITIALIZED_PREF, true).apply(); |
| } |
| } |
| @@ -130,11 +162,23 @@ public class VariationsSeedFetcher { |
| histogram.record(timeDeltaMillis); |
| } |
| - private void downloadContent(Context context, String restrictMode) { |
| + /** |
| + * Actually download the variations seed data with platform and retrictMode |
|
Alexei Svitkine (slow)
2017/07/12 15:52:50
Nit: "Actually" doesn't add much, so just start wi
yiyuny
2017/07/12 18:31:30
Done.
|
| + * @param platform The platform parameter to let server only return experiments which can be |
| + * runned on the platform. |
|
Alexei Svitkine (slow)
2017/07/12 15:52:50
"can be run on that platform"
yiyuny
2017/07/12 18:31:30
Done.
|
| + * @param restrictMode The restrict mode parameter to pass to the server via a URL param. |
| + * @throws SocketTimeoutException when fetching seed connection times out. |
| + * @throws UnknownHostException when fetching seed connection has an unknown host. |
| + * @throws IOException when response code is not HTTP_OK or transmission fails on the open |
| + * connection. |
| + */ |
| + public SeedInfo downloadContent(VariationsPlatform platform, String restrictMode) |
| + throws SocketTimeoutException, UnknownHostException, IOException { |
| HttpURLConnection connection = null; |
| + SeedInfo info = null; |
| try { |
| long startTimeMillis = SystemClock.elapsedRealtime(); |
| - connection = getServerConnection(restrictMode); |
| + connection = getServerConnection(platform, restrictMode); |
| connection.setReadTimeout(READ_TIMEOUT); |
| connection.setConnectTimeout(REQUEST_TIMEOUT); |
| connection.setDoInput(true); |
| @@ -143,29 +187,35 @@ public class VariationsSeedFetcher { |
| int responseCode = connection.getResponseCode(); |
| recordFetchResultOrCode(responseCode); |
| if (responseCode != HttpURLConnection.HTTP_OK) { |
| - Log.w(TAG, "Non-OK response code = %d", responseCode); |
| - return; |
| + String errorMsg = "Non-OK response code = " + responseCode; |
| + Log.w(TAG, errorMsg); |
| + throw new IOException(errorMsg); |
| } |
| recordSeedConnectTime(SystemClock.elapsedRealtime() - startTimeMillis); |
| - // Convert the InputStream into a byte array. |
| - byte[] rawSeed = getRawSeed(connection); |
| - String signature = getHeaderFieldOrEmpty(connection, "X-Seed-Signature"); |
| - String country = getHeaderFieldOrEmpty(connection, "X-Country"); |
| - String date = getHeaderFieldOrEmpty(connection, "Date"); |
| - boolean isGzipCompressed = getHeaderFieldOrEmpty(connection, "IM").equals("gzip"); |
| - VariationsSeedBridge.setVariationsFirstRunSeed( |
| - rawSeed, signature, country, date, isGzipCompressed); |
| + |
| + info = new SeedInfo(); |
| + info.rawSeed = getRawSeed(connection); |
| + info.signature = getHeaderFieldOrEmpty(connection, "X-Seed-Signature"); |
| + info.country = getHeaderFieldOrEmpty(connection, "X-Country"); |
| + info.date = getHeaderFieldOrEmpty(connection, "Date"); |
| + info.isGzipCompressed = getHeaderFieldOrEmpty(connection, "IM").equals("gzip"); |
| recordSeedFetchTime(SystemClock.elapsedRealtime() - startTimeMillis); |
| + return info; |
| } catch (SocketTimeoutException e) { |
| recordFetchResultOrCode(SEED_FETCH_RESULT_TIMEOUT); |
| - Log.w(TAG, "SocketTimeoutException fetching first run seed: ", e); |
| + Log.w(TAG, "SocketTimeoutException timeout when fetching variations seed.", e); |
| + throw e; |
| } catch (UnknownHostException e) { |
| recordFetchResultOrCode(SEED_FETCH_RESULT_UNKNOWN_HOST_EXCEPTION); |
| - Log.w(TAG, "UnknownHostException fetching first run seed: ", e); |
| + Log.w(TAG, "UnknownHostException unknown host when fetching variations seed.", e); |
| + throw e; |
| } catch (IOException e) { |
| recordFetchResultOrCode(SEED_FETCH_RESULT_IOEXCEPTION); |
| - Log.w(TAG, "IOException fetching first run seed: ", e); |
| + Log.w(TAG, |
| + "IOException I/O errors while opening the connection to fetch variations seed.", |
| + e); |
| + throw e; |
| } finally { |
| if (connection != null) { |
| connection.disconnect(); |