Commit e952a67a authored by finnur's avatar finnur Committed by Commit bot

Revert of Fix BluetoothAdapterProfileChromeOS lifecycle management (patchset...

Revert of Fix BluetoothAdapterProfileChromeOS lifecycle management (patchset #7 id:120001 of https://codereview.chromium.org/935383003/)

Reason for revert:
Leaks detected.
https://build.chromium.org/p/chromium.memory/builders/Linux%20Chromium%20OS%20ASan%20LSan%20Tests%20%281%29/builds/7185

=================================================================
==22324==ERROR: LeakSanitizer: detected memory leaks

Indirect leak of 96 byte(s) in 1 object(s) allocated from:
#0 0x4d9b8b in operator new(unsigned long) (/mnt/data/b/build/slave/Linux_Chromium_OS_ASan_LSan_Tests__1_/build/src/out/Release/device_unittests+0x4d9b8b)
#1 0x901bd6 in chromeos::BluetoothAdapterProfileChromeOS::Register(device::BluetoothUUID const&, chromeos::BluetoothProfileManagerClient::Options const&, base::Callback<void (chromeos::BluetoothAdapterProfileChromeOS*)> const&, base::Callback<void (std::string const&, std::string const&)> const&) device/bluetooth/bluetooth_adapter_profile_chromeos.cc:28:7
#2 0x8f6c47 in chromeos::BluetoothAdapterChromeOS::UseProfile(device::BluetoothUUID const&, dbus::ObjectPath const&, chromeos::BluetoothProfileManagerClient::Options const&, chromeos::BluetoothProfileServiceProvider::Delegate*, base::Callback<void (chromeos::BluetoothAdapterProfileChromeOS*)> const&, base::Callback<void (std::string const&)> const&) device/bluetooth/bluetooth_adapter_chromeos.cc:982:5
#3 0x4ec8e2 in chromeos::BluetoothAdapterProfileChromeOSTest_SimultaneousRegisterFail_Test::TestBody() device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc:359:3
#4 0x85da05 in HandleExceptionsInMethodIfSupported<testing::Test, void> testing/gtest/src/gtest.cc:2420:12
#5 0x85da05 in testing::Test::Run() testing/gtest/src/gtest.cc:2436
#6 0x85f619 in testing::TestInfo::Run() testing/gtest/src/gtest.cc:2612:5
#7 0x86040a in testing::TestCase::Run() testing/gtest/src/gtest.cc:2730:5
#8 0x874063 in testing::internal::UnitTestImpl::RunAllTests() testing/gtest/src/gtest.cc:4602:11
#9 0x8736b7 in HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> testing/gtest/src/gtest.cc:2420:12
#10 0x8736b7 in testing::UnitTest::Run() testing/gtest/src/gtest.cc:4220
#11 0x814bda in RUN_ALL_TESTS testing/gtest/include/gtest/gtest.h:2326:10
#12 0x814bda in base::TestSuite::Run() base/test/test_suite.cc:230
#13 0x80ad38 in Run base/callback.h:396:12
#14 0x80ad38 in base::(anonymous namespace)::LaunchUnitTestsInternal(base::Callback<int ()> const&, int, bool, base::Callback<void ()> const&) base/test/launcher/unit_test_launcher.cc:181
#15 0x80a863 in base::LaunchUnitTests(int, char**, base::Callback<int ()> const&) base/test/launcher/unit_test_launcher.cc:423:10
#16 0x7d25ac in main device/test/run_all_unittests.cc:14:10
#17 0x7f35c8c7276c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226

Indirect leak of 93 byte(s) in 1 object(s) allocated from:
#0 0x4d9b8b in operator new(unsigned long) (/mnt/data/b/build/slave/Linux_Chromium_OS_ASan_LSan_Tests__1_/build/src/out/Release/device_unittests+0x4d9b8b)
#1 0x7f35c92df739 in __gnu_cxx::new_allocator<char>::allocate(unsigned long, void const*) /build/buildd/gcc-4.6-4.6.3/build/x86_64-linux-gnu/libstdc++-v3/include/ext/new_allocator.h:92
#2 0x7f35c92ded2c in std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) /build/buildd/gcc-4.6-4.6.3/build/x86_64-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:609
#3 0x7f35c92def04 in std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) /build/buildd/gcc-4.6-4.6.3/build/x86_64-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:631
#4 0x7f35c92dbc48 in std::string::reserve(unsigned long) /build/buildd/gcc-4.6-4.6.3/build/x86_64-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:512
#5 0x9021d7 in operator+<char, std::char_traits<char>, std::allocator<char> > /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/bits/basic_string.tcc:702:7
#6 0x9021d7 in chromeos::BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS(device::BluetoothUUID const&) device/bluetooth/bluetooth_adapter_profile_chromeos.cc:47
#7 0x901be8 in chromeos::BluetoothAdapterProfileChromeOS::Register(device::BluetoothUUID const&, chromeos::BluetoothProfileManagerClient::Options const&, base::Callback<void (chromeos::BluetoothAdapterProfileChromeOS*)> const&, base::Callback<void (std::string const&, std::string const&)> const&) device/bluetooth/bluetooth_adapter_profile_chromeos.cc:28:11
#8 0x8f6c47 in chromeos::BluetoothAdapterChromeOS::UseProfile(device::BluetoothUUID const&, dbus::ObjectPath const&, chromeos::BluetoothProfileManagerClient::Options const&, chromeos::BluetoothProfileServiceProvider::Delegate*, base::Callback<void (chromeos::BluetoothAdapterProfileChromeOS*)> const&, base::Callback<void (std::string const&)> const&) device/bluetooth/bluetooth_adapter_chromeos.cc:982:5
#9 0x4ec8e2 in chromeos::BluetoothAdapterProfileChromeOSTest_SimultaneousRegisterFail_Test::TestBody() device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc:359:3
#10 0x85da05 in HandleExceptionsInMethodIfSupported<testing::Test, void> testing/gtest/src/gtest.cc:2420:12
#11 0x85da05 in testing::Test::Run() testing/gtest/src/gtest.cc:2436
#12 0x85f619 in testing::TestInfo::Run() testing/gtest/src/gtest.cc:2612:5
#13 0x86040a in testing::TestCase::Run() testing/gtest/src/gtest.cc:2730:5
#14 0x874063 in testing::internal::UnitTestImpl::RunAllTests() testing/gtest/src/gtest.cc:4602:11
#15 0x8736b7 in HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> testing/gtest/src/gtest.cc:2420:12
#16 0x8736b7 in testing::UnitTest::Run() testing/gtest/src/gtest.cc:4220
#17 0x814bda in RUN_ALL_TESTS testing/gtest/include/gtest/gtest.h:2326:10
#18 0x814bda in base::TestSuite::Run() base/test/test_suite.cc:230
#19 0x80ad38 in Run base/callback.h:396:12
#20 0x80ad38 in base::(anonymous namespace)::LaunchUnitTestsInternal(base::Callback<int ()> const&, int, bool, base::Callback<void ()> const&) base/test/launcher/unit_test_launcher.cc:181
#21 0x80a863 in base::LaunchUnitTests(int, char**, base::Callback<int ()> const&) base/test/launcher/unit_test_launcher.cc:423:10
#22 0x7d25ac in main device/test/run_all_unittests.cc:14:10
#23 0x7f35c8c7276c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226

Indirect leak of 24 byte(s) in 1 object(s) allocated from:
#0 0x4d9b8b in operator new(unsigned long) (/mnt/data/b/build/slave/Linux_Chromium_OS_ASan_LSan_Tests__1_/build/src/out/Release/device_unittests+0x4d9b8b)
#1 0xd9c743 in chromeos::BluetoothProfileServiceProvider::Create(dbus::Bus*, dbus::ObjectPath const&, chromeos::BluetoothProfileServiceProvider::Delegate*) chromeos/dbus/bluetooth_profile_service_provider.cc:251:12
#2 0x90227f in chromeos::BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS(device::BluetoothUUID const&) device/bluetooth/bluetooth_adapter_profile_chromeos.cc:51:7
#3 0x901be8 in chromeos::BluetoothAdapterProfileChromeOS::Register(device::BluetoothUUID const&, chromeos::BluetoothProfileManagerClient::Options const&, base::Callback<void (chromeos::BluetoothAdapterProfileChromeOS*)> const&, base::Callback<void (std::string const&, std::string const&)> const&) device/bluetooth/bluetooth_adapter_profile_chromeos.cc:28:11
#4 0x8f6c47 in chromeos::BluetoothAdapterChromeOS::UseProfile(device::BluetoothUUID const&, dbus::ObjectPath const&, chromeos::BluetoothProfileManagerClient::Options const&, chromeos::BluetoothProfileServiceProvider::Delegate*, base::Callback<void (chromeos::BluetoothAdapterProfileChromeOS*)> const&, base::Callback<void (std::string const&)> const&) device/bluetooth/bluetooth_adapter_chromeos.cc:982:5
#5 0x4ec8e2 in chromeos::BluetoothAdapterProfileChromeOSTest_SimultaneousRegisterFail_Test::TestBody() device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc:359:3
#6 0x85da05 in HandleExceptionsInMethodIfSupported<testing::Test, void> testing/gtest/src/gtest.cc:2420:12
#7 0x85da05 in testing::Test::Run() testing/gtest/src/gtest.cc:2436
#8 0x85f619 in testing::TestInfo::Run() testing/gtest/src/gtest.cc:2612:5
#9 0x86040a in testing::TestCase::Run() testing/gtest/src/gtest.cc:2730:5
#10 0x874063 in testing::internal::UnitTestImpl::RunAllTests() testing/gtest/src/gtest.cc:4602:11
#11 0x8736b7 in HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> testing/gtest/src/gtest.cc:2420:12
#12 0x8736b7 in testing::UnitTest::Run() testing/gtest/src/gtest.cc:4220
#13 0x814bda in RUN_ALL_TESTS testing/gtest/include/gtest/gtest.h:2326:10
#14 0x814bda in base::TestSuite::Run() base/test/test_suite.cc:230
#15 0x80ad38 in Run base/callback.h:396:12
#16 0x80ad38 in base::(anonymous namespace)::LaunchUnitTestsInternal(base::Callback<int ()> const&, int, bool, base::Callback<void ()> const&) base/test/launcher/unit_test_launcher.cc:181
#17 0x80a863 in base::LaunchUnitTests(int, char**, base::Callback<int ()> const&) base/test/launcher/unit_test_launcher.cc:423:10
#18 0x7d25ac in main device/test/run_all_unittests.cc:14:10
#19 0x7f35c8c7276c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226

Original issue's description:
> Fix BluetoothAdapterProfileChromeOS lifecycle management
>
> Have BluetoothAdapterProfileChromeOS remove itself from adapters when it
> is deleted via it's deconstructor, to avoid references being left behind
> after deletion.
>
> BUG=457978
>
> Committed: https://crrev.com/0cca591aaf6f6a0cbf46840faaead236dd8317a2
> Cr-Commit-Position: refs/heads/master@{#318925}

TBR=keybuk@chromium.org,isherman@chromium.org,armansito@chromium.org,stgao@chromium.org,jamuraa@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=457978

Review URL: https://codereview.chromium.org/975323002

Cr-Commit-Position: refs/heads/master@{#319034}
parent ee687fd9
......@@ -19,8 +19,6 @@ const char FakeBluetoothProfileManagerClient::kL2capUuid[] =
"4d995052-33cc-4fdf-b446-75f32942a076";
const char FakeBluetoothProfileManagerClient::kRfcommUuid[] =
"3f6d6dbf-a6ad-45fc-9653-47dc912ef70e";
const char FakeBluetoothProfileManagerClient::kUnregisterableUuid[] =
"00000000-0000-0000-0000-000000000000";
FakeBluetoothProfileManagerClient::FakeBluetoothProfileManagerClient() {
}
......@@ -39,14 +37,6 @@ void FakeBluetoothProfileManagerClient::RegisterProfile(
const ErrorCallback& error_callback) {
VLOG(1) << "RegisterProfile: " << profile_path.value() << ": " << uuid;
if (uuid == kUnregisterableUuid) {
base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(error_callback,
bluetooth_profile_manager::kErrorInvalidArguments,
"Can't register this UUID"));
return;
}
// check options for channel & psm
ServiceProviderMap::iterator iter = service_provider_map_.find(profile_path);
......
......@@ -51,7 +51,6 @@ class CHROMEOS_EXPORT FakeBluetoothProfileManagerClient
// UUIDs recognised for testing.
static const char kL2capUuid[];
static const char kRfcommUuid[];
static const char kUnregisterableUuid[];
private:
// Map of a D-Bus object path to the FakeBluetoothProfileServiceProvider
......
......@@ -85,13 +85,6 @@ void BluetoothAdapterChromeOS::Shutdown() {
if (IsPresent())
RemoveAdapter(); // Also deletes devices_.
DCHECK(devices_.empty());
// profiles_ should be empty because all BluetoothSockets have been signaled
// that this adapter is disappearing.
DCHECK(profiles_.empty());
for (auto& it : profile_queues_)
delete it.second;
profile_queues_.clear();
DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(this);
DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this);
......@@ -964,12 +957,6 @@ void BluetoothAdapterChromeOS::UseProfile(
const ErrorCompletionCallback& error_callback) {
DCHECK(delegate);
if (!IsPresent()) {
VLOG(2) << "Adapter not present, erroring out";
error_callback.Run("Adapter not present");
return;
}
if (profiles_.find(uuid) != profiles_.end()) {
// TODO(jamuraa) check that the options are the same and error when they are
// not.
......@@ -978,35 +965,15 @@ void BluetoothAdapterChromeOS::UseProfile(
return;
}
if (profile_queues_.find(uuid) == profile_queues_.end()) {
BluetoothAdapterProfileChromeOS::Register(
uuid, options,
base::Bind(&BluetoothAdapterChromeOS::OnRegisterProfile, this, uuid),
base::Bind(&BluetoothAdapterChromeOS::OnRegisterProfileError, this,
uuid));
profile_queues_[uuid] = new std::vector<RegisterProfileCompletionPair>();
}
profile_queues_[uuid]->push_back(std::make_pair(
base::Bind(&BluetoothAdapterChromeOS::SetProfileDelegate, this, uuid,
profiles_[uuid] = BluetoothAdapterProfileChromeOS::Register(
this, uuid, options,
base::Bind(&BluetoothAdapterChromeOS::OnRegisterProfile, this, uuid,
device_path, delegate, success_callback, error_callback),
error_callback));
}
void BluetoothAdapterChromeOS::ReleaseProfile(
const dbus::ObjectPath& device_path,
BluetoothAdapterProfileChromeOS* profile) {
VLOG(2) << "Releasing Profile: " << profile->uuid().canonical_value()
<< " from " << device_path.value();
profile->RemoveDelegate(
device_path, base::Bind(&BluetoothAdapterChromeOS::RemoveProfile,
weak_ptr_factory_.GetWeakPtr(), profile->uuid()));
base::Bind(&BluetoothAdapterChromeOS::OnRegisterProfileError, this, uuid,
error_callback));
}
void BluetoothAdapterChromeOS::RemoveProfile(const BluetoothUUID& uuid) {
VLOG(2) << "Remove Profile: " << uuid.canonical_value();
void BluetoothAdapterChromeOS::ReleaseProfile(const BluetoothUUID& uuid) {
if (profiles_.find(uuid) != profiles_.end()) {
delete profiles_[uuid];
profiles_.erase(uuid);
......@@ -1015,52 +982,39 @@ void BluetoothAdapterChromeOS::RemoveProfile(const BluetoothUUID& uuid) {
void BluetoothAdapterChromeOS::OnRegisterProfile(
const BluetoothUUID& uuid,
BluetoothAdapterProfileChromeOS* profile) {
profiles_[uuid] = profile;
if (profile_queues_.find(uuid) == profile_queues_.end())
return;
for (auto& it : *profile_queues_[uuid])
it.first.Run();
delete profile_queues_[uuid];
profile_queues_.erase(uuid);
const dbus::ObjectPath& device_path,
BluetoothProfileServiceProvider::Delegate* delegate,
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback) {
SetProfileDelegate(uuid, device_path, delegate, success_callback,
error_callback);
}
void BluetoothAdapterChromeOS::SetProfileDelegate(
bool BluetoothAdapterChromeOS::SetProfileDelegate(
const BluetoothUUID& uuid,
const dbus::ObjectPath& device_path,
BluetoothProfileServiceProvider::Delegate* delegate,
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback) {
if (profiles_.find(uuid) == profiles_.end()) {
error_callback.Run("Cannot find profile!");
return;
}
if (profiles_[uuid]->SetDelegate(device_path, delegate)) {
success_callback.Run(profiles_[uuid]);
return;
return true;
}
// Already set
error_callback.Run(bluetooth_agent_manager::kErrorAlreadyExists);
return false;
}
void BluetoothAdapterChromeOS::OnRegisterProfileError(
const BluetoothUUID& uuid,
const ErrorCompletionCallback& error_callback,
const std::string& error_name,
const std::string& error_message) {
VLOG(2) << object_path_.value() << ": Failed to register profile: "
<< error_name << ": " << error_message;
if (profile_queues_.find(uuid) == profile_queues_.end())
return;
for (auto& it : *profile_queues_[uuid])
it.second.Run(error_message);
delete profile_queues_[uuid];
profile_queues_.erase(uuid);
LOG(WARNING) << object_path_.value()
<< ": Failed to register profile: " << error_name << ": "
<< error_message;
error_callback.Run(error_message);
ReleaseProfile(uuid);
}
void BluetoothAdapterChromeOS::OnSetDiscoverable(
......
......@@ -145,9 +145,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback);
// Release use of a profile by a device.
void ReleaseProfile(const dbus::ObjectPath& device_path,
BluetoothAdapterProfileChromeOS* profile);
// Releases the profile associated with |uuid|
void ReleaseProfile(const device::BluetoothUUID& uuid);
protected:
// BluetoothAdapter:
......@@ -284,21 +283,20 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
// Called by dbus:: on completion of the D-Bus method to register a profile.
void OnRegisterProfile(const device::BluetoothUUID& uuid,
BluetoothAdapterProfileChromeOS* profile);
void SetProfileDelegate(const device::BluetoothUUID& uuid,
const dbus::ObjectPath& device_path,
BluetoothProfileServiceProvider::Delegate* delegate,
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback);
bool SetProfileDelegate(const device::BluetoothUUID& uuid,
const dbus::ObjectPath& device_path,
BluetoothProfileServiceProvider::Delegate* delegate,
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback);
void OnRegisterProfileError(const device::BluetoothUUID& uuid,
const ErrorCompletionCallback& error_callback,
const std::string& error_name,
const std::string& error_message);
// Called by BluetoothAdapterProfileChromeOS when no users of a profile
// remain.
void RemoveProfile(const device::BluetoothUUID& uuid);
// Processes the queued discovery requests. For each DiscoveryCallbackPair in
// the queue, this method will try to add a new discovery session. This method
// is called whenever a pending D-Bus call to start or stop discovery has
......@@ -342,14 +340,6 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
// The profiles we have registered with the bluetooth daemon.
std::map<device::BluetoothUUID, BluetoothAdapterProfileChromeOS*> profiles_;
// Callback pair for the profile registration queue.
typedef std::pair<base::Closure, ErrorCompletionCallback>
RegisterProfileCompletionPair;
// Queue of delegates waiting for a profile to register.
std::map<device::BluetoothUUID, std::vector<RegisterProfileCompletionPair>*>
profile_queues_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<BluetoothAdapterChromeOS> weak_ptr_factory_;
......
......@@ -20,27 +20,28 @@ namespace chromeos {
// static
BluetoothAdapterProfileChromeOS* BluetoothAdapterProfileChromeOS::Register(
BluetoothAdapterChromeOS* adapter,
const device::BluetoothUUID& uuid,
const BluetoothProfileManagerClient::Options& options,
const BluetoothAdapterChromeOS::ProfileRegisteredCallback& success_callback,
const base::Closure& success_callback,
const BluetoothProfileManagerClient::ErrorCallback& error_callback) {
DCHECK(adapter);
BluetoothAdapterProfileChromeOS* profile =
new BluetoothAdapterProfileChromeOS(uuid);
new BluetoothAdapterProfileChromeOS(adapter, uuid);
VLOG(1) << "Registering profile: " << profile->object_path().value();
DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->RegisterProfile(
profile->object_path(),
uuid.canonical_value(),
options,
base::Bind(success_callback, profile),
profile->object_path(), uuid.canonical_value(), options, success_callback,
error_callback);
return profile;
}
BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS(
BluetoothAdapterChromeOS* adapter,
const device::BluetoothUUID& uuid)
: uuid_(uuid), weak_ptr_factory_(this) {
: uuid_(uuid), adapter_(adapter), weak_ptr_factory_(this) {
std::string uuid_path;
base::ReplaceChars(uuid.canonical_value(), ":-", "_", &uuid_path);
object_path_ =
......@@ -53,6 +54,7 @@ BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS(
}
BluetoothAdapterProfileChromeOS::~BluetoothAdapterProfileChromeOS() {
profile_.reset();
}
bool BluetoothAdapterProfileChromeOS::SetDelegate(
......
......@@ -21,22 +21,17 @@ namespace chromeos {
// profile for custom Bluetooth services managed by a BluetoothAdapter.
// Maintains a list of delegates which may serve the profile.
// One delegate is allowed for each device.
//
// BluetoothAdapterProfileChromeOS objects are owned by the
// BluetoothAdapterChromeOS and allocated through Register()
class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS
: public chromeos::BluetoothProfileServiceProvider::Delegate {
public:
typedef base::Callback<void(BluetoothAdapterProfileChromeOS* profile)>
ProfileRegisteredCallback;
// Registers a profile with the BlueZ server for |uuid| with the
// options |options|. Returns a newly allocated pointer, or nullptr
// if there was a problem.
static BluetoothAdapterProfileChromeOS* Register(
BluetoothAdapterChromeOS* adapter,
const device::BluetoothUUID& uuid,
const BluetoothProfileManagerClient::Options& options,
const ProfileRegisteredCallback& success_callback,
const base::Closure& success_callback,
const BluetoothProfileManagerClient::ErrorCallback& error_callback);
~BluetoothAdapterProfileChromeOS() override;
......@@ -44,9 +39,6 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS
// The object path of the profile.
const dbus::ObjectPath& object_path() const { return object_path_; }
// Returns the UUID of the profile
const device::BluetoothUUID& uuid() const { return uuid_; }
// Add a delegate for a device associated with this profile.
// An empty |device_path| indicates a local listening service.
// Returns true if the delegate was set, and false if the |device_path|
......@@ -63,7 +55,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS
size_t DelegateCount() const { return delegates_.size(); }
private:
BluetoothAdapterProfileChromeOS(const device::BluetoothUUID& uuid);
BluetoothAdapterProfileChromeOS(BluetoothAdapterChromeOS* adapter,
const device::BluetoothUUID& uuid);
// BluetoothProfileServiceProvider::Delegate:
void Released() override;
......@@ -93,6 +86,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS
// Profile dbus object for receiving profile method calls from BlueZ
scoped_ptr<BluetoothProfileServiceProvider> profile_;
// Adapter that owns this profile.
BluetoothAdapterChromeOS* adapter_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<BluetoothAdapterProfileChromeOS> weak_ptr_factory_;
......
......@@ -20,6 +20,14 @@
using device::BluetoothAdapter;
using device::BluetoothUUID;
namespace {
void DoNothingDBusErrorCallback(const std::string& error_name,
const std::string& error_message) {
}
} // namespace
namespace chromeos {
class BluetoothAdapterProfileChromeOSTest : public testing::Test {
......@@ -94,7 +102,7 @@ class BluetoothAdapterProfileChromeOSTest : public testing::Test {
close(fd->TakeValue());
callback.Run(SUCCESS);
if (device_path_.value() != "")
ASSERT_EQ(device_path_, device_path);
ASSERT_TRUE(device_path == device_path_);
}
void RequestDisconnection(const dbus::ObjectPath& device_path,
......@@ -119,17 +127,6 @@ class BluetoothAdapterProfileChromeOSTest : public testing::Test {
BluetoothAdapterProfileChromeOS* profile_;
void ProfileSuccessCallback(BluetoothAdapterProfileChromeOS* profile) {
profile_ = profile;
++success_callback_count_;
}
void MatchedProfileCallback(BluetoothAdapterProfileChromeOS* profile) {
VLOG(1) << "Matched Profile Callback";
ASSERT_EQ(profile_, profile);
++success_callback_count_;
}
void DBusConnectSuccessCallback() { ++success_callback_count_; }
void DBusErrorCallback(const std::string& error_name,
......@@ -138,11 +135,6 @@ class BluetoothAdapterProfileChromeOSTest : public testing::Test {
++error_callback_count_;
}
void BasicErrorCallback(const std::string& error_message) {
VLOG(1) << "Error: " << error_message;
++error_callback_count_;
}
protected:
base::MessageLoop message_loop_;
......@@ -158,18 +150,13 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, DelegateCount) {
options.require_authentication.reset(new bool(false));
BluetoothAdapterProfileChromeOS::Register(
uuid, options,
base::Bind(&BluetoothAdapterProfileChromeOSTest::ProfileSuccessCallback,
base::Unretained(this)),
base::Bind(&BluetoothAdapterProfileChromeOSTest::DBusErrorCallback,
base::Unretained(this)));
profile_ = BluetoothAdapterProfileChromeOS::Register(
static_cast<BluetoothAdapterChromeOS*>(adapter_.get()), uuid, options,
base::Bind(&base::DoNothing), base::Bind(&DoNothingDBusErrorCallback));
message_loop_.RunUntilIdle();
EXPECT_TRUE(profile_);
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_EQ(0U, profile_->DelegateCount());
......@@ -197,10 +184,11 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, BlackHole) {
options.require_authentication.reset(new bool(false));
BluetoothAdapterProfileChromeOS::Register(
uuid, options,
base::Bind(&BluetoothAdapterProfileChromeOSTest::ProfileSuccessCallback,
base::Unretained(this)),
profile_ = BluetoothAdapterProfileChromeOS::Register(
static_cast<BluetoothAdapterChromeOS*>(adapter_.get()), uuid, options,
base::Bind(
&BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback,
base::Unretained(this)),
base::Bind(&BluetoothAdapterProfileChromeOSTest::DBusErrorCallback,
base::Unretained(this)));
......@@ -236,17 +224,16 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, Routing) {
options.require_authentication.reset(new bool(false));
profile_ = BluetoothAdapterProfileChromeOS::Register(
uuid, options,
base::Bind(&BluetoothAdapterProfileChromeOSTest::ProfileSuccessCallback,
base::Unretained(this)),
static_cast<BluetoothAdapterChromeOS*>(adapter_.get()), uuid, options,
base::Bind(
&BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback,
base::Unretained(this)),
base::Bind(&BluetoothAdapterProfileChromeOSTest::DBusErrorCallback,
base::Unretained(this)));
message_loop_.RunUntilIdle();
ASSERT_TRUE(profile_);
ASSERT_EQ(1U, success_callback_count_);
ASSERT_EQ(0U, error_callback_count_);
profile_->SetDelegate(fake_delegate_paired_.device_path_,
&fake_delegate_paired_);
......@@ -307,75 +294,4 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, Routing) {
delete profile_;
};
TEST_F(BluetoothAdapterProfileChromeOSTest, SimultaneousRegister) {
BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kRfcommUuid);
BluetoothProfileManagerClient::Options options;
BluetoothAdapterChromeOS* adapter =
static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
options.require_authentication.reset(new bool(false));
success_callback_count_ = 0;
error_callback_count_ = 0;
adapter->UseProfile(
uuid, fake_delegate_paired_.device_path_, options, &fake_delegate_paired_,
base::Bind(&BluetoothAdapterProfileChromeOSTest::ProfileSuccessCallback,
base::Unretained(this)),
base::Bind(&BluetoothAdapterProfileChromeOSTest::BasicErrorCallback,
base::Unretained(this)));
adapter->UseProfile(
uuid, fake_delegate_autopair_.device_path_, options,
&fake_delegate_autopair_,
base::Bind(&BluetoothAdapterProfileChromeOSTest::MatchedProfileCallback,
base::Unretained(this)),
base::Bind(&BluetoothAdapterProfileChromeOSTest::BasicErrorCallback,
base::Unretained(this)));
message_loop_.RunUntilIdle();
EXPECT_TRUE(profile_);
EXPECT_EQ(2U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
adapter->ReleaseProfile(fake_delegate_paired_.device_path_, profile_);
adapter->ReleaseProfile(fake_delegate_autopair_.device_path_, profile_);
message_loop_.RunUntilIdle();
};
TEST_F(BluetoothAdapterProfileChromeOSTest, SimultaneousRegisterFail) {
BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kUnregisterableUuid);
BluetoothProfileManagerClient::Options options;
BluetoothAdapterChromeOS* adapter =
static_cast<BluetoothAdapterChromeOS*>(adapter_.get());
options.require_authentication.reset(new bool(false));
success_callback_count_ = 0;
error_callback_count_ = 0;
adapter->UseProfile(
uuid, fake_delegate_paired_.device_path_, options, &fake_delegate_paired_,
base::Bind(&BluetoothAdapterProfileChromeOSTest::ProfileSuccessCallback,
base::Unretained(this)),
base::Bind(&BluetoothAdapterProfileChromeOSTest::BasicErrorCallback,
base::Unretained(this)));
adapter->UseProfile(
uuid, fake_delegate_autopair_.device_path_, options,
&fake_delegate_autopair_,
base::Bind(&BluetoothAdapterProfileChromeOSTest::MatchedProfileCallback,
base::Unretained(this)),
base::Bind(&BluetoothAdapterProfileChromeOSTest::BasicErrorCallback,
base::Unretained(this)));
message_loop_.RunUntilIdle();
EXPECT_FALSE(profile_);
EXPECT_EQ(0U, success_callback_count_);
EXPECT_EQ(2U, error_callback_count_);
};
} // namespace chromeos
......@@ -324,8 +324,7 @@ class BluetoothChromeOSTest : public testing::Test {
QuitMessageLoop();
}
void ProfileRegisteredCallback(BluetoothAdapterProfileChromeOS* profile) {
adapter_profile_ = profile;
void ProfileRegisteredCallback(BluetoothAdapterProfileChromeOS*) {
++callback_count_;
QuitMessageLoop();
}
......@@ -427,7 +426,6 @@ class BluetoothChromeOSTest : public testing::Test {
enum BluetoothDevice::ConnectErrorCode last_connect_error_;
std::string last_client_error_;
ScopedVector<BluetoothDiscoverySession> discovery_sessions_;
BluetoothAdapterProfileChromeOS *adapter_profile_;
private:
// Some tests use a message loop since background processing is simulated;
......@@ -3190,8 +3188,6 @@ TEST_F(BluetoothChromeOSTest, Shutdown) {
EXPECT_EQ(dbus::ObjectPath(""), adapter_chrome_os->object_path());
adapter_profile_ = NULL;
FakeBluetoothProfileServiceProviderDelegate profile_delegate;
adapter_chrome_os->UseProfile(
BluetoothUUID(), dbus::ObjectPath(""),
......@@ -3200,10 +3196,11 @@ TEST_F(BluetoothChromeOSTest, Shutdown) {
base::Unretained(this)),
base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback,
base::Unretained(this)));
base::MessageLoop::current()->Run();
EXPECT_EQ(1, callback_count_--) << "UseProfile error";
EXPECT_EQ(0, error_callback_count_) << "UseProfile error";
EXPECT_FALSE(adapter_profile_) << "UseProfile error";
EXPECT_EQ(0, callback_count_) << "UseProfile error";
EXPECT_EQ(1, error_callback_count_--) << "UseProfile error";
adapter_chrome_os->ReleaseProfile(BluetoothUUID());
// Protected and private methods:
......@@ -3261,8 +3258,6 @@ TEST_F(BluetoothChromeOSTest, Shutdown) {
// OnStopDiscovery tested in Shutdown_OnStopDiscovery
// OnStopDiscoveryError tested in Shutdown_OnStopDiscoveryError
adapter_profile_ = NULL;
// OnRegisterProfile SetProfileDelegate, OnRegisterProfileError, require
// UseProfile to be set first, do so again here just before calling them.
adapter_chrome_os->UseProfile(
......@@ -3273,9 +3268,14 @@ TEST_F(BluetoothChromeOSTest, Shutdown) {
base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback,
base::Unretained(this)));
EXPECT_FALSE(adapter_profile_) << "UseProfile error";
EXPECT_EQ(0, callback_count_) << "UseProfile error";
EXPECT_EQ(1, error_callback_count_--) << "UseProfile error";
adapter_chrome_os->OnRegisterProfile(
BluetoothUUID(), dbus::ObjectPath(""), &profile_delegate,
base::Bind(&BluetoothChromeOSTest::ProfileRegisteredCallback,
base::Unretained(this)),
base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback,
base::Unretained(this)));
EXPECT_EQ(1, callback_count_--) << "OnRegisterProfile error";
EXPECT_EQ(1, error_callback_count_--) << "OnRegisterProfile error";
adapter_chrome_os->SetProfileDelegate(
BluetoothUUID(), dbus::ObjectPath(""), &profile_delegate,
......@@ -3286,9 +3286,13 @@ TEST_F(BluetoothChromeOSTest, Shutdown) {
EXPECT_EQ(0, callback_count_) << "SetProfileDelegate error";
EXPECT_EQ(1, error_callback_count_--) << "SetProfileDelegate error";
adapter_chrome_os->OnRegisterProfileError(BluetoothUUID(), "", "");
adapter_chrome_os->OnRegisterProfileError(
BluetoothUUID(),
base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback,
base::Unretained(this)),
"", "");
EXPECT_EQ(0, callback_count_) << "OnRegisterProfileError error";
EXPECT_EQ(0, error_callback_count_) << "OnRegisterProfileError error";
EXPECT_EQ(1, error_callback_count_--) << "OnRegisterProfileError error";
adapter_chrome_os->ProcessQueuedDiscoveryRequests();
......
......@@ -110,8 +110,6 @@ void BluetoothSocketChromeOS::Connect(
if (security_level == SECURITY_LEVEL_LOW)
options_->require_authentication.reset(new bool(false));
adapter_ = device->adapter();
RegisterProfile(device->adapter(), success_callback, error_callback);
}
......@@ -130,8 +128,7 @@ void BluetoothSocketChromeOS::Listen(
return;
}
adapter_ = adapter;
adapter_->AddObserver(this);
adapter->AddObserver(this);
uuid_ = uuid;
options_.reset(new BluetoothProfileManagerClient::Options());
......@@ -224,10 +221,12 @@ void BluetoothSocketChromeOS::RegisterProfile(
DCHECK(!profile_);
DCHECK(adapter);
adapter_ = adapter;
// If the adapter is not present, this is a listening socket and the
// adapter isn't running yet. Report success and carry on;
// the profile will be registered when the daemon becomes available.
if (!adapter->IsPresent()) {
if (!adapter_->IsPresent()) {
VLOG(1) << uuid_.canonical_value() << " on " << device_path_.value()
<< ": Delaying profile registration.";
base::MessageLoop::current()->PostTask(FROM_HERE, success_callback);
......@@ -310,7 +309,7 @@ void BluetoothSocketChromeOS::AdapterPresentChanged(BluetoothAdapter* adapter,
DCHECK(ui_task_runner()->RunsTasksOnCurrentThread());
if (!present) {
// Adapter removed, we can't use the profile anymore.
// Adapter removed, the profile is now invalid.
UnregisterProfile();
return;
}
......@@ -550,9 +549,20 @@ void BluetoothSocketChromeOS::UnregisterProfile() {
VLOG(1) << profile_->object_path().value() << ": Release profile";
static_cast<BluetoothAdapterChromeOS*>(adapter_.get())
->ReleaseProfile(device_path_, profile_);
profile_->RemoveDelegate(
device_path_,
base::Bind(&BluetoothSocketChromeOS::ReleaseProfile, this, profile_));
profile_ = nullptr;
}
void BluetoothSocketChromeOS::ReleaseProfile(
BluetoothAdapterProfileChromeOS* profile) {
if (adapter_)
static_cast<BluetoothAdapterChromeOS*>(adapter_.get())
->ReleaseProfile(uuid_);
else
delete profile;
}
} // namespace chromeos
......@@ -148,10 +148,12 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS
// Method run to clean-up a listening socket.
void DoCloseListening();
// Unregisters this socket's usage of the Bluetooth profile which cleans up
// the profile if no one is using it.
// Unregister the underlying profile client object from the Bluetooth Daemon.
void UnregisterProfile();
// Releases the profile after the delegate is gone.
void ReleaseProfile(BluetoothAdapterProfileChromeOS* profile);
// Adapter the profile is registered against
scoped_refptr<device::BluetoothAdapter> adapter_;
......
......@@ -107,8 +107,7 @@ class BluetoothSocketChromeOSTest : public testing::Test {
++error_callback_count_;
last_message_ = message;
if (message_loop_.is_running())
message_loop_.Quit();
message_loop_.Quit();
}
void ConnectToServiceSuccessCallback(scoped_refptr<BluetoothSocket> socket) {
......@@ -559,71 +558,4 @@ TEST_F(BluetoothSocketChromeOSTest, PairedConnectFails) {
EXPECT_TRUE(last_socket_.get() == NULL);
}
TEST_F(BluetoothSocketChromeOSTest, SocketListenTwice) {
adapter_->CreateRfcommService(
BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
BluetoothAdapter::ServiceOptions(),
base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
base::Unretained(this)),
base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
base::Unretained(this)));
message_loop_.Run();
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != NULL);
// Take control of this socket.
scoped_refptr<BluetoothSocket> server_socket;
server_socket.swap(last_socket_);
server_socket->Accept(
base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback,
base::Unretained(this)),
base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
base::Unretained(this)));
server_socket->Close();
server_socket = NULL;
message_loop_.RunUntilIdle();
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(1U, error_callback_count_);
adapter_->CreateRfcommService(
BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
BluetoothAdapter::ServiceOptions(),
base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
base::Unretained(this)),
base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
base::Unretained(this)));
message_loop_.Run();
EXPECT_EQ(2U, success_callback_count_);
EXPECT_EQ(1U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != NULL);
// Take control of this socket.
server_socket.swap(last_socket_);
server_socket->Accept(
base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback,
base::Unretained(this)),
base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
base::Unretained(this)));
server_socket->Close();
server_socket = NULL;
message_loop_.RunUntilIdle();
EXPECT_EQ(2U, success_callback_count_);
EXPECT_EQ(2U, error_callback_count_);
}
} // namespace chromeos
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment