| OLD | NEW | 
|---|
| 1 <!DOCTYPE html> | 1 <!DOCTYPE html> | 
| 2 <script src="../resources/testharness.js"></script> | 2 <script src="../resources/testharness.js"></script> | 
| 3 <script src="../resources/testharnessreport.js"></script> | 3 <script src="../resources/testharnessreport.js"></script> | 
| 4 <script src="resources/bluetooth-helpers.js"></script> | 4 <script src="resources/bluetooth-helpers.js"></script> | 
| 5 <script> | 5 <script> | 
| 6 'use strict' | 6 'use strict' | 
| 7 | 7 | 
| 8 test(t => { assert_true(window.testRunner instanceof Object); t.done(); }, | 8 test(t => { assert_true(window.testRunner instanceof Object); t.done(); }, | 
| 9      'window.testRunner is required for the following tests.'); | 9      'window.testRunner is required for the following tests.'); | 
| 10 | 10 | 
| 11 promise_test(() => { | 11 promise_test(() => { | 
| 12   testRunner.setBluetoothMockDataSet('HeartRateAdapter'); | 12   return setBluetoothFakeAdapter('HeartRateAdapter') | 
| 13   return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}], | 13     .then(() => requestDeviceWithKeyDown({ | 
| 14                                    optionalServices: ['generic_access']}) | 14       filters: [{services: ['heart_rate']}], | 
|  | 15       optionalServices: ['generic_access']})) | 
| 15     .then(device => device.gatt.connect()) | 16     .then(device => device.gatt.connect()) | 
| 16     .then(gattServer => { | 17     .then(gattServer => { | 
| 17       testRunner.setBluetoothMockDataSet('EmptyAdapter'); | 18       return setBluetoothFakeAdapter('EmptyAdapter') | 
| 18       return assert_promise_rejects_with_message( | 19         .then(() => assert_promise_rejects_with_message( | 
| 19         gattServer.getPrimaryService('generic_access'), | 20           gattServer.getPrimaryService('generic_access'), | 
| 20         new DOMException('Bluetooth Device is no longer in range.', | 21           new DOMException('Bluetooth Device is no longer in range.', | 
| 21                          'NetworkError'), | 22                            'NetworkError'), | 
| 22         'Device went out of range.'); | 23           'Device went out of range.')); | 
| 23     }); | 24     }); | 
| 24 }, 'Device goes out of range. Reject with NetworkError.'); | 25 }, 'Device goes out of range. Reject with NetworkError.'); | 
| 25 | 26 | 
| 26 promise_test(() => { | 27 promise_test(() => { | 
| 27   testRunner.setBluetoothMockDataSet('HeartRateAdapter'); |  | 
| 28   let expected = new DOMException('Service not found in device.', | 28   let expected = new DOMException('Service not found in device.', | 
| 29                                   'NotFoundError'); | 29                                   'NotFoundError'); | 
| 30   return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}], | 30   return setBluetoothFakeAdapter('HeartRateAdapter') | 
| 31                                    optionalServices: ['glucose']}) | 31     .then(() => requestDeviceWithKeyDown({ | 
|  | 32       filters: [{services: ['heart_rate']}], | 
|  | 33       optionalServices: ['glucose']})) | 
| 32     .then(device => device.gatt.connect()) | 34     .then(device => device.gatt.connect()) | 
| 33     .then(gattServer => Promise.all( | 35     .then(gattServer => Promise.all( | 
| 34       [assert_promise_rejects_with_message( | 36       [assert_promise_rejects_with_message( | 
| 35         gattServer.getPrimaryService(glucose.alias), expected), | 37         gattServer.getPrimaryService(glucose.alias), expected), | 
| 36        assert_promise_rejects_with_message( | 38        assert_promise_rejects_with_message( | 
| 37          gattServer.getPrimaryService(glucose.name), expected), | 39          gattServer.getPrimaryService(glucose.name), expected), | 
| 38        assert_promise_rejects_with_message( | 40        assert_promise_rejects_with_message( | 
| 39          gattServer.getPrimaryService(glucose.uuid), expected)])); | 41          gattServer.getPrimaryService(glucose.uuid), expected)])); | 
| 40 }, 'Request for wrong service. Reject with NotFoundError.'); | 42 }, 'Request for wrong service. Reject with NotFoundError.'); | 
| 41 | 43 | 
| 42 promise_test(() => { | 44 promise_test(() => { | 
| 43   testRunner.setBluetoothMockDataSet('DelayedServicesDiscoveryAdapter'); | 45   return setBluetoothFakeAdapter('DelayedServicesDiscoveryAdapter') | 
| 44   return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) | 46     .then(() => requestDeviceWithKeyDown({ | 
|  | 47       filters: [{services: ['heart_rate']}]})) | 
| 45     .then(device => device.gatt.connect()) | 48     .then(device => device.gatt.connect()) | 
| 46     .then(gattServer => gattServer.getPrimaryService('heart_rate')) | 49     .then(gattServer => gattServer.getPrimaryService('heart_rate')) | 
| 47     .then(service => { | 50     .then(service => { | 
| 48       assert_equals(service.uuid, heart_rate.uuid); | 51       assert_equals(service.uuid, heart_rate.uuid); | 
| 49     }); | 52     }); | 
| 50 }, 'Request for service. Must return even when the services are not immediately 
     discovered'); | 53 }, 'Request for service. Must return even when the services are not immediately 
     discovered'); | 
| 51 | 54 | 
| 52 promise_test(() => { | 55 promise_test(() => { | 
| 53   testRunner.setBluetoothMockDataSet('DelayedServicesDiscoveryAdapter'); | 56   return setBluetoothFakeAdapter('DelayedServicesDiscoveryAdapter') | 
| 54   return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}], | 57     .then(() => requestDeviceWithKeyDown({ | 
| 55                                    optionalServices: ['battery_service']}) | 58       filters: [{services: ['heart_rate']}], | 
|  | 59       optionalServices: ['battery_service']})) | 
| 56     .then(device => device.gatt.connect()) | 60     .then(device => device.gatt.connect()) | 
| 57     .then(gattServer => { | 61     .then(gattServer => { | 
| 58       return assert_promise_rejects_with_message( | 62       return assert_promise_rejects_with_message( | 
| 59         gattServer.getPrimaryService('battery_service'), | 63         gattServer.getPrimaryService('battery_service'), | 
| 60         new DOMException('Service not found in device.', 'NotFoundError')); | 64         new DOMException('Service not found in device.', 'NotFoundError')); | 
| 61     }); | 65     }); | 
| 62 }, 'Request for wrong service. Must reject with NotFoundError even when the serv
     ices' + | 66 }, 'Request for wrong service. Must reject with NotFoundError even when the serv
     ices' + | 
| 63    ' are not immediately discovered'); | 67    ' are not immediately discovered'); | 
| 64 | 68 | 
| 65 promise_test(() => { | 69 promise_test(() => { | 
| 66   testRunner.setBluetoothMockDataSet('HeartRateAdapter'); |  | 
| 67   let expected = new DOMException('Origin is not allowed to access the ' + | 70   let expected = new DOMException('Origin is not allowed to access the ' + | 
| 68                                   'service. Remember to add the service to a ' + | 71                                   'service. Remember to add the service to a ' + | 
| 69                                   'filter or to optionalServices in ' + | 72                                   'filter or to optionalServices in ' + | 
| 70                                   'requestDevice().', | 73                                   'requestDevice().', | 
| 71                                   'SecurityError'); | 74                                   'SecurityError'); | 
| 72   return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) | 75   return setBluetoothFakeAdapter('HeartRateAdapter') | 
|  | 76     .then(() => requestDeviceWithKeyDown({ | 
|  | 77       filters: [{services: ['heart_rate']}]})) | 
| 73     .then(device => device.gatt.connect()) | 78     .then(device => device.gatt.connect()) | 
| 74     .then(gattServer => Promise.all( | 79     .then(gattServer => Promise.all( | 
| 75       [assert_promise_rejects_with_message( | 80       [assert_promise_rejects_with_message( | 
| 76         gattServer.getPrimaryService(glucose.alias), expected), | 81         gattServer.getPrimaryService(glucose.alias), expected), | 
| 77        assert_promise_rejects_with_message( | 82        assert_promise_rejects_with_message( | 
| 78          gattServer.getPrimaryService(glucose.name), expected), | 83          gattServer.getPrimaryService(glucose.name), expected), | 
| 79        assert_promise_rejects_with_message( | 84        assert_promise_rejects_with_message( | 
| 80          gattServer.getPrimaryService(glucose.uuid), expected)])); | 85          gattServer.getPrimaryService(glucose.uuid), expected)])); | 
| 81 }, 'Request for absent service without permission. Reject with SecurityError.'); | 86 }, 'Request for absent service without permission. Reject with SecurityError.'); | 
| 82 | 87 | 
| 83 promise_test(() => { | 88 promise_test(() => { | 
| 84   testRunner.setBluetoothMockDataSet('HeartRateAdapter'); |  | 
| 85   let expected = new DOMException('Origin is not allowed to access the ' + | 89   let expected = new DOMException('Origin is not allowed to access the ' + | 
| 86                                   'service. Remember to add the service to a ' + | 90                                   'service. Remember to add the service to a ' + | 
| 87                                   'filter or to optionalServices in ' + | 91                                   'filter or to optionalServices in ' + | 
| 88                                   'requestDevice().', | 92                                   'requestDevice().', | 
| 89                                   'SecurityError'); | 93                                   'SecurityError'); | 
| 90   return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) | 94   return setBluetoothFakeAdapter('HeartRateAdapter') | 
|  | 95     .then(() => requestDeviceWithKeyDown({ | 
|  | 96       filters: [{services: ['heart_rate']}]})) | 
| 91     .then(device => device.gatt.connect()) | 97     .then(device => device.gatt.connect()) | 
| 92     .then(gattServer => Promise.all( | 98     .then(gattServer => Promise.all( | 
| 93       [assert_promise_rejects_with_message( | 99       [assert_promise_rejects_with_message( | 
| 94         gattServer.getPrimaryService(generic_access.alias), expected), | 100         gattServer.getPrimaryService(generic_access.alias), expected), | 
| 95        assert_promise_rejects_with_message( | 101        assert_promise_rejects_with_message( | 
| 96          gattServer.getPrimaryService(generic_access.name), expected), | 102          gattServer.getPrimaryService(generic_access.name), expected), | 
| 97        assert_promise_rejects_with_message( | 103        assert_promise_rejects_with_message( | 
| 98          gattServer.getPrimaryService(generic_access.uuid), expected)])); | 104          gattServer.getPrimaryService(generic_access.uuid), expected)])); | 
| 99 }, 'Request for present service without permission. Reject with SecurityError.')
     ; | 105 }, 'Request for present service without permission. Reject with SecurityError.')
     ; | 
