OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 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 #import "ios/chrome/browser/web/auto_reload_controller.h" |
| 6 |
| 7 #include <memory> |
| 8 |
| 9 #include "base/ios/weak_nsobject.h" |
| 10 #include "base/mac/bind_objc_block.h" |
| 11 #include "base/mac/scoped_nsobject.h" |
| 12 #include "base/timer/timer.h" |
| 13 |
| 14 namespace { |
| 15 |
| 16 base::TimeDelta GetAutoReloadTime(size_t reload_count) { |
| 17 static const int kDelaysMs[] = { |
| 18 0, 5000, 30000, 60000, 300000, 600000, 1800000, |
| 19 }; |
| 20 if (reload_count >= arraysize(kDelaysMs)) |
| 21 reload_count = arraysize(kDelaysMs) - 1; |
| 22 return base::TimeDelta::FromMilliseconds(kDelaysMs[reload_count]); |
| 23 } |
| 24 |
| 25 } // namespace |
| 26 |
| 27 @interface AutoReloadController () { |
| 28 GURL _failedUrl; |
| 29 int _reloadCount; |
| 30 BOOL _shouldReload; |
| 31 BOOL _online; |
| 32 id<AutoReloadDelegate> _delegate; |
| 33 std::unique_ptr<base::Timer> _timer; |
| 34 } |
| 35 |
| 36 // This method is called when the system transitions to offline from online, |
| 37 // possibly causing a paused reload timer to start. |
| 38 - (void)transitionedToOffline; |
| 39 |
| 40 // This method is called when the system transitions from online to offline, |
| 41 // possibly pausing the reload timer. |
| 42 - (void)transitionedToOnline; |
| 43 |
| 44 // This method is called to actually start the reload timer. |
| 45 - (void)startTimer; |
| 46 |
| 47 // This method is called back from the reload timer when it fires. |
| 48 - (void)timerFired; |
| 49 |
| 50 @end |
| 51 |
| 52 @implementation AutoReloadController |
| 53 |
| 54 - (id)initWithDelegate:(id<AutoReloadDelegate>)delegate |
| 55 onlineStatus:(BOOL)online { |
| 56 if ((self = [super init])) { |
| 57 _delegate = delegate; |
| 58 _timer.reset(new base::Timer(false /* don't retain user task */, |
| 59 false /* don't repeat automatically */)); |
| 60 _online = online; |
| 61 } |
| 62 return self; |
| 63 } |
| 64 |
| 65 - (void)loadStartedForURL:(const GURL&)url { |
| 66 if (_timer->IsRunning()) { |
| 67 // Stop the timer, since the starting load was not started by this class and |
| 68 // it would be bad to replace another load. |
| 69 _timer->Stop(); |
| 70 } |
| 71 if (url != _failedUrl) { |
| 72 // Changed URLs, reset the backoff counter. |
| 73 _reloadCount = 0; |
| 74 } |
| 75 } |
| 76 |
| 77 - (void)loadFinishedForURL:(const GURL&)url wasPost:(BOOL)wasPost { |
| 78 DCHECK(!_timer->IsRunning()); |
| 79 } |
| 80 |
| 81 - (void)loadFailedForURL:(const GURL&)url wasPost:(BOOL)wasPost { |
| 82 DCHECK(!_timer->IsRunning()); |
| 83 if (wasPost) |
| 84 return; |
| 85 _failedUrl = url; |
| 86 if (_online) |
| 87 [self startTimer]; |
| 88 else |
| 89 _shouldReload = true; |
| 90 } |
| 91 |
| 92 - (void)networkStateChangedToOnline:(BOOL)online { |
| 93 if (!online && _online) |
| 94 [self transitionedToOffline]; |
| 95 else if (online && !_online) |
| 96 [self transitionedToOnline]; |
| 97 _online = online; |
| 98 } |
| 99 |
| 100 - (void)setTimerForTesting:(std::unique_ptr<base::Timer>)timer { |
| 101 _timer.reset(timer.release()); |
| 102 } |
| 103 |
| 104 - (void)startTimer { |
| 105 base::WeakNSObject<AutoReloadController> weakSelf(self); |
| 106 base::TimeDelta delay = GetAutoReloadTime(_reloadCount); |
| 107 _timer->Start(FROM_HERE, delay, base::BindBlock(^{ |
| 108 base::scoped_nsobject<AutoReloadController> strongSelf( |
| 109 [weakSelf retain]); |
| 110 // self owns the timer owns this closure, so self must outlive |
| 111 // this closure. |
| 112 DCHECK(strongSelf); |
| 113 [strongSelf timerFired]; |
| 114 })); |
| 115 } |
| 116 |
| 117 - (void)transitionedToOffline { |
| 118 DCHECK(!_shouldReload); |
| 119 if (_timer->IsRunning()) { |
| 120 _shouldReload = true; |
| 121 _timer->Stop(); |
| 122 } |
| 123 } |
| 124 |
| 125 - (void)transitionedToOnline { |
| 126 if (_shouldReload) { |
| 127 _shouldReload = false; |
| 128 [self startTimer]; |
| 129 } |
| 130 } |
| 131 |
| 132 - (void)timerFired { |
| 133 _reloadCount++; |
| 134 [_delegate reload]; |
| 135 } |
| 136 |
| 137 @end |
OLD | NEW |