chromium/device/bluetooth/bluetooth_remote_gatt_characteristic_unittest.cc

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"

#include <stdint.h>

#include <functional>
#include <utility>

#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_remote_gatt_service.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(IS_ANDROID)
#include "device/bluetooth/test/bluetooth_test_android.h"
#elif BUILDFLAG(IS_APPLE)
#include "device/bluetooth/test/bluetooth_test_mac.h"
#elif BUILDFLAG(IS_WIN)
#include "device/bluetooth/test/bluetooth_test_win.h"
#elif defined(USE_CAST_BLUETOOTH_ADAPTER)
#include "device/bluetooth/test/bluetooth_test_cast.h"
#elif BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
#include "device/bluetooth/test/bluetooth_test_bluez.h"
#elif BUILDFLAG(IS_FUCHSIA)
#include "device/bluetooth/test/bluetooth_test_fuchsia.h"
#endif

_;
Invoke;
WriteType;

namespace device {

class BluetoothRemoteGattCharacteristicTest :
#if BUILDFLAG(IS_WIN)
    public BluetoothTestWinrt {};

#if BUILDFLAG(IS_WIN)
using BluetoothRemoteGattCharacteristicTestWinrt =
    BluetoothRemoteGattCharacteristicTest;
#endif

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GetIdentifier
#else
#define MAYBE_GetIdentifier
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, GetIdentifier) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_GetIdentifier) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GetUUID
#else
#define MAYBE_GetUUID
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, GetUUID) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_GetUUID) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GetProperties
#else
#define MAYBE_GetProperties
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, GetProperties) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_GetProperties) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GetService
#else
#define MAYBE_GetService
#endif
// Tests GetService.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, GetService) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_GetService) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ReadRemoteCharacteristic_Empty
#else
#define MAYBE_ReadRemoteCharacteristic_Empty
#endif
// Tests ReadRemoteCharacteristic and GetValue with empty value buffer.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       ReadRemoteCharacteristic_Empty) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_ReadRemoteCharacteristic_Empty) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_WriteRemoteCharacteristic_Empty
#else
#define MAYBE_WriteRemoteCharacteristic_Empty
#endif
// Tests WriteRemoteCharacteristic with empty value buffer.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       WriteRemoteCharacteristic_Empty) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_WriteRemoteCharacteristic_Empty) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteRemoteCharacteristic_Empty
#else
#define MAYBE_DeprecatedWriteRemoteCharacteristic_Empty
#endif
// Tests DeprecatedWriteRemoteCharacteristic with empty value buffer.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       DeprecatedWriteRemoteCharacteristic_Empty) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeprecatedWriteRemoteCharacteristic_Empty) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_Retry_ReadRemoteCharacteristic_DuringDestruction_Fails
#else
#define MAYBE_Retry_ReadRemoteCharacteristic_DuringDestruction_Fails
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       Retry_ReadRemoteCharacteristic_DuringDestruction_Fails) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_Retry_ReadRemoteCharacteristic_DuringDestruction_Fails) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_Retry_WriteRemoteCharacteristic_DuringDestruction_Fails
#else
#define MAYBE_Retry_WriteRemoteCharacteristic_DuringDestruction_Fails
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       Retry_WriteRemoteCharacteristic_DuringDestruction_Fails) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_Retry_WriteRemoteCharacteristic_DuringDestruction_Fails) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_Retry_DeprecatedWriteRemoteCharacteristic_DuringDestruction_Fails
#else
#define MAYBE_Retry_DeprecatedWriteRemoteCharacteristic_DuringDestruction_Fails
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       Retry_DeprecatedWriteRemoteCharacteristic_DuringDestruction_Fails) {
#else
TEST_F(
    BluetoothRemoteGattCharacteristicTest,
    MAYBE_Retry_DeprecatedWriteRemoteCharacteristic_DuringDestruction_Fails) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_ReadRemoteCharacteristic_AfterDeleted
#else
#define MAYBE_ReadRemoteCharacteristic_AfterDeleted
#endif
// Tests ReadRemoteCharacteristic completing after Chrome objects are deleted.
// macOS: Not applicable: This can never happen if CBPeripheral delegate is set
// to nil.
// Windows: Not applicable: Pending callbacks won't fire once the underlying
// object is destroyed.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_ReadRemoteCharacteristic_AfterDeleted) {}

// TODO(crbug.com/40492509): Enable test on windows when disconnection is
// implemented.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ReadRemoteCharacteristic_Disconnected
#else
#define MAYBE_ReadRemoteCharacteristic_Disconnected
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       ReadRemoteCharacteristic_Disconnected) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_ReadRemoteCharacteristic_Disconnected) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_WriteRemoteCharacteristic_AfterDeleted
#else
#define MAYBE_WriteRemoteCharacteristic_AfterDeleted
#endif
// Tests WriteRemoteCharacteristic completing after Chrome objects are deleted.
// macOS: Not applicable: This can never happen if CBPeripheral
// delegate is set to nil.
// Windows: Not applicable: Pending callbacks won't fire once the underlying
// object is destroyed.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_WriteRemoteCharacteristic_AfterDeleted) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_DeprecatedWriteRemoteCharacteristic_AfterDeleted
#else
#define MAYBE_DeprecatedWriteRemoteCharacteristic_AfterDeleted
#endif
// Tests DeprecatedWriteRemoteCharacteristic completing after Chrome objects are
// deleted.
// macOS: Not applicable: This can never happen if CBPeripheral
// delegate is set to nil.
// Windows: Not applicable: Pending callbacks won't fire once the underlying
// object is destroyed.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeprecatedWriteRemoteCharacteristic_AfterDeleted) {}

