1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_REQUEST_MANAGER_H_
#define CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_REQUEST_MANAGER_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/files/file.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ash/file_system_provider/notification_manager_interface.h"
#include "chrome/browser/ash/file_system_provider/request_value.h"
class Profile;
namespace ash::file_system_provider {
// Request type, passed to RequestManager::CreateRequest. For logging purposes.
enum class RequestType {
kAbort = 0,
kAddWatcher = 1,
kCloseFile = 2,
kConfigure = 3,
kCopyEntry = 4,
kCreateDirectory = 5,
kCreateFile = 6,
kDeleteEntry = 7,
kExecuteAction = 8,
kGetActions = 9,
kGetMetadata = 10,
kMount = 11,
kMoveEntry = 12,
kOpenFile = 13,
kReadDirectory = 14,
kReadFile = 15,
kRemoveWatcher = 16,
kTruncate = 17,
kUnmount = 18,
kWriteFile = 19,
};
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class OperationCompletion {
kCompletedNormally = 0,
kCompletedAfterWarning = 1,
kAbortedFromNotification = 2,
kAbortedInternally = 3,
kMaxValue = kAbortedInternally,
};
// Manages requests between the service, async utils and the providing
// extension or native provider.
class RequestManager {
public:
// Handles requests. Each request implementation must implement
// this interface.
class HandlerInterface {
public:
virtual ~HandlerInterface() = default;
// Called when the request is created. Executes the request implementation.
// Returns false in case of a execution failure.
virtual bool Execute(int request_id) = 0;
// Success callback invoked by the provider in response to
// Execute(). It may be called more than once, until |has_more| is set to
// false.
virtual void OnSuccess(int request_id,
const RequestValue& result,
bool has_more) = 0;
// Error callback invoked by the providing extension in response to
// Execute(). It can be called at most once. It can be also called if the
// request is aborted due to a timeout.
virtual void OnError(int request_id,
const RequestValue& result,
base::File::Error error) = 0;
// Called when the request is aborted due to timeout, before |OnError| is
// called.
virtual void OnAbort(int request_id) = 0;
};
// Observes activities in the request manager.
class Observer {
public:
virtual ~Observer() = default;
// Called when the request is created.
virtual void OnRequestCreated(int request_id, RequestType type) = 0;
// Called when the request is destroyed.
virtual void OnRequestDestroyed(int request_id,
OperationCompletion completion) = 0;
// Called when the request is executed.
virtual void OnRequestExecuted(int request_id) = 0;
// Called when the request is fulfilled with a success.
virtual void OnRequestFulfilled(int request_id,
const RequestValue& result,
bool has_more) = 0;
// Called when the request is rejected with an error.
virtual void OnRequestRejected(int request_id,
const RequestValue& result,
base::File::Error error) = 0;
// Called when the request is timed out.
virtual void OnRequestTimedOut(int request_id) = 0;
};
RequestManager(Profile* profile,
NotificationManagerInterface* notification_manager,
base::TimeDelta timeout);
RequestManager(const RequestManager&) = delete;
RequestManager& operator=(const RequestManager&) = delete;
virtual ~RequestManager();
// Creates a request and returns its request id (greater than 0). Returns 0 in
// case of an error (eg. too many requests). The |type| argument indicates
// what kind of request it is.
int CreateRequest(RequestType type,
std::unique_ptr<HandlerInterface> handler);
// Handles successful response for the |request_id|. If |has_more| is false,
// then the request is disposed, after handling the |response|. On success,
// returns base::File::FILE_OK. Otherwise returns an error code. |response|
// must not be NULL.
base::File::Error FulfillRequest(int request_id,
const RequestValue& response,
bool has_more);
// Handles error response for the |request_id|. If handling the error
// succeeds, theen returns base::File::FILE_OK. Otherwise returns an error
// code. Always disposes the request. |response| must not be NULL.
base::File::Error RejectRequest(int request_id,
const RequestValue& response,
base::File::Error error);
// Sets a custom timeout for tests. The new timeout value will be applied to
// new requests
void SetTimeoutForTesting(const base::TimeDelta& timeout);
// Gets list of active request ids.
std::vector<int> GetActiveRequestIds() const;
// Adds and removes observers.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Destroys the request with the passed |request_id|.
void DestroyRequest(int request_id, OperationCompletion completion);
protected:
struct Request {
Request();
Request(const Request&) = delete;
Request& operator=(const Request&) = delete;
~Request();
// Timer for discarding the request during a timeout.
base::OneShotTimer timeout_timer;
// Handler tied to this request.
std::unique_ptr<HandlerInterface> handler;
// Indicates if this operation timed out and a warning has been shown to the
// user.
bool shown_unresponsive_notification = false;
};
// Called when a request with |request_id| timeouts.
virtual void OnRequestTimeout(int request_id);
// Called when an user either aborts the unresponsive request or lets it
// continue.
void OnUnresponsiveNotificationResult(
int request_id,
NotificationManagerInterface::NotificationResult result);
// Resets the timeout timer for the specified request.
void ResetTimer(int request_id);
// Reject a request specifying how it was completed.
base::File::Error RejectRequestInternal(int request_id,
const RequestValue& response,
base::File::Error error,
OperationCompletion completion);
raw_ptr<Profile> profile_; // Not owned.
std::map<int, std::unique_ptr<Request>> requests_;
raw_ptr<NotificationManagerInterface, DanglingUntriaged>
notification_manager_; // Not owned.
int next_id_;
base::TimeDelta timeout_;
base::ObserverList<Observer>::UncheckedAndDanglingUntriaged observers_;
base::WeakPtrFactory<RequestManager> weak_ptr_factory_{this};
};
} // namespace ash::file_system_provider
#endif // CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_REQUEST_MANAGER_H_
|