Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8831)

Unified Diff: chrome/browser/sync/glue/sync_backend_host.h

Issue 160598: Add files to browser/sync. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/sync/glue/model_associator.cc ('k') | chrome/browser/sync/glue/sync_backend_host.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/sync/glue/sync_backend_host.h
===================================================================
--- chrome/browser/sync/glue/sync_backend_host.h (revision 0)
+++ chrome/browser/sync/glue/sync_backend_host.h (revision 0)
@@ -0,0 +1,274 @@
+// Copyright (c) 2006-2008 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.
+
+#ifdef CHROME_PERSONALIZATION
+
+#ifndef CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
+#define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
+
+#include <string>
+
+#include "base/file_path.h"
+#include "base/lock.h"
+#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/thread.h"
+#include "base/timer.h"
+#include "chrome/browser/sync/auth_error_state.h"
+#include "chrome/browser/sync/engine/syncapi.h"
+#include "chrome/browser/sync/glue/bookmark_model_worker.h"
+#include "googleurl/src/gurl.h"
+
+namespace browser_sync {
+
+class SyncFrontend;
+
+// A UI-thread safe API into the sync backend that "hosts" the top-level
+// syncapi element, the SyncManager, on its own thread. This class handles
+// dispatch of potentially blocking calls to appropriate threads and ensures
+// that the SyncFrontend is only accessed on the UI loop.
+class SyncBackendHost {
+ public:
+ typedef sync_api::UserShare* UserShareHandle;
+ typedef sync_api::SyncManager::Status::Summary StatusSummary;
+ typedef sync_api::SyncManager::Status Status;
+
+ // Create a SyncBackendHost with a reference to the |frontend| that it serves
+ // and communicates to via the SyncFrontend interface (on the same thread
+ // it used to call the constructor).
+ SyncBackendHost(SyncFrontend* frontend, const FilePath& proifle_path);
+ ~SyncBackendHost();
+
+ // Called on |frontend_loop_| to kick off asynchronous initialization.
+ void Initialize(const GURL& service_url);
+
+ // Called on |frontend_loop_| to kick off asynchronous authentication.
+ void Authenticate(const std::string& username, const std::string& password);
+
+ // Called on |frontend_loop_| to kick off shutdown.
+ // |sync_disabled| indicates if syncing is being disabled or not.
+ // See the implementation and Core::DoShutdown for details.
+ void Shutdown(bool sync_disabled);
+
+ // Called on |frontend_loop_| to obtain a handle to the UserShare needed
+ // for creating transactions.
+ UserShareHandle GetUserShareHandle() const;
+
+ // Called from any thread to obtain current status information in detailed or
+ // summarized form.
+ Status GetDetailedStatus();
+ StatusSummary GetStatusSummary();
+ AuthErrorState GetAuthErrorState() const;
+
+ const FilePath& sync_data_folder_path() const {
+ return sync_data_folder_path_;
+ }
+
+ // Returns the authenticated username of the sync user, or empty if none
+ // exists. It will only exist if the authentication service provider (e.g
+ // GAIA) has confirmed the username is authentic.
+ string16 GetAuthenticatedUsername() const;
+
+#ifdef UNIT_TEST
+ // Called from unit test to bypass authentication and initialize the syncapi
+ // to a state suitable for testing but not production.
+ void InitializeForTestMode(const std::wstring& test_user) {
+ if (!core_thread_.Start())
+ return;
+ bookmark_model_worker_ = new BookmarkModelWorker(frontend_loop_);
+ core_thread_.message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(core_.get(),
+ &SyncBackendHost::Core::DoInitializeForTest,
+ bookmark_model_worker_,
+ test_user));
+ }
+#endif
+
+ private:
+ // The real guts of SyncBackendHost, to keep the public client API clean.
+ class Core : public base::RefCountedThreadSafe<SyncBackendHost::Core>,
+ public sync_api::SyncManager::Observer {
+ public:
+ explicit Core(SyncBackendHost* backend);
+
+ // Note: This destructor should *always* be called from the thread that
+ // created it, and *always* after core_thread_ has exited. The syncapi
+ // watches thread exit events and keeps pointers to objects this dtor will
+ // destroy, so this ordering is important.
+ ~Core() {
+ }
+
+ // SyncManager::Observer implementation. The Core just acts like an air
+ // traffic controller here, forwarding incoming messages to appropriate
+ // landing threads.
+ virtual void OnChangesApplied(
+ const sync_api::BaseTransaction* trans,
+ const sync_api::SyncManager::ChangeRecord* changes,
+ int change_count);
+ virtual void OnSyncCycleCompleted();
+ virtual void OnInitializationComplete();
+ virtual void OnAuthProblem(
+ sync_api::SyncManager::AuthProblem auth_problem);
+
+ // Note:
+ //
+ // The Do* methods are the various entry points from our SyncBackendHost.
+ // It calls us on a dedicated thread to actually perform synchronous
+ // (and potentially blocking) syncapi operations.
+ //
+ // Called on the SyncBackendHost core_thread_ to perform initialization
+ // of the syncapi on behalf of SyncBackendHost::Initialize.
+ void DoInitialize(const GURL& service_url,
+ BookmarkModelWorker* bookmark_model_worker_,
+ bool attempt_last_user_authentication);
+
+ // Called on our SyncBackendHost's core_thread_ to perform authentication
+ // on behalf of SyncBackendHost::Authenticate.
+ void DoAuthenticate(const std::string& username,
+ const std::string& password);
+
+ // The shutdown order is a bit complicated:
+ // 1) From |core_thread_|, invoke the syncapi Shutdown call to do a final
+ // SaveChanges, close sqlite handles, and halt the syncer thread (which
+ // could potentially block for 1 minute).
+ // 2) Then, from |frontend_loop_|, halt the core_thread_. This causes
+ // syncapi thread-exit handlers to run and make use of cached pointers to
+ // various components owned implicitly by us.
+ // 3) Destroy this Core. That will delete syncapi components in a safe order
+ // because the thread that was using them has exited (in step 2).
+ void DoShutdown(bool stopping_sync);
+
+ sync_api::SyncManager* syncapi() { return syncapi_.get(); }
+
+#ifdef UNIT_TEST
+ // Special form of initialization that does not try and authenticate the
+ // last known user (since it will fail in test mode) and does some extra
+ // setup to nudge the syncapi into a useable state.
+ void DoInitializeForTest(BookmarkModelWorker* bookmark_model_worker,
+ const std::wstring& test_user) {
+ DoInitialize(GURL(), bookmark_model_worker, false);
+ syncapi_->SetupForTestMode(WideToUTF16(test_user).c_str());
+ }
+#endif
+
+ private:
+ // FrontendNotification defines parameters for NotifyFrontend. Each enum
+ // value corresponds to the one SyncFrontend interface method that
+ // NotifyFrontend should invoke.
+ enum FrontendNotification {
+ INITIALIZED, // OnBackendInitialized.
+ SYNC_CYCLE_COMPLETED, // A round-trip sync-cycle took place and
+ // the syncer has resolved any conflicts
+ // that may have arisen.
+ };
+
+ // NotifyFrontend is how the Core communicates with the frontend across
+ // threads. Having this extra method (rather than having the Core PostTask
+ // to the frontend explicitly) means SyncFrontend implementations don't
+ // need to be RefCountedThreadSafe because NotifyFrontend is invoked on the
+ // |frontend_loop_|.
+ void NotifyFrontend(FrontendNotification notification);
+
+ // Invoked when initialization of syncapi is complete and we can start
+ // our timer.
+ // This must be called from the thread on which SaveChanges is intended to
+ // be run on; the host's |core_thread_|.
+ void StartSavingChanges();
+
+ // Invoked periodically to tell the syncapi to persist its state
+ // by writing to disk.
+ // This is called from the thread we were created on (which is the
+ // SyncBackendHost |core_thread_|), using a repeating timer that is kicked
+ // off as soon as the SyncManager tells us it completed
+ // initialization.
+ void SaveChanges();
+
+ // Dispatched to from HandleAuthErrorEventOnCoreLoop to handle updating
+ // frontend UI components.
+ void HandleAuthErrorEventOnFrontendLoop(AuthErrorState new_auth_error);
+
+ // Our parent SyncBackendHost
+ SyncBackendHost* host_;
+
+ // The timer used to periodically call SaveChanges.
+ base::RepeatingTimer<Core> save_changes_timer_;
+
+ // The top-level syncapi entry point.
+ scoped_ptr<sync_api::SyncManager> syncapi_;
+
+ DISALLOW_COPY_AND_ASSIGN(Core);
+ };
+
+ // A thread we dedicate for use by our Core to perform initialization,
+ // authentication, handle messages from the syncapi, and periodically tell
+ // the syncapi to persist itself.
+ base::Thread core_thread_;
+
+ // Our core, which communicates directly to the syncapi.
+ scoped_refptr<Core> core_;
+
+ // A reference to the MessageLoop used to construct |this|, so we know how
+ // to safely talk back to the SyncFrontend.
+ MessageLoop* const frontend_loop_;
+
+ // We hold on to the BookmarkModelWorker created for the syncapi to ensure
+ // shutdown occurs in the sequence we expect by calling Stop() at the
+ // appropriate time. It is guaranteed to be valid because the worker is
+ // only destroyed when the SyncManager is destroyed, which happens when
+ // our Core is destroyed, which happens in Shutdown().
+ BookmarkModelWorker* bookmark_model_worker_;
+
+ // The frontend which we serve (and are owned by).
+ SyncFrontend* frontend_;
+
+ // Path of the folder that stores the sync data files.
+ FilePath sync_data_folder_path_;
+
+ // UI-thread cache of the last AuthErrorState received from syncapi.
+ AuthErrorState last_auth_error_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyncBackendHost);
+};
+
+// SyncFrontend is the interface used by SyncBackendHost to communicate with
+// the entity that created it and, presumably, is interested in sync-related
+// activity.
+// NOTE: All methods will be invoked by a SyncBackendHost on the same thread
+// used to create that SyncBackendHost.
+class SyncFrontend {
+ public:
+ typedef sync_api::BaseTransaction BaseTransaction;
+ typedef sync_api::SyncManager::ChangeRecord ChangeRecord;
+ SyncFrontend() {
+ }
+
+ // The backend has completed initialization and it is now ready to accept and
+ // process changes.
+ virtual void OnBackendInitialized() = 0;
+
+ // The backend queried the server recently and received some updates.
+ virtual void OnSyncCycleCompleted() = 0;
+
+ // The backend encountered an authentication problem and requests new
+ // credentials to be provided. See SyncBackendHost::Authenticate for details.
+ virtual void OnAuthError() = 0;
+
+ // Changes have been applied to the backend model and are ready to be
+ // applied to the frontend model. See syncapi.h for detailed instructions on
+ // how to interpret and process |changes|.
+ virtual void ApplyModelChanges(const BaseTransaction* trans,
+ const ChangeRecord* changes,
+ int change_count) = 0;
+ protected:
+ // Don't delete through SyncFrontend interface.
+ virtual ~SyncFrontend() {
+ }
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SyncFrontend);
+};
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
+#endif // CHROME_PERSONALIZATION
Property changes on: chrome\browser\sync\glue\sync_backend_host.h
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « chrome/browser/sync/glue/model_associator.cc ('k') | chrome/browser/sync/glue/sync_backend_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698