summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/engine/all_status.h
diff options
context:
space:
mode:
authornick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-10 06:05:27 +0000
committernick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-10 06:05:27 +0000
commit5852edc1b6eab234b9e048c41dd0d664ae7fc747 (patch)
tree9e5d8eb4833b76cdb11e66fc3607689e0f5e0122 /chrome/browser/sync/engine/all_status.h
parentf6059e37f8b8ac335ce18a189a13e702974a1c7e (diff)
downloadchromium_src-5852edc1b6eab234b9e048c41dd0d664ae7fc747.zip
chromium_src-5852edc1b6eab234b9e048c41dd0d664ae7fc747.tar.gz
chromium_src-5852edc1b6eab234b9e048c41dd0d664ae7fc747.tar.bz2
Initial commit of sync engine code to browser/sync.
The code is not built on any platform yet. That will arrive as a subsequent checkin. This is an implementation of the interface exposed earlier through syncapi.h. It is the client side of a sync protocol that lets users sync their browser data (currently, just bookmarks) with their Google Account. Table of contents: browser/sync/ protocol - The protocol definition, and other definitions necessary to connect to the service. syncable/ - defines a data model for syncable objects, and provides a sqlite-based backing store for this model. engine/ - includes the core sync logic, including commiting changes to the server, downloading changes from the server, resolving conflicts, other parts of the sync algorithm. engine/net - parts of the sync engine focused on the business of talking to the server. Some of this is binds a generic "server connection" interface to a concrete implementation provided by Chromium. notifier - the part of the syncer focused on the business of sending and receiving xmpp notifications. Notifications are used instead of polling to achieve very low latency change propagation. util - not necessarily sync specific utility code. Much of this is scaffolding which should either be replaced by, or merged with, the utility code in base/. BUG=none TEST=this code includes its own suite of unit tests. Review URL: http://codereview.chromium.org/194065 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25850 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/sync/engine/all_status.h')
-rw-r--r--chrome/browser/sync/engine/all_status.h210
1 files changed, 210 insertions, 0 deletions
diff --git a/chrome/browser/sync/engine/all_status.h b/chrome/browser/sync/engine/all_status.h
new file mode 100644
index 0000000..e7fb0ba
--- /dev/null
+++ b/chrome/browser/sync/engine/all_status.h
@@ -0,0 +1,210 @@
+// Copyright (c) 2006-2009 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.
+
+//
+// The all status object watches various sync engine components and aggregates
+// the status of all of them into one place.
+//
+#ifndef CHROME_BROWSER_SYNC_ENGINE_ALL_STATUS_H_
+#define CHROME_BROWSER_SYNC_ENGINE_ALL_STATUS_H_
+
+#include <map>
+
+#include "base/atomicops.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/sync/engine/syncer_status.h"
+#include "chrome/browser/sync/util/event_sys.h"
+#include "chrome/browser/sync/util/pthread_helpers.h"
+
+namespace browser_sync {
+class AuthWatcher;
+class GaiaAuthenticator;
+class ScopedStatusLockWithNotify;
+class ServerConnectionManager;
+class Syncer;
+class SyncerThread;
+class TalkMediator;
+struct AllStatusEvent;
+struct AuthWatcherEvent;
+struct GaiaAuthEvent;
+struct ServerConnectionEvent;
+struct SyncerEvent;
+struct TalkMediatorEvent;
+
+class AllStatus {
+ friend class ScopedStatusLockWithNotify;
+ public:
+ typedef EventChannel<AllStatusEvent, PThreadMutex> Channel;
+
+ // Status of the entire sync process distilled into a single enum.
+ enum SyncStatus {
+ // Can't connect to server, but there are no pending changes in
+ // our local dataase.
+ OFFLINE,
+ // Can't connect to server, and there are pending changes in our
+ // local cache.
+ OFFLINE_UNSYNCED,
+ // Connected and syncing.
+ SYNCING,
+ // Connected, no pending changes.
+ READY,
+ // Internal sync error.
+ CONFLICT,
+ // Can't connect to server, and we haven't completed the initial
+ // sync yet. So there's nothing we can do but wait for the server.
+ OFFLINE_UNUSABLE,
+ // For array sizing, etc.
+ ICON_STATUS_COUNT
+ };
+
+ struct Status {
+ SyncStatus icon;
+ int unsynced_count;
+ int conflicting_count;
+ bool syncing;
+ bool authenticated; // Successfully authenticated via gaia
+ // True if we have received at least one good reply from the server.
+ bool server_up;
+ bool server_reachable;
+ // True after a client has done a first sync.
+ bool initial_sync_ended;
+ // True if any syncer is stuck.
+ bool syncer_stuck;
+ // True if any syncer is stopped because of server issues.
+ bool server_broken;
+ // True only if the notification listener has subscribed.
+ bool notifications_enabled;
+ // Notifications counters updated by the actions in synapi.
+ int notifications_received;
+ int notifications_sent;
+ // The max number of consecutive errors from any component.
+ int max_consecutive_errors;
+ bool disk_full;
+
+ // Contains current transfer item meta handle
+ int64 current_item_meta_handle;
+ // The next two values will be equal if all updates have been received.
+ // total updates available.
+ int64 updates_available;
+ // total updates received.
+ int64 updates_received;
+ };
+
+ // Maximum interval for exponential backoff.
+ static const int kMaxBackoffSeconds = 60 * 60 * 4; // 4 hours.
+
+ AllStatus();
+ ~AllStatus();
+
+ void WatchConnectionManager(ServerConnectionManager* conn_mgr);
+ void HandleServerConnectionEvent(const ServerConnectionEvent& event);
+
+ // Both WatchAuthenticator/HandleGaiaAuthEvent and WatchAuthWatcher/
+ // HandleAuthWatcherEventachieve have the same goal; use only one of the
+ // following two. (The AuthWatcher is watched under Windows; the
+ // GaiaAuthenticator is watched under Mac/Linux.)
+ void WatchAuthenticator(GaiaAuthenticator* gaia);
+ void HandleGaiaAuthEvent(const GaiaAuthEvent& event);
+
+ void WatchAuthWatcher(AuthWatcher* auth_watcher);
+ void HandleAuthWatcherEvent(const AuthWatcherEvent& event);
+
+ void WatchSyncerThread(SyncerThread* syncer_thread);
+ void HandleSyncerEvent(const SyncerEvent& event);
+
+ void WatchTalkMediator(
+ const browser_sync::TalkMediator* talk_mediator);
+ void HandleTalkMediatorEvent(
+ const browser_sync::TalkMediatorEvent& event);
+
+ // Returns a string description of the SyncStatus (currently just the ascii
+ // version of the enum). Will LOG(FATAL) if the status us out of range.
+ static const char* GetSyncStatusString(SyncStatus status);
+
+ Channel* channel() const { return channel_; }
+
+ Status status() const;
+
+ // DDOS avoidance function. The argument and return value is in seconds
+ static int GetRecommendedDelaySeconds(int base_delay_seconds);
+
+ // This uses AllStatus' max_consecutive_errors as the error count
+ int GetRecommendedDelay(int base_delay) const;
+
+ protected:
+ typedef PThreadScopedLock<PThreadMutex> MutexLock;
+ typedef std::map<Syncer*, EventListenerHookup*> Syncers;
+
+ // Examines syncer to calculate syncing and the unsynced count,
+ // and returns a Status with new values.
+ Status CalcSyncing() const;
+ Status CalcSyncing(const SyncerEvent& event) const;
+ Status CreateBlankStatus() const;
+
+ // Examines status to see what has changed, updates old_status in place.
+ int CalcStatusChanges(Status* old_status);
+
+ Status status_;
+ Channel* const channel_;
+ scoped_ptr<EventListenerHookup> conn_mgr_hookup_;
+ scoped_ptr<EventListenerHookup> gaia_hookup_;
+ scoped_ptr<EventListenerHookup> authwatcher_hookup_;
+ scoped_ptr<EventListenerHookup> syncer_thread_hookup_;
+ scoped_ptr<EventListenerHookup> diskfull_hookup_;
+ scoped_ptr<EventListenerHookup> talk_mediator_hookup_;
+
+ mutable PThreadMutex mutex_; // Protects all data members.
+};
+
+struct AllStatusEvent {
+ enum { // A bit mask of which members have changed.
+ SHUTDOWN = 0x0000,
+ ICON = 0x0001,
+ UNSYNCED_COUNT = 0x0002,
+ AUTHENTICATED = 0x0004,
+ SYNCING = 0x0008,
+ SERVER_UP = 0x0010,
+ NOTIFICATIONS_ENABLED = 0x0020,
+ INITIAL_SYNC_ENDED = 0x0080,
+ SERVER_REACHABLE = 0x0100,
+ DISK_FULL = 0x0200,
+ OVER_QUOTA = 0x0400,
+ NOTIFICATIONS_RECEIVED = 0x0800,
+ NOTIFICATIONS_SENT = 0x1000,
+ TRASH_WARNING = 0x40000,
+ };
+ int what_changed;
+ AllStatus::Status status;
+
+ typedef AllStatusEvent EventType;
+ static inline bool IsChannelShutdownEvent(const AllStatusEvent& e) {
+ return SHUTDOWN == e.what_changed;
+ }
+};
+
+enum StatusNotifyPlan {
+ NOTIFY_IF_STATUS_CHANGED,
+ // A small optimization, don't do the big compare when we know
+ // nothing has changed.
+ DONT_NOTIFY,
+};
+
+class ScopedStatusLockWithNotify {
+ public:
+ explicit ScopedStatusLockWithNotify(AllStatus* allstatus);
+ ~ScopedStatusLockWithNotify();
+ // Defaults to true, but can be explicitly reset so we don't have to
+ // do the big compare in the destructor. Small optimization.
+
+ inline void set_notify_plan(StatusNotifyPlan plan) { plan_ = plan; }
+ void NotifyOverQuota();
+ protected:
+ AllStatusEvent event_;
+ AllStatus* const allstatus_;
+ StatusNotifyPlan plan_;
+};
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_ENGINE_ALL_STATUS_H_