// TODO(crbug.com/40492509): Enable test on windows when disconnection is
// implemented.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_WriteRemoteCharacteristic_Disconnected
#else
#define MAYBE_WriteRemoteCharacteristic_Disconnected
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       WriteRemoteCharacteristic_Disconnected) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_WriteRemoteCharacteristic_Disconnected) {}

// TODO(crbug.com/40492509): Enable test on windows when disconnection is
// implemented.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteRemoteCharacteristic_Disconnected
#else
#define MAYBE_DeprecatedWriteRemoteCharacteristic_Disconnected
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       DeprecatedWriteRemoteCharacteristic_Disconnected) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeprecatedWriteRemoteCharacteristic_Disconnected) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ReadRemoteCharacteristic
#else
#define MAYBE_ReadRemoteCharacteristic
#endif
// Tests ReadRemoteCharacteristic and GetValue with non-empty value buffer.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, ReadRemoteCharacteristic) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_ReadRemoteCharacteristic) {}

// Callback that make sure GattCharacteristicValueChanged has been called
// before the callback runs.
static void TestCallback(
    BluetoothRemoteGattCharacteristic::ValueCallback callback,
    const TestBluetoothAdapterObserver& callback_observer,
    std::optional<BluetoothGattService::GattErrorCode> error_code,
    const std::vector<uint8_t>& value) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ReadRemoteCharacteristic_GattCharacteristicValueChangedNotCalled
