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
3 // found in the LICENSE file.
5 #include "net/base/backoff_entry_serializer.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/time/tick_clock.h"
9 #include "base/values.h"
10 #include "net/base/backoff_entry.h"
13 // Increment this number when changing the serialization format, to avoid old
14 // serialized values loaded from disk etc being misinterpreted.
15 const int kSerializationFormatVersion
= 1;
20 scoped_ptr
<base::Value
> BackoffEntrySerializer::SerializeToValue(
21 const BackoffEntry
& entry
, base::Time time_now
) {
22 scoped_ptr
<base::ListValue
> serialized(new base::ListValue());
23 serialized
->AppendInteger(kSerializationFormatVersion
);
25 serialized
->AppendInteger(entry
.failure_count());
27 // Can't use entry.GetTimeUntilRelease as it doesn't allow negative deltas.
28 base::TimeDelta backoff_duration
=
29 entry
.GetReleaseTime() - entry
.tick_clock()->NowTicks();
30 // Redundantly stores both the remaining time delta and the absolute time.
31 // The delta is used to work around some cases where wall clock time changes.
32 serialized
->AppendDouble(backoff_duration
.InSecondsF());
33 base::Time absolute_release_time
= backoff_duration
+ time_now
;
34 serialized
->AppendString(
35 base::Int64ToString(absolute_release_time
.ToInternalValue()));
37 return serialized
.Pass();
40 scoped_ptr
<BackoffEntry
> BackoffEntrySerializer::DeserializeFromValue(
41 const base::Value
& serialized
, const BackoffEntry::Policy
* policy
,
42 base::TickClock
* tick_clock
, base::Time time_now
) {
43 const base::ListValue
* serialized_list
= nullptr;
44 if (!serialized
.GetAsList(&serialized_list
))
46 if (serialized_list
->GetSize() != 4)
49 if (!serialized_list
->GetInteger(0, &version_number
) ||
50 version_number
!= kSerializationFormatVersion
) {
55 if (!serialized_list
->GetInteger(1, &failure_count
) || failure_count
< 0)
57 double original_backoff_duration_double
;
58 if (!serialized_list
->GetDouble(2, &original_backoff_duration_double
))
60 std::string absolute_release_time_string
;
61 if (!serialized_list
->GetString(3, &absolute_release_time_string
))
63 int64_t absolute_release_time_us
;
64 if (!base::StringToInt64(absolute_release_time_string
,
65 &absolute_release_time_us
) ||
66 absolute_release_time_us
< 0) {
70 scoped_ptr
<BackoffEntry
> entry(new BackoffEntry(policy
, tick_clock
));
72 for (int n
= 0; n
< failure_count
; n
++)
73 entry
->InformOfRequest(false);
75 base::TimeDelta original_backoff_duration
=
76 base::TimeDelta::FromSecondsD(original_backoff_duration_double
);
77 base::Time absolute_release_time
=
78 base::Time::FromInternalValue(absolute_release_time_us
);
79 base::TimeDelta backoff_duration
= absolute_release_time
- time_now
;
80 // In cases where the system wall clock is rewound, use the redundant
81 // original_backoff_duration to ensure the backoff duration isn't longer
82 // than it was before serializing (note that it's not possible to protect
83 // against the clock being wound forward).
84 if (backoff_duration
> original_backoff_duration
)
85 backoff_duration
= original_backoff_duration
;
86 entry
->SetCustomReleaseTime(
87 entry
->BackoffDurationToReleaseTime(backoff_duration
));