diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-05 16:01:49 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-05 16:01:49 +0000 |
commit | 3b35564a393a641b95f4fd307d5b1b126b498e5a (patch) | |
tree | df57140fbf8f5dd425f35bbd65a61795f3e0e084 /chrome/browser/tabs | |
parent | 210e33bb96f415629c4404b8b72199de80f3a33b (diff) | |
download | chromium_src-3b35564a393a641b95f4fd307d5b1b126b498e5a.zip chromium_src-3b35564a393a641b95f4fd307d5b1b126b498e5a.tar.gz chromium_src-3b35564a393a641b95f4fd307d5b1b126b498e5a.tar.bz2 |
Wires TabContents to app extensions.
BUG=32845
TEST=none
Review URL: http://codereview.chromium.org/566032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38212 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/tabs')
-rw-r--r-- | chrome/browser/tabs/tab_strip_model.cc | 77 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model.h | 4 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model_unittest.cc | 13 |
3 files changed, 74 insertions, 20 deletions
diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc index 4e3708c..39dea18 100644 --- a/chrome/browser/tabs/tab_strip_model.cc +++ b/chrome/browser/tabs/tab_strip_model.cc @@ -13,6 +13,7 @@ #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/browser_shutdown.h" #include "chrome/browser/defaults.h" +#include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/render_process_host.h" @@ -23,6 +24,7 @@ #include "chrome/browser/tab_contents/tab_contents_delegate.h" #include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/extensions/extension.h" #include "chrome/common/notification_service.h" #include "chrome/common/url_constants.h" @@ -56,6 +58,9 @@ TabStripModel::TabStripModel(TabStripModelDelegate* delegate, Profile* profile) registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, NotificationService::AllSources()); + registrar_.Add(this, + NotificationType::EXTENSION_UNLOADED, + Source<Profile>(profile_)); order_controller_ = new TabStripModelOrderController(this); } @@ -104,7 +109,7 @@ void TabStripModel::InsertTabContentsAt(int index, bool inherit_group) { // Make sure the index maintains that all app tab occurs before non-app tabs. int first_non_app = IndexOfFirstNonAppTab(); - if (contents->app()) + if (contents->is_app()) index = std::min(first_non_app, index); else index = std::max(first_non_app, index); @@ -418,7 +423,7 @@ bool TabStripModel::IsTabPinned(int index) const { } bool TabStripModel::IsAppTab(int index) const { - return GetTabContentsAt(index)->app(); + return GetTabContentsAt(index)->is_app(); } bool TabStripModel::IsPhantomTab(int index) const { @@ -432,7 +437,7 @@ bool TabStripModel::IsTabBlocked(int index) const { int TabStripModel::IndexOfFirstNonAppTab() const { for (size_t i = 0; i < contents_data_.size(); ++i) { - if (!contents_data_[i]->contents->app()) + if (!contents_data_[i]->contents->is_app()) return static_cast<int>(i); } // No app tabs. @@ -670,22 +675,41 @@ std::vector<int> TabStripModel::GetIndexesOpenedBy(int index) const { void TabStripModel::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { - DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED); - // Sometimes, on qemu, it seems like a TabContents object can be destroyed - // while we still have a reference to it. We need to break this reference - // here so we don't crash later. - int index = GetIndexOfTabContents(Source<TabContents>(source).ptr()); - if (index != TabStripModel::kNoTab) { - // Note that we only detach the contents here, not close it - it's already - // been closed. We just want to undo our bookkeeping. - if (IsAppTab(index) && IsTabPinned(index) && !IsPhantomTab(index) && - !closing_all_) { - // We don't actually allow pinned tabs to close. Instead they become - // phantom. - MakePhantom(index); - } else { - DetachTabContentsAt(index); + switch (type.value) { + case NotificationType::TAB_CONTENTS_DESTROYED: { + // Sometimes, on qemu, it seems like a TabContents object can be destroyed + // while we still have a reference to it. We need to break this reference + // here so we don't crash later. + int index = GetIndexOfTabContents(Source<TabContents>(source).ptr()); + if (index != TabStripModel::kNoTab) { + // Note that we only detach the contents here, not close it - it's + // already been closed. We just want to undo our bookkeeping. + if (ShouldMakePhantomOnClose(index)) { + // We don't actually allow pinned tabs to close. Instead they become + // phantom. + MakePhantom(index); + } else { + DetachTabContentsAt(index); + } + } + break; + } + + case NotificationType::EXTENSION_UNLOADED: { + Extension* extension = Details<Extension>(details).ptr(); + // Iterate backwards as we may remove items while iterating. + for (int i = count() - 1; i >= 0; i--) { + if (GetTabContentsAt(i)->app_extension() == extension) { + // The extension an app tab was created from has been nuked. Delete + // the TabContents. + delete GetTabContentsAt(i); + } + } + break; } + + default: + NOTREACHED(); } } @@ -828,6 +852,23 @@ int TabStripModel::IndexOfNextNonPhantomTab(int index, return start; } +bool TabStripModel::ShouldMakePhantomOnClose(int index) { + if (IsAppTab(index) && IsTabPinned(index) && !IsPhantomTab(index) && + !closing_all_ && profile()) { + ExtensionsService* extension_service = profile()->GetExtensionsService(); + if (!extension_service) + return false; + + Extension* app_extension = GetTabContentsAt(index)->app_extension(); + DCHECK(app_extension); + + // Only allow the tab to be made phantom if the extension still exists. + return extension_service->GetExtensionById(app_extension->id(), + false) != NULL; + } + return false; +} + void TabStripModel::MakePhantom(int index) { if (selected_index_ == index) { // Change the selection, otherwise we're going to force the phantom tab diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h index 24eb20e..305c562 100644 --- a/chrome/browser/tabs/tab_strip_model.h +++ b/chrome/browser/tabs/tab_strip_model.h @@ -592,6 +592,10 @@ class TabStripModel : public NotificationObserver { // |ignore_index|. int IndexOfNextNonPhantomTab(int index, int ignore_index); + // Returns true if the tab at the specified index should be made phantom when + // the tab is closing. + bool ShouldMakePhantomOnClose(int index); + // Makes the tab a phantom tab. void MakePhantom(int index); diff --git a/chrome/browser/tabs/tab_strip_model_unittest.cc b/chrome/browser/tabs/tab_strip_model_unittest.cc index 7330a41..f577bc6 100644 --- a/chrome/browser/tabs/tab_strip_model_unittest.cc +++ b/chrome/browser/tabs/tab_strip_model_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "app/system_monitor.h" +#include "base/file_path.h" #include "base/file_util.h" #include "base/path_service.h" #include "base/string_util.h" @@ -16,6 +17,7 @@ #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/tabs/tab_strip_model_order_controller.h" +#include "chrome/common/extensions/extension.h" #include "chrome/common/pref_names.h" #include "chrome/common/property_bag.h" #include "chrome/common/url_constants.h" @@ -1347,10 +1349,17 @@ TEST_F(TabStripModelTest, Apps) { typedef MockTabStripModelObserver::State State; +#if defined(OS_WIN) + FilePath path(FILE_PATH_LITERAL("c:\\foo")); +#elif defined(OS_POSIX) + FilePath path(FILE_PATH_LITERAL("/foo")); +#endif + Extension app_extension(path); + app_extension.app_launch_url_ = GURL("http://www.google.com"); TabContents* contents1 = CreateTabContents(); - contents1->set_app(true); + contents1->SetAppExtension(&app_extension); TabContents* contents2 = CreateTabContents(); - contents2->set_app(true); + contents2->SetAppExtension(&app_extension); TabContents* contents3 = CreateTabContents(); SetID(contents1, 1); |