#else
#define MAYBE_ReadRemoteCharacteristic_GattCharacteristicValueChangedNotCalled
#endif
// Tests that ReadRemoteCharacteristic doesn't result in a
// GattCharacteristicValueChanged call.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       ReadRemoteCharacteristic_GattCharacteristicValueChangedNotCalled) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_ReadRemoteCharacteristic_GattCharacteristicValueChangedNotCalled) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_WriteRemoteCharacteristic
#else
#define MAYBE_WriteRemoteCharacteristic
#endif
// Tests WriteRemoteCharacteristic with non-empty value buffer.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, WriteRemoteCharacteristic) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_WriteRemoteCharacteristic) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteRemoteCharacteristic
#else
#define MAYBE_DeprecatedWriteRemoteCharacteristic
#endif
// Tests DeprecatedWriteRemoteCharacteristic with non-empty value buffer.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       DeprecatedWriteRemoteCharacteristic) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeprecatedWriteRemoteCharacteristic) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ReadRemoteCharacteristic_Twice
#else
#define MAYBE_ReadRemoteCharacteristic_Twice
#endif
// Tests ReadRemoteCharacteristic and GetValue multiple times.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       ReadRemoteCharacteristic_Twice) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_ReadRemoteCharacteristic_Twice) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_WriteRemoteCharacteristic_Twice
#else
#define MAYBE_WriteRemoteCharacteristic_Twice
#endif
// Tests WriteRemoteCharacteristic multiple times.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       WriteRemoteCharacteristic_Twice) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_WriteRemoteCharacteristic_Twice) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteRemoteCharacteristic_Twice
#else
#define MAYBE_DeprecatedWriteRemoteCharacteristic_Twice
#endif
// Tests DeprecatedWriteRemoteCharacteristic multiple times.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       DeprecatedWriteRemoteCharacteristic_Twice) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeprecatedWriteRemoteCharacteristic_Twice) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ReadRemoteCharacteristic_MultipleCharacteristics
#else
#define MAYBE_ReadRemoteCharacteristic_MultipleCharacteristics
#endif
// Tests ReadRemoteCharacteristic on two characteristics.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       ReadRemoteCharacteristic_MultipleCharacteristics) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_ReadRemoteCharacteristic_MultipleCharacteristics) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_WriteRemoteCharacteristic_MultipleCharacteristics
#else
#define MAYBE_WriteRemoteCharacteristic_MultipleCharacteristics
#endif
// Tests WriteRemoteCharacteristic on two characteristics.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       WriteRemoteCharacteristic_MultipleCharacteristics) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_WriteRemoteCharacteristic_MultipleCharacteristics) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteRemoteCharacteristic_MultipleCharacteristics
#else
#define MAYBE_DeprecatedWriteRemoteCharacteristic_MultipleCharacteristics
#endif
// Tests DeprecatedWriteRemoteCharacteristic on two characteristics.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       DeprecatedWriteRemoteCharacteristic_MultipleCharacteristics) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeprecatedWriteRemoteCharacteristic_MultipleCharacteristics) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoteCharacteristic_Nested_Read_Read
#else
#define MAYBE_RemoteCharacteristic_Nested_Read_Read
#endif
// Tests a nested ReadRemoteCharacteristic from within another
// ReadRemoteCharacteristic.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       RemoteCharacteristic_Nested_Read_Read) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_RemoteCharacteristic_Nested_Read_Read) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoteCharacteristic_Nested_Write_Write
#else
#define MAYBE_RemoteCharacteristic_Nested_Write_Write
#endif
// Tests a nested WriteRemoteCharacteristic from within another
// WriteRemoteCharacteristic.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       RemoteCharacteristic_Nested_Write_Write) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_RemoteCharacteristic_Nested_Write_Write) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoteCharacteristic_Nested_DeprecatedWrite_DeprecatedWrite
#else
#define MAYBE_RemoteCharacteristic_Nested_DeprecatedWrite_DeprecatedWrite
#endif
// Tests a nested DeprecatedWriteRemoteCharacteristic from within another
// DeprecatedWriteRemoteCharacteristic.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       RemoteCharacteristic_Nested_DeprecatedWrite_DeprecatedWrite) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_RemoteCharacteristic_Nested_DeprecatedWrite_DeprecatedWrite) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoteCharacteristic_Nested_Read_Write
#else
#define MAYBE_RemoteCharacteristic_Nested_Read_Write
#endif
// Tests a nested WriteRemoteCharacteristic from within a
// ReadRemoteCharacteristic.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       RemoteCharacteristic_Nested_Read_Write) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_RemoteCharacteristic_Nested_Read_Write) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoteCharacteristic_Nested_Read_DeprecatedWrite
#else
#define MAYBE_RemoteCharacteristic_Nested_Read_DeprecatedWrite
#endif
// Tests a nested DeprecatedWriteRemoteCharacteristic from within a
// ReadRemoteCharacteristic.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       RemoteCharacteristic_Nested_Read_DeprecatedWrite) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_RemoteCharacteristic_Nested_Read_DeprecatedWrite) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoteCharacteristic_Nested_Write_Read
#else
#define MAYBE_RemoteCharacteristic_Nested_Write_Read
#endif
// Tests a nested ReadRemoteCharacteristic from within a
// WriteRemoteCharacteristic.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       RemoteCharacteristic_Nested_Write_Read) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_RemoteCharacteristic_Nested_Write_Read) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoteCharacteristic_Nested_DeprecatedWrite_Read
#else
#define MAYBE_RemoteCharacteristic_Nested_DeprecatedWrite_Read
#endif
// Tests a nested ReadRemoteCharacteristic from within a
// DeprecatedWriteRemoteCharacteristic.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       RemoteCharacteristic_Nested_DeprecatedWrite_Read) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_RemoteCharacteristic_Nested_DeprecatedWrite_Read) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ReadError
#else
#define MAYBE_ReadError
#endif
// Tests ReadRemoteCharacteristic asynchronous error.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, ReadError) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_ReadError) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_WriteError
#else
#define MAYBE_WriteError
#endif
// Tests WriteRemoteCharacteristic asynchronous error.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, WriteError) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_WriteError) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteError
#else
#define MAYBE_DeprecatedWriteError
#endif
// Tests DeprecatedWriteRemoteCharacteristic asynchronous error.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, DeprecatedWriteError) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_DeprecatedWriteError) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_ReadSynchronousError
#else
#define MAYBE_ReadSynchronousError
#endif
// Tests ReadRemoteCharacteristic synchronous error.
// Test not relevant for macOS and WinRT since characteristic read cannot
// generate synchronous error.
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_ReadSynchronousError) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_WriteSynchronousError
#else
#define MAYBE_WriteSynchronousError
#endif
// Tests WriteRemoteCharacteristic synchronous error.
// This test doesn't apply to macOS and WinRT since a synchronous API does not
// exist.
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_WriteSynchronousError) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_DeprecatedWriteSynchronousError
#else
#define MAYBE_DeprecatedWriteSynchronousError
#endif
// Tests DeprecatedWriteRemoteCharacteristic synchronous error.
// This test doesn't apply to macOS and WinRT since a synchronous API does not
// exist.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeprecatedWriteSynchronousError) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ReadRemoteCharacteristic_ReadPending
#else
#define MAYBE_ReadRemoteCharacteristic_ReadPending
#endif
// Tests ReadRemoteCharacteristic error with a pending read operation.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       ReadRemoteCharacteristic_ReadPending) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_ReadRemoteCharacteristic_ReadPending) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_WriteRemoteCharacteristic_WritePending
#else
#define MAYBE_WriteRemoteCharacteristic_WritePending
#endif
// Tests WriteRemoteCharacteristic error with a pending write
// operation.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       WriteRemoteCharacteristic_WritePending) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_WriteRemoteCharacteristic_WritePending) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteRemoteCharacteristic_WritePending
#else
#define MAYBE_DeprecatedWriteRemoteCharacteristic_WritePending
#endif
// Tests DeprecatedWriteRemoteCharacteristic error with a pending write
// operation.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       DeprecatedWriteRemoteCharacteristic_WritePending) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeprecatedWriteRemoteCharacteristic_WritePending) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ReadRemoteCharacteristic_WritePending
#else
#define MAYBE_ReadRemoteCharacteristic_WritePending
#endif
// Tests ReadRemoteCharacteristic error with a pending write operation.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       ReadRemoteCharacteristic_WritePending) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_ReadRemoteCharacteristic_WritePending) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ReadRemoteCharacteristic_DeprecatedWritePending
#else
#define MAYBE_ReadRemoteCharacteristic_DeprecatedWritePending
#endif
// Tests ReadRemoteCharacteristic error with a pending write operation.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       ReadRemoteCharacteristic_DeprecatedWritePending) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_ReadRemoteCharacteristic_DeprecatedWritePending) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_WriteRemoteCharacteristic_ReadPending
#else
#define MAYBE_WriteRemoteCharacteristic_ReadPending
#endif
// Tests WriteRemoteCharacteristic error with a pending Read operation.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       WriteRemoteCharacteristic_ReadPending) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_WriteRemoteCharacteristic_ReadPending) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteRemoteCharacteristic_ReadPending
#else
#define MAYBE_DeprecatedWriteRemoteCharacteristic_ReadPending
#endif
// Tests DeprecatedWriteRemoteCharacteristic error with a pending Read
// operation.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       DeprecatedWriteRemoteCharacteristic_ReadPending) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeprecatedWriteRemoteCharacteristic_ReadPending) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_Notification_During_ReadRemoteCharacteristic
#else
#define MAYBE_Notification_During_ReadRemoteCharacteristic
#endif
// TODO(crbug.com/41314495): Enable on windows once it better matches
// how other platforms set global variables.
// Tests that a notification arriving during a pending read doesn't
// cause a crash.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       Notification_During_ReadRemoteCharacteristic) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_Notification_During_ReadRemoteCharacteristic) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_Notification_During_WriteRemoteCharacteristic
#else
#define MAYBE_Notification_During_WriteRemoteCharacteristic
#endif
// Tests that a notification arriving during a pending write doesn't
// cause a crash.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       Notification_During_WriteRemoteCharacteristic) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_Notification_During_WriteRemoteCharacteristic) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_Notification_During_DeprecatedWriteRemoteCharacteristic
#else
#define MAYBE_Notification_During_DeprecatedWriteRemoteCharacteristic
#endif
// Tests that a notification arriving during a pending write doesn't
// cause a crash.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       Notification_During_DeprecatedWriteRemoteCharacteristic) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_Notification_During_DeprecatedWriteRemoteCharacteristic) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySession_NoNotifyOrIndicate
#else
#define MAYBE_StartNotifySession_NoNotifyOrIndicate
#endif
// StartNotifySession fails if characteristic doesn't have Notify or Indicate
// property.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StartNotifySession_NoNotifyOrIndicate) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_NoNotifyOrIndicate) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySession_NoConfigDescriptor
#else
#define MAYBE_StartNotifySession_NoConfigDescriptor
#endif
// StartNotifySession fails if the characteristic is missing the Client
// Characteristic Configuration descriptor.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StartNotifySession_NoConfigDescriptor) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_NoConfigDescriptor) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySession_MultipleConfigDescriptor
#else
#define MAYBE_StartNotifySession_MultipleConfigDescriptor
#endif
// StartNotifySession fails if the characteristic has multiple Client
// Characteristic Configuration descriptors.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StartNotifySession_MultipleConfigDescriptor) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_MultipleConfigDescriptor) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_StartNotifySession_FailToSetCharacteristicNotification
#else
#define MAYBE_StartNotifySession_FailToSetCharacteristicNotification
#endif
// StartNotifySession fails synchronously when failing to set a characteristic
// to enable notifications.
// Android: This is mBluetoothGatt.setCharacteristicNotification failing.
// macOS: Not applicable: CoreBluetooth doesn't support synchronous API.
// Windows: Synchronous Test Not Applicable: OS calls are all made
// asynchronously from BluetoothTaskManagerWin.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_FailToSetCharacteristicNotification) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_StartNotifySession_WriteDescriptorSynchronousError
#else
#define MAYBE_StartNotifySession_WriteDescriptorSynchronousError
#endif
// Tests StartNotifySession descriptor write synchronous failure.
// macOS: Not applicable: No need to write to the descriptor manually.
// -[CBPeripheral setNotifyValue:forCharacteristic:] takes care of it.
// Windows: Synchronous Test Not Applicable: OS calls are all made
// asynchronously from BluetoothTaskManagerWin.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_WriteDescriptorSynchronousError) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySession
#else
#define MAYBE_StartNotifySession
#endif
// Tests StartNotifySession success on a characteristic that enabled Notify.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, StartNotifySession) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_StartNotifySession) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySession_OnIndicate
#else
#define MAYBE_StartNotifySession_OnIndicate
#endif
// Tests StartNotifySession success on a characteristic that enabled Indicate.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StartNotifySession_OnIndicate) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_OnIndicate) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySession_OnNotifyAndIndicate
#else
#define MAYBE_StartNotifySession_OnNotifyAndIndicate
#endif
// Tests StartNotifySession success on a characteristic that enabled Notify &
// Indicate.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StartNotifySession_OnNotifyAndIndicate) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_OnNotifyAndIndicate) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySession_Multiple
#else
#define MAYBE_StartNotifySession_Multiple
#endif
// Tests multiple StartNotifySession success.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StartNotifySession_Multiple) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_Multiple) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySessionError_Multiple
#else
#define MAYBE_StartNotifySessionError_Multiple
#endif
// Tests multiple StartNotifySessions pending and then an error.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StartNotifySessionError_Multiple) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySessionError_Multiple) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySessionDisconnectOnError
#else
#define MAYBE_StartNotifySessionDisconnectOnError
#endif
// Test that a GATT disconnect in a StartNotifications error callback will
// behave correctly. Regression test for crbug.com/1107577.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StartNotifySessionDisconnectOnError) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySessionDisconnectOnError) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_StartNotifySession_AfterDeleted
#else
#define MAYBE_StartNotifySession_AfterDeleted
#endif
// Tests StartNotifySession completing after chrome objects are deleted.
// macOS: Not applicable: This can never happen if CBPeripheral delegate is set
// to nil.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_AfterDeleted) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySession_BeforeDeleted
#else
#define MAYBE_StartNotifySession_BeforeDeleted
#endif
// Tests StartNotifySession completing before chrome objects are deleted.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StartNotifySession_BeforeDeleted) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_BeforeDeleted) {}

