diff options
-rw-r--r-- | ash/test/test_metro_viewer_process_host.cc | 7 | ||||
-rw-r--r-- | ash/test/test_metro_viewer_process_host.h | 2 | ||||
-rw-r--r-- | chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc | 35 | ||||
-rw-r--r-- | chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h | 2 | ||||
-rw-r--r-- | chrome/browser/ui/ash/chrome_shell_delegate_views.cc | 7 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 4 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 | ||||
-rw-r--r-- | ui/metro_viewer/metro_viewer_messages.h | 6 | ||||
-rw-r--r-- | win8/metro_driver/chrome_app_view_ash.cc | 95 | ||||
-rw-r--r-- | win8/metro_driver/chrome_app_view_ash.h | 14 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_process_host.cc | 2 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_process_host.h | 9 |
12 files changed, 177 insertions, 7 deletions
diff --git a/ash/test/test_metro_viewer_process_host.cc b/ash/test/test_metro_viewer_process_host.cc index a5d36e9..a7c8504 100644 --- a/ash/test/test_metro_viewer_process_host.cc +++ b/ash/test/test_metro_viewer_process_host.cc @@ -51,5 +51,12 @@ void TestMetroViewerProcessHost::OnSetTargetSurface( aura::RemoteRootWindowHostWin::Instance()->Connected(this); } +void TestMetroViewerProcessHost::OnOpenURL(const string16& url) { +} + +void TestMetroViewerProcessHost::OnHandleSearchRequest( + const string16& search_string) { +} + } // namespace test } // namespace ash diff --git a/ash/test/test_metro_viewer_process_host.h b/ash/test/test_metro_viewer_process_host.h index 0f24169..63ca815 100644 --- a/ash/test/test_metro_viewer_process_host.h +++ b/ash/test/test_metro_viewer_process_host.h @@ -26,6 +26,8 @@ class TestMetroViewerProcessHost : public win8::MetroViewerProcessHost { // win8::MetroViewerProcessHost implementation virtual void OnChannelError() OVERRIDE; virtual void OnSetTargetSurface(gfx::NativeViewId target_surface) OVERRIDE; + virtual void OnOpenURL(const string16& url) OVERRIDE; + virtual void OnHandleSearchRequest(const string16& search_string) OVERRIDE; scoped_ptr<AcceleratedSurface> backing_surface; diff --git a/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc b/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc index 03385f7..268510e 100644 --- a/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc +++ b/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.cc @@ -8,8 +8,13 @@ #include "base/memory/ref_counted.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part_aurawin.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/search_engines/template_url.h" +#include "chrome/browser/search_engines/template_url_service.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/ui/ash/ash_init.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/host_desktop.h" @@ -17,7 +22,9 @@ #include "chrome/common/chrome_notification_types.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" +#include "content/public/browser/page_navigator.h" #include "content/public/browser/web_contents.h" +#include "googleurl/src/gurl.h" #include "ui/aura/remote_root_window_host_win.h" #include "ui/surface/accelerated_surface_win.h" @@ -39,6 +46,15 @@ void CloseOpenAshBrowsers() { } } +void OpenURL(const GURL& url) { + Browser* browser = chrome::FindOrCreateTabbedBrowser( + ProfileManager::GetDefaultProfileOrOffTheRecord(), + chrome::HOST_DESKTOP_TYPE_ASH); + browser->OpenURL(content::OpenURLParams( + GURL(url), content::Referrer(), NEW_FOREGROUND_TAB, + content::PAGE_TRANSITION_TYPED, false)); +} + } // namespace ChromeMetroViewerProcessHost::ChromeMetroViewerProcessHost( @@ -84,3 +100,22 @@ void ChromeMetroViewerProcessHost::OnSetTargetSurface( content::NotificationService::AllSources(), content::NotificationService::NoDetails()); } + +void ChromeMetroViewerProcessHost::OnOpenURL(const string16& url) { + OpenURL(GURL(url)); +} + +void ChromeMetroViewerProcessHost::OnHandleSearchRequest( + const string16& search_string) { + const TemplateURL* default_provider = + TemplateURLServiceFactory::GetForProfile( + ProfileManager::GetDefaultProfileOrOffTheRecord())-> + GetDefaultSearchProvider(); + if (default_provider) { + const TemplateURLRef& search_url = default_provider->url_ref(); + DCHECK(search_url.SupportsReplacement()); + GURL request_url = GURL(search_url.ReplaceSearchTerms( + TemplateURLRef::SearchTermsArgs(search_string))); + OpenURL(request_url); + } +} diff --git a/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h b/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h index f3411c7..826deb2 100644 --- a/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h +++ b/chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h @@ -17,6 +17,8 @@ class ChromeMetroViewerProcessHost : public win8::MetroViewerProcessHost { // win8::MetroViewerProcessHost implementation virtual void OnChannelError() OVERRIDE; virtual void OnSetTargetSurface(gfx::NativeViewId target_surface) OVERRIDE; + virtual void OnOpenURL(const string16& url) OVERRIDE; + virtual void OnHandleSearchRequest(const string16& search_string) OVERRIDE; DISALLOW_COPY_AND_ASSIGN(ChromeMetroViewerProcessHost); }; diff --git a/chrome/browser/ui/ash/chrome_shell_delegate_views.cc b/chrome/browser/ui/ash/chrome_shell_delegate_views.cc index 2e07206..7169cc5 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate_views.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate_views.cc @@ -18,6 +18,7 @@ #include "chrome/browser/ui/host_desktop.h" #include "chrome/browser/ui/startup/startup_browser_creator_impl.h" #include "chrome/common/chrome_notification_types.h" +#include "chrome/common/chrome_switches.h" #include "content/public/browser/notification_service.h" #if defined(OS_WIN) @@ -120,6 +121,12 @@ void ChromeShellDelegate::Observe(int type, const content::NotificationDetails& details) { switch (type) { case chrome::NOTIFICATION_ASH_SESSION_STARTED: { + // If we are launched to service a windows 8 search request then let the + // IPC which carries the search string create the browser and initiate + // the navigation. + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kWindows8Search)) + break; // If Chrome ASH is launched when no browser is open in the desktop, // we should execute the startup code. // If there are browsers open in the desktop, we create a browser window diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index c38e88a..1c588c6 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -1566,6 +1566,10 @@ const char kRelaunchShortcut[] = "relaunch-shortcut"; // Waits for the given handle to be signaled before relaunching metro Chrome on // Windows 8 and higher. const char kWaitForMutex[] = "wait-for-mutex"; + +// Indicates that chrome was launched to service a search request in Windows 8. +const char kWindows8Search[] = "windows8-search"; + #endif #ifndef NDEBUG diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 04f8ed7..feaa283 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -437,6 +437,7 @@ extern const char kOverlappedRead[]; extern const char kPrintRaster[]; extern const char kRelaunchShortcut[]; extern const char kWaitForMutex[]; +extern const char kWindows8Search[]; #endif #ifndef NDEBUG diff --git a/ui/metro_viewer/metro_viewer_messages.h b/ui/metro_viewer/metro_viewer_messages.h index f301618..d26b12d 100644 --- a/ui/metro_viewer/metro_viewer_messages.h +++ b/ui/metro_viewer/metro_viewer_messages.h @@ -145,3 +145,9 @@ IPC_MESSAGE_CONTROL2(MetroViewerHostMsg_SetCursorPos, // Ack sent by the viewer process indicating that the SetCursorPos operation // was completed. IPC_MESSAGE_CONTROL0(MetroViewerHostMsg_SetCursorPosAck) + +IPC_MESSAGE_CONTROL1(MetroViewerHostMsg_OpenURL, + string16) /* url */ + +IPC_MESSAGE_CONTROL1(MetroViewerHostMsg_SearchRequest, + string16) /* search_string */ diff --git a/win8/metro_driver/chrome_app_view_ash.cc b/win8/metro_driver/chrome_app_view_ash.cc index f3a3a88..8a9e8a1 100644 --- a/win8/metro_driver/chrome_app_view_ash.cc +++ b/win8/metro_driver/chrome_app_view_ash.cc @@ -6,6 +6,7 @@ #include "win8/metro_driver/chrome_app_view_ash.h" #include <corewindow.h> +#include <shellapi.h> #include <windows.foundation.h> #include "base/bind.h" @@ -294,7 +295,9 @@ uint32 GetKeyboardEventFlags() { ChromeAppViewAsh::ChromeAppViewAsh() : mouse_down_flags_(ui::EF_NONE), ui_channel_(nullptr), - core_window_hwnd_(NULL) { + core_window_hwnd_(NULL), + ui_loop_(base::MessageLoop::TYPE_UI) { + DVLOG(1) << __FUNCTION__; globals.previous_state = winapp::Activation::ApplicationExecutionState_NotRunning; } @@ -414,9 +417,6 @@ ChromeAppViewAsh::Run() { return hr; } - // Create a message loop to allow message passing into this thread. - base::MessageLoop msg_loop(base::MessageLoop::TYPE_UI); - // Create the IPC channel IO thread. It needs to out-live the ChannelProxy. base::Thread io_thread("metro_IO_thread"); base::Thread::Options options; @@ -435,7 +435,7 @@ ChromeAppViewAsh::Run() { // In Aura mode we create an IPC channel to the browser, then ask it to // connect to us. - ChromeChannelListener ui_channel_listener(&msg_loop, this); + ChromeChannelListener ui_channel_listener(&ui_loop_, this); IPC::ChannelProxy ui_channel(ipc_channel_name, IPC::Channel::MODE_NAMED_CLIENT, &ui_channel_listener, @@ -449,8 +449,8 @@ ChromeAppViewAsh::Run() { DVLOG(1) << "ICoreWindow sent " << core_window_hwnd_; // And post the task that'll do the inner Metro message pumping to it. - msg_loop.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); - msg_loop.Run(); + ui_loop_.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); + ui_loop_.Run(); DVLOG(0) << "ProcessEvents done, hr=" << hr; return hr; @@ -603,6 +603,18 @@ HRESULT ChromeAppViewAsh::OnActivate( args->get_PreviousExecutionState(&globals.previous_state); DVLOG(1) << "Previous Execution State: " << globals.previous_state; + winapp::Activation::ActivationKind activation_kind; + CheckHR(args->get_Kind(&activation_kind)); + if (activation_kind == winapp::Activation::ActivationKind_Search) + HandleSearchRequest(args); + else if (activation_kind == winapp::Activation::ActivationKind_Protocol) + HandleProtocolRequest(args); + // We call ICoreWindow::Activate after the handling for the search/protocol + // requests because Chrome can be launched to handle a search request which + // in turn launches the chrome browser process in desktop mode via + // ShellExecute. If we call ICoreWindow::Activate before this, then + // Windows kills the metro chrome process when it calls ShellExecute. Seems + // to be a bug. window_->Activate(); return S_OK; } @@ -830,6 +842,75 @@ HRESULT ChromeAppViewAsh::OnWindowActivated( return S_OK; } +HRESULT ChromeAppViewAsh::HandleSearchRequest( + winapp::Activation::IActivatedEventArgs* args) { + mswr::ComPtr<winapp::Activation::ISearchActivatedEventArgs> search_args; + CheckHR(args->QueryInterface( + winapp::Activation::IID_ISearchActivatedEventArgs, &search_args)); + + if (!ui_channel_) { + DVLOG(1) << "Launched to handle search request"; + base::FilePath chrome_exe_path; + + if (!PathService::Get(base::FILE_EXE, &chrome_exe_path)) + return E_FAIL; + + SHELLEXECUTEINFO sei = { sizeof(sei) }; + sei.nShow = SW_SHOWNORMAL; + sei.lpFile = chrome_exe_path.value().c_str(); + sei.lpDirectory = L""; + sei.lpParameters = + L"--silent-launch --viewer-connection=viewer --windows8-search"; + ::ShellExecuteEx(&sei); + } + + mswrw::HString search_string; + CheckHR(search_args->get_QueryText(search_string.GetAddressOf())); + string16 search_text(MakeStdWString(search_string.Get())); + + ui_loop_.PostTask(FROM_HERE, + base::Bind(&ChromeAppViewAsh::OnSearchRequest, + base::Unretained(this), + search_text)); + return S_OK; +} + +HRESULT ChromeAppViewAsh::HandleProtocolRequest( + winapp::Activation::IActivatedEventArgs* args) { + DVLOG(1) << __FUNCTION__; + if (!ui_channel_) + DVLOG(1) << "Launched to handle url request"; + + mswr::ComPtr<winapp::Activation::IProtocolActivatedEventArgs> + protocol_args; + CheckHR(args->QueryInterface( + winapp::Activation::IID_IProtocolActivatedEventArgs, + &protocol_args)); + + mswr::ComPtr<winfoundtn::IUriRuntimeClass> uri; + protocol_args->get_Uri(&uri); + mswrw::HString url; + uri->get_AbsoluteUri(url.GetAddressOf()); + string16 actual_url(MakeStdWString(url.Get())); + DVLOG(1) << "Received url request: " << actual_url; + + ui_loop_.PostTask(FROM_HERE, + base::Bind(&ChromeAppViewAsh::OnNavigateToUrl, + base::Unretained(this), + actual_url)); + return S_OK; +} + +void ChromeAppViewAsh::OnSearchRequest(const string16& search_string) { + DCHECK(ui_channel_); + ui_channel_->Send(new MetroViewerHostMsg_SearchRequest(search_string)); +} + +void ChromeAppViewAsh::OnNavigateToUrl(const string16& url) { + DCHECK(ui_channel_); + ui_channel_->Send(new MetroViewerHostMsg_OpenURL(url)); +} + /////////////////////////////////////////////////////////////////////////////// diff --git a/win8/metro_driver/chrome_app_view_ash.h b/win8/metro_driver/chrome_app_view_ash.h index 0989cda..35c283e 100644 --- a/win8/metro_driver/chrome_app_view_ash.h +++ b/win8/metro_driver/chrome_app_view_ash.h @@ -12,6 +12,7 @@ #include "base/files/file_path.h" #include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" #include "base/string16.h" #include "ui/base/events/event_constants.h" #include "win8/metro_driver/direct3d_helper.h" @@ -111,6 +112,16 @@ class ChromeAppViewAsh HRESULT OnWindowActivated(winui::Core::ICoreWindow* sender, winui::Core::IWindowActivatedEventArgs* args); + // Helper to handle search requests received via the search charm in ASH. + HRESULT HandleSearchRequest(winapp::Activation::IActivatedEventArgs* args); + // Helper to handle http/https url requests in ASH. + HRESULT HandleProtocolRequest(winapp::Activation::IActivatedEventArgs* args); + + // Tasks posted to the UI thread to initiate the search/url navigation + // requests. + void OnSearchRequest(const string16& search_string); + void OnNavigateToUrl(const string16& url); + mswr::ComPtr<winui::Core::ICoreWindow> window_; mswr::ComPtr<winapp::Core::ICoreApplicationView> view_; EventRegistrationToken activated_token_; @@ -138,6 +149,9 @@ class ChromeAppViewAsh // The actual window behind the view surface. HWND core_window_hwnd_; + + // UI message loop to allow message passing into this thread. + base::MessageLoop ui_loop_; }; #endif // WIN8_METRO_DRIVER_CHROME_APP_VIEW_ASH_H_ diff --git a/win8/viewer/metro_viewer_process_host.cc b/win8/viewer/metro_viewer_process_host.cc index f945039..0e4c535 100644 --- a/win8/viewer/metro_viewer_process_host.cc +++ b/win8/viewer/metro_viewer_process_host.cc @@ -94,6 +94,8 @@ bool MetroViewerProcessHost::OnMessageReceived( bool handled = true; IPC_BEGIN_MESSAGE_MAP(MetroViewerProcessHost, message) IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetTargetSurface, OnSetTargetSurface) + IPC_MESSAGE_HANDLER(MetroViewerHostMsg_OpenURL, OnOpenURL) + IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SearchRequest, OnHandleSearchRequest) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled ? true : diff --git a/win8/viewer/metro_viewer_process_host.h b/win8/viewer/metro_viewer_process_host.h index b9c3e77..5dfa5d3 100644 --- a/win8/viewer/metro_viewer_process_host.h +++ b/win8/viewer/metro_viewer_process_host.h @@ -65,6 +65,15 @@ class MetroViewerProcessHost : public IPC::Listener, // drawing to |target_surface|. virtual void OnSetTargetSurface(gfx::NativeViewId target_surface) = 0; + // Called over IPC by the viewer process to request that the url passed in be + // opened. + virtual void OnOpenURL(const string16& url) = 0; + + // Called over IPC by the viewer process to request that the search string + // passed in is passed to the default search provider and a URL navigation be + // performed. + virtual void OnHandleSearchRequest(const string16& search_string) = 0; + void NotifyChannelConnected(); // Inner message filter used to handle connection event on the IPC channel |