• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
Get(Profile * profile)33 AppSyncUIState* AppSyncUIState::Get(Profile* profile) {
34   return AppSyncUIStateFactory::GetForProfile(profile);
35 }
36 
37 // static
ShouldObserveAppSyncForProfile(Profile * profile)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 
AppSyncUIState(Profile * profile)55 AppSyncUIState::AppSyncUIState(Profile* profile)
56     : profile_(profile),
57       sync_service_(NULL),
58       status_(STATUS_NORMAL) {
59   StartObserving();
60 }
61 
~AppSyncUIState()62 AppSyncUIState::~AppSyncUIState() {
63   StopObserving();
64 }
65 
AddObserver(AppSyncUIStateObserver * observer)66 void AppSyncUIState::AddObserver(AppSyncUIStateObserver* observer) {
67   observers_.AddObserver(observer);
68 }
69 
RemoveObserver(AppSyncUIStateObserver * observer)70 void AppSyncUIState::RemoveObserver(AppSyncUIStateObserver* observer) {
71   observers_.RemoveObserver(observer);
72 }
73 
StartObserving()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 
StopObserving()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 
SetStatus(Status status)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 
CheckAppSync()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 
OnMaxSyncingTimer()136 void AppSyncUIState::OnMaxSyncingTimer() {
137   SetStatus(STATUS_TIMED_OUT);
138 }
139 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)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 
OnStateChanged()147 void AppSyncUIState::OnStateChanged() {
148   DCHECK(sync_service_);
149   CheckAppSync();
150 }
151