#if BUILDFLAG(IS_APPLE)
#define MAYBE_StartNotifySession_Reentrant_Success_Success
#else
#define MAYBE_StartNotifySession_Reentrant_Success_Success
#endif
// Tests StartNotifySession reentrant in start notify session success callback
// and the reentrant start notify session success.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StartNotifySession_Reentrant_Success_Success) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySession_Reentrant_Success_Success) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession
#else
#define MAYBE_StopNotifySession
#endif
// Tests StopNotifySession success on a characteristic that enabled Notify.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, StopNotifySession) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_StopNotifySession) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_SessionDeleted
#else
#define MAYBE_StopNotifySession_SessionDeleted
#endif
// Tests that deleted sessions are stopped.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_SessionDeleted) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_SessionDeleted) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_SessionDeleted2
#else
#define MAYBE_StopNotifySession_SessionDeleted2
#endif
// Tests that deleting the sessions before the stop callbacks have been
// invoked does not cause problems.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_SessionDeleted2) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_SessionDeleted2) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_Cancelled
#else
#define MAYBE_StopNotifySession_Cancelled
#endif
// Tests that cancelling StopNotifySession works.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_Cancelled) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_Cancelled) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_AfterDeleted
#else
#define MAYBE_StopNotifySession_AfterDeleted
#endif
// Tests that deleted sessions are stopped.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_AfterDeleted) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_AfterDeleted) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_OnIndicate
#else
#define MAYBE_StopNotifySession_OnIndicate
#endif
// Tests StopNotifySession success on a characteristic that enabled Indicate.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_OnIndicate) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_OnIndicate) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_OnNotifyAndIndicate
#else
#define MAYBE_StopNotifySession_OnNotifyAndIndicate
#endif
// Tests StopNotifySession success on a characteristic that enabled Notify &
// Indicate.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_OnNotifyAndIndicate) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_OnNotifyAndIndicate) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_Error
#else
#define MAYBE_StopNotifySession_Error
#endif
// Tests StopNotifySession error
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, StopNotifySession_Error) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_StopNotifySession_Error) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_Multiple1
#else
#define MAYBE_StopNotifySession_Multiple1
#endif
// Tests multiple StopNotifySession calls for a single session.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_Multiple1) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_Multiple1) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_Multiple2
#else
#define MAYBE_StopNotifySession_Multiple2
#endif
// Tests multiple StartNotifySession calls and multiple StopNotifySession calls.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_Multiple2) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_Multiple2) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_StopStart
#else
#define MAYBE_StopNotifySession_StopStart
#endif
// Tests starting a new notify session before the previous stop request
// resolves.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_StopStart) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_StopStart) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_StartStopStart
#else
#define MAYBE_StopNotifySession_StartStopStart
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_StartStopStart) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_StartStopStart) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_StopStopStart
#else
#define MAYBE_StopNotifySession_StopStopStart
#endif
// Tests starting a new notify session before the previous stop requests
// resolve.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_StopStopStart) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_StopStopStart) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_Reentrant_Success_Stop
#else
#define MAYBE_StopNotifySession_Reentrant_Success_Stop
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_Reentrant_Success_Stop) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_Reentrant_Success_Stop) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_Reentrant_Stop_StartSuccess
#else
#define MAYBE_StopNotifySession_Reentrant_Stop_StartSuccess
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_Reentrant_Stop_StartSuccess) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_Reentrant_Stop_StartSuccess) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_StopNotifySession_Reentrant_Stop_StartError
#else
#define MAYBE_StopNotifySession_Reentrant_Stop_StartError
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       StopNotifySession_Reentrant_Stop_StartError) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySession_Reentrant_Stop_StartError) {}

