Support SizeClassIdiom on iOS7.
[chromium-blink-merge.git] / chrome / app / chrome_watcher_command_line_win.cc
blob1e576261e5c6dd60e9681328ff1f2b6429f020ce
1 // Copyright (c) 2014 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 "chrome/app/chrome_watcher_command_line_win.h"
7 #include <string>
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/stringprintf.h"
14 #include "chrome/common/chrome_switches.h"
16 namespace {
18 const char kOnIninitializedEventHandleSwitch[] = "on-initialized-event-handle";
19 const char kParentHandleSwitch[] = "parent-handle";
20 const char kMainThreadIdSwitch[] = "main-thread-id";
22 void AppendHandleSwitch(const std::string& switch_name,
23 HANDLE handle,
24 base::CommandLine* command_line) {
25 command_line->AppendSwitchASCII(
26 switch_name, base::UintToString(reinterpret_cast<uint32_t>(handle)));
29 uint32_t ReadUintSwitch(const base::CommandLine& command_line,
30 const std::string& switch_name) {
31 std::string switch_string = command_line.GetSwitchValueASCII(switch_name);
32 unsigned int switch_uint = 0;
33 if (switch_string.empty() ||
34 !base::StringToUint(switch_string, &switch_uint)) {
35 DLOG(ERROR) << "Missing or invalid " << switch_name << " argument.";
36 return 0;
38 return switch_uint;
41 HANDLE ReadHandleFromSwitch(const base::CommandLine& command_line,
42 const std::string& switch_name) {
43 return reinterpret_cast<HANDLE>(ReadUintSwitch(command_line, switch_name));
46 } // namespace
48 base::CommandLine GenerateChromeWatcherCommandLine(
49 const base::FilePath& chrome_exe,
50 HANDLE parent_process,
51 DWORD main_thread_id,
52 HANDLE on_initialized_event) {
53 base::CommandLine command_line(chrome_exe);
54 command_line.AppendSwitchASCII(switches::kProcessType, "watcher");
55 command_line.AppendSwitchASCII(kMainThreadIdSwitch,
56 base::UintToString(main_thread_id));
57 AppendHandleSwitch(kOnIninitializedEventHandleSwitch, on_initialized_event,
58 &command_line);
59 AppendHandleSwitch(kParentHandleSwitch, parent_process, &command_line);
60 return command_line;
63 bool InterpretChromeWatcherCommandLine(
64 const base::CommandLine& command_line,
65 base::win::ScopedHandle* parent_process,
66 DWORD* main_thread_id,
67 base::win::ScopedHandle* on_initialized_event) {
68 DCHECK(on_initialized_event);
69 DCHECK(parent_process);
71 // For consistency, always close any existing HANDLEs here.
72 on_initialized_event->Close();
73 parent_process->Close();
75 HANDLE parent_handle =
76 ReadHandleFromSwitch(command_line, kParentHandleSwitch);
77 HANDLE on_initialized_event_handle =
78 ReadHandleFromSwitch(command_line, kOnIninitializedEventHandleSwitch);
79 *main_thread_id = ReadUintSwitch(command_line, kMainThreadIdSwitch);
81 if (parent_handle) {
82 // Initial test of the handle, a zero PID indicates invalid handle, or not
83 // a process handle. In this case, parsing fails and we avoid closing the
84 // handle.
85 DWORD process_pid = ::GetProcessId(parent_handle);
86 if (process_pid == 0) {
87 DLOG(ERROR) << "Invalid " << kParentHandleSwitch
88 << " argument. Can't get parent PID.";
89 } else {
90 parent_process->Set(parent_handle);
94 if (on_initialized_event_handle) {
95 DWORD result = ::WaitForSingleObject(on_initialized_event_handle, 0);
96 if (result == WAIT_FAILED) {
97 DPLOG(ERROR)
98 << "Unexpected error while testing the initialization event.";
99 } else if (result != WAIT_TIMEOUT) {
100 DLOG(ERROR) << "Unexpected result while testing the initialization event "
101 "with WaitForSingleObject: " << result;
102 } else {
103 on_initialized_event->Set(on_initialized_event_handle);
107 if (!*main_thread_id || !on_initialized_event->IsValid() ||
108 !parent_process->IsValid()) {
109 // If one was valid and not the other, free the valid one.
110 on_initialized_event->Close();
111 parent_process->Close();
112 *main_thread_id = 0;
113 return false;
116 return true;