/**
* BluetoothContext:
* - BluetoothContext is an Observable that wraps the platform Bluetooth
* object.
* - BluetoothContext is a singleton that you can easily use it to fetch some
* shared data across different panels.
* - It has some observable properties: state, enabled, address, name,
* discoverable, discovering, numberOfPairedDevices, firstPairedDeviceName,
* hasPairedDevice.
* - It has two observable array: _pairedDevices, _remoteDevices.
* BluetoothContext only update state and does not involve in any UI logic.
*
* @module BluetoothContext
*/
define(function(require) {
'use strict';
var AdapterManager = require('modules/bluetooth/bluetooth_adapter_manager');
var BtDevice = require('modules/bluetooth/bluetooth_device');
var ConnectionManager =
require('modules/bluetooth/bluetooth_connection_manager');
var Observable = require('modules/mvvm/observable');
var ObservableArray = require('modules/mvvm/observable_array');
var SettingsCache = require('modules/settings_cache');
var settings = navigator.mozSettings;
var _debug = false;
var Debug = function() {};
if (_debug) {
Debug = function btc_debug(msg) {
console.log('--> [BluetoothContext]: ' + msg);
};
}
var BluetoothContext = {
/**
* State of Bluetooth default adapter.
* This is an enum of BluetoothAdapterState.
* State: 'disabled', 'disabling', 'enabled', 'enabling'
*
* @readonly
* @memberOf BluetoothContext
* @type {String}
*/
state: 'disabled',
/**
* State of Bluetooth.
*
* @readonly
* @memberOf BluetoothContext
* @type {Boolean}
*/
enabled: false,
/**
* The address of the device's adapter on the bluetooth micro-network.
*
* @readonly
* @memberOf BluetoothContext
* @type {String}
*/
address: null,
/**
* The human readable name of the device's adapter.
*
* @readonly
* @memberOf BluetoothContext
* @type {String}
*/
name: '',
/**
* Indicates if the device is discoverable (true) or not (false)
* by other bluetooth devices.
*
* @readonly
* @memberOf BluetoothContext
* @type {Boolean}
*/
discoverable: false,
/**
* Indicates if the device is in the process of discovering (true) or
* not (false) surrounding bluetooth devices.
*
* @readonly
* @memberOf BluetoothContext
* @type {Boolean}
*/
discovering: false,
/**
* Number of Bluetooth paired devices.
*
* @readonly
* @memberOf BluetoothContext
* @type {Number}
*/
numberOfPairedDevices: 0,
/**
* Device name of Bluetooth paired devices in the first sorting.
*
* @readonly
* @memberOf BluetoothContext
* @type {String}
*/
firstPairedDeviceName: '',
/**
* Indicates if the paired device is in the paired devices list (true) or
* not (false).
*
* @readonly
* @memberOf BluetoothContext
* @type {Boolean}
*/
hasPairedDevice: false,
/**
* Default adapter of Bluetooth.
*
* @access private
* @memberOf BluetoothContext
* @type {BluetoothAdapter}
*/
_defaultAdapter: null,
/**
* Init BluetoothContext module.
*
* @access private
* @memberOf BluetoothContext
*/
_init: function btc__init() {
// Observe 'defaultAdapter' property for reaching default adapter.
AdapterManager.observe('defaultAdapter',
this._onDefaultAdapterChanged.bind(this));
this._onDefaultAdapterChanged(AdapterManager.defaultAdapter);
// Watch 'connecting' event for reaching connecting device.
ConnectionManager.addEventListener('connecting',
this._updateDeviceConnectionInfo.bind(this));
// Watch 'connected' event for reaching connected device.
ConnectionManager.addEventListener('connected',
this._updateDeviceConnectionInfo.bind(this));
// Watch 'disconnected' event for reaching disconnected device.
ConnectionManager.addEventListener('disconnected',
this._updateDeviceConnectionInfo.bind(this));
// Watch 'profileChange' event for reaching device connection profile.
ConnectionManager.addEventListener('profileChanged',
this._updateDeviceConnectionInfo.bind(this));
},
/**
* Init properties from default adapter.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
*/
_initProperties: function btc__initProperties(adapter) {
// init observable properties
this._updateStatus(adapter.state);
this.address = adapter.address;
this.name = adapter.name;
this.discoverable = adapter.discoverable;
this.discovering = adapter.discovering;
},
/**
* Only reset properties since there is no available default adapter.
*
* @access private
* @memberOf BluetoothContext
*/
_resetProperties: function btc__resetProperties() {
this._updateStatus('disabled');
this.address = '';
this.name = '';
this.discoverable = false;
this.discovering = false;
},
/**
* Watch 'attributechanged' event from default adapter for updating
* enabled/disabled status immediately.
*
* Description of 'attributechanged' event:
* A handler to trigger when one of the local bluetooth adapter's properties
* has changed. Note access to the changed property in this event handler
* would get the updated value.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
*/
_watchDefaultAdapterAttributechanged:
function btc__watchDefaultAdapterAttributechanged(adapter) {
adapter.addEventListener('attributechanged',
this._onAdapterAttributeChanged.bind(this, adapter));
},
/**
* Unwatch 'attributechanged' event from default adapter since adapter is
* removed.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
*/
_unwatchDefaultAdapterAttributechanged:
function btc__unwatchDefaultAdapterAttributechanged(adapter) {
adapter.removeEventListener('attributechanged',
this._onAdapterAttributeChanged);
},
/**
* Watch 'ondevicepaired' event from default adapter for updating paired
* device immediately.
*
* Description of 'ondevicepaired' event:
* A handler to trigger when a remote device gets paired with local
* bluetooth adapter.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
*/
_watchDefaultAdapterOndevicepaired:
function btc__watchDefaultAdapterOndevicepaired(adapter) {
adapter.ondevicepaired =
this._onAdapterDevicepaired.bind(this, adapter);
},
/**
* Unwatch 'ondevicepaired' event from default adapter since adapter is
* removed.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
*/
_unwatchDefaultAdapterOndevicepaired:
function btc__unwatchDefaultAdapterOndevicepaired(adapter) {
adapter.ondevicepaired = null;
},
/**
* Watch 'ondeviceunpaired' event from default adapter for updating unpaired
* device immediately.
*
* Description of 'ondeviceunpaired' event:
* A handler to trigger when a remote device gets unpaired from local
* bluetooth adapter.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
*/
_watchDefaultAdapterOndeviceunpaired:
function btc__watchDefaultAdapterOndeviceunpaired(adapter) {
adapter.ondeviceunpaired =
this._onAdapterDeviceunpaired.bind(this, adapter);
},
/**
* Unwatch 'ondeviceunpaired' event from default adapter since adapter is
* removed.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
*/
_unwatchDefaultAdapterOndeviceunpaired:
function btc__unwatchDefaultAdapterOndeviceunpaired(adapter) {
adapter.ondeviceunpaired = null;
},
/**
* 'attributechanged' event handler from default adapter for updating
* latest BluetoothContext information.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
* @param {event} evt
*/
_onAdapterAttributeChanged:
function btc__onAdapterAttributeChanged(adapter, evt) {
for (var i in evt.attrs) {
Debug('--> _onAdapterAttributeChanged(): ' + evt.attrs[i]);
switch (evt.attrs[i]) {
case 'state':
this._updateStatus(adapter.state);
if (adapter.state === 'enabled') {
// Init paired device information while Bluetooth is enabled.
this._refreshPairedDevicesInfo(adapter);
// Manually start discovery while the adapter state
// is already enabled.
this.startDiscovery();
}
break;
case 'address':
this.address = adapter.address;
break;
case 'name':
this.name = adapter.name;
break;
case 'discoverable':
this.discoverable = adapter.discoverable;
break;
case 'discovering':
this.discovering = adapter.discovering;
break;
default:
break;
}
}
},
/**
* 'ondevicepaired' event handler from default adapter for updating paired
* device in remote/paired devices list.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
* @param {event} evt
*/
_onAdapterDevicepaired:
function btc__onAdapterDevicepaired(adapter, evt) {
Debug('_onAdapterDevicepaired evt = ' + evt);
// have to get device object in this event handler
// Ex. evt.device --> device
// Remove the paired device from remote devices list.
this._removeItemFromList(this._remoteDevices, evt.device.address);
// Instead of adding the paired device in paired devices list,
// get paired devices from adapter directly.
this._refreshPairedDevicesInfo(adapter);
},
/**
* 'ondeviceunpaired' event handler from default adapter for updating
* unpaired device in remote/paired devices list.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
* @param {event} evt
*/
_onAdapterDeviceunpaired:
function btc__onAdapterDeviceunpaired(adapter, evt) {
Debug('_onAdapterDeviceunpaired evt = ' + evt);
// have to get the device address in this event handler Ex. evt -> address
// Instead of removing the paired device from paired devices list,
// get paired devices from adapter directly.
this._refreshPairedDevicesInfo(adapter);
},
/**
* 'defaultAdapter' change event handler from adapter manager for
* watch/unwatch default adapter relative event immediately.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} newAdapter
* @param {BluetoothAdapter} oldAdapter
*/
_onDefaultAdapterChanged:
function btc__onDefaultAdapterChanged(newAdapter, oldAdapter) {
Debug('_onDefaultAdapterChanged(): newAdapter = ' + newAdapter);
Debug('_onDefaultAdapterChanged(): oldAdapter = ' + oldAdapter);
// save default adapter
this._defaultAdapter = newAdapter;
if (oldAdapter) {
// unwatch event since the old adapter is no longer usefull
this._unwatchDefaultAdapterAttributechanged(oldAdapter);
this._unwatchDefaultAdapterOndeviceunpaired(oldAdapter);
this._unwatchDefaultAdapterOndevicepaired(oldAdapter);
}
if (newAdapter) {
// watch event since the new adapter is ready to access
this._initProperties(newAdapter);
this._watchDefaultAdapterAttributechanged(newAdapter);
this._watchDefaultAdapterOndevicepaired(newAdapter);
this._watchDefaultAdapterOndeviceunpaired(newAdapter);
// init paired device information while Bluetooth is enabled
if (newAdapter.state === 'enabled') {
this._refreshPairedDevicesInfo(newAdapter);
}
} else {
// reset properties only
this._resetProperties();
}
},
/**
* Refresh paired devices information.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothAdapter} adapter
*/
_refreshPairedDevicesInfo: function btc__refreshPairedDevicesInfo(adapter) {
var pairedDevices = adapter.getPairedDevices();
Debug('pairedDevices.length = ' + pairedDevices.length);
// reset paired devices list
this._pairedDevices.reset([]);
// refresh properties about paired devices
if (pairedDevices.length === 0) {
// reset the name
this.firstPairedDeviceName = '';
// update property 'hasPairedDevice'
this.hasPairedDevice = false;
} else {
// sort paired devices
pairedDevices.sort(function(a, b) {
return a.name > b.name;
});
// save paired devices in list
for (var i in pairedDevices) {
// create observable BtDevice
var observableBtDevice = BtDevice(pairedDevices[i]);
// push device in devices list with observable object
this._pairedDevices.push(observableBtDevice);
}
// set the name
this.firstPairedDeviceName = this._pairedDevices.get(0).name;
// update property 'hasPairedDevice'
this.hasPairedDevice = true;
// Update connection status and profile for these paired devices.
this._initConnectingDevices();
this._initConnectedDevices();
}
this.numberOfPairedDevices = pairedDevices.length;
},
/**
* Since we have three properties which are relative with hardware status,
* update them via this method here.
* Update status, enabled, settings key 'bluetooth.enabled'
* The input state would be {'disabled', 'disabling', 'enabled', 'enabling'}
*
* @access private
* @memberOf BluetoothContext
* @param {String} state
*/
_updateStatus: function btc__updateStatus(state) {
// Wrapper state to enabled/disabled toggle state.
var enabled;
if (state === 'enabled' || state === 'disabling') {
enabled = true;
} else if (state === 'disabled' || state === 'enabling') {
enabled = false;
}
// Update state
this.state = state;
Debug('_updateStatus(): set state = ' + state);
// Update enabled
this.enabled = enabled;
Debug('_updateStatus(): set enabled = ' + enabled);
// Sync with settings key
this._syncWithSettingsKey(enabled);
},
/**
* The function provides to set booleans to update the 'bluetooth.enabled'
* settings key if the value is not sync.
*
* @access private
* @memberOf BluetoothContext
* @param {Boolean} enabled
*/
_syncWithSettingsKey: function btc__syncWithSettingsKey(enabled) {
SettingsCache.getSettings((results) => {
var btEnabled = results['bluetooth.enabled'];
if (btEnabled !== enabled) {
settings.createLock().set({'bluetooth.enabled': enabled});
}
});
},
/**
* Set Bluetooth enable/disable.
*
* @access public
* @memberOf BluetoothContext
* @param {Boolean} enabled
* @returns {Promise}
*/
setEnabled: function btc_setEnabled(enabled) {
Debug('setEnabled(): request set enabled = ' + enabled);
if ((this.enabled === enabled) ||
(this.state === 'enabling') ||
(this.state === 'disabling')) {
return Promise.reject('state transition!!');
}
if (!this._defaultAdapter) {
return Promise.reject('default adapter is not existed!!');
}
if (enabled) {
return this._defaultAdapter.enable().then(() => {
Debug('setEnabled(): set enable successfully :)');
}, (reason) => {
Debug('setEnabled(): set enable failed: reason = ' + reason);
return Promise.reject(reason);
});
} else {
return this._defaultAdapter.disable().then(() => {
Debug('setEnabled(): set disable successfully :)');
}, (reason) => {
Debug('setEnabled(): set disable failed: reason = ' + reason);
return Promise.reject(reason);
});
}
},
/**
* Set Bluetooth discoverable.
*
* @access public
* @memberOf BluetoothContext
* @param {Boolean} enabled
* @returns {Promise}
*/
setDiscoverable: function btc_setDiscoverable(enabled) {
if ((this.discoverable === enabled) || (this.state !== 'enabled')) {
return Promise.reject('same state or Bluetooth is disabled!!');
}
if (!this._defaultAdapter) {
return Promise.reject('default adapter is not existed!!');
}
return this._defaultAdapter.setDiscoverable(enabled).then(() => {
Debug('setDiscoverable(): set discoverable ' +
enabled + ' successfully :)');
}, (reason) => {
Debug('setDiscoverable(): set discoverable failed: ' +
'reason = ' + reason);
return Promise.reject(reason);
});
},
/**
* Set adapter name.
*
* @access public
* @memberOf BluetoothContext
* @param {String} name
* @returns {Promise}
*/
setName: function btc_setName(name) {
if (name === this.name) {
return Promise.reject('same name!!');
}
if (!this._defaultAdapter) {
return Promise.reject('default adapter is not existed!!');
}
return this._defaultAdapter.setName(name).then(() => {
Debug('setName(): set name successfully :) name = ' +
this._defaultAdapter.name);
}, (reason) => {
Debug('setName(): set name failed: reason = ' + reason);
return Promise.reject(reason);
});
},
/**
* Set adapter name by product model.
*
* @access public
* @memberOf BluetoothContext
*/
setNameByProductModel: function btc_setNameByProductModel() {
// Bug 847459: Default name of the bluetooth device is set by bluetoothd
// to the value of the Android ro.product.model property upon first
// start. In case the user gives an empty bluetooth device name, we want
// to revert to the original ro.product.model. Gecko exposes it under
// the deviceinfo.product_model setting.
SettingsCache.getSettings((results) => {
var productModel = results['deviceinfo.product_model'];
Debug('setNameByProductModel(): productModel = ' + productModel);
this.setName(productModel);
});
},
/**
* An observable array to maintain paired devices which are just found out.
*
* @access private
* @memberOf BluetoothContext
* @type {ObservableArray}
*/
_pairedDevices: ObservableArray([]),
/**
* An observable array to maintain remote devices which are just found out.
*
* @access private
* @memberOf BluetoothContext
* @type {ObservableArray}
*/
_remoteDevices: ObservableArray([]),
/**
* An handler to handle 'ondevicefound' event. Then, we can save and update
* found device in the remote devices array.
*
* @access private
* @memberOf BluetoothContext
* @type {Function}
*/
_discoveryHandler: null,
/**
* The method makes the device's adapter start seeking for remote devices.
* The discovery process may be terminated after discovering a period of
* time. If the startDiscovery operation succeeds, an onattributechanged
* event would be triggered before the Promise is resolved to indicate
* property discovering becomes true.
*
* @access public
* @memberOf BluetoothContext
* @type {Function}
* @returns {Promise}
*/
startDiscovery: function btc_startDiscovery() {
if ((this.discovering === true) || (this.state !== 'enabled')) {
return Promise.reject('same state or Bluetooth is disabled!!');
}
// clean up found devices list
this._remoteDevices.reset([]);
if (!this._defaultAdapter) {
return Promise.reject('default adapter is not existed!!');
}
return this._defaultAdapter.startDiscovery().then((handle) => {
Debug('startDiscovery(): startDiscovery successfully :)');
// Keep reference to handle in order to listen to
// ondevicefound event handler
this._setDiscoveryHandler(handle);
}, (reason) => {
Debug('startDiscovery(): startDiscovery failed: ' +
'reason = ' + reason);
return Promise.reject(reason);
});
},
/**
* The method makes the device's adapter stop seeking for remote devices.
* This is an asynchronous method and its result is returned via a Promise.
* If the stopDiscovery operation succeeds, an onattributechanged would be
* triggered before the Promise is resolved to indicate property discovering
* becomes false. Note adapter may still receive
* BluetoothDiscoveryHandle.ondevicefound event until the Promise is
* resolved.
*
* @access public
* @memberOf BluetoothContext
* @type {Function}
* @returns {Promise}
*/
stopDiscovery: function btc_stopDiscovery() {
if (this.discovering === false) {
Debug('stopDiscovery(): stopDiscovery successfully in same state :)');
return Promise.resolve('same state');
}
if (this.state !== 'enabled') {
return Promise.reject('Bluetooth is disabled!!');
}
if (!this._defaultAdapter) {
return Promise.reject('default adapter is not existed!!');
}
return this._defaultAdapter.stopDiscovery().then(() => {
Debug('stopDiscovery(): stopDiscovery successfully :)');
}, (reason) => {
Debug('stopDiscovery(): stopDiscovery failed: reason = ' + reason);
return Promise.reject(reason);
});
},
/**
* A function to receive BluetoothDiscoveryHandle. And set a function to
* handle 'ondevicefound' event.
*
* @access private
* @memberOf BluetoothContext
* @param {BluetoothDiscoveryHandle} handle
*/
_setDiscoveryHandler: function btc__setDiscoveryHandler(handle) {
Debug('_setDiscoveryHandler(): handle = ' + handle);
// make the code base easy to do unit test
this._discoveryHandler = handle;
this._discoveryHandler.ondevicefound = this._onDeviceFound.bind(this);
},
/**
* Handle 'ondevicefound' event to access remote device in list with
* observable object.
*
* @access private
* @memberOf BluetoothContext
* @param {Object} evt
*/
_onDeviceFound: function btc__onDeviceFound(evt) {
// save device
this._saveDevice(evt.device);
},
/**
* To distinguish between paired and unpaired.
* Then, save/update the device in list corresponding to the state of
* property paired.
*
* @access private
* @memberOf BluetoothContext
* @param {Observable} device
*/
_saveDevice: function btc__saveDevice(device) {
// Find the device is existed in devices list or not.
var existedDevice =
this._findDeviceByAddress({
paired: device.paired,
address: device.address
});
// If the device is not existed yet, create observable object
// for saving this device.
if (!existedDevice) {
// create observable BtDevice
var observableBtDevice = BtDevice(device);
// push device in devices list with observable object
var operatingDevices =
(device.paired) ? this.getPairedDevices() : this.getRemoteDevices();
operatingDevices.push(observableBtDevice);
} else {
// The device is existed, no need to do any thing here.
// set device in devices list
// operatingDevices.set(index, device);
}
},
/**
* Given an observable arrry and item address. The function will remove it,
* if it's existed in the array.
*
* @access private
* @memberOf BluetoothContext
* @param {ObservableArray} list
* @param {String} address
*/
_removeItemFromList: function btc__removeItemFromList(list, address) {
// check the device is existed or not in remote/paired devices array
var index =
list.array.findIndex(this._matchDeviceByAddress.bind(this, address));
if (index > -1) {
// The device is existed, remove it from observable list.
list.splice(index, 1);
Debug('_removeItemFromList(): index = ' + index);
} else {
// The device is not existed, no need to do any thing here.
}
},
/**
* Given paired, address properties to find out device element
* from remote/paired devices list.
*
* @access private
* @memberOf BluetoothContext
* @param {Object} options
* @param {String} options.paired - is paired or not
* @param {String} options.address - the address of the device
* @return {Object} device
*/
_findDeviceByAddress:
function btc__findDeviceByAddress(options) {
// Distinguish to find the specific device in remote/paired devices list.
var operatingDevices =
(options.paired) ? this.getPairedDevices() : this.getRemoteDevices();
// Check the device is existed or not in remote/paired devices array.
var index = operatingDevices.array.findIndex(
this._matchDeviceByAddress.bind(this, options.address));
if (index > -1) {
return operatingDevices.get(index);
} else {
return null;
}
},
/**
* Given address to find out device element from array.
*
* @access private
* @memberOf BluetoothContext
* @param {String} address
* @param {BluetoothDevice} btDevice
* @return {Boolean}
*/
_matchDeviceByAddress:
function btc__matchDeviceByAddress(address, btDevice) {
return btDevice.address && (btDevice.address === address);
},
/**
* Return paired devices list which is maintained in BluetoothContext.
*
* @access public
* @memberOf BluetoothContext
* @return {ObservableArray}
*/
getPairedDevices: function btc_getPairedDevices() {
return this._pairedDevices;
},
/**
* Return remote devices list which is maintained in BluetoothContext.
*
* @access public
* @memberOf BluetoothContext
* @return {ObservableArray}
*/
getRemoteDevices: function btc_getRemoteDevices() {
return this._remoteDevices;
},
/**
* The method starts pairing a remote device with the device's adapter.
*
* @access public
* @memberOf BluetoothContext
* @param {String} address
* @returns {Promise}
*/
pair: function btc_pair(address) {
if (!this._defaultAdapter) {
return Promise.reject('default adapter is not existed!!');
}
// Note on Bluedroid stack, discovery has to be stopped before pairing
// (i.e., call stopDiscovery() before pair()) otherwise stack callbacks
// with pairing failure.
return this.stopDiscovery().then(() => {
return this._defaultAdapter.pair(address).then(() => {
Debug('pair(): Resolved with void value');
}, (reason) => {
Debug('pair(): Reject with this reason: ' + reason);
return Promise.reject(reason);
});
}, (reason) => {
return Promise.reject(reason);
});
},
/**
* The method starts unpairs a remote device with the device's adapter.
*
* @access public
* @memberOf BluetoothContext
* @param {String} address
* @returns {Promise}
*/
unpair: function btc_unpair(address) {
if (!this._defaultAdapter) {
return Promise.reject('default adapter is not existed!!');
}
return this._defaultAdapter.unpair(address).then(() => {
Debug('unpair(): Resolved with void value');
}, (reason) => {
Debug('unpair(): Reject with this reason: ' + reason);
return Promise.reject(reason);
});
},
/**
* The method starts sending file to a remote device with the device's
* adapter.
*
* @access public
* @memberOf BluetoothContext
* @param {String} address - address of target device
* @param {Object} blob - blob(file) to send
* @returns {Promise}
*/
sendFile: function btc_sendFile(address, blob) {
if (!this._defaultAdapter) {
return Promise.reject('default adapter is not existed!!');
}
return this._defaultAdapter.sendFile(address, blob).then(() => {
Debug('sendFile(): Resolved with void value');
}, (reason) => {
Debug('sendFile(): Reject with this reason: ' + reason);
return Promise.reject(reason);
});
},
/**
* Init the connecting device which is browsed in paired devices list.
* Get connection info from ConnectionManager.
*
* @access private
* @memberOf BluetoothContext
*/
_initConnectingDevices: function btc__initConnectingDevices() {
// Init the paired device connection status for connecting device.
if (!ConnectionManager.connectingAddress) {
return;
}
var existedDevice =
this._findDeviceByAddress({
paired: true,
address: ConnectionManager.connectingAddress
});
if (existedDevice) {
// The connecting device is existed. Init connection status for it.
var options = {
connectionStatus: 'connecting'
};
Debug('_initConnectingDevices(): options = ' + JSON.stringify(options));
existedDevice.updateConnectionInfo(options);
}
},
/**
* Init the connected device which is browsed in paired devices list.
* Get connection info from ConnectionManager.
*
* @access private
* @memberOf BluetoothContext
*/
_initConnectedDevices: function btc__initConnectedDevices() {
// Init the connection status of paired device for connected device.
ConnectionManager.getConnectedDevices().then((connectedDevices) => {
for (var address in connectedDevices) {
var existedDevice =
this._findDeviceByAddress({paired: true, address: address});
if (existedDevice) {
// The connected device is existed.
// Init connection status/profiles for it.
var options = {
connectionStatus: 'connected',
profiles: connectedDevices[address].connectedProfiles
};
Debug('_initConnectedDevices(): address = ' + address +
', options = ' + JSON.stringify(options));
existedDevice.updateConnectionInfo(options);
}
}
}, (reason) => {
Debug('_initConnectedDevices(): getConnectedDevices(): failed, ' +
'reason = ' + reason);
});
},
/**
* Device 'connecting', 'connected', 'disconnected', and 'profiles'
* properties are changed from ConnectionManager operation.
* Update device properties of connection info via event 'type', 'detail'.
*
* @access private
* @memberOf BluetoothContext
* @param {Object} event
* @param {String} event.type - type of event name
* @param {Object} event.detail - device info in this object
* @param {Object} event.detail.address - address of device
* @param {Object} event.detail.profiles - connection profiles of device
*/
_updateDeviceConnectionInfo:
function btc__updateDeviceConnectionInfo(event) {
Debug('_updateDeviceConnectionInfo(): event = ' + JSON.stringify(event));
var existedDevice =
this._findDeviceByAddress(
{paired: true, address: event.detail.address});
if (existedDevice) {
// The device is existed, update device info by event type.
var options;
switch (event.type) {
case 'connecting':
case 'connected':
case 'disconnected':
options = {
connectionStatus: event.type
};
break;
case 'profileChanged':
options = {
profiles: event.detail.profiles
};
break;
default:
break;
}
Debug('_updateDeviceConnectionInfo(): options = ' +
JSON.stringify(options));
existedDevice.updateConnectionInfo(options);
} else {
// If the device is not existed yet, do nothing here.
}
}
};
// Create the observable object using the prototype.
var bluetoothContext = Observable(BluetoothContext);
bluetoothContext._init();
return bluetoothContext;
});