| Index: win8/metro_driver/chrome_app_view_ash.cc
|
| diff --git a/win8/metro_driver/chrome_app_view_ash.cc b/win8/metro_driver/chrome_app_view_ash.cc
|
| index db2d9f30c4e66cfdd04b7b275fae33bde260a6c4..8c4df51847892b9bcbdfdaed656be04ee99eccd1 100644
|
| --- a/win8/metro_driver/chrome_app_view_ash.cc
|
| +++ b/win8/metro_driver/chrome_app_view_ash.cc
|
| @@ -14,7 +14,6 @@
|
| #include "base/files/file_path.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/path_service.h"
|
| -#include "base/threading/thread.h"
|
| #include "base/win/metro.h"
|
| #include "base/win/win_util.h"
|
| #include "base/win/windows_version.h"
|
| @@ -87,6 +86,8 @@ enum KeyModifier {
|
| ALT = 4
|
| };
|
|
|
| +const int kChromeChannelPollTimerMs = 100;
|
| +
|
| // Helper function to send keystrokes via the SendInput function.
|
| // mnemonic_char: The keystroke to be sent.
|
| // modifiers: Combination with Alt, Ctrl, Shift, etc.
|
| @@ -273,16 +274,6 @@ class ChromeChannelListener : public IPC::Listener {
|
| ChromeAppViewAsh* app_view_;
|
| };
|
|
|
| -bool WaitForChromeIPCConnection(const std::string& channel_name) {
|
| - int ms_elapsed = 0;
|
| - while (!IPC::Channel::IsNamedServerInitialized(channel_name) &&
|
| - ms_elapsed < 10000) {
|
| - ms_elapsed += 100;
|
| - Sleep(100);
|
| - }
|
| - return IPC::Channel::IsNamedServerInitialized(channel_name);
|
| -}
|
| -
|
| void RunMessageLoop(winui::Core::ICoreDispatcher* dispatcher) {
|
| // We're entering a nested message loop, let's allow dispatching
|
| // tasks while we're in there.
|
| @@ -531,7 +522,8 @@ ChromeAppViewAsh::ChromeAppViewAsh()
|
| core_window_hwnd_(NULL),
|
| metro_dpi_scale_(0),
|
| win32_dpi_scale_(0),
|
| - last_cursor_(NULL) {
|
| + last_cursor_(NULL),
|
| + channel_listener_(NULL) {
|
| DVLOG(1) << __FUNCTION__;
|
| globals.previous_state =
|
| winapp::Activation::ApplicationExecutionState_NotRunning;
|
| @@ -678,52 +670,29 @@ ChromeAppViewAsh::Run() {
|
| CheckHR(hr, "Dispatcher failed.");
|
|
|
| // Create the IPC channel IO thread. It needs to out-live the ChannelProxy.
|
| - base::Thread io_thread("metro_IO_thread");
|
| + io_thread_.reset(new base::Thread("metro_IO_thread"));
|
| base::Thread::Options options;
|
| options.message_loop_type = base::MessageLoop::TYPE_IO;
|
| - io_thread.StartWithOptions(options);
|
| -
|
| - // Start up Chrome and wait for the desired IPC server connection to exist.
|
| - WaitForChromeIPCConnection(win8::kMetroViewerIPCChannelName);
|
| + io_thread_->StartWithOptions(options);
|
|
|
| - // In Aura mode we create an IPC channel to the browser, then ask it to
|
| - // connect to us.
|
| ChromeChannelListener ui_channel_listener(&ui_loop_, this);
|
| - scoped_ptr<IPC::ChannelProxy> channel =
|
| - IPC::ChannelProxy::Create(win8::kMetroViewerIPCChannelName,
|
| - IPC::Channel::MODE_NAMED_CLIENT,
|
| - &ui_channel_listener,
|
| - io_thread.message_loop_proxy());
|
| - ui_channel_ = channel.get();
|
| + channel_listener_ = &ui_channel_listener;
|
|
|
| - // Upon receipt of the MetroViewerHostMsg_SetTargetSurface message the
|
| - // browser will use D3D from the browser process to present to our Window.
|
| - ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface(
|
| - gfx::NativeViewId(core_window_hwnd_), win32_dpi_scale_));
|
| - DVLOG(1) << "ICoreWindow sent " << core_window_hwnd_;
|
| + // We can't do anything until the Chrome browser IPC channel is initialized.
|
| + // Lazy initialization in a timer.
|
| + ui_loop_.PostDelayedTask(FROM_HERE,
|
| + base::Bind(base::IgnoreResult(&ChromeAppViewAsh::StartChromeOSMode),
|
| + base::Unretained(this)),
|
| + base::TimeDelta::FromMilliseconds(kChromeChannelPollTimerMs));
|
|
|
| - // Send an initial size message so that the Ash root window host gets sized
|
| - // correctly.
|
| - RECT rect = {0};
|
| - ::GetWindowRect(core_window_hwnd_, &rect);
|
| - ui_channel_->Send(
|
| - new MetroViewerHostMsg_WindowSizeChanged(rect.right - rect.left,
|
| - rect.bottom - rect.top));
|
| -
|
| - input_source_ = metro_driver::InputSource::Create();
|
| - if (input_source_) {
|
| - input_source_->AddObserver(this);
|
| - // Send an initial input source.
|
| - OnInputSourceChanged();
|
| - }
|
| -
|
| - // Start receiving IME popup window notifications.
|
| - metro_driver::AddImePopupObserver(this);
|
| -
|
| - // And post the task that'll do the inner Metro message pumping to it.
|
| + // Post the task that'll do the inner Metro message pumping to it.
|
| ui_loop_.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get()));
|
| ui_loop_.Run();
|
|
|
| + io_thread_.reset(NULL);
|
| + ui_channel_.reset(NULL);
|
| + channel_listener_ = NULL;
|
| +
|
| DVLOG(0) << "ProcessEvents done, hr=" << hr;
|
| return hr;
|
| }
|
| @@ -976,6 +945,8 @@ void ChromeAppViewAsh::OnInputSourceChanged() {
|
| if (!input_source_)
|
| return;
|
|
|
| + DCHECK(ui_channel_);
|
| +
|
| LANGID langid = 0;
|
| bool is_ime = false;
|
| if (!input_source_->GetActiveSource(&langid, &is_ime)) {
|
| @@ -1006,6 +977,8 @@ void ChromeAppViewAsh::SendMouseButton(int x,
|
| uint32 flags,
|
| ui::EventFlags changed_button,
|
| bool is_horizontal_wheel) {
|
| + if (!ui_channel_)
|
| + return;
|
| MetroViewerHostMsg_MouseButtonParams params;
|
| params.x = static_cast<int32>(x);
|
| params.y = static_cast<int32>(y);
|
| @@ -1075,6 +1048,9 @@ HRESULT ChromeAppViewAsh::OnActivate(
|
|
|
| HRESULT ChromeAppViewAsh::OnPointerMoved(winui::Core::ICoreWindow* sender,
|
| winui::Core::IPointerEventArgs* args) {
|
| + if (!ui_channel_)
|
| + return S_OK;
|
| +
|
| PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_);
|
| HRESULT hr = pointer.Init(args);
|
| if (FAILED(hr))
|
| @@ -1110,6 +1086,9 @@ HRESULT ChromeAppViewAsh::OnPointerMoved(winui::Core::ICoreWindow* sender,
|
| HRESULT ChromeAppViewAsh::OnPointerPressed(
|
| winui::Core::ICoreWindow* sender,
|
| winui::Core::IPointerEventArgs* args) {
|
| + if (!ui_channel_)
|
| + return S_OK;
|
| +
|
| PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_);
|
| HRESULT hr = pointer.Init(args);
|
| if (FAILED(hr))
|
| @@ -1133,6 +1112,9 @@ HRESULT ChromeAppViewAsh::OnPointerPressed(
|
| HRESULT ChromeAppViewAsh::OnPointerReleased(
|
| winui::Core::ICoreWindow* sender,
|
| winui::Core::IPointerEventArgs* args) {
|
| + if (!ui_channel_)
|
| + return S_OK;
|
| +
|
| PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_);
|
| HRESULT hr = pointer.Init(args);
|
| if (FAILED(hr))
|
| @@ -1158,6 +1140,9 @@ HRESULT ChromeAppViewAsh::OnPointerReleased(
|
| HRESULT ChromeAppViewAsh::OnWheel(
|
| winui::Core::ICoreWindow* sender,
|
| winui::Core::IPointerEventArgs* args) {
|
| + if (!ui_channel_)
|
| + return S_OK;
|
| +
|
| PointerInfoHandler pointer(metro_dpi_scale_, win32_dpi_scale_);
|
| HRESULT hr = pointer.Init(args);
|
| if (FAILED(hr))
|
| @@ -1172,6 +1157,9 @@ HRESULT ChromeAppViewAsh::OnWheel(
|
| HRESULT ChromeAppViewAsh::OnKeyDown(
|
| winui::Core::ICoreWindow* sender,
|
| winui::Core::IKeyEventArgs* args) {
|
| + if (!ui_channel_)
|
| + return S_OK;
|
| +
|
| winsys::VirtualKey virtual_key;
|
| HRESULT hr = args->get_VirtualKey(&virtual_key);
|
| if (FAILED(hr))
|
| @@ -1191,6 +1179,9 @@ HRESULT ChromeAppViewAsh::OnKeyDown(
|
| HRESULT ChromeAppViewAsh::OnKeyUp(
|
| winui::Core::ICoreWindow* sender,
|
| winui::Core::IKeyEventArgs* args) {
|
| + if (!ui_channel_)
|
| + return S_OK;
|
| +
|
| winsys::VirtualKey virtual_key;
|
| HRESULT hr = args->get_VirtualKey(&virtual_key);
|
| if (FAILED(hr))
|
| @@ -1210,6 +1201,9 @@ HRESULT ChromeAppViewAsh::OnKeyUp(
|
| HRESULT ChromeAppViewAsh::OnAcceleratorKeyDown(
|
| winui::Core::ICoreDispatcher* sender,
|
| winui::Core::IAcceleratorKeyEventArgs* args) {
|
| + if (!ui_channel_)
|
| + return S_OK;
|
| +
|
| winsys::VirtualKey virtual_key;
|
| HRESULT hr = args->get_VirtualKey(&virtual_key);
|
| if (FAILED(hr))
|
| @@ -1264,6 +1258,9 @@ HRESULT ChromeAppViewAsh::OnAcceleratorKeyDown(
|
| HRESULT ChromeAppViewAsh::OnCharacterReceived(
|
| winui::Core::ICoreWindow* sender,
|
| winui::Core::ICharacterReceivedEventArgs* args) {
|
| + if (!ui_channel_)
|
| + return S_OK;
|
| +
|
| unsigned int char_code = 0;
|
| HRESULT hr = args->get_KeyCode(&char_code);
|
| if (FAILED(hr))
|
| @@ -1284,6 +1281,9 @@ HRESULT ChromeAppViewAsh::OnCharacterReceived(
|
| HRESULT ChromeAppViewAsh::OnWindowActivated(
|
| winui::Core::ICoreWindow* sender,
|
| winui::Core::IWindowActivatedEventArgs* args) {
|
| + if (!ui_channel_)
|
| + return S_OK;
|
| +
|
| if (args) {
|
| winui::Core::CoreWindowActivationState state;
|
| HRESULT hr = args->get_WindowActivationState(&state);
|
| @@ -1358,18 +1358,19 @@ HRESULT ChromeAppViewAsh::HandleProtocolRequest(
|
| HRESULT ChromeAppViewAsh::OnEdgeGestureCompleted(
|
| winui::Input::IEdgeGesture* gesture,
|
| winui::Input::IEdgeGestureEventArgs* args) {
|
| - ui_channel_->Send(new MetroViewerHostMsg_EdgeGesture());
|
| + if (ui_channel_)
|
| + ui_channel_->Send(new MetroViewerHostMsg_EdgeGesture());
|
| return S_OK;
|
| }
|
|
|
| void ChromeAppViewAsh::OnSearchRequest(const base::string16& search_string) {
|
| - DCHECK(ui_channel_);
|
| - ui_channel_->Send(new MetroViewerHostMsg_SearchRequest(search_string));
|
| + if (ui_channel_)
|
| + ui_channel_->Send(new MetroViewerHostMsg_SearchRequest(search_string));
|
| }
|
|
|
| void ChromeAppViewAsh::OnNavigateToUrl(const base::string16& url) {
|
| - DCHECK(ui_channel_);
|
| - ui_channel_->Send(new MetroViewerHostMsg_OpenURL(url));
|
| + if (ui_channel_)
|
| + ui_channel_->Send(new MetroViewerHostMsg_OpenURL(url));
|
| }
|
|
|
| HRESULT ChromeAppViewAsh::OnSizeChanged(winui::Core::ICoreWindow* sender,
|
| @@ -1392,6 +1393,69 @@ HRESULT ChromeAppViewAsh::OnSizeChanged(winui::Core::ICoreWindow* sender,
|
| return S_OK;
|
| }
|
|
|
| +void ChromeAppViewAsh::StartChromeOSMode() {
|
| + static int ms_elapsed = 0;
|
| +
|
| + if (!IPC::Channel::IsNamedServerInitialized(
|
| + win8::kMetroViewerIPCChannelName) && ms_elapsed < 10000) {
|
| + ms_elapsed += 100;
|
| + ui_loop_.PostDelayedTask(FROM_HERE,
|
| + base::Bind(base::IgnoreResult(&ChromeAppViewAsh::StartChromeOSMode),
|
| + base::Unretained(this)),
|
| + base::TimeDelta::FromMilliseconds(kChromeChannelPollTimerMs));
|
| + return;
|
| + }
|
| +
|
| + if (!IPC::Channel::IsNamedServerInitialized(
|
| + win8::kMetroViewerIPCChannelName)) {
|
| + DVLOG(1) << "Failed to connect to chrome channel : "
|
| + << win8::kMetroViewerIPCChannelName;
|
| + DVLOG(1) << "Exiting. Elapsed time :" << ms_elapsed;
|
| + PostMessage(core_window_hwnd_, WM_CLOSE, 0, 0);
|
| + return;
|
| + }
|
| +
|
| + DVLOG(1) << "Found channel : " << win8::kMetroViewerIPCChannelName;
|
| +
|
| + DCHECK(channel_listener_);
|
| +
|
| + // In Aura mode we create an IPC channel to the browser, then ask it to
|
| + // connect to us.
|
| + ui_channel_ =
|
| + IPC::ChannelProxy::Create(win8::kMetroViewerIPCChannelName,
|
| + IPC::Channel::MODE_NAMED_CLIENT,
|
| + channel_listener_,
|
| + io_thread_->message_loop_proxy());
|
| + DVLOG(1) << "Created channel proxy";
|
| +
|
| + // Upon receipt of the MetroViewerHostMsg_SetTargetSurface message the
|
| + // browser will use D3D from the browser process to present to our Window.
|
| + ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface(
|
| + gfx::NativeViewId(core_window_hwnd_),
|
| + win32_dpi_scale_));
|
| + DVLOG(1) << "ICoreWindow sent " << core_window_hwnd_;
|
| +
|
| + // Send an initial size message so that the Ash root window host gets sized
|
| + // correctly.
|
| + RECT rect = {0};
|
| + ::GetWindowRect(core_window_hwnd_, &rect);
|
| + ui_channel_->Send(
|
| + new MetroViewerHostMsg_WindowSizeChanged(rect.right - rect.left,
|
| + rect.bottom - rect.top));
|
| +
|
| + input_source_ = metro_driver::InputSource::Create();
|
| + if (input_source_) {
|
| + input_source_->AddObserver(this);
|
| + // Send an initial input source.
|
| + OnInputSourceChanged();
|
| + }
|
| +
|
| + // Start receiving IME popup window notifications.
|
| + metro_driver::AddImePopupObserver(this);
|
| +
|
| + DVLOG(1) << "Channel setup complete";
|
| +}
|
| +
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| ChromeAppViewFactory::ChromeAppViewFactory(
|
|
|