WebAPI/WebBluetooth: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
No edit summary
 
(13 intermediate revisions by one other user not shown)
Line 9: Line 9:
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.
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 v1.3) ===
=== Current Status ===


Until Firefox OS v1.3 (feature complete target on: 2013/12/9), 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.
Firefox OS v2.2 (feature landing target on: 2014/11/24) will adopt refined Bluetooth APIs as listed in [[WebAPI/WebBluetooth#DOM_API|DOM API]] section. Detailed documentation and the latest refinement progress can be found in [[B2G/Bluetooth/WebBluetooth-v2|WebBluetooth-v2]]. In addition, Firefox OS v2.2 will also expose Bluetooth Low Energy (BLE) Generic Attribute Profile (GATT) client APIs to 3rd party web apps. Privileged apps will be able to develop BLE profiles and control customized bluetooth LE devices.


Since the API we have now is too BlueZ-specific, we have already put 'refining Bluetooth API' on the desired feature list of Firefox OS v1.4.
[http://www.w3.org/community/web-bluetooth/ W3C Bluetooth Community Group] is discussing on specification for Bluetooth APIs to allow websites to communicate with devices in a secure and privacy-preserving way. Google has proposed [http://webbluetoothcg.github.io/web-bluetooth/ an intial API] and [https://webbluetoothcg.github.io/web-bluetooth/use-cases.html use cases]. Mozilla also participates in discussion to integrate Firefox OS Bluetooth APIs into the finalized version. See section [[B2G/Bluetooth/WebBluetooth-v2#Google_Bluetooth_APIs|Google Bluetooth APIs]] for more information about Google Bluetooth APIs.


=== DOM API (Until Firefox OS v1.3) ===
=== DOM API (Since Firefox OS 2.2) ===


==== BluetoothManager.webidl ====
==== BluetoothManager.webidl ====
Line 67: Line 67:
  };
  };


  interface BluetoothAdapter : EventTarget
  enum BluetoothAdapterState
  {
  {
   readonly attribute DOMString      address;
   "disabled",
   readonly attribute unsigned long class;
  "disabling",
   readonly attribute boolean        discovering;
  "enabled",
   readonly attribute DOMString      name;
   "enabling"
   readonly attribute boolean        discoverable;
  };
   readonly attribute unsigned long discoverableTimeout; // in seconds
 
   
enum BluetoothAdapterAttribute
  // array of type BluetoothDevice[]
{
  [GetterThrows]
  "unknown",
   readonly attribute any            devices;
   "state",
  "address",
   // array of type DOMString[]
   "name",
  [GetterThrows]
   "discoverable",
   readonly attribute any            uuids;
   "discovering"
  };
            attribute EventHandler  ondevicefound;
 
  [CheckPermissions="bluetooth"]
   // Fired when pairing process is completed
interface BluetoothAdapter : EventTarget {
            attribute EventHandler  onpairedstatuschanged;
   readonly attribute BluetoothAdapterState  state;
   readonly attribute DOMString             address;
   readonly attribute DOMString              name;
  readonly attribute boolean                discoverable;
   readonly attribute boolean                discovering;
   
   
  [AvailableIn=CertifiedApps]
  readonly attribute BluetoothPairingListener pairingReqs;
 
   // Fired when a2dp connection status changed
   // Fired when a2dp connection status changed
             attribute EventHandler  ona2dpstatuschanged;
             attribute EventHandler  ona2dpstatuschanged;
Line 101: Line 108:
             attribute EventHandler  onrequestmediaplaystatus;
             attribute EventHandler  onrequestmediaplaystatus;
   
   
  // Fired when attributes of BluetoothAdapter changed
            attribute EventHandler  onattributechanged;
  // Fired when a remote device gets paired with the adapter
            attribute EventHandler  ondevicepaired;
  // Fired when a remote device gets unpaired from the adapter
            attribute EventHandler  ondeviceunpaired;
  /**
    * Enable/Disable a local bluetooth adapter by asynchronus methods and return
    * its result through a Promise.
    *
    * Several onattributechanged events would be triggered during processing the
    * request, and the last one would indicate adapter.state becomes
    * enabled/disabled.
  */
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest setName(DOMString name);
   Promise<void> enable();
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest setDiscoverable(boolean discoverable);
   Promise<void> disable();
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest setDiscoverableTimeout(unsigned long timeout);
   Promise<void> setName(DOMString aName);
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest startDiscovery();
   Promise<void> setDiscoverable(boolean aDiscoverable);
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest stopDiscovery();
   Promise<BluetoothDiscoveryHandle> startDiscovery();
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest pair(DOMString deviceAddress);
   Promise<void> stopDiscovery();
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest unpair(DOMString deviceAddress);
   Promise<void> Promise pair(DOMString deviceAddress);
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest getPairedDevices();
   Promise unpair(DOMString deviceAddress);
  sequence<BluetoothDevice> getPairedDevices();
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest getConnectedDevices(unsigned short serviceUuid);
   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.
    * Connect/Disconnect to a specific service of a target remote device.
  * To check the value of service UUIDs, please check "Bluetooth Assigned
    * To check the value of service UUIDs, please check "Bluetooth Assigned
  * Numbers" / "Service Discovery Protocol" for more information.
    * Numbers" / "Service Discovery Protocol" for more information.
  *
    *
  * Note that service UUID is optional. If it isn't passed when calling
    * Note that service UUID is optional. If it isn't passed when calling
  * Connect, multiple profiles are tried sequentially based on the class of
    * Connect, multiple profiles are tried sequentially based on the class of
  * device (CoD). If it isn't passed when calling Disconnect, all connected
    * device (CoD). If it isn't passed when calling Disconnect, all connected
  * profiles are going to be closed.
    * profiles are going to be closed.
  *
    *
  * Reply success if the connection of any profile is successfully
    * Reply success if the connection of any profile is successfully
  * established/released; reply error if we failed to connect/disconnect all
    * established/released; reply error if we failed to connect/disconnect all
  * of the planned profiles.
    * of the planned profiles.
  *
    *
  * @param device Remote device
    * @param device Remote device
  * @param profile 2-octets service UUID. This is optional.
    * @param profile 2-octets service UUID. This is optional.
  */
    */
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest connect(BluetoothDevice device, optional unsigned short serviceUuid);
   DOMRequest connect(BluetoothDevice device, optional unsigned short serviceUuid);
Line 165: Line 189:
   DOMRequest isScoConnected();
   DOMRequest isScoConnected();
   
   
  /**
  /**
  * Additional HFP methods to handle CDMA network.
    * Additional HFP methods to handle CDMA network.
  *
    *
  * In GSM network we observe call operations from RIL call state changes;
    * 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
    * 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, so we need these additional methods to be informed of these
  * operations from dialer.
    * operations from dialer.
  *
    *
  * For more information please refer to bug 912005 and 925638.
    * For more information please refer to bug 912005 and 925638.
  */
    */
   [NewObject, Throws]
   [NewObject, Throws]
   DOMRequest answerWaitingCall();
   DOMRequest answerWaitingCall();
Line 191: Line 215:
==== BluetoothDevice.webidl ====
==== BluetoothDevice.webidl ====


[CheckPermissions="bluetooth"]
  interface BluetoothDevice : EventTarget
  interface BluetoothDevice : EventTarget
  {
  {
   readonly attribute DOMString     address;
   readonly attribute DOMString             address;
   readonly attribute DOMString      name;
   readonly attribute BluetoothClassOfDevice cod;
   readonly attribute DOMString     icon;
   readonly attribute DOMString             name;
  readonly attribute boolean        connected;
   readonly attribute boolean               paired;
   readonly attribute boolean       paired;
  readonly attribute unsigned long  class;
   
   
   // array of type DOMString[]
   [Cached, Pure]
  [Throws]
   readonly attribute sequence<DOMString>    uuids;
   readonly attribute any            uuids;
   
   
   // array of type DOMString[]
            attribute EventHandler          onattributechanged;
   [Throws]
   readonly attribute any            services;
   /**
    * Fetch the up-to-date UUID list of each bluetooth service that the device
    * provides and refresh the cache value of attribute uuids if it is updated.
    *
    * If the operation succeeds, the promise will be resolved with up-to-date
    * UUID list which is identical to attribute uuids.
    */
   [NewObject, Throws]
   Promise<sequence<DOMString>>              fetchUuids();
  };
  };


=== Implementation Specifics ===
/*
 
  * Set of attributes that might be changed and reported by attributechanged
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.
  * event.
 
  * Address is not included since it should not be changed once BluetoothDevice
==== DBus Usage and Licensing ====
  * is created.
 
  */
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.
enum BluetoothDeviceAttribute
 
{
==== DBus on Linux and Android ====
  "unknown",
 
  "cod",
There are many ways to access DBus from code. On linux, gecko already uses the glib bindings for battery information on linux ([https://github.com/doublec/mozilla-central/blob/master/hal/linux/UPowerClient.cpp UPowerClient.cpp]).
  "name",
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 [http://dbus.freedesktop.org/doc/api/html/ DBus API Documentation]). Even so, due to the [http://gitorious.org/dbus-cplusplus 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.
  "paired",
 
  "uuids"
=== Links ===
};
 
==== Introduction ====
 
* [https://wiki.mozilla.org/B2G/Bluetooth Bluetooth on Firefox OS]
 
==== Bugzilla ====
 
* {{bug|674737}}
 
==== External ====


* [http://www.freedesktop.org/wiki/IntroductionToDBus DBus Intro]
=== DOM API (Until Firefox OS 2.1) ===
* [http://developer.android.com/guide/topics/wireless/bluetooth.html Android Bluetooth Manual]
Check [[WebAPI/WebBluetooth_(Until_Firefox_OS_2.1)|pre-2.2 DOM API]] if you are interested in WebBluetooth API until Firefox OS v2.1.
* [https://sites.google.com/a/android.com/opensource/projects/bluetooth-faq/android_bluetooth_architecture_10.jpg Android Bluetooth Architecture]
* [http://www.koders.com/info.aspx?c%3DProjectInfo&pid%3DVSUQMUU6D7UTSCHL199PKTHKGC&s%3Dcdef%253asocket Bluetool C++ Bluez Interaction Code]
* [https://sites.google.com/a/android.com/opensource/projects/bluetooth-faq Android Bluetooth FAQ]


==== Relevant Source Code ====
[[Category:Web APIs]]
* [https://github.com/cgjones/android-frameworks-base/blob/gingerbread-b2g/core/jni/ Frameworks JNI Core]
** [https://github.com/cgjones/android-frameworks-base/blob/gingerbread-b2g/core/jni/android_server_BluetoothService.cpp BluetoothService JNI]
** [https://github.com/cgjones/android-frameworks-base/blob/gingerbread-b2g/core/jni/android_server_BluetoothEventLoop.cpp BluetoothEventLoop JNI]
* [https://github.com/mozilla-b2g/android_system_bluetooth/blob/gingerbread/bluedroid/bluetooth.c Bluedroid]

Latest revision as of 23:22, 1 October 2014

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

Firefox OS v2.2 (feature landing target on: 2014/11/24) will adopt refined Bluetooth APIs as listed in DOM API section. Detailed documentation and the latest refinement progress can be found in WebBluetooth-v2. In addition, Firefox OS v2.2 will also expose Bluetooth Low Energy (BLE) Generic Attribute Profile (GATT) client APIs to 3rd party web apps. Privileged apps will be able to develop BLE profiles and control customized bluetooth LE devices.

W3C Bluetooth Community Group is discussing on specification for Bluetooth APIs to allow websites to communicate with devices in a secure and privacy-preserving way. Google has proposed an intial API and use cases. Mozilla also participates in discussion to integrate Firefox OS Bluetooth APIs into the finalized version. See section Google Bluetooth APIs for more information about Google Bluetooth APIs.

DOM API (Since Firefox OS 2.2)

BluetoothManager.webidl

[CheckPermissions="bluetooth"]
interface BluetoothManager: EventTarget
{
  readonly attribute BluetoothAdapter? defaultAdapter;

           attribute EventHandler onattributechanged;
           attribute EventHandler onadapteradded;
           attribute EventHandler onadapterremoved;

  sequence<BluetoothAdapter> getAdapters();
};
enum BluetoothManagerAttribute
{
  "unknown",
  "defaultAdapter"
};

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 = "";
};
enum BluetoothAdapterState
{
  "disabled",
  "disabling",
  "enabled",
  "enabling"
};
enum BluetoothAdapterAttribute
{
  "unknown",
  "state",
  "address",
  "name",
  "discoverable",
  "discovering"
};
[CheckPermissions="bluetooth"]
interface BluetoothAdapter : EventTarget {
  readonly attribute BluetoothAdapterState  state;
  readonly attribute DOMString              address;
  readonly attribute DOMString              name;
  readonly attribute boolean                discoverable;
  readonly attribute boolean                discovering;

  [AvailableIn=CertifiedApps]
  readonly attribute BluetoothPairingListener pairingReqs;
 
  // 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;

  // Fired when attributes of BluetoothAdapter changed
           attribute EventHandler   onattributechanged;

  // Fired when a remote device gets paired with the adapter
           attribute EventHandler   ondevicepaired;

  // Fired when a remote device gets unpaired from the adapter
           attribute EventHandler   ondeviceunpaired;

  /**
   * Enable/Disable a local bluetooth adapter by asynchronus methods and return
   * its result through a Promise.
   *
   * Several onattributechanged events would be triggered during processing the
   * request, and the last one would indicate adapter.state becomes
   * enabled/disabled.
  */
  [NewObject, Throws]
  Promise<void> enable();
  [NewObject, Throws]
  Promise<void> disable();

  [NewObject, Throws]
  Promise<void> setName(DOMString aName);
  [NewObject, Throws]
  Promise<void> setDiscoverable(boolean aDiscoverable);

  [NewObject, Throws]
  Promise<BluetoothDiscoveryHandle> startDiscovery();
  [NewObject, Throws]
  Promise<void> stopDiscovery();

  [NewObject, Throws]
  Promise<void> Promise pair(DOMString deviceAddress);
  [NewObject, Throws]
  Promise unpair(DOMString deviceAddress);

  sequence<BluetoothDevice> getPairedDevices();

  [NewObject, Throws]
  DOMRequest getConnectedDevices(unsigned short serviceUuid);

  /**
   * 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

[CheckPermissions="bluetooth"]
interface BluetoothDevice : EventTarget
{
  readonly attribute DOMString              address;
  readonly attribute BluetoothClassOfDevice cod;
  readonly attribute DOMString              name;
  readonly attribute boolean                paired;

  [Cached, Pure]
  readonly attribute sequence<DOMString>    uuids;

           attribute EventHandler           onattributechanged;

  /**
   * Fetch the up-to-date UUID list of each bluetooth service that the device
   * provides and refresh the cache value of attribute uuids if it is updated.
   *
   * If the operation succeeds, the promise will be resolved with up-to-date
   * UUID list which is identical to attribute uuids.
   */
  [NewObject, Throws]
  Promise<sequence<DOMString>>              fetchUuids();
};
/*
 * Set of attributes that might be changed and reported by attributechanged
 * event.
 * Address is not included since it should not be changed once BluetoothDevice
 * is created.
 */
enum BluetoothDeviceAttribute
{
  "unknown",
  "cod",
  "name",
  "paired",
  "uuids"
};

DOM API (Until Firefox OS 2.1)

Check pre-2.2 DOM API if you are interested in WebBluetooth API until Firefox OS v2.1.