mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-08 08:39:59 +00:00
Check bridge compat before initializing cast shim
This commit is contained in:
@@ -10,6 +10,7 @@ export default async function getBridgeInfo () {
|
||||
|
||||
applicationVersion = response.data;
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import defaultOptions from "./options/defaultOptions";
|
||||
import messageRouter from "./messageRouter";
|
||||
import getBridgeInfo from "./lib/getBridgeInfo";
|
||||
|
||||
import semver from "semver";
|
||||
|
||||
@@ -421,7 +422,16 @@ messageRouter.register("main", async (message, sender) => {
|
||||
|
||||
switch (message.subject) {
|
||||
case "main:initialize": {
|
||||
initBridge(tabId, sender.tab.frameId);
|
||||
const bridgeInfo = await getBridgeInfo();
|
||||
if (bridgeInfo && bridgeInfo.isVersionCompatible) {
|
||||
initBridge(tabId, sender.tab.frameId);
|
||||
}
|
||||
|
||||
browser.tabs.sendMessage(sender.tab.id, {
|
||||
subject: "shim:initialized"
|
||||
, data: bridgeInfo
|
||||
}, { frameId: sender.tab.frameId });
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
|
||||
@@ -244,7 +244,7 @@ function onMediaSeekError (err) {
|
||||
|
||||
window.__onGCastApiAvailable = async function (loaded, errorInfo) {
|
||||
if (!loaded) {
|
||||
logMessage("__onGCastApiAvailable error");
|
||||
console.error("__onGCastApiAvailable error");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,264 +1,259 @@
|
||||
"use strict";
|
||||
|
||||
import ApiConfig from "./classes/ApiConfig";
|
||||
import DialRequest from "./classes/DialRequest";
|
||||
import Error_ from "./classes/Error";
|
||||
import Image_ from "./classes/Image";
|
||||
import Receiver from "./classes/Receiver";
|
||||
import ReceiverDisplayStatus from "./classes/ReceiverDisplayStatus";
|
||||
import SenderApplication from "./classes/SenderApplication";
|
||||
import Session from "./classes/Session";
|
||||
import SessionRequest from "./classes/SessionRequest";
|
||||
import Timeout from "./classes/Timeout";
|
||||
import Volume from "./classes/Volume";
|
||||
|
||||
import { AutoJoinPolicy
|
||||
, Capability
|
||||
, DefaultActionPolicy
|
||||
, DialAppState
|
||||
, ErrorCode
|
||||
, ReceiverAction
|
||||
, ReceiverAvailability
|
||||
, ReceiverType
|
||||
, SenderPlatform
|
||||
, SessionStatus
|
||||
, VolumeControlType } from "./enums";
|
||||
|
||||
import { requestSession as requestSessionTimeout } from "../timeout";
|
||||
|
||||
import state from "../state";
|
||||
|
||||
import { onMessage, sendMessage } from "../messageBridge";
|
||||
|
||||
|
||||
const cast = {
|
||||
// Enums
|
||||
AutoJoinPolicy
|
||||
, Capability
|
||||
, DefaultActionPolicy
|
||||
, DialAppState
|
||||
, ErrorCode
|
||||
, ReceiverAction
|
||||
, ReceiverAvailability
|
||||
, ReceiverType
|
||||
, SenderPlatform
|
||||
, SessionStatus
|
||||
, VolumeControlType
|
||||
|
||||
// Classes
|
||||
, ApiConfig
|
||||
, DialRequest
|
||||
, Error: Error_
|
||||
, Image: Image_
|
||||
, Receiver
|
||||
, ReceiverDisplayStatus
|
||||
, SenderApplication
|
||||
, Session
|
||||
, SessionRequest
|
||||
, Timeout
|
||||
, Volume
|
||||
|
||||
, timeout: new Timeout()
|
||||
, isAvailable: true
|
||||
, VERSION: [ 1, 2 ]
|
||||
};
|
||||
|
||||
|
||||
const receiverListeners = new Set();
|
||||
|
||||
let sessionSuccessCallback;
|
||||
let sessionErrorCallback;
|
||||
|
||||
|
||||
cast.addReceiverActionListener = (listener) => {
|
||||
console.info("Caster (Debug): cast.addReceiverActionListener");
|
||||
receiverListeners.add(listener);
|
||||
};
|
||||
|
||||
cast.initialize = (
|
||||
apiConfig
|
||||
, successCallback
|
||||
, errorCallback) => {
|
||||
|
||||
console.info("Caster (Debug): cast.initialize");
|
||||
|
||||
// Already initialized
|
||||
if (state.apiConfig) {
|
||||
errorCallback(new Error_(ErrorCode.RECEIVER_UNAVAILABLE));
|
||||
return;
|
||||
}
|
||||
|
||||
state.apiConfig = apiConfig;
|
||||
|
||||
sendMessage({
|
||||
subject: "bridge:discover"
|
||||
});
|
||||
|
||||
apiConfig.receiverListener(state.receiverList.length
|
||||
? ReceiverAvailability.AVAILABLE
|
||||
: ReceiverAvailability.UNAVAILABLE);
|
||||
|
||||
successCallback();
|
||||
};
|
||||
|
||||
cast.logMessage = (message) => {
|
||||
console.log("CAST MSG:", message);
|
||||
};
|
||||
|
||||
cast.precache = (data) => {
|
||||
console.info("STUB :: cast.precache");
|
||||
};
|
||||
|
||||
cast.removeReceiverActionListener = (listener) => {
|
||||
receiverListeners.delete(listener);
|
||||
}
|
||||
|
||||
cast.requestSession = (
|
||||
successCallback
|
||||
, errorCallback
|
||||
, opt_sessionRequest = state.apiConfig.sessionRequest) => {
|
||||
|
||||
console.info("Caster (Debug): cast.requestSession");
|
||||
|
||||
// Called before initialization
|
||||
if (!state.apiConfig) {
|
||||
errorCallback(new Error_(ErrorCode.API_NOT_INITIALIZED));
|
||||
return;
|
||||
}
|
||||
|
||||
// No available receivers
|
||||
if (!state.receiverList.length) {
|
||||
errorCallback(new Error_(ErrorCode.RECEIVER_UNAVAILABLE));
|
||||
return;
|
||||
}
|
||||
|
||||
sessionSuccessCallback = successCallback;
|
||||
sessionErrorCallback = errorCallback;
|
||||
|
||||
// Open destination chooser
|
||||
sendMessage({
|
||||
subject: "main:openPopup"
|
||||
});
|
||||
};
|
||||
|
||||
cast.requestSessionById = (sessionId) => {
|
||||
console.info("STUB :: cast.requestSessionById");
|
||||
};
|
||||
|
||||
cast.setCustomReceivers = (receivers, successCallback, errorCallback) => {
|
||||
console.info("STUB :: cast.setCustomReceivers");
|
||||
};
|
||||
|
||||
cast.setPageContext = (win) => {
|
||||
console.info("STUB :: cast.setPageContext");
|
||||
};
|
||||
|
||||
cast.setReceiverDisplayStatus = (sessionId) => {
|
||||
console.info("STUB :: cast.setReceiverDisplayStatus");
|
||||
};
|
||||
|
||||
cast.unescape = (escaped) => unescape(escaped);
|
||||
|
||||
|
||||
onMessage(message => {
|
||||
switch (message.subject) {
|
||||
/**
|
||||
* Cast destination found (serviceUp). Set the API availability
|
||||
* property and call the page event function (__onGCastApiAvailable).
|
||||
*/
|
||||
case "shim:serviceUp":
|
||||
const receiver = new Receiver(
|
||||
message.data.id
|
||||
, message.data.friendlyName);
|
||||
|
||||
receiver._address = message.data.address;
|
||||
receiver._port = message.data.port;
|
||||
|
||||
if (state.receiverList.find(r => r.label === receiver.label)) {
|
||||
break;
|
||||
}
|
||||
|
||||
state.receiverList.push(receiver);
|
||||
|
||||
// Notify listeners of new cast destination
|
||||
state.apiConfig.receiverListener(ReceiverAvailability.AVAILABLE);
|
||||
receiverListeners.forEach(
|
||||
listener => listener(ReceiverAvailability.AVAILABLE));
|
||||
|
||||
break;
|
||||
|
||||
/**
|
||||
* Cast destination lost (serviceDown). Remove from the receiver list
|
||||
* and update availability state.
|
||||
*/
|
||||
case "shim:serviceDown":
|
||||
state.receiverList = state.receiverList.filter(
|
||||
receiver => receiver.label !== message.data.id);
|
||||
|
||||
if (state.receiverList.length === 0) {
|
||||
state.apiConfig.receiverListener(
|
||||
ReceiverAvailability.UNAVAILABLE);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "shim:selectReceiver":
|
||||
console.info("Caster (Debug): Selected receiver");
|
||||
const selectedReceiver = message.data.receiver;
|
||||
|
||||
const sessionConstructorArgs = [
|
||||
state.sessionList.length // sessionId
|
||||
, state.apiConfig.sessionRequest.appId // appId
|
||||
, selectedReceiver.friendlyName // displayName
|
||||
, [] // appImages
|
||||
, selectedReceiver // receiver
|
||||
, (session) => {
|
||||
sendMessage({
|
||||
subject: "popup:close"
|
||||
});
|
||||
|
||||
state.apiConfig.sessionListener(session);
|
||||
sessionSuccessCallback(session, message.data.selectedMedia);
|
||||
}
|
||||
];
|
||||
|
||||
// If existing session active, stop it and start new one
|
||||
if (state.sessionList.length) {
|
||||
const lastSession
|
||||
= state.sessionList[state.sessionList.length - 1];
|
||||
|
||||
if (lastSession.status !== SessionStatus.STOPPED) {
|
||||
lastSession.stop(() => {
|
||||
state.sessionList.push(new Session(
|
||||
...sessionConstructorArgs));
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
state.sessionList.push(new Session(...sessionConstructorArgs));
|
||||
|
||||
break;
|
||||
|
||||
/**
|
||||
* Popup is ready to receive data to populate the cast destination
|
||||
* chooser.
|
||||
*/
|
||||
case "shim:popupReady":
|
||||
sendMessage({
|
||||
subject: "popup:populate"
|
||||
, data: {
|
||||
receivers: state.receiverList
|
||||
, selectedMedia: state.apiConfig._selectedMedia
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger bridge mDNS discovery
|
||||
sendMessage({
|
||||
subject: "main:initialize"
|
||||
});
|
||||
|
||||
export default cast;
|
||||
"use strict";
|
||||
|
||||
import ApiConfig from "./classes/ApiConfig";
|
||||
import DialRequest from "./classes/DialRequest";
|
||||
import Error_ from "./classes/Error";
|
||||
import Image_ from "./classes/Image";
|
||||
import Receiver from "./classes/Receiver";
|
||||
import ReceiverDisplayStatus from "./classes/ReceiverDisplayStatus";
|
||||
import SenderApplication from "./classes/SenderApplication";
|
||||
import Session from "./classes/Session";
|
||||
import SessionRequest from "./classes/SessionRequest";
|
||||
import Timeout from "./classes/Timeout";
|
||||
import Volume from "./classes/Volume";
|
||||
|
||||
import { AutoJoinPolicy
|
||||
, Capability
|
||||
, DefaultActionPolicy
|
||||
, DialAppState
|
||||
, ErrorCode
|
||||
, ReceiverAction
|
||||
, ReceiverAvailability
|
||||
, ReceiverType
|
||||
, SenderPlatform
|
||||
, SessionStatus
|
||||
, VolumeControlType } from "./enums";
|
||||
|
||||
import { requestSession as requestSessionTimeout } from "../timeout";
|
||||
|
||||
import state from "../state";
|
||||
|
||||
import { onMessage, sendMessage } from "../messageBridge";
|
||||
|
||||
|
||||
const cast = {
|
||||
// Enums
|
||||
AutoJoinPolicy
|
||||
, Capability
|
||||
, DefaultActionPolicy
|
||||
, DialAppState
|
||||
, ErrorCode
|
||||
, ReceiverAction
|
||||
, ReceiverAvailability
|
||||
, ReceiverType
|
||||
, SenderPlatform
|
||||
, SessionStatus
|
||||
, VolumeControlType
|
||||
|
||||
// Classes
|
||||
, ApiConfig
|
||||
, DialRequest
|
||||
, Error: Error_
|
||||
, Image: Image_
|
||||
, Receiver
|
||||
, ReceiverDisplayStatus
|
||||
, SenderApplication
|
||||
, Session
|
||||
, SessionRequest
|
||||
, Timeout
|
||||
, Volume
|
||||
|
||||
, timeout: new Timeout()
|
||||
, isAvailable: true
|
||||
, VERSION: [ 1, 2 ]
|
||||
};
|
||||
|
||||
|
||||
const receiverListeners = new Set();
|
||||
|
||||
let sessionSuccessCallback;
|
||||
let sessionErrorCallback;
|
||||
|
||||
|
||||
cast.addReceiverActionListener = (listener) => {
|
||||
console.info("Caster (Debug): cast.addReceiverActionListener");
|
||||
receiverListeners.add(listener);
|
||||
};
|
||||
|
||||
cast.initialize = (
|
||||
apiConfig
|
||||
, successCallback
|
||||
, errorCallback) => {
|
||||
|
||||
console.info("Caster (Debug): cast.initialize");
|
||||
|
||||
// Already initialized
|
||||
if (state.apiConfig) {
|
||||
errorCallback(new Error_(ErrorCode.RECEIVER_UNAVAILABLE));
|
||||
return;
|
||||
}
|
||||
|
||||
state.apiConfig = apiConfig;
|
||||
|
||||
sendMessage({
|
||||
subject: "bridge:discover"
|
||||
});
|
||||
|
||||
apiConfig.receiverListener(state.receiverList.length
|
||||
? ReceiverAvailability.AVAILABLE
|
||||
: ReceiverAvailability.UNAVAILABLE);
|
||||
|
||||
successCallback();
|
||||
};
|
||||
|
||||
cast.logMessage = (message) => {
|
||||
console.log("CAST MSG:", message);
|
||||
};
|
||||
|
||||
cast.precache = (data) => {
|
||||
console.info("STUB :: cast.precache");
|
||||
};
|
||||
|
||||
cast.removeReceiverActionListener = (listener) => {
|
||||
receiverListeners.delete(listener);
|
||||
}
|
||||
|
||||
cast.requestSession = (
|
||||
successCallback
|
||||
, errorCallback
|
||||
, opt_sessionRequest = state.apiConfig.sessionRequest) => {
|
||||
|
||||
console.info("Caster (Debug): cast.requestSession");
|
||||
|
||||
// Called before initialization
|
||||
if (!state.apiConfig) {
|
||||
errorCallback(new Error_(ErrorCode.API_NOT_INITIALIZED));
|
||||
return;
|
||||
}
|
||||
|
||||
// No available receivers
|
||||
if (!state.receiverList.length) {
|
||||
errorCallback(new Error_(ErrorCode.RECEIVER_UNAVAILABLE));
|
||||
return;
|
||||
}
|
||||
|
||||
sessionSuccessCallback = successCallback;
|
||||
sessionErrorCallback = errorCallback;
|
||||
|
||||
// Open destination chooser
|
||||
sendMessage({
|
||||
subject: "main:openPopup"
|
||||
});
|
||||
};
|
||||
|
||||
cast.requestSessionById = (sessionId) => {
|
||||
console.info("STUB :: cast.requestSessionById");
|
||||
};
|
||||
|
||||
cast.setCustomReceivers = (receivers, successCallback, errorCallback) => {
|
||||
console.info("STUB :: cast.setCustomReceivers");
|
||||
};
|
||||
|
||||
cast.setPageContext = (win) => {
|
||||
console.info("STUB :: cast.setPageContext");
|
||||
};
|
||||
|
||||
cast.setReceiverDisplayStatus = (sessionId) => {
|
||||
console.info("STUB :: cast.setReceiverDisplayStatus");
|
||||
};
|
||||
|
||||
cast.unescape = (escaped) => unescape(escaped);
|
||||
|
||||
|
||||
onMessage(message => {
|
||||
switch (message.subject) {
|
||||
/**
|
||||
* Cast destination found (serviceUp). Set the API availability
|
||||
* property and call the page event function (__onGCastApiAvailable).
|
||||
*/
|
||||
case "shim:serviceUp":
|
||||
const receiver = new Receiver(
|
||||
message.data.id
|
||||
, message.data.friendlyName);
|
||||
|
||||
receiver._address = message.data.address;
|
||||
receiver._port = message.data.port;
|
||||
|
||||
if (state.receiverList.find(r => r.label === receiver.label)) {
|
||||
break;
|
||||
}
|
||||
|
||||
state.receiverList.push(receiver);
|
||||
|
||||
// Notify listeners of new cast destination
|
||||
state.apiConfig.receiverListener(ReceiverAvailability.AVAILABLE);
|
||||
receiverListeners.forEach(
|
||||
listener => listener(ReceiverAvailability.AVAILABLE));
|
||||
|
||||
break;
|
||||
|
||||
/**
|
||||
* Cast destination lost (serviceDown). Remove from the receiver list
|
||||
* and update availability state.
|
||||
*/
|
||||
case "shim:serviceDown":
|
||||
state.receiverList = state.receiverList.filter(
|
||||
receiver => receiver.label !== message.data.id);
|
||||
|
||||
if (state.receiverList.length === 0) {
|
||||
state.apiConfig.receiverListener(
|
||||
ReceiverAvailability.UNAVAILABLE);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "shim:selectReceiver":
|
||||
console.info("Caster (Debug): Selected receiver");
|
||||
const selectedReceiver = message.data.receiver;
|
||||
|
||||
const sessionConstructorArgs = [
|
||||
state.sessionList.length // sessionId
|
||||
, state.apiConfig.sessionRequest.appId // appId
|
||||
, selectedReceiver.friendlyName // displayName
|
||||
, [] // appImages
|
||||
, selectedReceiver // receiver
|
||||
, (session) => {
|
||||
sendMessage({
|
||||
subject: "popup:close"
|
||||
});
|
||||
|
||||
state.apiConfig.sessionListener(session);
|
||||
sessionSuccessCallback(session, message.data.selectedMedia);
|
||||
}
|
||||
];
|
||||
|
||||
// If existing session active, stop it and start new one
|
||||
if (state.sessionList.length) {
|
||||
const lastSession
|
||||
= state.sessionList[state.sessionList.length - 1];
|
||||
|
||||
if (lastSession.status !== SessionStatus.STOPPED) {
|
||||
lastSession.stop(() => {
|
||||
state.sessionList.push(new Session(
|
||||
...sessionConstructorArgs));
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
state.sessionList.push(new Session(...sessionConstructorArgs));
|
||||
|
||||
break;
|
||||
|
||||
/**
|
||||
* Popup is ready to receive data to populate the cast destination
|
||||
* chooser.
|
||||
*/
|
||||
case "shim:popupReady":
|
||||
sendMessage({
|
||||
subject: "popup:populate"
|
||||
, data: {
|
||||
receivers: state.receiverList
|
||||
, selectedMedia: state.apiConfig._selectedMedia
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
export default cast;
|
||||
|
||||
@@ -1,18 +1,35 @@
|
||||
"use strict";
|
||||
|
||||
import cast from "./cast";
|
||||
import media from "./media";
|
||||
|
||||
if (!window.chrome) {
|
||||
window.chrome = {};
|
||||
}
|
||||
|
||||
window.chrome.cast = cast;
|
||||
window.chrome.cast.media = media;
|
||||
|
||||
// Call page's API loaded function if defined
|
||||
const readyFunction = window.__onGCastApiAvailable;
|
||||
console.log(readyFunction);
|
||||
if (readyFunction && typeof readyFunction === "function") {
|
||||
readyFunction(true);
|
||||
}
|
||||
"use strict";
|
||||
|
||||
import cast from "./cast";
|
||||
import media from "./media";
|
||||
|
||||
import { onMessage, sendMessage } from "./messageBridge";
|
||||
|
||||
|
||||
if (!window.chrome) {
|
||||
window.chrome = {};
|
||||
}
|
||||
|
||||
window.chrome.cast = cast;
|
||||
window.chrome.cast.media = media;
|
||||
|
||||
|
||||
onMessage(message => {
|
||||
switch (message.subject) {
|
||||
case "shim:initialized": {
|
||||
const bridgeInfo = message.data;
|
||||
|
||||
// Call page's API loaded function if defined
|
||||
const readyFunction = window.__onGCastApiAvailable;
|
||||
if (readyFunction && typeof readyFunction === "function") {
|
||||
readyFunction(bridgeInfo && bridgeInfo.isVersionCompatible);
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger bridge mDNS discovery
|
||||
sendMessage({
|
||||
subject: "main:initialize"
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user