| 100 | 106 | 
| 101 promise_test(function() { | 107 promise_test(function() { | 
| 102   testRunner.setBluetoothMockDataSet('HeartRateAdapter'); | 108   return setBluetoothFakeAdapter('HeartRateAdapter') | 
| 103   return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}], | 109     .then(() => requestDeviceWithKeyDown({ | 
| 104                                    optionalServices: ['generic_access']}) | 110       filters: [{services: ['heart_rate']}], | 
|  | 111       optionalServices: ['generic_access']})) | 
| 105     .then(device => device.gatt.connect()) | 112     .then(device => device.gatt.connect()) | 
| 106     .then(gattServer => Promise.all( | 113     .then(gattServer => Promise.all( | 
| 107       [gattServer.getPrimaryService(generic_access.alias), | 114       [gattServer.getPrimaryService(generic_access.alias), | 
| 108        gattServer.getPrimaryService(generic_access.name), | 115        gattServer.getPrimaryService(generic_access.name), | 
| 109        gattServer.getPrimaryService(generic_access.uuid)])) | 116        gattServer.getPrimaryService(generic_access.uuid)])) | 
| 110     .then(services => { | 117     .then(services => { | 
| 111       services.forEach(service => { | 118       services.forEach(service => { | 
| 112         assert_equals(service.uuid, generic_access.uuid, | 119         assert_equals(service.uuid, generic_access.uuid, | 
| 113                       'Service UUID should be the same as requested UUID.'); | 120                       'Service UUID should be the same as requested UUID.'); | 
| 114         assert_true(service.isPrimary, | 121         assert_true(service.isPrimary, | 
| 115                     'getPrimaryService should return a primary service.'); | 122                     'getPrimaryService should return a primary service.'); | 
| 116       }); | 123       }); | 
| 117     }); | 124     }); | 
| 118 }, 'Request for service. Should return right service'); | 125 }, 'Request for service. Should return right service'); | 
| 119 | 126 | 
| 120 promise_test(() => { | 127 promise_test(() => { | 
| 121   testRunner.setBluetoothMockDataSet('HeartRateAdapter'); | 128   return setBluetoothFakeAdapter('HeartRateAdapter') | 
| 122   return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}], | 129     .then(() => requestDeviceWithKeyDown({ | 
| 123                                    optionalServices: ['generic_access']}) | 130       filters: [{services: ['heart_rate']}], | 
|  | 131       optionalServices: ['generic_access']})) | 
| 124     .then(device => device.gatt.connect()) | 132     .then(device => device.gatt.connect()) | 
| 125     .then(gattServer => Promise.all( | 133     .then(gattServer => Promise.all( | 
| 126       [gattServer.getPrimaryService(generic_access.alias), | 134       [gattServer.getPrimaryService(generic_access.alias), | 
| 127        gattServer.getPrimaryService(generic_access.alias), | 135        gattServer.getPrimaryService(generic_access.alias), | 
| 128        gattServer.getPrimaryService(generic_access.name), | 136        gattServer.getPrimaryService(generic_access.name), | 
| 129        gattServer.getPrimaryService(generic_access.name), | 137        gattServer.getPrimaryService(generic_access.name), | 
| 130        gattServer.getPrimaryService(generic_access.uuid), | 138        gattServer.getPrimaryService(generic_access.uuid), | 
| 131        gattServer.getPrimaryService(generic_access.uuid)])) | 139        gattServer.getPrimaryService(generic_access.uuid)])) | 
| 132     .then(services => { | 140     .then(services => { | 
| 133       // getPrimaryService should return the same object if it was created | 141       // getPrimaryService should return the same object if it was created | 
| 134       // earlier. https://crbug.com/495270 | 142       // earlier. https://crbug.com/495270 | 
| 135       // TODO(ortuno): Change to assert_equals. | 143       // TODO(ortuno): Change to assert_equals. | 
| 136       for (let i = 1; i < services.length; i++) { | 144       for (let i = 1; i < services.length; i++) { | 
| 137         assert_not_equals(services[0], services[i], | 145         assert_not_equals(services[0], services[i], | 
| 138                           'Should return the same service as the first call.'); | 146                           'Should return the same service as the first call.'); | 
| 139       } | 147       } | 
| 140     }); | 148     }); | 
| 141 }, 'Calls to get the same service should return the same object.'); | 149 }, 'Calls to get the same service should return the same object.'); | 
| 142 | 150 | 
| 143 promise_test(() => { | 151 promise_test(() => { | 
| 144   testRunner.setBluetoothMockDataSet('HeartRateAdapter'); | 152   return setBluetoothFakeAdapter('HeartRateAdapter') | 
| 145   return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) | 153     .then(() => requestDeviceWithKeyDown({ | 
|  | 154       filters: [{services: ['heart_rate']}]})) | 
| 146     .then(device => device.gatt.connect()) | 155     .then(device => device.gatt.connect()) | 
| 147     .then(gattServer => { | 156     .then(gattServer => { | 
| 148       return assert_promise_rejects_with_message( | 157       return assert_promise_rejects_with_message( | 
| 149         gattServer.getPrimaryService('wrong_name'), new DOMException( | 158         gattServer.getPrimaryService('wrong_name'), new DOMException( | 
| 150           'Failed to execute \'getPrimaryService\' on ' + | 159           'Failed to execute \'getPrimaryService\' on ' + | 
| 151           '\'BluetoothRemoteGATTServer\': Invalid Service name: ' + | 160           '\'BluetoothRemoteGATTServer\': Invalid Service name: ' + | 
| 152           '\'wrong_name\'. ' + | 161           '\'wrong_name\'. ' + | 
| 153           'It must be a valid UUID alias (e.g. 0x1234), ' + | 162           'It must be a valid UUID alias (e.g. 0x1234), ' + | 
| 154           'UUID (lowercase hex characters e.g. ' + | 163           'UUID (lowercase hex characters e.g. ' + | 
| 155           '\'00001234-0000-1000-8000-00805f9b34fb\'), ' + | 164           '\'00001234-0000-1000-8000-00805f9b34fb\'), ' + | 
| 156           'or recognized standard name from ' + | 165           'or recognized standard name from ' + | 
| 157           'https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
     ' + | 166           'https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx
     ' + | 
| 158           ' e.g. \'alert_notification\'.', | 167           ' e.g. \'alert_notification\'.', | 
| 159           'SyntaxError'), | 168           'SyntaxError'), | 
| 160         'Wrong Service name passed.'); | 169         'Wrong Service name passed.'); | 
| 161     }); | 170     }); | 
| 162 }, 'Wrong Service name. Reject with SyntaxError.'); | 171 }, 'Wrong Service name. Reject with SyntaxError.'); | 
| 163 </script> | 172 </script> | 
| OLD | NEW | 
|---|