dlcservice_client_unittest.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. // Copyright (c) 2019 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 "chromeos/dbus/dlcservice/dlcservice_client.h"
  5. #include <algorithm>
  6. #include <atomic>
  7. #include <functional>
  8. #include <memory>
  9. #include <utility>
  10. #include <vector>
  11. #include "base/bind.h"
  12. #include "base/callback_helpers.h"
  13. #include "base/run_loop.h"
  14. #include "base/test/task_environment.h"
  15. #include "dbus/mock_bus.h"
  16. #include "dbus/mock_object_proxy.h"
  17. #include "dbus/object_path.h"
  18. #include "testing/gmock/include/gmock/gmock.h"
  19. #include "testing/gtest/include/gtest/gtest.h"
  20. using ::testing::_;
  21. using ::testing::Invoke;
  22. using ::testing::Return;
  23. using ::testing::WithArg;
  24. namespace chromeos {
  25. namespace {
  26. std::unique_ptr<dbus::Signal> CreateSignal(
  27. const dlcservice::DlcState& dlc_state) {
  28. auto signal =
  29. std::make_unique<dbus::Signal>("com.example.Interface", "SomeSignal");
  30. dbus::MessageWriter writer(signal.get());
  31. writer.AppendProtoAsArrayOfBytes(dlc_state);
  32. return signal;
  33. }
  34. class DlcserviceClientTest : public testing::Test {
  35. public:
  36. void SetUp() override {
  37. dbus::Bus::Options options;
  38. options.bus_type = dbus::Bus::SYSTEM;
  39. mock_bus_ = base::MakeRefCounted<::testing::NiceMock<dbus::MockBus>>(
  40. dbus::Bus::Options());
  41. mock_proxy_ = base::MakeRefCounted<dbus::MockObjectProxy>(
  42. mock_bus_.get(), dlcservice::kDlcServiceServiceName,
  43. dbus::ObjectPath(dlcservice::kDlcServiceServicePath));
  44. EXPECT_CALL(
  45. *mock_bus_.get(),
  46. GetObjectProxy(dlcservice::kDlcServiceServiceName,
  47. dbus::ObjectPath(dlcservice::kDlcServiceServicePath)))
  48. .WillOnce(Return(mock_proxy_.get()));
  49. EXPECT_CALL(*mock_proxy_.get(),
  50. DoConnectToSignal(dlcservice::kDlcServiceInterface, _, _, _))
  51. .WillOnce(Invoke(this, &DlcserviceClientTest::ConnectToSignal));
  52. EXPECT_CALL(*mock_proxy_.get(), DoWaitForServiceToBeAvailable(_)).Times(1);
  53. DlcserviceClient::Initialize(mock_bus_.get());
  54. client_ = DlcserviceClient::Get();
  55. base::RunLoop().RunUntilIdle();
  56. }
  57. void TearDown() override { DlcserviceClient::Shutdown(); }
  58. void CallMethodWithErrorResponse(
  59. dbus::MethodCall* method_call,
  60. int timeout_ms,
  61. dbus::ObjectProxy::ResponseOrErrorCallback* callback) {
  62. dbus::Response* response = nullptr;
  63. dbus::ErrorResponse* err_response = nullptr;
  64. if (!responses_.empty()) {
  65. used_responses_.push_back(std::move(responses_.front()));
  66. responses_.pop_front();
  67. response = used_responses_.back().get();
  68. }
  69. if (!err_responses_.empty()) {
  70. used_err_responses_.push_back(std::move(err_responses_.front()));
  71. err_responses_.pop_front();
  72. err_response = used_err_responses_.back().get();
  73. }
  74. CHECK((response != nullptr) != (err_response != nullptr));
  75. task_environment_.GetMainThreadTaskRunner()->PostTask(
  76. FROM_HERE,
  77. base::BindOnce(std::move(*callback), response, err_response));
  78. }
  79. protected:
  80. dlcservice::InstallRequest CreateInstallRequest(
  81. const std::string& id = {},
  82. const std::string& omaha_url = {},
  83. bool reserve = false) {
  84. dlcservice::InstallRequest install_request;
  85. install_request.set_id(id);
  86. install_request.set_omaha_url(omaha_url);
  87. install_request.set_reserve(reserve);
  88. return install_request;
  89. }
  90. base::test::SingleThreadTaskEnvironment task_environment_;
  91. DlcserviceClient* client_;
  92. scoped_refptr<dbus::MockBus> mock_bus_;
  93. scoped_refptr<dbus::MockObjectProxy> mock_proxy_;
  94. std::deque<std::unique_ptr<dbus::Response>> responses_;
  95. std::deque<std::unique_ptr<dbus::ErrorResponse>> err_responses_;
  96. private:
  97. void ConnectToSignal(
  98. const std::string& interface_name,
  99. const std::string& signal_name,
  100. dbus::ObjectProxy::SignalCallback signal_callback,
  101. dbus::ObjectProxy::OnConnectedCallback* on_connected_callback) {
  102. EXPECT_EQ(interface_name, dlcservice::kDlcServiceInterface);
  103. task_environment_.GetMainThreadTaskRunner()->PostTask(
  104. FROM_HERE,
  105. base::BindOnce(std::move(*on_connected_callback), interface_name,
  106. signal_name, true /* success */));
  107. }
  108. std::deque<std::unique_ptr<dbus::Response>> used_responses_;
  109. std::deque<std::unique_ptr<dbus::ErrorResponse>> used_err_responses_;
  110. };
  111. class MockObserver : public DlcserviceClient::Observer {
  112. public:
  113. MOCK_METHOD(void,
  114. OnDlcStateChanged,
  115. (const dlcservice::DlcState& dlc_state),
  116. ());
  117. };
  118. TEST_F(DlcserviceClientTest, GetDlcStateSuccessTest) {
  119. responses_.push_back(dbus::Response::CreateEmpty());
  120. dbus::Response* response = responses_.front().get();
  121. dbus::MessageWriter writer(response);
  122. dlcservice::DlcState dlc_state;
  123. writer.AppendProtoAsArrayOfBytes(dlc_state);
  124. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  125. .WillOnce(
  126. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  127. DlcserviceClient::GetDlcStateCallback callback =
  128. base::BindOnce([](const std::string& err, const dlcservice::DlcState&) {
  129. EXPECT_EQ(dlcservice::kErrorNone, err);
  130. });
  131. client_->GetDlcState("some-dlc-id", std::move(callback));
  132. base::RunLoop().RunUntilIdle();
  133. }
  134. TEST_F(DlcserviceClientTest, GetDlcStateFailureTest) {
  135. dbus::MethodCall method_call(dlcservice::kDlcServiceInterface,
  136. dlcservice::kGetDlcStateMethod);
  137. method_call.SetSerial(123);
  138. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  139. &method_call, DBUS_ERROR_FAILED, "some-unknown-error"));
  140. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  141. .WillRepeatedly(
  142. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  143. client_->GetDlcState(
  144. "some-dlc-id",
  145. base::BindOnce([](const std::string& err, const dlcservice::DlcState&) {
  146. EXPECT_EQ(dlcservice::kErrorInternal, err);
  147. }));
  148. base::RunLoop().RunUntilIdle();
  149. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  150. &method_call, dlcservice::kErrorInvalidDlc,
  151. "Some error due to bad DLC."));
  152. client_->GetDlcState(
  153. "some-dlc-id",
  154. base::BindOnce([](const std::string& err, const dlcservice::DlcState&) {
  155. EXPECT_EQ(dlcservice::kErrorInvalidDlc, err);
  156. }));
  157. base::RunLoop().RunUntilIdle();
  158. }
  159. TEST_F(DlcserviceClientTest, GetExistingDlcsSuccessTest) {
  160. responses_.push_back(dbus::Response::CreateEmpty());
  161. dbus::Response* response = responses_.front().get();
  162. dbus::MessageWriter writer(response);
  163. dlcservice::DlcsWithContent dlcs_with_content;
  164. writer.AppendProtoAsArrayOfBytes(dlcs_with_content);
  165. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  166. .WillOnce(
  167. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  168. DlcserviceClient::GetExistingDlcsCallback callback = base::BindOnce(
  169. [](const std::string& err, const dlcservice::DlcsWithContent&) {
  170. EXPECT_EQ(dlcservice::kErrorNone, err);
  171. });
  172. client_->GetExistingDlcs(std::move(callback));
  173. base::RunLoop().RunUntilIdle();
  174. }
  175. TEST_F(DlcserviceClientTest, GetExistingDlcsFailureTest) {
  176. dbus::MethodCall method_call(dlcservice::kDlcServiceInterface,
  177. dlcservice::kGetExistingDlcsMethod);
  178. method_call.SetSerial(123);
  179. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  180. &method_call, DBUS_ERROR_FAILED, "some-unknown-error"));
  181. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  182. .WillRepeatedly(
  183. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  184. client_->GetExistingDlcs(base::BindOnce(
  185. [](const std::string& err, const dlcservice::DlcsWithContent&) {
  186. EXPECT_EQ(dlcservice::kErrorInternal, err);
  187. }));
  188. base::RunLoop().RunUntilIdle();
  189. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  190. &method_call, dlcservice::kErrorInvalidDlc,
  191. "Some error due to bad DLC."));
  192. client_->GetExistingDlcs(base::BindOnce(
  193. [](const std::string& err, const dlcservice::DlcsWithContent&) {
  194. EXPECT_EQ(dlcservice::kErrorInvalidDlc, err);
  195. }));
  196. base::RunLoop().RunUntilIdle();
  197. }
  198. TEST_F(DlcserviceClientTest, UninstallSuccessTest) {
  199. responses_.push_back(dbus::Response::CreateEmpty());
  200. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  201. .WillOnce(
  202. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  203. DlcserviceClient::UninstallCallback callback = base::BindOnce(
  204. [](const std::string& err) { EXPECT_EQ(dlcservice::kErrorNone, err); });
  205. client_->Uninstall("some-dlc-id", std::move(callback));
  206. base::RunLoop().RunUntilIdle();
  207. }
  208. TEST_F(DlcserviceClientTest, UninstallFailureTest) {
  209. dbus::MethodCall method_call(dlcservice::kDlcServiceInterface,
  210. dlcservice::kUninstallMethod);
  211. method_call.SetSerial(123);
  212. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  213. &method_call, dlcservice::kErrorInternal, ""));
  214. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  215. .WillRepeatedly(
  216. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  217. DlcserviceClient::UninstallCallback callback =
  218. base::BindOnce([](const std::string& err) {
  219. EXPECT_EQ(dlcservice::kErrorInternal, err);
  220. });
  221. client_->Uninstall("some-dlc-id", std::move(callback));
  222. base::RunLoop().RunUntilIdle();
  223. }
  224. TEST_F(DlcserviceClientTest, UninstallBusyStatusTest) {
  225. dbus::MethodCall method_call(dlcservice::kDlcServiceInterface,
  226. dlcservice::kUninstallMethod);
  227. method_call.SetSerial(123);
  228. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  229. &method_call, dlcservice::kErrorBusy, ""));
  230. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  231. .WillRepeatedly(
  232. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  233. DlcserviceClient::UninstallCallback callback = base::BindOnce(
  234. [](const std::string& err) { EXPECT_EQ(dlcservice::kErrorBusy, err); });
  235. client_->Uninstall("some-dlc-id", std::move(callback));
  236. base::RunLoop().RunUntilIdle();
  237. }
  238. TEST_F(DlcserviceClientTest, PurgeSuccessTest) {
  239. responses_.push_back(dbus::Response::CreateEmpty());
  240. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  241. .WillOnce(
  242. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  243. DlcserviceClient::PurgeCallback callback = base::BindOnce(
  244. [](const std::string& err) { EXPECT_EQ(dlcservice::kErrorNone, err); });
  245. client_->Purge("some-dlc-id", std::move(callback));
  246. base::RunLoop().RunUntilIdle();
  247. }
  248. TEST_F(DlcserviceClientTest, PurgeFailureTest) {
  249. dbus::MethodCall method_call(dlcservice::kDlcServiceInterface,
  250. dlcservice::kPurgeMethod);
  251. method_call.SetSerial(123);
  252. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  253. &method_call, dlcservice::kErrorInternal, ""));
  254. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  255. .WillRepeatedly(
  256. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  257. DlcserviceClient::PurgeCallback callback =
  258. base::BindOnce([](const std::string& err) {
  259. EXPECT_EQ(dlcservice::kErrorInternal, err);
  260. });
  261. client_->Purge("some-dlc-id", std::move(callback));
  262. base::RunLoop().RunUntilIdle();
  263. }
  264. TEST_F(DlcserviceClientTest, PurgeBusyStatusTest) {
  265. dbus::MethodCall method_call(dlcservice::kDlcServiceInterface,
  266. dlcservice::kPurgeMethod);
  267. method_call.SetSerial(123);
  268. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  269. &method_call, dlcservice::kErrorBusy, ""));
  270. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  271. .WillRepeatedly(
  272. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  273. DlcserviceClient::PurgeCallback callback = base::BindOnce(
  274. [](const std::string& err) { EXPECT_EQ(dlcservice::kErrorBusy, err); });
  275. client_->Purge("some-dlc-id", std::move(callback));
  276. base::RunLoop().RunUntilIdle();
  277. }
  278. TEST_F(DlcserviceClientTest, InstallSuccessTest) {
  279. responses_.push_back(dbus::Response::CreateEmpty());
  280. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  281. .WillOnce(
  282. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  283. DlcserviceClient::InstallCallback install_callback =
  284. base::BindOnce([](const DlcserviceClient::InstallResult& install_result) {
  285. EXPECT_EQ(dlcservice::kErrorNone, install_result.error);
  286. });
  287. client_->Install(CreateInstallRequest("foo-dlc"), std::move(install_callback),
  288. base::DoNothing());
  289. base::RunLoop().RunUntilIdle();
  290. }
  291. TEST_F(DlcserviceClientTest, InstallFailureTest) {
  292. dbus::MethodCall method_call(dlcservice::kDlcServiceInterface,
  293. dlcservice::kInstallMethod);
  294. method_call.SetSerial(123);
  295. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  296. &method_call, dlcservice::kErrorInternal, ""));
  297. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  298. .WillOnce(
  299. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  300. DlcserviceClient::InstallCallback install_callback =
  301. base::BindOnce([](const DlcserviceClient::InstallResult& install_result) {
  302. EXPECT_EQ(dlcservice::kErrorInternal, install_result.error);
  303. });
  304. client_->Install(CreateInstallRequest("foo-dlc"), std::move(install_callback),
  305. base::DoNothing());
  306. base::RunLoop().RunUntilIdle();
  307. }
  308. TEST_F(DlcserviceClientTest, InstallProgressTest) {
  309. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  310. .WillOnce(
  311. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  312. std::atomic<size_t> counter{0};
  313. DlcserviceClient::InstallCallback install_callback = base::BindOnce(
  314. [](const DlcserviceClient::InstallResult& install_result) {});
  315. DlcserviceClient::ProgressCallback progress_callback = base::BindRepeating(
  316. [](decltype(counter)* counter, double) { ++*counter; }, &counter);
  317. responses_.push_back(dbus::Response::CreateEmpty());
  318. client_->Install(CreateInstallRequest(), std::move(install_callback),
  319. std::move(progress_callback));
  320. base::RunLoop().RunUntilIdle();
  321. EXPECT_EQ(0u, counter.load());
  322. dlcservice::DlcState dlc_state;
  323. dlc_state.set_state(dlcservice::DlcState::INSTALLING);
  324. auto signal = CreateSignal(dlc_state);
  325. client_->DlcStateChangedForTest(signal.get());
  326. base::RunLoop().RunUntilIdle();
  327. EXPECT_EQ(1u, counter.load());
  328. }
  329. TEST_F(DlcserviceClientTest, InstallProgressSkipUnheldDlcIdsTest) {
  330. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  331. .WillOnce(Return());
  332. std::atomic<size_t> counter{0};
  333. DlcserviceClient::InstallCallback install_callback = base::BindOnce(
  334. [](const DlcserviceClient::InstallResult& install_result) {});
  335. DlcserviceClient::ProgressCallback progress_callback = base::BindRepeating(
  336. [](decltype(counter)* counter, double) { ++*counter; }, &counter);
  337. client_->Install(CreateInstallRequest("foo"), std::move(install_callback),
  338. std::move(progress_callback));
  339. base::RunLoop().RunUntilIdle();
  340. EXPECT_EQ(0u, counter.load());
  341. dlcservice::DlcState dlc_state;
  342. dlc_state.set_id("bar-is-not-foo");
  343. dlc_state.set_state(dlcservice::DlcState::INSTALLING);
  344. auto signal = CreateSignal(dlc_state);
  345. client_->DlcStateChangedForTest(signal.get());
  346. base::RunLoop().RunUntilIdle();
  347. EXPECT_EQ(0u, counter.load());
  348. }
  349. TEST_F(DlcserviceClientTest, InstallBusyStatusTest) {
  350. dbus::MethodCall method_call(dlcservice::kDlcServiceInterface,
  351. dlcservice::kInstallMethod);
  352. method_call.SetSerial(123);
  353. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  354. &method_call, dlcservice::kErrorBusy, ""));
  355. err_responses_.push_back(dbus::ErrorResponse::FromMethodCall(
  356. &method_call, dlcservice::kErrorNone, ""));
  357. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  358. .WillRepeatedly(
  359. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  360. DlcserviceClient::InstallCallback install_callback =
  361. base::BindOnce([](const DlcserviceClient::InstallResult& install_result) {
  362. EXPECT_EQ(dlcservice::kErrorNone, install_result.error);
  363. });
  364. client_->Install(CreateInstallRequest("foo-dlc"), std::move(install_callback),
  365. base::DoNothing());
  366. base::RunLoop().RunUntilIdle();
  367. }
  368. TEST_F(DlcserviceClientTest, PendingTaskTest) {
  369. const size_t kLoopCount = 3;
  370. EXPECT_CALL(*mock_proxy_.get(), DoCallMethodWithErrorResponse(_, _, _))
  371. .Times(kLoopCount)
  372. .WillRepeatedly(
  373. Invoke(this, &DlcserviceClientTest::CallMethodWithErrorResponse));
  374. std::atomic<size_t> counter{0};
  375. // All |Install()| request after the first should be queued.
  376. for (size_t i = 0; i < kLoopCount; ++i) {
  377. DlcserviceClient::InstallCallback install_callback = base::BindOnce(
  378. [](decltype(counter)* counter,
  379. const DlcserviceClient::InstallResult& install_result) {
  380. ++*counter;
  381. },
  382. &counter);
  383. responses_.push_back(dbus::Response::CreateEmpty());
  384. client_->Install(CreateInstallRequest(), std::move(install_callback),
  385. base::DoNothing());
  386. }
  387. base::RunLoop().RunUntilIdle();
  388. EXPECT_EQ(0u, counter.load());
  389. dlcservice::DlcState dlc_state;
  390. dlc_state.set_state(dlcservice::DlcState::INSTALLED);
  391. auto signal = CreateSignal(dlc_state);
  392. for (size_t i = 1; i < 100; ++i) {
  393. client_->DlcStateChangedForTest(signal.get());
  394. base::RunLoop().RunUntilIdle();
  395. EXPECT_EQ(i <= kLoopCount ? i : kLoopCount, counter.load());
  396. }
  397. }
  398. TEST_F(DlcserviceClientTest, StateChangeObserver) {
  399. dlcservice::DlcState dlc_state;
  400. dlc_state.set_state(dlcservice::DlcState::INSTALLED);
  401. auto signal = CreateSignal(dlc_state);
  402. MockObserver observer;
  403. // If no observer has been added, nothing should be called.
  404. EXPECT_CALL(observer, OnDlcStateChanged(_)).Times(0);
  405. client_->DlcStateChangedForTest(signal.get());
  406. // Adding one observer should call once.
  407. EXPECT_CALL(observer, OnDlcStateChanged(_)).Times(1);
  408. client_->AddObserver(&observer);
  409. client_->DlcStateChangedForTest(signal.get());
  410. // Removing the observer causes nothing to be called.
  411. EXPECT_CALL(observer, OnDlcStateChanged(_)).Times(0);
  412. client_->RemoveObserver(&observer);
  413. client_->DlcStateChangedForTest(signal.get());
  414. }
  415. } // namespace
  416. } // namespace chromeos