#include "chrome/browser/chromeos/file_system_provider/request_manager.h"
+#include "base/debug/trace_event.h"
#include "base/files/file.h"
#include "base/stl_util.h"
return "CLOSE_FILE";
case READ_FILE:
return "READ_FILE";
+ case CREATE_DIRECTORY:
+ return "CREATE_DIRECTORY";
+ case DELETE_ENTRY:
+ return "DELETE_ENTRY";
+ case CREATE_FILE:
+ return "CREATE_FILE";
+ case COPY_ENTRY:
+ return "COPY_ENTRY";
+ case MOVE_ENTRY:
+ return "MOVE_ENTRY";
+ case TRUNCATE:
+ return "TRUNCATE";
+ case WRITE_FILE:
+ return "WRITE_FILE";
case TESTING:
return "TESTING";
}
return "";
}
-RequestManager::RequestManager()
- : next_id_(1),
+RequestManager::RequestManager(
+ NotificationManagerInterface* notification_manager)
+ : notification_manager_(notification_manager),
+ next_id_(1),
timeout_(base::TimeDelta::FromSeconds(kDefaultTimeout)),
- weak_ptr_factory_(this) {}
+ weak_ptr_factory_(this) {
+}
RequestManager::~RequestManager() {
// Abort all of the active requests.
while (it != requests_.end()) {
const int request_id = it->first;
++it;
- RejectRequest(request_id, base::File::FILE_ERROR_ABORT);
+ RejectRequest(request_id,
+ scoped_ptr<RequestValue>(new RequestValue()),
+ base::File::FILE_ERROR_ABORT);
}
DCHECK_EQ(0u, requests_.size());
if (requests_.find(request_id) != requests_.end())
return 0;
+ TRACE_EVENT_ASYNC_BEGIN1("file_system_provider",
+ "RequestManager::Request",
+ request_id,
+ "type",
+ type);
+
Request* request = new Request;
request->handler = handler.Pass();
- request->timeout_timer.Start(FROM_HERE,
- timeout_,
- base::Bind(&RequestManager::OnRequestTimeout,
- weak_ptr_factory_.GetWeakPtr(),
- request_id));
requests_[request_id] = request;
+ ResetTimer(request_id);
FOR_EACH_OBSERVER(Observer, observers_, OnRequestCreated(request_id, type));
bool RequestManager::FulfillRequest(int request_id,
scoped_ptr<RequestValue> response,
bool has_more) {
+ CHECK(response.get());
RequestMap::iterator request_it = requests_.find(request_id);
if (request_it == requests_.end())
return false;
- request_it->second->handler->OnSuccess(request_id, response.Pass(), has_more);
+ FOR_EACH_OBSERVER(Observer,
+ observers_,
+ OnRequestFulfilled(request_id, *response.get(), has_more));
- FOR_EACH_OBSERVER(
- Observer, observers_, OnRequestFulfilled(request_id, has_more));
+ request_it->second->handler->OnSuccess(request_id, response.Pass(), has_more);
- if (!has_more)
+ if (!has_more) {
DestroyRequest(request_id);
- else
- request_it->second->timeout_timer.Reset();
+ } else {
+ if (notification_manager_)
+ notification_manager_->HideUnresponsiveNotification(request_id);
+ ResetTimer(request_id);
+ }
return true;
}
-bool RequestManager::RejectRequest(int request_id, base::File::Error error) {
+bool RequestManager::RejectRequest(int request_id,
+ scoped_ptr<RequestValue> response,
+ base::File::Error error) {
+ CHECK(response.get());
RequestMap::iterator request_it = requests_.find(request_id);
if (request_it == requests_.end())
return false;
- request_it->second->handler->OnError(request_id, error);
-
- FOR_EACH_OBSERVER(Observer, observers_, OnRequestRejected(request_id, error));
-
+ FOR_EACH_OBSERVER(Observer,
+ observers_,
+ OnRequestRejected(request_id, *response.get(), error));
+ request_it->second->handler->OnError(request_id, response.Pass(), error);
DestroyRequest(request_id);
return true;
void RequestManager::OnRequestTimeout(int request_id) {
FOR_EACH_OBSERVER(Observer, observers_, OnRequestTimeouted(request_id));
- RejectRequest(request_id, base::File::FILE_ERROR_ABORT);
+ if (!notification_manager_) {
+ RejectRequest(request_id,
+ scoped_ptr<RequestValue>(new RequestValue()),
+ base::File::FILE_ERROR_ABORT);
+ return;
+ }
+
+ notification_manager_->ShowUnresponsiveNotification(
+ request_id,
+ base::Bind(&RequestManager::OnUnresponsiveNotificationResult,
+ weak_ptr_factory_.GetWeakPtr(),
+ request_id));
+}
+
+void RequestManager::OnUnresponsiveNotificationResult(
+ int request_id,
+ NotificationManagerInterface::NotificationResult result) {
+ RequestMap::iterator request_it = requests_.find(request_id);
+ if (request_it == requests_.end())
+ return;
+
+ if (result == NotificationManagerInterface::CONTINUE) {
+ ResetTimer(request_id);
+ return;
+ }
+
+ RejectRequest(request_id,
+ scoped_ptr<RequestValue>(new RequestValue()),
+ base::File::FILE_ERROR_ABORT);
+}
+
+void RequestManager::ResetTimer(int request_id) {
+ RequestMap::iterator request_it = requests_.find(request_id);
+ if (request_it == requests_.end())
+ return;
+
+ request_it->second->timeout_timer.Start(
+ FROM_HERE,
+ timeout_,
+ base::Bind(&RequestManager::OnRequestTimeout,
+ weak_ptr_factory_.GetWeakPtr(),
+ request_id));
}
void RequestManager::DestroyRequest(int request_id) {
delete request_it->second;
requests_.erase(request_it);
+ if (notification_manager_)
+ notification_manager_->HideUnresponsiveNotification(request_id);
+
FOR_EACH_OBSERVER(Observer, observers_, OnRequestDestroyed(request_id));
+
+ TRACE_EVENT_ASYNC_END0(
+ "file_system_provider", "RequestManager::Request", request_id);
}
} // namespace file_system_provider