diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-05 21:37:20 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-05 21:37:20 +0000 |
commit | 7f8d70ea6f2ad3fd5dafc079d519389f96263e25 (patch) | |
tree | d98811674067cbe8d11153fc45d44f1a53a2f4b0 | |
parent | 8776526cc3928b6f46f01976342fd46198103409 (diff) | |
download | chromium_src-7f8d70ea6f2ad3fd5dafc079d519389f96263e25.zip chromium_src-7f8d70ea6f2ad3fd5dafc079d519389f96263e25.tar.gz chromium_src-7f8d70ea6f2ad3fd5dafc079d519389f96263e25.tar.bz2 |
Support searching through the Windows 8 Search charm and url navigations from the Start menu in Windows 8 ASH.
Changes as below:-
1. In the metro driver we need to handle the search and protocol activation requests.
Search requests when Chrome ASH is not running result in ASH being launched by Windows without going through
the normal delegate execute mechanism.
This means that the browser process will not be running to service the viewer ASH process. We need to launch the
server via ShellExecute to ensure that it launches in desktop mode.
If the search/protocol requests are received when Chrome ASH is being launched we ensure that the IPC messages
to service these requests are sent out after the MetroViewerHostMsg_SetTargetSurface IPC.
If Chrome ASH is running when we receive these requests we send out the search/navigation IPCs to Chrome.
2. Added the following IPC messages to metro_viewer_messages.h
1. MetroViewerHostMsg_SearchRequest
2. MetroViewerHostMsg_OpenURL
The handling for these messages is implemented via virtual functions OnOpenURL and OnHandleSearchRequest in the
MetroViewerProcessHost interface with the ChromeMetroViewerProcessHost overriding this to ensure that the URL
is opened.
3. Added a switch kWindows8MetroSearch to chrome_switches.cc/.h. This is passed in from the metro driver on Windows 8
if we are launched to service a search request from the start screen. We don't attempt to create a browser or
run the session restore code in the NOTIFICATION_ASH_SESSION_STARTED notification if this switch exists. The desired
browser window for the search is created in the MetroViewerHostMsg_SearchRequest IPC.
BUG=245899
R=cpu@chromium.org, jschuh@chromium.org, sky@chromium.org
Review URL: https://codereview.chromium.org/16282002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204344 0039d316-1c4b-4281-b951-d872f2087c98
-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 |