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

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

Issue 4136004: Track in which frames navigation errors occurred and don't send further navigation events for them (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/chrome/browser/extensions
Patch Set: Created 10 years, 1 month 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 // Implements the Chrome Extensions WebNavigation API. 5 // Implements the Chrome Extensions WebNavigation API.
6 6
7 #include "chrome/browser/extensions/extension_webnavigation_api.h" 7 #include "chrome/browser/extensions/extension_webnavigation_api.h"
8 8
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "base/values.h" 11 #include "base/values.h"
12 #include "chrome/browser/extensions/extension_event_router.h" 12 #include "chrome/browser/extensions/extension_event_router.h"
13 #include "chrome/browser/extensions/extension_tabs_module.h" 13 #include "chrome/browser/extensions/extension_tabs_module.h"
14 #include "chrome/browser/extensions/extension_webnavigation_api_constants.h" 14 #include "chrome/browser/extensions/extension_webnavigation_api_constants.h"
15 #include "chrome/browser/profile.h" 15 #include "chrome/browser/profile.h"
16 #include "chrome/browser/tab_contents/navigation_controller.h" 16 #include "chrome/browser/tab_contents/navigation_controller.h"
17 #include "chrome/browser/tab_contents/provisional_load_details.h" 17 #include "chrome/browser/tab_contents/provisional_load_details.h"
18 #include "chrome/common/notification_type.h" 18 #include "chrome/common/notification_type.h"
19 #include "chrome/common/notification_service.h" 19 #include "chrome/common/notification_service.h"
20 #include "chrome/common/url_constants.h"
20 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
21 22
22 namespace keys = extension_webnavigation_api_constants; 23 namespace keys = extension_webnavigation_api_constants;
23 24
24 namespace { 25 namespace {
25 26
26 // Returns 0 if the navigation happens in the main frame, or the frame ID 27 // Returns 0 if the navigation happens in the main frame, or the frame ID
27 // modulo 32 bits otherwise. 28 // modulo 32 bits otherwise.
28 int GetFrameId(ProvisionalLoadDetails* details) { 29 int GetFrameId(ProvisionalLoadDetails* details) {
29 return details->main_frame() ? 0 : static_cast<int>(details->frame_id()); 30 return details->main_frame() ? 0 : static_cast<int>(details->frame_id());
30 } 31 }
31 32
32 // Returns |time| as milliseconds since the epoch. 33 // Returns |time| as milliseconds since the epoch.
33 double MilliSecondsFromTime(const base::Time& time) { 34 double MilliSecondsFromTime(const base::Time& time) {
34 return 1000 * time.ToDoubleT(); 35 return 1000 * time.ToDoubleT();
35 } 36 }
36 37
37 } // namespace 38 } // namespace
38 39
40 FrameNavigationState::FrameNavigationState() {
41 registrar_.Add(this,
42 NotificationType::TAB_CONTENTS_DESTROYED,
43 NotificationService::AllSources());
44 }
45
46 FrameNavigationState::~FrameNavigationState() {
47 }
48
49 bool FrameNavigationState::CanSendEvents(long long frame_id) const {
50 FrameIdToErrorStateMap::const_iterator frame_state =
51 frame_state_map_.find(frame_id);
52 return frame_state != frame_state_map_.end() &&
53 !frame_state->second;
54 }
55
56 void FrameNavigationState::TrackFrame(long long frame_id,
57 const GURL& url,
58 bool is_main_frame,
59 const TabContents* tab_contents) {
60 if (is_main_frame)
61 RemoveTabContentsState(tab_contents);
62 tab_contents_map_.insert(
63 TabContentsToFrameIdMap::value_type(tab_contents, frame_id));
64 frame_state_map_[frame_id] =
65 (url.spec() == chrome::kChromeUnreachableWebDataURL);
66 }
67
68 void FrameNavigationState::ErrorOccurredInFrame(long long frame_id) {
69 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end());
70 frame_state_map_[frame_id] = true;
71 }
72
73 void FrameNavigationState::Observe(
74 NotificationType type,
75 const NotificationSource& source,
76 const NotificationDetails& details) {
77 RemoveTabContentsState(Source<TabContents>(source).ptr());
78 }
79
80 void FrameNavigationState::RemoveTabContentsState(
81 const TabContents* tab_contents) {
82 typedef TabContentsToFrameIdMap::iterator FrameIdIterator;
83 std::pair<FrameIdIterator, FrameIdIterator> frame_ids =
84 tab_contents_map_.equal_range(tab_contents);
85 for (FrameIdIterator frame_id = frame_ids.first; frame_id != frame_ids.second;
86 frame_id++) {
yzshen 2010/10/27 17:43:38 [optional] Better to use ++frame_id.
87 frame_state_map_.erase(frame_id->second);
88 }
89 tab_contents_map_.erase(tab_contents);
90 }
91
92
39 // static 93 // static
40 ExtensionWebNavigationEventRouter* 94 ExtensionWebNavigationEventRouter*
41 ExtensionWebNavigationEventRouter::GetInstance() { 95 ExtensionWebNavigationEventRouter::GetInstance() {
42 return Singleton<ExtensionWebNavigationEventRouter>::get(); 96 return Singleton<ExtensionWebNavigationEventRouter>::get();
43 } 97 }
44 98
45 void ExtensionWebNavigationEventRouter::Init() { 99 void ExtensionWebNavigationEventRouter::Init() {
46 if (registrar_.IsEmpty()) { 100 if (registrar_.IsEmpty()) {
47 registrar_.Add(this, 101 registrar_.Add(this,
48 NotificationType::FRAME_PROVISIONAL_LOAD_START, 102 NotificationType::FRAME_PROVISIONAL_LOAD_START,
(...skipping 28 matching lines...) Expand all
77 Details<ProvisionalLoadDetails>(details).ptr()); 131 Details<ProvisionalLoadDetails>(details).ptr());
78 break; 132 break;
79 133
80 default: 134 default:
81 NOTREACHED(); 135 NOTREACHED();
82 } 136 }
83 } 137 }
84 void ExtensionWebNavigationEventRouter::FrameProvisionalLoadStart( 138 void ExtensionWebNavigationEventRouter::FrameProvisionalLoadStart(
85 NavigationController* controller, 139 NavigationController* controller,
86 ProvisionalLoadDetails* details) { 140 ProvisionalLoadDetails* details) {
141 navigation_state_.TrackFrame(details->frame_id(),
142 details->url(),
143 details->main_frame(),
144 controller->tab_contents());
87 ListValue args; 145 ListValue args;
88 DictionaryValue* dict = new DictionaryValue(); 146 DictionaryValue* dict = new DictionaryValue();
89 dict->SetInteger(keys::kTabIdKey, 147 dict->SetInteger(keys::kTabIdKey,
90 ExtensionTabUtil::GetTabId(controller->tab_contents())); 148 ExtensionTabUtil::GetTabId(controller->tab_contents()));
91 dict->SetString(keys::kUrlKey, 149 dict->SetString(keys::kUrlKey,
92 details->url().spec()); 150 details->url().spec());
93 dict->SetInteger(keys::kFrameIdKey, GetFrameId(details)); 151 dict->SetInteger(keys::kFrameIdKey, GetFrameId(details));
94 dict->SetInteger(keys::kRequestIdKey, 0); 152 dict->SetInteger(keys::kRequestIdKey, 0);
95 dict->SetReal(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); 153 dict->SetReal(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
96 args.Append(dict); 154 args.Append(dict);
97 155
98 std::string json_args; 156 std::string json_args;
99 base::JSONWriter::Write(&args, false, &json_args); 157 base::JSONWriter::Write(&args, false, &json_args);
100 DispatchEvent(controller->profile(), keys::kOnBeforeNavigate, json_args); 158 if (navigation_state_.CanSendEvents(details->frame_id()))
159 DispatchEvent(controller->profile(), keys::kOnBeforeNavigate, json_args);
101 } 160 }
102 161
103 void ExtensionWebNavigationEventRouter::FrameProvisionalLoadCommitted( 162 void ExtensionWebNavigationEventRouter::FrameProvisionalLoadCommitted(
104 NavigationController* controller, 163 NavigationController* controller,
105 ProvisionalLoadDetails* details) { 164 ProvisionalLoadDetails* details) {
106 ListValue args; 165 ListValue args;
107 DictionaryValue* dict = new DictionaryValue(); 166 DictionaryValue* dict = new DictionaryValue();
108 dict->SetInteger(keys::kTabIdKey, 167 dict->SetInteger(keys::kTabIdKey,
109 ExtensionTabUtil::GetTabId(controller->tab_contents())); 168 ExtensionTabUtil::GetTabId(controller->tab_contents()));
110 dict->SetString(keys::kUrlKey, 169 dict->SetString(keys::kUrlKey,
111 details->url().spec()); 170 details->url().spec());
112 dict->SetInteger(keys::kFrameIdKey, GetFrameId(details)); 171 dict->SetInteger(keys::kFrameIdKey, GetFrameId(details));
113 dict->SetString(keys::kTransitionTypeKey, 172 dict->SetString(keys::kTransitionTypeKey,
114 PageTransition::CoreTransitionString( 173 PageTransition::CoreTransitionString(
115 details->transition_type())); 174 details->transition_type()));
116 dict->SetString(keys::kTransitionQualifiersKey, 175 dict->SetString(keys::kTransitionQualifiersKey,
117 PageTransition::QualifierString( 176 PageTransition::QualifierString(
118 details->transition_type())); 177 details->transition_type()));
119 dict->SetReal(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); 178 dict->SetReal(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
120 args.Append(dict); 179 args.Append(dict);
121 180
122 std::string json_args; 181 std::string json_args;
123 base::JSONWriter::Write(&args, false, &json_args); 182 base::JSONWriter::Write(&args, false, &json_args);
124 DispatchEvent(controller->profile(), keys::kOnCommitted, json_args); 183 if (navigation_state_.CanSendEvents(details->frame_id()))
184 DispatchEvent(controller->profile(), keys::kOnCommitted, json_args);
125 } 185 }
126 186
127 void ExtensionWebNavigationEventRouter::FailProvisionalLoadWithError( 187 void ExtensionWebNavigationEventRouter::FailProvisionalLoadWithError(
128 NavigationController* controller, 188 NavigationController* controller,
129 ProvisionalLoadDetails* details) { 189 ProvisionalLoadDetails* details) {
130 ListValue args; 190 ListValue args;
131 DictionaryValue* dict = new DictionaryValue(); 191 DictionaryValue* dict = new DictionaryValue();
132 dict->SetInteger(keys::kTabIdKey, 192 dict->SetInteger(keys::kTabIdKey,
133 ExtensionTabUtil::GetTabId(controller->tab_contents())); 193 ExtensionTabUtil::GetTabId(controller->tab_contents()));
134 dict->SetString(keys::kUrlKey, 194 dict->SetString(keys::kUrlKey,
135 details->url().spec()); 195 details->url().spec());
136 dict->SetInteger(keys::kFrameIdKey, GetFrameId(details)); 196 dict->SetInteger(keys::kFrameIdKey, GetFrameId(details));
137 dict->SetString(keys::kErrorKey, 197 dict->SetString(keys::kErrorKey,
138 std::string(net::ErrorToString(details->error_code()))); 198 std::string(net::ErrorToString(details->error_code())));
139 dict->SetReal(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); 199 dict->SetReal(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
140 args.Append(dict); 200 args.Append(dict);
141 201
142 std::string json_args; 202 std::string json_args;
143 base::JSONWriter::Write(&args, false, &json_args); 203 base::JSONWriter::Write(&args, false, &json_args);
144 DispatchEvent(controller->profile(), keys::kOnErrorOccurred, json_args); 204 if (navigation_state_.CanSendEvents(details->frame_id())) {
205 navigation_state_.ErrorOccurredInFrame(details->frame_id());
206 DispatchEvent(controller->profile(), keys::kOnErrorOccurred, json_args);
207 }
145 } 208 }
146 209
147 void ExtensionWebNavigationEventRouter::DispatchEvent( 210 void ExtensionWebNavigationEventRouter::DispatchEvent(
148 Profile* profile, 211 Profile* profile,
149 const char* event_name, 212 const char* event_name,
150 const std::string& json_args) { 213 const std::string& json_args) {
151 if (profile && profile->GetExtensionEventRouter()) { 214 if (profile && profile->GetExtensionEventRouter()) {
152 profile->GetExtensionEventRouter()->DispatchEventToRenderers( 215 profile->GetExtensionEventRouter()->DispatchEventToRenderers(
153 event_name, json_args, profile, GURL()); 216 event_name, json_args, profile, GURL());
154 } 217 }
155 } 218 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698