15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implements the Chrome Extensions WebNavigation API. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/web_navigation/web_navigation_api_constants.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_tab_util.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/common/extensions/api/web_navigation.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/render_frame_host.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/event_filtering_info.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/base/page_transition_types.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = web_navigation_api_constants; 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace web_navigation = api::web_navigation; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace web_navigation_api_helpers { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns |time| as milliseconds since the epoch. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)double MilliSecondsFromTime(const base::Time& time) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1000 * time.ToDoubleT(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Dispatches events to the extension message service. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DispatchEvent(content::BrowserContext* browser_context, 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& event_name, 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> args, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventFilteringInfo info; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.SetURL(url); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = Profile::FromBrowserContext(browser_context); 490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter* event_router = EventRouter::Get(profile); 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (profile && event_router) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Event> event(new Event(event_name, args.Pass())); 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event->restrict_to_browser_context = profile; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->filter_info = info; 540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch event_router->BroadcastEvent(event.Pass()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdochint GetFrameId(content::RenderFrameHost* frame_host) { 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!frame_host) 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return -1; 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return !frame_host->GetParent() ? 0 : frame_host->GetRoutingID(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs and dispatches an onBeforeNavigate event. 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// TODO(dcheng): Is the parent process ID needed here? http://crbug.com/393640 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Collisions are probably possible... but maybe this won't ever happen because 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// of the SiteInstance grouping policies. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DispatchOnBeforeNavigate(content::WebContents* web_contents, 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::RenderFrameHost* frame_host, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& validated_url) { 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> args(new base::ListValue()); 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* dict = new base::DictionaryValue(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kTabIdKey, ExtensionTabUtil::GetTabId(web_contents)); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kUrlKey, validated_url.spec()); 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID()); 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kParentFrameIdKey, 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetFrameId(frame_host->GetParent())); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->Append(dict); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(web_contents->GetBrowserContext(), 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_navigation::OnBeforeNavigate::kEventName, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Pass(), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) validated_url); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs and dispatches an onCommitted or onReferenceFragmentUpdated 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// event. 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DispatchOnCommitted(const std::string& event_name, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents, 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::RenderFrameHost* frame_host, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PageTransition transition_type) { 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> args(new base::ListValue()); 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* dict = new base::DictionaryValue(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kTabIdKey, ExtensionTabUtil::GetTabId(web_contents)); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kUrlKey, url.spec()); 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID()); 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host)); 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string transition_type_string = 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PageTransitionGetCoreTransitionString(transition_type); 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For webNavigation API backward compatibility, keep "start_page" even after 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // renamed to "auto_toplevel". 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ui::PageTransitionStripQualifier(transition_type) == 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PAGE_TRANSITION_AUTO_TOPLEVEL) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transition_type_string = "start_page"; 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dict->SetString(keys::kTransitionTypeKey, transition_type_string); 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ListValue* qualifiers = new base::ListValue(); 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (transition_type & ui::PAGE_TRANSITION_CLIENT_REDIRECT) 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) qualifiers->Append(new base::StringValue("client_redirect")); 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (transition_type & ui::PAGE_TRANSITION_SERVER_REDIRECT) 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) qualifiers->Append(new base::StringValue("server_redirect")); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (transition_type & ui::PAGE_TRANSITION_FORWARD_BACK) 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) qualifiers->Append(new base::StringValue("forward_back")); 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (transition_type & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) qualifiers->Append(new base::StringValue("from_address_bar")); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kTransitionQualifiersKey, qualifiers); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->Append(dict); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(web_contents->GetBrowserContext(), event_name, args.Pass(), 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs and dispatches an onDOMContentLoaded event. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DispatchOnDOMContentLoaded(content::WebContents* web_contents, 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::RenderFrameHost* frame_host, 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const GURL& url) { 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> args(new base::ListValue()); 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* dict = new base::DictionaryValue(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kTabIdKey, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabId(web_contents)); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kUrlKey, url.spec()); 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID()); 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host)); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->Append(dict); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DispatchEvent(web_contents->GetBrowserContext(), 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_navigation::OnDOMContentLoaded::kEventName, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Pass(), 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs and dispatches an onCompleted event. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DispatchOnCompleted(content::WebContents* web_contents, 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::RenderFrameHost* frame_host, 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const GURL& url) { 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> args(new base::ListValue()); 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* dict = new base::DictionaryValue(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kTabIdKey, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabId(web_contents)); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kUrlKey, url.spec()); 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID()); 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host)); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->Append(dict); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DispatchEvent(web_contents->GetBrowserContext(), 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_navigation::OnCompleted::kEventName, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Pass(), url); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs and dispatches an onCreatedNavigationTarget event. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DispatchOnCreatedNavigationTarget( 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* web_contents, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserContext* browser_context, 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::RenderFrameHost* source_frame_host, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* target_web_contents, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& target_url) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that the tab is already inserted into a tab strip model. This code 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // path is exercised by ExtensionApiTest.WebNavigationRequestOpenTab. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ExtensionTabUtil::GetTabById( 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabId(target_web_contents), 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(target_web_contents->GetBrowserContext()), 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, NULL, NULL, NULL, NULL)); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> args(new base::ListValue()); 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* dict = new base::DictionaryValue(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kSourceTabIdKey, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabId(web_contents)); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kSourceProcessIdKey, 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch source_frame_host->GetProcess()->GetID()); 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kSourceFrameIdKey, GetFrameId(source_frame_host)); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kUrlKey, target_url.possibly_invalid_spec()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kTabIdKey, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabId(target_web_contents)); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->Append(dict); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DispatchEvent(browser_context, 1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_navigation::OnCreatedNavigationTarget::kEventName, 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args.Pass(), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_url); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs and dispatches an onErrorOccurred event. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DispatchOnErrorOccurred(content::WebContents* web_contents, 202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::RenderFrameHost* frame_host, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_code) { 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> args(new base::ListValue()); 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* dict = new base::DictionaryValue(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kTabIdKey, ExtensionTabUtil::GetTabId(web_contents)); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kUrlKey, url.spec()); 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kProcessIdKey, frame_host->GetProcess()->GetID()); 210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dict->SetInteger(keys::kFrameIdKey, GetFrameId(frame_host)); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString(keys::kErrorKey, net::ErrorToString(error_code)); 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dict->SetDouble(keys::kTimeStampKey, 2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MilliSecondsFromTime(base::Time::Now())); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->Append(dict); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DispatchEvent(web_contents->GetBrowserContext(), 2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_navigation::OnErrorOccurred::kEventName, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Pass(), url); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs and dispatches an onTabReplaced event. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DispatchOnTabReplaced( 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* old_web_contents, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserContext* browser_context, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* new_web_contents) { 226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<base::ListValue> args(new base::ListValue()); 227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::DictionaryValue* dict = new base::DictionaryValue(); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetInteger(keys::kReplacedTabIdKey, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabId(old_web_contents)); 2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dict->SetInteger( 2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) keys::kTabIdKey, 2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ExtensionTabUtil::GetTabId(new_web_contents)); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetDouble(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now())); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args->Append(dict); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DispatchEvent(browser_context, 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) web_navigation::OnTabReplaced::kEventName, 2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args.Pass(), 2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GURL()); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace web_navigation_api_helpers 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 245