blob: a11a11ba5ddcda7c04fd1e30664aa8673f009963 [file] [log] [blame]
jlebela58fd752016-03-14 10:33:281// Copyright 2015 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
jlebelf11faf4f2016-03-23 11:05:535#include "device/bluetooth/test/mock_bluetooth_cbperipheral_mac.h"
jlebela58fd752016-03-14 10:33:286
jlebelf11faf4f2016-03-23 11:05:537#include "base/mac/foundation_util.h"
jlebela58fd752016-03-14 10:33:288#include "base/mac/scoped_nsobject.h"
jlebelc4b09782016-05-10 00:31:589#include "device/bluetooth/test/bluetooth_test_mac.h"
jlebel9bb8cf242017-01-10 01:29:0210#include "device/bluetooth/test/mock_bluetooth_cbcharacteristic_mac.h"
jlebelc4b09782016-05-10 00:31:5811#include "device/bluetooth/test/mock_bluetooth_cbservice_mac.h"
jlebelf11faf4f2016-03-23 11:05:5312
13using base::mac::ObjCCast;
14using base::scoped_nsobject;
jlebela58fd752016-03-14 10:33:2815
16@interface MockCBPeripheral () {
jlebelf11faf4f2016-03-23 11:05:5317 scoped_nsobject<NSUUID> _identifier;
18 scoped_nsobject<NSString> _name;
jlebelc4b09782016-05-10 00:31:5819 id<CBPeripheralDelegate> _delegate;
20 scoped_nsobject<NSMutableArray> _services;
jlebela58fd752016-03-14 10:33:2821}
22
23@end
24
25@implementation MockCBPeripheral
26
27@synthesize state = _state;
jlebelc4b09782016-05-10 00:31:5828@synthesize delegate = _delegate;
29@synthesize bluetoothTestMac = _bluetoothTestMac;
jlebela58fd752016-03-14 10:33:2830
jlebelf11faf4f2016-03-23 11:05:5331- (instancetype)init {
32 [self doesNotRecognizeSelector:_cmd];
33 return self;
34}
35
36- (instancetype)initWithUTF8StringIdentifier:(const char*)utf8Identifier {
scheibdd9ce7002016-07-21 07:06:0637 return [self initWithUTF8StringIdentifier:utf8Identifier name:nil];
jlebelf11faf4f2016-03-23 11:05:5338}
39
scheibdd9ce7002016-07-21 07:06:0640- (instancetype)initWithUTF8StringIdentifier:(const char*)utf8Identifier
41 name:(NSString*)name {
42 scoped_nsobject<NSUUID> identifier(
43 [[NSUUID alloc] initWithUUIDString:@(utf8Identifier)]);
44 return [self initWithIdentifier:identifier name:name];
jlebelf11faf4f2016-03-23 11:05:5345}
46
47- (instancetype)initWithIdentifier:(NSUUID*)identifier name:(NSString*)name {
jlebela58fd752016-03-14 10:33:2848 self = [super init];
49 if (self) {
50 _identifier.reset([identifier retain]);
jlebelf11faf4f2016-03-23 11:05:5351 if (name) {
52 _name.reset([name retain]);
jlebelf11faf4f2016-03-23 11:05:5353 }
jlebela58fd752016-03-14 10:33:2854 _state = CBPeripheralStateDisconnected;
55 }
56 return self;
57}
58
jlebelf11faf4f2016-03-23 11:05:5359- (BOOL)isKindOfClass:(Class)aClass {
60 if (aClass == [CBPeripheral class] ||
61 [aClass isSubclassOfClass:[CBPeripheral class]]) {
62 return YES;
63 }
64 return [super isKindOfClass:aClass];
65}
66
67- (BOOL)isMemberOfClass:(Class)aClass {
68 if (aClass == [CBPeripheral class] ||
69 [aClass isSubclassOfClass:[CBPeripheral class]]) {
70 return YES;
71 }
72 return [super isKindOfClass:aClass];
73}
74
jlebela58fd752016-03-14 10:33:2875- (void)setState:(CBPeripheralState)state {
76 _state = state;
jlebel471d7dd2016-06-03 08:07:1277 if (_state == CBPeripheralStateDisconnected) {
ccameron1c9b9832016-06-03 23:54:0678 _services.reset();
jlebel471d7dd2016-06-03 08:07:1279 }
jlebela58fd752016-03-14 10:33:2880}
81
jlebelc4b09782016-05-10 00:31:5882- (void)discoverServices:(NSArray*)serviceUUIDs {
83 if (_bluetoothTestMac) {
84 _bluetoothTestMac->OnFakeBluetoothServiceDiscovery();
85 }
jlebel620327d2016-06-20 13:01:0086 [_delegate peripheral:self.peripheral didDiscoverServices:nil];
87}
88
89- (void)discoverCharacteristics:(NSArray*)characteristics
90 forService:(CBService*)service {
jlebelc4b09782016-05-10 00:31:5891}
92
jlebel9bb8cf242017-01-10 01:29:0293- (void)discoverDescriptorsForCharacteristic:(CBCharacteristic*)characteristic {
94 MockCBCharacteristic* mock_characteristic =
95 ObjCCast<MockCBCharacteristic>(characteristic);
96 [mock_characteristic discoverDescriptors];
97}
98
jlebele223e9292016-06-27 15:22:5699- (void)readValueForCharacteristic:(CBCharacteristic*)characteristic {
100 DCHECK(_bluetoothTestMac);
101 _bluetoothTestMac->OnFakeBluetoothCharacteristicReadValue();
102}
103
jlebel4e58d3d2016-06-28 01:43:26104- (void)writeValue:(NSData*)data
105 forCharacteristic:(CBCharacteristic*)characteristic
106 type:(CBCharacteristicWriteType)type {
107 DCHECK(_bluetoothTestMac);
108 const uint8_t* buffer = static_cast<const uint8_t*>(data.bytes);
109 std::vector<uint8_t> value(buffer, buffer + data.length);
110 _bluetoothTestMac->OnFakeBluetoothCharacteristicWriteValue(value);
111}
112
jlebelc4b09782016-05-10 00:31:58113- (void)removeAllServices {
114 [_services.get() removeAllObjects];
115}
116
117- (void)addServices:(NSArray*)services {
jlebel471d7dd2016-06-03 08:07:12118 if (!_services.get()) {
119 _services.reset([[NSMutableArray alloc] init]);
120 }
jlebelc4b09782016-05-10 00:31:58121 for (CBUUID* uuid in services) {
jlebel620327d2016-06-20 13:01:00122 base::scoped_nsobject<MockCBService> service([[MockCBService alloc]
123 initWithPeripheral:self.peripheral
124 CBUUID:uuid
125 primary:YES]);
jlebelc4b09782016-05-10 00:31:58126 [_services.get() addObject:service.get().service];
127 }
128}
129
jlebel471d7dd2016-06-03 08:07:12130- (void)didDiscoverServicesWithError:(NSError*)error {
jlebelc4b09782016-05-10 00:31:58131 [_delegate peripheral:self.peripheral didDiscoverServices:error];
132}
133
134- (void)removeService:(CBService*)service {
135 base::scoped_nsobject<CBService> serviceToRemove(service,
136 base::scoped_policy::RETAIN);
jlebel20060d02016-05-28 11:23:19137 DCHECK(serviceToRemove);
jlebelc4b09782016-05-10 00:31:58138 [_services.get() removeObject:serviceToRemove];
jlebel620327d2016-06-20 13:01:00139 [self didModifyServices:@[ serviceToRemove ]];
140}
141
jlebel062d7b42017-01-07 13:32:20142- (void)mockDidDiscoverEvents {
143 [_delegate peripheral:self.peripheral didDiscoverServices:nil];
144 // BluetoothLowEnergyDeviceMac is expected to call
145 // -[CBPeripheral discoverCharacteristics:forService:] for each services,
146 // so -[<CBPeripheralDelegate peripheral:didDiscoverCharacteristicsForService:
147 // error:] needs to be called for all services.
148 for (CBService* service in _services.get()) {
149 [_delegate peripheral:self.peripheral
150 didDiscoverCharacteristicsForService:service
151 error:nil];
jlebel9bb8cf242017-01-10 01:29:02152 for (CBCharacteristic* characteristic in service.characteristics) {
153 // After discovering services, BluetoothLowEnergyDeviceMac is expected to
154 // discover characteristics for all services.
155 [_delegate peripheral:self.peripheral
156 didDiscoverDescriptorsForCharacteristic:characteristic
157 error:nil];
158 }
jlebel062d7b42017-01-07 13:32:20159 }
160}
161
jlebel9bb8cf242017-01-10 01:29:02162- (void)didModifyServices:(NSArray*)invalidatedServices {
163 DCHECK(
164 [_delegate respondsToSelector:@selector(peripheral:didModifyServices:)]);
165 [_delegate peripheral:self.peripheral didModifyServices:invalidatedServices];
166}
167
168- (void)didDiscoverDescriptorsWithCharacteristic:
169 (MockCBCharacteristic*)characteristic_mock {
170 [_delegate peripheral:self.peripheral
171 didDiscoverDescriptorsForCharacteristic:characteristic_mock.characteristic
172 error:nil];
173}
174
jlebela58fd752016-03-14 10:33:28175- (NSUUID*)identifier {
176 return _identifier.get();
177}
178
179- (NSString*)name {
180 return _name.get();
181}
182
jlebelc4b09782016-05-10 00:31:58183- (NSArray*)services {
184 return _services.get();
185}
186
jlebelf11faf4f2016-03-23 11:05:53187- (CBPeripheral*)peripheral {
188 return ObjCCast<CBPeripheral>(self);
189}
190
jlebel9db20212016-06-29 15:03:48191- (void)setNotifyValue:(BOOL)notification
192 forCharacteristic:(CBCharacteristic*)characteristic {
jlebel7c346d72017-02-14 08:54:42193 _bluetoothTestMac->OnFakeBluetoothGattSetCharacteristicNotification(
194 notification == YES);
jlebel9db20212016-06-29 15:03:48195}
196
jlebela58fd752016-03-14 10:33:28197@end