Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc

Issue 23458016: Added probe to determine if data reduction proxy can be used (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added more unit tests Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h"
6
7 #include "base/android/build_info.h"
8 #include "base/android/jni_android.h"
9 #include "base/android/jni_string.h"
10 #include "base/base64.h"
11 #include "base/command_line.h"
12 #include "base/metrics/field_trial.h"
13 #include "base/metrics/histogram.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/prefs/proxy_prefs.h"
21 #include "chrome/browser/prefs/scoped_user_pref_update.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/profiles/profile_manager.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/pref_names.h"
26 #include "jni/DataReductionProxySettingsAndroid_jni.h"
27 #include "net/base/host_port_pair.h"
28 #include "net/base/load_flags.h"
29 #include "net/base/net_errors.h"
30 #include "net/url_request/url_fetcher.h"
31 #include "net/url_request/url_fetcher_delegate.h"
32 #include "net/url_request/url_request_status.h"
33 #include "url/gurl.h"
34
35 using base::android::CheckException;
36 using base::android::ConvertJavaStringToUTF8;
37 using base::android::ConvertUTF8ToJavaString;
38 using base::android::ScopedJavaLocalRef;
39 using base::FieldTrialList;
40 using base::StringPrintf;
41
42
43 namespace {
44
45 // The C++ definition of enum SpdyProxyAuthState defined in
46 // tools/histograms/histograms.xml.
47 // New values should be added at the end before |NUM_SPDY_PROXY_AUTH_STATE|
48 enum {
49 CHROME_STARTUP,
50 SPDY_PROXY_AUTH_ON_AT_STARTUP,
51 SPDY_PROXY_AUTH_ON_BY_USER,
52 SPDY_PROXY_AUTH_OFF_BY_USER,
53 // Used by UMA histograms and should always be the last value.
54 NUM_SPDY_PROXY_AUTH_STATE
55 };
56
57 bool IsProxyAvailable() {
mmenke 2013/09/12 16:30:41 If a proxy is specified via the command line, shou
bengr 2013/09/17 01:06:19 Done.
58 return (FieldTrialList::FindFullName("DataCompressionProxyRollout") ==
59 "Enabled");
60 }
61
62 bool IsProxyPromoAvailable() {
63 return (IsProxyAvailable() &&
64 FieldTrialList::FindFullName("DataCompressionProxyPromoVisibility") ==
65 "Enabled");
66 }
67
68 int64 GetInt64PrefValue(const ListValue& list_value, size_t index) {
69 int64 val = 0;
70 std::string pref_value;
71 bool rv = list_value.GetString(index, &pref_value);
72 DCHECK(rv);
73 if (rv) {
74 rv = base::StringToInt64(pref_value, &val);
75 DCHECK(rv);
76 }
77 return val;
78 }
79
80 std::string GetProxyCheckURL() {
81 #if defined(DATA_REDUCTION_PROXY_PROBE_URL)
82 return DATA_REDUCTION_PROXY_PROBE_URL;
mmenke 2013/09/12 16:30:41 Should be returning an empty string in the case th
bengr 2013/09/17 01:06:19 We didn't have a switch for this, but I've added o
83 #else
84 return std::string();
85 #endif
86 }
87
88 } // namespace
89
90
91 DataReductionProxySettingsAndroid::DataReductionProxySettingsAndroid(
92 JNIEnv* env, jobject obj)
93 : has_turned_on_(false),
94 has_turned_off_(false),
95 disabled_by_carrier_(false),
96 enabled_by_user_(false),
97 profile_prefs_for_testing_(NULL),
98 local_state_prefs_for_testing_(NULL) {
99 }
100
101 DataReductionProxySettingsAndroid::~DataReductionProxySettingsAndroid() {
102 }
103
104 void DataReductionProxySettingsAndroid::BypassHostPattern(
105 JNIEnv* env, jobject obj, jstring pattern) {
106 AddHostPatternToBypass(ConvertJavaStringToUTF8(env, pattern));
107 }
108 void DataReductionProxySettingsAndroid::BypassURLPattern(
109 JNIEnv* env, jobject obj, jstring pattern) {
110 AddURLPatternToBypass(ConvertJavaStringToUTF8(env, pattern));
111 }
112
113 jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyAvailable(
114 JNIEnv* env, jobject obj) {
115 return IsProxyAvailable();
116 }
117
118 jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyPromoAvailable(
119 JNIEnv* env, jobject obj) {
120 return IsProxyPromoAvailable();
121 }
122
123 std::string
124 DataReductionProxySettingsAndroid::GetDataReductionProxyOriginInternal() {
mmenke 2013/09/12 16:30:41 nit: Definition order should match declaration or
bengr 2013/09/17 01:06:19 Done.
125 if (!IsProxyAvailable())
126 return std::string();
127 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
128 if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin)) {
129 return command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthOrigin);
130 }
131 #if defined(SPDY_PROXY_AUTH_ORIGIN)
132 return SPDY_PROXY_AUTH_ORIGIN;
133 #else
134 return std::string();
135 #endif
136 }
137
138 ScopedJavaLocalRef<jstring>
139 DataReductionProxySettingsAndroid::GetDataReductionProxyOrigin(
140 JNIEnv* env, jobject obj) {
141 return ConvertUTF8ToJavaString(env, GetDataReductionProxyOriginInternal());
142 }
143
144 ScopedJavaLocalRef<jstring>
145 DataReductionProxySettingsAndroid::GetDataReductionProxyAuth(
146 JNIEnv* env, jobject obj) {
147 if (!IsProxyAvailable())
148 return ConvertUTF8ToJavaString(env, std::string());
149 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
150 if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin)) {
151 // If an origin is provided via a switch, then only consider the value
152 // that is provided by a switch. Do not use the preprocessor constant.
153 if (command_line.HasSwitch(switches::kSpdyProxyAuthValue)) {
mmenke 2013/09/12 16:30:41 What if a proxy origin is set via the command line
bengr 2013/09/17 01:06:19 Done.
154 return ConvertUTF8ToJavaString(
155 env,
156 command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthValue));
157 }
158 }
159 #if defined(SPDY_PROXY_AUTH_VALUE)
160 return ConvertUTF8ToJavaString(env, SPDY_PROXY_AUTH_VALUE);
161 #else
162 return ConvertUTF8ToJavaString(env, std::string());
163 #endif
164 }
165
166 jlong DataReductionProxySettingsAndroid::GetDataReductionLastUpdateTime(
167 JNIEnv* env, jobject obj) {
168 PrefService* local_state = GetLocalStatePrefs();
169 int64 last_update_internal =
170 local_state->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate);
171 base::Time last_update = base::Time::FromInternalValue(last_update_internal);
172 return static_cast<int64>(last_update.ToJsTime());
173 }
174
175 base::android::ScopedJavaLocalRef<jobject>
176 DataReductionProxySettingsAndroid::GetContentLengths(JNIEnv* env,
177 jobject obj) {
178 int64 original_content_length;
179 int64 received_content_length;
180 int64 last_update_internal;
181 GetContentLengthsInternal(spdyproxy::kNumDaysInHistorySummary,
182 &original_content_length,
183 &received_content_length, &last_update_internal);
184
185 return Java_ContentLengths_create(env,
186 original_content_length,
187 received_content_length);
188 }
189
190 void DataReductionProxySettingsAndroid::AddDefaultProxyBypassRules() {
191 // localhost
192 AddHostToBypass("localhost");
193 AddHostPatternToBypass("localhost.*");
194 AddHostToBypass("127.0.0.1");
mmenke 2013/09/12 16:30:41 "::1" for IPv6 support? (Or should it be [::1]? -
bengr 2013/09/17 01:06:19 I'll add [::1]. Do you know how to add (and see) l
195 // TODO(bengr): revisit 192.168.*, 10.*, 172.16.0.0 - 172.31.255.255. The
196 // concern was that adding these and other rules would add to the processing
197 // time.
198
199 // TODO(bengr): See http://crbug.com/169959. For some reason the data
200 // reduction proxy is breaking the omnibox SearchProvider. Remove this rule
201 // when this is fixed.
202 AddURLPatternToBypass("http://www.google.com/complete/search*");
203
204 // Check for proxy availability
205 std::string proxy_check_url = GetProxyCheckURL();
206 if (!proxy_check_url.empty()) {
207 AddURLPatternToBypass(GetProxyCheckURL());
208 }
209 }
210
211 void DataReductionProxySettingsAndroid::AddURLPatternToBypass(
212 const std::string& pattern) {
213 AddPatternToBypass("url", pattern);
214 }
215
216 void DataReductionProxySettingsAndroid::AddHostPatternToBypass(
217 const std::string& pattern) {
218 AddPatternToBypass("host", pattern);
219 }
220
221 void DataReductionProxySettingsAndroid::AddPatternToBypass(
222 const std::string& url_or_host,
223 const std::string& pattern) {
224 bypass_rules_.push_back(
225 StringPrintf("shExpMatch(%s, \"%s\")",
226 url_or_host.c_str(), pattern.c_str()));
227 }
228
229 void DataReductionProxySettingsAndroid::AddHostToBypass(
230 const std::string& host) {
231 bypass_rules_.push_back(
232 StringPrintf("host == \"%s\"", host.c_str()));
233 }
234
235 // TODO(bengr): Replace with our own ProxyResolver.
236 std::string DataReductionProxySettingsAndroid::GetProxyPacScript() {
237 std::string bypass_clause = "(" + JoinString(bypass_rules_, ") || (") + ")";
238
239 // We want to fall back to direct loading when the proxy is unavailable and
240 // only process HTTP traffic, so we concoct a PAC configuration
241 // accordingly. (With a statically configured proxy, proxy failures will
242 // simply result in a connection error presented to users.)
243
244 std::string pac = "function FindProxyForURL(url, host) {"
245 " if (" + bypass_clause + ") {"
246 " return \"DIRECT\";"
247 " } "
248 " if (url.substring(0, 5) == \"http:\") {"
249 " return \"HTTPS " + GetDataReductionProxyOriginHostPort() +
250 "; DIRECT\";"
251 " }"
252 " return \"DIRECT\";"
253 "}";
254 return pac;
255 }
256
257 PrefService* DataReductionProxySettingsAndroid::OriginalProfilePrefs() {
258 if (profile_prefs_for_testing_)
259 return profile_prefs_for_testing_;
260 return g_browser_process->profile_manager()->GetDefaultProfile()->
261 GetOriginalProfile()->GetPrefs();
262 }
263
264 PrefService* DataReductionProxySettingsAndroid::GetLocalStatePrefs() {
265 if (local_state_prefs_for_testing_)
266 return local_state_prefs_for_testing_;
267 return g_browser_process->local_state();
268 }
269
270 void DataReductionProxySettingsAndroid::set_profile_prefs_for_testing(
271 PrefService* pref_service) {
272 profile_prefs_for_testing_ = pref_service;
273 }
274
275 void DataReductionProxySettingsAndroid::set_local_state_prefs_for_testing(
276 PrefService* local_state) {
277 local_state_prefs_for_testing_ = local_state;
278 }
279
280 std::string
281 DataReductionProxySettingsAndroid::GetDataReductionProxyOriginHostPort() {
282 std::string spdy_proxy = GetDataReductionProxyOriginInternal();
283 if (spdy_proxy.empty()) {
284 DLOG(ERROR) << "A SPDY proxy has not been set.";
285 return spdy_proxy;
286 }
287 // Remove a trailing slash from the proxy string if one exists as well as
288 // leading HTTPS scheme.
289 return net::HostPortPair::FromURL(GURL(spdy_proxy)).ToString();
290 }
291
292 void DataReductionProxySettingsAndroid::ResetDataReductionStatistics() {
293 PrefService* prefs = GetLocalStatePrefs();
294 if (!prefs)
295 return;
296 ListPrefUpdate original_update(prefs, prefs::kDailyHttpOriginalContentLength);
297 ListPrefUpdate received_update(prefs, prefs::kDailyHttpReceivedContentLength);
298 original_update->Clear();
299 received_update->Clear();
300 for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) {
301 original_update->AppendString(base::Int64ToString(0));
302 received_update->AppendString(base::Int64ToString(0));
303 }
304 }
305
306 void DataReductionProxySettingsAndroid::InitDataReductionProxySettings(
307 JNIEnv* env,
308 jobject obj) {
309 // Disable the proxy is it's not meant to be available.
310 if (!IsProxyAvailable())
311 return;
312
313 AddDefaultProxyBypassRules();
314 net::NetworkChangeNotifier::AddIPAddressObserver(this);
315
316 PrefService* prefs = OriginalProfilePrefs();
317 CommandLine* command_line = CommandLine::ForCurrentProcess();
318 bool spdy_proxy_enabled = prefs->GetBoolean(prefs::kSpdyProxyAuthEnabled);
319
320 // Setting the kEnableSpdyProxyAuth switch has the same effect as enabling
321 // the feature via settings, in that once set, the preference will be sticky
322 // across instances of Chrome. Disabling the feature can only be done through
323 // the settings menu.
324 UMA_HISTOGRAM_ENUMERATION("SpdyProxyAuth.State", CHROME_STARTUP,
325 NUM_SPDY_PROXY_AUTH_STATE);
326 if (command_line->HasSwitch(switches::kEnableSpdyProxyAuth) ||
327 spdy_proxy_enabled) {
328 SetDataReductionProxyEnabled(NULL, NULL, true);
329 } else {
330 LOG(WARNING) << "SPDY proxy OFF at startup.";
mmenke 2013/09/12 16:30:41 Do we really need the log statement? Fine with a
bengr 2013/09/17 01:06:19 Unfortunately, yes. See my reply below.
331 }
332 }
333
334 jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyEnabled(
335 JNIEnv* env, jobject obj) {
336 return OriginalProfilePrefs()->GetBoolean(prefs::kSpdyProxyAuthEnabled);
337 }
338
339 jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyManaged(
340 JNIEnv* env, jobject obj) {
341 return OriginalProfilePrefs()->IsManagedPreference(
342 prefs::kSpdyProxyAuthEnabled);
343 }
344
345 void DataReductionProxySettingsAndroid::SetDataReductionProxyEnabled(
346 JNIEnv* env,
347 jobject obj,
348 jboolean enabled) {
349 // Prevent configuring the proxy when it is unavailable.
350 if (!IsProxyAvailable())
351 return;
352
353 // Check if the proxy has been disabled explicitly by the carrier.
354 ProbeWhetherDataReductionProxyIsAvailable(GetProxyCheckURL());
mmenke 2013/09/12 16:30:41 While this works, it seems weird to me that this i
mmenke 2013/09/12 16:30:41 Should we be doing the probe if the proxy is disab
bengr 2013/09/17 01:06:19 Done.
bengr 2013/09/17 01:06:19 Done.
355
356 PrefService* prefs = OriginalProfilePrefs();
357
358 prefs->SetBoolean(prefs::kSpdyProxyAuthEnabled, enabled);
mmenke 2013/09/12 16:30:41 This seems a little weird to me. Is there any rea
bengr 2013/09/17 01:06:19 Done.
359
360 if (enabled && !prefs->GetBoolean(prefs::kSpdyProxyAuthWasEnabledBefore)) {
361 prefs->SetBoolean(prefs::kSpdyProxyAuthWasEnabledBefore, true);
362 ResetDataReductionStatistics();
363 }
364
365 std::string spdy_proxy_origin = GetDataReductionProxyOriginHostPort();
366
367 // Configure use of the data reduction proxy if it is enabled and the proxy
368 // origin is non-empty.
369 enabled_by_user_= enabled && spdy_proxy_origin != "";
370 SetProxyPac(enabled_by_user_, !env);
mmenke 2013/09/12 16:30:41 To avoid weird duplicate enabled cases, you should
bengr 2013/09/17 01:06:19 Done.
371 }
372
373 void DataReductionProxySettingsAndroid::SetProxyPac(bool enable_spdy_proxy,
374 bool at_startup) {
375 PrefService* prefs = OriginalProfilePrefs();
376 DCHECK(prefs);
377 // Keys duplicated from proxy_config_dictionary.cc
378 // TODO(bengr): Move these to proxy_config_dictionary.h and reuse them here.
379 const char kProxyMode[] = "mode";
380 const char kProxyPacURL[] = "pac_url";
381 const char kAtStartup[] = "at startup";
382 const char kByUser[] = "by user action";
383
384 DictionaryPrefUpdate update(prefs, prefs::kProxy);
385 DictionaryValue* dict = update.Get();
386 if (enable_spdy_proxy) {
387 LOG(WARNING) << "SPDY proxy ON " << (at_startup ? kAtStartup : kByUser);
mmenke 2013/09/12 16:30:41 Not a big fan of LOGs compiled into production cod
bengr 2013/09/17 01:06:19 Unfortunately we do. We have code that searches fo
388 // Convert to a data URI and update the PAC settings.
389 std::string base64_pac;
390 base::Base64Encode(GetProxyPacScript(), &base64_pac);
391
392 dict->SetString(kProxyPacURL,
393 "data:application/x-ns-proxy-autoconfig;base64," +
394 base64_pac);
395 dict->SetString(kProxyMode,
396 ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT));
397
398 if (at_startup) {
399 UMA_HISTOGRAM_ENUMERATION("SpdyProxyAuth.State",
400 SPDY_PROXY_AUTH_ON_AT_STARTUP,
401 NUM_SPDY_PROXY_AUTH_STATE);
402 } else if (!has_turned_on_) {
403 // SPDY proxy auth is turned on by user action for the first time in
404 // this session.
405 UMA_HISTOGRAM_ENUMERATION("SpdyProxyAuth.State",
406 SPDY_PROXY_AUTH_ON_BY_USER,
407 NUM_SPDY_PROXY_AUTH_STATE);
408 has_turned_on_ = true;
409 }
410 } else {
411 LOG(WARNING) << "SPDY proxy OFF " << (at_startup ? kAtStartup : kByUser);
412 dict->SetString(kProxyMode, ProxyModeToString(ProxyPrefs::MODE_SYSTEM));
413 dict->SetString(kProxyPacURL, "");
414
415 if (!at_startup && !has_turned_off_) {
416 UMA_HISTOGRAM_ENUMERATION("SpdyProxyAuth.State",
417 SPDY_PROXY_AUTH_OFF_BY_USER,
418 NUM_SPDY_PROXY_AUTH_STATE);
419 has_turned_off_ = true;
420 }
421 }
422 }
423
424 void DataReductionProxySettingsAndroid::OnIPAddressChanged() {
425 ProbeWhetherDataReductionProxyIsAvailable(GetProxyCheckURL());
426 }
427
428 void
429 DataReductionProxySettingsAndroid::ProbeWhetherDataReductionProxyIsAvailable(
430 const std::string& url) {
mmenke 2013/09/12 16:30:41 Do we really need to take the URL as a parameter?
bengr 2013/09/17 01:06:19 Done.
431 if (url.empty())
432 return;
433 fetcher_.reset(net::URLFetcher::Create(0, GURL(url),
434 net::URLFetcher::GET, this));
435 fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
436 Profile* profile = g_browser_process->profile_manager()->
437 GetDefaultProfile();
438 fetcher_->SetRequestContext(profile->GetRequestContext());
439 // Configure to max_retries at most kMaxRetries times for 5xx errors.
440 static const int kMaxRetries = 5;
441 fetcher_->SetMaxRetriesOn5xx(kMaxRetries);
442 fetcher_->Start();
443 }
444
445 void DataReductionProxySettingsAndroid::OnURLFetchComplete(
446 const net::URLFetcher* source) {
447 net::URLRequestStatus status = source->GetStatus();
448 if (status.status() == net::URLRequestStatus::FAILED &&
449 status.error() == net::ERR_INTERNET_DISCONNECTED) {
450 return;
451 }
452
453 std::string response;
454 source->GetResponseAsString(&response);
455
456 if ("OK" == response.substr(0, 2)) {
457 DVLOG(1) << "The data reduction proxy is not blocked.";
458
459 if (enabled_by_user_ && disabled_by_carrier_) {
460 // The user enabled the proxy, but sometime previously in the session,
461 // the network operator had blocked the proxy. Now that the network
462 // operator is unblocking it, configure it to the user's desires.
463 SetProxyPac(true, false);
464 }
465 disabled_by_carrier_ = false;
466 return;
467 }
468 DVLOG(1) << "The data reduction proxy is blocked.";
469
470 if (enabled_by_user_ && !disabled_by_carrier_) {
471 // Disable the proxy.
472 SetProxyPac(false, false);
473 }
474 disabled_by_carrier_ = true;
475 }
476
477 ScopedJavaLocalRef<jlongArray>
478 DataReductionProxySettingsAndroid::GetDailyContentLengths(
479 JNIEnv* env, const char* pref_name) {
480 jlongArray result = env->NewLongArray(spdyproxy::kNumDaysInHistory);
481 PrefService* local_state = GetLocalStatePrefs();
482 if (!local_state)
483 return ScopedJavaLocalRef<jlongArray>(env, result);
484
485 const ListValue* list_value = local_state->GetList(pref_name);
486 if (list_value->GetSize() != spdyproxy::kNumDaysInHistory)
487 return ScopedJavaLocalRef<jlongArray>(env, result);
488
489 jlong jval[spdyproxy::kNumDaysInHistory];
490 for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) {
491 jval[i] = GetInt64PrefValue(*list_value, i);
492 }
493 env->SetLongArrayRegion(result, 0, spdyproxy::kNumDaysInHistory, jval);
494 return ScopedJavaLocalRef<jlongArray>(env, result);
495 }
496
497 ScopedJavaLocalRef<jlongArray>
498 DataReductionProxySettingsAndroid::GetDailyOriginalContentLengths(
499 JNIEnv* env, jobject obj) {
500 return GetDailyContentLengths(env, prefs::kDailyHttpOriginalContentLength);
501 }
502
503 ScopedJavaLocalRef<jlongArray>
504 DataReductionProxySettingsAndroid::GetDailyReceivedContentLengths(
505 JNIEnv* env, jobject obj) {
506 return GetDailyContentLengths(env, prefs::kDailyHttpReceivedContentLength);
507 }
508
509 void DataReductionProxySettingsAndroid::GetContentLengthsInternal(
510 unsigned int days,
511 int64* original_content_length,
512 int64* received_content_length,
513 int64* last_update_time) {
514 DCHECK_LE(days, spdyproxy::kNumDaysInHistory);
515 PrefService* local_state = GetLocalStatePrefs();
516 if (!local_state) {
517 *original_content_length = 0L;
518 *received_content_length = 0L;
519 *last_update_time = 0L;
520 return;
521 }
522
523 const ListValue* original_list =
524 local_state->GetList(prefs::kDailyHttpOriginalContentLength);
525 const ListValue* received_list =
526 local_state->GetList(prefs::kDailyHttpReceivedContentLength);
527 int64 last_update_internal =
528 local_state->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate);
529
530 if (original_list->GetSize() != spdyproxy::kNumDaysInHistory ||
531 received_list->GetSize() != spdyproxy::kNumDaysInHistory) {
532 *original_content_length = 0L;
533 *received_content_length = 0L;
534 *last_update_time = 0L;
535 return;
536 }
537
538 int64 orig = 0L;
539 int64 recv = 0L;
540 // We include days from the end of the list going backwards.
541 for (unsigned int i = 0; i < days; ++i) {
542 int read_index = spdyproxy::kNumDaysInHistory - 1 - i;
543 std::string result;
544 orig += GetInt64PrefValue(*original_list, read_index);
545 recv += GetInt64PrefValue(*received_list, read_index);
546 }
547 *original_content_length = orig;
548 *received_content_length = recv;
549 *last_update_time = last_update_internal;
550 }
551
552 // Used by generated jni code.
553 static jint Init(JNIEnv* env, jobject obj) {
554 DataReductionProxySettingsAndroid* settings =
555 new DataReductionProxySettingsAndroid(env, obj);
556 return reinterpret_cast<jint>(settings);
557 }
558
559 // static
560 bool DataReductionProxySettingsAndroid::Register(JNIEnv* env) {
561 bool register_natives_impl_result = RegisterNativesImpl(env);
562 return register_natives_impl_result;
563 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698