quick_pair_process_manager_impl.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright 2021 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 "ash/services/quick_pair/quick_pair_process_manager_impl.h"
  5. #include <memory>
  6. #include "ash/quick_pair/common/logging.h"
  7. #include "ash/quick_pair/common/quick_pair_browser_delegate.h"
  8. #include "ash/services/quick_pair/public/mojom/fast_pair_data_parser.mojom.h"
  9. #include "ash/services/quick_pair/quick_pair_process_shutdown_controller.h"
  10. #include "base/bind.h"
  11. #include "base/threading/sequenced_task_runner_handle.h"
  12. #include "base/unguessable_token.h"
  13. #include "mojo/public/cpp/bindings/pending_receiver.h"
  14. #include "mojo/public/cpp/bindings/pending_remote.h"
  15. namespace ash {
  16. namespace quick_pair {
  17. QuickPairProcessManagerImpl::ProcessReferenceImpl::ProcessReferenceImpl(
  18. const mojo::SharedRemote<mojom::FastPairDataParser>& fast_pair_data_parser,
  19. base::OnceClosure destructor_callback)
  20. : fast_pair_data_parser_(fast_pair_data_parser),
  21. destructor_callback_(std::move(destructor_callback)) {}
  22. QuickPairProcessManagerImpl::ProcessReferenceImpl::~ProcessReferenceImpl() {
  23. // Reset the SharedRemotes before the destructor callback is run to ensure
  24. // that all connections to the utility process are destroyed before we attempt
  25. // to tear the process down.
  26. fast_pair_data_parser_.reset();
  27. std::move(destructor_callback_).Run();
  28. }
  29. const mojo::SharedRemote<mojom::FastPairDataParser>&
  30. QuickPairProcessManagerImpl::ProcessReferenceImpl::GetFastPairDataParser()
  31. const {
  32. return fast_pair_data_parser_;
  33. }
  34. QuickPairProcessManagerImpl::QuickPairProcessManagerImpl()
  35. : QuickPairProcessManagerImpl(
  36. std::make_unique<QuickPairProcessShutdownController>()) {}
  37. QuickPairProcessManagerImpl::QuickPairProcessManagerImpl(
  38. std::unique_ptr<QuickPairProcessShutdownController> shutdown_controller)
  39. : process_shutdown_controller_(std::move(shutdown_controller)) {}
  40. QuickPairProcessManagerImpl::~QuickPairProcessManagerImpl() = default;
  41. std::unique_ptr<QuickPairProcessManager::ProcessReference>
  42. QuickPairProcessManagerImpl::GetProcessReference(
  43. QuickPairProcessManager::ProcessStoppedCallback
  44. on_process_stopped_callback) {
  45. // Start the process if we don't have valid bound Remotes.
  46. if (!service_ || !fast_pair_data_parser_)
  47. BindToProcess();
  48. QP_LOG(VERBOSE) << __func__ << ": New process reference requested.";
  49. // Ensure the process isn't shutdown (it's possible the controller has started
  50. // their procedure by here.)
  51. process_shutdown_controller_->Stop();
  52. auto reference_id = base::UnguessableToken::Create();
  53. id_to_process_stopped_callback_map_[reference_id] =
  54. std::move(on_process_stopped_callback);
  55. return std::make_unique<ProcessReferenceImpl>(
  56. fast_pair_data_parser_,
  57. base::BindOnce(&QuickPairProcessManagerImpl::OnReferenceDeleted,
  58. weak_ptr_factory_.GetWeakPtr(), reference_id));
  59. }
  60. void QuickPairProcessManagerImpl::BindToProcess() {
  61. DCHECK(!service_ && !fast_pair_data_parser_);
  62. QP_LOG(INFO) << "Starting up QuickPair utility process";
  63. QuickPairBrowserDelegate::Get()->RequestService(
  64. service_.BindNewPipeAndPassReceiver());
  65. service_.set_disconnect_handler(
  66. base::BindOnce(&QuickPairProcessManagerImpl::ShutdownProcess,
  67. weak_ptr_factory_.GetWeakPtr(), ShutdownReason::kCrash));
  68. mojo::PendingRemote<mojom::FastPairDataParser> fast_pair_data_parser;
  69. mojo::PendingReceiver<mojom::FastPairDataParser>
  70. fast_pair_data_parser_receiver =
  71. fast_pair_data_parser.InitWithNewPipeAndPassReceiver();
  72. fast_pair_data_parser_.Bind(std::move(fast_pair_data_parser),
  73. /*bind_task_runner=*/nullptr);
  74. fast_pair_data_parser_.set_disconnect_handler(
  75. base::BindOnce(&QuickPairProcessManagerImpl::ShutdownProcess,
  76. weak_ptr_factory_.GetWeakPtr(),
  77. ShutdownReason::kFastPairDataParserMojoPipeDisconnection),
  78. base::SequencedTaskRunnerHandle::Get());
  79. service_->Connect(std::move(fast_pair_data_parser_receiver));
  80. }
  81. void QuickPairProcessManagerImpl::OnReferenceDeleted(
  82. base::UnguessableToken id) {
  83. auto it = id_to_process_stopped_callback_map_.find(id);
  84. DCHECK(it != id_to_process_stopped_callback_map_.end());
  85. // Do not call the callback because its owner has already explicitly deleted
  86. // its reference.
  87. id_to_process_stopped_callback_map_.erase(it);
  88. // If there are still active references, the process should be kept alive, so
  89. // return early.
  90. if (!id_to_process_stopped_callback_map_.empty())
  91. return;
  92. QP_LOG(VERBOSE)
  93. << "All process references have been released. Starting shutdown timer";
  94. process_shutdown_controller_->Start(
  95. base::BindOnce(&QuickPairProcessManagerImpl::ShutdownProcess,
  96. weak_ptr_factory_.GetWeakPtr(), ShutdownReason::kNormal));
  97. }
  98. void QuickPairProcessManagerImpl::ShutdownProcess(
  99. ShutdownReason shutdown_reason) {
  100. if (!service_ && !fast_pair_data_parser_)
  101. return;
  102. QP_LOG(WARNING) << __func__ << ": " << shutdown_reason;
  103. // Ensure that we don't try to stop the process again.
  104. process_shutdown_controller_->Stop();
  105. // Prevent the Remotes' disconnect handler and the OnReferenceDeleted
  106. // callbacks from firing.
  107. weak_ptr_factory_.InvalidateWeakPtrs();
  108. service_.reset();
  109. fast_pair_data_parser_.reset();
  110. // Move the map to a local variable to ensure that the instance field is
  111. // empty before any callbacks are made.
  112. auto old_map = std::move(id_to_process_stopped_callback_map_);
  113. id_to_process_stopped_callback_map_.clear();
  114. // Invoke the "process stopped" callback for each client.
  115. for (auto& it : old_map)
  116. std::move(it.second).Run(shutdown_reason);
  117. }
  118. } // namespace quick_pair
  119. } // namespace ash