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

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

Issue 10895: Add Terminate() to the Process object, have RenderProcessHost use this to avo... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 1 month 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
« no previous file with comments | « chrome/browser/browser_main.cc ('k') | chrome/browser/greasemonkey_master.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 <windows.h> 5 #include <windows.h>
6 #include <shlobj.h> 6 #include <shlobj.h>
7 7
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "chrome/browser/first_run.h" 10 #include "chrome/browser/first_run.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 exe = L"Global\\" + exe; 199 exe = L"Global\\" + exe;
200 if (handle != NULL) 200 if (handle != NULL)
201 CloseHandle(handle); 201 CloseHandle(handle);
202 handle = CreateEvent(NULL, TRUE, TRUE, exe.c_str()); 202 handle = CreateEvent(NULL, TRUE, TRUE, exe.c_str());
203 int error = GetLastError(); 203 int error = GetLastError();
204 return (error == ERROR_ALREADY_EXISTS || error == ERROR_ACCESS_DENIED); 204 return (error == ERROR_ALREADY_EXISTS || error == ERROR_ACCESS_DENIED);
205 } 205 }
206 206
207 bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) { 207 bool Upgrade::RelaunchChromeBrowser(const CommandLine& command_line) {
208 ::SetEnvironmentVariable(google_update::kEnvProductVersionKey, NULL); 208 ::SetEnvironmentVariable(google_update::kEnvProductVersionKey, NULL);
209 return process_util::LaunchApp(command_line.command_line_string(), 209 return base::LaunchApp(command_line.command_line_string(),
210 false, false, NULL); 210 false, false, NULL);
211 } 211 }
212 212
213 bool Upgrade::SwapNewChromeExeIfPresent() { 213 bool Upgrade::SwapNewChromeExeIfPresent() {
214 std::wstring new_chrome_exe; 214 std::wstring new_chrome_exe;
215 if (!GetNewerChromeFile(&new_chrome_exe)) 215 if (!GetNewerChromeFile(&new_chrome_exe))
216 return false; 216 return false;
217 if (!file_util::PathExists(new_chrome_exe)) 217 if (!file_util::PathExists(new_chrome_exe))
218 return false; 218 return false;
219 std::wstring old_chrome_exe; 219 std::wstring old_chrome_exe;
220 if (!PathService::Get(base::FILE_EXE, &old_chrome_exe)) 220 if (!PathService::Get(base::FILE_EXE, &old_chrome_exe))
221 return false; 221 return false;
222 RegKey key; 222 RegKey key;
223 HKEY reg_root = InstallUtil::IsPerUserInstall(old_chrome_exe.c_str()) ? 223 HKEY reg_root = InstallUtil::IsPerUserInstall(old_chrome_exe.c_str()) ?
224 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE; 224 HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
225 BrowserDistribution *dist = BrowserDistribution::GetDistribution(); 225 BrowserDistribution *dist = BrowserDistribution::GetDistribution();
226 std::wstring rename_cmd; 226 std::wstring rename_cmd;
227 if (key.Open(reg_root, dist->GetVersionKey().c_str(), KEY_READ) && 227 if (key.Open(reg_root, dist->GetVersionKey().c_str(), KEY_READ) &&
228 key.ReadValue(google_update::kRegRenameCmdField, &rename_cmd)) { 228 key.ReadValue(google_update::kRegRenameCmdField, &rename_cmd)) {
229 ProcessHandle handle; 229 base::ProcessHandle handle;
230 if (process_util::LaunchApp(rename_cmd, true, true, &handle)) { 230 if (base::LaunchApp(rename_cmd, true, true, &handle)) {
231 DWORD exit_code; 231 DWORD exit_code;
232 ::GetExitCodeProcess(handle, &exit_code); 232 ::GetExitCodeProcess(handle, &exit_code);
233 ::CloseHandle(handle); 233 ::CloseHandle(handle);
234 if (exit_code == installer_util::RENAME_SUCCESSFUL) 234 if (exit_code == installer_util::RENAME_SUCCESSFUL)
235 return true; 235 return true;
236 } 236 }
237 } 237 }
238 std::wstring backup_exe; 238 std::wstring backup_exe;
239 if (!GetBackupChromeFile(&backup_exe)) 239 if (!GetBackupChromeFile(&backup_exe))
240 return false; 240 return false;
(...skipping 19 matching lines...) Expand all
260 260
261 // This class is used by FirstRun::ImportSettings to determine when the import 261 // This class is used by FirstRun::ImportSettings to determine when the import
262 // process has ended and what was the result of the operation as reported by 262 // process has ended and what was the result of the operation as reported by
263 // the process exit code. This class executes in the context of the main chrome 263 // the process exit code. This class executes in the context of the main chrome
264 // process. 264 // process.
265 class ImportProcessRunner : public base::ObjectWatcher::Delegate { 265 class ImportProcessRunner : public base::ObjectWatcher::Delegate {
266 public: 266 public:
267 // The constructor takes the importer process to watch and then it does a 267 // The constructor takes the importer process to watch and then it does a
268 // message loop blocking wait until the process ends. This object now owns 268 // message loop blocking wait until the process ends. This object now owns
269 // the import_process handle. 269 // the import_process handle.
270 explicit ImportProcessRunner(ProcessHandle import_process) 270 explicit ImportProcessRunner(base::ProcessHandle import_process)
271 : import_process_(import_process), 271 : import_process_(import_process),
272 exit_code_(ResultCodes::NORMAL_EXIT) { 272 exit_code_(ResultCodes::NORMAL_EXIT) {
273 watcher_.StartWatching(import_process, this); 273 watcher_.StartWatching(import_process, this);
274 MessageLoop::current()->Run(); 274 MessageLoop::current()->Run();
275 } 275 }
276 virtual ~ImportProcessRunner() { 276 virtual ~ImportProcessRunner() {
277 ::CloseHandle(import_process_); 277 ::CloseHandle(import_process_);
278 } 278 }
279 // Returns the child process exit code. There are 3 expected values: 279 // Returns the child process exit code. There are 3 expected values:
280 // NORMAL_EXIT, IMPORTER_CANCEL or IMPORTER_HUNG. 280 // NORMAL_EXIT, IMPORTER_CANCEL or IMPORTER_HUNG.
281 int exit_code() const { 281 int exit_code() const {
282 return exit_code_; 282 return exit_code_;
283 } 283 }
284 // The child process has terminated. Find the exit code and quit the loop. 284 // The child process has terminated. Find the exit code and quit the loop.
285 virtual void OnObjectSignaled(HANDLE object) { 285 virtual void OnObjectSignaled(HANDLE object) {
286 DCHECK(object == import_process_); 286 DCHECK(object == import_process_);
287 if (!::GetExitCodeProcess(import_process_, &exit_code_)) { 287 if (!::GetExitCodeProcess(import_process_, &exit_code_)) {
288 NOTREACHED(); 288 NOTREACHED();
289 } 289 }
290 MessageLoop::current()->Quit(); 290 MessageLoop::current()->Quit();
291 } 291 }
292 292
293 private: 293 private:
294 base::ObjectWatcher watcher_; 294 base::ObjectWatcher watcher_;
295 ProcessHandle import_process_; 295 base::ProcessHandle import_process_;
296 DWORD exit_code_; 296 DWORD exit_code_;
297 }; 297 };
298 298
299 // Check every 3 seconds if the importer UI has hung. 299 // Check every 3 seconds if the importer UI has hung.
300 const int kPollHangFrequency = 3000; 300 const int kPollHangFrequency = 3000;
301 301
302 // This class specializes on finding hung 'owned' windows. Unfortunately, the 302 // This class specializes on finding hung 'owned' windows. Unfortunately, the
303 // HungWindowDetector class cannot be used here because it assumes child 303 // HungWindowDetector class cannot be used here because it assumes child
304 // windows and not owned top-level windows. 304 // windows and not owned top-level windows.
305 // This code is executed in the context of the main browser process and will 305 // This code is executed in the context of the main browser process and will
306 // terminate the importer process if it is hung. 306 // terminate the importer process if it is hung.
307 class HungImporterMonitor : public WorkerThreadTicker::Callback { 307 class HungImporterMonitor : public WorkerThreadTicker::Callback {
308 public: 308 public:
309 // The ctor takes the owner popup window and the process handle of the 309 // The ctor takes the owner popup window and the process handle of the
310 // process to kill in case the popup or its owned active popup become 310 // process to kill in case the popup or its owned active popup become
311 // unresponsive. 311 // unresponsive.
312 HungImporterMonitor(HWND owner_window, ProcessHandle import_process) 312 HungImporterMonitor(HWND owner_window, base::ProcessHandle import_process)
313 : owner_window_(owner_window), 313 : owner_window_(owner_window),
314 import_process_(import_process), 314 import_process_(import_process),
315 ticker_(kPollHangFrequency) { 315 ticker_(kPollHangFrequency) {
316 ticker_.RegisterTickHandler(this); 316 ticker_.RegisterTickHandler(this);
317 ticker_.Start(); 317 ticker_.Start();
318 } 318 }
319 virtual ~HungImporterMonitor() { 319 virtual ~HungImporterMonitor() {
320 ticker_.Stop(); 320 ticker_.Stop();
321 ticker_.UnregisterTickHandler(this); 321 ticker_.UnregisterTickHandler(this);
322 } 322 }
323 323
324 private: 324 private:
325 virtual void OnTick() { 325 virtual void OnTick() {
326 if (!import_process_) 326 if (!import_process_)
327 return; 327 return;
328 // We find the top active popup that we own, this will be either the 328 // We find the top active popup that we own, this will be either the
329 // owner_window_ itself or the dialog window of the other process. In 329 // owner_window_ itself or the dialog window of the other process. In
330 // both cases it is worth hung testing because both windows share the 330 // both cases it is worth hung testing because both windows share the
331 // same message queue and at some point the other window could be gone 331 // same message queue and at some point the other window could be gone
332 // while the other process still not pumping messages. 332 // while the other process still not pumping messages.
333 HWND active_window = ::GetLastActivePopup(owner_window_); 333 HWND active_window = ::GetLastActivePopup(owner_window_);
334 if (::IsHungAppWindow(active_window) || ::IsHungAppWindow(owner_window_)) { 334 if (::IsHungAppWindow(active_window) || ::IsHungAppWindow(owner_window_)) {
335 ::TerminateProcess(import_process_, ResultCodes::IMPORTER_HUNG); 335 ::TerminateProcess(import_process_, ResultCodes::IMPORTER_HUNG);
336 import_process_ = NULL; 336 import_process_ = NULL;
337 } 337 }
338 } 338 }
339 339
340 HWND owner_window_; 340 HWND owner_window_;
341 ProcessHandle import_process_; 341 base::ProcessHandle import_process_;
342 WorkerThreadTicker ticker_; 342 WorkerThreadTicker ticker_;
343 DISALLOW_EVIL_CONSTRUCTORS(HungImporterMonitor); 343 DISALLOW_EVIL_CONSTRUCTORS(HungImporterMonitor);
344 }; 344 };
345 345
346 // This class is used by FirstRun::ImportNow to get notified of the outcome of 346 // This class is used by FirstRun::ImportNow to get notified of the outcome of
347 // the import operation. It differs from ImportProcessRunner in that this 347 // the import operation. It differs from ImportProcessRunner in that this
348 // class executes in the context of importing child process. 348 // class executes in the context of importing child process.
349 // The values that it handles are meant to be used as the process exit code. 349 // The values that it handles are meant to be used as the process exit code.
350 class FirstRunImportObserver : public ImportObserver { 350 class FirstRunImportObserver : public ImportObserver {
351 public: 351 public:
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 if (cmdline.HasSwitch(switch_names[i])) { 411 if (cmdline.HasSwitch(switch_names[i])) {
412 CommandLine::AppendSwitchWithValue( 412 CommandLine::AppendSwitchWithValue(
413 &import_cmd, switch_names[i], 413 &import_cmd, switch_names[i],
414 cmdline.GetSwitchValue(switch_names[i])); 414 cmdline.GetSwitchValue(switch_names[i]));
415 } 415 }
416 } 416 }
417 CommandLine::AppendSwitchWithValue(&import_cmd, switches::kImport, 417 CommandLine::AppendSwitchWithValue(&import_cmd, switches::kImport,
418 EncodeImportParams(browser, items_to_import, parent_window)); 418 EncodeImportParams(browser, items_to_import, parent_window));
419 419
420 // Time to launch the process that is going to do the import. 420 // Time to launch the process that is going to do the import.
421 ProcessHandle import_process; 421 base::ProcessHandle import_process;
422 if (!process_util::LaunchApp(import_cmd, false, false, &import_process)) 422 if (!base::LaunchApp(import_cmd, false, false, &import_process))
423 return false; 423 return false;
424 424
425 // Activate the importer monitor. It awakes periodically in another thread 425 // Activate the importer monitor. It awakes periodically in another thread
426 // and checks that the importer UI is still pumping messages. 426 // and checks that the importer UI is still pumping messages.
427 if (parent_window) 427 if (parent_window)
428 HungImporterMonitor hang_monitor(parent_window, import_process); 428 HungImporterMonitor hang_monitor(parent_window, import_process);
429 429
430 // We block inside the import_runner ctor, pumping messages until the 430 // We block inside the import_runner ctor, pumping messages until the
431 // importer process ends. This can happen either by completing the import 431 // importer process ends. This can happen either by completing the import
432 // or by hang_monitor killing it. 432 // or by hang_monitor killing it.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 bool FirstRun::SetShowWelcomePagePref() { 489 bool FirstRun::SetShowWelcomePagePref() {
490 PrefService* local_state = g_browser_process->local_state(); 490 PrefService* local_state = g_browser_process->local_state();
491 if (!local_state) 491 if (!local_state)
492 return false; 492 return false;
493 if (!local_state->IsPrefRegistered(prefs::kShouldShowWelcomePage)) { 493 if (!local_state->IsPrefRegistered(prefs::kShouldShowWelcomePage)) {
494 local_state->RegisterBooleanPref(prefs::kShouldShowWelcomePage, false); 494 local_state->RegisterBooleanPref(prefs::kShouldShowWelcomePage, false);
495 local_state->SetBoolean(prefs::kShouldShowWelcomePage, true); 495 local_state->SetBoolean(prefs::kShouldShowWelcomePage, true);
496 } 496 }
497 return true; 497 return true;
498 } 498 }
OLDNEW
« no previous file with comments | « chrome/browser/browser_main.cc ('k') | chrome/browser/greasemonkey_master.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698