bluetooth_chromeos_unittest.cc revision f2477e01787aa58f445919b809d89e252beef54f
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)
59ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/fake_bluetooth_adapter_client.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/fake_bluetooth_device_client.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chromeos/dbus/fake_bluetooth_input_client.h"
118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/dbus/fake_dbus_thread_manager.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/object_path.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "device/bluetooth/bluetooth_adapter.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_chromeos.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "device/bluetooth/bluetooth_adapter_factory.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "device/bluetooth/bluetooth_device.h"
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "device/bluetooth/bluetooth_device_chromeos.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothAdapter;
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothAdapterFactory;
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using device::BluetoothDevice;
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos {
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestObserver : public BluetoothAdapter::Observer {
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver(scoped_refptr<BluetoothAdapter> adapter)
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : present_changed_count_(0),
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        powered_changed_count_(0),
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        discovering_changed_count_(0),
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_present_(false),
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_powered_(false),
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_discovering_(false),
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        device_added_count_(0),
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        device_changed_count_(0),
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        device_removed_count_(0),
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_device_(NULL),
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        adapter_(adapter) {
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~TestObserver() {}
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AdapterPresentChanged(BluetoothAdapter* adapter,
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     bool present) OVERRIDE {
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(adapter_, adapter);
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++present_changed_count_;
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_present_ = present;
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AdapterPoweredChanged(BluetoothAdapter* adapter,
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     bool powered) OVERRIDE {
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(adapter_, adapter);
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++powered_changed_count_;
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_powered_ = powered;
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AdapterDiscoveringChanged(BluetoothAdapter* adapter,
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         bool discovering) OVERRIDE {
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(adapter_, adapter);
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++discovering_changed_count_;
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_discovering_ = discovering;
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void DeviceAdded(BluetoothAdapter* adapter,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           BluetoothDevice* device) OVERRIDE {
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(adapter_, adapter);
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++device_added_count_;
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_ = device;
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_address_ = device->GetAddress();
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void DeviceChanged(BluetoothAdapter* adapter,
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             BluetoothDevice* device) OVERRIDE {
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(adapter_, adapter);
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++device_changed_count_;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_ = device;
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_address_ = device->GetAddress();
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void DeviceRemoved(BluetoothAdapter* adapter,
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             BluetoothDevice* device) OVERRIDE {
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(adapter_, adapter);
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++device_removed_count_;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Can't save device, it may be freed
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_device_address_ = device->GetAddress();
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int present_changed_count_;
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int powered_changed_count_;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int discovering_changed_count_;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool last_present_;
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool last_powered_;
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool last_discovering_;
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int device_added_count_;
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int device_changed_count_;
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int device_removed_count_;
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* last_device_;
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string last_device_address_;
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Some tests use a message loop since background processing is simulated;
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // break out of those loops.
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void QuitMessageLoop() {
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (base::MessageLoop::current() &&
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::MessageLoop::current()->is_running())
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::MessageLoop::current()->Quit();
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<BluetoothAdapter> adapter_;
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestPairingDelegate : public BluetoothDevice::PairingDelegate {
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate()
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : call_count_(0),
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        request_pincode_count_(0),
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        request_passkey_count_(0),
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        display_pincode_count_(0),
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        display_passkey_count_(0),
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        keys_entered_count_(0),
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        confirm_passkey_count_(0),
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        dismiss_count_(0),
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_passkey_(9999999U),
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        last_entered_(999U) {}
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~TestPairingDelegate() {}
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void RequestPinCode(BluetoothDevice* device) OVERRIDE {
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++request_pincode_count_;
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void RequestPasskey(BluetoothDevice* device) OVERRIDE {
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++request_passkey_count_;
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
151b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void DisplayPinCode(BluetoothDevice* device,
152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                              const std::string& pincode) OVERRIDE {
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++display_pincode_count_;
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_pincode_ = pincode;
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void DisplayPasskey(BluetoothDevice* device,
160b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                              uint32 passkey) OVERRIDE {
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++display_passkey_count_;
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_passkey_ = passkey;
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
167b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void KeysEntered(BluetoothDevice* device, uint32 entered) OVERRIDE {
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++keys_entered_count_;
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_entered_ = entered;
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
174b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void ConfirmPasskey(BluetoothDevice* device,
175b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                              uint32 passkey) OVERRIDE {
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++confirm_passkey_count_;
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_passkey_ = passkey;
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
182b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void DismissDisplayOrConfirm() OVERRIDE {
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++call_count_;
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++dismiss_count_;
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    QuitMessageLoop();
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int call_count_;
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int request_pincode_count_;
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int request_passkey_count_;
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int display_pincode_count_;
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int display_passkey_count_;
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int keys_entered_count_;
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int confirm_passkey_count_;
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int dismiss_count_;
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 last_passkey_;
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 last_entered_;
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string last_pincode_;
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  private:
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   // Some tests use a message loop since background processing is simulated;
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   // break out of those loops.
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   void QuitMessageLoop() {
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     if (base::MessageLoop::current() &&
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         base::MessageLoop::current()->is_running())
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       base::MessageLoop::current()->Quit();
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   }
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BluetoothChromeOSTest : public testing::Test {
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() {
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeDBusThreadManager* fake_dbus_thread_manager = new FakeDBusThreadManager;
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_bluetooth_adapter_client_ = new FakeBluetoothAdapterClient;
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_dbus_thread_manager->SetBluetoothAdapterClient(
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<BluetoothAdapterClient>(fake_bluetooth_adapter_client_));
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_bluetooth_device_client_ = new FakeBluetoothDeviceClient;
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_dbus_thread_manager->SetBluetoothDeviceClient(
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<BluetoothDeviceClient>(fake_bluetooth_device_client_));
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_dbus_thread_manager->SetBluetoothInputClient(
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient));
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fake_dbus_thread_manager->SetBluetoothAgentManagerClient(
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<BluetoothAgentManagerClient>(
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            new FakeBluetoothAgentManagerClient));
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager);
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_count_ = 0;
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_callback_count_ = 0;
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_connect_error_ = BluetoothDevice::ERROR_UNKNOWN;
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TearDown() {
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_ = NULL;
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DBusThreadManager::Shutdown();
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Generic callbacks
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Callback() {
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++callback_count_;
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ErrorCallback() {
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++error_callback_count_;
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ConnectErrorCallback(enum BluetoothDevice::ConnectErrorCode error) {
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ++error_callback_count_;
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_connect_error_ = error;
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Call to fill the adapter_ member with a BluetoothAdapter instance.
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void GetAdapter() {
2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    adapter_ = new BluetoothAdapterChromeOS();
2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ASSERT_TRUE(adapter_.get() != NULL);
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(adapter_->IsInitialized());
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Run a discovery phase until the named device is detected, or if the named
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // device is not created, the discovery process ends without finding it.
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The correct behavior of discovery is tested by the "Discovery" test case
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // without using this function.
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DiscoverDevice(const std::string& address) {
2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ASSERT_TRUE(adapter_.get() != NULL);
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (base::MessageLoop::current() == NULL) {
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DiscoverDevices();
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TestObserver observer(adapter_);
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_->AddObserver(&observer);
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_->SetPowered(
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        true,
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::Callback,
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)),
2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)));
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_->StartDiscovering(
2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::Callback,
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)),
2867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)));
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(2, callback_count_);
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(0, error_callback_count_);
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_count_ = 0;
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(adapter_->IsPowered());
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(adapter_->IsDiscovering());
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    while (!observer.device_removed_count_ &&
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           observer.last_device_address_ != address)
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::MessageLoop::current()->Run();
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_->StopDiscovering(
3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::Callback,
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)),
3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothChromeOSTest::ErrorCallback,
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)));
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(1, callback_count_);
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_EQ(0, error_callback_count_);
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_count_ = 0;
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_FALSE(adapter_->IsDiscovering());
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    adapter_->RemoveObserver(&observer);
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Run a discovery phase so we have devices that can be paired with.
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DiscoverDevices() {
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Pass an invalid address for the device so that the discovery process
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // completes with all devices.
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DiscoverDevice("does not exist");
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothAdapterClient* fake_bluetooth_adapter_client_;
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient* fake_bluetooth_device_client_;
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<BluetoothAdapter> adapter_;
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int callback_count_;
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int error_callback_count_;
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  enum BluetoothDevice::ConnectErrorCode last_connect_error_;
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, AlreadyPresent) {
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This verifies that the class gets the list of adapters when created;
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and initializes with an existing adapter if there is one.
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPresent());
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterAddress,
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            adapter_->GetAddress());
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // There should be a device
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1U, devices.size());
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            devices[0]->GetAddress());
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, BecomePresent) {
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(adapter_->IsPresent());
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the AdapterPresentChanged to be called
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with true, and IsPresent() to return true.
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(true);
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.present_changed_count_);
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer.last_present_);
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPresent());
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We should have had a device announced.
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_added_count_);
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Other callbacks shouldn't be called if the values are false.
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.powered_changed_count_);
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, BecomeNotPresent) {
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPresent());
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the AdapterPresentChanged to be called
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with false, and IsPresent() to return false.
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.present_changed_count_);
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_present_);
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPresent());
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We should have had a device removed.
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_removed_count_);
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Other callbacks shouldn't be called since the values are false.
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.powered_changed_count_);
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, SecondAdapter) {
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPresent());
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer, then add a second adapter. Nothing should change,
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // we ignore the second adapter.
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetSecondVisible(true);
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.present_changed_count_);
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPresent());
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterAddress,
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            adapter_->GetAddress());
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Try removing the first adapter, we should now act as if the adapter
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is no longer present rather than fall back to the second.
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.present_changed_count_);
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_present_);
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPresent());
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We should have had a device removed.
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_removed_count_);
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Other callbacks shouldn't be called since the values are false.
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.powered_changed_count_);
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer.device_removed_count_ = 0;
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Removing the second adapter shouldn't set anything either.
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetSecondVisible(false);
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.device_removed_count_);
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.powered_changed_count_);
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, BecomePowered) {
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(adapter_->IsPowered());
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the AdapterPoweredChanged to be called
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with true, and IsPowered() to return true.
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
4637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.powered_changed_count_);
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer.last_powered_);
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPowered());
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, BecomeNotPowered) {
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
4827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the AdapterPoweredChanged to be called
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with false, and IsPowered() to return false.
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      false,
4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.powered_changed_count_);
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_powered_);
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, StopDiscovery) {
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
5197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->StartDiscovering(
5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
5247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, callback_count_);
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsDiscovering());
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; aside from the callback, expect the
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // AdapterDiscoveringChanged method to be called and no longer to be
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // discovering,
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->StopDiscovering(
5407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, StopDiscoveryAfterTwoStarts) {
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
5607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
5627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->StartDiscovering(
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(2, callback_count_);
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsDiscovering());
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer and start discovering again; only the callback
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // should be called since we were already discovering to begin with.
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->StartDiscovering(
5827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
5847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Stop discovering; only the callback should be called since we're still
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // discovering. The adapter should be still discovering.
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->StopDiscovering(
5957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
5977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.discovering_changed_count_);
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Stop discovering one more time; aside from the callback, expect the
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // AdapterDiscoveringChanged method to be called and no longer to be
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // discovering,
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->StopDiscovering(
6117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
6137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, Discovery) {
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test a simulated discovery session.
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
6387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->StartDiscovering(
6417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
6437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, callback_count_);
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsDiscovering());
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // First device to appear should be an Apple Mouse.
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_added_count_);
656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kAppleMouseAddress,
657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Next we should get another two devices...
660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(3, observer.device_added_count_);
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Okay, let's run forward until a device is actually removed...
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (!observer.device_removed_count_)
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop.Run();
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_removed_count_);
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kVanishingDeviceAddress,
669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PoweredAndDiscovering) {
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->SetPowered(
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
6787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
6807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->StartDiscovering(
6837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
6857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, callback_count_);
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Stop the timers that the simulation uses
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->EndDiscoverySimulation(
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath));
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsPowered());
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(adapter_->IsDiscovering());
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(adapter_->IsPresent());
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the AdapterPresentChanged,
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // AdapterPoweredChanged and AdapterDiscoveringChanged methods to be called
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with true, and IsPresent(), IsPowered() and IsDiscovering() to all
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // return true.
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(true);
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.present_changed_count_);
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer.last_present_);
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPresent());
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.powered_changed_count_);
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer.last_powered_);
716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsPowered());
717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(observer.last_discovering_);
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(adapter_->IsDiscovering());
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer.present_changed_count_ = 0;
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer.powered_changed_count_ = 0;
724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  observer.discovering_changed_count_ = 0;
725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now mark the adapter not present again. Expect the methods to be called
727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // again, to reset the properties back to false
728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_adapter_client_->SetVisible(false);
729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.present_changed_count_);
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_present_);
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPresent());
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.powered_changed_count_);
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_powered_);
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsPowered());
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.discovering_changed_count_);
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(observer.last_discovering_);
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(adapter_->IsDiscovering());
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DeviceProperties) {
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, devices.size());
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            devices[0]->GetAddress());
750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify the other device properties.
752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName),
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            devices[0]->GetName());
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::DEVICE_COMPUTER, devices[0]->GetDeviceType());
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(devices[0]->IsPaired());
756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(devices[0]->IsConnected());
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(devices[0]->IsConnecting());
758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Non HID devices are always connectable.
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(devices[0]->IsConnectable());
761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice::ServiceList uuids = devices[0]->GetServices();
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(2U, uuids.size());
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[0], "00001800-0000-1000-8000-00805f9b34fb");
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[1], "00001801-0000-1000-8000-00805f9b34fb");
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0x05ac, devices[0]->GetVendorID());
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0x030d, devices[0]->GetProductID());
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0x0306, devices[0]->GetDeviceID());
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DeviceClassChanged) {
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Simulate a change of class of a device, as sometimes occurs
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // during discovery.
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, devices.size());
779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            devices[0]->GetAddress());
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(BluetoothDevice::DEVICE_COMPUTER, devices[0]->GetDeviceType());
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the DeviceChanged method to be called when
784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // we change the class of the device.
785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  properties->bluetooth_class.ReplaceValue(0x002580);
793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_changed_count_);
795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(devices[0], observer.last_device_);
796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::DEVICE_MOUSE, devices[0]->GetDeviceType());
798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DeviceNameChanged) {
801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Simulate a change of name of a device.
802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, devices.size());
806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            devices[0]->GetAddress());
808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName),
809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            devices[0]->GetName());
810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the DeviceChanged method to be called when
812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // we change the alias of the device.
813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const std::string new_name("New Device Name");
821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  properties->alias.ReplaceValue(new_name);
822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_changed_count_);
824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(devices[0], observer.last_device_);
825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(UTF8ToUTF16(new_name), devices[0]->GetName());
827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DeviceUuidsChanged) {
830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Simulate a change of advertised services of a device.
831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, devices.size());
835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            devices[0]->GetAddress());
837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice::ServiceList uuids = devices[0]->GetServices();
839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(2U, uuids.size());
840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(uuids[0], "00001800-0000-1000-8000-00805f9b34fb");
841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(uuids[1], "00001801-0000-1000-8000-00805f9b34fb");
842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the DeviceChanged method to be called when
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // we change the class of the device.
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath));
851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uuids.push_back("0000110c-0000-1000-8000-00805f9b34fb");
853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uuids.push_back("0000110e-0000-1000-8000-00805f9b34fb");
854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uuids.push_back("0000110a-0000-1000-8000-00805f9b34fb");
855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  properties->uuids.ReplaceValue(uuids);
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_changed_count_);
859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(devices[0], observer.last_device_);
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Fetching the value should give the new one.
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uuids = devices[0]->GetServices();
863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(5U, uuids.size());
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[0], "00001800-0000-1000-8000-00805f9b34fb");
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[1], "00001801-0000-1000-8000-00805f9b34fb");
866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[2], "0000110c-0000-1000-8000-00805f9b34fb");
867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[3], "0000110e-0000-1000-8000-00805f9b34fb");
868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[4], "0000110a-0000-1000-8000-00805f9b34fb");
869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ForgetDevice) {
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, devices.size());
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress,
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            devices[0]->GetAddress());
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string address = devices[0]->GetAddress();
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the DeviceRemoved method to be called
882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with the device we remove.
883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  devices[0]->Forget(
8877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_removed_count_);
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(address, observer.last_device_address_);
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // GetDevices shouldn't return the device either.
895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  devices = adapter_->GetDevices();
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(0U, devices.size());
897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ForgetUnpairedDevice) {
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kMicrosoftMouseAddress);
905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Connect the device so it becomes trusted and remembered.
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NULL,
9117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
9137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1, callback_count_);
917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(0, error_callback_count_);
918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device->IsConnected());
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsConnecting());
922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true.
924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kMicrosoftMousePath));
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(properties->trusted.value());
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install an observer; expect the DeviceRemoved method to be called
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // with the device we remove.
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Forget(
9357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_removed_count_);
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(FakeBluetoothDeviceClient::kMicrosoftMouseAddress,
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            observer.last_device_address_);
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // GetDevices shouldn't return the device either.
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device = adapter_->GetDevice(
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kMicrosoftMouseAddress);
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device != NULL);
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ConnectPairedDevice) {
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kPairedDeviceAddress);
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device->IsPaired());
956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Connect without a pairing delegate; since the device is already Paired
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // this should succeed and the device should become connected.
962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NULL,
9647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
9667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Two changes for connecting, one for connected and one for for trusted
973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // after connecting.
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(4, observer.device_changed_count_);
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ConnectUnpairableDevice) {
982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kMicrosoftMouseAddress);
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Connect without a pairing delegate; since the device does not require
994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pairing, this should succeed and the device should become connected.
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NULL,
9977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
9997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Two changes for connecting, one for connected, one for for trusted after
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // connection, and one for the reconnect mode (IsConnectable).
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(5, observer.device_changed_count_);
1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true.
1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kMicrosoftMousePath));
1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify is a HID device and is not connectable.
1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice::ServiceList uuids = device->GetServices();
1021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, uuids.size());
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[0], "00001124-0000-1000-8000-00805f9b34fb");
1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnectable());
1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ConnectConnectedDevice) {
1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kPairedDeviceAddress);
1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device->IsPaired());
1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NULL,
10367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
10387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1, callback_count_);
1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(0, error_callback_count_);
1043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device->IsConnected());
1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Connect again; since the device is already Connected, this shouldn't do
1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // anything to initiate the connection.
1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NULL,
10547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
10567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The observer will be called because Connecting will toggle true and false,
1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // and the trusted property will be updated to true.
1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(3, observer.device_changed_count_);
1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, ConnectDeviceFails) {
1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kAppleMouseAddress);
1076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Connect without a pairing delegate; since the device requires pairing,
1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // this should fail with an error.
1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NULL,
10867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
10887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_);
1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
1096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DisconnectDevice) {
1102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kPairedDeviceAddress);
1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device->IsPaired());
1108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NULL,
11117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
11137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1, callback_count_);
1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(0, error_callback_count_);
1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  callback_count_ = 0;
1119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device->IsConnected());
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsConnecting());
1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Disconnect the device, we should see the observer method fire and the
1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // device get dropped.
1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Disconnect(
11297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
11317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, observer.device_changed_count_);
1138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, DisconnectUnconnectedDevice) {
1144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kPairedDeviceAddress);
1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device->IsPaired());
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsConnected());
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Disconnect the device, we should see the observer method fire and the
1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // device get dropped.
1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Disconnect(
11587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
11607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ErrorCallback,
1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, observer.device_changed_count_);
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairAppleMouse) {
1172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The Apple Mouse requires no PIN or Passkey to pair; this is equivalent
1179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // to Simple Secure Pairing or a device with a fixed 0000 PIN.
1180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kAppleMouseAddress);
1182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
11917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
11937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
1197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired,
1205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // two for trusted (after pairing and connection), and one for the reconnect
1206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // mode (IsConnectable).
1207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(7, observer.device_changed_count_);
1208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
1214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify is a HID device and is connectable.
1216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice::ServiceList uuids = device->GetServices();
1217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, uuids.size());
1218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[0], "00001124-0000-1000-8000-00805f9b34fb");
1219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
1220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true.
1226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kAppleMousePath));
1229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairAppleKeyboard) {
1233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The Apple Keyboard requires that we display a randomly generated
1240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // PIN on the screen.
1241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kAppleKeyboardAddress);
1243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
12527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
12547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.display_pincode_count_);
1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("123456", pairing_delegate.last_pincode_);
1260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired,
1268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // two for trusted (after pairing and connection), and one for the reconnect
1269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // mode (IsConnectable).
1270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(7, observer.device_changed_count_);
1271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
1277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify is a HID device and is connectable.
1279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice::ServiceList uuids = device->GetServices();
1280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, uuids.size());
1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[0], "00001124-0000-1000-8000-00805f9b34fb");
1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
1283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true.
1288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kAppleKeyboardPath));
1291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairMotorolaKeyboard) {
1295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The Motorola Keyboard requires that we display a randomly generated
1302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Passkey on the screen, and notifies us as it's typed in.
1303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kMotorolaKeyboardAddress);
1305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
13147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
13167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // One call for DisplayPasskey() and one for KeysEntered().
1320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.display_passkey_count_);
1322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(123456U, pairing_delegate.last_passkey_);
1323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.keys_entered_count_);
1324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0U, pairing_delegate.last_entered_);
1325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // One call to KeysEntered() for each key, including [enter].
1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for(int i = 1; i <= 7; ++i) {
1330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop.Run();
1331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(2 + i, pairing_delegate.call_count_);
1333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(1 + i, pairing_delegate.keys_entered_count_);
1334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(static_cast<uint32_t>(i), pairing_delegate.last_entered_);
1335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // 8 KeysEntered notifications (0 to 7, inclusive). Two aditional calls for
1340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // DisplayPasskey() and DismissDisplayOrConfirm().
1341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(10, pairing_delegate.call_count_);
1342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(8, pairing_delegate.keys_entered_count_);
1343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(7U, pairing_delegate.last_entered_);
1344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired,
1349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // two for trusted (after pairing and connection), and one for the reconnect
1350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // mode (IsConnectable).
1351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(7, observer.device_changed_count_);
1352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
1358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify is a HID device.
1360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice::ServiceList uuids = device->GetServices();
1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, uuids.size());
1362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(uuids[0], "00001124-0000-1000-8000-00805f9b34fb");
1363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Fake MotorolaKeyboard is not connectable.
1365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnectable());
1366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true.
1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kMotorolaKeyboardPath));
1374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairSonyHeadphones) {
1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The Sony Headphones fake requires that the user enters a PIN for them.
1385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kSonyHeadphonesAddress);
1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
13967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
13987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
1403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set the PIN.
1406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->SetPinCode("1234");
1407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired and
1413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // two for trusted (after pairing and connection).
1414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(6, observer.device_changed_count_);
1415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
1421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verify is not a HID device.
1423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice::ServiceList uuids = device->GetServices();
1424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(0U, uuids.size());
1425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Non HID devices are always connectable.
1427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
1428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true.
1434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kSonyHeadphonesPath));
1437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairPhone) {
1441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The fake phone requests that we confirm a displayed passkey.
1448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kPhoneAddress);
1450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
14597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
14617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
1466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(123456U, pairing_delegate.last_passkey_);
1467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Confirm the passkey.
1470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->ConfirmPairing();
1471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired and
1477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // two for trusted (after pairing and connection).
1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(6, observer.device_changed_count_);
1479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
1485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Non HID devices are always connectable.
1487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
1488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true.
1494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kPhonePath));
1497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairWeirdDevice) {
1501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Use the "weird device" fake that requires that the user enters a Passkey,
1508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // this would be some kind of device that has a display, but doesn't use
1509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // "just works" - maybe a car?
1510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kWeirdDeviceAddress);
1512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
15217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
15237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
1528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set the Passkey.
1531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->SetPasskey(1234);
1532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, callback_count_);
1535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, error_callback_count_);
1536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Two changes for connecting, one change for connected, one for paired and
1538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // two for trusted (after pairing and connection).
1539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(6, observer.device_changed_count_);
1540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnected());
1543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
1546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Non HID devices are always connectable.
1548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnectable());
1549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true.
1555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(FakeBluetoothDeviceClient::kWeirdDevicePath));
1558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairUnpairableDeviceFails) {
1562b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1563b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1564b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1565b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GetAdapter();
1566b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DiscoverDevice(FakeBluetoothDeviceClient::kUnconnectableDeviceAddress);
1567b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1568b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1569b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      FakeBluetoothDeviceClient::kUnpairableDeviceAddress);
1570b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1571b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1572b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1573b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TestObserver observer(adapter_);
1574b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  adapter_->AddObserver(&observer);
1575b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1576b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1577b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  device->Connect(
1578b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      &pairing_delegate,
15797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1580b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                 base::Unretained(this)),
15817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1582b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                 base::Unretained(this)));
1583b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1584b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
1585b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1586b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1587b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Run the loop to get the error..
1588b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  message_loop.Run();
1589b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1590b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1591b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1592b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1593b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_);
1594b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1595b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1596b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1597b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
1598b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1599b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Pairing dialog should be dismissed
1600b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1601b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1602b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
1603b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
16047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingFails) {
1605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevice(FakeBluetoothDeviceClient::kVanishingDeviceAddress);
1610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The vanishing device times out during pairing
1612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kVanishingDeviceAddress);
1614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
16237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
16257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
1629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Run the loop to get the error..
1632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_TIMEOUT, last_connect_error_);
1638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
1642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingFailsAtConnection) {
1649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Everything seems to go according to plan with the unconnectable device;
1656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // it pairs, but then you can't make connections to it after.
1657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kUnconnectableDeviceAddress);
1659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
16687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
16707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
1674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_);
1681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Two changes for connecting, one for paired and one for trusted after
1683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // pairing. The device should not be connected.
1684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(4, observer.device_changed_count_);
1685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(device, observer.last_device_);
1686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsPaired());
1691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Make sure the trusted property has been set to true still (since pairing
1697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // worked).
1698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeBluetoothDeviceClient::Properties* properties =
1699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fake_bluetooth_device_client_->GetProperties(
1700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          dbus::ObjectPath(
1701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              FakeBluetoothDeviceClient::kUnconnectableDevicePath));
1702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(properties->trusted.value());
1703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingRejectedAtPinCode) {
1706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Reject the pairing after we receive a request for the PIN code.
1713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kSonyHeadphonesAddress);
1715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
17247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
17267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
1731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Reject the pairing.
1734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->RejectPairing();
1735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_);
1740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should be no changes except connecting going true and false.
1742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
1743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
1746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingCancelledAtPinCode) {
1753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cancel the pairing after we receive a request for the PIN code.
1760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kSonyHeadphonesAddress);
1762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
17717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
17737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
1778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cancel the pairing.
1781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->CancelPairing();
1782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);
1787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should be no changes except connecting going true and false.
1789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
1790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
1793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingRejectedAtPasskey) {
1800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Reject the pairing after we receive a request for the passkey.
1807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kWeirdDeviceAddress);
1809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
18187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
18207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
1825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Reject the pairing.
1828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->RejectPairing();
1829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_);
1834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should be no changes except connecting going true and false.
1836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
1837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
1840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingCancelledAtPasskey) {
1847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cancel the pairing after we receive a request for the passkey.
1854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kWeirdDeviceAddress);
1856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
18657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
18677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.request_passkey_count_);
1872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cancel the pairing.
1875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->CancelPairing();
1876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);
1881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should be no changes except connecting going true and false.
1883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
1884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
1887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingRejectedAtConfirmation) {
1894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Reject the pairing after we receive a request for passkey confirmation.
1901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kPhoneAddress);
1903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
19127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
19147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
1919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Reject the pairing.
1922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->RejectPairing();
1923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_);
1928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should be no changes except connecting going true and false.
1930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
1931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
1934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingCancelledAtConfirmation) {
1941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cancel the pairing after we receive a request for the passkey.
1948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kPhoneAddress);
1950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
1954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
1955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
1957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
1958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
19597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
1960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
19617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
1962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
1963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
1965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_);
1966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
1967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cancel the pairing.
1969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->CancelPairing();
1970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
1971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
1973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
1974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);
1975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should be no changes except connecting going true and false.
1977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
1978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
1979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
1980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
1981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
1983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, pairing_delegate.call_count_);
1984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
1985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BluetoothChromeOSTest, PairingCancelledInFlight) {
1988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT);
1989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fake_bluetooth_device_client_->SetSimulationIntervalMs(10);
1990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetAdapter();
1992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DiscoverDevices();
1993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cancel the pairing while we're waiting for the remote host.
1995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice* device = adapter_->GetDevice(
1996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FakeBluetoothDeviceClient::kAppleMouseAddress);
1997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(device != NULL);
1998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_FALSE(device->IsPaired());
1999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestObserver observer(adapter_);
2001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  adapter_->AddObserver(&observer);
2002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestPairingDelegate pairing_delegate;
2004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->Connect(
2005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &pairing_delegate,
20067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::Callback,
2007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)),
20087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
2009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
2010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, pairing_delegate.call_count_);
2012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(device->IsConnecting());
2013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cancel the pairing.
2015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  device->CancelPairing();
2016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_loop.Run();
2017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, callback_count_);
2019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, error_callback_count_);
2020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_);
2021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Should be no changes except connecting going true and false.
2023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(2, observer.device_changed_count_);
2024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnected());
2025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsConnecting());
2026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(device->IsPaired());
2027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pairing dialog should be dismissed
2029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.call_count_);
2030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(1, pairing_delegate.dismiss_count_);
2031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace chromeos
2034