Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #31247 from dwi2/bug1186301_reland
Browse files Browse the repository at this point in the history
Bug 1186301 - [Stingray] Scanning and display BT devices in Device Deck
  • Loading branch information
KevinGrandon committed Aug 5, 2015
2 parents 23ba264 + 5efc4cc commit 2905411
Show file tree
Hide file tree
Showing 13 changed files with 584 additions and 24 deletions.
6 changes: 3 additions & 3 deletions shared/test/unit/mocks/mock_navigator_moz_bluetooth_v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
onscostatuschanged: null,
onhfpstatuschanged: null,
ona2dpstatuschanged: null,
onrequestmediaplaystatus: null,
onrequestmediaplaystatus: null
};

var mManagerEventListeners = [];
Expand All @@ -71,10 +71,10 @@
});
}

function mmb_triggerEventListeners(type) {
function mmb_triggerEventListeners(type, eventObj) {
mManagerEventListeners.forEach(function(eventListener) {
if (eventListener.type === type) {
eventListener.callback();
eventListener.callback(eventObj);
}
});
}
Expand Down
4 changes: 2 additions & 2 deletions tv_apps/device-deck/bower_components/smart-icons/.bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
"README.md",
"package.json"
],
"_release": "2f16605d7c",
"_release": "096856d7f3",
"_resolution": {
"type": "branch",
"branch": "master",
"commit": "2f16605d7c965c5d801149b9fed6598621342c54"
"commit": "096856d7f3ff97352f5b0a822497f7057de96825"
},
"_source": "git://github.com/smart-components/smart-icons.git",
"_target": "*",
Expand Down
Binary file not shown.

Large diffs are not rendered by default.

19 changes: 9 additions & 10 deletions tv_apps/device-deck/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@
<!-- building blocks -->
<script defer src="bower_components/smart-button/script.js"></script>

<!-- For test purpose on phone only -->
<script defer src="shared/js/gesture_detector.js"></script>
<script defer src="shared/js/smart-screen/init_gesture.js"></script>

<!-- Shared libraries -->
<script defer src="shared/js/smart-screen/shared_utils.js"></script>
<script defer src="shared/js/smart-screen/spatial_navigator.js"></script>
<script defer src="shared/js/smart-screen/key_navigation_adapter.js"></script>

<!-- Specific code -->
<script defer src="js/bluetooth_loader.js"></script>
<script defer src="js/bluetooth_cod_mapper.js"></script>
<script defer src="js/bluetooth_manager.js"></script>
<script defer src="js/device_deck.js"></script>

