1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/ui/webui/chromeos/provided_file_systems_ui.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <string>
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <vector>
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h"
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/files/file.h"
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/weak_ptr.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/values.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/request_manager.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/service.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/service_factory.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/url_constants.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/web_ui.h"
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/web_ui_data_source.h"
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/web_ui_message_handler.h"
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "grit/browser_resources.h"
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using content::BrowserThread;
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace chromeos {
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kKeyId[] = "id";
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kKeyEventType[] = "eventType";
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kKeyRequestType[] = "requestType";
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kKeyTime[] = "time";
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kKeyHasMore[] = "hasMore";
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kKeyError[] = "error";
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kKeyExecutionTime[] = "executionTime";
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kKeyValueSize[] = "valueSize";
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kKeyName[] = "name";
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kKeyExtensionId[] = "extensionId";
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kKeyMountPath[] = "mountPath";
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kKeyActiveRequests[] = "activeRequests";
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kRequestCreated[] = "created";
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kRequestDestroyed[] = "destroyed";
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kRequestExecuted[] = "executed";
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kRequestFulfilled[] = "fulfilled";
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kRequestRejected[] = "rejected";
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kRequestTimeouted[] = "timeouted";
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kFunctionOnRequestEvent[] = "onRequestEvent";
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kFunctionUpdateFileSystems[] = "updateFileSystems";
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kFunctionSelectFileSystem[] = "selectFileSystem";
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Creates a dictionary holding common fields for the onRequest* events.
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)scoped_ptr<base::DictionaryValue> CreateRequestEvent(const std::string& type,
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                     int request_id) {
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> event(new base::DictionaryValue);
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  event->SetInteger(kKeyId, request_id);
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  event->SetString(kKeyEventType, type);
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  event->SetDouble(kKeyTime, base::Time::Now().ToJsTime());
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return event.Pass();
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Gets execution time from a RequestValue instance. If the |response| doesn't
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// have execution time, then returns 0.
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint GetExecutionTime(const file_system_provider::RequestValue& response) {
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  {
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const extensions::api::file_system_provider_internal::
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        UnmountRequestedSuccess::Params* value =
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            response.unmount_success_params();
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (value)
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return value->execution_time;
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  {
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const extensions::api::file_system_provider_internal::
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        GetMetadataRequestedSuccess::Params* value =
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            response.get_metadata_success_params();
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (value)
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return value->execution_time;
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  {
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const extensions::api::file_system_provider_internal::
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ReadDirectoryRequestedSuccess::Params* value =
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            response.read_directory_success_params();
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (value)
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return value->execution_time;
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  {
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const extensions::api::file_system_provider_internal::
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ReadFileRequestedSuccess::Params* value =
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            response.read_file_success_params();
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (value)
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return value->execution_time;
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  {
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const extensions::api::file_system_provider_internal::
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        OperationRequestedSuccess::Params* value =
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            response.operation_success_params();
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (value)
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return value->execution_time;
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  {
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const extensions::api::file_system_provider_internal::
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        OperationRequestedError::Params* value =
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            response.operation_error_params();
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (value)
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return value->execution_time;
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return 0;
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Gets value size in bytes from a RequestValue instance. If not available,
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// then returns 0.
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint GetValueSize(const file_system_provider::RequestValue& response) {
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const extensions::api::file_system_provider_internal::
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ReadFileRequestedSuccess::Params* value =
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          response.read_file_success_params();
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (value)
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return value->data.size();
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return 0;
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Class to handle messages from chrome://provided-file-systems.
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class ProvidedFileSystemsWebUIHandler
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    : public content::WebUIMessageHandler,
13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      public file_system_provider::RequestManager::Observer {
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ProvidedFileSystemsWebUIHandler() : weak_ptr_factory_(this) {}
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~ProvidedFileSystemsWebUIHandler();
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // RequestManager::Observer overrides.
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnRequestCreated(
14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      int request_id,
14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      file_system_provider::RequestType type) OVERRIDE;
14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnRequestDestroyed(int request_id) OVERRIDE;
14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnRequestExecuted(int request_id) OVERRIDE;
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnRequestFulfilled(
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      int request_id,
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const file_system_provider::RequestValue& result,
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bool has_more) OVERRIDE;
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnRequestRejected(
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      int request_id,
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const file_system_provider::RequestValue& result,
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::File::Error error) OVERRIDE;
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnRequestTimeouted(int request_id) OVERRIDE;
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // content::WebUIMessageHandler overrides.
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void RegisterMessages() OVERRIDE;
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Gets a file system provider service for the current profile. If not found,
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // then NULL.
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_system_provider::Service* GetService();
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Invoked when updating file system list is requested.
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void UpdateFileSystems(const base::ListValue* args);
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Invoked when a file system is selected from the list.
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SelectFileSystem(const base::ListValue* args);
16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string selected_extension_id;
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string selected_file_system_id;
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::WeakPtrFactory<ProvidedFileSystemsWebUIHandler> weak_ptr_factory_;
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ProvidedFileSystemsWebUIHandler);
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ProvidedFileSystemsWebUIHandler::~ProvidedFileSystemsWebUIHandler() {
17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Stop observing the currently selected file system.
17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  file_system_provider::Service* const service = GetService();
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!service)
18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  file_system_provider::ProvidedFileSystemInterface* const file_system =
18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      service->GetProvidedFileSystem(selected_extension_id,
18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                     selected_file_system_id);
18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (file_system) {
18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    file_system_provider::RequestManager* const request_manager =
18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        file_system->GetRequestManager();
18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DCHECK(request_manager);
19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    request_manager->RemoveObserver(this);
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProvidedFileSystemsWebUIHandler::OnRequestCreated(
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int request_id,
19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    file_system_provider::RequestType type) {
19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> const event =
19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      CreateRequestEvent(kRequestCreated, request_id);
19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  event->SetString(kKeyRequestType,
20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   file_system_provider::RequestTypeToString(type));
20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event);
20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProvidedFileSystemsWebUIHandler::OnRequestDestroyed(int request_id) {
20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> const event =
20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      CreateRequestEvent(kRequestDestroyed, request_id);
20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event);
20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProvidedFileSystemsWebUIHandler::OnRequestExecuted(int request_id) {
21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> const event =
21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      CreateRequestEvent(kRequestExecuted, request_id);
21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event);
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ProvidedFileSystemsWebUIHandler::OnRequestFulfilled(
217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int request_id,
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const file_system_provider::RequestValue& result,
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool has_more) {
22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> const event =
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      CreateRequestEvent(kRequestFulfilled, request_id);
22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  event->SetBoolean(kKeyHasMore, has_more);
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  event->SetInteger(kKeyExecutionTime, GetExecutionTime(result));
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  event->SetInteger(kKeyValueSize, GetValueSize(result));
22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event);
22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProvidedFileSystemsWebUIHandler::OnRequestRejected(
22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    int request_id,
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const file_system_provider::RequestValue& result,
23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::File::Error error) {
23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> const event =
23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      CreateRequestEvent(kRequestRejected, request_id);
23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  event->SetString(kKeyError, base::File::ErrorToString(error));
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  event->SetInteger(kKeyExecutionTime, GetExecutionTime(result));
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  event->SetInteger(kKeyValueSize, GetValueSize(result));
23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event);
23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProvidedFileSystemsWebUIHandler::OnRequestTimeouted(int request_id) {
24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> const event =
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      CreateRequestEvent(kRequestTimeouted, request_id);
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_ui()->CallJavascriptFunction(kFunctionOnRequestEvent, *event);
24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ProvidedFileSystemsWebUIHandler::RegisterMessages() {
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  web_ui()->RegisterMessageCallback(
24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      kFunctionUpdateFileSystems,
24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&ProvidedFileSystemsWebUIHandler::UpdateFileSystems,
25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_ui()->RegisterMessageCallback(
25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      kFunctionSelectFileSystem,
25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&ProvidedFileSystemsWebUIHandler::SelectFileSystem,
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)file_system_provider::Service* ProvidedFileSystemsWebUIHandler::GetService() {
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::UI);
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Profile* const profile = Profile::FromWebUI(web_ui());
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return file_system_provider::ServiceFactory::FindExisting(profile);
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProvidedFileSystemsWebUIHandler::UpdateFileSystems(
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::ListValue* args) {
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::UI);
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_system_provider::Service* const service = GetService();
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!service)
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::ListValue items;
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const std::vector<file_system_provider::ProvidedFileSystemInfo>
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      file_system_info_list = service->GetProvidedFileSystemInfoList();
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < file_system_info_list.size(); ++i) {
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const file_system_provider::ProvidedFileSystemInfo file_system_info =
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        file_system_info_list[i];
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    file_system_provider::ProvidedFileSystemInterface* const file_system =
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        service->GetProvidedFileSystem(file_system_info.extension_id(),
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       file_system_info.file_system_id());
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(file_system);
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    file_system_provider::RequestManager* const request_manager =
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        file_system->GetRequestManager();
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(request_manager);
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::DictionaryValue* item = new base::DictionaryValue();
29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    item->SetString(kKeyId, file_system_info.file_system_id());
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    item->SetString(kKeyName, file_system_info.display_name());
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    item->SetString(kKeyExtensionId, file_system_info.extension_id());
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    item->SetString(kKeyMountPath,
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                    file_system_info.mount_path().AsUTF8Unsafe());
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    item->SetInteger(kKeyActiveRequests,
29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     request_manager->GetActiveRequestIds().size());
29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    items.Append(item);
30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_ui()->CallJavascriptFunction(kFunctionUpdateFileSystems, items);
30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void ProvidedFileSystemsWebUIHandler::SelectFileSystem(
30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::ListValue* args) {
30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::UI);
30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  file_system_provider::Service* const service = GetService();
31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!service)
31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string extension_id;
31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!args->GetString(0, &extension_id))
31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::string file_system_id;
31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!args->GetString(1, &file_system_id))
31946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
32046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
32146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Stop observing the previously selected request manager.
32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  {
32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    file_system_provider::ProvidedFileSystemInterface* const file_system =
32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        service->GetProvidedFileSystem(selected_extension_id,
32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                       selected_file_system_id);
32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (file_system) {
32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      file_system_provider::RequestManager* const request_manager =
32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          file_system->GetRequestManager();
32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      DCHECK(request_manager);
33046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      request_manager->RemoveObserver(this);
33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Observe the selected file system.
33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  file_system_provider::ProvidedFileSystemInterface* const file_system =
33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      service->GetProvidedFileSystem(extension_id, file_system_id);
33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!file_system)
33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  file_system_provider::RequestManager* const request_manager =
34146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      file_system->GetRequestManager();
34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(request_manager);
34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  request_manager->AddObserver(this);
34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  selected_extension_id = extension_id;
34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  selected_file_system_id = file_system_id;
347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ProvidedFileSystemsUI::ProvidedFileSystemsUI(content::WebUI* web_ui)
352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : WebUIController(web_ui) {
353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  web_ui->AddMessageHandler(new ProvidedFileSystemsWebUIHandler());
354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::WebUIDataSource* source = content::WebUIDataSource::Create(
356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      chrome::kChromeUIProvidedFileSystemsHost);
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  source->AddResourcePath("provided_file_systems.css",
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          IDR_PROVIDED_FILE_SYSTEMS_CSS);
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  source->AddResourcePath("provided_file_systems.js",
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          IDR_PROVIDED_FILE_SYSTEMS_JS);
361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  source->SetDefaultResource(IDR_PROVIDED_FILE_SYSTEMS_HTML);
362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Profile* profile = Profile::FromWebUI(web_ui);
364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::WebUIDataSource::Add(profile, source);
365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace chromeos
368