Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: chrome/browser/extensions/browser_event_router.cc

Issue 17382005: Unbreak tabs.onRemove extension API in face of fast tab closure Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Don't modify content Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698