#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
#define MAYBE_GattCharacteristicAdded
#else
#define MAYBE_GattCharacteristicAdded
#endif
// TODO(crbug.com/41356253) Android should report that services are discovered
// when a characteristic is added, but currently does not.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, GattCharacteristicAdded) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_GattCharacteristicAdded) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GattCharacteristicValueChanged
#else
#define MAYBE_GattCharacteristicValueChanged
#endif
// Tests Characteristic Value changes during a Notify Session.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       GattCharacteristicValueChanged) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_GattCharacteristicValueChanged) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_TwoGattCharacteristicValueChanges
#else
#define MAYBE_TwoGattCharacteristicValueChanges
#endif
// Tests that Characteristic value changes arriving consecutively result in
// two notifications with correct values.
// macOS: Does not apply. All events arrive on the UI Thread.
// TODO(crbug.com/41303035): Enable this test on Windows.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_TwoGattCharacteristicValueChanges) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_GattCharacteristicValueChanged_AfterDeleted
#else
#define MAYBE_GattCharacteristicValueChanged_AfterDeleted
#endif
// Tests Characteristic Value changing after a Notify Session and objects being
// destroyed.
// macOS: Not applicable: This can never happen if CBPeripheral delegate is set
// to nil.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_GattCharacteristicValueChanged_AfterDeleted) {}

