Home | History | Annotate | Download | only in ash
      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