diff options
author | mtomasz@chromium.org <mtomasz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-03 08:54:35 +0000 |
---|---|---|
committer | mtomasz@chromium.org <mtomasz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-03 08:54:35 +0000 |
commit | f757be0920c38c3007a3f9f08a5ecd6423681250 (patch) | |
tree | 68001a282d938d4f302b7f9e80db241b1b51154e | |
parent | 299e3d00feb290b960889c0ae43f97dcaa066a91 (diff) | |
download | chromium_src-f757be0920c38c3007a3f9f08a5ecd6423681250.zip chromium_src-f757be0920c38c3007a3f9f08a5ecd6423681250.tar.gz chromium_src-f757be0920c38c3007a3f9f08a5ecd6423681250.tar.bz2 |
[fsp] Show request logs in chrome://provided-file-systems.
This CL adds displaying live log from the request manager of the selected
file system.
TEST=Tested manually with a testing extension.
BUG=376095
Review URL: https://codereview.chromium.org/301873002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274436 0039d316-1c4b-4281-b951-d872f2087c98
8 files changed, 422 insertions, 101 deletions
diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system.cc index 316c87d..743abc8 100644 --- a/chrome/browser/chromeos/file_system_provider/provided_file_system.cc +++ b/chrome/browser/chromeos/file_system_provider/provided_file_system.cc @@ -35,7 +35,7 @@ ProvidedFileSystem::~ProvidedFileSystem() {} void ProvidedFileSystem::RequestUnmount( const fileapi::AsyncFileUtil::StatusCallback& callback) { if (!request_manager_.CreateRequest( - RequestManager::REQUEST_UNMOUNT, + REQUEST_UNMOUNT, scoped_ptr<RequestManager::HandlerInterface>(new operations::Unmount( event_router_, file_system_info_, callback)))) { callback.Run(base::File::FILE_ERROR_SECURITY); @@ -46,7 +46,7 @@ void ProvidedFileSystem::GetMetadata( const base::FilePath& entry_path, const fileapi::AsyncFileUtil::GetFileInfoCallback& callback) { if (!request_manager_.CreateRequest( - RequestManager::GET_METADATA, + GET_METADATA, scoped_ptr<RequestManager::HandlerInterface>( new operations::GetMetadata( event_router_, file_system_info_, entry_path, callback)))) { @@ -58,7 +58,7 @@ void ProvidedFileSystem::ReadDirectory( const base::FilePath& directory_path, const fileapi::AsyncFileUtil::ReadDirectoryCallback& callback) { if (!request_manager_.CreateRequest( - RequestManager::READ_DIRECTORY, + READ_DIRECTORY, scoped_ptr< RequestManager::HandlerInterface>(new operations::ReadDirectory( event_router_, file_system_info_, directory_path, callback)))) { @@ -74,7 +74,7 @@ void ProvidedFileSystem::ReadFile(int file_handle, int length, const ReadChunkReceivedCallback& callback) { if (!request_manager_.CreateRequest( - RequestManager::READ_FILE, + READ_FILE, make_scoped_ptr<RequestManager::HandlerInterface>( new operations::ReadFile(event_router_, file_system_info_, @@ -101,7 +101,7 @@ void ProvidedFileSystem::OpenFile(const base::FilePath& file_path, } if (!request_manager_.CreateRequest( - RequestManager::OPEN_FILE, + OPEN_FILE, scoped_ptr<RequestManager::HandlerInterface>( new operations::OpenFile(event_router_, file_system_info_, @@ -117,7 +117,7 @@ void ProvidedFileSystem::CloseFile( int file_handle, const fileapi::AsyncFileUtil::StatusCallback& callback) { if (!request_manager_.CreateRequest( - RequestManager::CLOSE_FILE, + CLOSE_FILE, scoped_ptr<RequestManager::HandlerInterface>( new operations::CloseFile( event_router_, file_system_info_, file_handle, callback)))) { diff --git a/chrome/browser/chromeos/file_system_provider/request_manager.cc b/chrome/browser/chromeos/file_system_provider/request_manager.cc index 928e95e..6fb996d 100644 --- a/chrome/browser/chromeos/file_system_provider/request_manager.cc +++ b/chrome/browser/chromeos/file_system_provider/request_manager.cc @@ -9,7 +9,6 @@ namespace chromeos { namespace file_system_provider { - namespace { // Timeout in seconds, before a request is considered as stale and hence @@ -18,6 +17,27 @@ const int kDefaultTimeout = 10; } // namespace +std::string RequestTypeToString(RequestType type) { + switch (type) { + case REQUEST_UNMOUNT: + return "REQUEST_UNMOUNT"; + case GET_METADATA: + return "GET_METADATA"; + case READ_DIRECTORY: + return "READ_DIRECTORY"; + case OPEN_FILE: + return "OPEN_FILE"; + case CLOSE_FILE: + return "CLOSE_FILE"; + case READ_FILE: + return "READ_FILE"; + case TESTING: + return "TESTING"; + } + NOTREACHED(); + return ""; +} + RequestManager::RequestManager() : next_id_(1), timeout_(base::TimeDelta::FromSeconds(kDefaultTimeout)), diff --git a/chrome/browser/chromeos/file_system_provider/request_manager.h b/chrome/browser/chromeos/file_system_provider/request_manager.h index 0f092ac..edfb560 100644 --- a/chrome/browser/chromeos/file_system_provider/request_manager.h +++ b/chrome/browser/chromeos/file_system_provider/request_manager.h @@ -21,21 +21,24 @@ namespace chromeos { namespace file_system_provider { +// Request type, passed to RequestManager::CreateRequest. For logging purposes. +enum RequestType { + REQUEST_UNMOUNT, + GET_METADATA, + READ_DIRECTORY, + OPEN_FILE, + CLOSE_FILE, + READ_FILE, + TESTING +}; + +// Converts a request type to human-readable format. +std::string RequestTypeToString(RequestType type); + // Manages requests between the service, async utils and the providing // extensions. class RequestManager { public: - // Request type, passed to |CreateRequest|. For logging purposes. - enum RequestType { - REQUEST_UNMOUNT, - GET_METADATA, - READ_DIRECTORY, - OPEN_FILE, - CLOSE_FILE, - READ_FILE, - TESTING - }; - // Handles requests. Each request implementation must implement // this interface. class HandlerInterface { diff --git a/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc b/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc index 2acd609..b45e972 100644 --- a/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc +++ b/chrome/browser/chromeos/file_system_provider/request_manager_unittest.cc @@ -157,14 +157,14 @@ class RequestObserver : public RequestManager::Observer { class CreatedEvent : public Event { public: - CreatedEvent(int request_id, RequestManager::RequestType type) + CreatedEvent(int request_id, RequestType type) : Event(request_id), type_(type) {} virtual ~CreatedEvent() {} - RequestManager::RequestType type() const { return type_; } + RequestType type() const { return type_; } private: - RequestManager::RequestType type_; + RequestType type_; }; class FulfilledEvent : public Event { @@ -195,8 +195,7 @@ class RequestObserver : public RequestManager::Observer { virtual ~RequestObserver() {} // RequestManager::Observer overrides. - virtual void OnRequestCreated(int request_id, - RequestManager::RequestType type) OVERRIDE { + virtual void OnRequestCreated(int request_id, RequestType type) OVERRIDE { created_.push_back(CreatedEvent(request_id, type)); } @@ -265,7 +264,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateFailure) { request_manager_->AddObserver(&observer); const int request_id = request_manager_->CreateRequest( - RequestManager::TESTING, + TESTING, make_scoped_ptr<RequestManager::HandlerInterface>( new FakeHandler(logger.GetWeakPtr(), false /* execute_reply */))); @@ -274,7 +273,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateFailure) { EXPECT_EQ(0u, logger.error_events().size()); EXPECT_EQ(1u, observer.created().size()); - EXPECT_EQ(RequestManager::TESTING, observer.created()[0].type()); + EXPECT_EQ(TESTING, observer.created()[0].type()); EXPECT_EQ(1u, observer.destroyed().size()); EXPECT_EQ(0u, observer.executed().size()); @@ -287,7 +286,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill) { request_manager_->AddObserver(&observer); const int request_id = request_manager_->CreateRequest( - RequestManager::TESTING, + TESTING, make_scoped_ptr<RequestManager::HandlerInterface>( new FakeHandler(logger.GetWeakPtr(), true /* execute_reply */))); @@ -297,7 +296,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill) { ASSERT_EQ(1u, observer.created().size()); EXPECT_EQ(request_id, observer.created()[0].request_id()); - EXPECT_EQ(RequestManager::TESTING, observer.created()[0].type()); + EXPECT_EQ(TESTING, observer.created()[0].type()); ASSERT_EQ(1u, observer.executed().size()); EXPECT_EQ(request_id, observer.executed()[0].request_id()); @@ -355,7 +354,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill_WithHasNext) { request_manager_->AddObserver(&observer); const int request_id = request_manager_->CreateRequest( - RequestManager::TESTING, + TESTING, make_scoped_ptr<RequestManager::HandlerInterface>( new FakeHandler(logger.GetWeakPtr(), true /* execute_reply */))); @@ -365,7 +364,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndFulFill_WithHasNext) { ASSERT_EQ(1u, observer.created().size()); EXPECT_EQ(request_id, observer.created()[0].request_id()); - EXPECT_EQ(RequestManager::TESTING, observer.created()[0].type()); + EXPECT_EQ(TESTING, observer.created()[0].type()); ASSERT_EQ(1u, observer.executed().size()); EXPECT_EQ(request_id, observer.executed()[0].request_id()); @@ -424,7 +423,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndReject) { request_manager_->AddObserver(&observer); const int request_id = request_manager_->CreateRequest( - RequestManager::TESTING, + TESTING, make_scoped_ptr<RequestManager::HandlerInterface>( new FakeHandler(logger.GetWeakPtr(), true /* execute_reply */))); @@ -434,7 +433,7 @@ TEST_F(FileSystemProviderRequestManagerTest, CreateAndReject) { ASSERT_EQ(1u, observer.created().size()); EXPECT_EQ(request_id, observer.created()[0].request_id()); - EXPECT_EQ(RequestManager::TESTING, observer.created()[0].type()); + EXPECT_EQ(TESTING, observer.created()[0].type()); ASSERT_EQ(1u, observer.executed().size()); EXPECT_EQ(request_id, observer.executed()[0].request_id()); @@ -485,7 +484,7 @@ TEST_F(FileSystemProviderRequestManagerTest, request_manager_->AddObserver(&observer); const int request_id = request_manager_->CreateRequest( - RequestManager::TESTING, + TESTING, make_scoped_ptr<RequestManager::HandlerInterface>( new FakeHandler(logger.GetWeakPtr(), true /* execute_reply */))); @@ -495,7 +494,7 @@ TEST_F(FileSystemProviderRequestManagerTest, ASSERT_EQ(1u, observer.created().size()); EXPECT_EQ(request_id, observer.created()[0].request_id()); - EXPECT_EQ(RequestManager::TESTING, observer.created()[0].type()); + EXPECT_EQ(TESTING, observer.created()[0].type()); ASSERT_EQ(1u, observer.executed().size()); EXPECT_EQ(request_id, observer.executed()[0].request_id()); @@ -532,7 +531,7 @@ TEST_F(FileSystemProviderRequestManagerTest, request_manager_->AddObserver(&observer); const int request_id = request_manager_->CreateRequest( - RequestManager::TESTING, + TESTING, make_scoped_ptr<RequestManager::HandlerInterface>( new FakeHandler(logger.GetWeakPtr(), true /* execute_reply */))); @@ -542,7 +541,7 @@ TEST_F(FileSystemProviderRequestManagerTest, ASSERT_EQ(1u, observer.created().size()); EXPECT_EQ(request_id, observer.created()[0].request_id()); - EXPECT_EQ(RequestManager::TESTING, observer.created()[0].type()); + EXPECT_EQ(TESTING, observer.created()[0].type()); ASSERT_EQ(1u, observer.executed().size()); EXPECT_EQ(request_id, observer.executed()[0].request_id()); @@ -571,12 +570,12 @@ TEST_F(FileSystemProviderRequestManagerTest, UniqueIds) { EventLogger logger; const int first_request_id = request_manager_->CreateRequest( - RequestManager::TESTING, + TESTING, make_scoped_ptr<RequestManager::HandlerInterface>( new FakeHandler(logger.GetWeakPtr(), true /* execute_reply */))); const int second_request_id = request_manager_->CreateRequest( - RequestManager::TESTING, + TESTING, make_scoped_ptr<RequestManager::HandlerInterface>( new FakeHandler(logger.GetWeakPtr(), true /* execute_reply */))); @@ -594,7 +593,7 @@ TEST_F(FileSystemProviderRequestManagerTest, AbortOnDestroy) { request_manager.AddObserver(&observer); request_id = request_manager.CreateRequest( - RequestManager::TESTING, + TESTING, make_scoped_ptr<RequestManager::HandlerInterface>( new FakeHandler(logger.GetWeakPtr(), true /* execute_reply */))); @@ -604,7 +603,7 @@ TEST_F(FileSystemProviderRequestManagerTest, AbortOnDestroy) { ASSERT_EQ(1u, observer.created().size()); EXPECT_EQ(request_id, observer.created()[0].request_id()); - EXPECT_EQ(RequestManager::TESTING, observer.created()[0].type()); + EXPECT_EQ(TESTING, observer.created()[0].type()); ASSERT_EQ(1u, observer.executed().size()); EXPECT_EQ(request_id, observer.executed()[0].request_id()); @@ -639,7 +638,7 @@ TEST_F(FileSystemProviderRequestManagerTest, AbortOnTimeout) { request_manager_->SetTimeoutForTests(base::TimeDelta::FromSeconds(0)); const int request_id = request_manager_->CreateRequest( - RequestManager::TESTING, + TESTING, make_scoped_ptr<RequestManager::HandlerInterface>( new FakeHandler(logger.GetWeakPtr(), true /* execute_reply */))); EXPECT_EQ(1, request_id); @@ -648,7 +647,7 @@ TEST_F(FileSystemProviderRequestManagerTest, AbortOnTimeout) { ASSERT_EQ(1u, observer.created().size()); EXPECT_EQ(request_id, observer.created()[0].request_id()); - EXPECT_EQ(RequestManager::TESTING, observer.created()[0].type()); + EXPECT_EQ(TESTING, observer.created()[0].type()); ASSERT_EQ(1u, observer.executed().size()); EXPECT_EQ(request_id, observer.executed()[0].request_id()); diff --git a/chrome/browser/resources/chromeos/provided_file_systems.css b/chrome/browser/resources/chromeos/provided_file_systems.css index 7d94dfd..b049d4a1 100644 --- a/chrome/browser/resources/chromeos/provided_file_systems.css +++ b/chrome/browser/resources/chromeos/provided_file_systems.css @@ -4,38 +4,66 @@ */ body { + background-color: rgba(0, 0, 0, 0.05); font-family: 'Verdana', 'Arial'; font-size: 14px; margin: 20px; } -h1 { - font-size: 20px; - font-weight: normal; +#fileSystems, +#requestEvents { + background-color: white; + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2); + margin-bottom: 20px; } -table { +#fileSystems table, +#requestEvents table { border-collapse: collapse; width: 100%; } -table th { - background-color: rgb(92, 107, 192); - color: white; - font-weight: normal; - height: 50px; +#fileSystems th, +#requestEvents th { + height: 30px; } -table td { - border-bottom: 1px solid #eee; +#fileSystems .message { + border-top: 1px solid #eee; +} + +#fileSystems td { + border-top: 1px solid #eee; height: 40px; line-height: 24px; text-align: center; } -table td .icon { +#fileSystems td .icon { display: inline-block; height: 24px; vertical-align: middle; width: 24px; } + +#fileSystems tbody tr { + cursor: pointer; +} + +#fileSystems tbody tr:active td { + background-color: #eee; +} + +#requestEvents { + font-size: 12px; +} + +#requestEvents td { + padding: 8px; + text-align: center; + vertical-align: top; +} + +#requestEvents td { + border-top: 1px solid #eee; +} diff --git a/chrome/browser/resources/chromeos/provided_file_systems.html b/chrome/browser/resources/chromeos/provided_file_systems.html index 6eff7c2..d7add37 100644 --- a/chrome/browser/resources/chromeos/provided_file_systems.html +++ b/chrome/browser/resources/chromeos/provided_file_systems.html @@ -12,37 +12,77 @@ <template> <link rel="stylesheet" href="chrome://provided-file-systems/provided_file_systems.css"> - <table> - <thead> - <tr> - <th>ID</th> - <th>Name</th> - <th>Extension ID</th> - <th>Active Requests</th> - </tr> - </thead> - <tbody> - <template id="file-system" repeat="{{item in model}}"> + <div id="fileSystems"> + <table> + <thead> <tr> - <td>{{item.id}}</td> - <td>{{item.name}}</td> - <td> - <div class="icon" style="background-image: -webkit-image-set( - url(chrome://extension-icon/{{item.extensionId}}/24/1) 1x, - url(chrome://extension-icon/{{item.extensionId}}/48/1) - 2x)"></div> - {{item.extensionId}} - </td> - <td>{{item.activeRequests}}</td> + <th>ID</th> + <th>Name</th> + <th>Extension ID</th> + <th>Active Requests</th> </tr> - </template> - </tbody> - </table> + </thead> + <tbody> + <template id="file-system" repeat="{{item in model}}"> + <tr on-click="{{rowClicked}}" data-id="{{item.id}}" + data-extension-id="{{item.extensionId}}"> + <td>{{item.id}}</td> + <td>{{item.name}}</td> + <td> + <div class="icon" style="background-image: + -webkit-image-set( + url(chrome://extension-icon/{{item.extensionId}}/24/1) + 1x, + url(chrome://extension-icon/{{item.extensionId}}/48/1) + 2x)"></div> + {{item.extensionId}} + </td> + <td>{{item.activeRequests}}</td> + </tr> + </template> + </tbody> + </table> + </div> </template> </polymer-element> - <h1>Mounted provided file systems</h1> - <file-systems id="mounted-file-systems"> + <polymer-element name="request-events"> + <template> + <link rel="stylesheet" + href="chrome://provided-file-systems/provided_file_systems.css"> + <div id="requestEvents"> + <table> + <thead> + <tr> + <th>Time</th> + <th>Request ID</th> + <th>Request Type</th> + <th>Event Type</th> + <th>Error</th> + <th>Has Next</th> + </tr> + </thead> + <tbody> + <template id="request-event" repeat="{{item in model}}"> + <tr> + <td>{{item.time | formatTime}}</td> + <td>{{item.id}}</td> + <td>{{item.requestType}}</td> + <td>{{item.eventType}}</td> + <td>{{item.error}}</td> + <td>{{item.hasMore | formatHasMore}}</td> + </tr> + </template> + </tbody> + </table> + </div> + </template> + </polymer-element> + + <file-systems id="file-systems"> </file-systems> + + <request-events hidden id="request-events"> + </request-events> </body> </html> diff --git a/chrome/browser/resources/chromeos/provided_file_systems.js b/chrome/browser/resources/chromeos/provided_file_systems.js index db23dee..712f859 100644 --- a/chrome/browser/resources/chromeos/provided_file_systems.js +++ b/chrome/browser/resources/chromeos/provided_file_systems.js @@ -5,28 +5,94 @@ <include src="../../../../third_party/polymer/platform/platform.js"> <include src="../../../../third_party/polymer/polymer/polymer.js"> -// Define the file-systems element. +// Defines the file-systems element. Polymer('file-systems', { + /** + * Called when the element is created. + */ ready: function() { }, /** + * Selects an active file system from the list. + * @param {Event} event Event. + * @param {number} detail Detail. + * @param {HTMLElement} sender Sender. + */ + rowClicked: function(event, detail, sender) { + var requestEventsNode = document.querySelector('#request-events'); + requestEventsNode.hidden = false; + requestEventsNode.model = []; + + console.log(sender.dataset.extensionId, sender.dataset.id); + chrome.send('selectFileSystem', [sender.dataset.extensionId, + sender.dataset.id]); + }, + + /** * List of provided file system information maps. * @type {Array.<Object>} */ model: [] }); +// Defines the request-log element. +Polymer('request-events', { + /** + * Called when the element is created. + */ + ready: function() { + }, + + /** + * Formats time to a hh:mm:ss.xxxx format. + * @param {Date} time Input time. + * @return {string} Output string in a human-readable format. + */ + formatTime: function(time) { + return ('0' + time.getHours()).slice(-2) + ':' + + ('0' + time.getMinutes()).slice(-2) + ':' + + ('0' + time.getSeconds()).slice(-2) + '.' + + ('000' + time.getMilliseconds()).slice(-3); + }, + + /** + * Formats a boolean value to human-readable form. + * @param {boolean=} opt_hasMore Input value. + * @return {string} Output string in a human-readable format. + */ + formatHasMore: function(opt_hasMore) { + if (opt_hasMore == undefined) + return ''; + + return opt_hasMore ? 'HAS_MORE' : 'LAST'; + }, + + /** + * List of events. + * @type {Array.<Object>} + */ + model: [] +}); + /* * Updates the mounted file system list. - * @param {Object} fileSystems Dictionary containing provided file system + * @param {Array.<Object>} fileSystems Array containing provided file system * information. - * */ function updateFileSystems(fileSystems) { - var mountedFileSystems = document.querySelector('#mounted-file-systems'); - mountedFileSystems.model = fileSystems; - Platform.performMicrotaskCheckpoint(); + var fileSystemsNode = document.querySelector('#file-systems'); + fileSystemsNode.model = fileSystems; +} + +/** + * Called when a request is created. + * @param {Object} event Event. + */ +function onRequestEvent(event) { + var requestEventsNode = document.querySelector('#request-events'); + event.time = new Date(event.time); // Convert to a real Date object. + requestEventsNode.model.push(event); } document.addEventListener('DOMContentLoaded', function() { diff --git a/chrome/browser/ui/webui/chromeos/provided_file_systems_ui.cc b/chrome/browser/ui/webui/chromeos/provided_file_systems_ui.cc index 1dbbe44..ed682b2 100644 --- a/chrome/browser/ui/webui/chromeos/provided_file_systems_ui.cc +++ b/chrome/browser/ui/webui/chromeos/provided_file_systems_ui.cc @@ -4,9 +4,12 @@ #include "chrome/browser/ui/webui/chromeos/provided_file_systems_ui.h" +#include <string> #include <vector> #include "base/bind.h" +#include "base/files/file.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/values.h" #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h" @@ -28,12 +31,58 @@ namespace chromeos { namespace { +const char kKeyId[] = "id"; +const char kKeyEventType[] = "eventType"; +const char kKeyRequestType[] = "requestType"; +const char kKeyTime[] = "time"; +const char kKeyHasMore[] = "hasMore"; +const char kKeyError[] = "error"; + +const char kKeyName[] = "name"; +const char kKeyExtensionId[] = "extensionId"; +const char kKeyMountPath[] = "mountPath"; +const char kKeyActiveRequests[] = "activeRequests"; + +const char kRequestCreated[] = "created"; +const char kRequestDestroyed[] = "destroyed"; +const char kRequestExecuted[] = "executed"; +const char kRequestFulfilled[] = "fulfilled"; +const char kRequestRejected[] = "rejected"; +const char kRequestTimeouted[] = "timeouted"; + +const char kFunctionOnRequestEvent[] = "onRequestEvent"; +const char kFunctionUpdateFileSystems[] = "updateFileSystems"; +const char kFunctionSelectFileSystem[] = "selectFileSystem"; + +// Creates a dictionary holding common fields for the onRequest* events. +scoped_ptr<base::DictionaryValue> CreateRequestEvent(const std::string& type, + int request_id) { + scoped_ptr<base::DictionaryValue> event(new base::DictionaryValue); + event->SetInteger(kKeyId, request_id); + event->SetString(kKeyEventType, type); + event->SetDouble(kKeyTime, base::Time::Now().ToJsTime()); + return event.Pass(); +} + // Class to handle messages from chrome://provided-file-systems. -class ProvidedFileSystemsWebUIHandler : public content::WebUIMessageHandler { +class ProvidedFileSystemsWebUIHandler + : public content::WebUIMessageHandler, + public file_system_provider::RequestManager::Observer { public: ProvidedFileSystemsWebUIHandler() : weak_ptr_factory_(this) {} - virtual ~ProvidedFileSystemsWebUIHandler() {} + virtual ~ProvidedFileSystemsWebUIHandler(); + + // RequestManager::Observer overrides. + virtual void OnRequestCreated( + int request_id, + file_system_provider::RequestType type) OVERRIDE; + virtual void OnRequestDestroyed(int request_id) OVERRIDE; + virtual void OnRequestExecuted(int request_id) OVERRIDE; + virtual void OnRequestFulfilled(int request_id, bool has_more) OVERRIDE; + virtual void OnRequestRejected(int request_id, + base::File::Error error) OVERRIDE; + virtual void OnRequestTimeouted(int request_id) OVERRIDE; private: // content::WebUIMessageHandler overrides. @@ -44,17 +93,89 @@ class ProvidedFileSystemsWebUIHandler : public content::WebUIMessageHandler { file_system_provider::Service* GetService(); // Invoked when updating file system list is requested. - void OnUpdateFileSystems(const base::ListValue* args); + void UpdateFileSystems(const base::ListValue* args); + // Invoked when a file system is selected from the list. + void SelectFileSystem(const base::ListValue* args); + + std::string selected_extension_id; + std::string selected_file_system_id; base::WeakPtrFactory<ProvidedFileSystemsWebUIHandler> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ProvidedFileSystemsWebUIHandler); }; +ProvidedFileSystemsWebUIHandler::~ProvidedFileSystemsWebUIHandler() { + // Stop observing the currently selected file system. + file_system_provider::Service* const service = GetService(); + if (!service) + return; + + file_system_provider::ProvidedFileSystemInterface* const file_system = + service->GetProvidedFileSystem(selected_extension_id, + selected_file_system_id); + + if (file_system) { + file_system_provider::RequestManager* const request_manager = + file_system->GetRequestManager(); + DCHECK(request_manager); + request_manager->RemoveObserver(this); + } +} + +void ProvidedFileSystemsWebUIHandler::OnRequestCreated( + int request_id, + file_system_provider::RequestType type) { + scoped_ptr<base::DictionaryValue> const event = + CreateRequestEvent(kRequestCreated, request_id); + event->SetString(kKeyRequestType, + file_system_provider::RequestTypeToString(type)); + web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event); +} + +void ProvidedFileSystemsWebUIHandler::OnRequestDestroyed(int request_id) { + scoped_ptr<base::DictionaryValue> const event = + CreateRequestEvent(kRequestDestroyed, request_id); + web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event); +} + +void ProvidedFileSystemsWebUIHandler::OnRequestExecuted(int request_id) { + scoped_ptr<base::DictionaryValue> const event = + CreateRequestEvent(kRequestExecuted, request_id); + web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event); +} + +void ProvidedFileSystemsWebUIHandler::OnRequestFulfilled(int request_id, + bool has_more) { + scoped_ptr<base::DictionaryValue> const event = + CreateRequestEvent(kRequestFulfilled, request_id); + event->SetBoolean(kKeyHasMore, has_more); + web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event); +} + +void ProvidedFileSystemsWebUIHandler::OnRequestRejected( + int request_id, + base::File::Error error) { + scoped_ptr<base::DictionaryValue> const event = + CreateRequestEvent(kRequestRejected, request_id); + event->SetString(kKeyError, base::File::ErrorToString(error)); + web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event); +} + +void ProvidedFileSystemsWebUIHandler::OnRequestTimeouted(int request_id) { + scoped_ptr<base::DictionaryValue> const event = + CreateRequestEvent(kRequestTimeouted, request_id); + web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event); +} + void ProvidedFileSystemsWebUIHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( - "updateFileSystems", - base::Bind(&ProvidedFileSystemsWebUIHandler::OnUpdateFileSystems, + kFunctionUpdateFileSystems, + base::Bind(&ProvidedFileSystemsWebUIHandler::UpdateFileSystems, + weak_ptr_factory_.GetWeakPtr())); + web_ui()->RegisterMessageCallback( + kFunctionSelectFileSystem, + base::Bind(&ProvidedFileSystemsWebUIHandler::SelectFileSystem, weak_ptr_factory_.GetWeakPtr())); } @@ -65,7 +186,7 @@ file_system_provider::Service* ProvidedFileSystemsWebUIHandler::GetService() { return file_system_provider::ServiceFactory::FindExisting(profile); } -void ProvidedFileSystemsWebUIHandler::OnUpdateFileSystems( +void ProvidedFileSystemsWebUIHandler::UpdateFileSystems( const base::ListValue* args) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -91,19 +212,63 @@ void ProvidedFileSystemsWebUIHandler::OnUpdateFileSystems( file_system->GetRequestManager(); DCHECK(request_manager); - base::DictionaryValue* item_value = new base::DictionaryValue(); - item_value->SetString("id", file_system_info.file_system_id()); - item_value->SetString("name", file_system_info.file_system_name()); - item_value->SetString("extensionId", file_system_info.extension_id()); - item_value->SetString("mountPath", - file_system_info.mount_path().AsUTF8Unsafe()); - item_value->SetInteger("activeRequests", - request_manager->GetActiveRequestsForLogging()); + base::DictionaryValue* item = new base::DictionaryValue(); + item->SetString(kKeyId, file_system_info.file_system_id()); + item->SetString(kKeyName, file_system_info.file_system_name()); + item->SetString(kKeyExtensionId, file_system_info.extension_id()); + item->SetString(kKeyMountPath, + file_system_info.mount_path().AsUTF8Unsafe()); + item->SetInteger(kKeyActiveRequests, + request_manager->GetActiveRequestsForLogging()); + + items.Append(item); + } + + web_ui()->CallJavascriptFunction(kFunctionUpdateFileSystems, items); +} + +void ProvidedFileSystemsWebUIHandler::SelectFileSystem( + const base::ListValue* args) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + file_system_provider::Service* const service = GetService(); + if (!service) + return; + + std::string extension_id; + if (!args->GetString(0, &extension_id)) + return; - items.Append(item_value); + std::string file_system_id; + if (!args->GetString(1, &file_system_id)) + return; + + // Stop observing the previously selected request manager. + { + file_system_provider::ProvidedFileSystemInterface* const file_system = + service->GetProvidedFileSystem(selected_extension_id, + selected_file_system_id); + if (file_system) { + file_system_provider::RequestManager* const request_manager = + file_system->GetRequestManager(); + DCHECK(request_manager); + request_manager->RemoveObserver(this); + } } - web_ui()->CallJavascriptFunction("updateFileSystems", items); + // Observe the selected file system. + file_system_provider::ProvidedFileSystemInterface* const file_system = + service->GetProvidedFileSystem(extension_id, file_system_id); + if (!file_system) + return; + + file_system_provider::RequestManager* const request_manager = + file_system->GetRequestManager(); + DCHECK(request_manager); + + request_manager->AddObserver(this); + selected_extension_id = extension_id; + selected_file_system_id = file_system_id; } } // namespace |