| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "win8/metro_driver/stdafx.h" | 5 #include "win8/metro_driver/stdafx.h" |
| 6 #include "win8/metro_driver/chrome_app_view_ash.h" | 6 #include "win8/metro_driver/chrome_app_view_ash.h" |
| 7 | 7 |
| 8 #include <corewindow.h> |
| 8 #include <windows.foundation.h> | 9 #include <windows.foundation.h> |
| 9 | 10 |
| 10 #include "base/bind.h" | 11 #include "base/bind.h" |
| 11 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 12 #include "base/message_loop.h" | 13 #include "base/message_loop.h" |
| 13 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 14 #include "base/process_util.h" | 15 #include "base/process_util.h" |
| 15 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 16 #include "base/win/metro.h" | 17 #include "base/win/metro.h" |
| 17 #include "base/win/win_util.h" | 18 #include "base/win/win_util.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 47 | 48 |
| 48 typedef winfoundtn::ITypedEventHandler< | 49 typedef winfoundtn::ITypedEventHandler< |
| 49 winui::Core::CoreWindow*, | 50 winui::Core::CoreWindow*, |
| 50 winui::Core::VisibilityChangedEventArgs*> VisibilityChangedHandler; | 51 winui::Core::VisibilityChangedEventArgs*> VisibilityChangedHandler; |
| 51 | 52 |
| 52 // This function is exported by chrome.exe. | 53 // This function is exported by chrome.exe. |
| 53 typedef int (__cdecl *BreakpadExceptionHandler)(EXCEPTION_POINTERS* info); | 54 typedef int (__cdecl *BreakpadExceptionHandler)(EXCEPTION_POINTERS* info); |
| 54 | 55 |
| 55 // Global information used across the metro driver. | 56 // Global information used across the metro driver. |
| 56 struct Globals { | 57 struct Globals { |
| 57 LPTHREAD_START_ROUTINE host_main; | |
| 58 HWND core_window; | |
| 59 DWORD main_thread_id; | |
| 60 winapp::Activation::ApplicationExecutionState previous_state; | 58 winapp::Activation::ApplicationExecutionState previous_state; |
| 61 winapp::Core::ICoreApplicationExit* app_exit; | 59 winapp::Core::ICoreApplicationExit* app_exit; |
| 62 BreakpadExceptionHandler breakpad_exception_handler; | 60 BreakpadExceptionHandler breakpad_exception_handler; |
| 63 } globals; | 61 } globals; |
| 64 | 62 |
| 65 namespace { | 63 namespace { |
| 66 | 64 |
| 67 // TODO(robertshield): Share this with chrome_app_view.cc | 65 // TODO(robertshield): Share this with chrome_app_view.cc |
| 68 void MetroExit() { | 66 void MetroExit() { |
| 69 globals.app_exit->Exit(); | 67 globals.app_exit->Exit(); |
| 70 globals.core_window = NULL; | |
| 71 } | 68 } |
| 72 | 69 |
| 73 class ChromeChannelListener : public IPC::Listener { | 70 class ChromeChannelListener : public IPC::Listener { |
| 74 public: | 71 public: |
| 75 ChromeChannelListener(MessageLoop* ui_loop, ChromeAppViewAsh* app_view) | 72 ChromeChannelListener(MessageLoop* ui_loop, ChromeAppViewAsh* app_view) |
| 76 : ui_proxy_(ui_loop->message_loop_proxy()), | 73 : ui_proxy_(ui_loop->message_loop_proxy()), |
| 77 app_view_(app_view) { | 74 app_view_(app_view) { |
| 78 } | 75 } |
| 79 | 76 |
| 80 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 77 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 if (base::win::IsCtrlPressed()) | 262 if (base::win::IsCtrlPressed()) |
| 266 flags |= ui::EF_CONTROL_DOWN; | 263 flags |= ui::EF_CONTROL_DOWN; |
| 267 if (base::win::IsAltPressed()) | 264 if (base::win::IsAltPressed()) |
| 268 flags |= ui::EF_ALT_DOWN; | 265 flags |= ui::EF_ALT_DOWN; |
| 269 return flags; | 266 return flags; |
| 270 } | 267 } |
| 271 | 268 |
| 272 } // namespace | 269 } // namespace |
| 273 | 270 |
| 274 ChromeAppViewAsh::ChromeAppViewAsh() | 271 ChromeAppViewAsh::ChromeAppViewAsh() |
| 275 : mouse_down_flags_(ui::EF_NONE), ui_channel_(nullptr) { | 272 : mouse_down_flags_(ui::EF_NONE), |
| 273 ui_channel_(nullptr), |
| 274 core_window_hwnd_(NULL) { |
| 276 globals.previous_state = | 275 globals.previous_state = |
| 277 winapp::Activation::ApplicationExecutionState_NotRunning; | 276 winapp::Activation::ApplicationExecutionState_NotRunning; |
| 278 } | 277 } |
| 279 | 278 |
| 280 ChromeAppViewAsh::~ChromeAppViewAsh() { | 279 ChromeAppViewAsh::~ChromeAppViewAsh() { |
| 281 DVLOG(1) << __FUNCTION__; | 280 DVLOG(1) << __FUNCTION__; |
| 282 } | 281 } |
| 283 | 282 |
| 284 IFACEMETHODIMP | 283 IFACEMETHODIMP |
| 285 ChromeAppViewAsh::Initialize(winapp::Core::ICoreApplicationView* view) { | 284 ChromeAppViewAsh::Initialize(winapp::Core::ICoreApplicationView* view) { |
| 286 view_ = view; | 285 view_ = view; |
| 287 DVLOG(1) << __FUNCTION__; | 286 DVLOG(1) << __FUNCTION__; |
| 288 globals.main_thread_id = ::GetCurrentThreadId(); | |
| 289 | |
| 290 HRESULT hr = view_->add_Activated(mswr::Callback<ActivatedHandler>( | 287 HRESULT hr = view_->add_Activated(mswr::Callback<ActivatedHandler>( |
| 291 this, &ChromeAppViewAsh::OnActivate).Get(), | 288 this, &ChromeAppViewAsh::OnActivate).Get(), |
| 292 &activated_token_); | 289 &activated_token_); |
| 293 CheckHR(hr); | 290 CheckHR(hr); |
| 294 return hr; | 291 return hr; |
| 295 } | 292 } |
| 296 | 293 |
| 297 IFACEMETHODIMP | 294 IFACEMETHODIMP |
| 298 ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) { | 295 ChromeAppViewAsh::SetWindow(winui::Core::ICoreWindow* window) { |
| 299 window_ = window; | 296 window_ = window; |
| 300 DVLOG(1) << __FUNCTION__; | 297 DVLOG(1) << __FUNCTION__; |
| 298 |
| 299 // Retrieve the native window handle via the interop layer. |
| 300 mswr::ComPtr<ICoreWindowInterop> interop; |
| 301 HRESULT hr = window->QueryInterface(interop.GetAddressOf()); |
| 302 CheckHR(hr); |
| 303 hr = interop->get_WindowHandle(&core_window_hwnd_); |
| 304 CheckHR(hr); |
| 305 |
| 301 // Register for pointer and keyboard notifications. We forward | 306 // Register for pointer and keyboard notifications. We forward |
| 302 // them to the browser process via IPC. | 307 // them to the browser process via IPC. |
| 303 HRESULT hr = window_->add_PointerMoved(mswr::Callback<PointerEventHandler>( | 308 hr = window_->add_PointerMoved(mswr::Callback<PointerEventHandler>( |
| 304 this, &ChromeAppViewAsh::OnPointerMoved).Get(), | 309 this, &ChromeAppViewAsh::OnPointerMoved).Get(), |
| 305 &pointermoved_token_); | 310 &pointermoved_token_); |
| 306 CheckHR(hr); | 311 CheckHR(hr); |
| 307 | 312 |
| 308 hr = window_->add_PointerPressed(mswr::Callback<PointerEventHandler>( | 313 hr = window_->add_PointerPressed(mswr::Callback<PointerEventHandler>( |
| 309 this, &ChromeAppViewAsh::OnPointerPressed).Get(), | 314 this, &ChromeAppViewAsh::OnPointerPressed).Get(), |
| 310 &pointerpressed_token_); | 315 &pointerpressed_token_); |
| 311 CheckHR(hr); | 316 CheckHR(hr); |
| 312 | 317 |
| 313 hr = window_->add_PointerReleased(mswr::Callback<PointerEventHandler>( | 318 hr = window_->add_PointerReleased(mswr::Callback<PointerEventHandler>( |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 } | 374 } |
| 370 | 375 |
| 371 IFACEMETHODIMP | 376 IFACEMETHODIMP |
| 372 ChromeAppViewAsh::Run() { | 377 ChromeAppViewAsh::Run() { |
| 373 DVLOG(1) << __FUNCTION__; | 378 DVLOG(1) << __FUNCTION__; |
| 374 mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; | 379 mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher; |
| 375 HRESULT hr = window_->get_Dispatcher(&dispatcher); | 380 HRESULT hr = window_->get_Dispatcher(&dispatcher); |
| 376 CheckHR(hr, "Dispatcher failed."); | 381 CheckHR(hr, "Dispatcher failed."); |
| 377 | 382 |
| 378 hr = window_->Activate(); | 383 hr = window_->Activate(); |
| 379 if (SUCCEEDED(hr)) { | 384 if (FAILED(hr)) { |
| 380 // TODO(cpu): Draw something here. | 385 DLOG(WARNING) << "activation failed hr=" << hr; |
| 381 } else { | 386 return hr; |
| 382 DVLOG(1) << "Activate failed, hr=" << hr; | |
| 383 } | 387 } |
| 384 | 388 |
| 385 // Create a message loop to allow message passing into this thread. | 389 // Create a message loop to allow message passing into this thread. |
| 386 MessageLoop msg_loop(MessageLoop::TYPE_UI); | 390 MessageLoop msg_loop(MessageLoop::TYPE_UI); |
| 387 | 391 |
| 388 // Create the IPC channel IO thread. It needs to out-live the ChannelProxy. | 392 // Create the IPC channel IO thread. It needs to out-live the ChannelProxy. |
| 389 base::Thread io_thread("metro_IO_thread"); | 393 base::Thread io_thread("metro_IO_thread"); |
| 390 base::Thread::Options options; | 394 base::Thread::Options options; |
| 391 options.message_loop_type = MessageLoop::TYPE_IO; | 395 options.message_loop_type = MessageLoop::TYPE_IO; |
| 392 io_thread.StartWithOptions(options); | 396 io_thread.StartWithOptions(options); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 403 | 407 |
| 404 // In Aura mode we create an IPC channel to the browser, then ask it to | 408 // In Aura mode we create an IPC channel to the browser, then ask it to |
| 405 // connect to us. | 409 // connect to us. |
| 406 ChromeChannelListener ui_channel_listener(&msg_loop, this); | 410 ChromeChannelListener ui_channel_listener(&msg_loop, this); |
| 407 IPC::ChannelProxy ui_channel(ipc_channel_name, | 411 IPC::ChannelProxy ui_channel(ipc_channel_name, |
| 408 IPC::Channel::MODE_NAMED_CLIENT, | 412 IPC::Channel::MODE_NAMED_CLIENT, |
| 409 &ui_channel_listener, | 413 &ui_channel_listener, |
| 410 io_thread.message_loop_proxy()); | 414 io_thread.message_loop_proxy()); |
| 411 ui_channel_ = &ui_channel; | 415 ui_channel_ = &ui_channel; |
| 412 | 416 |
| 417 // Upon receipt of the MetroViewerHostMsg_SetTargetSurface message the |
| 418 // browser will use D3D from the browser process to present to our Window. |
| 413 ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface( | 419 ui_channel_->Send(new MetroViewerHostMsg_SetTargetSurface( |
| 414 gfx::NativeViewId(globals.core_window))); | 420 gfx::NativeViewId(core_window_hwnd_))); |
| 415 DVLOG(1) << "ICoreWindow sent " << globals.core_window; | 421 DVLOG(1) << "ICoreWindow sent " << core_window_hwnd_; |
| 416 | 422 |
| 417 // And post the task that'll do the inner Metro message pumping to it. | 423 // And post the task that'll do the inner Metro message pumping to it. |
| 418 msg_loop.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); | 424 msg_loop.PostTask(FROM_HERE, base::Bind(&RunMessageLoop, dispatcher.Get())); |
| 419 msg_loop.Run(); | 425 msg_loop.Run(); |
| 420 | 426 |
| 421 DVLOG(0) << "ProcessEvents done, hr=" << hr; | 427 DVLOG(0) << "ProcessEvents done, hr=" << hr; |
| 422 return hr; | 428 return hr; |
| 423 } | 429 } |
| 424 | 430 |
| 425 IFACEMETHODIMP | 431 IFACEMETHODIMP |
| 426 ChromeAppViewAsh::Uninitialize() { | 432 ChromeAppViewAsh::Uninitialize() { |
| 427 DVLOG(1) << __FUNCTION__; | 433 DVLOG(1) << __FUNCTION__; |
| 428 window_ = nullptr; | 434 window_ = nullptr; |
| 429 view_ = nullptr; | 435 view_ = nullptr; |
| 436 core_window_hwnd_ = NULL; |
| 430 return S_OK; | 437 return S_OK; |
| 431 } | 438 } |
| 432 | 439 |
| 433 // static | 440 // static |
| 434 HRESULT ChromeAppViewAsh::Unsnap() { | 441 HRESULT ChromeAppViewAsh::Unsnap() { |
| 435 mswr::ComPtr<winui::ViewManagement::IApplicationViewStatics> view_statics; | 442 mswr::ComPtr<winui::ViewManagement::IApplicationViewStatics> view_statics; |
| 436 HRESULT hr = winrt_utils::CreateActivationFactory( | 443 HRESULT hr = winrt_utils::CreateActivationFactory( |
| 437 RuntimeClass_Windows_UI_ViewManagement_ApplicationView, | 444 RuntimeClass_Windows_UI_ViewManagement_ApplicationView, |
| 438 view_statics.GetAddressOf()); | 445 view_statics.GetAddressOf()); |
| 439 CheckHR(hr); | 446 CheckHR(hr); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 save_file_picker->result(), | 526 save_file_picker->result(), |
| 520 save_file_picker->filter_index())); | 527 save_file_picker->filter_index())); |
| 521 } | 528 } |
| 522 delete save_file_picker; | 529 delete save_file_picker; |
| 523 } | 530 } |
| 524 | 531 |
| 525 HRESULT ChromeAppViewAsh::OnActivate( | 532 HRESULT ChromeAppViewAsh::OnActivate( |
| 526 winapp::Core::ICoreApplicationView*, | 533 winapp::Core::ICoreApplicationView*, |
| 527 winapp::Activation::IActivatedEventArgs* args) { | 534 winapp::Activation::IActivatedEventArgs* args) { |
| 528 DVLOG(1) << __FUNCTION__; | 535 DVLOG(1) << __FUNCTION__; |
| 529 | 536 // Note: If doing more work in this function, you migth need to call |
| 537 // get_PreviousExecutionState() and skip the work if the result is |
| 538 // ApplicationExecutionState_Running and globals.previous_state is too. |
| 530 args->get_PreviousExecutionState(&globals.previous_state); | 539 args->get_PreviousExecutionState(&globals.previous_state); |
| 531 DVLOG(1) << "Previous Execution State: " << globals.previous_state; | 540 DVLOG(1) << "Previous Execution State: " << globals.previous_state; |
| 532 | 541 |
| 533 window_->Activate(); | 542 window_->Activate(); |
| 534 | |
| 535 if (globals.previous_state == | |
| 536 winapp::Activation::ApplicationExecutionState_Running) { | |
| 537 DVLOG(1) << "Already running. Skipping rest of OnActivate."; | |
| 538 return S_OK; | |
| 539 } | |
| 540 | |
| 541 globals.core_window = | |
| 542 winrt_utils::FindCoreWindow(globals.main_thread_id, 10); | |
| 543 return S_OK; | 543 return S_OK; |
| 544 } | 544 } |
| 545 | 545 |
| 546 HRESULT ChromeAppViewAsh::OnPointerMoved(winui::Core::ICoreWindow* sender, | 546 HRESULT ChromeAppViewAsh::OnPointerMoved(winui::Core::ICoreWindow* sender, |
| 547 winui::Core::IPointerEventArgs* args) { | 547 winui::Core::IPointerEventArgs* args) { |
| 548 PointerInfoHandler pointer; | 548 PointerInfoHandler pointer; |
| 549 HRESULT hr = pointer.Init(args); | 549 HRESULT hr = pointer.Init(args); |
| 550 if (FAILED(hr)) | 550 if (FAILED(hr)) |
| 551 return hr; | 551 return hr; |
| 552 | 552 |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 mswr::ComPtr<winapp::Core::ICoreApplicationExit> app_exit; | 764 mswr::ComPtr<winapp::Core::ICoreApplicationExit> app_exit; |
| 765 CheckHR(core_app.As(&app_exit)); | 765 CheckHR(core_app.As(&app_exit)); |
| 766 globals.app_exit = app_exit.Detach(); | 766 globals.app_exit = app_exit.Detach(); |
| 767 } | 767 } |
| 768 | 768 |
| 769 IFACEMETHODIMP | 769 IFACEMETHODIMP |
| 770 ChromeAppViewFactory::CreateView(winapp::Core::IFrameworkView** view) { | 770 ChromeAppViewFactory::CreateView(winapp::Core::IFrameworkView** view) { |
| 771 *view = mswr::Make<ChromeAppViewAsh>().Detach(); | 771 *view = mswr::Make<ChromeAppViewAsh>().Detach(); |
| 772 return (*view) ? S_OK : E_OUTOFMEMORY; | 772 return (*view) ? S_OK : E_OUTOFMEMORY; |
| 773 } | 773 } |
| OLD | NEW |