| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/extension_browser_event_router.h" | 5 #include "chrome/browser/extensions/extension_browser_event_router.h" |
| 6 | 6 |
| 7 #include "base/json_writer.h" | 7 #include "base/json_writer.h" |
| 8 #include "base/values.h" | 8 #include "base/values.h" |
| 9 #include "chrome/browser/browser.h" | 9 #include "chrome/browser/browser.h" |
| 10 #include "chrome/browser/profile.h" | 10 #include "chrome/browser/profile.h" |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 bool foreground) { | 143 bool foreground) { |
| 144 ListValue args; | 144 ListValue args; |
| 145 args.Append(ExtensionTabUtil::CreateTabValue(contents)); | 145 args.Append(ExtensionTabUtil::CreateTabValue(contents)); |
| 146 std::string json_args; | 146 std::string json_args; |
| 147 JSONWriter::Write(&args, false, &json_args); | 147 JSONWriter::Write(&args, false, &json_args); |
| 148 | 148 |
| 149 DispatchEvent(contents->profile(), events::kOnTabCreated, json_args); | 149 DispatchEvent(contents->profile(), events::kOnTabCreated, json_args); |
| 150 | 150 |
| 151 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, | 151 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, |
| 152 Source<NavigationController>(&contents->controller())); | 152 Source<NavigationController>(&contents->controller())); |
| 153 |
| 154 // Observing TAB_CONTENTS_DESTROYED is necessary because it's |
| 155 // possible for tabs to be created, detached and then destroyed without |
| 156 // ever having been re-attached and closed. This happens in the case of |
| 157 // a devtools TabContents that is opened in window, docked, then closed. |
| 158 registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, |
| 159 Source<TabContents>(contents)); |
| 153 } | 160 } |
| 154 | 161 |
| 155 void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents, | 162 void ExtensionBrowserEventRouter::TabInsertedAt(TabContents* contents, |
| 156 int index, | 163 int index, |
| 157 bool foreground) { | 164 bool foreground) { |
| 158 // If tab is new, send tab-created event. | 165 // If tab is new, send tab-created event. |
| 159 int tab_id = ExtensionTabUtil::GetTabId(contents); | 166 int tab_id = ExtensionTabUtil::GetTabId(contents); |
| 160 if (tab_entries_.find(tab_id) == tab_entries_.end()) { | 167 if (tab_entries_.find(tab_id) == tab_entries_.end()) { |
| 161 tab_entries_[tab_id] = TabEntry(contents); | 168 tab_entries_[tab_id] = TabEntry(contents); |
| 162 | 169 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 | 220 |
| 214 std::string json_args; | 221 std::string json_args; |
| 215 JSONWriter::Write(&args, false, &json_args); | 222 JSONWriter::Write(&args, false, &json_args); |
| 216 | 223 |
| 217 DispatchEvent(contents->profile(), events::kOnTabRemoved, json_args); | 224 DispatchEvent(contents->profile(), events::kOnTabRemoved, json_args); |
| 218 | 225 |
| 219 int removed_count = tab_entries_.erase(tab_id); | 226 int removed_count = tab_entries_.erase(tab_id); |
| 220 DCHECK(removed_count > 0); | 227 DCHECK(removed_count > 0); |
| 221 | 228 |
| 222 registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED, | 229 registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED, |
| 223 Source<NavigationController>(&contents->controller())); | 230 Source<NavigationController>(&contents->controller())); |
| 231 registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED, |
| 232 Source<TabContents>(contents)); |
| 224 } | 233 } |
| 225 | 234 |
| 226 void ExtensionBrowserEventRouter::TabSelectedAt(TabContents* old_contents, | 235 void ExtensionBrowserEventRouter::TabSelectedAt(TabContents* old_contents, |
| 227 TabContents* new_contents, | 236 TabContents* new_contents, |
| 228 int index, | 237 int index, |
| 229 bool user_gesture) { | 238 bool user_gesture) { |
| 230 ListValue args; | 239 ListValue args; |
| 231 args.Append(Value::CreateIntegerValue( | 240 args.Append(Value::CreateIntegerValue( |
| 232 ExtensionTabUtil::GetTabId(new_contents))); | 241 ExtensionTabUtil::GetTabId(new_contents))); |
| 233 | 242 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 261 std::string json_args; | 270 std::string json_args; |
| 262 JSONWriter::Write(&args, false, &json_args); | 271 JSONWriter::Write(&args, false, &json_args); |
| 263 | 272 |
| 264 DispatchEvent(contents->profile(), events::kOnTabMoved, json_args); | 273 DispatchEvent(contents->profile(), events::kOnTabMoved, json_args); |
| 265 } | 274 } |
| 266 | 275 |
| 267 void ExtensionBrowserEventRouter::TabUpdated(TabContents* contents, | 276 void ExtensionBrowserEventRouter::TabUpdated(TabContents* contents, |
| 268 bool did_navigate) { | 277 bool did_navigate) { |
| 269 int tab_id = ExtensionTabUtil::GetTabId(contents); | 278 int tab_id = ExtensionTabUtil::GetTabId(contents); |
| 270 std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id); | 279 std::map<int, TabEntry>::iterator i = tab_entries_.find(tab_id); |
| 271 if(tab_entries_.end() == i) { | 280 DCHECK(tab_entries_.end() != i); |
| 272 // TODO(rafaelw): Unregister EBER on TAB_CONTENTS_DESTROYED in order | |
| 273 // not to receive NAV_ENTRY_COMMITTED from objects that are allocated | |
| 274 // at the same address as previously deleted TabContents. | |
| 275 // | |
| 276 // The problem here is that NAV_ENTRY_COMMITTED is issued by the navigation | |
| 277 // controller independently from tabstrip model. One should not rely upon | |
| 278 // TabStripModelObserver events when registering / unregistering | |
| 279 // tab contents events' handlers. | |
| 280 registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED, | |
| 281 Source<NavigationController>(&contents->controller())); | |
| 282 return; | |
| 283 } | |
| 284 TabEntry& entry = i->second; | 281 TabEntry& entry = i->second; |
| 285 | 282 |
| 286 DictionaryValue* changed_properties = NULL; | 283 DictionaryValue* changed_properties = NULL; |
| 287 if (did_navigate) | 284 if (did_navigate) |
| 288 changed_properties = entry.DidNavigate(contents); | 285 changed_properties = entry.DidNavigate(contents); |
| 289 else | 286 else |
| 290 changed_properties = entry.UpdateLoadState(contents); | 287 changed_properties = entry.UpdateLoadState(contents); |
| 291 | 288 |
| 292 if (changed_properties) { | 289 if (changed_properties) { |
| 293 // The state of the tab (as seen from the extension point of view) has | 290 // The state of the tab (as seen from the extension point of view) has |
| 294 // changed. Send a notification to the extension. | 291 // changed. Send a notification to the extension. |
| 295 ListValue args; | 292 ListValue args; |
| 296 args.Append(Value::CreateIntegerValue(tab_id)); | 293 args.Append(Value::CreateIntegerValue(tab_id)); |
| 297 args.Append(changed_properties); | 294 args.Append(changed_properties); |
| 298 | 295 |
| 299 std::string json_args; | 296 std::string json_args; |
| 300 JSONWriter::Write(&args, false, &json_args); | 297 JSONWriter::Write(&args, false, &json_args); |
| 301 | 298 |
| 302 DispatchEvent(contents->profile(), events::kOnTabUpdated, json_args); | 299 DispatchEvent(contents->profile(), events::kOnTabUpdated, json_args); |
| 303 } | 300 } |
| 304 } | 301 } |
| 305 | 302 |
| 306 void ExtensionBrowserEventRouter::Observe(NotificationType type, | 303 void ExtensionBrowserEventRouter::Observe(NotificationType type, |
| 307 const NotificationSource& source, | 304 const NotificationSource& source, |
| 308 const NotificationDetails& details) { | 305 const NotificationDetails& details) { |
| 309 if (type == NotificationType::NAV_ENTRY_COMMITTED) { | 306 if (type == NotificationType::NAV_ENTRY_COMMITTED) { |
| 310 NavigationController* source_controller = | 307 NavigationController* source_controller = |
| 311 Source<NavigationController>(source).ptr(); | 308 Source<NavigationController>(source).ptr(); |
| 312 TabUpdated(source_controller->tab_contents(), true); | 309 TabUpdated(source_controller->tab_contents(), true); |
| 310 } else if (type == NotificationType::TAB_CONTENTS_DESTROYED) { |
| 311 // Tab was destroyed after being detached (without being re-attached). |
| 312 TabContents* contents = Source<TabContents>(source).ptr(); |
| 313 registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED, |
| 314 Source<NavigationController>(&contents->controller())); |
| 315 registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED, |
| 316 Source<TabContents>(contents)); |
| 313 } else { | 317 } else { |
| 314 NOTREACHED(); | 318 NOTREACHED(); |
| 315 } | 319 } |
| 316 } | 320 } |
| 317 | 321 |
| 318 void ExtensionBrowserEventRouter::TabChangedAt(TabContents* contents, | 322 void ExtensionBrowserEventRouter::TabChangedAt(TabContents* contents, |
| 319 int index, | 323 int index, |
| 320 bool loading_only) { | 324 bool loading_only) { |
| 321 TabUpdated(contents, false); | 325 TabUpdated(contents, false); |
| 322 } | 326 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 336 data->Set(tab_keys::kTabUrlKey, Value::CreateStringValue(url)); | 340 data->Set(tab_keys::kTabUrlKey, Value::CreateStringValue(url)); |
| 337 object_args->Set(tab_keys::kDataKey, data); | 341 object_args->Set(tab_keys::kDataKey, data); |
| 338 | 342 |
| 339 args.Append(object_args); | 343 args.Append(object_args); |
| 340 | 344 |
| 341 std::string json_args; | 345 std::string json_args; |
| 342 JSONWriter::Write(&args, false, &json_args); | 346 JSONWriter::Write(&args, false, &json_args); |
| 343 | 347 |
| 344 DispatchEvent(profile, events::kOnPageActionExecuted, json_args); | 348 DispatchEvent(profile, events::kOnPageActionExecuted, json_args); |
| 345 } | 349 } |
| OLD | NEW |