<commit_before>// Copyright 2013 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_socket_chromeos.h"

#include <queue>
#include <string>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_util.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/worker_pool.h"
#include "chromeos/dbus/bluetooth_device_client.h"
#include "chromeos/dbus/bluetooth_profile_manager_client.h"
#include "chromeos/dbus/bluetooth_profile_service_provider.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "dbus/bus.h"
#include "dbus/file_descriptor.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_chromeos.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_device_chromeos.h"
#include "device/bluetooth/bluetooth_socket.h"
#include "device/bluetooth/bluetooth_socket_net.h"
#include "device/bluetooth/bluetooth_socket_thread.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

using device::BluetoothAdapter;
using device::BluetoothDevice;
using device::BluetoothSocketThread;
using device::BluetoothUUID;

namespace {

const char kAcceptFailed[] = "Failed to accept connection.";
const char kInvalidUUID[] = "Invalid UUID";
const char kSocketNotListening[] = "Socket is not listening.";

}  // namespace

namespace chromeos {

// static
scoped_refptr<BluetoothSocketChromeOS>
BluetoothSocketChromeOS::CreateBluetoothSocket(
    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
    scoped_refptr<BluetoothSocketThread> socket_thread) {
  DCHECK(ui_task_runner->RunsTasksOnCurrentThread());

  return make_scoped_refptr(
      new BluetoothSocketChromeOS(ui_task_runner, socket_thread));
}

BluetoothSocketChromeOS::AcceptRequest::AcceptRequest() {}

BluetoothSocketChromeOS::AcceptRequest::~AcceptRequest() {}

BluetoothSocketChromeOS::ConnectionRequest::ConnectionRequest()
    : accepting(false),
      cancelled(false) {}

BluetoothSocketChromeOS::ConnectionRequest::~ConnectionRequest() {}

BluetoothSocketChromeOS::BluetoothSocketChromeOS(
    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
    scoped_refptr<BluetoothSocketThread> socket_thread)
    : BluetoothSocketNet(ui_task_runner, socket_thread) {
}

BluetoothSocketChromeOS::~BluetoothSocketChromeOS() {
  DCHECK(object_path_.value().empty());
  DCHECK(profile_.get() == NULL);

  if (adapter_.get()) {
    adapter_->RemoveObserver(this);
    adapter_ = NULL;
  }
}

void BluetoothSocketChromeOS::Connect(
    const BluetoothDeviceChromeOS* device,
    const BluetoothUUID& uuid,
    const base::Closure& success_callback,
    const ErrorCompletionCallback& error_callback) {
  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
  DCHECK(object_path_.value().empty());
  DCHECK(!profile_.get());

  if (!uuid.IsValid()) {
    error_callback.Run(kInvalidUUID);
    return;
  }

  device_address_ = device->GetAddress();
  device_path_ = device->object_path();
  uuid_ = uuid;
  options_.reset(new BluetoothProfileManagerClient::Options());

  RegisterProfile(success_callback, error_callback);
}

void BluetoothSocketChromeOS::Listen(
    scoped_refptr<BluetoothAdapter> adapter,
    SocketType socket_type,
    const BluetoothUUID& uuid,
    const BluetoothAdapter::ServiceOptions& service_options,
    const base::Closure& success_callback,
    const ErrorCompletionCallback& error_callback) {
  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
  DCHECK(object_path_.value().empty());
  DCHECK(!profile_.get());

  if (!uuid.IsValid()) {
    error_callback.Run(kInvalidUUID);
    return;
  }

  adapter_ = adapter;
  adapter_->AddObserver(this);

  uuid_ = uuid;
  options_.reset(new BluetoothProfileManagerClient::Options());
  if (service_options.name)
    options_->name.reset(new std::string(*service_options.name));

  switch (socket_type) {
    case kRfcomm:
      options_->channel.reset(
          new uint16(service_options.channel ? *service_options.channel : 0));
      break;
    case kL2cap:
      options_->psm.reset(
          new uint16(service_options.psm ? *service_options.psm : 0));
      break;
    default:
      NOTREACHED();
  }

  RegisterProfile(success_callback, error_callback);
}

void BluetoothSocketChromeOS::Close() {
  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());

  if (profile_)
    UnregisterProfile();

  if (!device_path_.value().empty()) {
    BluetoothSocketNet::Close();
  } else {
    DoCloseListening();
  }
}

void BluetoothSocketChromeOS::Disconnect(const base::Closure& callback) {
  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());

  if (profile_)
   UnregisterProfile();<commit_msg>device/bluetooth: Release |adapter_| in BluetoothSocketChromeOS::Close.<commit_after>// Copyright 2013 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_socket_chromeos.h"

