void OnError(BluetoothStatus aStatus) override
  {
    BT_WARNING("BluetoothGattClientInterface::RegisterClient failed: %d",
               (int)aStatus);

    BluetoothService* bs = BluetoothService::Get();
    NS_ENSURE_TRUE_VOID(bs);

    // Notify BluetoothGatt for client disconnected
    BluetoothSignal signal(
      NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
      mClient->mAppUuid,
      BluetoothValue(false)); // Disconnected
    bs->DistributeSignal(signal);

    // Reject the connect request
    if (mClient->mConnectRunnable) {
      NS_NAMED_LITERAL_STRING(errorStr, "Register GATT client failed");
      DispatchBluetoothReply(mClient->mConnectRunnable,
                             BluetoothValue(),
                             errorStr);
      mClient->mConnectRunnable = nullptr;
    }

    sClients->RemoveElement(mClient);
  }
//
// Notification Handlers
//
void
BluetoothGattManager::RegisterClientNotification(int aStatus,
                                                 int aClientIf,
                                                 const BluetoothUuid& aAppUuid)
{
  BT_API2_LOGR("Client Registered, clientIf = %d", aClientIf);
  MOZ_ASSERT(NS_IsMainThread());

  nsString uuid;
  UuidToString(aAppUuid, uuid);

  size_t index = sClients->IndexOf(uuid, 0 /* Start */, UuidComparator());
  NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
  nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);

  BluetoothService* bs = BluetoothService::Get();
  NS_ENSURE_TRUE_VOID(bs);

  if (aStatus) { // operation failed
    BT_API2_LOGR(
      "RegisterClient failed, clientIf = %d, status = %d, appUuid = %s",
      aClientIf, aStatus, NS_ConvertUTF16toUTF8(uuid).get());

    // Notify BluetoothGatt for client disconnected
    BluetoothSignal signal(
      NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
      uuid, BluetoothValue(false)); // Disconnected
    bs->DistributeSignal(signal);

    // Reject the connect request
    if (client->mConnectRunnable) {
      NS_NAMED_LITERAL_STRING(errorStr,
                              "Connect failed due to registration failed");
      DispatchBluetoothReply(client->mConnectRunnable,
                             BluetoothValue(),
                             errorStr);
      client->mConnectRunnable = nullptr;
    }

    sClients->RemoveElement(client);
    return;
  }

  client->mClientIf = aClientIf;

  // Notify BluetoothGatt to update the clientIf
  BluetoothSignal signal(
    NS_LITERAL_STRING("ClientRegistered"),
    uuid, BluetoothValue(uint32_t(aClientIf)));
  bs->DistributeSignal(signal);

  // Client just registered, proceed remaining connect request.
  if (client->mConnectRunnable) {
    sBluetoothGattClientInterface->Connect(
      aClientIf, client->mDeviceAddr, true /* direct connect */,
      new ConnectResultHandler(client));
  }
}
/* static */
void AudioNotificationReceiver::Unregister(
    DeviceChangeListener* aDeviceChangeListener) {
  MOZ_ASSERT(XRE_IsContentProcess());

  StaticMutexAutoLock lock(sMutex);
  MOZ_ASSERT(!sSubscribers->IsEmpty(), "No subscriber.");

  sSubscribers->RemoveElement(aDeviceChangeListener);
  if (sSubscribers->IsEmpty()) {
    // Clear the static pointer here to prevent memory leak.
    sSubscribers = nullptr;
  }

  ANR_LOG("The DeviceChangeListener: %p is unregistered successfully.",
          aDeviceChangeListener);
}
  void UnregisterClient() override
  {
    MOZ_ASSERT(mClient->mUnregisterClientRunnable);
    BluetoothService* bs = BluetoothService::Get();
    NS_ENSURE_TRUE_VOID(bs);

    // Notify BluetoothGatt to clear the clientIf
    BluetoothSignal signal(
      NS_LITERAL_STRING("ClientUnregistered"),
      mClient->mAppUuid,
      BluetoothValue(true));
    bs->DistributeSignal(signal);

    // Resolve the unregister request
    DispatchBluetoothReply(mClient->mUnregisterClientRunnable,
                           BluetoothValue(true),
                           EmptyString());
    mClient->mUnregisterClientRunnable = nullptr;

    sClients->RemoveElement(mClient);
  }