VulpesOS/gaia/tv_apps/smart-system/js/bluetooth.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

193 lines
6.3 KiB
JavaScript
Executable file

/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* global SettingsCache, SettingsListener */
'use strict';
var Bluetooth = {
get Profiles() {
return {
HFP: 'hfp', // Hands-Free Profile
OPP: 'opp', // Object Push Profile
A2DP: 'a2dp', // A2DP status
SCO: 'sco' // Synchronous Connection-Oriented
};
},
_setProfileConnected: function bt_setProfileConnected(profile, connected) {
var value = this['_' + profile + 'Connected'];
if (value != connected) {
this['_' + profile + 'Connected'] = connected;
// Raise an event for the profile connection changes.
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('bluetoothprofileconnectionchange',
/* canBubble */ true, /* cancelable */ false,
{
name: profile,
connected: connected
});
window.dispatchEvent(evt);
}
},
isProfileConnected: function bt_isProfileConnected(profile) {
var isConnected = this['_' + profile + 'Connected'];
if (isConnected === undefined) {
return false;
} else {
return isConnected;
}
},
/* this property store a reference of the default adapter */
defaultAdapter: null,
/* keep a global connected property here */
connected: false,
init: function bt_init() {
if (!window.navigator.mozSettings) {
return;
}
if (!window.navigator.mozBluetooth) {
return;
}
var bluetooth = window.navigator.mozBluetooth;
var self = this;
SettingsCache.observe('bluetooth.enabled', true, function(value) {
if (!bluetooth) {
// roll back the setting value to notify the UIs
// that Bluetooth interface is not available
if (value) {
SettingsListener.getSettingsLock().set({
'bluetooth.enabled': false
});
}
return;
}
});
// when bluetooth adapter is ready, emit event to notify QuickSettings
// and try to get defaultAdapter at this moment
bluetooth.onadapteradded = function bt_onAdapterAdded() {
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('bluetooth-adapter-added',
/* canBubble */ true, /* cancelable */ false, null);
window.dispatchEvent(evt);
self.initDefaultAdapter();
};
// if bluetooth is enabled in booting time, try to get adapter now
this.initDefaultAdapter();
// when bluetooth is really disabled, emit event to notify QuickSettings
bluetooth.ondisabled = function bt_onDisabled() {
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('bluetooth-disabled',
/* canBubble */ true, /* cancelable */ false, null);
window.dispatchEvent(evt);
};
/* In file transfering case:
* since System Message can't be listened in two js files within a app,
* so we listen here but dispatch events to bluetooth_transfer.js
* when getting bluetooth file transfer start/complete system messages
*/
navigator.mozSetMessageHandler('bluetooth-opp-transfer-start',
function bt_fileTransferUpdate(transferInfo) {
self._setProfileConnected(self.Profiles.OPP, true);
self.updateConnected();
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('bluetooth-opp-transfer-start',
/* canBubble */ true, /* cancelable */ false,
{transferInfo: transferInfo});
window.dispatchEvent(evt);
}
);
navigator.mozSetMessageHandler('bluetooth-opp-transfer-complete',
function bt_fileTransferUpdate(transferInfo) {
self._setProfileConnected(self.Profiles.OPP, false);
self.updateConnected();
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('bluetooth-opp-transfer-complete',
/* canBubble */ true, /* cancelable */ false,
{transferInfo: transferInfo});
window.dispatchEvent(evt);
}
);
},
// Get adapter for BluetoothTransfer when everytime bluetooth is enabled
initDefaultAdapter: function bt_initDefaultAdapter() {
var bluetooth = window.navigator.mozBluetooth;
var self = this;
if (!bluetooth || !bluetooth.enabled ||
!('getDefaultAdapter' in bluetooth)) {
return;
}
var req = bluetooth.getDefaultAdapter();
req.onsuccess = function bt_gotDefaultAdapter(evt) {
self.defaultAdapter = req.result;
self.initWithAdapter(self.defaultAdapter);
};
},
initWithAdapter: function bt_initWithAdapter(adapter) {
/* for v1, we only support two use cases for bluetooth connection:
* 1. connecting with a headset
* 2. transfering a file to/from another device
* So we need to listen to corresponding events to know we are (aren't)
* connected, then summarize to an event and dispatch to StatusBar
*/
// In headset connected case:
var self = this;
adapter.onhfpstatuschanged = function bt_hfpStatusChanged(evt) {
self._setProfileConnected(self.Profiles.HFP, evt.status);
self.updateConnected();
};
adapter.ona2dpstatuschanged = function bt_a2dpStatusChanged(evt) {
self._setProfileConnected(self.Profiles.A2DP, evt.status);
self.updateConnected();
};
adapter.onscostatuschanged = function bt_scoStatusChanged(evt) {
self._setProfileConnected(self.Profiles.SCO, evt.status);
};
},
updateConnected: function bt_updateConnected() {
var bluetooth = window.navigator.mozBluetooth;
if (!bluetooth || !('isConnected' in bluetooth)) {
return;
}
var wasConnected = this.connected;
this.connected = this.isProfileConnected(this.Profiles.HFP) ||
this.isProfileConnected(this.Profiles.A2DP) ||
this.isProfileConnected(this.Profiles.OPP);
if (wasConnected !== this.connected) {
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('bluetoothconnectionchange',
/* canBubble */ true, /* cancelable */ false,
{deviceConnected: this.connected});
window.dispatchEvent(evt);
}
},
// This function is called by external (BluetoothTransfer) for re-use adapter
getAdapter: function bt_getAdapter() {
return this.defaultAdapter;
}
};
Bluetooth.init();