1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// found in the LICENSE file. 4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#ifndef CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_REQUEST_MANAGER_H_ 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_REQUEST_MANAGER_H_ 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <map> 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <string> 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <vector> 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/callback.h" 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/files/file.h" 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/memory/scoped_ptr.h" 150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/memory/weak_ptr.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/observer_list.h" 170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/time/time.h" 180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/timer/timer.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/file_system_provider/notification_manager_interface.h" 200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h" 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/chromeos/file_system_provider/request_value.h" 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace chromeos { 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace file_system_provider { 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Request type, passed to RequestManager::CreateRequest. For logging purposes. 2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)enum RequestType { 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) REQUEST_UNMOUNT, 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GET_METADATA, 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) READ_DIRECTORY, 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OPEN_FILE, 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CLOSE_FILE, 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) READ_FILE, 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CREATE_DIRECTORY, 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DELETE_ENTRY, 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CREATE_FILE, 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) COPY_ENTRY, 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOVE_ENTRY, 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRUNCATE, 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WRITE_FILE, 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ABORT, 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) TESTING 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Converts a request type to human-readable format. 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)std::string RequestTypeToString(RequestType type); 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Manages requests between the service, async utils and the providing 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// extensions. 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass RequestManager { 51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public: 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Handles requests. Each request implementation must implement 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // this interface. 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu class HandlerInterface { 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual ~HandlerInterface() {} 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Called when the request is created. Executes the request implementation. 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Returns false in case of a execution failure. 605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool Execute(int request_id) = 0; 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Success callback invoked by the providing extension in response to 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Execute(). It may be called more than once, until |has_more| is set to 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // false. 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void OnSuccess(int request_id, 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<RequestValue> result, 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool has_more) = 0; 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Error callback invoked by the providing extension in response to 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Execute(). It can be called at most once. It can be also called if the 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // request is aborted due to a timeout. 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void OnError(int request_id, 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<RequestValue> result, 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::File::Error error) = 0; 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu }; 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Observes activities in the request manager. 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) class Observer { 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~Observer() {} 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Called when the request is created. 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnRequestCreated(int request_id, RequestType type) = 0; 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Called when the request is destroyed. 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnRequestDestroyed(int request_id) = 0; 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Called when the request is executed. 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnRequestExecuted(int request_id) = 0; 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Called when the request is fulfilled with a success. 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void OnRequestFulfilled(int request_id, 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const RequestValue& result, 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool has_more) = 0; 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Called when the request is rejected with an error. 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void OnRequestRejected(int request_id, 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const RequestValue& result, 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::File::Error error) = 0; 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Called when the request is timeouted. 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnRequestTimeouted(int request_id) = 0; 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }; 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch explicit RequestManager(NotificationManagerInterface* notification_manager); 106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual ~RequestManager(); 107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Creates a request and returns its request id (greater than 0). Returns 0 in 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // case of an error (eg. too many requests). The |type| argument indicates 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // what kind of request it is. 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int CreateRequest(RequestType type, scoped_ptr<HandlerInterface> handler); 112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Handles successful response for the |request_id|. If |has_more| is false, 114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // then the request is disposed, after handling the |response|. On error, 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // returns false, and the request is disposed. |response| must not be NULL. 1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool FulfillRequest(int request_id, 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<RequestValue> response, 11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool has_more); 119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Handles error response for the |request_id|. If handling the error fails, 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // returns false. Always disposes the request. |response| must not be NULL. 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool RejectRequest(int request_id, 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<RequestValue> response, 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::File::Error error); 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Sets a custom timeout for tests. The new timeout value will be applied to 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // new requests 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) void SetTimeoutForTesting(const base::TimeDelta& timeout); 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Gets list of active request ids. 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<int> GetActiveRequestIds() const; 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Adds and removes observers. 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void AddObserver(Observer* observer); 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void RemoveObserver(Observer* observer); 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private: 138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch struct Request { 139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Request(); 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ~Request(); 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Timer for discarding the request during a timeout. 1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::OneShotTimer<RequestManager> timeout_timer; 144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Handler tied to this request. 1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<HandlerInterface> handler; 1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private: 1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(Request); 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch }; 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch typedef std::map<int, Request*> RequestMap; 1530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Destroys the request with the passed |request_id|. 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void DestroyRequest(int request_id); 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Called when a request with |request_id| timeouts. 1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void OnRequestTimeout(int request_id); 159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Called when an user either aborts the unresponsive request or lets it 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // continue. 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void OnUnresponsiveNotificationResult( 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int request_id, 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NotificationManagerInterface::NotificationResult result); 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Resets the timeout timer for the specified request. 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void ResetTimer(int request_id); 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch RequestMap requests_; 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NotificationManagerInterface* notification_manager_; // Not owned. 171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int next_id_; 1720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::TimeDelta timeout_; 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ObserverList<Observer> observers_; 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtrFactory<RequestManager> weak_ptr_factory_; 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DISALLOW_COPY_AND_ASSIGN(RequestManager); 177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace file_system_provider 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace chromeos 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif // CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_REQUEST_MANAGER_H_ 183