WebAPI/WebBluetooth (Until Firefox OS 2.1)

From MozillaWiki
Jump to: navigation, search

WebBluetooth

Goals

The aim of WebBluetooth is to establish a DOM API to set up and communicate with Bluetooth devices. This includes setting properties on adapters and devices, scanning for devices, bonding, and socket initialization.

Firefox OS Needs

Firefox OS is the main consumer of WebBluetooth for the moment. Most operating systems already provide a configuration layer for bluetooth, and we do not plan on overriding that. However, Firefox OS will require its own settings and initialization code, so the focus of the API is on that platform for the time being.

Current Status

Until Firefox OS v2.1, Bluetooth APIs still haven't been exposed for 3rd party web apps. In other words, only certified apps with Bluetooth permission are allowed to use Bluetooth API for now, and there is no interface like BluetoothSocket for Gaia developers to use Bluetooth as a media to transfer data.

Since the API we have now is too BlueZ-specific, we will refine Bluetooth API since Firefox OS v2.2.

DOM API

BluetoothManager.webidl

interface BluetoothManager : EventTarget
{
  [Throws]
  readonly attribute boolean      enabled;

           attribute EventHandler onenabled;
           attribute EventHandler ondisabled;
           attribute EventHandler onadapteradded;

  [Throws]
  boolean     isConnected(unsigned short aProfile);
  [NewObject, Throws]
  DOMRequest? getDefaultAdapter();
};

BluetoothAdapter.webidl

// MediaMetadata and MediaPlayStatus are used to keep data from Applications.
// Please see specification of AVRCP 1.3 for more details.
dictionary MediaMetaData
{
  // track title
  DOMString   title = "";
  // artist name
  DOMString   artist = "";
  // album name
  DOMString   album = "";
  // track number
  long long   mediaNumber = -1;
  // number of tracks in the album
  long long   totalMediaCount = -1;
  // playing time (ms)
  long long   duration = -1;
};
dictionary MediaPlayStatus
{
  // current track length (ms)
  long long   duration = -1;
  // playing time (ms)
  long long   position = -1;
  // one of 'STOPPED'/'PLAYING'/'PAUSED'/'FWD_SEEK'/'REV_SEEK'/'ERROR'
  DOMString   playStatus = "";
};
interface BluetoothAdapter : EventTarget
{
  readonly attribute DOMString      address;
  readonly attribute unsigned long  class;
  readonly attribute boolean        discovering;
  readonly attribute DOMString      name;
  readonly attribute boolean        discoverable;
  readonly attribute unsigned long  discoverableTimeout; // in seconds

  // array of type BluetoothDevice[]
  [GetterThrows]
  readonly attribute any            devices;

  // array of type DOMString[]
  [GetterThrows]
  readonly attribute any            uuids;

           attribute EventHandler   ondevicefound;

  // Fired when pairing process is completed
           attribute EventHandler   onpairedstatuschanged;

  // Fired when a2dp connection status changed
           attribute EventHandler   ona2dpstatuschanged;

  // Fired when handsfree connection status changed
           attribute EventHandler   onhfpstatuschanged;

  // Fired when sco connection status changed
           attribute EventHandler   onscostatuschanged;

  // Fired when remote devices query current media play status
           attribute EventHandler   onrequestmediaplaystatus;

  [NewObject, Throws]
  DOMRequest setName(DOMString name);
  [NewObject, Throws]
  DOMRequest setDiscoverable(boolean discoverable);
  [NewObject, Throws]
  DOMRequest setDiscoverableTimeout(unsigned long timeout);
  [NewObject, Throws]
  DOMRequest startDiscovery();
  [NewObject, Throws]
  DOMRequest stopDiscovery();
  [NewObject, Throws]
  DOMRequest pair(DOMString deviceAddress);
  [NewObject, Throws]
  DOMRequest unpair(DOMString deviceAddress);
  [NewObject, Throws]
  DOMRequest getPairedDevices();
  [NewObject, Throws]
  DOMRequest getConnectedDevices(unsigned short serviceUuid);
  [NewObject, Throws]
  DOMRequest setPinCode(DOMString deviceAddress, DOMString pinCode);
  [NewObject, Throws]
  DOMRequest setPasskey(DOMString deviceAddress, unsigned long passkey);
  [NewObject, Throws]
  DOMRequest setPairingConfirmation(DOMString deviceAddress, boolean confirmation);

