Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / extensions / api / web_navigation / web_navigation_api_helpers.cc
blob3b04125a35373f2826840b85c5a3914624cbc65d
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
3 // found in the LICENSE file.
5 // Implements the Chrome Extensions WebNavigation API.
7 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h"
9 #include "base/json/json_writer.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/time/time.h"
12 #include "base/values.h"
13 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_constants.h"
14 #include "chrome/browser/extensions/extension_tab_util.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/extensions/api/web_navigation.h"
17 #include "content/public/browser/render_frame_host.h"
18 #include "content/public/browser/render_process_host.h"
19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/browser/web_contents.h"
21 #include "extensions/browser/event_router.h"
22 #include "extensions/common/event_filtering_info.h"
23 #include "net/base/net_errors.h"
24 #include "ui/base/page_transition_types.h"
26 namespace extensions {
28 namespace keys = web_navigation_api_constants;
29 namespace web_navigation = api::web_navigation;
31 namespace web_navigation_api_helpers {
33 namespace {
35 // Returns |time| as milliseconds since the epoch.
36 double MilliSecondsFromTime(const base::Time& time) {
37 return 1000 * time.ToDoubleT();
40 // Dispatches events to the extension message service.
41 void DispatchEvent(content::BrowserContext* browser_context,
42 events::HistogramValue histogram_value,
43 const std::string& event_name,
44 scoped_ptr<base::ListValue> args,
45 const GURL& url) {
46 EventFilteringInfo info;
47 info.SetURL(url);
49 Profile* profile = Profile::FromBrowserContext(browser_context);
50 EventRouter* event_router = EventRouter::Get(profile);
51 if (profile && event_router) {
52 scoped_ptr<Event> event(
53 new Event(histogram_value, event_name, args.Pass()));
54 event->restrict_to_browser_context = profile;
55 event->filter_info = info;
56 event_router->BroadcastEvent(event.Pass());
60 } // namespace
62 int GetFrameId(content::RenderFrameHost* frame_host) {
63 if (!frame_host)
64 return -1;
65 return !frame_host->GetParent() ? 0 : frame_host->GetRoutingID();
68 // Constructs and dispatches an onBeforeNavigate event.
69 // TODO(dcheng): Is the parent process ID needed here? http://crbug.com/393640
70 // Collisions are probably possible... but maybe this won't ever happen because
71 // of the SiteInstance grouping policies.
72 void DispatchOnBeforeNavigate(content::WebContents* web_contents,
73 content::RenderFrameHost* frame_host,
74 const GURL& validated_url) {
75 scoped_ptr<base::ListValue> args(new base::ListValue());
76 base::DictionaryValue* dict = new base::DictionaryValue();
77 dict->SetInteger(keys::kTabIdKey, ExtensionTabUtil::GetTabId(web_contents));
78 dict->SetString(keys::kUrlKey, validated_url.spec());
79 dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID());
80 dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host));
81 dict->SetInteger(keys::kParentFrameIdKey,
82 GetFrameId(frame_host->GetParent()));
83 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
84 args->Append(dict);
86 DispatchEvent(web_contents->GetBrowserContext(),
87 events::WEB_NAVIGATION_ON_BEFORE_NAVIGATE,
88 web_navigation::OnBeforeNavigate::kEventName, args.Pass(),
89 validated_url);
92 // Constructs and dispatches an onCommitted or onReferenceFragmentUpdated
93 // event.
94 void DispatchOnCommitted(events::HistogramValue histogram_value,
95 const std::string& event_name,
96 content::WebContents* web_contents,
97 content::RenderFrameHost* frame_host,
98 const GURL& url,
99 ui::PageTransition transition_type) {
100 scoped_ptr<base::ListValue> args(new base::ListValue());
101 base::DictionaryValue* dict = new base::DictionaryValue();
102 dict->SetInteger(keys::kTabIdKey, ExtensionTabUtil::GetTabId(web_contents));
103 dict->SetString(keys::kUrlKey, url.spec());
104 dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID());
105 dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host));
106 std::string transition_type_string =
107 ui::PageTransitionGetCoreTransitionString(transition_type);
108 // For webNavigation API backward compatibility, keep "start_page" even after
109 // renamed to "auto_toplevel".
110 if (ui::PageTransitionStripQualifier(transition_type) ==
111 ui::PAGE_TRANSITION_AUTO_TOPLEVEL)
112 transition_type_string = "start_page";
113 dict->SetString(keys::kTransitionTypeKey, transition_type_string);
114 base::ListValue* qualifiers = new base::ListValue();
115 if (transition_type & ui::PAGE_TRANSITION_CLIENT_REDIRECT)
116 qualifiers->Append(new base::StringValue("client_redirect"));
117 if (transition_type & ui::PAGE_TRANSITION_SERVER_REDIRECT)
118 qualifiers->Append(new base::StringValue("server_redirect"));
119 if (transition_type & ui::PAGE_TRANSITION_FORWARD_BACK)
120 qualifiers->Append(new base::StringValue("forward_back"));
121 if (transition_type & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR)
122 qualifiers->Append(new base::StringValue("from_address_bar"));
123 dict->Set(keys::kTransitionQualifiersKey, qualifiers);
124 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
125 args->Append(dict);
127 DispatchEvent(web_contents->GetBrowserContext(), histogram_value, event_name,
128 args.Pass(), url);
131 // Constructs and dispatches an onDOMContentLoaded event.
132 void DispatchOnDOMContentLoaded(content::WebContents* web_contents,
133 content::RenderFrameHost* frame_host,
134 const GURL& url) {
135 scoped_ptr<base::ListValue> args(new base::ListValue());
136 base::DictionaryValue* dict = new base::DictionaryValue();
137 dict->SetInteger(keys::kTabIdKey,
138 ExtensionTabUtil::GetTabId(web_contents));
139 dict->SetString(keys::kUrlKey, url.spec());
140 dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID());
141 dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host));
142 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
143 args->Append(dict);
145 DispatchEvent(web_contents->GetBrowserContext(),
146 events::WEB_NAVIGATION_ON_DOM_CONTENT_LOADED,
147 web_navigation::OnDOMContentLoaded::kEventName, args.Pass(),
148 url);
151 // Constructs and dispatches an onCompleted event.
152 void DispatchOnCompleted(content::WebContents* web_contents,
153 content::RenderFrameHost* frame_host,
154 const GURL& url) {
155 scoped_ptr<base::ListValue> args(new base::ListValue());
156 base::DictionaryValue* dict = new base::DictionaryValue();
157 dict->SetInteger(keys::kTabIdKey,
158 ExtensionTabUtil::GetTabId(web_contents));
159 dict->SetString(keys::kUrlKey, url.spec());
160 dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID());
161 dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host));
162 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
163 args->Append(dict);
165 DispatchEvent(web_contents->GetBrowserContext(),
166 events::WEB_NAVIGATION_ON_COMPLETED,
167 web_navigation::OnCompleted::kEventName, args.Pass(), url);
170 // Constructs and dispatches an onCreatedNavigationTarget event.
171 void DispatchOnCreatedNavigationTarget(
172 content::WebContents* web_contents,
173 content::BrowserContext* browser_context,
174 content::RenderFrameHost* source_frame_host,
175 content::WebContents* target_web_contents,
176 const GURL& target_url) {
177 // Check that the tab is already inserted into a tab strip model. This code
178 // path is exercised by ExtensionApiTest.WebNavigationRequestOpenTab.
179 DCHECK(ExtensionTabUtil::GetTabById(
180 ExtensionTabUtil::GetTabId(target_web_contents),
181 Profile::FromBrowserContext(target_web_contents->GetBrowserContext()),
182 false, NULL, NULL, NULL, NULL));
184 scoped_ptr<base::ListValue> args(new base::ListValue());
185 base::DictionaryValue* dict = new base::DictionaryValue();
186 dict->SetInteger(keys::kSourceTabIdKey,
187 ExtensionTabUtil::GetTabId(web_contents));
188 dict->SetInteger(keys::kSourceProcessIdKey,
189 source_frame_host->GetProcess()->GetID());
190 dict->SetInteger(keys::kSourceFrameIdKey, GetFrameId(source_frame_host));
191 dict->SetString(keys::kUrlKey, target_url.possibly_invalid_spec());
192 dict->SetInteger(keys::kTabIdKey,
193 ExtensionTabUtil::GetTabId(target_web_contents));
194 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
195 args->Append(dict);
197 DispatchEvent(browser_context,
198 events::WEB_NAVIGATION_ON_CREATED_NAVIGATION_TARGET,
199 web_navigation::OnCreatedNavigationTarget::kEventName,
200 args.Pass(), target_url);
203 // Constructs and dispatches an onErrorOccurred event.
204 void DispatchOnErrorOccurred(content::WebContents* web_contents,
205 content::RenderFrameHost* frame_host,
206 const GURL& url,
207 int error_code) {
208 scoped_ptr<base::ListValue> args(new base::ListValue());
209 base::DictionaryValue* dict = new base::DictionaryValue();
210 dict->SetInteger(keys::kTabIdKey, ExtensionTabUtil::GetTabId(web_contents));
211 dict->SetString(keys::kUrlKey, url.spec());
212 dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID());
213 dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host));
214 dict->SetString(keys::kErrorKey, net::ErrorToString(error_code));
215 dict->SetDouble(keys::kTimeStampKey,
216 MilliSecondsFromTime(base::Time::Now()));
217 args->Append(dict);
219 DispatchEvent(web_contents->GetBrowserContext(),
220 events::WEB_NAVIGATION_ON_ERROR_OCCURRED,
221 web_navigation::OnErrorOccurred::kEventName, args.Pass(), url);
224 // Constructs and dispatches an onTabReplaced event.
225 void DispatchOnTabReplaced(
226 content::WebContents* old_web_contents,
227 content::BrowserContext* browser_context,
228 content::WebContents* new_web_contents) {
229 scoped_ptr<base::ListValue> args(new base::ListValue());
230 base::DictionaryValue* dict = new base::DictionaryValue();
231 dict->SetInteger(keys::kReplacedTabIdKey,
232 ExtensionTabUtil::GetTabId(old_web_contents));
233 dict->SetInteger(
234 keys::kTabIdKey,
235 ExtensionTabUtil::GetTabId(new_web_contents));
236 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
237 args->Append(dict);
239 DispatchEvent(browser_context, events::WEB_NAVIGATION_ON_TAB_REPLACED,
240 web_navigation::OnTabReplaced::kEventName, args.Pass(), GURL());
243 } // namespace web_navigation_api_helpers
245 } // namespace extensions