Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / file_system_provider / request_manager.cc
blobbcb639fd10434d37ae988d93e6f65ce128eaa1ea
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.
5 #include "chrome/browser/chromeos/file_system_provider/request_manager.h"
7 #include "base/files/file.h"
8 #include "base/stl_util.h"
9 #include "base/trace_event/trace_event.h"
11 namespace chromeos {
12 namespace file_system_provider {
13 namespace {
15 // Timeout in seconds, before a request is considered as stale and hence
16 // aborted.
17 const int kDefaultTimeout = 10;
19 } // namespace
21 std::string RequestTypeToString(RequestType type) {
22 switch (type) {
23 case REQUEST_UNMOUNT:
24 return "REQUEST_UNMOUNT";
25 case GET_METADATA:
26 return "GET_METADATA";
27 case READ_DIRECTORY:
28 return "READ_DIRECTORY";
29 case OPEN_FILE:
30 return "OPEN_FILE";
31 case CLOSE_FILE:
32 return "CLOSE_FILE";
33 case READ_FILE:
34 return "READ_FILE";
35 case CREATE_DIRECTORY:
36 return "CREATE_DIRECTORY";
37 case DELETE_ENTRY:
38 return "DELETE_ENTRY";
39 case CREATE_FILE:
40 return "CREATE_FILE";
41 case COPY_ENTRY:
42 return "COPY_ENTRY";
43 case MOVE_ENTRY:
44 return "MOVE_ENTRY";
45 case TRUNCATE:
46 return "TRUNCATE";
47 case WRITE_FILE:
48 return "WRITE_FILE";
49 case ABORT:
50 return "ABORT";
51 case ADD_WATCHER:
52 return "ADD_WATCHER";
53 case REMOVE_WATCHER:
54 return "REMOVE_WATCHER";
55 case TESTING:
56 return "TESTING";
58 NOTREACHED();
59 return "";
62 RequestManager::RequestManager(
63 NotificationManagerInterface* notification_manager)
64 : notification_manager_(notification_manager),
65 next_id_(1),
66 timeout_(base::TimeDelta::FromSeconds(kDefaultTimeout)),
67 weak_ptr_factory_(this) {
70 RequestManager::~RequestManager() {
71 // Abort all of the active requests.
72 RequestMap::iterator it = requests_.begin();
73 while (it != requests_.end()) {
74 const int request_id = it->first;
75 ++it;
76 RejectRequest(request_id,
77 scoped_ptr<RequestValue>(new RequestValue()),
78 base::File::FILE_ERROR_ABORT);
81 DCHECK_EQ(0u, requests_.size());
82 STLDeleteValues(&requests_);
85 int RequestManager::CreateRequest(RequestType type,
86 scoped_ptr<HandlerInterface> handler) {
87 // The request id is unique per request manager, so per service, thereof
88 // per profile.
89 int request_id = next_id_++;
91 // If cycled the int, then signal an error.
92 if (requests_.find(request_id) != requests_.end())
93 return 0;
95 TRACE_EVENT_ASYNC_BEGIN1("file_system_provider",
96 "RequestManager::Request",
97 request_id,
98 "type",
99 type);
101 Request* request = new Request;
102 request->handler = handler.Pass();
103 requests_[request_id] = request;
104 ResetTimer(request_id);
106 FOR_EACH_OBSERVER(Observer, observers_, OnRequestCreated(request_id, type));
108 // Execute the request implementation. In case of an execution failure,
109 // unregister and return 0. This may often happen, eg. if the providing
110 // extension is not listening for the request event being sent.
111 // In such case, we should abort as soon as possible.
112 if (!request->handler->Execute(request_id)) {
113 DestroyRequest(request_id);
114 return 0;
117 FOR_EACH_OBSERVER(Observer, observers_, OnRequestExecuted(request_id));
119 return request_id;
122 base::File::Error RequestManager::FulfillRequest(
123 int request_id,
124 scoped_ptr<RequestValue> response,
125 bool has_more) {
126 CHECK(response.get());
127 RequestMap::iterator request_it = requests_.find(request_id);
128 if (request_it == requests_.end())
129 return base::File::FILE_ERROR_NOT_FOUND;
131 FOR_EACH_OBSERVER(Observer,
132 observers_,
133 OnRequestFulfilled(request_id, *response.get(), has_more));
135 request_it->second->handler->OnSuccess(request_id, response.Pass(), has_more);
137 if (!has_more) {
138 DestroyRequest(request_id);
139 } else {
140 if (notification_manager_)
141 notification_manager_->HideUnresponsiveNotification(request_id);
142 ResetTimer(request_id);
145 return base::File::FILE_OK;
148 base::File::Error RequestManager::RejectRequest(
149 int request_id,
150 scoped_ptr<RequestValue> response,
151 base::File::Error error) {
152 CHECK(response.get());
153 RequestMap::iterator request_it = requests_.find(request_id);
154 if (request_it == requests_.end())
155 return base::File::FILE_ERROR_NOT_FOUND;
157 FOR_EACH_OBSERVER(Observer,
158 observers_,
159 OnRequestRejected(request_id, *response.get(), error));
160 request_it->second->handler->OnError(request_id, response.Pass(), error);
161 DestroyRequest(request_id);
163 return base::File::FILE_OK;
166 void RequestManager::SetTimeoutForTesting(const base::TimeDelta& timeout) {
167 timeout_ = timeout;
170 std::vector<int> RequestManager::GetActiveRequestIds() const {
171 std::vector<int> result;
173 for (RequestMap::const_iterator request_it = requests_.begin();
174 request_it != requests_.end();
175 ++request_it) {
176 result.push_back(request_it->first);
179 return result;
182 void RequestManager::AddObserver(Observer* observer) {
183 DCHECK(observer);
184 observers_.AddObserver(observer);
187 void RequestManager::RemoveObserver(Observer* observer) {
188 DCHECK(observer);
189 observers_.RemoveObserver(observer);
192 RequestManager::Request::Request() {}
194 RequestManager::Request::~Request() {}
196 void RequestManager::OnRequestTimeout(int request_id) {
197 FOR_EACH_OBSERVER(Observer, observers_, OnRequestTimeouted(request_id));
199 if (!notification_manager_) {
200 RejectRequest(request_id,
201 scoped_ptr<RequestValue>(new RequestValue()),
202 base::File::FILE_ERROR_ABORT);
203 return;
206 notification_manager_->ShowUnresponsiveNotification(
207 request_id,
208 base::Bind(&RequestManager::OnUnresponsiveNotificationResult,
209 weak_ptr_factory_.GetWeakPtr(),
210 request_id));
213 void RequestManager::OnUnresponsiveNotificationResult(
214 int request_id,
215 NotificationManagerInterface::NotificationResult result) {
216 RequestMap::iterator request_it = requests_.find(request_id);
217 if (request_it == requests_.end())
218 return;
220 if (result == NotificationManagerInterface::CONTINUE) {
221 ResetTimer(request_id);
222 return;
225 RejectRequest(request_id,
226 scoped_ptr<RequestValue>(new RequestValue()),
227 base::File::FILE_ERROR_ABORT);
230 void RequestManager::ResetTimer(int request_id) {
231 RequestMap::iterator request_it = requests_.find(request_id);
232 if (request_it == requests_.end())
233 return;
235 request_it->second->timeout_timer.Start(
236 FROM_HERE,
237 timeout_,
238 base::Bind(&RequestManager::OnRequestTimeout,
239 weak_ptr_factory_.GetWeakPtr(),
240 request_id));
243 void RequestManager::DestroyRequest(int request_id) {
244 RequestMap::iterator request_it = requests_.find(request_id);
245 if (request_it == requests_.end())
246 return;
248 delete request_it->second;
249 requests_.erase(request_it);
251 if (notification_manager_)
252 notification_manager_->HideUnresponsiveNotification(request_id);
254 FOR_EACH_OBSERVER(Observer, observers_, OnRequestDestroyed(request_id));
256 TRACE_EVENT_ASYNC_END0(
257 "file_system_provider", "RequestManager::Request", request_id);
260 } // namespace file_system_provider
261 } // namespace chromeos