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/ui/ash/app_sync_ui_state.h" 6 7 #include "base/prefs/pref_service.h" 8 #include "chrome/browser/extensions/extension_service.h" 9 #include "chrome/browser/extensions/pending_extension_manager.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/sync/profile_sync_service.h" 12 #include "chrome/browser/sync/profile_sync_service_factory.h" 13 #include "chrome/browser/ui/ash/app_sync_ui_state_factory.h" 14 #include "chrome/browser/ui/ash/app_sync_ui_state_observer.h" 15 #include "extensions/browser/extension_registry.h" 16 #include "extensions/browser/extension_system.h" 17 18 #if defined(OS_CHROMEOS) 19 #include "components/user_manager/user_manager.h" 20 #endif 21 22 namespace { 23 24 // Max loading animation time in milliseconds. 25 const int kMaxSyncingTimeMs = 60 * 1000; 26 27 } // namespace 28 29 // static 30 AppSyncUIState* AppSyncUIState::Get(Profile* profile) { 31 return AppSyncUIStateFactory::GetForProfile(profile); 32 } 33 34 // static 35 bool AppSyncUIState::ShouldObserveAppSyncForProfile(Profile* profile) { 36 #if defined(OS_CHROMEOS) 37 if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) 38 return false; 39 40 if (!profile || profile->IsOffTheRecord()) 41 return false; 42 43 if (!ProfileSyncServiceFactory::HasProfileSyncService(profile)) 44 return false; 45 46 return profile->IsNewProfile(); 47 #else 48 return false; 49 #endif 50 } 51 52 AppSyncUIState::AppSyncUIState(Profile* profile) 53 : profile_(profile), 54 sync_service_(NULL), 55 status_(STATUS_NORMAL), 56 extension_registry_(NULL) { 57 StartObserving(); 58 } 59 60 AppSyncUIState::~AppSyncUIState() { 61 StopObserving(); 62 } 63 64 void AppSyncUIState::AddObserver(AppSyncUIStateObserver* observer) { 65 observers_.AddObserver(observer); 66 } 67 68 void AppSyncUIState::RemoveObserver(AppSyncUIStateObserver* observer) { 69 observers_.RemoveObserver(observer); 70 } 71 72 void AppSyncUIState::StartObserving() { 73 DCHECK(ShouldObserveAppSyncForProfile(profile_)); 74 DCHECK(!sync_service_); 75 DCHECK(!extension_registry_); 76 77 extension_registry_ = extensions::ExtensionRegistry::Get(profile_); 78 extension_registry_->AddObserver(this); 79 80 sync_service_ = ProfileSyncServiceFactory::GetForProfile(profile_); 81 CHECK(sync_service_); 82 sync_service_->AddObserver(this); 83 } 84 85 void AppSyncUIState::StopObserving() { 86 if (!sync_service_) 87 return; 88 89 sync_service_->RemoveObserver(this); 90 sync_service_ = NULL; 91 92 if (extension_registry_) 93 extension_registry_->RemoveObserver(this); 94 extension_registry_ = NULL; 95 96 profile_ = NULL; 97 } 98 99 void AppSyncUIState::SetStatus(Status status) { 100 if (status_ == status) 101 return; 102 103 status_ = status; 104 switch (status_) { 105 case STATUS_SYNCING: 106 max_syncing_status_timer_.Start( 107 FROM_HERE, 108 base::TimeDelta::FromMilliseconds(kMaxSyncingTimeMs), 109 this, &AppSyncUIState::OnMaxSyncingTimer); 110 break; 111 case STATUS_NORMAL: 112 case STATUS_TIMED_OUT: 113 max_syncing_status_timer_.Stop(); 114 StopObserving(); 115 break; 116 } 117 118 FOR_EACH_OBSERVER(AppSyncUIStateObserver, 119 observers_, 120 OnAppSyncUIStatusChanged()); 121 } 122 123 void AppSyncUIState::CheckAppSync() { 124 if (!sync_service_ || !sync_service_->HasSyncSetupCompleted()) 125 return; 126 127 const bool synced = sync_service_->ShouldPushChanges(); 128 const bool has_pending_extension = 129 extensions::ExtensionSystem::Get(profile_)->extension_service()-> 130 pending_extension_manager()->HasPendingExtensionFromSync(); 131 132 if (synced && !has_pending_extension) 133 SetStatus(STATUS_NORMAL); 134 else 135 SetStatus(STATUS_SYNCING); 136 } 137 138 void AppSyncUIState::OnMaxSyncingTimer() { 139 SetStatus(STATUS_TIMED_OUT); 140 } 141 142 void AppSyncUIState::OnStateChanged() { 143 DCHECK(sync_service_); 144 CheckAppSync(); 145 } 146 147 void AppSyncUIState::OnExtensionLoaded(content::BrowserContext* browser_context, 148 const extensions::Extension* extension) { 149 CheckAppSync(); 150 } 151