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

Side by Side Diff: chrome/browser/first_run/upgrade_util_win.cc

Issue 10885047: Metro mode switching (chrome side) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "chrome/browser/first_run/upgrade_util.h" 5 #include "chrome/browser/first_run/upgrade_util.h"
6 6
7 #include <windows.h>
8 #include <shellapi.h>
9
7 #include <algorithm> 10 #include <algorithm>
8 #include <string> 11 #include <string>
9 12
10 #include "base/base_paths.h" 13 #include "base/base_paths.h"
11 #include "base/command_line.h" 14 #include "base/command_line.h"
12 #include "base/environment.h" 15 #include "base/environment.h"
13 #include "base/file_path.h" 16 #include "base/file_path.h"
14 #include "base/file_util.h" 17 #include "base/file_util.h"
15 #include "base/logging.h" 18 #include "base/logging.h"
16 #include "base/path_service.h" 19 #include "base/path_service.h"
17 #include "base/process_util.h" 20 #include "base/process_util.h"
18 #include "base/string_number_conversions.h" 21 #include "base/string_number_conversions.h"
19 #include "base/string_util.h" 22 #include "base/string_util.h"
23 #include "base/stringprintf.h"
20 #include "base/win/metro.h" 24 #include "base/win/metro.h"
21 #include "base/win/registry.h" 25 #include "base/win/registry.h"
22 #include "base/win/scoped_comptr.h" 26 #include "base/win/scoped_comptr.h"
27 #include "base/win/windows_version.h"
23 #include "chrome/browser/first_run/upgrade_util_win.h" 28 #include "chrome/browser/first_run/upgrade_util_win.h"
24 #include "chrome/browser/shell_integration.h" 29 #include "chrome/browser/shell_integration.h"
25 #include "chrome/common/chrome_constants.h" 30 #include "chrome/common/chrome_constants.h"
26 #include "chrome/common/chrome_switches.h" 31 #include "chrome/common/chrome_switches.h"
27 #include "chrome/installer/util/browser_distribution.h" 32 #include "chrome/installer/util/browser_distribution.h"
28 #include "chrome/installer/util/google_update_constants.h" 33 #include "chrome/installer/util/google_update_constants.h"
29 #include "chrome/installer/util/install_util.h" 34 #include "chrome/installer/util/install_util.h"
30 #include "chrome/installer/util/shell_util.h" 35 #include "chrome/installer/util/shell_util.h"
31 #include "chrome/installer/util/util_constants.h" 36 #include "chrome/installer/util/util_constants.h"
32 #include "google_update/google_update_idl.h" 37 #include "google_update/google_update_idl.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 if (!version_str.empty()) 77 if (!version_str.empty())
73 path = path.AppendASCII(version_str); 78 path = path.AppendASCII(version_str);
74 79
75 return path.Append(installer::kDelegateExecuteExe); 80 return path.Append(installer::kDelegateExecuteExe);
76 } 81 }
77 82
78 } // namespace 83 } // namespace
79 84
80 namespace upgrade_util { 85 namespace upgrade_util {
81 86
82 bool RelaunchChromeBrowser(const CommandLine& command_line) { 87 bool RelaunchChromehelper(const CommandLine& command_line, bool mode_switch) {
83 scoped_ptr<base::Environment> env(base::Environment::Create()); 88 scoped_ptr<base::Environment> env(base::Environment::Create());
84 std::string version_str; 89 std::string version_str;
85 90
86 // Get the version variable and remove it from the environment. 91 // Get the version variable and remove it from the environment.
87 if (env->GetVar(chrome::kChromeVersionEnvVar, &version_str)) 92 if (env->GetVar(chrome::kChromeVersionEnvVar, &version_str))
88 env->UnSetVar(chrome::kChromeVersionEnvVar); 93 env->UnSetVar(chrome::kChromeVersionEnvVar);
89 else 94 else
90 version_str.clear(); 95 version_str.clear();
91 96
92 if (!base::win::IsMetroProcess()) 97 if (base::win::GetVersion() < base::win::VERSION_WIN8)
93 return base::LaunchProcess(command_line, base::LaunchOptions(), NULL); 98 return base::LaunchProcess(command_line, base::LaunchOptions(), NULL);
94 99
95 // Pass this Chrome's Start Menu shortcut path and handle to the relauncher. 100 // On Windows 8 we always use the delegate_execute for re-launching chrome.
96 // The relauncher will wait for this Chrome to exit then reactivate it by 101 //
97 // way of the Start Menu shortcut. 102 // Pass this Chrome's Start Menu shortcut path to the relauncher so it can
103 // re-activate chrome via ShellExecute.
98 FilePath chrome_exe; 104 FilePath chrome_exe;
99 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { 105 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
100 NOTREACHED(); 106 NOTREACHED();
101 return false; 107 return false;
102 } 108 }
103 109
104 // Get a handle to this process that can be passed to the relauncher. 110 // We need to use ShellExecute to launch the relauncher, which will wait until
105 HANDLE current_process = GetCurrentProcess(); 111 // we exit. But ShellExecute does not support handle passing to the child
106 base::win::ScopedHandle process_handle; 112 // process so we create a uniquely named mutex that we aquire and never
107 if (!::DuplicateHandle(current_process, current_process, current_process, 113 // release. So when we exit, Windows marks our mutex as abandoned and the
108 process_handle.Receive(), SYNCHRONIZE, TRUE, 0)) { 114 // wait is satisfied.
109 DPCHECK(false); 115 // The format of the named mutex is important. See DelegateExecuteOperation
116 // for more details.
117 string16 mutex_name =
118 base::StringPrintf(L"chrome.relaunch.%d", ::GetCurrentProcessId());
119 HANDLE mutex = ::CreateMutexW(NULL, TRUE, mutex_name.c_str());
120 // The |mutex| handle needs to be leaked. See comment above.
121 if (!mutex) {
122 NOTREACHED();
123 return false;
124 }
125 if (::GetLastError() == ERROR_ALREADY_EXISTS) {
126 NOTREACHED() << "Relaunch mutex already exists";
110 return false; 127 return false;
111 } 128 }
112 129
113 // Make the command line for the relauncher. 130 CommandLine relaunch_cmd(CommandLine::NO_PROGRAM);
114 CommandLine relaunch_cmd(GetMetroRelauncherPath(chrome_exe, version_str));
115 relaunch_cmd.AppendSwitchPath(switches::kRelaunchShortcut, 131 relaunch_cmd.AppendSwitchPath(switches::kRelaunchShortcut,
116 ShellIntegration::GetStartMenuShortcut(chrome_exe)); 132 ShellIntegration::GetStartMenuShortcut(chrome_exe));
117 relaunch_cmd.AppendSwitchNative(switches::kWaitForHandle, 133 relaunch_cmd.AppendSwitchNative(switches::kWaitForMutex, mutex_name);
118 base::UintToString16(reinterpret_cast<uint32>(process_handle.Get())));
119 134
120 base::LaunchOptions launch_options; 135 const char* flag;
121 launch_options.inherit_handles = true; 136 if (base::win::IsMetroProcess())
122 if (!base::LaunchProcess(relaunch_cmd, launch_options, NULL)) { 137 flag = mode_switch ? switches::kForceDesktop : switches::kForceImmersive;
123 DPLOG(ERROR) << "Failed to launch relauncher \"" 138 else
124 << relaunch_cmd.GetCommandLineString() << "\""; 139 flag = mode_switch ? switches::kForceImmersive : switches::kForceDesktop;
140 relaunch_cmd.AppendSwitch(flag);
141
142 string16 params(relaunch_cmd.GetCommandLineString());
143 string16 path(GetMetroRelauncherPath(chrome_exe, version_str).value());
144
145 SHELLEXECUTEINFO sei = { sizeof(sei) };
146 sei.fMask = SEE_MASK_FLAG_LOG_USAGE | SEE_MASK_NOCLOSEPROCESS;
147 sei.nShow = SW_SHOWNORMAL;
148 sei.lpFile = path.c_str();
149 sei.lpParameters = params.c_str();
150
151 if (!::ShellExecuteExW(&sei)) {
152 NOTREACHED() << "ShellExecute failed with " << GetLastError();
125 return false; 153 return false;
126 } 154 }
155 DWORD pid = ::GetProcessId(sei.hProcess);
156 CloseHandle(sei.hProcess);
157 if (!pid)
158 return false;
159 // The next call appears to be needed if we are relaunching from desktop into
160 // metro mode. The observed effect if not done is that chrome starts in metro
161 // mode but it is not given focus and it gets killed by windows after a few
162 // seconds.
163 ::AllowSetForegroundWindow(pid);
164 return true;
165 }
127 166
128 return true; 167 bool RelaunchChromeBrowser(const CommandLine& command_line) {
168 return RelaunchChromehelper(command_line, false);
169 }
170
171 bool RelaunchChromeWithModeSwitch(const CommandLine& command_line) {
172 return RelaunchChromehelper(command_line, true);
129 } 173 }
130 174
131 bool IsUpdatePendingRestart() { 175 bool IsUpdatePendingRestart() {
132 FilePath new_chrome_exe; 176 FilePath new_chrome_exe;
133 if (!GetNewerChromeFile(&new_chrome_exe)) 177 if (!GetNewerChromeFile(&new_chrome_exe))
134 return false; 178 return false;
135 return file_util::PathExists(new_chrome_exe); 179 return file_util::PathExists(new_chrome_exe);
136 } 180 }
137 181
138 bool SwapNewChromeExeIfPresent() { 182 bool SwapNewChromeExeIfPresent() {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 return false; 252 return false;
209 // At this point the chrome.exe has been swapped with the new one. 253 // At this point the chrome.exe has been swapped with the new one.
210 if (!RelaunchChromeBrowser(command_line)) { 254 if (!RelaunchChromeBrowser(command_line)) {
211 // The re-launch fails. Feel free to panic now. 255 // The re-launch fails. Feel free to panic now.
212 NOTREACHED(); 256 NOTREACHED();
213 } 257 }
214 return true; 258 return true;
215 } 259 }
216 260
217 } // namespace upgrade_util 261 } // namespace upgrade_util
OLDNEW
« no previous file with comments | « chrome/browser/first_run/upgrade_util.h ('k') | chrome/browser/ui/browser_command_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698