- add sources.
[platform/framework/web/crosswalk.git] / src / win8 / metro_driver / chrome_url_launch_handler.cc
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.
4
5 #include "stdafx.h"
6 #include "chrome_url_launch_handler.h"
7 #include "chrome_app_view.h"
8
9 #include <assert.h>
10 #include <shellapi.h>
11 #include <shlobj.h>
12 #include <string>
13
14 #include "base/command_line.h"
15
16 #include "winrt_utils.h"
17
18 typedef winfoundtn::ITypedEventHandler<
19     winapp::Search::SearchPane*,
20     winapp::Search::SearchPaneQuerySubmittedEventArgs*> QuerySubmittedHandler;
21
22 ChromeUrlLaunchHandler::ChromeUrlLaunchHandler() {
23   globals.is_initial_activation = true;
24   globals.initial_activation_kind = winapp::Activation::ActivationKind_Launch;
25   DVLOG(1) << __FUNCTION__;
26 }
27
28 // TODO(ananta)
29 // Remove this once we consolidate metro driver with chrome.
30 const wchar_t kMetroNavigationAndSearchMessage[] =
31     L"CHROME_METRO_NAV_SEARCH_REQUEST";
32
33 ChromeUrlLaunchHandler::~ChromeUrlLaunchHandler() {
34   DVLOG(1) << __FUNCTION__;
35   search_pane_->remove_QuerySubmitted(query_submitted_token_);
36 }
37
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");
44
45   hr = search_pane_statics->GetForCurrentView(&search_pane_);
46   if (FAILED(hr)) {
47     LOG(ERROR) << "Failed to get search pane for current view";
48     return hr;
49   }
50
51   hr = search_pane_->add_QuerySubmitted(mswr::Callback<QuerySubmittedHandler>(
52       this,
53       &ChromeUrlLaunchHandler::OnQuerySubmitted).Get(),
54       &query_submitted_token_);
55   if (FAILED(hr)) {
56     LOG(ERROR) << "Failed to register for Query Submitted event";
57     return hr;
58   }
59   return hr;
60 }
61
62 HRESULT ChromeUrlLaunchHandler::OnQuerySubmitted(
63     winapp::Search::ISearchPane* search_pane,
64     winapp::Search::ISearchPaneQuerySubmittedEventArgs* args) {
65   DVLOG(1) << "OnQuerySubmitted";
66   HandleSearchRequest(args);
67   return S_OK;
68 }
69
70 template<class T>
71 void ChromeUrlLaunchHandler::HandleSearchRequest(T* args) {
72   DVLOG(1) << __FUNCTION__;
73   mswrw::HString search_string;
74   args->get_QueryText(search_string.GetAddressOf());
75   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());
82 }
83
84 void ChromeUrlLaunchHandler::HandleProtocolLaunch(
85     winapp::Activation::IProtocolActivatedEventArgs* args) {
86   DVLOG(1) << __FUNCTION__;
87   mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri;
88   args->get_Uri(&uri);
89   mswrw::HString url;
90   uri->get_AbsoluteUri(url.GetAddressOf());
91   string16 actual_url(MakeStdWString(url.Get()));
92   globals.navigation_url = actual_url;
93
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);
98 }
99
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 string16 ChromeUrlLaunchHandler::GetUrlFromLaunchArgs(
104     const string16& launch_args) {
105   if (launch_args == L"opennewwindow") {
106     VLOG(1) << "Returning new tab url";
107     return L"chrome://newtab";
108   }
109   string16 dummy_command_line(L"dummy.exe ");
110   dummy_command_line.append(launch_args);
111   CommandLine command_line = CommandLine::FromString(dummy_command_line);
112   CommandLine::StringVector args = command_line.GetArgs();
113   if (args.size() > 0)
114     return args[0];
115
116   return string16();
117 }
118
119 void ChromeUrlLaunchHandler::HandleLaunch(
120     winapp::Activation::ILaunchActivatedEventArgs* args) {
121   mswrw::HString launch_args;
122   args->get_Arguments(launch_args.GetAddressOf());
123   string16 actual_launch_args(MakeStdWString(launch_args.Get()));
124   globals.navigation_url = GetUrlFromLaunchArgs(actual_launch_args);
125   DVLOG(1) << __FUNCTION__ << ", launch_args=" << actual_launch_args
126            << ", url=" << globals.navigation_url
127            << ", is_initial_activation=" << globals.is_initial_activation;
128
129   // If this is the initial launch then we wait for Chrome to initiate the
130   // navigation. In all other cases navigate right away.
131   if (!globals.is_initial_activation)
132     InitiateNavigationOrSearchRequest(globals.navigation_url.c_str(), 0);
133 }
134
135 void ChromeUrlLaunchHandler::Activate(
136     winapp::Activation::IActivatedEventArgs* args) {
137   winapp::Activation::ActivationKind activation_kind;
138   CheckHR(args->get_Kind(&activation_kind));
139
140   DVLOG(1) << __FUNCTION__ << ", activation_kind=" << activation_kind;
141
142   if (globals.is_initial_activation)
143     globals.initial_activation_kind = activation_kind;
144
145   if (activation_kind == winapp::Activation::ActivationKind_Launch) {
146     mswr::ComPtr<winapp::Activation::ILaunchActivatedEventArgs> launch_args;
147     if (args->QueryInterface(winapp::Activation::IID_ILaunchActivatedEventArgs,
148                              &launch_args) == S_OK) {
149       DVLOG(1) << "Activate: ActivationKind_Launch";
150       HandleLaunch(launch_args.Get());
151     }
152   } else if (activation_kind ==
153              winapp::Activation::ActivationKind_Search) {
154     mswr::ComPtr<winapp::Activation::ISearchActivatedEventArgs> search_args;
155     if (args->QueryInterface(winapp::Activation::IID_ISearchActivatedEventArgs,
156                              &search_args) == S_OK) {
157       DVLOG(1) << "Activate: ActivationKind_Search";
158       HandleSearchRequest(search_args.Get());
159     }
160   } else if (activation_kind ==
161              winapp::Activation::ActivationKind_Protocol) {
162     mswr::ComPtr<winapp::Activation::IProtocolActivatedEventArgs>
163         protocol_args;
164     if (args->QueryInterface(
165             winapp::Activation::IID_IProtocolActivatedEventArgs,
166             &protocol_args) == S_OK) {
167       DVLOG(1) << "Activate: ActivationKind_Protocol";
168       HandleProtocolLaunch(protocol_args.Get());
169     }
170   } else {
171     DVLOG(1) << "Activate: Unhandled mode: " << activation_kind;
172   }
173 }
174
175 void ChromeUrlLaunchHandler::InitiateNavigationOrSearchRequest(
176     const wchar_t* url, const wchar_t* search_string) {
177   DVLOG(1) << __FUNCTION__;
178   if (!url && !search_string) {
179     NOTREACHED();
180     return;
181   }
182
183   DVLOG(1) << (url ? url : L"NULL url");
184   DVLOG(1) << (search_string ? search_string : L"NULL search string");
185
186   if (globals.host_windows.empty()) {
187     DVLOG(1) << "No chrome windows registered. Ignoring nav request";
188     return;
189   }
190
191   // Custom registered message to navigate or search in chrome. WPARAM
192   // points to the URL and LPARAM contains the search string. They are
193   // mutually exclusive.
194   static const UINT navigation_search_message =
195       RegisterWindowMessage(kMetroNavigationAndSearchMessage);
196
197   if (url) {
198     VLOG(1) << "Posting url:" << url;
199     PostMessage(globals.host_windows.front().first, navigation_search_message,
200                 reinterpret_cast<WPARAM>(url), 0);
201   } else {
202     VLOG(1) << "Posting search string:" << search_string;
203     PostMessage(globals.host_windows.front().first, navigation_search_message,
204                 0, reinterpret_cast<LPARAM>(search_string));
205   }
206 }