 /**
  * Connect/Disconnect to a specific service of a target remote device.
  * To check the value of service UUIDs, please check "Bluetooth Assigned
  * Numbers" / "Service Discovery Protocol" for more information.
  *
  * Note that service UUID is optional. If it isn't passed when calling
  * Connect, multiple profiles are tried sequentially based on the class of
  * device (CoD). If it isn't passed when calling Disconnect, all connected
  * profiles are going to be closed.
  *
  * Reply success if the connection of any profile is successfully
  * established/released; reply error if we failed to connect/disconnect all
  * of the planned profiles.
  *
  * @param device Remote device
  * @param profile 2-octets service UUID. This is optional.
  */
  [NewObject, Throws]
  DOMRequest connect(BluetoothDevice device, optional unsigned short serviceUuid);

  [NewObject, Throws]
  DOMRequest disconnect(BluetoothDevice device, optional unsigned short serviceUuid);

  // One device can only send one file at a time
  [NewObject, Throws]
  DOMRequest sendFile(DOMString deviceAddress, Blob blob);
  [NewObject, Throws]
  DOMRequest stopSendingFile(DOMString deviceAddress);
  [NewObject, Throws]
  DOMRequest confirmReceivingFile(DOMString deviceAddress, boolean confirmation);

  // Connect/Disconnect SCO (audio) connection
  [NewObject, Throws]
  DOMRequest connectSco();
  [NewObject, Throws]
  DOMRequest disconnectSco();
  [NewObject, Throws]
  DOMRequest isScoConnected();

 /**
  * Additional HFP methods to handle CDMA network.
  *
  * In GSM network we observe call operations from RIL call state changes;
  * however in CDMA network RIL call states do not change under some call
  * operations, so we need these additional methods to be informed of these
  * operations from dialer.
  *
  * For more information please refer to bug 912005 and 925638.
  */
  [NewObject, Throws]
  DOMRequest answerWaitingCall();
  [NewObject, Throws]
  DOMRequest ignoreWaitingCall();
  [NewObject, Throws]
  DOMRequest toggleCalls();

  // AVRCP 1.3 methods
  [NewObject,Throws]
  DOMRequest sendMediaMetaData(optional MediaMetaData mediaMetaData);
  [NewObject,Throws]
  DOMRequest sendMediaPlayStatus(optional MediaPlayStatus mediaPlayStatus);
};

BluetoothDevice.webidl

interface BluetoothDevice : EventTarget
{
  readonly attribute DOMString      address;
  readonly attribute DOMString      name;
  readonly attribute DOMString      icon;
  readonly attribute boolean        connected;
  readonly attribute boolean        paired;
  readonly attribute unsigned long  class;

  // array of type DOMString[]
  [Throws]
  readonly attribute any            uuids;

  // array of type DOMString[]
  [Throws]
  readonly attribute any            services;
};

Implementation Specifics

For communicating with the bluetooth adapter and devices on Firefox OS, we will be using the DBus message system. This allows us to easily access all parts of the bluetooth system on Firefox OS based platforms, without having to worry about GPL licensing issues.

DBus Usage and Licensing

Bluetooth on Linux and B2G is accessed via the Bluez bluetooth stack. This stack is GPL, and the libraries that come with it to access bluetooth sockets are also GPL. To remove the licensing issues involved with this, the DBus communications layer is used to provide an IPC route for bluetooth related code. The WebBluetooth API (on Linux and Firefox OS) will use DBus to keep the code compatible with the MPL.

DBus on Linux and Android

There are many ways to access DBus from code. On linux, gecko already uses the glib bindings for battery information on linux (UPowerClient.cpp). Android uses the low level DBus bindings, mainly made for writing language binding systems. This tends to create very complicated code, which even the DBus maintainers warn developers off of (See DBus API Documentation). Even so, due to the dbus-c++ library depending on exceptions (though the Chromium project is working on fixing that) and not wanting to fold in glib to Firefox OS, we'll be using the low-level DBus API for Firefox OS's WebBluetooth layer.

Links

Introduction

Bugzilla

External

Relevant Source Code