<!-- Shared L10n libraries -->
Expand All @@ -45,19 +52,11 @@
<section role="region" class="skin-dark" id="grid">
<div id="connected-devices-container" class="devices-container">
<div class="devices-caption" data-l10n-id="connected"></div>
<div id="connected-devices-list" class="devices-list">
<!-- some dummy device icons-->
<smart-button type="app-button" app-type="device" label="Nexus 5" data-icon="phone" class="navigable"></smart-button>
<smart-button type="app-button" app-type="device" label="GamdPad" data-icon="game" class="navigable"></smart-button>
<smart-button type="app-button" app-type="device" label="Keyboard" data-icon="keyboard" class="navigable"></smart-button>
</div>
<div id="connected-devices-list" class="devices-list"></div>
</div>
<div id="newly-found-device-container" class="devices-container">
<div class="devices-caption" data-l10n-id="newly-found"></div>
<div id="newly-found-devices-list" class="devices-list">
<!-- some dummy device icons-->
<smart-button type="app-button" app-type="device" label="BT Speaker" data-icon="speaker" class="navigable"></smart-button>
</div>
<div id="newly-found-devices-list" class="devices-list"></div>
</div>
</section>
</article>
Expand Down
175 changes: 175 additions & 0 deletions tv_apps/device-deck/js/bluetooth_cod_mapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
(function(exports) {
'use strict';

// XXX: this module is copied and modified from
// apps/settings/js/modules/bluetooth/bluetooth_cod_mapper.js
// because it is not exposed as shared library and is in AMD style.
// We might need to consolidate them in the future.
var MinorDeviceClasses = {
Computer: {
0: 'computer', // Uncategorized, code for device not assigned
1: 'computer', // Desktop workstation
2: 'computer', // Server-class computer
3: 'computer', // Laptop
4: 'pda', // Handheld PC/PDA (clamshell)
5: 'pda', // Palm-size PC/PDA
6: 'computer', // Wearable computer (watch size)
7: 'computer', // Tablet
reserved: 'computer' // All other values reserved. Default type
// 'computer' given for reserved case.
},

Phone: {
0: 'phone', // Uncategorized, code for device not assigned
1: 'phone', // Cellular
2: 'phone', // Cordless
3: 'phone', // Smartphone
4: 'modem', // Wired modem or voice gateway
5: 'phone', // Common ISDN access
reserved: 'phone' // All other values reserved. Default type
// 'phone' given for reserved case.
},

AudioVideo: {
0: 'audio-card', // Uncategorized, code not assigned
1: 'audio-card', // Wearable Headset Device
2: 'audio-card', // Hands-free Device
4: 'audio-input-microphone', // Microphone
5: 'audio-card', // Loudspeaker
6: 'audio-card', // Headphones
7: 'audio-card', // Portable Audio
8: 'audio-card', // Car audio
9: 'audio-card', // Set-top box
10: 'audio-card', // HiFi Audio Device
11: 'camera-video', // VCR
12: 'camera-video', // Video Camera
13: 'camera-video', // Camcorder
14: 'video-display', // Video Monitor
15: 'video-display', // Video Display and Loudspeaker
16: 'video-display', // Video Conferencing
18: 'audio-card', // Gameing/Toy
reserved: 'audio-card' // All other values reserved. Default type
// 'audio-card' given for reserved case.
},

Peripheral: {
1: 'input-gaming', // Joystick
2: 'input-gaming', // Gamepad
16: 'input-keyboard', // Keyboard
17: 'input-keyboard', // Keyboard
18: 'input-keyboard', // Keyboard
19: 'input-keyboard', // Keyboard
20: 'input-keyboard', // Keyboard
21: 'input-keyboard', // Keyboard
22: 'input-keyboard', // Keyboard
23: 'input-keyboard', // Keyboard
24: 'input-keyboard', // Keyboard
25: 'input-keyboard', // Keyboard
26: 'input-keyboard', // Keyboard
27: 'input-keyboard', // Keyboard
28: 'input-keyboard', // Keyboard
29: 'input-keyboard', // Keyboard
30: 'input-keyboard', // Keyboard
31: 'input-keyboard', // Keyboard
32: 'input-mouse', // Pointing device
33: 'input-mouse', // Pointing device
34: 'input-mouse', // Pointing device
35: 'input-mouse', // Pointing device
36: 'input-mouse', // Pointing device
37: 'input-tablet', // Digitizer tablet
38: 'input-mouse', // Pointing device
39: 'input-mouse', // Pointing device
40: 'input-mouse', // Pointing device
41: 'input-mouse', // Pointing device
42: 'input-mouse', // Pointing device
43: 'input-mouse', // Pointing device
44: 'input-mouse', // Pointing device
45: 'input-mouse', // Pointing device
46: 'input-mouse', // Pointing device
47: 'input-mouse' // Pointing device
},

Imaging: {
4: 'video-display', // Display, bit: XXX1XX
8: 'camera-photo', // Camera, bit: XX1XXX
16: 'scanner', // Scanner, bit: X1XXXX
32: 'printer' // Printer, bit: 1XXXXX
}
};

var MajorDeviceClasses = {
1: MinorDeviceClasses.Computer,
2: MinorDeviceClasses.Phone,
3: 'network-wireless', // LAN/Network Access Point Major Class
4: MinorDeviceClasses.AudioVideo,
5: MinorDeviceClasses.Peripheral,
6: MinorDeviceClasses.Imaging
};

var DeviceIconTable = {
'computer': 'laptop',
'pda': 'phone',
'phone': 'phone',
'modem': 'bluetooth', // need icon
'audio-card': 'speaker',
'audio-input-microphone': 'mic',
'camera-video': 'recorder',
'video-display': 'tv',
'input-gaming': 'game',
'input-keyboard': 'keyboard',
'input-mouse': 'mouse',
'input-tablet': 'bluetooth', // need icon
'camera-photo': 'bluetooth', // need icon
'scanner': 'bluetooth', // need icon
'printer': 'bluetooth' // need icon
};

exports.BluetoothCodMapper = {
getDeviceType: function btcodm_getDeviceType(cod) {
// Given an empty string to be default type.
// Then, we won't show any icon for empty type.
var deviceType = '';
var majorDeviceClass = MajorDeviceClasses[cod.majorDeviceClass];
if (typeof(majorDeviceClass) === 'object') {
// drop in other Major Class
deviceType = majorDeviceClass[cod.minorDeviceClass] ||
majorDeviceClass.reserved || '';
return deviceType;
} else if (typeof(majorDeviceClass) === 'string') {
// drop in LAN/Network Access Point Major Class
return majorDeviceClass;
} else if (cod.majorServiceClass & 0x100) {
// Not in any Major Device Class which is defined in Gaia.
// Ex: Wearable, Toy, Health.

// Since there is no icon to display wearable, toy, health devices,
// file a bug 1163479[2] to define them for specification needed.
// But some of these devices probably service 'Audio' per Bluetooth
// specification[1].
// Property 'type' may be missed due to CoD of major class is TOY(0x08).
// But we need to assign 'type' as 'audio-card' if service class
// is 'Audio'. This is for PTS test case TC_AG_COD_BV_02_I.
// As HFP specification defines that service class is 'Audio' can
// be considered as HFP HF.
// [1]: HFP_SPEC_V16.pdf: A device implementing the HF role of HFP shall
// set the "Audio" bit in the Service Class field.
// [2]: Bug 1163479 - [Gaia][Bluetooth] Device icon definition for
// wearable, toy, health(Major Device Class) devices.
// (https://bugzilla.mozilla.org/show_bug.cgi?id=1163479)

// Major Service Class: Audio(Speaker, Microphone, Headset service, ...)
deviceType = 'audio-card';
return deviceType;
} else {
// Not in any Class which is defined in Gaia.
return deviceType;
}
},

getIconName: function btcodm_getIconName(cod) {
var humanReadableCod = this.getDeviceType(cod);
return (DeviceIconTable[humanReadableCod] ?
DeviceIconTable[humanReadableCod] : 'bluetooth');
}
};
}(window));
38 changes: 38 additions & 0 deletions tv_apps/device-deck/js/bluetooth_loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
(function (exports) {
'use strict';
exports.BluetoothLoader = {
// on b2g-desktop, we don't have mozBluetooth API, so we inject fake one
// just to make sure we won't break TV build on b2g-desktop
_fakeMozBluetooth: {
addEventListener: function() {},
defaultAdapter: {
_discoveryHandle: {
addEventListener: function() {}
},

state: 'disabled',
enable: function() {
return Promise.resolve();
},
disable: function() {
return Promise.resolve();
},
startDiscovery: function() {
return Promise.resolve(this._discoveryHandle);
},
stopDiscovery: function() {
return Promise.resolve();
}
}
},

getMozBluetooth: function() {
if (navigator.mozBluetooth) {
return navigator.mozBluetooth;
} else {
return this._fakeMozBluetooth;
}
}
};

}(window));
97 changes: 97 additions & 0 deletions tv_apps/device-deck/js/bluetooth_manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* globals evt, BluetoothLoader */
(function(exports) {
'use strict';

var BluetoothManager = function() {};

BluetoothManager.prototype = evt({
_mozBluetooth: undefined,

_defaultAdapter: undefined,

_discoveryHandle: undefined,

_handleDeviceFound: undefined,

_handleBeforeUnload: undefined,

_deviceDeck: undefined,

init: function bm_init() {
this._mozBluetooth = BluetoothLoader.getMozBluetooth();

this._handleDeviceFound = this.onDeviceFound.bind(this);

this._mozBluetooth.addEventListener('attributechanged',
this.onAttributeChanged.bind(this));

this._defaultAdapter = this._mozBluetooth.defaultAdapter;
},

onAttributeChanged: function bm_onAttributeChanged(evt) {
var that = this;
[].forEach.call(evt.attrs, function(attr, index) {
if (attr === 'defaultAdapter') {
that._defaultAdapter = that._mozBluetooth.defaultAdapter;
that.fire('default-adapter-ready');
}
});
},

_keepDiscoveryHandle: function bm_keepDiscoveryHandle(handle) {
this._discoveryHandle = handle;
this._discoveryHandle.addEventListener('devicefound',
this._handleDeviceFound);
},

_startDiscovery: function bm_startDiscovery() {
var that = this;
if (!this._defaultAdapter) {
return Promise.reject('default adapter doesn\'t exist');
}

if (this._defaultAdapter.state !== 'enabled') {
return this._defaultAdapter.enable().then(function() {
return that._defaultAdapter.startDiscovery();
}).then(this._keepDiscoveryHandle.bind(this));
}

return this._defaultAdapter.startDiscovery().then(
this._keepDiscoveryHandle.bind(this));
},

_stopDiscovery: function bm_stopDiscovery() {
if (!this._defaultAdapter) {
return Promise.reject('default adapter doesn\'t exist');
}

// force to stop anyway
return this._defaultAdapter.stopDiscovery();
},

safelyStartDiscovery: function bm_safelyStartDiscovery() {
var that = this;
if (!this._defaultAdapter) {
return new Promise(function(resolve, reject) {
that.on('default-adapter-ready', function() {
resolve(that._startDiscovery());
});
});
}
return this._startDiscovery();
},

safelyStopDiscovery: function bn_safelyStopDiscovery() {
return this._stopDiscovery().catch(function(reason) {
console.warn('failed to stop discovery: ' + reason);
});
},

onDeviceFound: function bm_onDeviceFound(evt) {
var device = evt.device;
this.fire('device-found', device);
}
});

exports.BluetoothManager = BluetoothManager;
}(window));
Loading

0 comments on commit 2905411

Please sign in to comment.