VulpesOS/gaia/shared/js/smart-screen/channel_manager.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

244 lines
6.4 KiB
JavaScript
Executable file

/* global evt */
'use strict';
(function(exports) {
function ChannelManager(tunerId) {
this.isReady = false;
this.currentTuners = {};
this.playingState = {
tunerId: tunerId || null,
sourceType: null,
channelNumber: null
};
}
var proto = Object.create(new evt());
// Current hash
Object.defineProperty(proto, 'currentHash', {
get: function() {
var state = this.playingState;
var currentHash = '#';
currentHash += state.tunerId;
currentHash += (',' + state.sourceType);
currentHash += (',' + state.channelNumber);
return currentHash;
}
});
proto.getTuner = function cm_getTuner(tunerId) {
tunerId = tunerId || this.playingState.tunerId;
return this.currentTuners[tunerId];
};
proto.getSource = function cm_getSource(sourceType) {
sourceType = sourceType || this.playingState.sourceType;
var tuner = this.getTuner();
if (!tuner || !tuner.sources) {
return null;
}
return tuner.sources[sourceType];
};
proto.getChannel = function cm_getChannel(channelNumber) {
channelNumber = channelNumber || this.playingState.channelNumber;
var source = this.getSource();
if (!source || !source.channelIndexHash) {
return null;
}
var index = source.channelIndexHash[channelNumber];
return source.channels[index];
};
/**
* Fetch tuner, source and channel settings from URL hash.
*/
proto.fetchSettingFromHash = function cm_fetchSettingFromHash(hash) {
if(hash) {
hash = hash.substring(1).split(',');
this.playingState = {
tunerId: hash[0],
sourceType: hash[1],
channelNumber: hash[2]
};
}
};
/**
* Retrieve all the currently available TV tuners.
*/
proto.scanTuners = function cm_scanTuners() {
navigator.tv.getTuners().then(function onsuccess(tuners) {
this.currentTuners = {};
tuners.forEach(function initTuner(tuner) {
this.currentTuners[tuner.id] = {
tuner: tuner,
sources: {}
};
}.bind(this));
if (!this.playingState.tunerId) {
this.playingState.tunerId = tuners[0].id;
}
if (!this.getTuner()) {
this.fire('error');
return;
}
this.scanSources();
}.bind(this));
};
/**
* Retrieve all the currently available TV sources from current TV tuner.
*/
proto.scanSources = function cm_scanSources() {
var tunerItem = this.getTuner();
tunerItem.tuner.getSources().then(function getSources(sources) {
tunerItem.sources = {};
if (sources.length === 0) {
console.error('Error, no source found!');
return;
}
sources.forEach(function initSource(source) {
tunerItem.sources[source.type] = {
source: source,
channels: [],
channelIndexHash: {}
};
}.bind(this));
if (!this.playingState.sourceType) {
if (tunerItem.tuner.currentSource) {
this.playingState.sourceType = tunerItem.tuner.currentSource.type;
} else {
this.playingState.sourceType = sources[0].type;
}
}
if (!this.getSource()) {
this.fire('error');
return;
}
this.scanChannels();
}.bind(this));
};
/**
* Retrieve all the currently available TV channels from current TV source.
* We have to scan the channels before calling getChannels.
*/
proto.scanChannels = function cm_scanChannels() {
var sourceItem = this.getSource();
sourceItem.source.getChannels().then(function onsuccess(channels) {
sourceItem.channels = [];
sourceItem.channelIndexHash = {};
if (channels.length === 0) {
console.error('Error, no channel found!');
return;
}
var i;
for (i = 0; i < channels.length; i++) {
sourceItem.channelIndexHash[channels[i].number] = i;
sourceItem.channels[i] = {
channel: channels[i],
programs: [],
};
}
if (!this.playingState.channelNumber) {
if (sourceItem.source.currentChannel) {
this.playingState.channelNumber =
sourceItem.source.currentChannel.number;
} else {
this.playingState.channelNumber = channels[0].number;
}
}
if (!this.getChannel()) {
this.fire('error');
return;
}
this.isReady = true;
this.fire('scanned');
}.bind(this), function onerror(error) {
console.error(error);
});
};
proto.setPlayingSource = function cm_setPlayingSource(callback) {
var tunerItem = this.getTuner();
if (tunerItem.tuner.currentSource === this.getSource().source) {
this.setPlayingChannel(callback);
return;
}
tunerItem.tuner.setCurrentSource(this.playingState.sourceType)
.then(function() {
this.setPlayingChannel(callback);
}.bind(this), function() {
console.error('Source not found');
});
};
proto.setPlayingChannel = function cm_setPlayingChannel(callback) {
if (this.getSource().source.isScanning) {
if (callback) {
callback();
}
console.error('Source is still scanning.');
return;
}
this.getSource().source.setCurrentChannel(this.playingState.channelNumber)
.then(function() {
if (callback) {
callback();
}
}.bind(this), function() {
console.error('Channel not found');
});
};
proto.switchChannel = function cm_switchChannel(direction) {
if (!this.getChannel() || !this.isReady) {
return false;
}
var channelList = this.getSource().channels;
var channelIndex = this.getSource()
.channelIndexHash[this.playingState.channelNumber];
if (channelIndex!== 0 && !channelIndex) {
return false;
}
switch(direction) {
case ChannelManager.KEY_UP:
channelIndex++;
break;
case ChannelManager.KEY_DOWN:
channelIndex--;
break;
default:
return;
}
channelIndex = (channelIndex < 0) ? channelList.length - 1 : channelIndex;
channelIndex = (channelIndex > channelList.length - 1) ? 0 : channelIndex;
this.playingState.channelNumber = channelList[channelIndex].channel.number;
return true;
};
ChannelManager.KEY_UP = 'up';
ChannelManager.KEY_DOWN = 'down';
ChannelManager.prototype = proto;
exports.ChannelManager = ChannelManager;
})(window);