1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_GOOGLE_APIS_OPERATION_REGISTRY_H_
6 #define CHROME_BROWSER_GOOGLE_APIS_OPERATION_REGISTRY_H_
11 #include "base/basictypes.h"
12 #include "base/files/file_path.h"
13 #include "base/id_map.h"
14 #include "base/observer_list.h"
15 #include "base/time.h"
16 #include "chrome/browser/google_apis/gdata_errorcode.h"
18 namespace google_apis
{
20 class OperationRegistryObserver
;
22 // Unique ID to identify each operation.
23 typedef int32 OperationID
;
25 // Enumeration type for indicating the direction of the operation.
32 // Enumeration type for indicating the state of the transfer.
33 enum OperationTransferState
{
34 OPERATION_NOT_STARTED
,
36 OPERATION_IN_PROGRESS
,
42 // Returns string representations of the operation type and state, which are
43 // exposed to the private extension API as in:
44 // operation.chrome/common/extensions/api/file_browser_private.json
45 std::string
OperationTypeToString(OperationType type
);
46 std::string
OperationTransferStateToString(OperationTransferState state
);
48 // Structure that packs progress information of each operation.
49 struct OperationProgressStatus
{
50 OperationProgressStatus(OperationType type
, const base::FilePath
& file_path
);
52 std::string
DebugString() const;
54 OperationID operation_id
;
56 // Type of the operation: upload/download.
57 OperationType operation_type
;
58 // GData path of the file dealt with the current operation.
59 base::FilePath file_path
;
60 // Current state of the transfer;
61 OperationTransferState transfer_state
;
62 // The time when the operation is initiated.
63 base::Time start_time
;
64 // Current fraction of progress of the operation.
65 int64 progress_current
;
66 // Expected total number of bytes to be transferred in the operation.
67 // -1 if no expectation is available (yet).
70 typedef std::vector
<OperationProgressStatus
> OperationProgressStatusList
;
72 // This class tracks all the in-flight GData operation objects and manage their
74 class OperationRegistry
{
79 // Base class for operations that this registry class can maintain.
80 // NotifyStart() passes the ownership of the Operation object to the registry.
81 // In particular, calling NotifyFinish() causes the registry to delete the
82 // Operation object itself.
85 explicit Operation(OperationRegistry
* registry
);
86 Operation(OperationRegistry
* registry
,
88 const base::FilePath
& file_path
);
91 // Cancels the ongoing operation. NotifyFinish() is called and the Operation
92 // object is deleted once the cancellation is done in DoCancel().
95 // Retrieves the current progress status of the operation.
96 const OperationProgressStatus
& progress_status() const {
97 return progress_status_
;
101 // Notifies the registry about current status.
103 void NotifyProgress(int64 current
, int64 total
);
104 void NotifyFinish(OperationTransferState status
);
105 // Notifies suspend/resume, used for chunked upload operations.
106 // The initial upload operation should issue "start" "progress"* "suspend".
107 // The subsequent operations will call "resume" "progress"* "suspend",
108 // and the last one will do "resume" "progress"* "finish".
109 // In other words, "suspend" is similar to "finish" except it lasts to live
110 // until the next "resume" comes. "Resume" is similar to "start", except
111 // that it removes the existing "suspend" operation.
112 void NotifySuspend();
116 // Does the cancellation.
117 virtual void DoCancel() = 0;
119 OperationRegistry
* const registry_
;
120 OperationProgressStatus progress_status_
;
123 // Cancels all in-flight operations.
126 // Cancels ongoing operation for a given virtual |file_path|. Returns true if
127 // the operation was found and canceled.
128 bool CancelForFilePath(const base::FilePath
& file_path
);
130 // Obtains the list of currently active operations.
131 OperationProgressStatusList
GetProgressStatusList();
133 // Sets an observer. The registry do NOT own observers; before destruction
134 // they need to be removed from the registry.
135 void AddObserver(OperationRegistryObserver
* observer
);
136 void RemoveObserver(OperationRegistryObserver
* observer
);
138 // Disables the notification suppression for testing purpose.
139 void DisableNotificationFrequencyControlForTest();
142 // Handlers for notifications from Operations.
143 friend class Operation
;
144 // Notifies that an operation has started. This method passes the ownership of
145 // the operation to the registry. A fresh operation ID is returned to *id.
146 void OnOperationStart(Operation
* operation
, OperationID
* id
);
147 void OnOperationProgress(OperationID operation
);
148 void OnOperationFinish(OperationID operation
);
149 void OnOperationSuspend(OperationID operation
);
150 void OnOperationResume(Operation
* operation
,
151 OperationProgressStatus
* new_status
);
153 bool IsFileTransferOperation(const Operation
* operation
) const;
155 // Controls the frequency of notifications, not to flood the listeners with
157 bool ShouldNotifyStatusNow(const OperationProgressStatusList
& list
);
158 // Sends notifications to the observers after checking that the frequency is
159 // not too high by ShouldNotifyStatusNow.
160 void NotifyStatusToObservers();
162 // Cancels the specified operation.
163 void CancelOperation(Operation
* operation
);
165 typedef IDMap
<Operation
, IDMapOwnPointer
> OperationIDMap
;
166 OperationIDMap in_flight_operations_
;
167 ObserverList
<OperationRegistryObserver
> observer_list_
;
168 base::Time last_notification_
;
169 bool do_notification_frequency_control_
;
171 DISALLOW_COPY_AND_ASSIGN(OperationRegistry
);
174 // Observer interface for listening changes in the active set of operations.
175 class OperationRegistryObserver
{
177 // Called when a GData operation started, made some progress, or finished.
178 virtual void OnProgressUpdate(const OperationProgressStatusList
& list
) {}
181 virtual ~OperationRegistryObserver() {}
184 } // namespace google_apis
186 #endif // CHROME_BROWSER_GOOGLE_APIS_OPERATION_REGISTRY_H_