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

Side by Side Diff: chrome/browser/chromeos/drive/drive_scheduler.cc

Issue 11142036: Add Move operation to the the scheduler (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "chrome/browser/chromeos/drive/drive_scheduler.h" 5 #include "chrome/browser/chromeos/drive/drive_scheduler.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
(...skipping 15 matching lines...) Expand all
26 DriveScheduler::JobInfo::JobInfo(JobType in_job_type, FilePath in_file_path) 26 DriveScheduler::JobInfo::JobInfo(JobType in_job_type, FilePath in_file_path)
27 : job_type(in_job_type), 27 : job_type(in_job_type),
28 job_id(-1), 28 job_id(-1),
29 completed_bytes(0), 29 completed_bytes(0),
30 total_bytes(0), 30 total_bytes(0),
31 file_path(in_file_path), 31 file_path(in_file_path),
32 state(STATE_NONE) { 32 state(STATE_NONE) {
33 } 33 }
34 34
35 DriveScheduler::QueueEntry::QueueEntry(JobType in_job_type, 35 DriveScheduler::QueueEntry::QueueEntry(JobType in_job_type,
36 FilePath in_file_path) 36 FilePath in_file_path,
37 : job_info(TYPE_REMOVE, in_file_path) { 37 FileOperationCallback in_callback)
38 : job_info(in_job_type, in_file_path),
39 callback(in_callback),
40 is_recursive(false) {
38 } 41 }
39 42
40 DriveScheduler::QueueEntry::~QueueEntry() { 43 DriveScheduler::QueueEntry::~QueueEntry() {
41 } 44 }
42 45
43 DriveScheduler::RemoveJobPrivate::RemoveJobPrivate(
44 bool in_is_recursive,
45 FileOperationCallback in_callback)
46 : is_recursive(in_is_recursive),
47 callback(in_callback) {
48 }
49
50 DriveScheduler::RemoveJobPrivate::~RemoveJobPrivate() {
51 }
52
53 DriveScheduler::DriveScheduler(Profile* profile, 46 DriveScheduler::DriveScheduler(Profile* profile,
54 file_system::DriveOperations* drive_operations) 47 file_system::DriveOperations* drive_operations)
55 : job_loop_is_running_(false), 48 : job_loop_is_running_(false),
56 next_job_id_(0), 49 next_job_id_(0),
57 throttle_count_(0), 50 throttle_count_(0),
58 disable_throttling_(false), 51 disable_throttling_(false),
59 drive_operations_(drive_operations), 52 drive_operations_(drive_operations),
60 profile_(profile), 53 profile_(profile),
61 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 54 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
62 initialized_(false) { 55 initialized_(false) {
(...skipping 11 matching lines...) Expand all
74 67
75 // Initialize() may be called more than once for the lifetime when the 68 // Initialize() may be called more than once for the lifetime when the
76 // file system is remounted. 69 // file system is remounted.
77 if (initialized_) 70 if (initialized_)
78 return; 71 return;
79 72
80 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 73 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
81 initialized_ = true; 74 initialized_ = true;
82 } 75 }
83 76
77 void DriveScheduler::Move(const FilePath& src_file_path,
78 const FilePath& dest_file_path,
79 const FileOperationCallback& callback) {
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
81
82 scoped_ptr<QueueEntry> new_job(
83 new QueueEntry(TYPE_MOVE, src_file_path, callback));
84 new_job->dest_file_path = dest_file_path;
85
86 QueueJob(new_job.Pass());
87
88 StartJobLoop();
89 }
90
84 void DriveScheduler::Remove(const FilePath& file_path, 91 void DriveScheduler::Remove(const FilePath& file_path,
85 bool is_recursive, 92 bool is_recursive,
86 const FileOperationCallback& callback) { 93 const FileOperationCallback& callback) {
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
88 95
89 QueueEntry* new_job = new QueueEntry(TYPE_REMOVE, file_path); 96 scoped_ptr<QueueEntry> new_job(
90 new_job->remove_private.reset(new RemoveJobPrivate(is_recursive, callback)); 97 new QueueEntry(TYPE_REMOVE, file_path, callback));
98 new_job->is_recursive = is_recursive;
91 99
92 QueueJob(new_job); 100 QueueJob(new_job.Pass());
93 101
94 StartJobLoop(); 102 StartJobLoop();
95 } 103 }
96 104
97 int DriveScheduler::QueueJob(QueueEntry* job) { 105 int DriveScheduler::QueueJob(scoped_ptr<QueueEntry> job) {
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
99 107
100 int job_id = next_job_id_; 108 int job_id = next_job_id_;
101 job->job_info.job_id = job_id; 109 job->job_info.job_id = job_id;
102 next_job_id_++; 110 next_job_id_++;
103 111
104 queue_.push_back(job_id); 112 queue_.push_back(job_id);
105 113
106 DCHECK(job_info_.find(job_id) == job_info_.end()); 114 DCHECK(job_info_map_.find(job_id) == job_info_map_.end());
107 job_info_[job_id] = make_linked_ptr(job); 115 job_info_map_[job_id] = make_linked_ptr(job.release());
108 116
109 return job_id; 117 return job_id;
110 } 118 }
111 119
112 void DriveScheduler::StartJobLoop() { 120 void DriveScheduler::StartJobLoop() {
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
114 122
115 if (!job_loop_is_running_) 123 if (!job_loop_is_running_)
116 DoJobLoop(); 124 DoJobLoop();
117 } 125 }
118 126
119 void DriveScheduler::DoJobLoop() { 127 void DriveScheduler::DoJobLoop() {
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
121 129
122 if (queue_.empty() || ShouldStopJobLoop()) { 130 if (queue_.empty() || ShouldStopJobLoop()) {
123 // Note that |queue_| is not cleared so the sync loop can resume. 131 // Note that |queue_| is not cleared so the sync loop can resume.
124 job_loop_is_running_ = false; 132 job_loop_is_running_ = false;
125 return; 133 return;
126 } 134 }
127 job_loop_is_running_ = true; 135 job_loop_is_running_ = true;
128 136
129 // Should copy before calling queue_.pop_front(). 137 // Should copy before calling queue_.pop_front().
130 int job_id = queue_.front(); 138 int job_id = queue_.front();
131 queue_.pop_front(); 139 queue_.pop_front();
132 140
133 JobMap::iterator job_iter = job_info_.find(job_id); 141 JobMap::iterator job_iter = job_info_map_.find(job_id);
134 DCHECK(job_iter != job_info_.end()); 142 DCHECK(job_iter != job_info_map_.end());
135 143
136 JobInfo& job_info = job_iter->second->job_info; 144 JobInfo& job_info = job_iter->second->job_info;
137 job_info.state = STATE_RUNNING; 145 job_info.state = STATE_RUNNING;
138 146
139 switch (job_info.job_type) { 147 switch (job_info.job_type) {
140 case TYPE_REMOVE: { 148 case TYPE_MOVE: {
141 DCHECK(job_iter->second->remove_private.get()); 149 drive_operations_->Move(
142
143 drive_operations_->Remove(
144 job_info.file_path, 150 job_info.file_path,
145 job_iter->second->remove_private->is_recursive, 151 job_iter->second->dest_file_path,
146 base::Bind(&DriveScheduler::OnRemoveDone, 152 base::Bind(&DriveScheduler::OnJobDone,
147 weak_ptr_factory_.GetWeakPtr(), 153 weak_ptr_factory_.GetWeakPtr(),
148 job_id)); 154 job_id));
149 } 155 }
150 break; 156 break;
157
158 case TYPE_REMOVE: {
159 drive_operations_->Remove(
160 job_info.file_path,
161 job_iter->second->is_recursive,
162 base::Bind(&DriveScheduler::OnJobDone,
163 weak_ptr_factory_.GetWeakPtr(),
164 job_id));
165 }
166 break;
167
168 // There is no default case so that there will be a compiler error if a type
169 // is added but unhandled.
151 } 170 }
152
153 } 171 }
154 172
155 bool DriveScheduler::ShouldStopJobLoop() { 173 bool DriveScheduler::ShouldStopJobLoop() {
156 // Should stop if the gdata feature was disabled while running the fetch 174 // Should stop if the gdata feature was disabled while running the fetch
157 // loop. 175 // loop.
158 if (profile_->GetPrefs()->GetBoolean(prefs::kDisableDrive)) 176 if (profile_->GetPrefs()->GetBoolean(prefs::kDisableDrive))
159 return true; 177 return true;
160 178
161 // Should stop if the network is not online. 179 // Should stop if the network is not online.
162 if (net::NetworkChangeNotifier::IsOffline()) 180 if (net::NetworkChangeNotifier::IsOffline())
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 DCHECK(posted); 214 DCHECK(posted);
197 } 215 }
198 216
199 void DriveScheduler::ResetThrottleAndContinueJobLoop() { 217 void DriveScheduler::ResetThrottleAndContinueJobLoop() {
200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
201 219
202 throttle_count_ = 0; 220 throttle_count_ = 0;
203 DoJobLoop(); 221 DoJobLoop();
204 } 222 }
205 223
206 void DriveScheduler::OnRemoveDone(int job_id, DriveFileError error) { 224 void DriveScheduler::OnJobDone(int job_id, DriveFileError error) {
207 JobMap::iterator job_iter = job_info_.find(job_id); 225 JobMap::iterator job_iter = job_info_map_.find(job_id);
208 DCHECK(job_iter != job_info_.end()); 226 DCHECK(job_iter != job_info_map_.end());
209 227
210 // Retry, depending on the error. 228 // Retry, depending on the error.
211 if (error == DRIVE_FILE_ERROR_THROTTLED || 229 if (error == DRIVE_FILE_ERROR_THROTTLED ||
212 error == DRIVE_FILE_ERROR_NO_CONNECTION) { 230 error == DRIVE_FILE_ERROR_NO_CONNECTION) {
213 job_iter->second->job_info.state = STATE_RETRY; 231 job_iter->second->job_info.state = STATE_RETRY;
214 232
215 // Requeue the job. 233 // Requeue the job.
216 queue_.push_back(job_id); 234 queue_.push_back(job_id);
217 ThrottleAndContinueJobLoop(); 235 ThrottleAndContinueJobLoop();
218 } else { 236 } else {
219 DCHECK(job_iter->second->remove_private.get());
220
221 // Handle the callback. 237 // Handle the callback.
222 if (!job_iter->second->remove_private->callback.is_null()) { 238 if (!job_iter->second->callback.is_null()) {
223 MessageLoop::current()->PostTask(FROM_HERE, 239 MessageLoop::current()->PostTask(FROM_HERE,
224 base::Bind(job_iter->second->remove_private->callback, error)); 240 base::Bind(job_iter->second->callback, error));
225 } 241 }
226 242
227 // Delete the job. 243 // Delete the job.
228 job_info_.erase(job_id); 244 job_info_map_.erase(job_id);
229 ResetThrottleAndContinueJobLoop(); 245 ResetThrottleAndContinueJobLoop();
230 } 246 }
231 } 247 }
232 248
233 void DriveScheduler::OnConnectionTypeChanged( 249 void DriveScheduler::OnConnectionTypeChanged(
234 net::NetworkChangeNotifier::ConnectionType type) { 250 net::NetworkChangeNotifier::ConnectionType type) {
235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 251 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
236 252
237 // Resume the job loop if the network is back online. Note that we don't 253 // Resume the job loop if the network is back online. Note that we don't
238 // need to check the type of the network as it will be checked in 254 // need to check the type of the network as it will be checked in
239 // ShouldStopJobLoop() as soon as the loop is resumed. 255 // ShouldStopJobLoop() as soon as the loop is resumed.
240 if (!net::NetworkChangeNotifier::IsOffline()) 256 if (!net::NetworkChangeNotifier::IsOffline())
241 StartJobLoop(); 257 StartJobLoop();
242 } 258 }
243 259
244 } // namespace drive 260 } // namespace drive
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/drive/drive_scheduler.h ('k') | chrome/browser/chromeos/drive/drive_scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698