17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_vector.h"
69ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromeos/dbus/dbus_thread_manager.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/fake_bluetooth_device_client.h"
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chromeos/dbus/fake_bluetooth_input_client.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/object_path.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "device/bluetooth/bluetooth_adapter.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_chromeos.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_factory.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "device/bluetooth/bluetooth_device.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_device_chromeos.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "device/bluetooth/bluetooth_discovery_session.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "device/bluetooth/bluetooth_pairing_chromeos.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothAdapter;
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothAdapterFactory;
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothDevice;
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using device::BluetoothDiscoverySession;
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochusing device::BluetoothUUID;
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace {
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestObserver : public BluetoothAdapter::Observer {
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver(scoped_refptr<BluetoothAdapter> adapter)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : present_changed_count_(0),
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        powered_changed_count_(0),
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        discoverable_changed_count_(0),
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        discovering_changed_count_(0),
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_present_(false),
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_powered_(false),
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_discovering_(false),
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        device_added_count_(0),
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        device_changed_count_(0),
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        device_removed_count_(0),
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_device_(NULL),
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        adapter_(adapter) {
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    adapter_->AddObserver(this);
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~TestObserver() {
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    adapter_->RemoveObserver(this);
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AdapterPresentChanged(BluetoothAdapter* adapter,
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     bool present) OVERRIDE {
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(adapter_.get(), adapter);
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++present_changed_count_;
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_present_ = present;
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AdapterPoweredChanged(BluetoothAdapter* adapter,
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     bool powered) OVERRIDE {
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(adapter_.get(), adapter);
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++powered_changed_count_;
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_powered_ = powered;
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void AdapterDiscoverableChanged(BluetoothAdapter* adapter,
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          bool discoverable) OVERRIDE {
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(adapter_.get(), adapter);
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ++discoverable_changed_count_;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AdapterDiscoveringChanged(BluetoothAdapter* adapter,
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         bool discovering) OVERRIDE {
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(adapter_.get(), adapter);
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++discovering_changed_count_;
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_discovering_ = discovering;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void DeviceAdded(BluetoothAdapter* adapter,
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           BluetoothDevice* device) OVERRIDE {
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(adapter_.get(), adapter);
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++device_added_count_;
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_ = device;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_address_ = device->GetAddress();
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void DeviceChanged(BluetoothAdapter* adapter,
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             BluetoothDevice* device) OVERRIDE {
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(adapter_.get(), adapter);
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++device_changed_count_;
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_ = device;
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_address_ = device->GetAddress();
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void DeviceRemoved(BluetoothAdapter* adapter,
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             BluetoothDevice* device) OVERRIDE {
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(adapter_.get(), adapter);
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++device_removed_count_;
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Can't save device, it may be freed
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_address_ = device->GetAddress();
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int present_changed_count_;
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int powered_changed_count_;
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int discoverable_changed_count_;
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int discovering_changed_count_;
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool last_present_;
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool last_powered_;
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool last_discovering_;
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int device_added_count_;
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int device_changed_count_;
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int device_removed_count_;
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* last_device_;
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string last_device_address_;
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Some tests use a message loop since background processing is simulated;
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // break out of those loops.
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void QuitMessageLoop() {
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (base::MessageLoop::current() &&
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::MessageLoop::current()->is_running())
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::MessageLoop::current()->Quit();
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<BluetoothAdapter> adapter_;
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace
147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestPairingDelegate : public BluetoothDevice::PairingDelegate {
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate()
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : call_count_(0),
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        request_pincode_count_(0),
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        request_passkey_count_(0),
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        display_pincode_count_(0),
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        display_passkey_count_(0),
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        keys_entered_count_(0),
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        confirm_passkey_count_(0),
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        authorize_pairing_count_(0),
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_passkey_(9999999U),
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_entered_(999U) {}
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~TestPairingDelegate() {}
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void RequestPinCode(BluetoothDevice* device) OVERRIDE {
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++request_pincode_count_;
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
169b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void RequestPasskey(BluetoothDevice* device) OVERRIDE {
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++request_passkey_count_;
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
175b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void DisplayPinCode(BluetoothDevice* device,
176b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                              const std::string& pincode) OVERRIDE {
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++display_pincode_count_;
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_pincode_ = pincode;
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
183b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void DisplayPasskey(BluetoothDevice* device,
184b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                              uint32 passkey) OVERRIDE {
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++display_passkey_count_;
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_passkey_ = passkey;
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
191b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void KeysEntered(BluetoothDevice* device, uint32 entered) OVERRIDE {
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++keys_entered_count_;
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_entered_ = entered;
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
198b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void ConfirmPasskey(BluetoothDevice* device,
199b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                              uint32 passkey) OVERRIDE {
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++confirm_passkey_count_;
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_passkey_ = passkey;
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void AuthorizePairing(BluetoothDevice* device) OVERRIDE {
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++authorize_pairing_count_;
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int call_count_;
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int request_pincode_count_;
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int request_passkey_count_;
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int display_pincode_count_;
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int display_passkey_count_;
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int keys_entered_count_;
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int confirm_passkey_count_;
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int authorize_pairing_count_;
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 last_passkey_;
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 last_entered_;
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string last_pincode_;
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  private:
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   // Some tests use a message loop since background processing is simulated;
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   // break out of those loops.
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   void QuitMessageLoop() {
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     if (base::MessageLoop::current() &&
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         base::MessageLoop::current()->is_running())
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       base::MessageLoop::current()->Quit();
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   }
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BluetoothChromeOSTest : public testing::Test {
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() {
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<DBusThreadManagerSetter> dbus_setter =
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        chromeos::DBusThreadManager::GetSetterForTesting();
2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // We need to initialize DBusThreadManager early to prevent
2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Bluetooth*::Create() methods from picking the real instead of fake
2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // implementations.
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_bluetooth_adapter_client_ = new FakeBluetoothAdapterClient;
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    dbus_setter->SetBluetoothAdapterClient(
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<BluetoothAdapterClient>(fake_bluetooth_adapter_client_));
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_bluetooth_device_client_ = new FakeBluetoothDeviceClient;
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    dbus_setter->SetBluetoothDeviceClient(
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<BluetoothDeviceClient>(fake_bluetooth_device_client_));
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    dbus_setter->SetBluetoothInputClient(
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient));
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    dbus_setter->SetBluetoothAgentManagerClient(
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<BluetoothAgentManagerClient>(
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            new FakeBluetoothAgentManagerClient));
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    dbus_setter->SetBluetoothGattServiceClient(
254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        scoped_ptr<BluetoothGattServiceClient>(
255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch            new FakeBluetoothGattServiceClient));
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    fake_bluetooth_adapter_client_->SetSimulationIntervalMs(10);
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_count_ = 0;
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_callback_count_ = 0;
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_connect_error_ = BluetoothDevice::ERROR_UNKNOWN;
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    last_client_error_ = "";
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TearDown() {
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (ScopedVector<BluetoothDiscoverySession>::iterator iter =
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            discovery_sessions_.begin();
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         iter != discovery_sessions_.end();
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         ++iter) {
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      BluetoothDiscoverySession* session = *iter;
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (!session->IsActive())
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        continue;
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      callback_count_ = 0;
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      session->Stop(
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          base::Bind(&BluetoothChromeOSTest::Callback,
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     base::Unretained(this)),
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          base::Bind(&BluetoothChromeOSTest::ErrorCallback,
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     base::Unretained(this)));
279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      message_loop_.Run();
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ASSERT_EQ(1, callback_count_);
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    discovery_sessions_.clear();
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_ = NULL;
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DBusThreadManager::Shutdown();
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Generic callbacks
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Callback() {
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++callback_count_;
290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    QuitMessageLoop();
291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void DiscoverySessionCallback(
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scoped_ptr<BluetoothDiscoverySession> discovery_session) {
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++callback_count_;
296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    discovery_sessions_.push_back(discovery_session.release());
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    QuitMessageLoop();
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ErrorCallback() {
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++error_callback_count_;
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    QuitMessageLoop();
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void DBusErrorCallback(const std::string& error_name,
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         const std::string& error_message) {
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ++error_callback_count_;
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    last_client_error_ = error_name;
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    QuitMessageLoop();
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void ConnectErrorCallback(BluetoothDevice::ConnectErrorCode error) {
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++error_callback_count_;
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_connect_error_ = error;
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Call to fill the adapter_ member with a BluetoothAdapter instance.
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GetAdapter() {
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    adapter_ = new BluetoothAdapterChromeOS();
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ASSERT_TRUE(adapter_.get() != NULL);
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(adapter_->IsInitialized());
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Run a discovery phase until the named device is detected, or if the named
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // device is not created, the discovery process ends without finding it.
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The correct behavior of discovery is tested by the "Discovery" test case
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // without using this function.
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DiscoverDevice(const std::string& address) {
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ASSERT_TRUE(adapter_.get() != NULL);
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_TRUE(base::MessageLoop::current() != NULL);
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestObserver observer(adapter_);
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_->SetPowered(
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        true,
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::Callback,
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)),
3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)));
342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    adapter_->StartDiscoverySession(
343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)),
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)));
347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::MessageLoop::current()->Run();
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(2, callback_count_);
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(0, error_callback_count_);
350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_EQ((size_t)1, discovery_sessions_.size());
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ASSERT_TRUE(discovery_sessions_[0]->IsActive());
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_count_ = 0;
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(adapter_->IsPowered());
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(adapter_->IsDiscovering());
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    while (!observer.device_removed_count_ &&
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           observer.last_device_address_ != address)
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::MessageLoop::current()->Run();
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    discovery_sessions_[0]->Stop(
3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::Callback,
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)),
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)));
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::MessageLoop::current()->Run();
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(1, callback_count_);
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(0, error_callback_count_);
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_count_ = 0;
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(adapter_->IsDiscovering());
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Run a discovery phase so we have devices that can be paired with.
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DiscoverDevices() {
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Pass an invalid address for the device so that the discovery process
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // completes with all devices.
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DiscoverDevice("does not exist");
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::MessageLoop message_loop_;
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothAdapterClient* fake_bluetooth_adapter_client_;
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<BluetoothAdapter> adapter_;
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int callback_count_;
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int error_callback_count_;
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  enum BluetoothDevice::ConnectErrorCode last_connect_error_;
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string last_client_error_;
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ScopedVector<BluetoothDiscoverySession> discovery_sessions_;
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Some tests use a message loop since background processing is simulated;
395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // break out of those loops.
396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void QuitMessageLoop() {
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (base::MessageLoop::current() &&
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::MessageLoop::current()->is_running())
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::MessageLoop::current()->Quit();
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, AlreadyPresent) {
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This verifies that the class gets the list of adapters when created;
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and initializes with an existing adapter if there is one.
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPresent());
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterAddress,
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            adapter_->GetAddress());
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // There should be a device
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1U, devices.size());
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            devices[0]->GetAddress());
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, BecomePresent) {
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(adapter_->IsPresent());
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the AdapterPresentChanged to be called
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with true, and IsPresent() to return true.
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(true);
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.present_changed_count_);
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer.last_present_);
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPresent());
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We should have had a device announced.
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_added_count_);
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Other callbacks shouldn't be called if the values are false.
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.powered_changed_count_);
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, BecomeNotPresent) {
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPresent());
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the AdapterPresentChanged to be called
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with false, and IsPresent() to return false.
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.present_changed_count_);
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_present_);
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPresent());
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We should have had a device removed.
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_removed_count_);
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Other callbacks shouldn't be called since the values are false.
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.powered_changed_count_);
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, SecondAdapter) {
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPresent());
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer, then add a second adapter. Nothing should change,
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // we ignore the second adapter.
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetSecondVisible(true);
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.present_changed_count_);
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPresent());
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterAddress,
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            adapter_->GetAddress());
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Try removing the first adapter, we should now act as if the adapter
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is no longer present rather than fall back to the second.
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.present_changed_count_);
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_present_);
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPresent());
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We should have had a device removed.
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_removed_count_);
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Other callbacks shouldn't be called since the values are false.
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.powered_changed_count_);
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer.device_removed_count_ = 0;
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Removing the second adapter shouldn't set anything either.
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetSecondVisible(false);
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.device_removed_count_);
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.powered_changed_count_);
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, BecomePowered) {
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(adapter_->IsPowered());
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the AdapterPoweredChanged to be called
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with true, and IsPowered() to return true.
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
5327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.powered_changed_count_);
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer.last_powered_);
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPowered());
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, BecomeNotPowered) {
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
5497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
5517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the AdapterPoweredChanged to be called
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with false, and IsPowered() to return false.
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      false,
5657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
5677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.powered_changed_count_);
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_powered_);
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ChangeAdapterName) {
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetAdapter();
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static const std::string new_name(".__.");
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  adapter_->SetName(
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new_name,
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this)),
5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this)));
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(new_name, adapter_->GetName());
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, BecomeDiscoverable) {
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetAdapter();
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(adapter_->IsDiscoverable());
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Install an observer; expect the AdapterDiscoverableChanged to be called
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // with true, and IsDiscoverable() to return true.
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestObserver observer(adapter_);
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  adapter_->SetDiscoverable(
6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      true,
6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this)),
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this)));
6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, observer.discoverable_changed_count_);
6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscoverable());
6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, BecomeNotDiscoverable) {
6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetAdapter();
6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  adapter_->SetDiscoverable(
6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      true,
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this)),
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this)));
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  callback_count_ = 0;
6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(adapter_->IsDiscoverable());
6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Install an observer; expect the AdapterDiscoverableChanged to be called
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // with false, and IsDiscoverable() to return false.
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestObserver observer(adapter_);
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  adapter_->SetDiscoverable(
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      false,
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this)),
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this)));
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, observer.discoverable_changed_count_);
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscoverable());
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, StopDiscovery) {
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
6547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
6567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->StartDiscoverySession(
659a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
6617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, callback_count_);
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsDiscovering());
670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)1, discovery_sessions_.size());
671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(discovery_sessions_[0]->IsActive());
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; aside from the callback, expect the
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // AdapterDiscoveringChanged method to be called and no longer to be
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // discovering,
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_[0]->Stop(
6797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
6817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, Discovery) {
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test a simulated discovery session.
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
7027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
7047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->StartDiscoverySession(
707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
7097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, callback_count_);
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsDiscovering());
718a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)1, discovery_sessions_.size());
719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(discovery_sessions_[0]->IsActive());
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
721effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // First two devices to appear.
722a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
724effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(2, observer.device_added_count_);
725effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress,
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Next we should get another two devices...
729a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
730effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(4, observer.device_added_count_);
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Okay, let's run forward until a device is actually removed...
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (!observer.device_removed_count_)
734a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    message_loop_.Run();
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_removed_count_);
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kVanishingDeviceAddress,
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PoweredAndDiscovering) {
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
7457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
7477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
749a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->StartDiscoverySession(
750a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
7527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
754a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, callback_count_);
756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)1, discovery_sessions_.size());
759a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(discovery_sessions_[0]->IsActive());
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Stop the timers that the simulation uses
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->EndDiscoverySimulation(
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsDiscovering());
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(adapter_->IsPresent());
770a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(discovery_sessions_[0]->IsActive());
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the AdapterPresentChanged,
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // AdapterPoweredChanged and AdapterDiscoveringChanged methods to be called
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with true, and IsPresent(), IsPowered() and IsDiscovering() to all
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // return true.
776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(true);
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.present_changed_count_);
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer.last_present_);
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPresent());
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.powered_changed_count_);
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer.last_powered_);
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPowered());
787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer.present_changed_count_ = 0;
793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer.powered_changed_count_ = 0;
794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer.discovering_changed_count_ = 0;
795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now mark the adapter not present again. Expect the methods to be called
797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // again, to reset the properties back to false
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.present_changed_count_);
801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_present_);
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPresent());
803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.powered_changed_count_);
805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_powered_);
806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
813a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// This unit test asserts that the basic reference counting logic works
814a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// correctly for discovery requests done via the BluetoothAdapter.
815a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, MultipleDiscoverySessions) {
816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
817a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->SetPowered(
818a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
819a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
820a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
821a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
822a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
823a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
824a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
825a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsPowered());
826a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_count_ = 0;
827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
828a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
830a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
831a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
832a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
834a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request device discovery 3 times.
835a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 3; i++) {
836a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    adapter_->StartDiscoverySession(
837a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
838a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
839a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
840a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
841a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
842a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Run only once, as there should have been one D-Bus call.
843a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
845a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The observer should have received the discovering changed event exactly
846a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // once, the success callback should have been called 3 times and the adapter
847a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // should be discovering.
848a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
849a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(3, callback_count_);
850a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
851a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
852a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
853a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)3, discovery_sessions_.size());
854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
855a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request to stop discovery twice.
856a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 2; i++) {
857a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    discovery_sessions_[i]->Stop(
858a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
859a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
860a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
861a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
862a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
864a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The observer should have received no additional discovering changed events,
865a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the success callback should have been called 2 times and the adapter should
866a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // still be discovering.
867a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
868a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5, callback_count_);
869a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
870a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
871a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
872a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
873a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(discovery_sessions_[1]->IsActive());
875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[2]->IsActive());
876a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
877a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request device discovery 3 times.
878a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 3; i++) {
879a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    adapter_->StartDiscoverySession(
880a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
881a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
882a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
883a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
884a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
886a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The observer should have received no additional discovering changed events,
887a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the success callback should have been called 3 times and the adapter should
888a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // still be discovering.
889a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
890a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(8, callback_count_);
891a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
892a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
893a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
894a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)6, discovery_sessions_.size());
895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
896a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request to stop discovery 4 times.
897a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 2; i < 6; i++) {
898a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    discovery_sessions_[i]->Stop(
899a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
900a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
901a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
902a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
903a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Run only once, as there should have been one D-Bus call.
905a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
906a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
907a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The observer should have received the discovering changed event exactly
908a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // once, the success callback should have been called 4 times and the adapter
909a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // should no longer be discovering.
910a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.discovering_changed_count_);
911a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(12, callback_count_);
912a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
913a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
914a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
916a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // All discovery sessions should be inactive.
917a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 6; i++)
918a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_FALSE(discovery_sessions_[i]->IsActive());
919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
920a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request to stop discovery on of the inactive sessions.
921a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_[0]->Stop(
922a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::Callback,
923a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)),
924a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::ErrorCallback,
925a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)));
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
927a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The call should have failed.
928a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.discovering_changed_count_);
929a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(12, callback_count_);
930a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
931a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
932a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
935a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// This unit test asserts that the reference counting logic works correctly in
936a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the cases when the adapter gets reset and D-Bus calls are made outside of
937a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the BluetoothAdapter.
938a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest,
939a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       UnexpectedChangesDuringMultipleDiscoverySessions) {
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
941a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->SetPowered(
942a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
943a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
944a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
945a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
946a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
947a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
948a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
949a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsPowered());
950a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_count_ = 0;
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
954a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
955a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
956a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
958a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request device discovery 3 times.
959a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 3; i++) {
960a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    adapter_->StartDiscoverySession(
961a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
962a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
963a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
964a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
965a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
966a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Run only once, as there should have been one D-Bus call.
967a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
969a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The observer should have received the discovering changed event exactly
970a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // once, the success callback should have been called 3 times and the adapter
971a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // should be discovering.
972a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
973a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(3, callback_count_);
974a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
975a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
976a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
977a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)3, discovery_sessions_.size());
978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
979a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 3; i++)
980a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(discovery_sessions_[i]->IsActive());
981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
982a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Stop the timers that the simulation uses
983a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->EndDiscoverySimulation(
984a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
986a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
987a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(adapter_->IsDiscovering());
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
989a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Stop device discovery behind the adapter. The adapter and the observer
990a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // should be notified of the change and the reference count should be reset.
991a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Even though FakeBluetoothAdapterClient does its own reference counting and
992a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // we called 3 BluetoothAdapter::StartDiscoverySession 3 times, the
993a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // FakeBluetoothAdapterClient's count should be only 1 and a single call to
994a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // FakeBluetoothAdapterClient::StopDiscovery should work.
995a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_adapter_client_->StopDiscovery(
996a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
997a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
998a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
999a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
1000a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1001a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1002a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.discovering_changed_count_);
1003a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(4, callback_count_);
1004a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1005a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1006a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1008a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // All discovery session instances should have been updated.
1009a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 3; i++)
1010a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_FALSE(discovery_sessions_[i]->IsActive());
1011a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_.clear();
1012a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1013a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // It should be possible to successfully start discovery.
1014a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 2; i++) {
1015a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    adapter_->StartDiscoverySession(
1016a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
1017a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1018a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1019a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1020a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1021a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Run only once, as there should have been one D-Bus call.
1022a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1023a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(3, observer.discovering_changed_count_);
1024a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(6, callback_count_);
1025a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1026a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1027a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1028a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)2, discovery_sessions_.size());
1029a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1030a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 2; i++)
1031a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(discovery_sessions_[i]->IsActive());
1032a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1033a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->EndDiscoverySimulation(
1034a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
1035a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1036a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make the adapter disappear and appear. This will make it come back as
1037a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // discovering. When this happens, the reference count should become and
1038a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // remain 0 as no new request was made through the BluetoothAdapter.
1039a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
1040a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(adapter_->IsPresent());
1041a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(4, observer.discovering_changed_count_);
1042a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(6, callback_count_);
1043a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1044a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1045a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1046a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1047a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 2; i++)
1048a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_FALSE(discovery_sessions_[i]->IsActive());
1049a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_.clear();
1050a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1051a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(true);
1052a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(adapter_->IsPresent());
1053a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5, observer.discovering_changed_count_);
1054a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(6, callback_count_);
1055a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1056a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1057a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1058a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1059a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Start and stop discovery. At this point, FakeBluetoothAdapterClient has
1060a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // a reference count that is equal to 1. Pretend that this was done by an
1061a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // application other than us. Starting and stopping discovery will succeed
1062a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // but it won't cause the discovery state to change.
1063a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->StartDiscoverySession(
1064a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
1065a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)),
1066a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1067a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)));
1068a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();  // Run the loop, as there should have been a D-Bus call.
1069a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5, observer.discovering_changed_count_);
1070a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(7, callback_count_);
1071a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1072a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1073a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1074a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)1, discovery_sessions_.size());
1075a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[0]->IsActive());
1076a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1077a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_[0]->Stop(
1078a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::Callback,
1079a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)),
1080a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1081a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)));
1082a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();  // Run the loop, as there should have been a D-Bus call.
1083a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5, observer.discovering_changed_count_);
1084a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(8, callback_count_);
1085a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1086a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1087a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1088a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
1089a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_.clear();
1090a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1091a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Start discovery again.
1092a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->StartDiscoverySession(
1093a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
1094a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)),
1095a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1096a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)));
1097a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();  // Run the loop, as there should have been a D-Bus call.
1098a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5, observer.discovering_changed_count_);
1099a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(9, callback_count_);
1100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)1, discovery_sessions_.size());
1104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[0]->IsActive());
1105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Stop discovery via D-Bus. The fake client's reference count will drop but
1107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the discovery state won't change since our BluetoothAdapter also just
1108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // requested it via D-Bus.
1109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_adapter_client_->StopDiscovery(
1110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
1114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5, observer.discovering_changed_count_);
1117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(10, callback_count_);
1118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Now end the discovery session. This should change the adapter's discovery
1123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // state.
1124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_[0]->Stop(
1125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::Callback,
1126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)),
1127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)));
1129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(6, observer.discovering_changed_count_);
1131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(11, callback_count_);
1132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
1136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, InvalidatedDiscoverySessions) {
1139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->SetPowered(
1141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
1142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsPowered());
1149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_count_ = 0;
1150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
1154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request device discovery 3 times.
1158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 3; i++) {
1159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    adapter_->StartDiscoverySession(
1160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
1161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Run only once, as there should have been one D-Bus call.
1166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The observer should have received the discovering changed event exactly
1169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // once, the success callback should have been called 3 times and the adapter
1170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // should be discovering.
1171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
1172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(3, callback_count_);
1173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)3, discovery_sessions_.size());
1177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 3; i++)
1179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(discovery_sessions_[i]->IsActive());
1180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Stop the timers that the simulation uses
1182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->EndDiscoverySimulation(
1183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
1184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
1186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(adapter_->IsDiscovering());
1187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Delete all but one discovery session.
1189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_.pop_back();
1190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_.pop_back();
1191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)1, discovery_sessions_.size());
1192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[0]->IsActive());
1193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Stop device discovery behind the adapter. The one active discovery session
1196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // should become inactive, but more importantly, we shouldn't run into any
1197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // memory errors as the sessions that we explicitly deleted should get
1198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // cleaned up.
1199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_adapter_client_->StopDiscovery(
1200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
1201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
1204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.discovering_changed_count_);
1207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(4, callback_count_);
1208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
1212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, QueuedDiscoveryRequests) {
1215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->SetPowered(
1218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
1219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsPowered());
1226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_count_ = 0;
1227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
1231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request to start discovery. The call should be pending.
1235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->StartDiscoverySession(
1236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
1237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)),
1238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)));
1240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->EndDiscoverySimulation(
1243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
1244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The underlying adapter has started discovery, but our call hasn't returned
1246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // yet.
1247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
1248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_.empty());
1251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request to start discovery twice. These should get queued and there should
1253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // be no change in state.
1254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 2; i++) {
1255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    adapter_->StartDiscoverySession(
1256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
1257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
1264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_.empty());
1267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Process the pending call. The queued calls should execute and the discovery
1269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // session reference count should increase.
1270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(3, callback_count_);
1272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
1274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)3, discovery_sessions_.size());
1277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Verify the reference count by removing sessions 3 times. The last request
1279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // should remain pending.
1280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 3; i++) {
1281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    discovery_sessions_[i]->Stop(
1282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5, callback_count_);
1288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.discovering_changed_count_);
1290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
1293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(discovery_sessions_[1]->IsActive());
1294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[2]->IsActive());
1295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request to stop the session whose call is pending should fail.
1297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_[2]->Stop(
1298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::Callback,
1299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)),
1300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)));
1302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5, callback_count_);
1303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.discovering_changed_count_);
1305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[2]->IsActive());
1308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request to start should get queued.
1310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->StartDiscoverySession(
1311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
1312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)),
1313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               base::Unretained(this)));
1315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5, callback_count_);
1316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.discovering_changed_count_);
1318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)3, discovery_sessions_.size());
1321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Run the pending request.
1323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(6, callback_count_);
1325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(3, observer.discovering_changed_count_);
1327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)3, discovery_sessions_.size());
1330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(discovery_sessions_[2]->IsActive());
1331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The queued request to start discovery should have been issued but is still
1333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // pending. Run the loop and verify.
1334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(7, callback_count_);
1336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(3, observer.discovering_changed_count_);
1338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)4, discovery_sessions_.size());
1341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[3]->IsActive());
1342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, StartDiscoverySession) {
1345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->SetPowered(
1348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
1349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsPowered());
1356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_count_ = 0;
1357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
1361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_.empty());
1364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request a new discovery session.
1366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->StartDiscoverySession(
1367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
1368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
1373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)1, discovery_sessions_.size());
1378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[0]->IsActive());
1379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Start another session. A new one should be returned in the callback, which
1381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // in turn will destroy the previous session. Adapter should still be
1382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // discovering and the reference count should be 1.
1383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->StartDiscoverySession(
1384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
1385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
1390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, callback_count_);
1391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)2, discovery_sessions_.size());
1395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[0]->IsActive());
1396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Request a new session.
1398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->StartDiscoverySession(
1399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DiscoverySessionCallback,
1400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
1405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(3, callback_count_);
1406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)3, discovery_sessions_.size());
1410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[1]->IsActive());
1411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_NE(discovery_sessions_[0], discovery_sessions_[1]);
1412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Stop the previous discovery session. The session should end but discovery
1414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // should continue.
1415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_[0]->Stop(
1416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
1422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(4, callback_count_);
1423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
1425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
1426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ((size_t)3, discovery_sessions_.size());
1427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
1428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(discovery_sessions_[1]->IsActive());
1429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Delete the current active session. Discovery should eventually stop.
1431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  discovery_sessions_.clear();
1432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  while (observer.last_discovering_)
1433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    message_loop_.RunUntilIdle();
1434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.discovering_changed_count_);
1436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(4, callback_count_);
1437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
1439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
1440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DeviceProperties) {
1443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
1446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, devices.size());
1447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
1448a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            devices[0]->GetAddress());
1449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Verify the other device properties.
1451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(base::UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName),
1452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            devices[0]->GetName());
1453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::DEVICE_COMPUTER, devices[0]->GetDeviceType());
1454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(devices[0]->IsPaired());
1455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(devices[0]->IsConnected());
1456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(devices[0]->IsConnecting());
1457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Non HID devices are always connectable.
1459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(devices[0]->IsConnectable());
1460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
146123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  BluetoothDevice::UUIDList uuids = devices[0]->GetUUIDs();
1462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(2U, uuids.size());
1463c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[0], BluetoothUUID("1800"));
1464c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[1], BluetoothUUID("1801"));
1465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::VENDOR_ID_USB, devices[0]->GetVendorIDSource());
1467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0x05ac, devices[0]->GetVendorID());
1468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0x030d, devices[0]->GetProductID());
1469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0x0306, devices[0]->GetDeviceID());
1470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DeviceClassChanged) {
1473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Simulate a change of class of a device, as sometimes occurs
1474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // during discovery.
1475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
1478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, devices.size());
1479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
1480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            devices[0]->GetAddress());
1481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(BluetoothDevice::DEVICE_COMPUTER, devices[0]->GetDeviceType());
1482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Install an observer; expect the DeviceChanged method to be called when
1484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // we change the class of the device.
1485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
1490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  properties->bluetooth_class.ReplaceValue(0x002580);
1492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.device_changed_count_);
1494a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(devices[0], observer.last_device_);
1495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::DEVICE_MOUSE, devices[0]->GetDeviceType());
1497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DeviceNameChanged) {
1500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Simulate a change of name of a device.
1501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
1504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, devices.size());
1505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
1506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            devices[0]->GetAddress());
1507a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(base::UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName),
1508a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            devices[0]->GetName());
1509a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Install an observer; expect the DeviceChanged method to be called when
1511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // we change the alias of the device.
1512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1513a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1516a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
1517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static const std::string new_name("New Device Name");
1519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  properties->alias.ReplaceValue(new_name);
1520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.device_changed_count_);
1522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(devices[0], observer.last_device_);
1523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(base::UTF8ToUTF16(new_name), devices[0]->GetName());
1525a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1526a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DeviceUuidsChanged) {
1528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Simulate a change of advertised services of a device.
1529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
1532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, devices.size());
1533a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
1534a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            devices[0]->GetAddress());
1535a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
153623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  BluetoothDevice::UUIDList uuids = devices[0]->GetUUIDs();
1537a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(2U, uuids.size());
1538c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ASSERT_EQ(uuids[0], BluetoothUUID("1800"));
1539c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ASSERT_EQ(uuids[1], BluetoothUUID("1801"));
1540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Install an observer; expect the DeviceChanged method to be called when
1542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // we change the class of the device.
1543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1544a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
1548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1549c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::vector<std::string> new_uuids;
1550c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  new_uuids.push_back(uuids[0].canonical_value());
1551c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  new_uuids.push_back(uuids[1].canonical_value());
1552c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  new_uuids.push_back("0000110c-0000-1000-8000-00805f9b34fb");
1553c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  new_uuids.push_back("0000110e-0000-1000-8000-00805f9b34fb");
1554c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  new_uuids.push_back("0000110a-0000-1000-8000-00805f9b34fb");
1555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1556c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  properties->uuids.ReplaceValue(new_uuids);
1557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1558a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.device_changed_count_);
1559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(devices[0], observer.last_device_);
1560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Fetching the value should give the new one.
156223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  uuids = devices[0]->GetUUIDs();
1563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(5U, uuids.size());
1564c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[0], BluetoothUUID("1800"));
1565c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[1], BluetoothUUID("1801"));
1566c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[2], BluetoothUUID("110c"));
1567c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[3], BluetoothUUID("110e"));
1568c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[4], BluetoothUUID("110a"));
1569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1571a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ForgetDevice) {
1572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1573a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
1575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, devices.size());
1576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
1577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            devices[0]->GetAddress());
1578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string address = devices[0]->GetAddress();
1580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Install an observer; expect the DeviceRemoved method to be called
1582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // with the device we remove.
1583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  devices[0]->Forget(
1586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.device_removed_count_);
1591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(address, observer.last_device_address_);
1592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // GetDevices shouldn't return the device either.
1594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  devices = adapter_->GetDevices();
1595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(0U, devices.size());
1596a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1597a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ForgetUnpairedDevice) {
1599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevices();
1601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1603a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kConnectUnpairableAddress);
1604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
1605a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Connect the device so it becomes trusted and remembered.
1608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
1609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NULL,
1610a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1, callback_count_);
1616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(0, error_callback_count_);
1617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_count_ = 0;
1618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device->IsConnected());
1620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsConnecting());
1621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
1623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kConnectUnpairablePath));
1626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(properties->trusted.value());
1627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Install an observer; expect the DeviceRemoved method to be called
1629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // with the device we remove.
1630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Forget(
1633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1634a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1635a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1636a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1637a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, observer.device_removed_count_);
1638a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kConnectUnpairableAddress,
1639a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            observer.last_device_address_);
1640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // GetDevices shouldn't return the device either.
1642a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device = adapter_->GetDevice(
1643a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kConnectUnpairableAddress);
1644a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device != NULL);
1645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1646a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ConnectPairedDevice) {
1648a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1650a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1651a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kPairedDeviceAddress);
1652a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
1653a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device->IsPaired());
1654a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1656a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1657a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Connect without a pairing delegate; since the device is already Paired
1658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // this should succeed and the device should become connected.
1659a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
1660a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NULL,
1661a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1662a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1664a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1665a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Two changes for connecting, one for connected and one for for trusted
1670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // after connecting.
1671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(4, observer.device_changed_count_);
1672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1673a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1675a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ConnectUnpairableDevice) {
1679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevices();
1681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kConnectUnpairableAddress);
1684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
1685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Connect without a pairing delegate; since the device does not require
1690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // pairing, this should succeed and the device should become connected.
1691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
1692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NULL,
1693a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1694a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1695a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1696a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1697a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1698a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1699a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1700a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1701a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Two changes for connecting, one for connected, one for for trusted after
1702a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // connection, and one for the reconnect mode (IsConnectable).
1703a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(5, observer.device_changed_count_);
1704a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1705a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1706a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1707a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
1710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kConnectUnpairablePath));
1713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1714a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1715a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Verify is a HID device and is not connectable.
171623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  BluetoothDevice::UUIDList uuids = device->GetUUIDs();
1717a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, uuids.size());
1718c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[0], BluetoothUUID("1124"));
1719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnectable());
1720a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1721a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1722a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ConnectConnectedDevice) {
1723a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1724a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1725a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kPairedDeviceAddress);
1727a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
1728a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device->IsPaired());
1729a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1730a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
1731a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NULL,
1732a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1733a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1734a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1735a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1736a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1737a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1, callback_count_);
1738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(0, error_callback_count_);
1739a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_count_ = 0;
1740a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1741a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device->IsConnected());
1742a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1743a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Connect again; since the device is already Connected, this shouldn't do
1744a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // anything to initiate the connection.
1745a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1746a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1747a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
1748a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NULL,
1749a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1750a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1751a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1752a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1753a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1754a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1755a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1756a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1757a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The observer will be called because Connecting will toggle true and false,
1758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // and the trusted property will be updated to true.
1759a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(3, observer.device_changed_count_);
1760a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1761a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1762a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1763a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1764a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1765a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ConnectDeviceFails) {
1766a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1767a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevices();
1768a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1769a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1770a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kLegacyAutopairAddress);
1771a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
1772a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1773a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1774a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1775a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Connect without a pairing delegate; since the device requires pairing,
1777a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // this should fail with an error.
1778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
1779a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NULL,
1780a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1781a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1784a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1785a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1786a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1787a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_);
1788a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1789a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
1790a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1791a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1792a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1793a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1794a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1795a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DisconnectDevice) {
1796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1797a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1798a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kPairedDeviceAddress);
1800a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
1801a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device->IsPaired());
1802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1803a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
1804a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      NULL,
1805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1806a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1807a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1808a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1809a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1810a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1, callback_count_);
1811a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(0, error_callback_count_);
1812a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  callback_count_ = 0;
1813a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1814a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device->IsConnected());
1815a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsConnecting());
1816a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1817a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Disconnect the device, we should see the observer method fire and the
1818a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // device get dropped.
1819a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1820a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1821a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Disconnect(
1822a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1823a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1824a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1825a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1826a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1827a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1828a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_changed_count_);
1831a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1833a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1836a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DisconnectUnconnectedDevice) {
1837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1839a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1840a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kPairedDeviceAddress);
1841a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
1842a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device->IsPaired());
1843a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsConnected());
1844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1845a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Disconnect the device, we should see the observer method fire and the
1846a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // device get dropped.
1847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1849a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Disconnect(
1850a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1851a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
18527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1854a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1855a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1856a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1857a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1858a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.device_changed_count_);
1859a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1860a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1861a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1862a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1863a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairLegacyAutopair) {
1864a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1865a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1866a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1867a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevices();
1868a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1869a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The Legacy Autopair device requires no PIN or Passkey to pair because
1870a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the daemon provides 0000 to the device for us.
1871a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1872a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kLegacyAutopairAddress);
1873a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
1874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1876a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1877a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1878a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
1879a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
1880a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
1881a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1882a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1883a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1884a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
1885a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1886a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
1887a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1888a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1889a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1890a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1891a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1894a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired,
1895a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // two for trusted (after pairing and connection), and one for the reconnect
1896a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // mode (IsConnectable).
1897a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(7, observer.device_changed_count_);
1898a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1900a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1901a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1902a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1903a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
1904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1905a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Verify is a HID device and is connectable.
190623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  BluetoothDevice::UUIDList uuids = device->GetUUIDs();
1907a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, uuids.size());
1908c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[0], BluetoothUUID("1124"));
1909a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
1910a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1911a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
1912a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1913a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1914a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kLegacyAutopairPath));
1915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1918a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairDisplayPinCode) {
1919a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1920a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1924a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requires that we display a randomly generated PIN on the screen.
1925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1926a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kDisplayPinCodeAddress);
1927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1930a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
1931a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1932a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
1933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1934a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
19357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
19377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1940a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1941a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.display_pincode_count_);
1942a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ("123456", pairing_delegate.last_pincode_);
1943a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1945a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
1946a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1947a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1948a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1949a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1950a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired,
1951a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // two for trusted (after pairing and connection), and one for the reconnect
1952a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // mode (IsConnectable).
1953a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(7, observer.device_changed_count_);
1954a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1955a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1956a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1957a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1958a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1959a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
1960a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1961a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Verify is a HID device and is connectable.
196223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  BluetoothDevice::UUIDList uuids = device->GetUUIDs();
1963a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, uuids.size());
1964c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[0], BluetoothUUID("1124"));
1965a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
1966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true.
1968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1970a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kDisplayPinCodePath));
1971a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1972a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1973a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1974a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairDisplayPasskey) {
1975a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1976a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1977a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
1978a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevices();
1979a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1980a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requires that we display a randomly generated Passkey on the screen,
1981a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // and notifies us as it's typed in.
1982a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1983a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kDisplayPasskeyAddress);
1984a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
1985a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1989a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
1990a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
1991a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
1992a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1993a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
1994a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1996a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1997a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // One call for DisplayPasskey() and one for KeysEntered().
1998a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1999a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.display_passkey_count_);
2000a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(123456U, pairing_delegate.last_passkey_);
2001a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.keys_entered_count_);
2002a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0U, pairing_delegate.last_entered_);
2003a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2004a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2005a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2006a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // One call to KeysEntered() for each key, including [enter].
2007a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for(int i = 1; i <= 7; ++i) {
2008a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    message_loop_.Run();
2009a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2010a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(2 + i, pairing_delegate.call_count_);
2011a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(1 + i, pairing_delegate.keys_entered_count_);
2012a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(static_cast<uint32_t>(i), pairing_delegate.last_entered_);
2013a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
2014a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2015a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2016a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2017a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // 8 KeysEntered notifications (0 to 7, inclusive) and one aditional call for
2018a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // DisplayPasskey().
2019a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(9, pairing_delegate.call_count_);
2020a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(8, pairing_delegate.keys_entered_count_);
2021a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(7U, pairing_delegate.last_entered_);
2022a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2023a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
2024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
2025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2026a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired,
2027a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // two for trusted (after pairing and connection), and one for the reconnect
2028a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // mode (IsConnectable).
2029a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(7, observer.device_changed_count_);
2030a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
2031a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2032a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
2033a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2034a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2035a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
2036a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2037a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Verify is a HID device.
203823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  BluetoothDevice::UUIDList uuids = device->GetUUIDs();
2039a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(1U, uuids.size());
2040c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(uuids[0], BluetoothUUID("1124"));
2041a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2042a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // And usually not connectable.
2043a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnectable());
2044a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2045a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
2046a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
2047a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
2048a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kDisplayPasskeyPath));
2049a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
2050a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
2051a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2052a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairRequestPinCode) {
2053a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2054a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2055a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
2056a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevices();
2057a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2058a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requires that the user enters a PIN for them.
2059a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2060a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPinCodeAddress);
2061a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
2062a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2063a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2064a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
2065a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2066a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2067a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
2068a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
2069a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2070a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)),
2071a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2072a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 base::Unretained(this)));
2073a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2074a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2075a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
2076a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2077a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2078a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set the PIN.
2079a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->SetPinCode("1234");
2080a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2081a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2082a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
2083a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
2084a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2085a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired and
2086a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // two for trusted (after pairing and connection).
2087a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(6, observer.device_changed_count_);
2088a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
2089a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2090a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
2091a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2092a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2093a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
2094a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2095a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Verify is not a HID device.
209623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  BluetoothDevice::UUIDList uuids = device->GetUUIDs();
2097a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(0U, uuids.size());
2098a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2099a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Non HID devices are always connectable.
2100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
2101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
2103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
2104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
2105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath));
2106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
2107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairConfirmPasskey) {
2110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevices();
2114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requests that we confirm a displayed passkey.
2116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
2118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
21267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
21287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
2133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(123456U, pairing_delegate.last_passkey_);
2134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Confirm the passkey.
2137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->ConfirmPairing();
2138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
2141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
2142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired and
2144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // two for trusted (after pairing and connection).
2145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(6, observer.device_changed_count_);
2146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
2147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
2149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
2152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Non HID devices are always connectable.
2154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
2155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
2157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
2158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
2159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath));
2160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
2161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairRequestPasskey) {
2164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
2168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requires that the user enters a Passkey, this would be some kind of
2170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // device that has a display, but doesn't use "just works" - maybe a car?
2171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPasskeyAddress);
2173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
21817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
21837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
2188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set the Passkey.
2191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->SetPasskey(1234);
2192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
2195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
2196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired and
2198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // two for trusted (after pairing and connection).
2199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(6, observer.device_changed_count_);
2200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
2201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
2203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
2206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Non HID devices are always connectable.
2208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
2209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true.
2211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
2212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
2213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath));
2214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
2215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairJustWorks) {
2218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevices();
2222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Uses just-works pairing, since this is an outgoing pairing, no delegate
2224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // interaction is required.
2225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kJustWorksAddress);
2227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
22357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
22377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
2241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
2245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
2246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired and
2248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // two for trusted (after pairing and connection).
2249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(6, observer.device_changed_count_);
2250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
2251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
2253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
2256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Non HID devices are always connectable.
2258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
2259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
2261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
2262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
2263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath));
2264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
2265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairUnpairableDeviceFails) {
2268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevice(FakeBluetoothDeviceClient::kUnconnectableDeviceAddress);
2272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kUnpairableDeviceAddress);
2275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
22837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
22857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
2289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Run the loop to get the error..
2292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_);
2298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingFails) {
2305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevice(FakeBluetoothDeviceClient::kVanishingDeviceAddress);
2309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The vanishing device times out during pairing
2311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kVanishingDeviceAddress);
2313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestObserver observer(adapter_);
2317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
23217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
23237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
2327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Run the loop to get the error..
2330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_TIMEOUT, last_connect_error_);
2336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingFailsAtConnection) {
2343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevices();
2347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Everything seems to go according to plan with the unconnectable device;
2349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // it pairs, but then you can't make connections to it after.
2350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kUnconnectableDeviceAddress);
2352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->Connect(
2359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
23607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
2362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
2366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_);
2373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Two changes for connecting, one for paired and one for trusted after
2375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // pairing. The device should not be connected.
2376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(4, observer.device_changed_count_);
2377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
2378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
2383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true still (since pairing
2385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // worked).
2386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
2387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
2388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(
2389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              FakeBluetoothDeviceClient::kUnconnectableDevicePath));
2390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
2391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingRejectedAtPinCode) {
2394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
2398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Reject the pairing after we receive a request for the PIN code.
2400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPinCodeAddress);
2402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
2408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
24107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
24127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
2417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Reject the pairing.
2420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->RejectPairing();
2421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_);
2426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Should be no changes except connecting going true and false.
2428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingCancelledAtPinCode) {
2435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
2439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cancel the pairing after we receive a request for the PIN code.
2441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPinCodeAddress);
2443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
2449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
24517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
24537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
2458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cancel the pairing.
2461a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->CancelPairing();
2462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);
2467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Should be no changes except connecting going true and false.
2469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingRejectedAtPasskey) {
2476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
2480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Reject the pairing after we receive a request for the passkey.
2482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPasskeyAddress);
2484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
2490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
24927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
24947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
2499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Reject the pairing.
2502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->RejectPairing();
2503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2507a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_);
2508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2509a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Should be no changes except connecting going true and false.
2510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2513a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2516a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingCancelledAtPasskey) {
2517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
2521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cancel the pairing after we receive a request for the passkey.
2523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPasskeyAddress);
2525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
2531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
25337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
25357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2539a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
2540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cancel the pairing.
2543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->CancelPairing();
2544a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);
2549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Should be no changes except connecting going true and false.
2551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingRejectedAtConfirmation) {
2558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
2562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Reject the pairing after we receive a request for passkey confirmation.
2564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
2566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
2572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
25747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
25767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
2581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Reject the pairing.
2584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->RejectPairing();
2585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_);
2590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Should be no changes except connecting going true and false.
2592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingCancelledAtConfirmation) {
2599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
2603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cancel the pairing after we receive a request for the passkey.
2605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
2607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
2613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
26157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
26177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
2622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cancel the pairing.
2625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->CancelPairing();
2626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);
2631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Should be no changes except connecting going true and false.
2633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2634a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2636a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2639a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingCancelledInFlight) {
2640b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2641b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2642b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GetAdapter();
2643a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DiscoverDevices();
2644b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cancel the pairing while we're waiting for the remote host.
2646b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kLegacyAutopairAddress);
2648b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2649b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2650b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2651b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TestObserver observer(adapter_);
2652b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2653b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
2654b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  device->Connect(
2655b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      &pairing_delegate,
26567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2657b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                 base::Unretained(this)),
26587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2659b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                 base::Unretained(this)));
2660b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2661b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
2662b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2663b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2664a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Cancel the pairing.
2665a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->CancelPairing();
2666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2667b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2668b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2669b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);
2671b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Should be no changes except connecting going true and false.
2673a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2674b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2675b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2676b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2677b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
2678b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, IncomingPairRequestPinCode) {
2680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->AddPairingDelegate(
2686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
2687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
2688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requires that we provide a PIN code.
2690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->CreateDevice(
2691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
2692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath));
2693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2694a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPinCodeAddress);
2695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2700a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SimulatePairing(
2701a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath),
2702a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
27037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
2705a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
2706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2708a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2709a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
2710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set the PIN.
2712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->SetPinCode("1234");
2713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2715a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
2716a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
2717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2718a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // One change for paired, and one for trusted.
2719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2720a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
2721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2722a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
2723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2724a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
2725a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
2726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
2727a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath));
2728a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(properties->trusted.value());
2729a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2730a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No pairing context should remain on the device.
2731a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDeviceChromeOS* device_chromeos =
2732a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<BluetoothDeviceChromeOS*>(device);
2733a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device_chromeos->GetPairing() == NULL);
2734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2736a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, IncomingPairConfirmPasskey) {
2737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2741a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2742a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->AddPairingDelegate(
2743a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
2744a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
2745a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2746a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requests that we confirm a displayed passkey.
2747a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->CreateDevice(
2748a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
2749a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath));
2750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2751a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
2752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2757a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SimulatePairing(
2758a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath),
2759a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
27607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
2762a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
2763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2765a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2766a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
2767a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(123456U, pairing_delegate.last_passkey_);
2768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2769a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Confirm the passkey.
2770a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->ConfirmPairing();
2771a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2773a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
2774a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
2775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // One change for paired, and one for trusted.
2777a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
2779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
2781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
2783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
2784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
2785a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath));
2786a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(properties->trusted.value());
2787a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2788a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No pairing context should remain on the device.
2789a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDeviceChromeOS* device_chromeos =
2790a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<BluetoothDeviceChromeOS*>(device);
2791a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device_chromeos->GetPairing() == NULL);
2792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2794a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, IncomingPairRequestPasskey) {
2795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2800a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->AddPairingDelegate(
2801a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
2802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
2803a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2804a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requests that we provide a Passkey.
2805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->CreateDevice(
2806a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
2807a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath));
2808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2809a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPasskeyAddress);
2810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2815a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SimulatePairing(
2816a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath),
2817a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
28187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
2820a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
2821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2824a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
2825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2826a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set the Passkey.
2827a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->SetPasskey(1234);
2828a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2830a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
2831a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
2832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2833a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // One change for paired, and one for trusted.
2834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2835a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
2836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2837a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
2838a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2839a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
2840a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
2841a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
2842a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath));
2843a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(properties->trusted.value());
2844a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2845a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No pairing context should remain on the device.
2846a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDeviceChromeOS* device_chromeos =
2847a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<BluetoothDeviceChromeOS*>(device);
2848a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device_chromeos->GetPairing() == NULL);
2849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2851a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, IncomingPairJustWorks) {
2852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2856a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
2857a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->AddPairingDelegate(
2858a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
2859a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
2860a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2861a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Uses just-works pairing so, sinec this an incoming pairing, require
2862a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // authorization from the user.
2863a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->CreateDevice(
2864a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
2865a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath));
2866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2867a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kJustWorksAddress);
2868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2873a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SimulatePairing(
2874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath),
2875a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
28767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
2878a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
2879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2882a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.authorize_pairing_count_);
2883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2884a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Confirm the pairing.
2885a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->ConfirmPairing();
2886a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2888a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, callback_count_);
2889a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
2890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2891a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // One change for paired, and one for trusted.
2892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2893a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
2894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2895a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
2896a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2897a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Make sure the trusted property has been set to true.
2898a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
2899a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
2900a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath));
2901a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(properties->trusted.value());
2902a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2903a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No pairing context should remain on the device.
2904a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDeviceChromeOS* device_chromeos =
2905a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<BluetoothDeviceChromeOS*>(device);
2906a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device_chromeos->GetPairing() == NULL);
2907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2909a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, IncomingPairRequestPinCodeWithoutDelegate) {
2910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2914a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requires that we provide a PIN Code, without a pairing delegate,
2915a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // that will be rejected.
2916a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->CreateDevice(
2917a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
2918a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath));
2919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2920a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPinCodeAddress);
2921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2926a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SimulatePairing(
2927a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath),
2928a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
29297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
2931a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
2932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2934a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2938a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(bluetooth_device::kErrorAuthenticationRejected, last_client_error_);
2939a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2940a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No changes should be observer.
2941a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.device_changed_count_);
2942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2945a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No pairing context should remain on the device.
2946a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDeviceChromeOS* device_chromeos =
2947a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<BluetoothDeviceChromeOS*>(device);
2948a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device_chromeos->GetPairing() == NULL);
2949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2951a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, IncomingPairConfirmPasskeyWithoutDelegate) {
2952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2956a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requests that we confirm a displayed passkey, without a pairing delegate,
2957a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // that will be rejected.
2958a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->CreateDevice(
2959a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
2960a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath));
2961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
2962a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kConfirmPasskeyAddress);
2963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
2964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
2965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2968a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SimulatePairing(
2969a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath),
2970a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
29717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
2973a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
2974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2976a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
2977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2980a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(bluetooth_device::kErrorAuthenticationRejected, last_client_error_);
2981a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2982a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No changes should be observer.
2983a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.device_changed_count_);
2984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2987a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No pairing context should remain on the device.
2988a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDeviceChromeOS* device_chromeos =
2989a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<BluetoothDeviceChromeOS*>(device);
2990a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device_chromeos->GetPairing() == NULL);
2991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2993a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, IncomingPairRequestPasskeyWithoutDelegate) {
2994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
2995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
2997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2998a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requests that we provide a displayed passkey, without a pairing delegate,
2999a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // that will be rejected.
3000a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->CreateDevice(
3001a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
3002a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath));
3003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
3004a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPasskeyAddress);
3005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
3006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
3007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
3009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3010a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SimulatePairing(
3011a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath),
3012a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
30137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
3014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
3015a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
3016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
3017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3018a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
3019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
3021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
3022a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(bluetooth_device::kErrorAuthenticationRejected, last_client_error_);
3023a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3024a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No changes should be observer.
3025a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.device_changed_count_);
3026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
3028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3029a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No pairing context should remain on the device.
3030a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDeviceChromeOS* device_chromeos =
3031a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<BluetoothDeviceChromeOS*>(device);
3032a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device_chromeos->GetPairing() == NULL);
3033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3035a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, IncomingPairJustWorksWithoutDelegate) {
3036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
3037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
3039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3040a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Uses just-works pairing and thus requires authorization for incoming
3041a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // pairings, without a pairing delegate, that will be rejected.
3042a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->CreateDevice(
3043a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
3044a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath));
3045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
3046a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kJustWorksAddress);
3047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
3048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
3049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
3051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3052a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SimulatePairing(
3053a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath),
3054a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
30557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
3056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
3057a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
3058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
3059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3060a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  message_loop_.Run();
3061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
3063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
3064a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(bluetooth_device::kErrorAuthenticationRejected, last_client_error_);
3065a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3066a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No changes should be observer.
3067a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.device_changed_count_);
3068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
3070c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3071a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No pairing context should remain on the device.
3072a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDeviceChromeOS* device_chromeos =
3073a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<BluetoothDeviceChromeOS*>(device);
3074a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device_chromeos->GetPairing() == NULL);
3075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3077a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, RemovePairingDelegateDuringPairing) {
3078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
3079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
3081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3082a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestPairingDelegate pairing_delegate;
3083a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->AddPairingDelegate(
3084a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &pairing_delegate,
3085a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
3086a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3087a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Requests that we provide a Passkey.
3088a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->CreateDevice(
3089a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
3090a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath));
3091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
3092a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kRequestPasskeyAddress);
3093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
3094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
3095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
3097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3098a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  fake_bluetooth_device_client_->SimulatePairing(
3099a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath),
3100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      true,
31017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
3102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
3103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::DBusErrorCallback,
3104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
3105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
3107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
3108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // A pairing context should now be set on the device.
3110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDeviceChromeOS* device_chromeos =
3111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      static_cast<BluetoothDeviceChromeOS*>(device);
3112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device_chromeos->GetPairing() != NULL);
3113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Removing the pairing delegate should remove that pairing context.
3115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  adapter_->RemovePairingDelegate(&pairing_delegate);
3116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(device_chromeos->GetPairing() == NULL);
3118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set the Passkey, this should now have no effect since the pairing has
3120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // been, in-effect, cancelled
3121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  device->SetPasskey(1234);
3122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
3124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
3125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, observer.device_changed_count_);
3126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
3128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
3129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DeviceId) {
3131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetAdapter();
3132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Use the built-in paired device for this test, grab its Properties
3134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // structure so we can adjust the underlying modalias property.
3135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
3136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FakeBluetoothDeviceClient::kPairedDeviceAddress);
3137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
3138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
3139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
3140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(device != NULL);
3142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(properties != NULL);
3143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Valid USB IF-assigned identifier.
3145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ("usb:v05ACp030Dd0306", properties->modalias.value());
3146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::VENDOR_ID_USB, device->GetVendorIDSource());
3148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0x05ac, device->GetVendorID());
3149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0x030d, device->GetProductID());
3150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0x0306, device->GetDeviceID());
3151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Valid Bluetooth SIG-assigned identifier.
3153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  properties->modalias.ReplaceValue("bluetooth:v00E0p2400d0400");
3154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::VENDOR_ID_BLUETOOTH, device->GetVendorIDSource());
3156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0x00e0, device->GetVendorID());
3157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0x2400, device->GetProductID());
3158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0x0400, device->GetDeviceID());
3159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Invalid USB IF-assigned identifier.
3161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  properties->modalias.ReplaceValue("usb:x00E0p2400d0400");
3162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::VENDOR_ID_UNKNOWN, device->GetVendorIDSource());
3164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, device->GetVendorID());
3165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, device->GetProductID());
3166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, device->GetDeviceID());
3167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Invalid Bluetooth SIG-assigned identifier.
3169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  properties->modalias.ReplaceValue("bluetooth:x00E0p2400d0400");
3170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::VENDOR_ID_UNKNOWN, device->GetVendorIDSource());
3172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, device->GetVendorID());
3173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, device->GetProductID());
3174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, device->GetDeviceID());
3175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Unknown vendor specification identifier.
3177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  properties->modalias.ReplaceValue("chrome:v00E0p2400d0400");
3178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(BluetoothDevice::VENDOR_ID_UNKNOWN, device->GetVendorIDSource());
3180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, device->GetVendorID());
3181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, device->GetProductID());
3182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(0, device->GetDeviceID());
3183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace chromeos
3186