| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/browser_event_router.h" | 5 #include "chrome/browser/extensions/browser_event_router.h" |
| 6 | 6 |
| 7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
| 8 #include "base/values.h" | 8 #include "base/values.h" |
| 9 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_
api_constants.h" | 9 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_
api_constants.h" |
| 10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" | 10 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" |
| 11 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h" | 11 #include "chrome/browser/extensions/api/tabs/tabs_windows_api.h" |
| 12 #include "chrome/browser/extensions/api/tabs/windows_event_router.h" | 12 #include "chrome/browser/extensions/api/tabs/windows_event_router.h" |
| 13 #include "chrome/browser/extensions/event_names.h" | 13 #include "chrome/browser/extensions/event_names.h" |
| 14 #include "chrome/browser/extensions/extension_action.h" | 14 #include "chrome/browser/extensions/extension_action.h" |
| 15 #include "chrome/browser/extensions/extension_service.h" | 15 #include "chrome/browser/extensions/extension_service.h" |
| 16 #include "chrome/browser/extensions/extension_system.h" | 16 #include "chrome/browser/extensions/extension_system.h" |
| 17 #include "chrome/browser/extensions/extension_tab_util.h" | 17 #include "chrome/browser/extensions/extension_tab_util.h" |
| 18 #include "chrome/browser/extensions/window_controller.h" | 18 #include "chrome/browser/extensions/window_controller.h" |
| 19 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
| 20 #include "chrome/browser/ui/browser.h" | 20 #include "chrome/browser/ui/browser.h" |
| 21 #include "chrome/browser/ui/browser_iterator.h" | 21 #include "chrome/browser/ui/browser_iterator.h" |
| 22 #include "chrome/browser/ui/browser_list.h" | 22 #include "chrome/browser/ui/browser_list.h" |
| 23 #include "chrome/browser/ui/tab_contents/core_tab_helper.h" |
| 23 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 24 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 24 #include "chrome/common/chrome_notification_types.h" | 25 #include "chrome/common/chrome_notification_types.h" |
| 25 #include "chrome/common/extensions/api/extension_action/action_info.h" | 26 #include "chrome/common/extensions/api/extension_action/action_info.h" |
| 26 #include "chrome/common/extensions/extension_constants.h" | 27 #include "chrome/common/extensions/extension_constants.h" |
| 27 #include "content/public/browser/favicon_status.h" | 28 #include "content/public/browser/favicon_status.h" |
| 28 #include "content/public/browser/navigation_controller.h" | 29 #include "content/public/browser/navigation_controller.h" |
| 29 #include "content/public/browser/navigation_entry.h" | 30 #include "content/public/browser/navigation_entry.h" |
| 30 #include "content/public/browser/notification_service.h" | 31 #include "content/public/browser/notification_service.h" |
| 31 #include "content/public/browser/notification_types.h" | 32 #include "content/public/browser/notification_types.h" |
| 32 #include "content/public/browser/web_contents.h" | 33 #include "content/public/browser/web_contents.h" |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 ExtensionTabUtil::GetWindowIdOfTab(contents))); | 209 ExtensionTabUtil::GetWindowIdOfTab(contents))); |
| 209 object_args->Set(tab_keys::kNewPositionKey, Value::CreateIntegerValue( | 210 object_args->Set(tab_keys::kNewPositionKey, Value::CreateIntegerValue( |
| 210 index)); | 211 index)); |
| 211 args->Append(object_args); | 212 args->Append(object_args); |
| 212 | 213 |
| 213 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); | 214 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); |
| 214 DispatchEvent(profile, events::kOnTabAttached, args.Pass(), | 215 DispatchEvent(profile, events::kOnTabAttached, args.Pass(), |
| 215 EventRouter::USER_GESTURE_UNKNOWN); | 216 EventRouter::USER_GESTURE_UNKNOWN); |
| 216 } | 217 } |
| 217 | 218 |
| 218 void BrowserEventRouter::TabDetachedAt(WebContents* contents, int index) { | 219 void BrowserEventRouter::TabDetachedAt(WebContents* contents, |
| 220 int index, |
| 221 bool closing_all) { |
| 219 if (!GetTabEntry(contents)) { | 222 if (!GetTabEntry(contents)) { |
| 220 // The tab was removed. Don't send detach event. | 223 // The tab was removed. Don't send detach/remove event. |
| 221 return; | 224 return; |
| 222 } | 225 } |
| 223 | 226 |
| 224 scoped_ptr<ListValue> args(new ListValue()); | 227 // If this detach is occuring as part of the process of closing |contents| |
| 225 args->Append(Value::CreateIntegerValue(ExtensionTabUtil::GetTabId(contents))); | 228 // then dispatch a remove event rather than a detach event. |
| 226 | 229 CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents); |
| 227 DictionaryValue* object_args = new DictionaryValue(); | 230 if (core_tab_helper->GetWebContentsDetachedToClose()) { |
| 228 object_args->Set(tab_keys::kOldWindowIdKey, Value::CreateIntegerValue( | 231 int tab_id = ExtensionTabUtil::GetTabId(contents); |
| 229 ExtensionTabUtil::GetWindowIdOfTab(contents))); | 232 DispatchTabRemovedAndUnregisterNotifications(contents, tab_id, closing_all); |
| 230 object_args->Set(tab_keys::kOldPositionKey, Value::CreateIntegerValue( | 233 } else { |
| 231 index)); | 234 DispatchTabDetached(contents, index); |
| 232 args->Append(object_args); | 235 } |
| 233 | |
| 234 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); | |
| 235 DispatchEvent(profile, events::kOnTabDetached, args.Pass(), | |
| 236 EventRouter::USER_GESTURE_UNKNOWN); | |
| 237 } | 236 } |
| 238 | 237 |
| 239 void BrowserEventRouter::TabClosingAt(TabStripModel* tab_strip_model, | 238 void BrowserEventRouter::TabClosingAt(TabStripModel* tab_strip_model, |
| 240 WebContents* contents, | 239 WebContents* contents, |
| 241 int index) { | 240 int index) { |
| 242 int tab_id = ExtensionTabUtil::GetTabId(contents); | 241 int tab_id = ExtensionTabUtil::GetTabId(contents); |
| 243 | 242 DispatchTabRemovedAndUnregisterNotifications(contents, tab_id, |
| 244 scoped_ptr<ListValue> args(new ListValue()); | 243 tab_strip_model->closing_all()); |
| 245 args->Append(Value::CreateIntegerValue(tab_id)); | |
| 246 | |
| 247 DictionaryValue* object_args = new DictionaryValue(); | |
| 248 object_args->SetInteger(tab_keys::kWindowIdKey, | |
| 249 ExtensionTabUtil::GetWindowIdOfTab(contents)); | |
| 250 object_args->SetBoolean(tab_keys::kWindowClosing, | |
| 251 tab_strip_model->closing_all()); | |
| 252 args->Append(object_args); | |
| 253 | |
| 254 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); | |
| 255 DispatchEvent(profile, events::kOnTabRemoved, args.Pass(), | |
| 256 EventRouter::USER_GESTURE_UNKNOWN); | |
| 257 | |
| 258 int removed_count = tab_entries_.erase(tab_id); | |
| 259 DCHECK_GT(removed_count, 0); | |
| 260 | |
| 261 UnregisterForTabNotifications(contents); | |
| 262 } | 244 } |
| 263 | 245 |
| 264 void BrowserEventRouter::ActiveTabChanged(WebContents* old_contents, | 246 void BrowserEventRouter::ActiveTabChanged(WebContents* old_contents, |
| 265 WebContents* new_contents, | 247 WebContents* new_contents, |
| 266 int index, | 248 int index, |
| 267 int reason) { | 249 int reason) { |
| 268 scoped_ptr<ListValue> args(new ListValue()); | 250 scoped_ptr<ListValue> args(new ListValue()); |
| 269 int tab_id = ExtensionTabUtil::GetTabId(new_contents); | 251 int tab_id = ExtensionTabUtil::GetTabId(new_contents); |
| 270 args->Append(Value::CreateIntegerValue(tab_id)); | 252 args->Append(Value::CreateIntegerValue(tab_id)); |
| 271 | 253 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 | 453 |
| 472 BrowserEventRouter::TabEntry* BrowserEventRouter::GetTabEntry( | 454 BrowserEventRouter::TabEntry* BrowserEventRouter::GetTabEntry( |
| 473 const WebContents* contents) { | 455 const WebContents* contents) { |
| 474 int tab_id = ExtensionTabUtil::GetTabId(contents); | 456 int tab_id = ExtensionTabUtil::GetTabId(contents); |
| 475 std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id); | 457 std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id); |
| 476 if (tab_entries_.end() == i) | 458 if (tab_entries_.end() == i) |
| 477 return NULL; | 459 return NULL; |
| 478 return &i->second; | 460 return &i->second; |
| 479 } | 461 } |
| 480 | 462 |
| 463 void BrowserEventRouter::DispatchTabDetached(WebContents* contents, |
| 464 int index) { |
| 465 scoped_ptr<ListValue> args(new ListValue()); |
| 466 args->Append(Value::CreateIntegerValue(ExtensionTabUtil::GetTabId(contents))); |
| 467 |
| 468 DictionaryValue* object_args = new DictionaryValue(); |
| 469 object_args->Set(tab_keys::kOldWindowIdKey, Value::CreateIntegerValue( |
| 470 ExtensionTabUtil::GetWindowIdOfTab(contents))); |
| 471 object_args->Set(tab_keys::kOldPositionKey, Value::CreateIntegerValue( |
| 472 index)); |
| 473 args->Append(object_args); |
| 474 |
| 475 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); |
| 476 DispatchEvent(profile, events::kOnTabDetached, args.Pass(), |
| 477 EventRouter::USER_GESTURE_UNKNOWN); |
| 478 } |
| 479 |
| 480 void BrowserEventRouter::DispatchTabRemovedAndUnregisterNotifications( |
| 481 WebContents* contents, int tab_id, bool window_closing) { |
| 482 scoped_ptr<ListValue> args(new ListValue()); |
| 483 args->Append(Value::CreateIntegerValue(tab_id)); |
| 484 |
| 485 DictionaryValue* object_args = new DictionaryValue(); |
| 486 object_args->SetInteger(tab_keys::kWindowIdKey, |
| 487 ExtensionTabUtil::GetWindowIdOfTab(contents)); |
| 488 object_args->SetBoolean(tab_keys::kWindowClosing, |
| 489 window_closing); |
| 490 args->Append(object_args); |
| 491 |
| 492 Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); |
| 493 DispatchEvent(profile, events::kOnTabRemoved, args.Pass(), |
| 494 EventRouter::USER_GESTURE_UNKNOWN); |
| 495 |
| 496 int removed_count = tab_entries_.erase(tab_id); |
| 497 DCHECK_GT(removed_count, 0); |
| 498 UnregisterForTabNotifications(contents); |
| 499 } |
| 500 |
| 481 void BrowserEventRouter::Observe(int type, | 501 void BrowserEventRouter::Observe(int type, |
| 482 const content::NotificationSource& source, | 502 const content::NotificationSource& source, |
| 483 const content::NotificationDetails& details) { | 503 const content::NotificationDetails& details) { |
| 484 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { | 504 if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) { |
| 485 NavigationController* source_controller = | 505 NavigationController* source_controller = |
| 486 content::Source<NavigationController>(source).ptr(); | 506 content::Source<NavigationController>(source).ptr(); |
| 487 TabUpdated(source_controller->GetWebContents(), true); | 507 TabUpdated(source_controller->GetWebContents(), true); |
| 488 } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { | 508 } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { |
| 489 // Tab was destroyed after being detached (without being re-attached). | 509 // Tab was destroyed after being detached (without being re-attached). |
| 490 WebContents* contents = content::Source<WebContents>(source).ptr(); | 510 WebContents* contents = content::Source<WebContents>(source).ptr(); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 | 659 |
| 640 DispatchEventToExtension(profile, | 660 DispatchEventToExtension(profile, |
| 641 extension_action.extension_id(), | 661 extension_action.extension_id(), |
| 642 event_name, | 662 event_name, |
| 643 args.Pass(), | 663 args.Pass(), |
| 644 EventRouter::USER_GESTURE_ENABLED); | 664 EventRouter::USER_GESTURE_ENABLED); |
| 645 } | 665 } |
| 646 } | 666 } |
| 647 | 667 |
| 648 } // namespace extensions | 668 } // namespace extensions |
| OLD | NEW |