// Tests that closing the GATT connection during a characteristic
// value notification is safe.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_GattCharacteristicValueChanged_DisconnectDuring
#else
#define MAYBE_GattCharacteristicValueChanged_DisconnectDuring
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       GattCharacteristicValueChanged_DisconnectDuring) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_GattCharacteristicValueChanged_DisconnectDuring) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_GetDescriptors_FindNone
#else
#define MAYBE_GetDescriptors_FindNone
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, GetDescriptors_FindNone) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_GetDescriptors_FindNone) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_GetDescriptors_and_GetDescriptor
#else
#define MAYBE_GetDescriptors_and_GetDescriptor
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       GetDescriptors_and_GetDescriptor) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_GetDescriptors_and_GetDescriptor) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_GetDescriptorsByUUID
#else
#define MAYBE_GetDescriptorsByUUID
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt, GetDescriptorsByUUID) {
#else
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_GetDescriptorsByUUID) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_ReadDuringDisconnect
#else
#define MAYBE_ReadDuringDisconnect
#endif
// Tests that read requests after a device disconnects but before the disconnect
// task has a chance to run result in an error.
// macOS: Does not apply. All events arrive on the UI Thread.
// TODO(crbug.com/41303035): Enable this test on Windows.
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_ReadDuringDisconnect) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_WriteDuringDisconnect
#else
#define MAYBE_WriteDuringDisconnect
#endif
// Tests that write requests after a device disconnects but before the
// disconnect task runs result in an error.
// macOS: Does not apply. All events arrive on the UI Thread.
// TODO(crbug.com/41303035): Enable this test on Windows.
TEST_F(BluetoothRemoteGattCharacteristicTest, MAYBE_WriteDuringDisconnect) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_DeprecatedWriteDuringDisconnect
#else
#define MAYBE_DeprecatedWriteDuringDisconnect
#endif
// Tests that write requests after a device disconnects but before the
// disconnect task runs result in an error.
// macOS: Does not apply. All events arrive on the UI Thread.
// TODO(crbug.com/41303035): Enable this test on Windows.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeprecatedWriteDuringDisconnect) {}

