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

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

Powered by Google App Engine
This is Rietveld 408576698