| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.feedback; | 5 package org.chromium.chrome.browser.feedback; |
| 6 | 6 |
| 7 import android.os.SystemClock; | 7 import android.os.SystemClock; |
| 8 | 8 |
| 9 import org.chromium.base.Log; | 9 import org.chromium.base.Log; |
| 10 import org.chromium.base.ThreadUtils; | 10 import org.chromium.base.ThreadUtils; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 static final String SYSTEM_HTTP_KEY = "HTTP connection check (Android networ
k stack)"; | 64 static final String SYSTEM_HTTP_KEY = "HTTP connection check (Android networ
k stack)"; |
| 65 | 65 |
| 66 /** | 66 /** |
| 67 * The key for the data describing whether Chrome was able to successfully c
onnect to the | 67 * The key for the data describing whether Chrome was able to successfully c
onnect to the |
| 68 * HTTPS connection check URL using the Android network stack. | 68 * HTTPS connection check URL using the Android network stack. |
| 69 * This string is user visible. | 69 * This string is user visible. |
| 70 */ | 70 */ |
| 71 @VisibleForTesting | 71 @VisibleForTesting |
| 72 static final String SYSTEM_HTTPS_KEY = "HTTPS connection check (Android netw
ork stack)"; | 72 static final String SYSTEM_HTTPS_KEY = "HTTPS connection check (Android netw
ork stack)"; |
| 73 | 73 |
| 74 private static String getHumanReadableString(Type type) { |
| 75 switch (type) { |
| 76 case CHROME_HTTP: |
| 77 return CHROME_HTTP_KEY; |
| 78 case CHROME_HTTPS: |
| 79 return CHROME_HTTPS_KEY; |
| 80 case SYSTEM_HTTP: |
| 81 return SYSTEM_HTTP_KEY; |
| 82 case SYSTEM_HTTPS: |
| 83 return SYSTEM_HTTPS_KEY; |
| 84 default: |
| 85 throw new IllegalArgumentException("Unknown connection type: " +
type); |
| 86 } |
| 87 } |
| 88 |
| 89 static String getHumanReadableString(int result) { |
| 90 switch (result) { |
| 91 case ConnectivityCheckResult.UNKNOWN: |
| 92 return "UNKNOWN"; |
| 93 case ConnectivityCheckResult.CONNECTED: |
| 94 return "CONNECTED"; |
| 95 case ConnectivityCheckResult.NOT_CONNECTED: |
| 96 return "NOT_CONNECTED"; |
| 97 case ConnectivityCheckResult.TIMEOUT: |
| 98 return "TIMEOUT"; |
| 99 case ConnectivityCheckResult.ERROR: |
| 100 return "ERROR"; |
| 101 default: |
| 102 throw new IllegalArgumentException("Unknown result value: " + re
sult); |
| 103 } |
| 104 } |
| 105 |
| 74 /** | 106 /** |
| 75 * FeedbackData contains the set of information that is to be included in a
feedback report. | 107 * FeedbackData contains the set of information that is to be included in a
feedback report. |
| 76 */ | 108 */ |
| 77 static final class FeedbackData { | 109 static final class FeedbackData { |
| 78 private final Map<Type, Result> mConnections; | 110 private final Map<Type, Integer> mConnections; |
| 79 private final int mTimeoutMs; | 111 private final int mTimeoutMs; |
| 80 private final long mElapsedTimeMs; | 112 private final long mElapsedTimeMs; |
| 81 | 113 |
| 82 private static String getHumanReadableString(Type type) { | 114 FeedbackData(Map<Type, Integer> connections, int timeoutMs, long elapsed
TimeMs) { |
| 83 switch (type) { | |
| 84 case CHROME_HTTP: | |
| 85 return CHROME_HTTP_KEY; | |
| 86 case CHROME_HTTPS: | |
| 87 return CHROME_HTTPS_KEY; | |
| 88 case SYSTEM_HTTP: | |
| 89 return SYSTEM_HTTP_KEY; | |
| 90 case SYSTEM_HTTPS: | |
| 91 return SYSTEM_HTTPS_KEY; | |
| 92 default: | |
| 93 throw new IllegalArgumentException("Unknown connection type:
" + type); | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 FeedbackData(Map<Type, Result> connections, int timeoutMs, long elapsedT
imeMs) { | |
| 98 mConnections = connections; | 115 mConnections = connections; |
| 99 mTimeoutMs = timeoutMs; | 116 mTimeoutMs = timeoutMs; |
| 100 mElapsedTimeMs = elapsedTimeMs; | 117 mElapsedTimeMs = elapsedTimeMs; |
| 101 } | 118 } |
| 102 | 119 |
| 103 /** | 120 /** |
| 104 * @return a {@link Map} with information about connection status for di
fferent connection | 121 * @return a {@link Map} with information about connection status for di
fferent connection |
| 105 * types. | 122 * types. |
| 106 */ | 123 */ |
| 107 @VisibleForTesting | 124 @VisibleForTesting |
| 108 Map<Type, Result> getConnections() { | 125 Map<Type, Integer> getConnections() { |
| 109 return Collections.unmodifiableMap(mConnections); | 126 return Collections.unmodifiableMap(mConnections); |
| 110 } | 127 } |
| 111 | 128 |
| 112 /** | 129 /** |
| 113 * @return the timeout that was used for data collection. | 130 * @return the timeout that was used for data collection. |
| 114 */ | 131 */ |
| 115 @VisibleForTesting | 132 @VisibleForTesting |
| 116 int getTimeoutMs() { | 133 int getTimeoutMs() { |
| 117 return mTimeoutMs; | 134 return mTimeoutMs; |
| 118 } | 135 } |
| 119 | 136 |
| 120 /** | 137 /** |
| 121 * @return the time that was used from starting the check until data was
gathered. | 138 * @return the time that was used from starting the check until data was
gathered. |
| 122 */ | 139 */ |
| 123 @VisibleForTesting | 140 @VisibleForTesting |
| 124 long getElapsedTimeMs() { | 141 long getElapsedTimeMs() { |
| 125 return mElapsedTimeMs; | 142 return mElapsedTimeMs; |
| 126 } | 143 } |
| 127 | 144 |
| 128 /** | 145 /** |
| 129 * @return a {@link Map} with all the data fields for this feedback. | 146 * @return a {@link Map} with all the data fields for this feedback. |
| 130 */ | 147 */ |
| 131 Map<String, String> toMap() { | 148 Map<String, String> toMap() { |
| 132 Map<String, String> map = new HashMap<>(); | 149 Map<String, String> map = new HashMap<>(); |
| 133 for (Map.Entry<Type, Result> entry : mConnections.entrySet()) { | 150 for (Map.Entry<Type, Integer> entry : mConnections.entrySet()) { |
| 134 map.put(getHumanReadableString(entry.getKey()), entry.getValue()
.name()); | 151 map.put(getHumanReadableString(entry.getKey()), |
| 152 getHumanReadableString(entry.getValue())); |
| 135 } | 153 } |
| 136 map.put(CONNECTION_CHECK_TIMEOUT_MS, String.valueOf(mTimeoutMs)); | 154 map.put(CONNECTION_CHECK_TIMEOUT_MS, String.valueOf(mTimeoutMs)); |
| 137 map.put(CONNECTION_CHECK_ELAPSED_MS, String.valueOf(mElapsedTimeMs))
; | 155 map.put(CONNECTION_CHECK_ELAPSED_MS, String.valueOf(mElapsedTimeMs))
; |
| 138 return map; | 156 return map; |
| 139 } | 157 } |
| 140 } | 158 } |
| 141 | 159 |
| 142 /** | 160 /** |
| 143 * The type of network stack and connectivity check this result is about. | 161 * The type of network stack and connectivity check this result is about. |
| 144 */ | 162 */ |
| 145 public enum Type { CHROME_HTTP, CHROME_HTTPS, SYSTEM_HTTP, SYSTEM_HTTPS } | 163 public enum Type { CHROME_HTTP, CHROME_HTTPS, SYSTEM_HTTP, SYSTEM_HTTPS } |
| 146 | 164 |
| 147 /** | |
| 148 * The result from the connectivity check. Will be {@link Result#UNKNOWN} if
the result is not | |
| 149 * ready yet. | |
| 150 */ | |
| 151 public enum Result { UNKNOWN, NOT_CONNECTED, CONNECTED } | |
| 152 | |
| 153 private class SingleTypeTask implements ConnectivityChecker.ConnectivityChec
kerCallback { | 165 private class SingleTypeTask implements ConnectivityChecker.ConnectivityChec
kerCallback { |
| 154 private final Type mType; | 166 private final Type mType; |
| 155 | 167 |
| 156 public SingleTypeTask(Type type) { | 168 public SingleTypeTask(Type type) { |
| 157 mType = type; | 169 mType = type; |
| 158 } | 170 } |
| 159 | 171 |
| 160 /** | 172 /** |
| 161 * Starts the current task by calling the appropriate method on the | 173 * Starts the current task by calling the appropriate method on the |
| 162 * {@link ConnectivityChecker}. | 174 * {@link ConnectivityChecker}. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 178 break; | 190 break; |
| 179 case SYSTEM_HTTPS: | 191 case SYSTEM_HTTPS: |
| 180 ConnectivityChecker.checkConnectivitySystemNetworkStack(true
, timeoutMs, this); | 192 ConnectivityChecker.checkConnectivitySystemNetworkStack(true
, timeoutMs, this); |
| 181 break; | 193 break; |
| 182 default: | 194 default: |
| 183 Log.e(TAG, "Failed to recognize type " + mType); | 195 Log.e(TAG, "Failed to recognize type " + mType); |
| 184 } | 196 } |
| 185 } | 197 } |
| 186 | 198 |
| 187 @Override | 199 @Override |
| 188 public void onResult(boolean connected) { | 200 public void onResult(int result) { |
| 189 Log.v(TAG, "Got result for " + mType + ": connected = " + connected)
; | 201 ThreadUtils.assertOnUiThread(); |
| 190 Result result = connected ? Result.CONNECTED : Result.NOT_CONNECTED; | 202 Log.v(TAG, "Got result for " + getHumanReadableString(mType) + ": re
sult = " |
| 203 + getHumanReadableString(result)); |
| 191 mResult.put(mType, result); | 204 mResult.put(mType, result); |
| 192 } | 205 } |
| 193 } | 206 } |
| 194 | 207 |
| 195 private final Map<Type, Result> mResult = new EnumMap<Type, Result>(Type.cla
ss); | 208 private final Map<Type, Integer> mResult = new EnumMap<Type, Integer>(Type.c
lass); |
| 196 private final int mTimeoutMs; | 209 private final int mTimeoutMs; |
| 197 private final long mStartCheckTimeMs; | 210 private final long mStartCheckTimeMs; |
| 198 | 211 |
| 199 private ConnectivityTask(Profile profile, int timeoutMs) { | 212 private ConnectivityTask(Profile profile, int timeoutMs) { |
| 200 mTimeoutMs = timeoutMs; | 213 mTimeoutMs = timeoutMs; |
| 201 mStartCheckTimeMs = SystemClock.elapsedRealtime(); | 214 mStartCheckTimeMs = SystemClock.elapsedRealtime(); |
| 202 for (Type t : Type.values()) { | 215 for (Type t : Type.values()) { |
| 203 SingleTypeTask task = new SingleTypeTask(t); | 216 SingleTypeTask task = new SingleTypeTask(t); |
| 204 task.start(profile, timeoutMs); | 217 task.start(profile, timeoutMs); |
| 205 } | 218 } |
| 206 } | 219 } |
| 207 | 220 |
| 208 /** | 221 /** |
| 209 * @return whether all connectivity type results have been collected. | 222 * @return whether all connectivity type results have been collected. |
| 210 */ | 223 */ |
| 211 public boolean isDone() { | 224 public boolean isDone() { |
| 212 ThreadUtils.assertOnUiThread(); | 225 ThreadUtils.assertOnUiThread(); |
| 213 return mResult.size() == Type.values().length; | 226 return mResult.size() == Type.values().length; |
| 214 } | 227 } |
| 215 | 228 |
| 216 /** | 229 /** |
| 217 * Retrieves the connectivity that has been collected up until this call. Th
is method fills in | 230 * Retrieves the connectivity that has been collected up until this call. Th
is method fills in |
| 218 * {@link Result#UNKNOWN} for results that have not been retrieved yet. | 231 * {@link ConnectivityCheckResult#UNKNOWN} for results that have not been re
trieved yet. |
| 219 * | 232 * |
| 220 * @return the {@link FeedbackData}. | 233 * @return the {@link FeedbackData}. |
| 221 */ | 234 */ |
| 222 public FeedbackData get() { | 235 public FeedbackData get() { |
| 223 ThreadUtils.assertOnUiThread(); | 236 ThreadUtils.assertOnUiThread(); |
| 224 Map<Type, Result> result = new EnumMap<Type, Result>(Type.class); | 237 Map<Type, Integer> result = new EnumMap<Type, Integer>(Type.class); |
| 225 // Ensure the map is filled with a result for all {@link Type}s. | 238 // Ensure the map is filled with a result for all {@link Type}s. |
| 226 for (Type type : Type.values()) { | 239 for (Type type : Type.values()) { |
| 227 if (mResult.containsKey(type)) { | 240 if (mResult.containsKey(type)) { |
| 228 result.put(type, mResult.get(type)); | 241 result.put(type, mResult.get(type)); |
| 229 } else { | 242 } else { |
| 230 result.put(type, Result.UNKNOWN); | 243 result.put(type, ConnectivityCheckResult.UNKNOWN); |
| 231 } | 244 } |
| 232 } | 245 } |
| 233 long elapsedTimeMs = SystemClock.elapsedRealtime() - mStartCheckTimeMs; | 246 long elapsedTimeMs = SystemClock.elapsedRealtime() - mStartCheckTimeMs; |
| 234 return new FeedbackData(result, mTimeoutMs, elapsedTimeMs); | 247 return new FeedbackData(result, mTimeoutMs, elapsedTimeMs); |
| 235 } | 248 } |
| 236 | 249 |
| 237 /** | 250 /** |
| 238 * Starts an asynchronous request for checking whether the device is current
ly connected to the | 251 * Starts an asynchronous request for checking whether the device is current
ly connected to the |
| 239 * Internet using both the Chrome and the Android system network stack. | 252 * Internet using both the Chrome and the Android system network stack. |
| 240 * | 253 * |
| 241 * The result can be retrieved by calling {@link #get}, and this call must h
appen from the main | 254 * The result can be retrieved by calling {@link #get}, and this call must h
appen from the main |
| 242 * thread. {@link #isDone} can be used to see if all requests have been comp
leted. It is OK to | 255 * thread. {@link #isDone} can be used to see if all requests have been comp
leted. It is OK to |
| 243 * get the result before {@link #isDone()} returns true. | 256 * get the result before {@link #isDone()} returns true. |
| 244 * | 257 * |
| 245 * @param profile the context to do the check in. | 258 * @param profile the context to do the check in. |
| 246 * @param timeoutMs number of milliseconds to wait before giving up waiting
for a connection. | 259 * @param timeoutMs number of milliseconds to wait before giving up waiting
for a connection. |
| 247 * @return a Future to retrieve the results. | 260 * @return a ConnectivityTask to retrieve the results. |
| 248 */ | 261 */ |
| 249 public static ConnectivityTask create(Profile profile, int timeoutMs) { | 262 public static ConnectivityTask create(Profile profile, int timeoutMs) { |
| 250 ThreadUtils.assertOnUiThread(); | 263 ThreadUtils.assertOnUiThread(); |
| 251 return new ConnectivityTask(profile, timeoutMs); | 264 return new ConnectivityTask(profile, timeoutMs); |
| 252 } | 265 } |
| 253 } | 266 } |
| OLD | NEW |