Skip to content

Commit

Permalink
Allow device/bluetooth to build on the macOS 10.13 SDK
Browse files Browse the repository at this point in the history
Some CoreBluetooth declarations tweaked in ways that are not compatible.

Also changes import/includes to match style guide:

https://google.github.io/styleguide/objcguide.xml?showone=_import_and__include#_import_and__include

BUG=729906

Review-Url: https://codereview.chromium.org/2924753002
Cr-Commit-Position: refs/heads/master@{#477867}
  • Loading branch information
tapted authored and Commit Bot committed Jun 8, 2017
1 parent c2fa681 commit 724d990
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 44 deletions.
19 changes: 19 additions & 0 deletions device/bluetooth/bluetooth_adapter_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@
@class NSArray;
@class NSDate;

#if !defined(MAC_OS_X_VERSION_10_13)

// The 10.13 SDK deprecates the CBCentralManagerState enum. When building
// against older SDKs, define the new enum in terms of the deprecated one.
using CBManagerState = CBCentralManagerState;
constexpr CBManagerState CBManagerStateUnknown = CBCentralManagerStateUnknown;
constexpr CBManagerState CBManagerStateResetting =
CBCentralManagerStateResetting;
constexpr CBManagerState CBManagerStateUnsupported =
CBCentralManagerStateUnsupported;
constexpr CBManagerState CBManagerStateUnauthorized =
CBCentralManagerStateUnauthorized;
constexpr CBManagerState CBManagerStatePoweredOff =
CBCentralManagerStatePoweredOff;
constexpr CBManagerState CBManagerStatePoweredOn =
CBCentralManagerStatePoweredOn;

#endif // MAC_OS_X_VERSION_10_13

namespace base {

class SequencedTaskRunner;
Expand Down
10 changes: 5 additions & 5 deletions device/bluetooth/bluetooth_adapter_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@
bool is_present = !address_.empty();
if (IsLowEnergyAvailable()) {
is_present = is_present || ([low_energy_central_manager_ state] !=
CBCentralManagerStateUnsupported);
CBManagerStateUnsupported);
}
return is_present;
}
Expand All @@ -164,7 +164,7 @@
bool is_powered = classic_powered_;
if (IsLowEnergyAvailable()) {
is_powered = is_powered || ([low_energy_central_manager_ state] ==
CBCentralManagerStatePoweredOn);
CBManagerStatePoweredOn);
}
return is_powered;
}
Expand Down Expand Up @@ -588,17 +588,17 @@
}
}

