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. 4 5 #include "chrome/browser/sync/glue/bookmark_data_type_controller.h" 6 7 #include "base/metrics/histogram.h" 8 #include "chrome/browser/bookmarks/bookmark_model.h" 9 #include "chrome/browser/bookmarks/bookmark_model_factory.h" 10 #include "chrome/browser/chrome_notification_types.h" 11 #include "chrome/browser/history/history_service.h" 12 #include "chrome/browser/history/history_service_factory.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/sync/profile_sync_components_factory.h" 15 #include "chrome/browser/sync/profile_sync_service.h" 16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/notification_details.h" 18 #include "content/public/browser/notification_source.h" 19 20 using content::BrowserThread; 21 22 namespace browser_sync { 23 24 BookmarkDataTypeController::BookmarkDataTypeController( 25 ProfileSyncComponentsFactory* profile_sync_factory, 26 Profile* profile, 27 ProfileSyncService* sync_service) 28 : FrontendDataTypeController(profile_sync_factory, 29 profile, 30 sync_service), 31 bookmark_model_(NULL), 32 installed_bookmark_observer_(false) { 33 } 34 35 syncer::ModelType BookmarkDataTypeController::type() const { 36 return syncer::BOOKMARKS; 37 } 38 39 void BookmarkDataTypeController::Observe( 40 int type, 41 const content::NotificationSource& source, 42 const content::NotificationDetails& details) { 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 44 DCHECK_EQ(state_, MODEL_STARTING); 45 DCHECK_EQ(chrome::NOTIFICATION_HISTORY_LOADED, type); 46 47 if (!DependentsLoaded()) 48 return; 49 50 bookmark_model_->RemoveObserver(this); 51 installed_bookmark_observer_ = false; 52 53 registrar_.RemoveAll(); 54 OnModelLoaded(); 55 } 56 57 BookmarkDataTypeController::~BookmarkDataTypeController() { 58 if (installed_bookmark_observer_ && bookmark_model_) { 59 DCHECK(profile_); 60 bookmark_model_->RemoveObserver(this); 61 } 62 } 63 64 bool BookmarkDataTypeController::StartModels() { 65 bookmark_model_ = BookmarkModelFactory::GetForProfile(profile_); 66 if (!DependentsLoaded()) { 67 bookmark_model_->AddObserver(this); 68 installed_bookmark_observer_ = true; 69 70 registrar_.Add(this, chrome::NOTIFICATION_HISTORY_LOADED, 71 content::Source<Profile>(sync_service_->profile())); 72 return false; 73 } 74 return true; 75 } 76 77 // Cleanup for our extra registrar usage. 78 void BookmarkDataTypeController::CleanUpState() { 79 registrar_.RemoveAll(); 80 } 81 82 void BookmarkDataTypeController::CreateSyncComponents() { 83 ProfileSyncComponentsFactory::SyncComponents sync_components = 84 profile_sync_factory_->CreateBookmarkSyncComponents(sync_service_, 85 this); 86 set_model_associator(sync_components.model_associator); 87 set_change_processor(sync_components.change_processor); 88 } 89 90 void BookmarkDataTypeController::BookmarkModelChanged() { 91 } 92 93 void BookmarkDataTypeController::Loaded(BookmarkModel* model, 94 bool ids_reassigned) { 95 DCHECK(model->loaded()); 96 model->RemoveObserver(this); 97 installed_bookmark_observer_ = false; 98 99 if (!DependentsLoaded()) 100 return; 101 102 registrar_.RemoveAll(); 103 OnModelLoaded(); 104 } 105 106 void BookmarkDataTypeController::BookmarkModelBeingDeleted( 107 BookmarkModel* model) { 108 installed_bookmark_observer_ = false; 109 } 110 111 // Check that both the bookmark model and the history service (for favicons) 112 // are loaded. 113 bool BookmarkDataTypeController::DependentsLoaded() { 114 if (!bookmark_model_ || !bookmark_model_->loaded()) 115 return false; 116 117 HistoryService* history = HistoryServiceFactory::GetForProfile( 118 profile_, Profile::EXPLICIT_ACCESS); 119 if (!history || !history->BackendLoaded()) 120 return false; 121 122 // All necessary services are loaded. 123 return true; 124 } 125 126 } // namespace browser_sync 127