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
3// found in the LICENSE file.
4
5#include "chrome/test/chromedriver/chrome/chrome_finder.h"
6
7#include <string>
8#include <vector>
9
10#include "base/base_paths.h"
11#include "base/bind.h"
12#include "base/callback.h"
13#include "base/files/file_path.h"
14#include "base/files/file_util.h"
15#include "base/path_service.h"
16#include "build/build_config.h"
17
18#if defined(OS_WIN)
19#include "base/base_paths_win.h"
20#include "base/win/windows_version.h"
21#endif
22
23namespace {
24
25#if defined(OS_WIN)
26void GetApplicationDirs(std::vector<base::FilePath>* locations) {
27  std::vector<base::FilePath> installation_locations;
28  base::FilePath local_app_data, program_files, program_files_x86;
29  if (PathService::Get(base::DIR_LOCAL_APP_DATA, &local_app_data))
30    installation_locations.push_back(local_app_data);
31  if (PathService::Get(base::DIR_PROGRAM_FILES, &program_files))
32    installation_locations.push_back(program_files);
33  if (PathService::Get(base::DIR_PROGRAM_FILESX86, &program_files_x86))
34    installation_locations.push_back(program_files_x86);
35
36  for (size_t i = 0; i < installation_locations.size(); ++i) {
37    locations->push_back(
38        installation_locations[i].Append(L"Google\\Chrome\\Application"));
39  }
40  for (size_t i = 0; i < installation_locations.size(); ++i) {
41    locations->push_back(
42        installation_locations[i].Append(L"Chromium\\Application"));
43  }
44}
45#elif defined(OS_LINUX)
46void GetApplicationDirs(std::vector<base::FilePath>* locations) {
47  locations->push_back(base::FilePath("/opt/google/chrome"));
48  locations->push_back(base::FilePath("/usr/local/bin"));
49  locations->push_back(base::FilePath("/usr/local/sbin"));
50  locations->push_back(base::FilePath("/usr/bin"));
51  locations->push_back(base::FilePath("/usr/sbin"));
52  locations->push_back(base::FilePath("/bin"));
53  locations->push_back(base::FilePath("/sbin"));
54}
55#endif
56
57}  // namespace
58
59namespace internal {
60
61bool FindExe(
62    const base::Callback<bool(const base::FilePath&)>& exists_func,
63    const std::vector<base::FilePath>& rel_paths,
64    const std::vector<base::FilePath>& locations,
65    base::FilePath* out_path) {
66  for (size_t i = 0; i < rel_paths.size(); ++i) {
67    for (size_t j = 0; j < locations.size(); ++j) {
68      base::FilePath path = locations[j].Append(rel_paths[i]);
69      if (exists_func.Run(path)) {
70        *out_path = path;
71        return true;
72      }
73    }
74  }
75  return false;
76}
77
78}  // namespace internal
79
80#if defined(OS_MACOSX)
81void GetApplicationDirs(std::vector<base::FilePath>* locations);
82#endif
83
84bool FindChrome(base::FilePath* browser_exe) {
85#if defined(OS_WIN)
86  base::FilePath browser_exes_array[] = {
87      base::FilePath(L"chrome.exe")
88  };
89#elif defined(OS_MACOSX)
90  base::FilePath browser_exes_array[] = {
91      base::FilePath("Google Chrome.app/Contents/MacOS/Google Chrome"),
92      base::FilePath("Chromium.app/Contents/MacOS/Chromium")
93  };
94#elif defined(OS_LINUX)
95  base::FilePath browser_exes_array[] = {
96      base::FilePath("google-chrome"),
97      base::FilePath("chrome"),
98      base::FilePath("chromium"),
99      base::FilePath("chromium-browser")
100  };
101#endif
102  std::vector<base::FilePath> browser_exes(
103      browser_exes_array, browser_exes_array + arraysize(browser_exes_array));
104  base::FilePath module_dir;
105  if (PathService::Get(base::DIR_MODULE, &module_dir)) {
106    for (size_t i = 0; i < browser_exes.size(); ++i) {
107      base::FilePath path = module_dir.Append(browser_exes[i]);
108      if (base::PathExists(path)) {
109        *browser_exe = path;
110        return true;
111      }
112    }
113  }
114
115  std::vector<base::FilePath> locations;
116  GetApplicationDirs(&locations);
117  return internal::FindExe(
118      base::Bind(&base::PathExists),
119      browser_exes,
120      locations,
121      browser_exe);
122}
123