1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_REQUEST_MANAGER_H_
6#define CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_REQUEST_MANAGER_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/callback.h"
13#include "base/files/file.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "base/observer_list.h"
17#include "base/time/time.h"
18#include "base/timer/timer.h"
19#include "chrome/browser/chromeos/file_system_provider/notification_manager_interface.h"
20#include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
21#include "chrome/browser/chromeos/file_system_provider/request_value.h"
22
23namespace chromeos {
24namespace file_system_provider {
25
26// Request type, passed to RequestManager::CreateRequest. For logging purposes.
27enum RequestType {
28  REQUEST_UNMOUNT,
29  GET_METADATA,
30  READ_DIRECTORY,
31  OPEN_FILE,
32  CLOSE_FILE,
33  READ_FILE,
34  CREATE_DIRECTORY,
35  DELETE_ENTRY,
36  CREATE_FILE,
37  COPY_ENTRY,
38  MOVE_ENTRY,
39  TRUNCATE,
40  WRITE_FILE,
41  ABORT,
42  TESTING
43};
44
45// Converts a request type to human-readable format.
46std::string RequestTypeToString(RequestType type);
47
48// Manages requests between the service, async utils and the providing
49// extensions.
50class RequestManager {
51 public:
52  // Handles requests. Each request implementation must implement
53  // this interface.
54  class HandlerInterface {
55   public:
56    virtual ~HandlerInterface() {}
57
58    // Called when the request is created. Executes the request implementation.
59    // Returns false in case of a execution failure.
60    virtual bool Execute(int request_id) = 0;
61
62    // Success callback invoked by the providing extension in response to
63    // Execute(). It may be called more than once, until |has_more| is set to
64    // false.
65    virtual void OnSuccess(int request_id,
66                           scoped_ptr<RequestValue> result,
67                           bool has_more) = 0;
68
69    // Error callback invoked by the providing extension in response to
70    // Execute(). It can be called at most once. It can be also called if the
71    // request is aborted due to a timeout.
72    virtual void OnError(int request_id,
73                         scoped_ptr<RequestValue> result,
74                         base::File::Error error) = 0;
75  };
76
77  // Observes activities in the request manager.
78  class Observer {
79   public:
80    virtual ~Observer() {}
81
82    // Called when the request is created.
83    virtual void OnRequestCreated(int request_id, RequestType type) = 0;
84
85    // Called when the request is destroyed.
86    virtual void OnRequestDestroyed(int request_id) = 0;
87
88    // Called when the request is executed.
89    virtual void OnRequestExecuted(int request_id) = 0;
90
91    // Called when the request is fulfilled with a success.
92    virtual void OnRequestFulfilled(int request_id,
93                                    const RequestValue& result,
94                                    bool has_more) = 0;
95
96    // Called when the request is rejected with an error.
97    virtual void OnRequestRejected(int request_id,
98                                   const RequestValue& result,
99                                   base::File::Error error) = 0;
100
101    // Called when the request is timeouted.
102    virtual void OnRequestTimeouted(int request_id) = 0;
103  };
104
105  explicit RequestManager(NotificationManagerInterface* notification_manager);
106  virtual ~RequestManager();
107
108  // Creates a request and returns its request id (greater than 0). Returns 0 in
109  // case of an error (eg. too many requests). The |type| argument indicates
110  // what kind of request it is.
111  int CreateRequest(RequestType type, scoped_ptr<HandlerInterface> handler);
112
113  // Handles successful response for the |request_id|. If |has_more| is false,
114  // then the request is disposed, after handling the |response|. On error,
115  // returns false, and the request is disposed. |response| must not be NULL.
116  bool FulfillRequest(int request_id,
117                      scoped_ptr<RequestValue> response,
118                      bool has_more);
119
120  // Handles error response for the |request_id|. If handling the error fails,
121  // returns false. Always disposes the request. |response| must not be NULL.
122  bool RejectRequest(int request_id,
123                     scoped_ptr<RequestValue> response,
124                     base::File::Error error);
125
126  // Sets a custom timeout for tests. The new timeout value will be applied to
127  // new requests
128  void SetTimeoutForTesting(const base::TimeDelta& timeout);
129
130  // Gets list of active request ids.
131  std::vector<int> GetActiveRequestIds() const;
132
133  // Adds and removes observers.
134  void AddObserver(Observer* observer);
135  void RemoveObserver(Observer* observer);
136
137 private:
138  struct Request {
139    Request();
140    ~Request();
141
142    // Timer for discarding the request during a timeout.
143    base::OneShotTimer<RequestManager> timeout_timer;
144
145    // Handler tied to this request.
146    scoped_ptr<HandlerInterface> handler;
147
148   private:
149    DISALLOW_COPY_AND_ASSIGN(Request);
150  };
151
152  typedef std::map<int, Request*> RequestMap;
153
154  // Destroys the request with the passed |request_id|.
155  void DestroyRequest(int request_id);
156
157  // Called when a request with |request_id| timeouts.
158  void OnRequestTimeout(int request_id);
159
160  // Called when an user either aborts the unresponsive request or lets it
161  // continue.
162  void OnUnresponsiveNotificationResult(
163      int request_id,
164      NotificationManagerInterface::NotificationResult result);
165
166  // Resets the timeout timer for the specified request.
167  void ResetTimer(int request_id);
168
169  RequestMap requests_;
170  NotificationManagerInterface* notification_manager_;  // Not owned.
171  int next_id_;
172  base::TimeDelta timeout_;
173  ObserverList<Observer> observers_;
174  base::WeakPtrFactory<RequestManager> weak_ptr_factory_;
175
176  DISALLOW_COPY_AND_ASSIGN(RequestManager);
177};
178
179}  // namespace file_system_provider
180}  // namespace chromeos
181
182#endif  // CHROME_BROWSER_CHROMEOS_FILE_SYSTEM_PROVIDER_REQUEST_MANAGER_H_
183