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.
6 #include "chrome_url_launch_handler.h"
7 #include "chrome_app_view.h"
14 #include "base/command_line.h"
16 #include "winrt_utils.h"
18 typedef winfoundtn::ITypedEventHandler
<
19 winapp::Search::SearchPane
*,
20 winapp::Search::SearchPaneQuerySubmittedEventArgs
*> QuerySubmittedHandler
;
22 ChromeUrlLaunchHandler::ChromeUrlLaunchHandler() {
23 globals
.is_initial_activation
= true;
24 globals
.initial_activation_kind
= winapp::Activation::ActivationKind_Launch
;
25 DVLOG(1) << __FUNCTION__
;
29 // Remove this once we consolidate metro driver with chrome.
30 const wchar_t kMetroNavigationAndSearchMessage
[] =
31 L
"CHROME_METRO_NAV_SEARCH_REQUEST";
33 ChromeUrlLaunchHandler::~ChromeUrlLaunchHandler() {
34 DVLOG(1) << __FUNCTION__
;
35 search_pane_
->remove_QuerySubmitted(query_submitted_token_
);
38 HRESULT
ChromeUrlLaunchHandler::Initialize() {
39 mswr::ComPtr
<winapp::Search::ISearchPaneStatics
> search_pane_statics
;
40 HRESULT hr
= winrt_utils::CreateActivationFactory(
41 RuntimeClass_Windows_ApplicationModel_Search_SearchPane
,
42 search_pane_statics
.GetAddressOf());
43 CheckHR(hr
, "Failed to activate ISearchPaneStatics");
45 hr
= search_pane_statics
->GetForCurrentView(&search_pane_
);
47 LOG(ERROR
) << "Failed to get search pane for current view";
51 hr
= search_pane_
->add_QuerySubmitted(mswr::Callback
<QuerySubmittedHandler
>(
53 &ChromeUrlLaunchHandler::OnQuerySubmitted
).Get(),
54 &query_submitted_token_
);
56 LOG(ERROR
) << "Failed to register for Query Submitted event";
62 HRESULT
ChromeUrlLaunchHandler::OnQuerySubmitted(
63 winapp::Search::ISearchPane
* search_pane
,
64 winapp::Search::ISearchPaneQuerySubmittedEventArgs
* args
) {
65 DVLOG(1) << "OnQuerySubmitted";
66 HandleSearchRequest(args
);
71 void ChromeUrlLaunchHandler::HandleSearchRequest(T
* args
) {
72 DVLOG(1) << __FUNCTION__
;
73 mswrw::HString search_string
;
74 args
->get_QueryText(search_string
.GetAddressOf());
75 base::string16
search_text(MakeStdWString(search_string
.Get()));
76 globals
.search_string
= search_text
;
77 DVLOG(1) << search_text
.c_str();
78 // If this is the initial activation then we wait for Chrome to initiate the
79 // navigation. In all other cases navigate right away.
80 if (!globals
.is_initial_activation
)
81 InitiateNavigationOrSearchRequest(NULL
, globals
.search_string
.c_str());
84 void ChromeUrlLaunchHandler::HandleProtocolLaunch(
85 winapp::Activation::IProtocolActivatedEventArgs
* args
) {
86 DVLOG(1) << __FUNCTION__
;
87 mswr::ComPtr
<winfoundtn::IUriRuntimeClass
> uri
;
90 uri
->get_AbsoluteUri(url
.GetAddressOf());
91 base::string16
actual_url(MakeStdWString(url
.Get()));
92 globals
.navigation_url
= actual_url
;
94 // If this is the initial activation then we wait for Chrome to initiate the
95 // navigation. In all other cases navigate right away.
96 if (!globals
.is_initial_activation
)
97 InitiateNavigationOrSearchRequest(globals
.navigation_url
.c_str(), 0);
100 // |launch_args| is an encoded command line, minus the executable name. To
101 // find the URL to launch the first argument is used. If any other parameters
102 // are encoded in |launch_args| they are ignored.
103 base::string16
ChromeUrlLaunchHandler::GetUrlFromLaunchArgs(
104 const base::string16
& launch_args
) {
105 if (launch_args
== L
"opennewwindow") {
106 VLOG(1) << "Returning new tab url";
107 return L
"chrome://newtab";
109 base::string16
dummy_command_line(L
"dummy.exe ");
110 dummy_command_line
.append(launch_args
);
111 base::CommandLine command_line
=
112 base::CommandLine::FromString(dummy_command_line
);
113 base::CommandLine::StringVector args
= command_line
.GetArgs();
117 return base::string16();
120 void ChromeUrlLaunchHandler::HandleLaunch(
121 winapp::Activation::ILaunchActivatedEventArgs
* args
) {
122 mswrw::HString launch_args
;
123 args
->get_Arguments(launch_args
.GetAddressOf());
124 base::string16
actual_launch_args(MakeStdWString(launch_args
.Get()));
125 globals
.navigation_url
= GetUrlFromLaunchArgs(actual_launch_args
);
126 DVLOG(1) << __FUNCTION__
<< ", launch_args=" << actual_launch_args
127 << ", url=" << globals
.navigation_url
128 << ", is_initial_activation=" << globals
.is_initial_activation
;
130 // If this is the initial launch then we wait for Chrome to initiate the
131 // navigation. In all other cases navigate right away.
132 if (!globals
.is_initial_activation
)
133 InitiateNavigationOrSearchRequest(globals
.navigation_url
.c_str(), 0);
136 void ChromeUrlLaunchHandler::Activate(
137 winapp::Activation::IActivatedEventArgs
* args
) {
138 winapp::Activation::ActivationKind activation_kind
;
139 CheckHR(args
->get_Kind(&activation_kind
));
141 DVLOG(1) << __FUNCTION__
<< ", activation_kind=" << activation_kind
;
143 if (globals
.is_initial_activation
)
144 globals
.initial_activation_kind
= activation_kind
;
146 if (activation_kind
== winapp::Activation::ActivationKind_Launch
) {
147 mswr::ComPtr
<winapp::Activation::ILaunchActivatedEventArgs
> launch_args
;
148 if (args
->QueryInterface(winapp::Activation::IID_ILaunchActivatedEventArgs
,
149 &launch_args
) == S_OK
) {
150 DVLOG(1) << "Activate: ActivationKind_Launch";
151 HandleLaunch(launch_args
.Get());
153 } else if (activation_kind
==
154 winapp::Activation::ActivationKind_Search
) {
155 mswr::ComPtr
<winapp::Activation::ISearchActivatedEventArgs
> search_args
;
156 if (args
->QueryInterface(winapp::Activation::IID_ISearchActivatedEventArgs
,
157 &search_args
) == S_OK
) {
158 DVLOG(1) << "Activate: ActivationKind_Search";
159 HandleSearchRequest(search_args
.Get());
161 } else if (activation_kind
==
162 winapp::Activation::ActivationKind_Protocol
) {
163 mswr::ComPtr
<winapp::Activation::IProtocolActivatedEventArgs
>
165 if (args
->QueryInterface(
166 winapp::Activation::IID_IProtocolActivatedEventArgs
,
167 &protocol_args
) == S_OK
) {
168 DVLOG(1) << "Activate: ActivationKind_Protocol";
169 HandleProtocolLaunch(protocol_args
.Get());
172 DVLOG(1) << "Activate: Unhandled mode: " << activation_kind
;
176 void ChromeUrlLaunchHandler::InitiateNavigationOrSearchRequest(
177 const wchar_t* url
, const wchar_t* search_string
) {
178 DVLOG(1) << __FUNCTION__
;
179 if (!url
&& !search_string
) {
184 DVLOG(1) << (url
? url
: L
"NULL url");
185 DVLOG(1) << (search_string
? search_string
: L
"NULL search string");
187 if (globals
.host_windows
.empty()) {
188 DVLOG(1) << "No chrome windows registered. Ignoring nav request";
192 // Custom registered message to navigate or search in chrome. WPARAM
193 // points to the URL and LPARAM contains the search string. They are
194 // mutually exclusive.
195 static const UINT navigation_search_message
=
196 RegisterWindowMessage(kMetroNavigationAndSearchMessage
);
199 VLOG(1) << "Posting url:" << url
;
200 PostMessage(globals
.host_windows
.front().first
, navigation_search_message
,
201 reinterpret_cast<WPARAM
>(url
), 0);
203 VLOG(1) << "Posting search string:" << search_string
;
204 PostMessage(globals
.host_windows
.front().first
, navigation_search_message
,
205 0, reinterpret_cast<LPARAM
>(search_string
));