Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Unified Diff: win8/metro_driver/chrome_app_view_ash.cc

Issue 593353003: The metro_driver should not block the UI thread while waiting for the Chrome browser IPC channel to… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..053ef8f09de7555bff185c3974414a07aba1c2e0 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,13 @@ enum KeyModifier {
ALT = 4
};
+const int kChromeChannelPollTimerMs = 100;
+const UINT_PTR kChromeChannelPollTimerId = 0xdeadbabe;
+static const wchar_t kChromeAppViewAshInstanceProp[] =
+ L"ChromeAppViewAshInstance";
+static const wchar_t kChromeChannelListenerProp[] =
+ L"ChromeChannelListenerProp";
+
// Helper function to send keystrokes via the SendInput function.
// mnemonic_char: The keystroke to be sent.
// modifiers: Combination with Alt, Ctrl, Shift, etc.
@@ -678,52 +684,32 @@ 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();
- // 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.
+ ::SetProp(core_window_hwnd_, kChromeAppViewAshInstanceProp, this);
+ ::SetProp(core_window_hwnd_, kChromeChannelListenerProp,
+ &ui_channel_listener);
- // 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);
+ UINT_PTR channel_setup_timer_id =
+ ::SetTimer(core_window_hwnd_,
+ kChromeChannelPollTimerId,
+ kChromeChannelPollTimerMs,
+ &ChromeAppViewAsh::StartChromeOSMode);
- // 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);
+
DVLOG(0) << "ProcessEvents done, hr=" << hr;
return hr;
}
@@ -1075,6 +1061,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 +1099,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 +1125,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 +1153,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 +1170,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 +1192,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 +1214,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 +1271,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 +1294,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);
@@ -1392,6 +1405,82 @@ HRESULT ChromeAppViewAsh::OnSizeChanged(winui::Core::ICoreWindow* sender,
return S_OK;
}
+// static
+void CALLBACK ChromeAppViewAsh::StartChromeOSMode(HWND core_window,
+ UINT message,
+ UINT_PTR timer_id,
+ DWORD time) {
+ static int ms_elapsed = 0;
+ if (!IPC::Channel::IsNamedServerInitialized(
scottmg 2014/09/24 02:40:32 WaitForChromeIPCConnection isn't used any more, sh
ananta 2014/09/24 18:22:33 Done.
+ win8::kMetroViewerIPCChannelName) && ms_elapsed < 10000) {
+ ms_elapsed += 100;
+ return;
+ }
+
+ if (!IPC::Channel::IsNamedServerInitialized(
+ win8::kMetroViewerIPCChannelName)) {
+ DVLOG(1) << "Failed to connect to chrome channel : "
+ << win8::kMetroViewerIPCChannelName;
+ DVLOG(1) << "Exiting...";
+ PostMessage(core_window, WM_CLOSE, 0, 0);
+ ::RemoveProp(core_window, kChromeAppViewAshInstanceProp);
scottmg 2014/09/24 02:40:32 why do we need window props instead of plain globa
ananta 2014/09/24 18:22:33 Good point. Done.
+ ::RemoveProp(core_window, kChromeChannelListenerProp);
+ ::KillTimer(core_window, kChromeChannelPollTimerId);
scottmg 2014/09/24 02:40:32 killtimer here and below can move out above the if
ananta 2014/09/24 18:22:33 Done.
+ return;
+ }
+
+ ::KillTimer(core_window, kChromeChannelPollTimerId);
+
+ DVLOG(1) << "Found channel : " << win8::kMetroViewerIPCChannelName;
+
+ ChromeAppViewAsh* instance = reinterpret_cast<ChromeAppViewAsh*>(
+ ::GetProp(core_window, kChromeAppViewAshInstanceProp));
+ DCHECK(instance);
+
+ ChromeChannelListener* listener = reinterpret_cast<ChromeChannelListener*>(
+ ::GetProp(core_window, kChromeChannelListenerProp));
+ DCHECK(listener);
+
+ // In Aura mode we create an IPC channel to the browser, then ask it to
+ // connect to us.
+ instance->ui_channel_ =
+ IPC::ChannelProxy::Create(win8::kMetroViewerIPCChannelName,
+ IPC::Channel::MODE_NAMED_CLIENT,
+ listener,
+ instance->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.
+ instance->ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface(
+ gfx::NativeViewId(core_window),
+ instance->win32_dpi_scale_));
+ DVLOG(1) << "ICoreWindow sent " << core_window;
+
+ // Send an initial size message so that the Ash root window host gets sized
+ // correctly.
+ RECT rect = {0};
+ ::GetWindowRect(core_window, &rect);
+ instance->ui_channel_->Send(
+ new MetroViewerHostMsg_WindowSizeChanged(rect.right - rect.left,
+ rect.bottom - rect.top));
+
+ instance->input_source_ = metro_driver::InputSource::Create();
+ if (instance->input_source_) {
+ instance->input_source_->AddObserver(instance);
+ // Send an initial input source.
+ instance->OnInputSourceChanged();
+ }
+
+ // Start receiving IME popup window notifications.
+ metro_driver::AddImePopupObserver(instance);
+
+ ::RemoveProp(core_window, kChromeAppViewAshInstanceProp);
+ ::RemoveProp(core_window, kChromeChannelListenerProp);
+
+ DVLOG(1) << "Channel setup complete";
+}
+
///////////////////////////////////////////////////////////////////////////////
ChromeAppViewFactory::ChromeAppViewFactory(
« win8/metro_driver/chrome_app_view_ash.h ('K') | « win8/metro_driver/chrome_app_view_ash.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698