// TODO(crbug.com/511025): Handle state < CBCentralManagerStatePoweredOff.
// TODO(crbug.com/511025): Handle state < CBManagerStatePoweredOff.
void BluetoothAdapterMac::LowEnergyCentralManagerUpdatedState() {
VLOG(1) << "Central manager state updated: "
<< [low_energy_central_manager_ state];
// A state with a value lower than CBCentralManagerStatePoweredOn implies that
// A state with a value lower than CBManagerStatePoweredOn implies that
// scanning has stopped and that any connected peripherals have been
// disconnected. Call DidDisconnectPeripheral manually to update the devices'
// states since macOS doesn't call it.
// See
// https://developer.apple.com/reference/corebluetooth/cbcentralmanagerdelegate/1518888-centralmanagerdidupdatestate?language=objc
if ([low_energy_central_manager_ state] < CBCentralManagerStatePoweredOn) {
if ([low_energy_central_manager_ state] < CBManagerStatePoweredOn) {
VLOG(1)
<< "Central no longer powered on. Notifying of device disconnection.";
for (BluetoothDevice* device : GetDevices()) {
Expand Down
26 changes: 13 additions & 13 deletions device/bluetooth/bluetooth_adapter_mac_unittest.mm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "device/bluetooth/bluetooth_adapter_mac.h"

#import <Foundation/Foundation.h>

#include <memory>

#include "base/bind.h"
Expand All @@ -15,20 +17,18 @@
#include "device/bluetooth/bluetooth_common.h"
#include "device/bluetooth/bluetooth_discovery_session.h"
#include "device/bluetooth/bluetooth_discovery_session_outcome.h"
#include "device/bluetooth/bluetooth_low_energy_device_mac.h"
#include "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h"
#include "device/bluetooth/test/mock_bluetooth_central_manager_mac.h"
#import "device/bluetooth/bluetooth_low_energy_device_mac.h"
#import "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h"
#import "device/bluetooth/test/mock_bluetooth_central_manager_mac.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/ocmock/OCMock/OCMock.h"
#import "third_party/ocmock/OCMock/OCMock.h"

#if defined(OS_IOS)
#import <CoreBluetooth/CoreBluetooth.h>
#else // !defined(OS_IOS)
#import <IOBluetooth/IOBluetooth.h>
#endif // defined(OS_IOS)

#import <Foundation/Foundation.h>

namespace {
// |kTestHashAddress| is the hash corresponding to identifier |kTestNSUUID|.
const char* const kTestNSUUID = "00000000-1111-2222-3333-444444444444";
Expand Down Expand Up @@ -92,7 +92,7 @@ bool DevicePresent(CBPeripheral* peripheral) {
return (device != NULL);
}

bool SetMockCentralManager(CBCentralManagerState desired_state) {
bool SetMockCentralManager(CBManagerState desired_state) {
if (!BluetoothAdapterMac::IsLowEnergyAvailable()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return false;
Expand Down Expand Up @@ -148,7 +148,7 @@ void DiscoveryErrorCallback(UMABluetoothDiscoverySessionOutcome) {
}

TEST_F(BluetoothAdapterMacTest, AddDiscoverySessionWithLowEnergyFilter) {
if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
if (!SetMockCentralManager(CBManagerStatePoweredOn))
return;
EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]);
EXPECT_EQ(0, NumDiscoverySessions());
Expand All @@ -168,7 +168,7 @@ void DiscoveryErrorCallback(UMABluetoothDiscoverySessionOutcome) {
// TODO(krstnmnlsn): Test changing the filter when adding the second discovery
// session (once we have that ability).
TEST_F(BluetoothAdapterMacTest, AddSecondDiscoverySessionWithLowEnergyFilter) {
if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
if (!SetMockCentralManager(CBManagerStatePoweredOn))
return;
std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(
new BluetoothDiscoveryFilter(BLUETOOTH_TRANSPORT_LE));
Expand All @@ -189,7 +189,7 @@ void DiscoveryErrorCallback(UMABluetoothDiscoverySessionOutcome) {
}

TEST_F(BluetoothAdapterMacTest, RemoveDiscoverySessionWithLowEnergyFilter) {
if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
if (!SetMockCentralManager(CBManagerStatePoweredOn))
return;
EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]);

Expand All @@ -212,7 +212,7 @@ void DiscoveryErrorCallback(UMABluetoothDiscoverySessionOutcome) {
}

TEST_F(BluetoothAdapterMacTest, RemoveDiscoverySessionWithLowEnergyFilterFail) {
if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
if (!SetMockCentralManager(CBManagerStatePoweredOn))
return;
EXPECT_EQ(0, [mock_central_manager_ scanForPeripheralsCallCount]);
EXPECT_EQ(0, [mock_central_manager_ stopScanCallCount]);
Expand All @@ -230,7 +230,7 @@ void DiscoveryErrorCallback(UMABluetoothDiscoverySessionOutcome) {
}

TEST_F(BluetoothAdapterMacTest, CheckGetPeripheralHashAddress) {
if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
if (!SetMockCentralManager(CBManagerStatePoweredOn))
return;
base::scoped_nsobject<CBPeripheral> mock_peripheral(
CreateMockPeripheral(kTestNSUUID));
Expand All @@ -240,7 +240,7 @@ void DiscoveryErrorCallback(UMABluetoothDiscoverySessionOutcome) {
}

TEST_F(BluetoothAdapterMacTest, LowEnergyDeviceUpdatedNewDevice) {
if (!SetMockCentralManager(CBCentralManagerStatePoweredOn))
if (!SetMockCentralManager(CBManagerStatePoweredOn))
return;
base::scoped_nsobject<CBPeripheral> mock_peripheral(
CreateMockPeripheral(kTestNSUUID));
Expand Down
12 changes: 12 additions & 0 deletions device/bluetooth/bluetooth_low_energy_device_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@
#include "device/bluetooth/bluetooth_remote_gatt_descriptor_mac.h"
#include "device/bluetooth/bluetooth_remote_gatt_service_mac.h"

// Remove when Chrome no longer supports 10.12.
#if defined(MAC_OS_X_VERSION_10_13)

// In the 10.13 SDK, CBPeripheral became a subclass of CBPeer, which defines
// -[CBPeer identifier] as partially available. Pretend it still exists on
// CBPeripheral. At runtime the implementation on CBPeer will be invoked.
@interface CBPeripheral (HighSierraSDK)
@property(readonly, nonatomic) NSUUID* identifier;
@end

#endif // MAC_OS_X_VERSION_10_13

namespace device {

BluetoothLowEnergyDeviceMac::BluetoothLowEnergyDeviceMac(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
return;
}

if ([central_manager_ state] != CBCentralManagerStatePoweredOn) {
VLOG(1) << "TryStartDiscovery != CBCentralManagerStatePoweredOn";
if ([central_manager_ state] != CBManagerStatePoweredOn) {
VLOG(1) << "TryStartDiscovery != CBManagerStatePoweredOn";
return;
}

Expand Down
37 changes: 18 additions & 19 deletions device/bluetooth/test/bluetooth_test_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "device/bluetooth/test/bluetooth_test_mac.h"
#import "device/bluetooth/test/bluetooth_test_mac.h"

#import <CoreBluetooth/CoreBluetooth.h>
#include <stdint.h>

#include "base/mac/foundation_util.h"
#import "base/mac/foundation_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_adapter_mac.h"
#include "device/bluetooth/bluetooth_device_mac.h"
#include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"
#include "device/bluetooth/bluetooth_remote_gatt_descriptor_mac.h"
#include "device/bluetooth/bluetooth_remote_gatt_service_mac.h"
#include "device/bluetooth/test/mock_bluetooth_cbcharacteristic_mac.h"
#include "device/bluetooth/test/mock_bluetooth_cbdescriptor_mac.h"
#include "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h"
#include "device/bluetooth/test/mock_bluetooth_cbservice_mac.h"
#include "device/bluetooth/test/mock_bluetooth_central_manager_mac.h"
#include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#include "third_party/ocmock/OCMock/OCMock.h"

#import <CoreBluetooth/CoreBluetooth.h>
#import "device/bluetooth/bluetooth_adapter_mac.h"
#import "device/bluetooth/bluetooth_device_mac.h"
#import "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"
#import "device/bluetooth/bluetooth_remote_gatt_descriptor_mac.h"
#import "device/bluetooth/bluetooth_remote_gatt_service_mac.h"
#import "device/bluetooth/test/mock_bluetooth_cbcharacteristic_mac.h"
#import "device/bluetooth/test/mock_bluetooth_cbdescriptor_mac.h"
#import "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h"
#import "device/bluetooth/test/mock_bluetooth_cbservice_mac.h"
#import "device/bluetooth/test/mock_bluetooth_central_manager_mac.h"
#import "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#import "third_party/ocmock/OCMock/OCMock.h"

using base::mac::ObjCCast;
using base::scoped_nsobject;
Expand Down Expand Up @@ -114,7 +113,7 @@ explicit ScopedMockCentralManager(MockCentralManager* mock_central_manager) {
mock_central_manager_.reset(
new ScopedMockCentralManager([[MockCentralManager alloc] init]));
[mock_central_manager_->get() setBluetoothTestMac:this];
[mock_central_manager_->get() setState:CBCentralManagerStateUnsupported];
[mock_central_manager_->get() setState:CBManagerStateUnsupported];
adapter_mac_->SetCentralManagerForTesting((id)mock_central_manager_->get());
}
}
Expand All @@ -130,7 +129,7 @@ explicit ScopedMockCentralManager(MockCentralManager* mock_central_manager) {
mock_central_manager_.reset(
new ScopedMockCentralManager([[MockCentralManager alloc] init]));
mock_central_manager_->get().bluetoothTestMac = this;
[mock_central_manager_->get() setState:CBCentralManagerStatePoweredOn];
[mock_central_manager_->get() setState:CBManagerStatePoweredOn];
adapter_mac_->SetCentralManagerForTesting((id)mock_central_manager_->get());
}
}
Expand All @@ -141,7 +140,7 @@ explicit ScopedMockCentralManager(MockCentralManager* mock_central_manager) {
}

void BluetoothTestMac::SimulateAdapterPoweredOff() {
[mock_central_manager_->get() setState:CBCentralManagerStatePoweredOff];
[mock_central_manager_->get() setState:CBManagerStatePoweredOff];

for (BluetoothDevice* device : adapter_->GetDevices()) {
MockCBPeripheral* peripheral_mock = GetMockCBPeripheral(device);
Expand Down
11 changes: 6 additions & 5 deletions device/bluetooth/test/mock_bluetooth_central_manager_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
#ifndef DEVICE_BLUETOOTH_MOCK_BLUETOOTH_CENTRAL_MANAGER_MAC_H_
#define DEVICE_BLUETOOTH_MOCK_BLUETOOTH_CENTRAL_MANAGER_MAC_H_

#include "base/mac/sdk_forward_declarations.h"
#include "build/build_config.h"
#include "device/bluetooth/test/bluetooth_test_mac.h"

#import <CoreBluetooth/CoreBluetooth.h>

#import "base/mac/sdk_forward_declarations.h"
#include "build/build_config.h"
#import "device/bluetooth/bluetooth_adapter_mac.h"
#import "device/bluetooth/test/bluetooth_test_mac.h"

// Class to mock a CBCentralManager. Cannot use a OCMockObject because mocking
// the 'state' property gives a compiler warning when mock_central_manager is of
// type id (multiple methods named 'state' found), and a compiler warning when
Expand All @@ -21,7 +22,7 @@
@property(nonatomic, assign) NSInteger scanForPeripheralsCallCount;
@property(nonatomic, assign) NSInteger stopScanCallCount;
@property(nonatomic, assign) id<CBCentralManagerDelegate> delegate;
@property(nonatomic, assign) CBCentralManagerState state;
@property(nonatomic, assign) CBManagerState state;
@property(nonatomic, assign) device::BluetoothTestMac* bluetoothTestMac;
@property(nonatomic, readonly) NSArray* retrieveConnectedPeripheralServiceUUIDs;

Expand Down

0 comments on commit 724d990

Please sign in to comment.