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 22namespace { 23 24// Max loading animation time in milliseconds. 25const int kMaxSyncingTimeMs = 60 * 1000; 26 27} // namespace 28 29// static 30AppSyncUIState* AppSyncUIState::Get(Profile* profile) { 31 return AppSyncUIStateFactory::GetForProfile(profile); 32} 33 34// static 35bool 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 52AppSyncUIState::AppSyncUIState(Profile* profile) 53 : profile_(profile), 54 sync_service_(NULL), 55 status_(STATUS_NORMAL), 56 extension_registry_(NULL) { 57 StartObserving(); 58} 59 60AppSyncUIState::~AppSyncUIState() { 61 StopObserving(); 62} 63 64void AppSyncUIState::AddObserver(AppSyncUIStateObserver* observer) { 65 observers_.AddObserver(observer); 66} 67 68void AppSyncUIState::RemoveObserver(AppSyncUIStateObserver* observer) { 69 observers_.RemoveObserver(observer); 70} 71 72void 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 85void 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 99void 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 123void 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 138void AppSyncUIState::OnMaxSyncingTimer() { 139 SetStatus(STATUS_TIMED_OUT); 140} 141 142void AppSyncUIState::OnStateChanged() { 143 DCHECK(sync_service_); 144 CheckAppSync(); 145} 146 147void AppSyncUIState::OnExtensionLoaded(content::BrowserContext* browser_context, 148 const extensions::Extension* extension) { 149 CheckAppSync(); 150} 151