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
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_GOOGLE_APIS_OPERATION_REGISTRY_H_
#define CHROME_BROWSER_GOOGLE_APIS_OPERATION_REGISTRY_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/id_map.h"
#include "base/observer_list.h"
#include "base/time.h"
#include "chrome/browser/google_apis/gdata_errorcode.h"
namespace google_apis {
class OperationRegistryObserver;
// Unique ID to identify each operation.
typedef int32 OperationID;
// Enumeration type for indicating the direction of the operation.
enum OperationType {
OPERATION_UPLOAD,
OPERATION_DOWNLOAD,
OPERATION_OTHER,
};
// Enumeration type for indicating the state of the transfer.
enum OperationTransferState {
OPERATION_NOT_STARTED,
OPERATION_STARTED,
OPERATION_IN_PROGRESS,
OPERATION_COMPLETED,
OPERATION_FAILED,
OPERATION_SUSPENDED,
};
// Returns string representations of the operation type and state, which are
// exposed to the private extension API as in:
// operation.chrome/common/extensions/api/file_browser_private.json
std::string OperationTypeToString(OperationType type);
std::string OperationTransferStateToString(OperationTransferState state);
// Structure that packs progress information of each operation.
struct OperationProgressStatus {
OperationProgressStatus(OperationType type, const base::FilePath& file_path);
// For debugging
std::string DebugString() const;
OperationID operation_id;
// Type of the operation: upload/download.
OperationType operation_type;
// GData path of the file dealt with the current operation.
base::FilePath file_path;
// Current state of the transfer;
OperationTransferState transfer_state;
// The time when the operation is initiated.
base::Time start_time;
// Current fraction of progress of the operation.
int64 progress_current;
// Expected total number of bytes to be transferred in the operation.
// -1 if no expectation is available (yet).
int64 progress_total;
};
typedef std::vector<OperationProgressStatus> OperationProgressStatusList;
// This class tracks all the in-flight GData operation objects and manage their
// lifetime.
class OperationRegistry {
public:
OperationRegistry();
~OperationRegistry();
// Base class for operations that this registry class can maintain.
// NotifyStart() passes the ownership of the Operation object to the registry.
// In particular, calling NotifyFinish() causes the registry to delete the
// Operation object itself.
class Operation {
public:
explicit Operation(OperationRegistry* registry);
Operation(OperationRegistry* registry,
OperationType type,
const base::FilePath& file_path);
virtual ~Operation();
// Cancels the ongoing operation. NotifyFinish() is called and the Operation
// object is deleted once the cancellation is done in DoCancel().
void Cancel();
// Retrieves the current progress status of the operation.
const OperationProgressStatus& progress_status() const {
return progress_status_;
}
protected:
// Notifies the registry about current status.
void NotifyStart();
void NotifyProgress(int64 current, int64 total);
void NotifyFinish(OperationTransferState status);
// Notifies suspend/resume, used for chunked upload operations.
// The initial upload operation should issue "start" "progress"* "suspend".
// The subsequent operations will call "resume" "progress"* "suspend",
// and the last one will do "resume" "progress"* "finish".
// In other words, "suspend" is similar to "finish" except it lasts to live
// until the next "resume" comes. "Resume" is similar to "start", except
// that it removes the existing "suspend" operation.
void NotifySuspend();
void NotifyResume();
private:
// Does the cancellation.
virtual void DoCancel() = 0;
OperationRegistry* const registry_;
OperationProgressStatus progress_status_;
};
// Cancels all in-flight operations.
void CancelAll();
// Cancels ongoing operation for a given virtual |file_path|. Returns true if
// the operation was found and canceled.
bool CancelForFilePath(const base::FilePath& file_path);
// Obtains the list of currently active operations.
OperationProgressStatusList GetProgressStatusList();
// Sets an observer. The registry do NOT own observers; before destruction
// they need to be removed from the registry.
void AddObserver(OperationRegistryObserver* observer);
void RemoveObserver(OperationRegistryObserver* observer);
// Disables the notification suppression for testing purpose.
void DisableNotificationFrequencyControlForTest();
private:
// Handlers for notifications from Operations.
friend class Operation;
// Notifies that an operation has started. This method passes the ownership of
// the operation to the registry. A fresh operation ID is returned to *id.
void OnOperationStart(Operation* operation, OperationID* id);
void OnOperationProgress(OperationID operation);
void OnOperationFinish(OperationID operation);
void OnOperationSuspend(OperationID operation);
void OnOperationResume(Operation* operation,
OperationProgressStatus* new_status);
bool IsFileTransferOperation(const Operation* operation) const;
// Controls the frequency of notifications, not to flood the listeners with
// too many events.
bool ShouldNotifyStatusNow(const OperationProgressStatusList& list);
// Sends notifications to the observers after checking that the frequency is
// not too high by ShouldNotifyStatusNow.
void NotifyStatusToObservers();
typedef IDMap<Operation, IDMapOwnPointer> OperationIDMap;
OperationIDMap in_flight_operations_;
ObserverList<OperationRegistryObserver> observer_list_;
base::Time last_notification_;
bool do_notification_frequency_control_;
DISALLOW_COPY_AND_ASSIGN(OperationRegistry);
};
// Observer interface for listening changes in the active set of operations.
class OperationRegistryObserver {
public:
// Called when a GData operation started, made some progress, or finished.
virtual void OnProgressUpdate(const OperationProgressStatusList& list) {}
protected:
virtual ~OperationRegistryObserver() {}
};
} // namespace google_apis
#endif // CHROME_BROWSER_GOOGLE_APIS_OPERATION_REGISTRY_H_
|