Windows should animate when they are about to get docked at screen edges.
[chromium-blink-merge.git] / win8 / delegate_execute / delegate_execute.cc
blob549716ac60d32cbfa62f1d0a66591267759ba3c7
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
3 // found in the LICENSE file.
5 #include "build/intsafe_workaround.h"
7 #include <atlbase.h>
8 #include <atlcom.h>
9 #include <atlctl.h>
10 #include <initguid.h>
11 #include <shellapi.h>
13 #include "base/at_exit.h"
14 #include "base/command_line.h"
15 #include "base/file_util.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/process/kill.h"
18 #include "base/strings/string16.h"
19 #include "base/win/scoped_com_initializer.h"
20 #include "base/win/scoped_handle.h"
21 #include "breakpad/src/client/windows/handler/exception_handler.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "win8/delegate_execute/command_execute_impl.h"
24 #include "win8/delegate_execute/crash_server_init.h"
25 #include "win8/delegate_execute/delegate_execute_operation.h"
26 #include "win8/delegate_execute/resource.h"
28 using namespace ATL;
30 class DelegateExecuteModule
31 : public ATL::CAtlExeModuleT< DelegateExecuteModule > {
32 public :
33 typedef ATL::CAtlExeModuleT<DelegateExecuteModule> ParentClass;
35 HRESULT RegisterServer(BOOL reg_type_lib) {
36 return ParentClass::RegisterServer(FALSE);
39 virtual HRESULT AddCommonRGSReplacements(IRegistrarBase* registrar) throw() {
40 AtlTrace(L"In %hs\n", __FUNCTION__);
41 HRESULT hr = ParentClass::AddCommonRGSReplacements(registrar);
42 if (FAILED(hr))
43 return hr;
45 wchar_t delegate_execute_clsid[MAX_PATH] = {0};
46 if (!StringFromGUID2(__uuidof(CommandExecuteImpl), delegate_execute_clsid,
47 ARRAYSIZE(delegate_execute_clsid))) {
48 ATLASSERT(false);
49 return E_FAIL;
52 hr = registrar->AddReplacement(L"DELEGATE_EXECUTE_CLSID",
53 delegate_execute_clsid);
54 ATLASSERT(SUCCEEDED(hr));
55 return hr;
59 DelegateExecuteModule _AtlModule;
61 using delegate_execute::DelegateExecuteOperation;
62 using base::win::ScopedHandle;
64 int RelaunchChrome(const DelegateExecuteOperation& operation) {
65 AtlTrace("Relaunching [%ls] with flags [%s]\n",
66 operation.mutex().c_str(), operation.relaunch_flags());
67 ScopedHandle mutex(OpenMutexW(SYNCHRONIZE, FALSE, operation.mutex().c_str()));
68 if (mutex.IsValid()) {
69 const int kWaitSeconds = 5;
70 DWORD result = ::WaitForSingleObject(mutex, kWaitSeconds * 1000);
71 if (result == WAIT_ABANDONED) {
72 // This is the normal case. Chrome exits and windows marks the mutex as
73 // abandoned.
74 } else if (result == WAIT_OBJECT_0) {
75 // This is unexpected. Check if somebody is not closing the mutex on
76 // RelaunchChromehelper, the mutex should not be closed.
77 AtlTrace("Unexpected release of the relaunch mutex!!\n");
78 } else if (result == WAIT_TIMEOUT) {
79 // This could mean that Chrome is hung. Proceed to exterminate.
80 DWORD pid = operation.GetParentPid();
81 AtlTrace("%ds timeout. Killing Chrome %d\n", kWaitSeconds, pid);
82 base::KillProcessById(pid, 0, false);
83 } else {
84 AtlTrace("Failed to wait for relaunch mutex, result is 0x%x\n", result);
86 } else {
87 // It is possible that chrome exits so fast that the mutex is not there.
88 AtlTrace("No relaunch mutex found\n");
91 base::win::ScopedCOMInitializer com_initializer;
93 string16 relaunch_flags(operation.relaunch_flags());
94 SHELLEXECUTEINFO sei = { sizeof(sei) };
95 sei.fMask = SEE_MASK_FLAG_LOG_USAGE;
96 sei.nShow = SW_SHOWNORMAL;
97 sei.lpFile = operation.shortcut().value().c_str();
98 sei.lpParameters = relaunch_flags.c_str();
100 AtlTrace(L"Relaunching Chrome via shortcut [%ls]\n", sei.lpFile);
102 if (!::ShellExecuteExW(&sei)) {
103 int error = HRESULT_FROM_WIN32(::GetLastError());
104 AtlTrace("ShellExecute returned 0x%08X\n", error);
105 return error;
107 return S_OK;
110 extern "C" int WINAPI _tWinMain(HINSTANCE , HINSTANCE, LPTSTR, int nShowCmd) {
111 scoped_ptr<google_breakpad::ExceptionHandler> breakpad =
112 delegate_execute::InitializeCrashReporting();
114 base::AtExitManager exit_manager;
115 AtlTrace("delegate_execute enter\n");
117 CommandLine::Init(0, NULL);
118 HRESULT ret_code = E_UNEXPECTED;
119 DelegateExecuteOperation operation;
120 if (operation.Init(CommandLine::ForCurrentProcess())) {
121 switch (operation.operation_type()) {
122 case DelegateExecuteOperation::DELEGATE_EXECUTE:
123 ret_code = _AtlModule.WinMain(nShowCmd);
124 break;
125 case DelegateExecuteOperation::RELAUNCH_CHROME:
126 ret_code = RelaunchChrome(operation);
127 break;
128 default:
129 NOTREACHED();
132 AtlTrace("delegate_execute exit, code = %d\n", ret_code);
133 return ret_code;