#include <queue>
#include <string>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_util.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/worker_pool.h"
#include "chromeos/dbus/bluetooth_device_client.h"
#include "chromeos/dbus/bluetooth_profile_manager_client.h"
#include "chromeos/dbus/bluetooth_profile_service_provider.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "dbus/bus.h"
#include "dbus/file_descriptor.h"
#include "dbus/object_path.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_chromeos.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_device_chromeos.h"
#include "device/bluetooth/bluetooth_socket.h"
#include "device/bluetooth/bluetooth_socket_net.h"
#include "device/bluetooth/bluetooth_socket_thread.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

using device::BluetoothAdapter;
using device::BluetoothDevice;
using device::BluetoothSocketThread;
using device::BluetoothUUID;

namespace {

const char kAcceptFailed[] = "Failed to accept connection.";
const char kInvalidUUID[] = "Invalid UUID";
const char kSocketNotListening[] = "Socket is not listening.";

}  // namespace

namespace chromeos {

// static
scoped_refptr<BluetoothSocketChromeOS>
BluetoothSocketChromeOS::CreateBluetoothSocket(
    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
    scoped_refptr<BluetoothSocketThread> socket_thread) {
  DCHECK(ui_task_runner->RunsTasksOnCurrentThread());

  return make_scoped_refptr(
      new BluetoothSocketChromeOS(ui_task_runner, socket_thread));
}

BluetoothSocketChromeOS::AcceptRequest::AcceptRequest() {}

BluetoothSocketChromeOS::AcceptRequest::~AcceptRequest() {}

BluetoothSocketChromeOS::ConnectionRequest::ConnectionRequest()
    : accepting(false),
      cancelled(false) {}

BluetoothSocketChromeOS::ConnectionRequest::~ConnectionRequest() {}

BluetoothSocketChromeOS::BluetoothSocketChromeOS(
    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
    scoped_refptr<BluetoothSocketThread> socket_thread)
    : BluetoothSocketNet(ui_task_runner, socket_thread) {
}

BluetoothSocketChromeOS::~BluetoothSocketChromeOS() {
  DCHECK(object_path_.value().empty());
  DCHECK(profile_.get() == NULL);

  if (adapter_.get()) {
    adapter_->RemoveObserver(this);
    adapter_ = NULL;
  }
}

void BluetoothSocketChromeOS::Connect(
    const BluetoothDeviceChromeOS* device,
    const BluetoothUUID& uuid,
    const base::Closure& success_callback,
    const ErrorCompletionCallback& error_callback) {
  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
  DCHECK(object_path_.value().empty());
  DCHECK(!profile_.get());

  if (!uuid.IsValid()) {
    error_callback.Run(kInvalidUUID);
    return;
  }

  device_address_ = device->GetAddress();
  device_path_ = device->object_path();
  uuid_ = uuid;
  options_.reset(new BluetoothProfileManagerClient::Options());

  RegisterProfile(success_callback, error_callback);
}

void BluetoothSocketChromeOS::Listen(
    scoped_refptr<BluetoothAdapter> adapter,
    SocketType socket_type,
    const BluetoothUUID& uuid,
    const BluetoothAdapter::ServiceOptions& service_options,
    const base::Closure& success_callback,
    const ErrorCompletionCallback& error_callback) {
  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
  DCHECK(object_path_.value().empty());
  DCHECK(!profile_.get());

  if (!uuid.IsValid()) {
    error_callback.Run(kInvalidUUID);
    return;
  }

  adapter_ = adapter;
  adapter_->AddObserver(this);

  uuid_ = uuid;
  options_.reset(new BluetoothProfileManagerClient::Options());
  if (service_options.name)
    options_->name.reset(new std::string(*service_options.name));

  switch (socket_type) {
    case kRfcomm:
      options_->channel.reset(
          new uint16(service_options.channel ? *service_options.channel : 0));
      break;
    case kL2cap:
      options_->psm.reset(
          new uint16(service_options.psm ? *service_options.psm : 0));
      break;
    default:
      NOTREACHED();
  }

  RegisterProfile(success_callback, error_callback);
}

void BluetoothSocketChromeOS::Close() {
  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());

  if (profile_)
    UnregisterProfile();

  // In the case below, where an asynchronous task gets posted on the socket
  // thread in BluetoothSocketNet::Close, a reference will be held to this
  // socket by the callback. This may cause the BluetoothAdapter to outlive
  // DBusThreadManager during shutdown if that callback executes too late.
  if (adapter_.get()) {
    adapter_->RemoveObserver(this);
    adapter_ = NULL;
  }

  if (!device_path_.value().empty()) {
    BluetoothSocketNet::Close();
  } else {
    DoCloseListening();
  }
}

void BluetoothSocketChromeOS::Disconnect(const base::Closure& callback) {
  DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());

  if (profile_)
   UnregisterProfile();
{'fraction_non_alphanumeric': 0.12023842786625687, 'fraction_numerical': 0.002048989475644966, 'mean_word_length': 5.817777777777778, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4323450', 'n_tokens_mistral': 3420, 'n_tokens_neox': 3385, 'n_words': 583}