evaluate_capability.cc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright 2017 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. #include "remoting/host/evaluate_capability.h"
  5. #include <iostream>
  6. #include "base/base_paths.h"
  7. #include "base/check.h"
  8. #include "base/command_line.h"
  9. #include "base/files/file_path.h"
  10. #include "base/notreached.h"
  11. #include "base/path_service.h"
  12. #include "base/process/kill.h"
  13. #include "base/process/launch.h"
  14. #include "base/threading/thread_restrictions.h"
  15. #include "build/build_config.h"
  16. #include "remoting/host/base/host_exit_codes.h"
  17. #include "remoting/host/base/switches.h"
  18. #include "remoting/host/ipc_constants.h"
  19. #if BUILDFLAG(IS_WIN)
  20. #include "remoting/host/win/evaluate_3d_display_mode.h"
  21. #include "remoting/host/win/evaluate_d3d.h"
  22. #endif
  23. namespace remoting {
  24. // TODO(crbug.com/1144161): Do not perform blocking operations on the IO thread.
  25. class ScopedBypassIOThreadRestrictions : public base::ScopedAllowBlocking {};
  26. namespace {
  27. // Returns the full path of the binary file we should use to evaluate the
  28. // capability. According to the platform and executing environment, return of
  29. // this function may vary. But in one process, the return value is guaranteed to
  30. // be the same.
  31. // This function uses capability_test_stub in unittest, or tries to use current
  32. // binary if supported, otherwise it falls back to use the default binary.
  33. base::FilePath BuildHostBinaryPath() {
  34. base::FilePath path;
  35. bool result = base::PathService::Get(base::FILE_EXE, &path);
  36. DCHECK(result);
  37. base::FilePath directory;
  38. result = base::PathService::Get(base::DIR_EXE, &directory);
  39. DCHECK(result);
  40. #if BUILDFLAG(IS_WIN)
  41. if (path.BaseName().value() == FILE_PATH_LITERAL("remoting_unittests.exe")) {
  42. return directory.Append(FILE_PATH_LITERAL("capability_test_stub.exe"));
  43. }
  44. #else
  45. if (path.BaseName().value() == FILE_PATH_LITERAL("remoting_unittests")) {
  46. return directory.Append(FILE_PATH_LITERAL("capability_test_stub"));
  47. }
  48. #endif
  49. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  50. if (path.BaseName().value() ==
  51. FILE_PATH_LITERAL("chrome-remote-desktop-host")) {
  52. return path;
  53. }
  54. if (path.BaseName().value() == FILE_PATH_LITERAL("remoting_me2me_host")) {
  55. return path;
  56. }
  57. return directory.Append(FILE_PATH_LITERAL("remoting_me2me_host"));
  58. #elif BUILDFLAG(IS_APPLE)
  59. if (path.BaseName().value() == FILE_PATH_LITERAL("remoting_me2me_host")) {
  60. return path;
  61. }
  62. return directory.Append(FILE_PATH_LITERAL(
  63. "remoting_me2me_host.app/Contents/MacOS/remoting_me2me_host"));
  64. #elif BUILDFLAG(IS_WIN)
  65. if (path.BaseName().value() == FILE_PATH_LITERAL("remoting_console.exe")) {
  66. return path;
  67. }
  68. if (path.BaseName().value() == FILE_PATH_LITERAL("remoting_desktop.exe")) {
  69. return path;
  70. }
  71. if (path.BaseName().value() == FILE_PATH_LITERAL("remoting_host.exe")) {
  72. return path;
  73. }
  74. return directory.Append(FILE_PATH_LITERAL("remoting_host.exe"));
  75. #else
  76. #error "BuildHostBinaryPath is not implemented for current platform."
  77. #endif
  78. }
  79. } // namespace
  80. int EvaluateCapabilityLocally(const std::string& type) {
  81. #if BUILDFLAG(IS_WIN)
  82. if (type == kEvaluateD3D) {
  83. return EvaluateD3D();
  84. }
  85. if (type == kEvaluate3dDisplayMode) {
  86. return Evaluate3dDisplayMode();
  87. }
  88. #endif
  89. return kInvalidCommandLineExitCode;
  90. }
  91. int EvaluateCapability(const std::string& type,
  92. std::string* output /* = nullptr */) {
  93. base::CommandLine command(BuildHostBinaryPath());
  94. command.AppendSwitchASCII(kProcessTypeSwitchName,
  95. kProcessTypeEvaluateCapability);
  96. command.AppendSwitchASCII(kEvaluateCapabilitySwitchName, type);
  97. int exit_code;
  98. std::string dummy_output;
  99. if (!output) {
  100. output = &dummy_output;
  101. }
  102. // TODO(crbug.com/1144161): Do not perform blocking operations on the IO
  103. // thread.
  104. ScopedBypassIOThreadRestrictions bypass;
  105. #if DCHECK_IS_ON() && !BUILDFLAG(IS_WIN)
  106. const bool result =
  107. #endif
  108. base::GetAppOutputWithExitCode(command, output, &exit_code);
  109. // On Windows, base::GetAppOutputWithExitCode() usually returns false when
  110. // receiving "unknown" exit code. See
  111. // https://cs.chromium.org/chromium/src/base/process/launch_win.cc?rcl=39ec40095376e8d977decbdc5d7ca28ba7d39cf2&l=130
  112. #if DCHECK_IS_ON() && !BUILDFLAG(IS_WIN)
  113. DCHECK(result) << "Failed to execute process "
  114. << command.GetCommandLineString() << ", exit code "
  115. << exit_code;
  116. #endif
  117. return exit_code;
  118. }
  119. } // namespace remoting