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#ifndef CHROME_BROWSER_UI_ASH_APP_SYNC_UI_STATE_H_
6#define CHROME_BROWSER_UI_ASH_APP_SYNC_UI_STATE_H_
7
8#include "base/basictypes.h"
9#include "base/compiler_specific.h"
10#include "base/observer_list.h"
11#include "base/timer/timer.h"
12#include "chrome/browser/sync/profile_sync_service_observer.h"
13#include "components/keyed_service/core/keyed_service.h"
14#include "content/public/browser/notification_observer.h"
15#include "content/public/browser/notification_registrar.h"
16#include "extensions/browser/extension_registry_observer.h"
17
18class AppSyncUIStateObserver;
19class Profile;
20class ProfileSyncService;
21
22namespace extensions {
23class ExtensionRegistry;
24}
25
26// AppSyncUIState watches app sync and installation and change its state
27// accordingly. Its status is for UI display only. It only watches for new
28// normal user profile (i.e. it does not watch for guest profile or exsiting
29// user profile) and lasts for at the most 1 minute.
30class AppSyncUIState : public KeyedService,
31                       public ProfileSyncServiceObserver,
32                       public extensions::ExtensionRegistryObserver {
33 public:
34  enum Status {
35    STATUS_NORMAL,
36    STATUS_SYNCING,    // Syncing apps or installing synced apps.
37    STATUS_TIMED_OUT,  // Timed out when waiting for sync to finish.
38  };
39
40  // Returns the instance for the given |profile|. It's a convenience wrapper
41  // of AppSyncUIStateFactory::GetForProfile. Note this function returns
42  // NULL if ShouldObserveAppSyncForProfile returns false for |profile|.
43  static AppSyncUIState* Get(Profile* profile);
44
45  // Returns true if |profile| should be watched for app syncing.
46  static bool ShouldObserveAppSyncForProfile(Profile* profile);
47
48  explicit AppSyncUIState(Profile* profile);
49  virtual ~AppSyncUIState();
50
51  void AddObserver(AppSyncUIStateObserver* observer);
52  void RemoveObserver(AppSyncUIStateObserver* observer);
53
54  Status status() const { return status_; }
55
56 private:
57  void StartObserving();
58  void StopObserving();
59
60  void SetStatus(Status status);
61
62  // Checks and sets app sync status. If sync has not setup, do nothing. If sync
63  // is completed and there is no pending synced extension install, sets
64  // STATUS_SYNCING. Otherwise, sets STATUS_NORMAL.
65  void CheckAppSync();
66
67  // Invoked when |max_syncing_status_timer_| fires.
68  void OnMaxSyncingTimer();
69
70  // ProfileSyncServiceObserver overrides:
71  virtual void OnStateChanged() OVERRIDE;
72
73  // extensions::ExtensionRegistryObserver overrides:
74  virtual void OnExtensionLoaded(
75      content::BrowserContext* browser_context,
76      const extensions::Extension* extension) OVERRIDE;
77
78  Profile* profile_;
79  ProfileSyncService* sync_service_;
80
81  // Timer to limit how much time STATUS_SYNCING is allowed.
82  base::OneShotTimer<AppSyncUIState> max_syncing_status_timer_;
83
84  Status status_;
85  ObserverList<AppSyncUIStateObserver> observers_;
86
87  extensions::ExtensionRegistry* extension_registry_;
88
89  DISALLOW_COPY_AND_ASSIGN(AppSyncUIState);
90};
91
92#endif  // CHROME_BROWSER_UI_ASH_APP_SYNC_UI_STATE_H_
93