VulpesOS/gaia/apps/bluetooth/js/views/pair_view.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

219 lines
6.6 KiB
JavaScript
Executable file

/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* global getTruncated */
/* exported Pairview */
'use strict';
var Pairview = {
/**
* flag for debugging.
*/
_debug: false,
/**
* remote device name to pair with.
*/
_remoteDeviceName: null,
/**
* device authentication method
*/
_pairMethod: null,
/**
* event handler of pairing request
*/
_options: null,
_passkey: '',
pairview: document.getElementById('pair-view'),
nameLabel: document.getElementById('label-name'),
pairDescription: document.getElementById('pair-description'),
pairButton: document.getElementById('button-pair'),
closeButton: document.getElementById('button-close'),
comfirmationItem: document.getElementById('confirmation-method'),
pinInputItem: document.getElementById('pin-input-method'),
passkey: document.getElementById('passkey'),
pinInput: document.getElementById('pin-input'),
get isFullAttentionMode() {
return (window.innerHeight > 200);
},
show: function pv_show() {
if (!this.isFullAttentionMode) {
this.close();
return;
}
var _ = navigator.mozL10n.get;
this.pairButton.addEventListener('click', this);
this.closeButton.addEventListener('click', this);
window.addEventListener('resize', this);
this._remoteDeviceName = this._remoteDeviceName || _('unnamed-device');
var truncatedDeviceName = getTruncated(this._remoteDeviceName, {
node: this.nameLabel,
maxLine: 2,
ellipsisIndex: 3
});
this.nameLabel.textContent = truncatedDeviceName;
this.pairview.hidden = false;
// Since pairing process is migrated from Settings app to Bluetooth app,
// there is no way to identify the pairing request in active/passive mode.
// In order to let the pairing messsage consistency,
// given the pairing mode to be passive.
var stringName = 'passive-pair-' + this._pairMethod;
this.pairDescription.textContent =
_(stringName, {device: truncatedDeviceName});
switch (this._pairMethod) {
case 'displaypasskey':
case 'confirmation':
this.passkey.textContent = this._passkey;
this.comfirmationItem.hidden = false;
this.pinInputItem.hidden = true;
break;
case 'enterpincode':
this.pinInputItem.hidden = false;
this.comfirmationItem.hidden = true;
this.pinInput.focus();
break;
case 'consent':
this.comfirmationItem.hidden = false;
this.pinInputItem.hidden = true;
break;
}
},
/**
* It is used to init pairing information in this pair view.
*
* @memberOf Pairview
* @access public
* @param {String} method - method of this pairing request
* @param {Object} options
* @param {String} options.deviceName - name of the remote bluetooth device
* @param {BluetoothPairingHandle} options.handle - property handle that
carries specific method
to reply by user.
*/
init: function pv_init(method, options) {
this._pairMethod = method;
this._options = options;
this._remoteDeviceName = options.deviceName;
if (options.handle && options.handle.passkey) {
var passkey = options.handle.passkey;
var len = passkey.toString().length;
var zeros = (len < 6) ? (new Array((6 - len) + 1)).join('0') : '';
this._passkey = zeros + passkey;
}
// show() only until the page is localized.
navigator.mozL10n.once(Pairview.show.bind(Pairview));
},
close: function pv_close() {
// Since user clicked close button, we reject pairing request.
// Because the reject() interface of pairing requests are same, we do same
// operation here.
this._options.handle.reject().then(() => {
this.debug('Resolved in reject ' + this._pairMethod + ' request.');
// Close window by self.
window.close();
}, (aReason) => {
this.debug('Rejected in reject ' + this._pairMethod +
' request with reason: ' + aReason);
// Close window by self.
window.close();
});
},
closeInput: function pv_closeInput() {
if (!this.pinInputItem.hidden) {
this.pinInput.blur();
}
},
handleEvent: function pv_handleEvent(evt) {
var _ = navigator.mozL10n.get;
if (!evt.target) {
return;
}
switch (evt.type) {
case 'click':
evt.preventDefault();
switch (evt.target.id) {
case 'button-pair':
this.pairDescription.textContent = _('device-status-waiting');
this.pairButton.disabled = true;
this.closeButton.disabled = true;
switch (this._pairMethod) {
case 'displaypasskey':
// Do nothing here since the pairing method display passkey only
// Close window by self.
window.close();
break;
case 'enterpincode':
var pinCode = this.pinInput.value;
this._options.handle.setPinCode(pinCode).then(() => {
this.debug('Resolved setPinCode operation');
// Close window by self.
window.close();
}, (aReason) => {
this.debug('Rejected setPinCode with reason: ' + aReason);
// Close window by self.
window.close();
});
break;
case 'confirmation':
case 'consent':
this._options.handle.accept().then(() => {
this.debug('Resolved in ' + this._pairMethod + ' request');
// Close window by self.
window.close();
}, (aReason) => {
this.debug('Rejected in ' + this._pairMethod + ' request ' +
' with reason: ' + aReason);
// Close window by self.
window.close();
});
break;
}
break;
case 'button-close':
this.close();
break;
}
break;
case 'resize':
// XXX: this is hack that we have to close the attention in this case,
// while in most other cases, we would just change it into an active
// status bar
if (!this.isFullAttentionMode) {
this.close();
}
break;
default:
break;
}
},
debug: function(msg) {
if (this._debug) {
console.log('Pairview(): ' + msg);
}
}
};