base: Add CHECK_IMPLIES and DCHECK_IMPLIES.
[chromium-blink-merge.git] / win8 / test / metro_registration_helper.cc
blobc5d6735a4e9c831e5fdc9d91a1888dfd0bf41bf2
1 // Copyright (c) 2013 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 "win8/test/metro_registration_helper.h"
7 #include <shlobj.h>
9 #include <vector>
11 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/logging.h"
15 #include "base/path_service.h"
16 #include "base/process/kill.h"
17 #include "base/process/launch.h"
18 #include "base/process/process.h"
19 #include "base/strings/string16.h"
20 #include "base/win/scoped_co_mem.h"
21 #include "base/win/scoped_comptr.h"
22 #include "base/win/scoped_handle.h"
23 #include "win8/test/open_with_dialog_controller.h"
24 #include "win8/test/test_registrar_constants.h"
26 namespace {
28 const int kRegistrationTimeoutSeconds = 30;
30 // Copied from util_constants.cc to avoid taking a dependency on installer_util.
31 const wchar_t kChromeExe[] = L"chrome.exe";
32 const wchar_t kRegistrar[] = L"test_registrar.exe";
34 // Registers chrome.exe as a potential Win8 default browser. It will then show
35 // up in the default browser selection dialog as kDefaultTestExeName. Intended
36 // to be used by a test binary in the build output directory and assumes the
37 // presence of test_registrar.exe, a viewer process, and all needed DLLs in the
38 // same directory as the calling module.
39 bool RegisterTestDefaultBrowser() {
40 base::FilePath dir;
41 if (!PathService::Get(base::DIR_EXE, &dir))
42 return false;
44 base::FilePath chrome_exe(dir.Append(kChromeExe));
45 base::FilePath registrar(dir.Append(kRegistrar));
47 if (!base::PathExists(chrome_exe) || !base::PathExists(registrar)) {
48 LOG(ERROR) << "Could not locate " << kChromeExe << " or " << kRegistrar;
49 return false;
52 // Perform the registration by invoking test_registrar.exe.
53 CommandLine register_command(registrar);
54 register_command.AppendArg("/RegServer");
56 base::win::ScopedHandle register_handle;
57 if (base::LaunchProcess(register_command.GetCommandLineString(),
58 base::LaunchOptions(),
59 &register_handle)) {
60 int ret = 0;
61 if (base::WaitForExitCodeWithTimeout(
62 register_handle.Get(), &ret,
63 base::TimeDelta::FromSeconds(kRegistrationTimeoutSeconds))) {
64 if (ret == 0) {
65 return true;
66 } else {
67 LOG(ERROR) << "Win8 registration using "
68 << register_command.GetCommandLineString()
69 << " failed with error code " << ret;
71 } else {
72 LOG(ERROR) << "Win8 registration using "
73 << register_command.GetCommandLineString() << " timed out.";
77 PLOG(ERROR) << "Failed to launch Win8 registration utility using "
78 << register_command.GetCommandLineString();
79 return false;
82 // Returns true if the test viewer's progid is the default handler for
83 // |protocol|.
84 bool IsTestDefaultForProtocol(const wchar_t* protocol) {
85 base::win::ScopedComPtr<IApplicationAssociationRegistration> registration;
86 HRESULT hr = registration.CreateInstance(
87 CLSID_ApplicationAssociationRegistration, NULL, CLSCTX_INPROC);
88 if (FAILED(hr)) {
89 LOG(ERROR) << std::hex << hr;
90 return false;
93 base::win::ScopedCoMem<wchar_t> current_app;
94 hr = registration->QueryCurrentDefault(protocol, AT_URLPROTOCOL,
95 AL_EFFECTIVE, &current_app);
96 if (FAILED(hr)) {
97 LOG(ERROR) << std::hex << hr;
98 return false;
101 return !base::string16(win8::test::kDefaultTestProgId).compare(current_app);
104 } // namespace
106 namespace win8 {
108 bool MakeTestDefaultBrowserSynchronously() {
109 static const wchar_t kDefaultBrowserProtocol[] = L"http";
111 if (!RegisterTestDefaultBrowser())
112 return false;
114 // Make sure the registration changes have been acknowledged by the shell
115 // before querying for the current default.
116 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH, NULL, NULL);
118 // OpenWithDialogController will fail if the Test Runner is already default
119 // since it will not show up verbatim in the dialog (e.g., in EN-US, it will
120 // be prefixed by "Keep using ").
121 if (IsTestDefaultForProtocol(kDefaultBrowserProtocol))
122 return true;
124 std::vector<base::string16> choices;
125 OpenWithDialogController controller;
126 HRESULT hr = controller.RunSynchronously(
127 NULL, kDefaultBrowserProtocol, win8::test::kDefaultTestExeName, &choices);
128 LOG_IF(ERROR, FAILED(hr)) << std::hex << hr;
129 DCHECK(IsTestDefaultForProtocol(kDefaultBrowserProtocol));
130 return SUCCEEDED(hr);
133 } // namespace win8