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_APP_LIST_EXTENSION_APP_MODEL_BUILDER_H_
6#define CHROME_BROWSER_UI_APP_LIST_EXTENSION_APP_MODEL_BUILDER_H_
7
8#include <string>
9#include <vector>
10
11#include "base/gtest_prod_util.h"
12#include "base/prefs/pref_change_registrar.h"
13#include "base/scoped_observer.h"
14#include "chrome/browser/extensions/install_observer.h"
15#include "extensions/browser/extension_registry_observer.h"
16#include "ui/app_list/app_list_model.h"
17#include "ui/base/models/list_model_observer.h"
18
19class AppListControllerDelegate;
20class ExtensionAppItem;
21class Profile;
22
23namespace app_list {
24class AppListSyncableService;
25}
26
27namespace extensions {
28class Extension;
29class ExtensionRegistry;
30class ExtensionSet;
31class InstallTracker;
32}
33
34namespace gfx {
35class ImageSkia;
36}
37
38// This class populates and maintains the given |model| with information from
39// |profile|.
40class ExtensionAppModelBuilder : public extensions::InstallObserver,
41                                 public extensions::ExtensionRegistryObserver,
42                                 public app_list::AppListItemListObserver {
43 public:
44  explicit ExtensionAppModelBuilder(AppListControllerDelegate* controller);
45  virtual ~ExtensionAppModelBuilder();
46
47  // Initialize to use app-list sync and sets |service_| to |service|.
48  void InitializeWithService(app_list::AppListSyncableService* service);
49
50  // Initialize to use extension sync and sets |service_| to NULL. Used in
51  // tests and when AppList sync is not enabled.
52  void InitializeWithProfile(Profile* profile, app_list::AppListModel* model);
53
54 private:
55  typedef std::vector<ExtensionAppItem*> ExtensionAppList;
56
57  // Builds the model with the current profile.
58  void BuildModel();
59
60  // extensions::InstallObserver.
61  virtual void OnBeginExtensionInstall(
62      const ExtensionInstallParams& params) OVERRIDE;
63  virtual void OnDownloadProgress(const std::string& extension_id,
64                                  int percent_downloaded) OVERRIDE;
65  virtual void OnInstallFailure(const std::string& extension_id) OVERRIDE;
66  virtual void OnDisabledExtensionUpdated(
67      const extensions::Extension* extension) OVERRIDE;
68  virtual void OnAppInstalledToAppList(
69      const std::string& extension_id) OVERRIDE;
70  virtual void OnShutdown() OVERRIDE;
71
72  // extensions::ExtensionRegistryObserver.
73  virtual void OnExtensionLoaded(
74      content::BrowserContext* browser_context,
75      const extensions::Extension* extension) OVERRIDE;
76  virtual void OnExtensionUnloaded(
77      content::BrowserContext* browser_context,
78      const extensions::Extension* extension,
79      extensions::UnloadedExtensionInfo::Reason reason) OVERRIDE;
80  virtual void OnExtensionUninstalled(
81      content::BrowserContext* browser_context,
82      const extensions::Extension* extension,
83      extensions::UninstallReason reason) OVERRIDE;
84  virtual void OnShutdown(extensions::ExtensionRegistry* registry) OVERRIDE;
85
86  // AppListItemListObserver.
87  virtual void OnListItemMoved(size_t from_index,
88                               size_t to_index,
89                               app_list::AppListItem* item) OVERRIDE;
90
91  scoped_ptr<ExtensionAppItem> CreateAppItem(
92      const std::string& extension_id,
93      const std::string& extension_name,
94      const gfx::ImageSkia& installing_icon,
95      bool is_platform_app);
96
97  // Populates the model with apps.
98  void PopulateApps();
99
100  // Inserts an app based on app ordinal prefs.
101  void InsertApp(scoped_ptr<ExtensionAppItem> app);
102
103  // Sets which app is intended to be highlighted. Will remove the highlight
104  // from a currently highlighted app.
105  void SetHighlightedApp(const std::string& extension_id);
106
107  // Sets the application app with |highlight_app_id_| in |model_| as
108  // highlighted if |highlighted_app_pending_| is true. If such an app is found,
109  // reset |highlighted_app_pending_| so that won't be highlighted again until
110  // another call to SetHighlightedApp() is made.
111  void UpdateHighlight();
112
113  // Returns app instance matching |extension_id| or NULL.
114  ExtensionAppItem* GetExtensionAppItem(const std::string& extension_id);
115
116  // Initializes the |profile_pref_change_registrar_| and the
117  // |extension_pref_change_registrar_| to listen for changes to profile and
118  // extension prefs, and call OnProfilePreferenceChanged() or
119  // OnExtensionPreferenceChanged().
120  void InitializePrefChangeRegistrars();
121
122  // Handles profile prefs changes.
123  void OnProfilePreferenceChanged();
124
125  // Handles extension prefs changes.
126  void OnExtensionPreferenceChanged();
127
128  // Unowned pointers to the service that owns this and associated profile.
129  app_list::AppListSyncableService* service_;
130  Profile* profile_;
131
132  // Registrar used to monitor the profile prefs.
133  PrefChangeRegistrar profile_pref_change_registrar_;
134
135  // Registrar used to monitor the extension prefs.
136  PrefChangeRegistrar extension_pref_change_registrar_;
137
138  // Unowned pointer to the app list controller.
139  AppListControllerDelegate* controller_;
140
141  // Unowned pointer to the app list model.
142  app_list::AppListModel* model_;
143
144  std::string highlight_app_id_;
145
146  // True if we haven't set |highlight_app_id_| to be highlighted. This happens
147  // if we try to highlight an app that doesn't exist in the list yet.
148  bool highlighted_app_pending_;
149
150  // We listen to this to show app installing progress.
151  extensions::InstallTracker* tracker_;
152
153  // Listen extension's load, unload, uninstalled.
154  extensions::ExtensionRegistry* extension_registry_;
155
156  DISALLOW_COPY_AND_ASSIGN(ExtensionAppModelBuilder);
157};
158
159#endif  // CHROME_BROWSER_UI_APP_LIST_EXTENSION_APP_MODEL_BUILDER_H_
160