Index: win8/metro_driver/chrome_url_launch_handler.cc |
diff --git a/win8/metro_driver/chrome_url_launch_handler.cc b/win8/metro_driver/chrome_url_launch_handler.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..866bccce66b10150ce3bd326fa7123c05537de3a |
--- /dev/null |
+++ b/win8/metro_driver/chrome_url_launch_handler.cc |
@@ -0,0 +1,201 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "stdafx.h" |
+#include "chrome_url_launch_handler.h" |
+#include "chrome_app_view.h" |
+ |
+#include <assert.h> |
+#include <shellapi.h> |
+#include <shlobj.h> |
+#include <string> |
+ |
+#include "base/string_tokenizer.h" |
+ |
+#include "winrt_utils.h" |
+ |
+typedef winfoundtn::ITypedEventHandler< |
+ winapp::Search::SearchPane*, |
+ winapp::Search::SearchPaneQuerySubmittedEventArgs*> QuerySubmittedHandler; |
+ |
+ChromeUrlLaunchHandler::ChromeUrlLaunchHandler() { |
+ globals.is_initial_activation = true; |
+ globals.initial_activation_kind = winapp::Activation::ActivationKind_Launch; |
+ DVLOG(1) << __FUNCTION__; |
+} |
+ |
+// TODO(ananta) |
+// Remove this once we consolidate metro driver with chrome. |
+const wchar_t kMetroNavigationAndSearchMessage[] = |
+ L"CHROME_METRO_NAV_SEARCH_REQUEST"; |
+ |
+ChromeUrlLaunchHandler::~ChromeUrlLaunchHandler() { |
+ DVLOG(1) << __FUNCTION__; |
+ search_pane_->remove_QuerySubmitted(query_submitted_token_); |
+} |
+ |
+HRESULT ChromeUrlLaunchHandler::Initialize() { |
+ mswr::ComPtr<winapp::Search::ISearchPaneStatics> search_pane_statics; |
+ HRESULT hr = winrt_utils::CreateActivationFactory( |
+ RuntimeClass_Windows_ApplicationModel_Search_SearchPane, |
+ search_pane_statics.GetAddressOf()); |
+ CheckHR(hr, "Failed to activate ISearchPaneStatics"); |
+ |
+ hr = search_pane_statics->GetForCurrentView(&search_pane_); |
+ if (FAILED(hr)) { |
+ LOG(ERROR) << "Failed to get search pane for current view"; |
+ return hr; |
+ } |
+ |
+ hr = search_pane_->add_QuerySubmitted(mswr::Callback<QuerySubmittedHandler>( |
+ this, |
+ &ChromeUrlLaunchHandler::OnQuerySubmitted).Get(), |
+ &query_submitted_token_); |
+ if (FAILED(hr)) { |
+ LOG(ERROR) << "Failed to register for Query Submitted event"; |
+ return hr; |
+ } |
+ return hr; |
+} |
+ |
+HRESULT ChromeUrlLaunchHandler::OnQuerySubmitted( |
+ winapp::Search::ISearchPane* search_pane, |
+ winapp::Search::ISearchPaneQuerySubmittedEventArgs* args) { |
+ DVLOG(1) << "OnQuerySubmitted"; |
+ HandleSearchRequest(args); |
+ return S_OK; |
+} |
+ |
+template<class T> |
+void ChromeUrlLaunchHandler::HandleSearchRequest(T* args) { |
+ DVLOG(1) << __FUNCTION__; |
+ mswrw::HString search_string; |
+ args->get_QueryText(search_string.GetAddressOf()); |
+ string16 search_text(MakeStdWString(search_string.Get())); |
+ globals.search_string = search_text; |
+ DVLOG(1) << search_text.c_str(); |
+ // If this is the initial activation then we wait for Chrome to initiate the |
+ // navigation. In all other cases navigate right away. |
+ if (!globals.is_initial_activation) |
+ InitiateNavigationOrSearchRequest(NULL, globals.search_string.c_str()); |
+} |
+ |
+void ChromeUrlLaunchHandler::HandleProtocolLaunch( |
+ winapp::Activation::IProtocolActivatedEventArgs* args) { |
+ DVLOG(1) << __FUNCTION__; |
+ mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; |
+ args->get_Uri(&uri); |
+ mswrw::HString url; |
+ uri->get_AbsoluteUri(url.GetAddressOf()); |
+ string16 actual_url(MakeStdWString(url.Get())); |
+ globals.navigation_url = actual_url; |
+ |
+ // If this is the initial activation then we wait for Chrome to initiate the |
+ // navigation. In all other cases navigate right away. |
+ if (!globals.is_initial_activation) |
+ InitiateNavigationOrSearchRequest(globals.navigation_url.c_str(), 0); |
+} |
+ |
+// The LaunchArgs are in a semi-color separated key_name=key_value list. At |
+// the moment the only key_name understaood is "url". |
+string16 ChromeUrlLaunchHandler::GetUrlFromLaunchArgs( |
+ const string16& launch_args) { |
+ WStringTokenizer tokenizer(launch_args, L";="); |
+ bool next_is_url = false; |
+ while (tokenizer.GetNext()) { |
+ if (next_is_url) |
+ return tokenizer.token(); |
+ if (tokenizer.token() == L"url") |
+ next_is_url = true; |
+ } |
+ if (launch_args == L"opennewwindow") { |
+ DVLOG(1) << "Returning new tab url"; |
+ return L"chrome://newtab"; |
+ } |
+ return string16(); |
+} |
+ |
+void ChromeUrlLaunchHandler::HandleLaunch( |
+ winapp::Activation::ILaunchActivatedEventArgs* args) { |
+ mswrw::HString launch_args; |
+ args->get_Arguments(launch_args.GetAddressOf()); |
+ string16 actual_launch_args(MakeStdWString(launch_args.Get())); |
+ globals.navigation_url = GetUrlFromLaunchArgs(actual_launch_args); |
+ DVLOG(1) << __FUNCTION__ << ", launch_args=" << actual_launch_args |
+ << ", url=" << globals.navigation_url |
+ << ", is_initial_activation=" << globals.is_initial_activation; |
+ |
+ // If this is the initial launch then we wait for Chrome to initiate the |
+ // navigation. In all other cases navigate right away. |
+ if (!globals.is_initial_activation) |
+ InitiateNavigationOrSearchRequest(globals.navigation_url.c_str(), 0); |
+} |
+ |
+void ChromeUrlLaunchHandler::Activate( |
+ winapp::Activation::IActivatedEventArgs* args) { |
+ winapp::Activation::ActivationKind activation_kind; |
+ CheckHR(args->get_Kind(&activation_kind)); |
+ |
+ DVLOG(1) << __FUNCTION__ << ", activation_kind=" << activation_kind; |
+ |
+ if (globals.is_initial_activation) |
+ globals.initial_activation_kind = activation_kind; |
+ |
+ if (activation_kind == winapp::Activation::ActivationKind_Launch) { |
+ mswr::ComPtr<winapp::Activation::ILaunchActivatedEventArgs> launch_args; |
+ if (args->QueryInterface(winapp::Activation::IID_ILaunchActivatedEventArgs, |
+ &launch_args) == S_OK) { |
+ DVLOG(1) << "Activate: ActivationKind_Launch"; |
+ HandleLaunch(launch_args.Get()); |
+ } |
+ } else if (activation_kind == |
+ winapp::Activation::ActivationKind_Search) { |
+ mswr::ComPtr<winapp::Activation::ISearchActivatedEventArgs> search_args; |
+ if (args->QueryInterface(winapp::Activation::IID_ISearchActivatedEventArgs, |
+ &search_args) == S_OK) { |
+ DVLOG(1) << "Activate: ActivationKind_Search"; |
+ HandleSearchRequest(search_args.Get()); |
+ } |
+ } else if (activation_kind == |
+ winapp::Activation::ActivationKind_Protocol) { |
+ mswr::ComPtr<winapp::Activation::IProtocolActivatedEventArgs> |
+ protocol_args; |
+ if (args->QueryInterface( |
+ winapp::Activation::IID_IProtocolActivatedEventArgs, |
+ &protocol_args) == S_OK) { |
+ DVLOG(1) << "Activate: ActivationKind_Protocol"; |
+ HandleProtocolLaunch(protocol_args.Get()); |
+ } |
+ } else { |
+ DVLOG(1) << "Activate: Unhandled mode: " << activation_kind; |
+ } |
+} |
+ |
+void ChromeUrlLaunchHandler::InitiateNavigationOrSearchRequest( |
+ const wchar_t* url, const wchar_t* search_string) { |
+ DVLOG(1) << __FUNCTION__; |
+ if (!url && !search_string) { |
+ NOTREACHED(); |
+ return; |
+ } |
+ |
+ DVLOG(1) << (url ? url : L"NULL url"); |
+ DVLOG(1) << (search_string ? search_string : L"NULL search string"); |
+ |
+ // Custom registered message to navigate or search in chrome. WPARAM |
+ // points to the URL and LPARAM contains the search string. They are |
+ // mutually exclusive. |
+ static const UINT navigation_search_message = |
+ RegisterWindowMessage(kMetroNavigationAndSearchMessage); |
+ |
+ if (url) { |
+ VLOG(1) << "Posting url:" << url; |
+ PostMessage(globals.host_windows.front().first, navigation_search_message, |
+ reinterpret_cast<WPARAM>(url), 0); |
+ } else { |
+ VLOG(1) << "Posting search string:" << search_string; |
+ PostMessage(globals.host_windows.front().first, navigation_search_message, |
+ 0, reinterpret_cast<LPARAM>(search_string)); |
+ } |
+} |