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