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

// Use the <code>chrome.bluetoothPrivate</code> API to control the Bluetooth
// adapter state and handle device pairing.
// NOTE: This IDL is dependent on bluetooth.idl.

[implemented_in = "extensions/browser/api/bluetooth/bluetooth_private_api.h"]
namespace bluetoothPrivate {
  // Events that can occur during pairing. The method used for pairing varies
  // depending on the capability of the two devices.
  enum PairingEventType {
    // An alphanumeric PIN code is required to be entered by the user.
    requestPincode,

    // Display a PIN code to the user.
    displayPincode,

    // A numeric passkey is required to be entered by the user.
    requestPasskey,

    // Display a zero padded 6 digit numeric passkey that the user entered on
    // the remote device. This event may occur multiple times during pairing to
    // update the entered passkey.
    displayPasskey,

    // The number of keys inputted by the user on the remote device when
    // entering a passkey. This event may be called multiple times during
    // pairing to update the number of keys inputted.
    keysEntered,

    // Requests that a 6 digit passkey be displayed and the user confirms that
    // both devies show the same passkey.
    confirmPasskey,

    // Requests authorization for a pairing under the just-works model. It is up
    // to the app to ask for user confirmation.
    requestAuthorization,

    // Pairing is completed.
    complete
  };

  // Results for connect(). See function declaration for details.
  enum ConnectResultType {
    alreadyConnected,
    authCanceled,
    authFailed,
    authRejected,
    authTimeout,
    failed,
    inProgress,
    success,
    unknownError,
    unsupportedDevice
  };

  // Valid pairing responses.
  enum PairingResponse {
    confirm, reject, cancel
  };

  enum TransportType {
    le, bredr, dual
  };

  // A pairing event received from a Bluetooth device.
  dictionary PairingEvent {
    PairingEventType pairing;
    bluetooth.Device device;
    DOMString? pincode;
    long? passkey;
    long? enteredKey;
  };

  dictionary NewAdapterState {
    // The human-readable name of the adapter.
    DOMString? name;

    // Whether or not the adapter has power.
    boolean? powered;

    // Whether the adapter is discoverable by other devices.
    boolean? discoverable;
  };

  dictionary SetPairingResponseOptions {
    // The remote device to send the pairing response.
    bluetooth.Device device;

    // The response type.
    PairingResponse response;

    // A 1-16 character alphanumeric set in response to
    // <code>requestPincode</code>.
    DOMString? pincode;

    // An integer between 0-999999 set in response to
    // <code>requestPasskey</code>.
    long? passkey;
  };

  dictionary DiscoveryFilter {
    // Transport type.
    TransportType? transport;

    // uuid of service or array of uuids
    (DOMString or DOMString[])? uuids;

    // RSSI ranging value. Only devices with RSSI higher than this value will be
    // reported.
    long? rssi;

    // Pathloss ranging value. Only devices with pathloss lower than this value
    // will be reported.
    long? pathloss;
  };

  callback VoidCallback = void();
  callback ConnectCallback = void(ConnectResultType result);

  // These functions all report failures via chrome.runtime.lastError.
  interface Functions {
    // Changes the state of the Bluetooth adapter.
    // |adapterState|:
    static void setAdapterState(NewAdapterState adapterState,
                                optional VoidCallback callback);

    static void setPairingResponse(SetPairingResponseOptions options,
                                   optional VoidCallback callback);

    // Tears down all connections to the given device.
    static void disconnectAll(DOMString deviceAddress,
                              optional VoidCallback callback);

    // Forgets the given device.
    static void forgetDevice(DOMString deviceAddress,
                             optional VoidCallback callback);

    // Set or clear discovery filter.
    static void setDiscoveryFilter(DiscoveryFilter discoveryFilter,
                                   optional VoidCallback callback);

    // Connects to the given device. This will only throw an error if the
    // device address is invalid or the device is already connected. Otherwise
    // this will succeed and invoke |callback| with ConnectResultType.
    static void connect(DOMString deviceAddress,
                        optional ConnectCallback callback);

    // Pairs the given device.
    static void pair(DOMString deviceAddress, optional VoidCallback callback);
  };

  interface Events {
    // Fired when a pairing event occurs.
    // |pairingEvent|: A pairing event.
    [maxListeners=1] static void onPairing(PairingEvent pairingEvent);
  };
};
