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

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

Issue 9968053: Refactor ProcessSingleton so that it may be used distinctly from a full browser process. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix comment nits. Created 8 years, 8 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
« no previous file with comments | « chrome/browser/process_singleton_mac_unittest.cc ('k') | no next file » | 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) 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/process_singleton.h" 5 #include "chrome/browser/process_singleton.h"
6 6
7 #include "base/base_paths.h" 7 #include "base/base_paths.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
11 #include "base/process_util.h" 11 #include "base/process_util.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "base/win/scoped_handle.h" 13 #include "base/win/scoped_handle.h"
14 #include "base/win/wrapped_window_proc.h" 14 #include "base/win/wrapped_window_proc.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/extensions/extensions_startup.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/simple_message_box.h" 15 #include "chrome/browser/simple_message_box.h"
20 #include "chrome/browser/ui/browser_init.h"
21 #include "chrome/common/chrome_constants.h" 16 #include "chrome/common/chrome_constants.h"
22 #include "chrome/common/chrome_paths.h"
23 #include "chrome/common/chrome_switches.h"
24 #include "chrome/installer/util/wmi.h" 17 #include "chrome/installer/util/wmi.h"
25 #include "content/public/common/result_codes.h" 18 #include "content/public/common/result_codes.h"
26 #include "grit/chromium_strings.h" 19 #include "grit/chromium_strings.h"
27 #include "grit/generated_resources.h" 20 #include "grit/generated_resources.h"
28 #include "ui/base/l10n/l10n_util.h" 21 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/base/win/hwnd_util.h" 22 #include "ui/base/win/hwnd_util.h"
30 23
31 namespace { 24 namespace {
32 25
33 // Checks the visibility of the enumerated window and signals once a visible 26 // Checks the visibility of the enumerated window and signals once a visible
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 HINSTANCE hinst = base::GetModuleFromAddress(&ThunkWndProc); 179 HINSTANCE hinst = base::GetModuleFromAddress(&ThunkWndProc);
187 180
188 WNDCLASSEX wc = {0}; 181 WNDCLASSEX wc = {0};
189 wc.cbSize = sizeof(wc); 182 wc.cbSize = sizeof(wc);
190 wc.lpfnWndProc = base::win::WrappedWindowProc<ThunkWndProc>; 183 wc.lpfnWndProc = base::win::WrappedWindowProc<ThunkWndProc>;
191 wc.hInstance = hinst; 184 wc.hInstance = hinst;
192 wc.lpszClassName = chrome::kMessageWindowClass; 185 wc.lpszClassName = chrome::kMessageWindowClass;
193 ATOM clazz = ::RegisterClassEx(&wc); 186 ATOM clazz = ::RegisterClassEx(&wc);
194 DCHECK(clazz); 187 DCHECK(clazz);
195 188
196 FilePath user_data_dir;
197 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
198
199 // Set the window's title to the path of our user data directory so other 189 // Set the window's title to the path of our user data directory so other
200 // Chrome instances can decide if they should forward to us or not. 190 // Chrome instances can decide if they should forward to us or not.
201 window_ = ::CreateWindow(MAKEINTATOM(clazz), 191 window_ = ::CreateWindow(MAKEINTATOM(clazz),
202 user_data_dir.value().c_str(), 192 user_data_dir.value().c_str(),
203 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, this); 193 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, this);
204 CHECK(window_); 194 CHECK(window_);
205 } 195 }
206 BOOL success = ReleaseMutex(only_me); 196 BOOL success = ReleaseMutex(only_me);
207 DCHECK(success) << "GetLastError = " << GetLastError(); 197 DCHECK(success) << "GetLastError = " << GetLastError();
208 } 198 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 return PROCESS_NOTIFIED; 272 return PROCESS_NOTIFIED;
283 } 273 }
284 } 274 }
285 275
286 // Time to take action. Kill the browser process. 276 // Time to take action. Kill the browser process.
287 base::KillProcessById(process_id, content::RESULT_CODE_HUNG, true); 277 base::KillProcessById(process_id, content::RESULT_CODE_HUNG, true);
288 remote_window_ = NULL; 278 remote_window_ = NULL;
289 return PROCESS_NONE; 279 return PROCESS_NONE;
290 } 280 }
291 281
292 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() { 282 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate(
283 const NotificationCallback& notification_callback) {
293 NotifyResult result = NotifyOtherProcess(); 284 NotifyResult result = NotifyOtherProcess();
294 if (result != PROCESS_NONE) 285 if (result != PROCESS_NONE)
295 return result; 286 return result;
296 return window_ ? PROCESS_NONE : PROFILE_IN_USE; 287 return Create(notification_callback) ? PROCESS_NONE : PROFILE_IN_USE;
297 } 288 }
298 289
299 // On Windows, there is no need to call Create() since the message 290 // On Windows, there is no need to call Create() since the message
300 // window is created in the constructor but to avoid having more 291 // window is created in the constructor but to avoid having more
301 // platform specific code in browser_main.cc we tolerate calls to 292 // platform specific code in browser_main.cc we tolerate calls to
302 // Create(), which will do nothing. 293 // Create().
303 bool ProcessSingleton::Create() { 294 bool ProcessSingleton::Create(
295 const NotificationCallback& notification_callback) {
304 DCHECK(!remote_window_); 296 DCHECK(!remote_window_);
297 DCHECK(notification_callback_.is_null());
298
299 if (window_ != NULL)
300 notification_callback_ = notification_callback;
301
305 return window_ != NULL; 302 return window_ != NULL;
306 } 303 }
307 304
308 void ProcessSingleton::Cleanup() { 305 void ProcessSingleton::Cleanup() {
309 // Window classes registered by DLLs are not cleaned up automatically on 306 // Window classes registered by DLLs are not cleaned up automatically on
310 // process exit, so we must unregister at the earliest chance possible. 307 // process exit, so we must unregister at the earliest chance possible.
311 // During the fast shutdown sequence, ProcessSingleton::Cleanup() is 308 // During the fast shutdown sequence, ProcessSingleton::Cleanup() is
312 // called if our process was the first to start. Therefore we try cleaning 309 // called if our process was the first to start. Therefore we try cleaning
313 // up here, and again in the destructor if needed to catch as many cases 310 // up here, and again in the destructor if needed to catch as many cases
314 // as possible. 311 // as possible.
(...skipping 21 matching lines...) Expand all
336 CommandLine parsed_command_line(CommandLine::NO_PROGRAM); 333 CommandLine parsed_command_line(CommandLine::NO_PROGRAM);
337 FilePath current_directory; 334 FilePath current_directory;
338 if (ParseCommandLine(cds, &parsed_command_line, &current_directory)) 335 if (ParseCommandLine(cds, &parsed_command_line, &current_directory))
339 saved_startup_messages_.push_back( 336 saved_startup_messages_.push_back(
340 std::make_pair(parsed_command_line.argv(), current_directory)); 337 std::make_pair(parsed_command_line.argv(), current_directory));
341 } 338 }
342 #endif 339 #endif
343 return TRUE; 340 return TRUE;
344 } 341 }
345 342
346 // Ignore the request if the browser process is already in shutdown path.
347 if (!g_browser_process || g_browser_process->IsShuttingDown()) {
348 LOG(WARNING) << "Not handling WM_COPYDATA as browser is shutting down";
349 return FALSE;
350 }
351
352 CommandLine parsed_command_line(CommandLine::NO_PROGRAM); 343 CommandLine parsed_command_line(CommandLine::NO_PROGRAM);
353 FilePath current_directory; 344 FilePath current_directory;
354 if (!ParseCommandLine(cds, &parsed_command_line, &current_directory)) 345 if (!ParseCommandLine(cds, &parsed_command_line, &current_directory))
355 return TRUE; 346 return TRUE;
356 ProcessCommandLine(parsed_command_line, current_directory); 347 return notification_callback_.Run(parsed_command_line, current_directory) ?
357 return TRUE; 348 TRUE : FALSE;
358 } 349 }
359 350
360 LRESULT ProcessSingleton::WndProc(HWND hwnd, UINT message, 351 LRESULT ProcessSingleton::WndProc(HWND hwnd, UINT message,
361 WPARAM wparam, LPARAM lparam) { 352 WPARAM wparam, LPARAM lparam) {
362 switch (message) { 353 switch (message) {
363 case WM_COPYDATA: 354 case WM_COPYDATA:
364 return OnCopyData(reinterpret_cast<HWND>(wparam), 355 return OnCopyData(reinterpret_cast<HWND>(wparam),
365 reinterpret_cast<COPYDATASTRUCT*>(lparam)); 356 reinterpret_cast<COPYDATASTRUCT*>(lparam));
366 default: 357 default:
367 break; 358 break;
368 } 359 }
369 360
370 return ::DefWindowProc(hwnd, message, wparam, lparam); 361 return ::DefWindowProc(hwnd, message, wparam, lparam);
371 } 362 }
372
373 void ProcessSingleton::ProcessCommandLine(const CommandLine& command_line,
374 const FilePath& current_directory) {
375 PrefService* prefs = g_browser_process->local_state();
376 DCHECK(prefs);
377
378 // Handle the --uninstall-extension startup action. This needs to done here
379 // in the process that is running with the target profile, otherwise the
380 // uninstall will fail to unload and remove all components.
381 if (command_line.HasSwitch(switches::kUninstallExtension)) {
382 // The uninstall extension switch can't be combined with the profile
383 // directory switch.
384 DCHECK(!command_line.HasSwitch(switches::kProfileDirectory));
385
386 Profile* profile = ProfileManager::GetLastUsedProfile();
387 if (!profile) {
388 // We should only be able to get here if the profile already exists and
389 // has been created.
390 NOTREACHED();
391 return;
392 }
393
394 ExtensionsStartupUtil ext_startup_util;
395 ext_startup_util.UninstallExtension(command_line, profile);
396 return;
397 }
398
399 // Run the browser startup sequence again, with the command line of the
400 // signalling process.
401 BrowserInit::ProcessCommandLineAlreadyRunning(command_line,
402 current_directory);
403 }
OLDNEW
« no previous file with comments | « chrome/browser/process_singleton_mac_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698