summaryrefslogtreecommitdiffstats
path: root/chrome/browser/tabs
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-05 16:01:49 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-05 16:01:49 +0000
commit3b35564a393a641b95f4fd307d5b1b126b498e5a (patch)
treedf57140fbf8f5dd425f35bbd65a61795f3e0e084 /chrome/browser/tabs
parent210e33bb96f415629c4404b8b72199de80f3a33b (diff)
downloadchromium_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.cc77
-rw-r--r--chrome/browser/tabs/tab_strip_model.h4
-rw-r--r--chrome/browser/tabs/tab_strip_model_unittest.cc13
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);