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