Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / extensions / api / web_navigation / web_navigation_api_helpers.cc
blobe9e90fad4c783284dfd003a0ac56dd6f3cfb7a0c
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 const std::string& event_name,
43 scoped_ptr<base::ListValue> args,
44 const GURL& url) {
45 EventFilteringInfo info;
46 info.SetURL(url);
48 Profile* profile = Profile::FromBrowserContext(browser_context);
49 EventRouter* event_router = EventRouter::Get(profile);
50 if (profile && event_router) {
51 scoped_ptr<Event> event(new Event(event_name, args.Pass()));
52 event->restrict_to_browser_context = profile;
53 event->filter_info = info;
54 event_router->BroadcastEvent(event.Pass());
58 } // namespace
60 int GetFrameId(content::RenderFrameHost* frame_host) {
61 if (!frame_host)
62 return -1;
63 return !frame_host->GetParent() ? 0 : frame_host->GetRoutingID();
66 // Constructs and dispatches an onBeforeNavigate event.
67 // TODO(dcheng): Is the parent process ID needed here? http://crbug.com/393640
68 // Collisions are probably possible... but maybe this won't ever happen because
69 // of the SiteInstance grouping policies.
70 void DispatchOnBeforeNavigate(content::WebContents* web_contents,
71 content::RenderFrameHost* frame_host,
72 const GURL& validated_url) {
73 scoped_ptr<base::ListValue> args(new base::ListValue());
74 base::DictionaryValue* dict = new base::DictionaryValue();
75 dict->SetInteger(keys::kTabIdKey, ExtensionTabUtil::GetTabId(web_contents));
76 dict->SetString(keys::kUrlKey, validated_url.spec());
77 dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID());
78 dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host));
79 dict->SetInteger(keys::kParentFrameIdKey,
80 GetFrameId(frame_host->GetParent()));
81 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
82 args->Append(dict);
84 DispatchEvent(web_contents->GetBrowserContext(),
85 web_navigation::OnBeforeNavigate::kEventName,
86 args.Pass(),
87 validated_url);
90 // Constructs and dispatches an onCommitted or onReferenceFragmentUpdated
91 // event.
92 void DispatchOnCommitted(const std::string& event_name,
93 content::WebContents* web_contents,
94 content::RenderFrameHost* frame_host,
95 const GURL& url,
96 ui::PageTransition transition_type) {
97 scoped_ptr<base::ListValue> args(new base::ListValue());
98 base::DictionaryValue* dict = new base::DictionaryValue();
99 dict->SetInteger(keys::kTabIdKey, ExtensionTabUtil::GetTabId(web_contents));
100 dict->SetString(keys::kUrlKey, url.spec());
101 dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID());
102 dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host));
103 std::string transition_type_string =
104 ui::PageTransitionGetCoreTransitionString(transition_type);
105 // For webNavigation API backward compatibility, keep "start_page" even after
106 // renamed to "auto_toplevel".
107 if (ui::PageTransitionStripQualifier(transition_type) ==
108 ui::PAGE_TRANSITION_AUTO_TOPLEVEL)
109 transition_type_string = "start_page";
110 dict->SetString(keys::kTransitionTypeKey, transition_type_string);
111 base::ListValue* qualifiers = new base::ListValue();
112 if (transition_type & ui::PAGE_TRANSITION_CLIENT_REDIRECT)
113 qualifiers->Append(new base::StringValue("client_redirect"));
114 if (transition_type & ui::PAGE_TRANSITION_SERVER_REDIRECT)
115 qualifiers->Append(new base::StringValue("server_redirect"));
116 if (transition_type & ui::PAGE_TRANSITION_FORWARD_BACK)
117 qualifiers->Append(new base::StringValue("forward_back"));
118 if (transition_type & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR)
119 qualifiers->Append(new base::StringValue("from_address_bar"));
120 dict->Set(keys::kTransitionQualifiersKey, qualifiers);
121 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
122 args->Append(dict);
124 DispatchEvent(web_contents->GetBrowserContext(), event_name, args.Pass(),
125 url);
128 // Constructs and dispatches an onDOMContentLoaded event.
129 void DispatchOnDOMContentLoaded(content::WebContents* web_contents,
130 content::RenderFrameHost* frame_host,
131 const GURL& url) {
132 scoped_ptr<base::ListValue> args(new base::ListValue());
133 base::DictionaryValue* dict = new base::DictionaryValue();
134 dict->SetInteger(keys::kTabIdKey,
135 ExtensionTabUtil::GetTabId(web_contents));
136 dict->SetString(keys::kUrlKey, url.spec());
137 dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID());
138 dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host));
139 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
140 args->Append(dict);
142 DispatchEvent(web_contents->GetBrowserContext(),
143 web_navigation::OnDOMContentLoaded::kEventName,
144 args.Pass(),
145 url);
148 // Constructs and dispatches an onCompleted event.
149 void DispatchOnCompleted(content::WebContents* web_contents,
150 content::RenderFrameHost* frame_host,
151 const GURL& url) {
152 scoped_ptr<base::ListValue> args(new base::ListValue());
153 base::DictionaryValue* dict = new base::DictionaryValue();
154 dict->SetInteger(keys::kTabIdKey,
155 ExtensionTabUtil::GetTabId(web_contents));
156 dict->SetString(keys::kUrlKey, url.spec());
157 dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID());
158 dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host));
159 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
160 args->Append(dict);
162 DispatchEvent(web_contents->GetBrowserContext(),
163 web_navigation::OnCompleted::kEventName,
164 args.Pass(), url);
167 // Constructs and dispatches an onCreatedNavigationTarget event.
168 void DispatchOnCreatedNavigationTarget(
169 content::WebContents* web_contents,
170 content::BrowserContext* browser_context,
171 content::RenderFrameHost* source_frame_host,
172 content::WebContents* target_web_contents,
173 const GURL& target_url) {
174 // Check that the tab is already inserted into a tab strip model. This code
175 // path is exercised by ExtensionApiTest.WebNavigationRequestOpenTab.
176 DCHECK(ExtensionTabUtil::GetTabById(
177 ExtensionTabUtil::GetTabId(target_web_contents),
178 Profile::FromBrowserContext(target_web_contents->GetBrowserContext()),
179 false, NULL, NULL, NULL, NULL));
181 scoped_ptr<base::ListValue> args(new base::ListValue());
182 base::DictionaryValue* dict = new base::DictionaryValue();
183 dict->SetInteger(keys::kSourceTabIdKey,
184 ExtensionTabUtil::GetTabId(web_contents));
185 dict->SetInteger(keys::kSourceProcessIdKey,
186 source_frame_host->GetProcess()->GetID());
187 dict->SetInteger(keys::kSourceFrameIdKey, GetFrameId(source_frame_host));
188 dict->SetString(keys::kUrlKey, target_url.possibly_invalid_spec());
189 dict->SetInteger(keys::kTabIdKey,
190 ExtensionTabUtil::GetTabId(target_web_contents));
191 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
192 args->Append(dict);
194 DispatchEvent(browser_context,
195 web_navigation::OnCreatedNavigationTarget::kEventName,
196 args.Pass(),
197 target_url);
200 // Constructs and dispatches an onErrorOccurred event.
201 void DispatchOnErrorOccurred(content::WebContents* web_contents,
202 content::RenderFrameHost* frame_host,
203 const GURL& url,
204 int error_code) {
205 scoped_ptr<base::ListValue> args(new base::ListValue());
206 base::DictionaryValue* dict = new base::DictionaryValue();
207 dict->SetInteger(keys::kTabIdKey, ExtensionTabUtil::GetTabId(web_contents));
208 dict->SetString(keys::kUrlKey, url.spec());
209 dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID());
210 dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host));
211 dict->SetString(keys::kErrorKey, net::ErrorToString(error_code));
212 dict->SetDouble(keys::kTimeStampKey,
213 MilliSecondsFromTime(base::Time::Now()));
214 args->Append(dict);
216 DispatchEvent(web_contents->GetBrowserContext(),
217 web_navigation::OnErrorOccurred::kEventName,
218 args.Pass(), url);
221 // Constructs and dispatches an onTabReplaced event.
222 void DispatchOnTabReplaced(
223 content::WebContents* old_web_contents,
224 content::BrowserContext* browser_context,
225 content::WebContents* new_web_contents) {
226 scoped_ptr<base::ListValue> args(new base::ListValue());
227 base::DictionaryValue* dict = new base::DictionaryValue();
228 dict->SetInteger(keys::kReplacedTabIdKey,
229 ExtensionTabUtil::GetTabId(old_web_contents));
230 dict->SetInteger(
231 keys::kTabIdKey,
232 ExtensionTabUtil::GetTabId(new_web_contents));
233 dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
234 args->Append(dict);
236 DispatchEvent(browser_context,
237 web_navigation::OnTabReplaced::kEventName,
238 args.Pass(),
239 GURL());
242 } // namespace web_navigation_api_helpers
244 } // namespace extensions