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