#if BUILDFLAG(IS_APPLE)
#define MAYBE_WriteWithoutResponseOnlyCharacteristic_WriteRemoteCharacteristicDuringDisconnect
#else
#define MAYBE_WriteWithoutResponseOnlyCharacteristic_WriteRemoteCharacteristicDuringDisconnect
#endif
// Tests that writing without response during a disconnect results in an error.
// Only applies to macOS and WinRT whose events arrive all on the UI thread. See
// other *DuringDisconnect tests for Android and Windows whose events arrive on
// a different thread.
#if BUILDFLAG(IS_WIN)
TEST_P(
    BluetoothRemoteGattCharacteristicTestWinrt,
    WriteWithoutResponseOnlyCharacteristic_WriteRemoteCharacteristicDuringDisconnect) {
#else
TEST_F(
    BluetoothRemoteGattCharacteristicTest,
    MAYBE_WriteWithoutResponseOnlyCharacteristic_WriteRemoteCharacteristicDuringDisconnect) {}

#if BUILDFLAG(IS_APPLE)
#define MAYBE_WriteWithoutResponseOnlyCharacteristic_DeprecatedWriteRemoteCharacteristicDuringDisconnect
#else
#define MAYBE_WriteWithoutResponseOnlyCharacteristic_DeprecatedWriteRemoteCharacteristicDuringDisconnect
#endif
// Tests that writing without response during a disconnect results in an error.
// Only applies to macOS and WinRT whose events arrive all on the UI thread. See
// other *DuringDisconnect tests for Android and Windows whose events arrive on
// a different thread.
#if BUILDFLAG(IS_WIN)
TEST_P(
    BluetoothRemoteGattCharacteristicTestWinrt,
    WriteWithoutResponseOnlyCharacteristic_DeprecatedWriteRemoteCharacteristicDuringDisconnect) {
#else
TEST_F(
    BluetoothRemoteGattCharacteristicTest,
    MAYBE_WriteWithoutResponseOnlyCharacteristic_DeprecatedWriteRemoteCharacteristicDuringDisconnect) {}

// Tests that closing the GATT connection when a characteristic value write
// fails due to a disconnect is safe.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_WriteWithoutResponseOnlyCharacteristic_CloseConnectionDuringDisconnect
#else
#define MAYBE_WriteWithoutResponseOnlyCharacteristic_CloseConnectionDuringDisconnect
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothRemoteGattCharacteristicTestWinrt,
       WriteWithoutResponseOnlyCharacteristic_CloseConnectionDuringDisconnect) {
#else
TEST_F(
    BluetoothRemoteGattCharacteristicTest,
    MAYBE_WriteWithoutResponseOnlyCharacteristic_CloseConnectionDuringDisconnect) {}

// Tests that closing the GATT connection when a characteristic value write
// fails due to a disconnect is safe.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteWithoutResponseOnlyCharacteristic_CloseConnectionDuringDisconnect
#else
#define MAYBE_DeprecatedWriteWithoutResponseOnlyCharacteristic_CloseConnectionDuringDisconnect
#endif
#if BUILDFLAG(IS_WIN)
TEST_P(
    BluetoothRemoteGattCharacteristicTestWinrt,
    DeprecatedWriteWithoutResponseOnlyCharacteristic_CloseConnectionDuringDisconnect) {
#else
TEST_F(
    BluetoothRemoteGattCharacteristicTest,
    MAYBE_DeprecatedWriteWithoutResponseOnlyCharacteristic_CloseConnectionDuringDisconnect) {}

#if BUILDFLAG(IS_APPLE)
#define MAYBE_WriteWithoutResponseOnlyCharacteristic_DisconnectCalledDuringWriteRemoteCharacteristic
#else
#define MAYBE_WriteWithoutResponseOnlyCharacteristic_DisconnectCalledDuringWriteRemoteCharacteristic
#endif
// Tests that disconnecting right after a write without response results in an
// error.
// TODO(crbug.com/41321574): Enable on other platforms depending on the
// resolution of crbug.com/726534.
TEST_F(
    BluetoothRemoteGattCharacteristicTest,
    MAYBE_WriteWithoutResponseOnlyCharacteristic_DisconnectCalledDuringWriteRemoteCharacteristic) {}

#if BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteWithoutResponseOnlyCharacteristic_DisconnectCalledDuringWriteRemoteCharacteristic
#else
#define MAYBE_DeprecatedWriteWithoutResponseOnlyCharacteristic_DisconnectCalledDuringWriteRemoteCharacteristic
#endif
// Tests that disconnecting right after a write without response results in an
// error.
// TODO(crbug.com/41321574): Enable on other platforms depending on the
// resolution of crbug.com/726534.
TEST_F(
    BluetoothRemoteGattCharacteristicTest,
    MAYBE_DeprecatedWriteWithoutResponseOnlyCharacteristic_DisconnectCalledDuringWriteRemoteCharacteristic) {}

#if BUILDFLAG(IS_APPLE)
#define MAYBE_WriteWithoutResponseOnlyCharacteristic_DisconnectCalledBeforeWriteRemoteCharacteristic
#else
#define MAYBE_WriteWithoutResponseOnlyCharacteristic_DisconnectCalledBeforeWriteRemoteCharacteristic
#endif
// Tests that disconnecting right before a write without response results in an
// error.
// TODO(crbug.com/41321574): Enable on other platforms depending on the
// resolution of crbug.com/726534.
TEST_F(
    BluetoothRemoteGattCharacteristicTest,
    MAYBE_WriteWithoutResponseOnlyCharacteristic_DisconnectCalledBeforeWriteRemoteCharacteristic) {}

#if BUILDFLAG(IS_APPLE)
#define MAYBE_DeprecatedWriteWithoutResponseOnlyCharacteristic_DisconnectCalledBeforeWriteRemoteCharacteristic
#else
#define MAYBE_DeprecatedWriteWithoutResponseOnlyCharacteristic_DisconnectCalledBeforeWriteRemoteCharacteristic
#endif
// Tests that disconnecting right before a write without response results in an
// error.
// TODO(crbug.com/41321574): Enable on other platforms depending on the
// resolution of crbug.com/726534.
TEST_F(
    BluetoothRemoteGattCharacteristicTest,
    MAYBE_DeprecatedWriteWithoutResponseOnlyCharacteristic_DisconnectCalledBeforeWriteRemoteCharacteristic) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_StartNotifySessionDuringDisconnect
#else
#define MAYBE_StartNotifySessionDuringDisconnect
#endif
// Tests that start notifications requests after a device disconnects but before
// the disconnect task runs result in an error.
// macOS: Does not apply. All events arrive on the UI Thread.
// TODO(crbug.com/41303035): Enable this test on Windows.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StartNotifySessionDuringDisconnect) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_StopNotifySessionDuringDisconnect
#else
#define MAYBE_StopNotifySessionDuringDisconnect
#endif
// Tests that stop notifications requests after a device disconnects but before
// the disconnect task runs do not result in a crash.
// macOS: Does not apply. All events arrive on the UI Thread.
// TODO(crbug.com/41303035): Enable this test on Windows.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_StopNotifySessionDuringDisconnect) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_DeleteNotifySessionDuringDisconnect
#else
#define MAYBE_DeleteNotifySessionDuringDisconnect
#endif
// Tests that deleting notify sessions after a device disconnects but before the
// disconnect task runs do not result in a crash.
// macOS: Does not apply. All events arrive on the UI Thread.
// TODO(crbug.com/41303035): Enable this test on Windows.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       MAYBE_DeleteNotifySessionDuringDisconnect) {}

#if BUILDFLAG(IS_APPLE)
// Tests to receive a services changed notification from macOS, while
// discovering descriptors. This test simulate having 2 descriptor scan at the
// same time. Only once both descriptor scanning is done, the gatt device is
// ready.
// Android: This test doesn't apply to Android because there is no services
// changed event that could arrive during a discovery procedure.
TEST_F(BluetoothRemoteGattCharacteristicTest,
       SimulateDeviceModificationWhileDiscoveringDescriptors) {
  InitWithFakeAdapter();
  StartLowEnergyDiscoverySession();
  BluetoothDevice* device = SimulateLowEnergyDevice(3);
  device->CreateGattConnection(
      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));

  TestBluetoothAdapterObserver observer(adapter_);

  // Starts first discovery process.
  SimulateGattConnection(device);
  EXPECT_EQ(1, observer.device_changed_count());
  AddServicesToDeviceMac(device, {kTestUUIDHeartRate});
  SimulateDidDiscoverServicesMac(device);
  EXPECT_EQ(1u, device->GetGattServices().size());
  BluetoothRemoteGattService* service = device->GetGattServices()[0];
  std::string characteristic_uuid = "11111111-0000-1000-8000-00805f9b34fb";
  AddCharacteristicToServiceMac(service, characteristic_uuid,
                                /* properties */ 0);
  SimulateDidDiscoverCharacteristicsMac(service);
  EXPECT_EQ(1u, service->GetCharacteristics().size());
  BluetoothRemoteGattCharacteristic* characteristic =
      service->GetCharacteristics()[0];
  std::string descriptor_uuid = "22222222-0000-1000-8000-00805f9b34fb";
  AddDescriptorToCharacteristicMac(characteristic, descriptor_uuid);
  // Now waiting for descriptor discovery.

  // Starts second discovery process.
  SimulateGattServicesChanged(device);
  EXPECT_EQ(2, observer.device_changed_count());
  SimulateDidDiscoverServicesMac(device);
  SimulateDidDiscoverCharacteristicsMac(service);
  // Now waiting for a second descriptor discovery.

  // Finish discovery process.
  // First system call to -[id<CBPeripheralDelegate>
  // peripheral:didDiscoverDescriptorsForCharacteristic:error:]
  SimulateDidDiscoverDescriptorsMac(characteristic);
  EXPECT_EQ(0, observer.gatt_service_changed_count());
  EXPECT_EQ(1u, service->GetCharacteristics().size());
  EXPECT_EQ(1u, characteristic->GetDescriptors().size());
  EXPECT_EQ(2, observer.device_changed_count());

  // Second system call to -[id<CBPeripheralDelegate>
  // peripheral:didDiscoverDescriptorsForCharacteristic:error:]
  // Finish second discovery process.
  observer.Reset();
  SimulateDidDiscoverDescriptorsMac(characteristic);
  EXPECT_EQ(1, observer.gatt_service_changed_count());
  EXPECT_EQ(1, observer.device_changed_count());
}
#endif  // BUILDFLAG(IS_APPLE)

#if BUILDFLAG(IS_APPLE)
// Simulates to receive an extra discovery descriptor notifications from  macOS.
// Those notifications should be ignored.
// Android: This test doesn't apply to Android because there is no services
// changed event that could arrive during a discovery procedure.
TEST_F(BluetoothRemoteGattCharacteristicTest, ExtraDidDiscoverDescriptorsCall) {
  InitWithFakeAdapter();
  StartLowEnergyDiscoverySession();
  BluetoothDevice* device = SimulateLowEnergyDevice(3);
  device->CreateGattConnection(
      GetGattConnectionCallback(Call::EXPECTED, Result::SUCCESS));

  TestBluetoothAdapterObserver observer(adapter_);

  // Starts first discovery process.
  SimulateGattConnection(device);
  AddServicesToDeviceMac(device, {kTestUUIDHeartRate});
  SimulateDidDiscoverServicesMac(device);
  EXPECT_EQ(1u, device->GetGattServices().size());
  BluetoothRemoteGattService* service = device->GetGattServices()[0];
  std::string characteristic_uuid = "11111111-0000-1000-8000-00805f9b34fb";
  AddCharacteristicToServiceMac(service, characteristic_uuid,
                                /* properties */ 0);
  SimulateDidDiscoverCharacteristicsMac(service);
  EXPECT_EQ(1u, service->GetCharacteristics().size());
  BluetoothRemoteGattCharacteristic* characteristic =
      service->GetCharacteristics()[0];
  std::string descriptor_uuid = "22222222-0000-1000-8000-00805f9b34fb";
  AddDescriptorToCharacteristicMac(characteristic, descriptor_uuid);
  SimulateDidDiscoverDescriptorsMac(characteristic);
  EXPECT_EQ(1, observer.gatt_service_changed_count());
  EXPECT_EQ(1u, service->GetCharacteristics().size());
  EXPECT_EQ(1u, characteristic->GetDescriptors().size());

  observer.Reset();
  SimulateDidDiscoverDescriptorsMac(characteristic);  // Extra system call.
  SimulateGattServicesChanged(device);
  SimulateDidDiscoverDescriptorsMac(characteristic);  // Extra system call.
  SimulateDidDiscoverServicesMac(device);
  SimulateDidDiscoverDescriptorsMac(characteristic);  // Extra system call.
  SimulateDidDiscoverCharacteristicsMac(service);
  SimulateDidDiscoverDescriptorsMac(characteristic);
  SimulateDidDiscoverDescriptorsMac(characteristic);  // Extra system call.
  EXPECT_EQ(2, observer.device_changed_count());
}
#endif  // BUILDFLAG(IS_APPLE)

#if BUILDFLAG(IS_WIN)
INSTANTIATE_TEST_SUITE_P(All,
                         BluetoothRemoteGattCharacteristicTestWinrt,
                         ::testing::ValuesIn(kBluetoothTestWinrtParam));
#endif  // BUILDFLAG(IS_WIN)

}  // namespace device