1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_toolbar_model.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_prefs.h"
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h"
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenExtensionToolbarModel::ExtensionToolbarModel(ExtensionService* service)
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : service_(service),
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      prefs_(service->profile()->GetPrefs()),
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_initialized_(false) {
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(service_);
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 Source<Profile>(service_->profile()));
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 Source<Profile>(service_->profile()));
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSIONS_READY,
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 Source<Profile>(service_->profile()));
27201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  registrar_.Add(this,
28201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                 NotificationType::EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
29201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                 NotificationService::AllSources());
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  visible_icon_count_ = prefs_->GetInteger(prefs::kExtensionToolbarSize);
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionToolbarModel::~ExtensionToolbarModel() {
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionToolbarModel::DestroyingProfile() {
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  registrar_.RemoveAll();
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionToolbarModel::AddObserver(Observer* observer) {
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observers_.AddObserver(observer);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionToolbarModel::RemoveObserver(Observer* observer) {
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  observers_.RemoveObserver(observer);
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ExtensionToolbarModel::MoveBrowserAction(const Extension* extension,
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              int index) {
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionList::iterator pos = std::find(begin(), end(), extension);
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pos == end()) {
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  toolitems_.erase(pos);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int i = 0;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool inserted = false;
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionList::iterator iter = begin(); iter != end(); ++iter, ++i) {
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (i == index) {
62513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      toolitems_.insert(iter, make_scoped_refptr(extension));
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      inserted = true;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!inserted) {
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_EQ(index, static_cast<int>(toolitems_.size()));
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    index = toolitems_.size();
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    toolitems_.push_back(make_scoped_refptr(extension));
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FOR_EACH_OBSERVER(Observer, observers_, BrowserActionMoved(extension, index));
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdatePrefs();
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionToolbarModel::SetVisibleIconCount(int count) {
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  visible_icon_count_ = count == static_cast<int>(size()) ? -1 : count;
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs_->SetInteger(prefs::kExtensionToolbarSize, visible_icon_count_);
83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  prefs_->ScheduleSavePersistentPrefs();
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionToolbarModel::Observe(NotificationType type,
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    const NotificationSource& source,
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    const NotificationDetails& details) {
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == NotificationType::EXTENSIONS_READY) {
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InitializeExtensionList();
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!service_->is_ready())
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  const Extension* extension = NULL;
9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (type == NotificationType::EXTENSION_UNLOADED) {
9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    extension = Details<UnloadedExtensionInfo>(details)->extension;
10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    extension = Details<const Extension>(details).ptr();
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == NotificationType::EXTENSION_LOADED) {
104201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // We don't want to add the same extension twice. It may have already been
105201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user
106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // hides the browser action and then disables and enables the extension.
107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    for (size_t i = 0; i < toolitems_.size(); i++) {
108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      if (toolitems_[i].get() == extension)
109201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        return;  // Already exists.
110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (service_->GetBrowserActionVisibility(extension))
11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      AddExtension(extension);
11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else if (type == NotificationType::EXTENSION_UNLOADED) {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RemoveExtension(extension);
115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  } else if (type ==
116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch             NotificationType::EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED) {
117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (service_->GetBrowserActionVisibility(extension))
118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      AddExtension(extension);
119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    else
120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      RemoveExtension(extension);
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED() << "Received unexpected notification";
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
126513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ExtensionToolbarModel::AddExtension(const Extension* extension) {
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We only care about extensions with browser actions.
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!extension->browser_action())
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension->id() == last_extension_removed_ &&
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      last_extension_removed_index_ < toolitems_.size()) {
133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    toolitems_.insert(begin() + last_extension_removed_index_,
134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                      make_scoped_refptr(extension));
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FOR_EACH_OBSERVER(Observer, observers_,
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        BrowserActionAdded(extension, last_extension_removed_index_));
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
138513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    toolitems_.push_back(make_scoped_refptr(extension));
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FOR_EACH_OBSERVER(Observer, observers_,
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      BrowserActionAdded(extension, toolitems_.size() - 1));
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  last_extension_removed_ = "";
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  last_extension_removed_index_ = -1;
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdatePrefs();
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ExtensionToolbarModel::RemoveExtension(const Extension* extension) {
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionList::iterator pos = std::find(begin(), end(), extension);
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pos == end()) {
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  last_extension_removed_ = extension->id();
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  last_extension_removed_index_ = pos - begin();
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  toolitems_.erase(pos);
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FOR_EACH_OBSERVER(Observer, observers_,
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    BrowserActionRemoved(extension));
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdatePrefs();
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Combine the currently enabled extensions that have browser actions (which
16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// we get from the ExtensionService) with the ordering we get from the
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// pref service. For robustness we use a somewhat inefficient process:
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 1. Create a vector of extensions sorted by their pref values. This vector may
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// have holes.
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 2. Create a vector of extensions that did not have a pref value.
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 3. Remove holes from the sorted vector and append the unsorted vector.
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionToolbarModel::InitializeExtensionList() {
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(service_->is_ready());
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> pref_order = service_->extension_prefs()->
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetToolbarOrder();
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Items that have a pref for their position.
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionList sorted;
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sorted.resize(pref_order.size(), NULL);
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The items that don't have a pref for their position.
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionList unsorted;
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create the lists.
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < service_->extensions()->size(); ++i) {
185513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const Extension* extension = service_->extensions()->at(i);
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!extension->browser_action())
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
188201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (!service_->GetBrowserActionVisibility(extension))
189201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      continue;
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<std::string>::iterator pos =
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        std::find(pref_order.begin(), pref_order.end(), extension->id());
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (pos != pref_order.end()) {
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int index = std::distance(pref_order.begin(), pos);
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      sorted[index] = extension;
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
197513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      unsorted.push_back(make_scoped_refptr(extension));
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Merge the lists.
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  toolitems_.reserve(sorted.size() + unsorted.size());
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionList::iterator iter = sorted.begin();
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       iter != sorted.end(); ++iter) {
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (*iter != NULL)
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      toolitems_.push_back(*iter);
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  toolitems_.insert(toolitems_.end(), unsorted.begin(), unsorted.end());
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Inform observers.
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < toolitems_.size(); i++) {
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FOR_EACH_OBSERVER(Observer, observers_,
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      BrowserActionAdded(toolitems_[i], i));
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdatePrefs();
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_initialized_ = true;
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FOR_EACH_OBSERVER(Observer, observers_, ModelLoaded());
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionToolbarModel::UpdatePrefs() {
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!service_->extension_prefs())
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> ids;
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ids.reserve(toolitems_.size());
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionList::iterator iter = begin(); iter != end(); ++iter)
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ids.push_back((*iter)->id());
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->extension_prefs()->SetToolbarOrder(ids);
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
233513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst Extension* ExtensionToolbarModel::GetExtensionByIndex(int index) const {
234201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return toolitems_[index];
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) {
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int original_index = 0, i = 0;
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionList::iterator iter = begin(); iter != end();
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ++iter, ++original_index) {
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (service_->IsIncognitoEnabled((*iter)->id())) {
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (incognito_index == i)
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ++i;
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return original_index;
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ExtensionToolbarModel::OriginalIndexToIncognito(int original_index) {
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int incognito_index = 0, i = 0;
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionList::iterator iter = begin(); iter != end();
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       ++iter, ++i) {
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (original_index == i)
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (service_->IsIncognitoEnabled((*iter)->id()))
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ++incognito_index;
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return incognito_index;
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
261