1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef DEVICE_BLUETOOTH_BLUETOOTH_DISCOVERY_SESSION_H_ 6 #define DEVICE_BLUETOOTH_BLUETOOTH_DISCOVERY_SESSION_H_ 7 8 #include <memory> 9 10 #include "base/bind_helpers.h" 11 #include "base/callback.h" 12 #include "base/macros.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/weak_ptr.h" 15 #include "device/bluetooth/bluetooth_adapter.h" 16 #include "device/bluetooth/bluetooth_discovery_filter.h" 17 #include "device/bluetooth/bluetooth_discovery_session_outcome.h" 18 #include "device/bluetooth/bluetooth_export.h" 19 20 namespace device { 21 22 // BluetoothDiscoverySession represents a current active or inactive device 23 // discovery session. Instances of this class are obtained by calling 24 // BluetoothAdapter::StartDiscoverySession. The Bluetooth adapter will be 25 // constantly searching for nearby devices, as long as at least one instance 26 // of an active BluetoothDiscoverySession exists. A BluetoothDiscoverySession is 27 // considered active, as long as the adapter is discovering AND the owner of the 28 // instance has not called BluetoothDiscoverySession::Stop. A 29 // BluetoothDiscoverySession might unexpectedly become inactive, if the adapter 30 // unexpectedly stops discovery. Users can implement the 31 // AdapterDiscoveringChanged method of the BluetoothAdapter::Observer interface 32 // to be notified of such a change and promptly request a new 33 // BluetoothDiscoverySession if their existing sessions have become inactive. 34 class DEVICE_BLUETOOTH_EXPORT BluetoothDiscoverySession { 35 public: 36 // The ErrorCallback is used by methods to asynchronously report errors. 37 typedef base::Closure ErrorCallback; 38 39 enum SessionStatus { 40 // Just added to the adapter. 41 PENDING_START, 42 // Request sent to OS. 43 STARTING, 44 // Actively scanning. 45 SCANNING, 46 // Finished scanning, should be deleted soon. 47 INACTIVE 48 }; 49 50 // Destructor automatically terminates the discovery session. If this 51 // results in a call to the underlying system to stop device discovery 52 // (i.e. this instance represents the last active discovery session), 53 // the call may not always succeed. To be notified of such failures, 54 // users are highly encouraged to call BluetoothDiscoverySession::Stop, 55 // instead of relying on the destructor. 56 virtual ~BluetoothDiscoverySession(); 57 58 // Returns true if the session is active, false otherwise. If false, the 59 // adapter might still be discovering as there might still be other active 60 // sessions; this just means that this instance no longer has a say in 61 // whether or not discovery should continue. In this case, the application 62 // should request a new BluetoothDiscoverySession to make sure that device 63 // discovery continues. 64 virtual bool IsActive() const; 65 66 // Requests this discovery session instance to stop. If this instance is 67 // active, the session will stop. On success, |callback| is called and 68 // on error |error_callback| is called. After a successful invocation, the 69 // adapter may or may not stop device discovery, depending on whether or not 70 // other active discovery sessions are present. Users are highly encouraged 71 // to call this method to end a discovery session, instead of relying on the 72 // destructor, so that they can be notified of the result via the callback 73 // arguments. 74 virtual void Stop(base::Closure callback = base::DoNothing(), 75 ErrorCallback error_callback = base::DoNothing()); 76 77 virtual const BluetoothDiscoveryFilter* GetDiscoveryFilter() const; 78 status()79 SessionStatus status() const { return status_; } 80 81 // Updates the status from PENDING_START to STARTING. 82 void PendingSessionsStarting(); 83 84 // Updates the status from STARTING to SCANNING. 85 void StartingSessionsScanning(); 86 87 base::WeakPtr<BluetoothDiscoverySession> GetWeakPtr(); 88 89 protected: 90 explicit BluetoothDiscoverySession( 91 scoped_refptr<BluetoothAdapter> adapter, 92 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter); 93 94 private: 95 friend class BluetoothAdapter; 96 97 // Internal callback invoked when a call to 98 // BluetoothAdapter::RemoveDiscoverySession has succeeded. Invokes 99 // |deactivate_discovery_session| if the session object still 100 // exists when this callback executes. Always invokes |success_callback|. 101 static void OnDiscoverySessionRemoved( 102 base::WeakPtr<BluetoothDiscoverySession> session, 103 const base::Closure& deactivate_discovery_session, 104 const base::Closure& success_callback); 105 106 static void OnDiscoverySessionRemovalFailed( 107 base::WeakPtr<BluetoothDiscoverySession> session, 108 const base::Closure& error_callback, 109 UMABluetoothDiscoverySessionOutcome outcome); 110 111 // Deactivate discovery session object after 112 // BluetoothAdapter::RemoveDiscoverySession completes. 113 void DeactivateDiscoverySession(); 114 115 // Marks this instance as inactive. Called by BluetoothAdapter to mark a 116 // session as inactive in the case of an unexpected change to the adapter 117 // discovery state. 118 void MarkAsInactive(); 119 120 // Indicates the state of this session. 121 SessionStatus status_; 122 123 // Whether a Stop() operation is in progress for this session. 124 bool is_stop_in_progress_; 125 126 // The adapter that created this instance. 127 scoped_refptr<BluetoothAdapter> adapter_; 128 129 // Filter assigned to this session, if any 130 std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter_; 131 132 // Note: This should remain the last member so it'll be destroyed and 133 // invalidate its weak pointers before any other members are destroyed. 134 base::WeakPtrFactory<BluetoothDiscoverySession> weak_ptr_factory_{this}; 135 136 DISALLOW_COPY_AND_ASSIGN(BluetoothDiscoverySession); 137 }; 138 139 } // namespace device 140 141 #endif // DEVICE_BLUETOOTH_BLUETOOTH_DISCOVERY_SESSION_H_ 142