// Copyright 2014 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 "device/bluetooth/bluetooth_discovery_session.h" #include "base/bind.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_discovery_filter.h" namespace device { BluetoothDiscoverySession::BluetoothDiscoverySession( scoped_refptr adapter, scoped_ptr discovery_filter) : active_(true), adapter_(adapter), discovery_filter_(discovery_filter.release()), weak_ptr_factory_(this) { DCHECK(adapter_.get()); } BluetoothDiscoverySession::~BluetoothDiscoverySession() { if (active_) { Stop(base::Bind(&base::DoNothing), base::Bind(&base::DoNothing)); MarkAsInactive(); } } bool BluetoothDiscoverySession::IsActive() const { return active_; } void BluetoothDiscoverySession::Stop(const base::Closure& success_callback, const ErrorCallback& error_callback) { if (!active_) { LOG(WARNING) << "Discovery session not active. Cannot stop."; BluetoothAdapter::RecordBluetoothDiscoverySessionStopOutcome( UMABluetoothDiscoverySessionOutcome::NOT_ACTIVE); error_callback.Run(); return; } VLOG(1) << "Stopping device discovery session."; base::Closure deactive_discovery_session = base::Bind(&BluetoothDiscoverySession::DeactivateDiscoverySession, weak_ptr_factory_.GetWeakPtr()); // Create a callback that runs // BluetoothDiscoverySession::DeactivateDiscoverySession if the session still // exists, but always runs success_callback. base::Closure discovery_session_removed_callback = base::Bind(&BluetoothDiscoverySession::OnDiscoverySessionRemoved, deactive_discovery_session, success_callback); adapter_->RemoveDiscoverySession( discovery_filter_.get(), discovery_session_removed_callback, base::Bind(&BluetoothDiscoverySession::OnDiscoverySessionRemovalFailed, error_callback)); } // static void BluetoothDiscoverySession::OnDiscoverySessionRemoved( const base::Closure& deactivate_discovery_session, const base::Closure& success_callback) { BluetoothAdapter::RecordBluetoothDiscoverySessionStopOutcome( UMABluetoothDiscoverySessionOutcome::SUCCESS); deactivate_discovery_session.Run(); success_callback.Run(); } // static void BluetoothDiscoverySession::OnDiscoverySessionRemovalFailed( const base::Closure& error_callback, UMABluetoothDiscoverySessionOutcome outcome) { BluetoothAdapter::RecordBluetoothDiscoverySessionStopOutcome(outcome); error_callback.Run(); } void BluetoothDiscoverySession::DeactivateDiscoverySession() { MarkAsInactive(); discovery_filter_.reset(); } void BluetoothDiscoverySession::MarkAsInactive() { if (!active_) return; active_ = false; adapter_->DiscoverySessionBecameInactive(this); } static void IgnoreDiscoveryOutcome( const base::Closure& error_callback, UMABluetoothDiscoverySessionOutcome outcome) { error_callback.Run(); } void BluetoothDiscoverySession::SetDiscoveryFilter( scoped_ptr discovery_filter, const base::Closure& callback, const ErrorCallback& error_callback) { discovery_filter_.reset(discovery_filter.release()); // BluetoothDiscoverySession::SetDiscoveryFilter is only used from a private // extension API, so we don't bother histogramming its failures. adapter_->SetDiscoveryFilter( adapter_->GetMergedDiscoveryFilter().Pass(), callback, base::Bind(&IgnoreDiscoveryOutcome, error_callback)); } const BluetoothDiscoveryFilter* BluetoothDiscoverySession::GetDiscoveryFilter() const { return discovery_filter_.get(); } } // namespace device