192 lines
7.5 KiB
JavaScript
192 lines
7.5 KiB
JavaScript
|
import browserInfo from '/imports/utils/browserInfo';
|
||
|
import logger from '/imports/startup/client/logger';
|
||
|
(function (){
|
||
|
// This function must be executed during the import time, that's why it's not exported to the caller component.
|
||
|
// It's needed because it changes some functions provided by browser, and these functions are verified during
|
||
|
// import time (like in ScreenshareBridgeService)
|
||
|
if(browserInfo.isMobileApp) {
|
||
|
logger.debug("Mobile APP detected");
|
||
|
|
||
|
// Store the method call sequential
|
||
|
const sequenceHolder = {sequence: 0};
|
||
|
|
||
|
// Store the promise for each method call
|
||
|
const promisesHolder = {};
|
||
|
|
||
|
// Call a method in the mobile application, returning a promise for its execution
|
||
|
function callNativeMethod(method, arguments=[]) {
|
||
|
try {
|
||
|
const sequence = ++sequenceHolder.sequence;
|
||
|
|
||
|
return new Promise ( (resolve, reject) => {
|
||
|
promisesHolder[sequence] = {
|
||
|
resolve, reject
|
||
|
};
|
||
|
|
||
|
window.ReactNativeWebView.postMessage(JSON.stringify({
|
||
|
sequence: sequenceHolder.sequence,
|
||
|
method: method,
|
||
|
arguments: arguments,
|
||
|
}));
|
||
|
} );
|
||
|
} catch(e) {
|
||
|
logger.error(`Error on callNativeMethod ${e.message}`, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// This method is called from the mobile app to notify us about a method invocation result
|
||
|
window.nativeMethodCallResult = (sequence, isResolve, resultOrException) => {
|
||
|
|
||
|
const promise = promisesHolder[sequence];
|
||
|
if(promise) {
|
||
|
if(isResolve) {
|
||
|
promise.resolve( resultOrException );
|
||
|
delete promisesHolder[sequence];
|
||
|
} else {
|
||
|
promise.reject( resultOrException );
|
||
|
delete promisesHolder[sequence];
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// WebRTC replacement functions
|
||
|
const buildVideoTrack = function () {}
|
||
|
const stream = {};
|
||
|
|
||
|
// Navigator
|
||
|
navigator.getDisplayMedia = function() {
|
||
|
logger.info("BBB-MOBILE - getDisplayMedia called", arguments);
|
||
|
|
||
|
return new Promise((resolve, reject) => {
|
||
|
callNativeMethod('initializeScreenShare').then(
|
||
|
() => {
|
||
|
const fakeVideoTrack = {};
|
||
|
fakeVideoTrack.applyConstraints = function (constraints) {
|
||
|
return new Promise(
|
||
|
(resolve, reject) => {
|
||
|
// alert("Constraints applied: " + JSON.stringify(constraints));
|
||
|
resolve();
|
||
|
}
|
||
|
);
|
||
|
};
|
||
|
fakeVideoTrack.onended = null; // callbacks added from screenshare (we can use it later)
|
||
|
fakeVideoTrack.oninactive = null; // callbacks added from screenshare (we can use it later)
|
||
|
|
||
|
const videoTracks = [
|
||
|
fakeVideoTrack
|
||
|
];
|
||
|
stream.getTracks = stream.getVideoTracks = function () {
|
||
|
return videoTracks;
|
||
|
};
|
||
|
resolve(stream);
|
||
|
}
|
||
|
).catch(
|
||
|
() => alert("Não deu")
|
||
|
);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// RTCPeerConnection
|
||
|
const prototype = window.RTCPeerConnection.prototype;
|
||
|
|
||
|
prototype.createOffer = function (options) {
|
||
|
logger.info("BBB-MOBILE - createOffer called", {options});
|
||
|
|
||
|
return new Promise( (resolve, reject) => {
|
||
|
callNativeMethod('createOffer').then ( sdp => {
|
||
|
logger.info("BBB-MOBILE - createOffer resolved", {sdp});
|
||
|
|
||
|
//
|
||
|
resolve({
|
||
|
type: 'offer',
|
||
|
sdp
|
||
|
});
|
||
|
});
|
||
|
} );
|
||
|
};
|
||
|
|
||
|
prototype.addEventListener = function (event, callback) {
|
||
|
logger.info("BBB-MOBILE - addEventListener called", {event, callback});
|
||
|
|
||
|
switch(event) {
|
||
|
case 'icecandidate':
|
||
|
window.bbbMobileScreenShareIceCandidateCallback = function () {
|
||
|
console.log("Received a bbbMobileScreenShareIceCandidateCallback call with arguments", arguments);
|
||
|
if(callback){
|
||
|
callback.apply(this, arguments);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
break;
|
||
|
case 'signalingstatechange':
|
||
|
window.bbbMobileScreenShareSignalingStateChangeCallback = function (newState) {
|
||
|
this.signalingState = newState;
|
||
|
callback();
|
||
|
};
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
prototype.setLocalDescription = function (description, successCallback, failureCallback) {
|
||
|
logger.info("BBB-MOBILE - setLocalDescription called", {description, successCallback, failureCallback});
|
||
|
|
||
|
// store the value
|
||
|
this._localDescription = JSON.parse(JSON.stringify(description));
|
||
|
// replace getter of localDescription to return this value
|
||
|
Object.defineProperty(this, 'localDescription', {get: function() {return this._localDescription;},set: function(newValue) {}});
|
||
|
|
||
|
// return a promise that resolves immediately
|
||
|
return new Promise( (resolve, reject) => {
|
||
|
resolve();
|
||
|
})
|
||
|
}
|
||
|
|
||
|
prototype.setRemoteDescription = function (description, successCallback, failureCallback) {
|
||
|
logger.info("BBB-MOBILE - setRemoteDescription called", {description, successCallback, failureCallback});
|
||
|
this._remoteDescription = JSON.parse(JSON.stringify(description));
|
||
|
Object.defineProperty(this, 'remoteDescription', {get: function() {return this._remoteDescription;},set: function(newValue) {}});
|
||
|
|
||
|
return new Promise( (resolve, reject) => {
|
||
|
callNativeMethod('setRemoteDescription', [description]).then ( () => {
|
||
|
logger.info("BBB-MOBILE - setRemoteDescription resolved");
|
||
|
|
||
|
resolve();
|
||
|
});
|
||
|
} );
|
||
|
}
|
||
|
|
||
|
prototype.addTrack = function (description, successCallback, failureCallback) {
|
||
|
logger.info("BBB-MOBILE - addTrack called", {description, successCallback, failureCallback});
|
||
|
}
|
||
|
|
||
|
prototype.getLocalStreams = function() {
|
||
|
logger.info("BBB-MOBILE - getLocalStreams called", arguments);
|
||
|
|
||
|
//
|
||
|
return [
|
||
|
stream
|
||
|
];
|
||
|
}
|
||
|
|
||
|
prototype.addTransceiver = function() {
|
||
|
logger.info("BBB-MOBILE - addTransceiver called", arguments);
|
||
|
}
|
||
|
|
||
|
prototype.addIceCandidate = function (candidate) {
|
||
|
logger.info("BBB-MOBILE - addIceCandidate called", {candidate});
|
||
|
|
||
|
return new Promise( (resolve, reject) => {
|
||
|
callNativeMethod('addRemoteIceCandidate', [candidate]).then ( () => {
|
||
|
logger.info("BBB-MOBILE - addRemoteIceCandidate resolved");
|
||
|
|
||
|
resolve();
|
||
|
});
|
||
|
} );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
})();
|
||
|
|
||
|
|