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.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,220 @@
/* global mDBG */
(function(exports) {
'use strict';
/**
* This object parses and process the message casted
* between receiver and controller.
*
* The message casted is in JSON and shall carry properties below:
* - seq: Number. The sequence of message sent. Increased by 1 when sending
* one new message. The message sequences from controller and receiver
* shall be independent to each other.
* - type: String. Indicate the message type.
* - other extra properties depending on the type
*
* For example, the message of loading request from a controller may be like:
* {
* 'seq': 3,
* 'type': 'load',
* 'url': 'http://www.example.com/foo.ogg'
* }
*/
var castingMessage = {};
castingMessage.type = Object.freeze({
/**
* Represent the device info.
* The extra message properties:
* - displayName: String. The device display name
*/
'device-info': {
name: 'device-info',
sanitizeMsg: function (msg) {
if (msg.displayName !== undefined &&
typeof msg.displayName != 'string'
) {
throw new Error('Ilegal display name = ' + msg.displayName +
' in casting message of type = ' + this.name);
}
return msg;
}
},
/**
* Represent acknowledgement of message receiving.
* The extra message properties:
* - error: String. Present if there is error
*/
ack: {
name: 'ack',
sanitizeMsg: function (msg) {
if (msg.error !== null &&
msg.error !== undefined &&
typeof msg.error != 'string'
) {
throw new Error('Ilegal error = ' + msg.error +
' in casting message of type = ' + this.name);
}
return msg;
}
},
/**
* Represent video playing status. The extra message properties:
* - time: Number. The current video time
* - status: String. Describe status, could be
* - buffering: Video buffering
* - loaded: The media's metadata has finished loading;
* all attributes now contain as much useful information
* as they're going to.
* - buffered: Video buffered and ready to play
* - playing: Video is playing
* - seeked: Video seeking is done
* - stopped: Video is not playing (maybe ended or paused).
* - error: Error on playing.
* When error occurs, one more extra message properties:
* - error: String. The error code.
*/
status: {
name: 'status',
sanitizeMsg: function (msg) {
if (typeof msg.time != 'number' || (msg.time >= 0) === false) {
throw new Error('Ilegal time = ' + msg.time +
' in casting message of type = ' + this.name);
}
var validStatus = [
'buffering', 'loaded', 'buffered',
'playing', 'seeked', 'stopped', 'error'
];
if (validStatus.indexOf(msg.status) < 0) {
throw new Error('Ilegal status = ' + msg.status +
' in casting message of type = ' + this.name);
}
if (msg.status == 'error' && typeof msg.error != 'string') {
throw new Error('Ilegal error = ' + msg.error +
' in casting message of type = ' + this.name);
}
return msg;
}
},
/**
* Request to load and play video. The extra message properties:
* - url : String. The video url.
*/
load: {
name: 'load',
sanitizeMsg: function (msg) {
if (typeof msg.url != 'string' || !msg.url) {
throw new Error('Ilegal url = ' + msg.url +
' in casting message of type = ' + this.name);
}
return msg;
}
},
/**
* Request to play video
*/
play: {
name: 'play'
},
/**
* Request to pause video
*/
pause: {
name: 'pause'
},
/**
* Request to seek on video. The extra message properties:
* - time: Number. The time to seek.
*/
seek: {
name: 'seek',
sanitizeMsg: function (msg) {
if (typeof msg.time != 'number' || (msg.time >= 0) === false) {
throw new Error('Ilegal time in casting message of type = ' +
this.name, msg.time);
}
return msg;
}
}
});
/**
* Validate and make sure the message format, datatype.
*
* @param {Object} content the message content to sanitize
* @return {Object} Sanitized message
*/
castingMessage.sanitizeMsg = function (content) {
mDBG.log('castingMessage#sanitizeMsg');
mDBG.log('Sanitize message content:', content);
if (this.type[content.type]) {
if (typeof content.seq == 'number' && content.seq >= 0) {
if (typeof this.type[content.type].sanitizeMsg == 'function') {
content = this.type[content.type].sanitizeMsg(content);
}
} else {
throw new Error('Missing sequence of casting message : ' +
JSON.stringify(content));
}
} else {
throw new Error('Unknown type of casting message : ' + content.type);
}
return content;
};
/**
* @param {String} txt the message txt sent from controller
* @return {Array.<Object>} the parsed messages
*/
castingMessage.parse = function (txt) {
mDBG.log('castingMessage#parse');
mDBG.log('Parsing : ', txt);
var data = '[' + txt.replace(/}{/g, '},{') + ']';
mDBG.log('Transformed : ', data);
var msgs = JSON.parse(data);
mDBG.log('JSON Parsed : ', msgs);
var results = [];
msgs.forEach((m) => {
try {
results.push(this.sanitizeMsg(m));
} catch (e) {
mDBG.error(e);
}
});
mDBG.log('Sanitized : ', results);
return results;
};
/**
* @param {Object} content the message content being sent.
* @return {String} the messsage txt to sent
*/
castingMessage.stringify = function (content) {
return JSON.stringify(this.sanitizeMsg(content));
};
exports.castingMessage = castingMessage;
})(window);