123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/services/quick_pair/quick_pair_process_manager_impl.h"
- #include <memory>
- #include "ash/quick_pair/common/logging.h"
- #include "ash/quick_pair/common/quick_pair_browser_delegate.h"
- #include "ash/services/quick_pair/public/mojom/fast_pair_data_parser.mojom.h"
- #include "ash/services/quick_pair/quick_pair_process_shutdown_controller.h"
- #include "base/bind.h"
- #include "base/threading/sequenced_task_runner_handle.h"
- #include "base/unguessable_token.h"
- #include "mojo/public/cpp/bindings/pending_receiver.h"
- #include "mojo/public/cpp/bindings/pending_remote.h"
- namespace ash {
- namespace quick_pair {
- QuickPairProcessManagerImpl::ProcessReferenceImpl::ProcessReferenceImpl(
- const mojo::SharedRemote<mojom::FastPairDataParser>& fast_pair_data_parser,
- base::OnceClosure destructor_callback)
- : fast_pair_data_parser_(fast_pair_data_parser),
- destructor_callback_(std::move(destructor_callback)) {}
- QuickPairProcessManagerImpl::ProcessReferenceImpl::~ProcessReferenceImpl() {
- // Reset the SharedRemotes before the destructor callback is run to ensure
- // that all connections to the utility process are destroyed before we attempt
- // to tear the process down.
- fast_pair_data_parser_.reset();
- std::move(destructor_callback_).Run();
- }
- const mojo::SharedRemote<mojom::FastPairDataParser>&
- QuickPairProcessManagerImpl::ProcessReferenceImpl::GetFastPairDataParser()
- const {
- return fast_pair_data_parser_;
- }
- QuickPairProcessManagerImpl::QuickPairProcessManagerImpl()
- : QuickPairProcessManagerImpl(
- std::make_unique<QuickPairProcessShutdownController>()) {}
- QuickPairProcessManagerImpl::QuickPairProcessManagerImpl(
- std::unique_ptr<QuickPairProcessShutdownController> shutdown_controller)
- : process_shutdown_controller_(std::move(shutdown_controller)) {}
- QuickPairProcessManagerImpl::~QuickPairProcessManagerImpl() = default;
- std::unique_ptr<QuickPairProcessManager::ProcessReference>
- QuickPairProcessManagerImpl::GetProcessReference(
- QuickPairProcessManager::ProcessStoppedCallback
- on_process_stopped_callback) {
- // Start the process if we don't have valid bound Remotes.
- if (!service_ || !fast_pair_data_parser_)
- BindToProcess();
- QP_LOG(VERBOSE) << __func__ << ": New process reference requested.";
- // Ensure the process isn't shutdown (it's possible the controller has started
- // their procedure by here.)
- process_shutdown_controller_->Stop();
- auto reference_id = base::UnguessableToken::Create();
- id_to_process_stopped_callback_map_[reference_id] =
- std::move(on_process_stopped_callback);
- return std::make_unique<ProcessReferenceImpl>(
- fast_pair_data_parser_,
- base::BindOnce(&QuickPairProcessManagerImpl::OnReferenceDeleted,
- weak_ptr_factory_.GetWeakPtr(), reference_id));
- }
- void QuickPairProcessManagerImpl::BindToProcess() {
- DCHECK(!service_ && !fast_pair_data_parser_);
- QP_LOG(INFO) << "Starting up QuickPair utility process";
- QuickPairBrowserDelegate::Get()->RequestService(
- service_.BindNewPipeAndPassReceiver());
- service_.set_disconnect_handler(
- base::BindOnce(&QuickPairProcessManagerImpl::ShutdownProcess,
- weak_ptr_factory_.GetWeakPtr(), ShutdownReason::kCrash));
- mojo::PendingRemote<mojom::FastPairDataParser> fast_pair_data_parser;
- mojo::PendingReceiver<mojom::FastPairDataParser>
- fast_pair_data_parser_receiver =
- fast_pair_data_parser.InitWithNewPipeAndPassReceiver();
- fast_pair_data_parser_.Bind(std::move(fast_pair_data_parser),
- /*bind_task_runner=*/nullptr);
- fast_pair_data_parser_.set_disconnect_handler(
- base::BindOnce(&QuickPairProcessManagerImpl::ShutdownProcess,
- weak_ptr_factory_.GetWeakPtr(),
- ShutdownReason::kFastPairDataParserMojoPipeDisconnection),
- base::SequencedTaskRunnerHandle::Get());
- service_->Connect(std::move(fast_pair_data_parser_receiver));
- }
- void QuickPairProcessManagerImpl::OnReferenceDeleted(
- base::UnguessableToken id) {
- auto it = id_to_process_stopped_callback_map_.find(id);
- DCHECK(it != id_to_process_stopped_callback_map_.end());
- // Do not call the callback because its owner has already explicitly deleted
- // its reference.
- id_to_process_stopped_callback_map_.erase(it);
- // If there are still active references, the process should be kept alive, so
- // return early.
- if (!id_to_process_stopped_callback_map_.empty())
- return;
- QP_LOG(VERBOSE)
- << "All process references have been released. Starting shutdown timer";
- process_shutdown_controller_->Start(
- base::BindOnce(&QuickPairProcessManagerImpl::ShutdownProcess,
- weak_ptr_factory_.GetWeakPtr(), ShutdownReason::kNormal));
- }
- void QuickPairProcessManagerImpl::ShutdownProcess(
- ShutdownReason shutdown_reason) {
- if (!service_ && !fast_pair_data_parser_)
- return;
- QP_LOG(WARNING) << __func__ << ": " << shutdown_reason;
- // Ensure that we don't try to stop the process again.
- process_shutdown_controller_->Stop();
- // Prevent the Remotes' disconnect handler and the OnReferenceDeleted
- // callbacks from firing.
- weak_ptr_factory_.InvalidateWeakPtrs();
- service_.reset();
- fast_pair_data_parser_.reset();
- // Move the map to a local variable to ensure that the instance field is
- // empty before any callbacks are made.
- auto old_map = std::move(id_to_process_stopped_callback_map_);
- id_to_process_stopped_callback_map_.clear();
- // Invoke the "process stopped" callback for each client.
- for (auto& it : old_map)
- std::move(it.second).Run(shutdown_reason);
- }
- } // namespace quick_pair
- } // namespace ash
|