Rename shim -> cast

This commit is contained in:
hensm
2022-03-15 07:00:45 +00:00
parent d7592d5806
commit 9af43c2910
51 changed files with 182 additions and 177 deletions

View File

@@ -216,7 +216,7 @@ Netflix / HTML5:
## Credit ## Credit
_**Note**: Since it seems to be causing confusion, this project does not use electron. The electron-chromecast library was only used as a reference for the initial implementation of the API shim._ _**Note**: Since it seems to be causing confusion, this project does not use electron. The electron-chromecast library was only used as a reference for the initial implementation of the API._
* [electron-chromecast](https://github.com/GPMDP/electron-chromecast) * [electron-chromecast](https://github.com/GPMDP/electron-chromecast)
* [node-castv2](https://github.com/thibauts/node-castv2) * [node-castv2](https://github.com/thibauts/node-castv2)

View File

@@ -79,7 +79,7 @@ export default class Session extends CastClient {
const { friendlyName } = this.receiverDevice; const { friendlyName } = this.receiverDevice;
sendMessage({ sendMessage({
subject: "shim:castSessionCreated", subject: "cast:sessionCreated",
data: { data: {
sessionId: this.sessionId, sessionId: this.sessionId,
statusText: application.statusText, statusText: application.statusText,
@@ -107,7 +107,7 @@ export default class Session extends CastClient {
} }
sendMessage({ sendMessage({
subject: "shim:castSessionUpdated", subject: "cast:sessionUpdated",
data: { data: {
sessionId: this.sessionId, sessionId: this.sessionId,
statusText: application.statusText, statusText: application.statusText,
@@ -144,7 +144,7 @@ export default class Session extends CastClient {
messageData = JSON.stringify(messageData); messageData = JSON.stringify(messageData);
sendMessage({ sendMessage({
subject: "shim:receivedCastSessionMessage", subject: "cast:receivedSessionMessage",
data: { data: {
sessionId: this.sessionId, sessionId: this.sessionId,
namespace, namespace,
@@ -181,7 +181,7 @@ export default class Session extends CastClient {
this.client.on("close", () => { this.client.on("close", () => {
if (this.sessionId) { if (this.sessionId) {
sendMessage({ sendMessage({
subject: "shim:castSessionStopped", subject: "cast:sessionStopped",
data: { sessionId: this.sessionId } data: { sessionId: this.sessionId }
}); });
} }

View File

@@ -30,7 +30,7 @@ export function handleCastMessage(message: Message) {
const session = sessions.get(sessionId); const session = sessions.get(sessionId);
if (!session) { if (!session) {
sendMessage({ sendMessage({
subject: "shim:impl_sendCastMessage", subject: "cast:impl_sendMessage",
data: { data: {
error: "Session does not exist", error: "Session does not exist",
sessionId, sessionId,
@@ -45,7 +45,7 @@ export function handleCastMessage(message: Message) {
session.sendReceiverMessage(messageData); session.sendReceiverMessage(messageData);
} catch (err) { } catch (err) {
sendMessage({ sendMessage({
subject: "shim:impl_sendCastMessage", subject: "cast:impl_sendMessage",
data: { data: {
error: `Failed to send message (${err})`, error: `Failed to send message (${err})`,
sessionId, sessionId,
@@ -58,7 +58,7 @@ export function handleCastMessage(message: Message) {
// Success // Success
sendMessage({ sendMessage({
subject: "shim:impl_sendCastMessage", subject: "cast:impl_sendMessage",
data: { sessionId, messageId } data: { sessionId, messageId }
}); });
@@ -71,7 +71,7 @@ export function handleCastMessage(message: Message) {
const session = sessions.get(sessionId); const session = sessions.get(sessionId);
if (!session) { if (!session) {
sendMessage({ sendMessage({
subject: "shim:impl_sendCastMessage", subject: "cast:impl_sendMessage",
data: { data: {
error: "Session does not exist", error: "Session does not exist",
sessionId, sessionId,
@@ -92,7 +92,7 @@ export function handleCastMessage(message: Message) {
session.sendMessage(namespace, messageData); session.sendMessage(namespace, messageData);
} catch (err) { } catch (err) {
sendMessage({ sendMessage({
subject: "shim:impl_sendCastMessage", subject: "cast:impl_sendMessage",
data: { data: {
error: `Failed to send message (${err})`, error: `Failed to send message (${err})`,
sessionId, sessionId,
@@ -105,7 +105,7 @@ export function handleCastMessage(message: Message) {
// Success // Success
sendMessage({ sendMessage({
subject: "shim:impl_sendCastMessage", subject: "cast:impl_sendMessage",
data: { sessionId, messageId } data: { sessionId, messageId }
}); });

View File

@@ -33,17 +33,17 @@ interface CastSessionCreated extends CastSessionUpdated {
* ext/src/messaging.ts > MessageDefinitions * ext/src/messaging.ts > MessageDefinitions
*/ */
type MessageDefinitions = { type MessageDefinitions = {
"shim:castSessionCreated": CastSessionCreated; "cast:sessionCreated": CastSessionCreated;
"shim:castSessionUpdated": CastSessionUpdated; "cast:sessionUpdated": CastSessionUpdated;
"shim:castSessionStopped": { "cast:sessionStopped": {
sessionId: string; sessionId: string;
}; };
"shim:receivedCastSessionMessage": { "cast:receivedSessionMessage": {
sessionId: string; sessionId: string;
namespace: string; namespace: string;
messageData: string; messageData: string;
}; };
"shim:impl_sendCastMessage": { "cast:impl_sendMessage": {
sessionId: string; sessionId: string;
messageId: string; messageId: string;
error?: string; error?: string;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -78,10 +78,10 @@ const buildOpts = {
`${srcPath}/senders/media/overlay/overlayContentLoader.ts`, `${srcPath}/senders/media/overlay/overlayContentLoader.ts`,
// Mirroring sender // Mirroring sender
`${srcPath}/senders/mirroring.ts`, `${srcPath}/senders/mirroring.ts`,
// Shim // Cast
`${srcPath}/shim/index.ts`, `${srcPath}/cast/index.ts`,
`${srcPath}/shim/content.ts`, `${srcPath}/cast/content.ts`,
`${srcPath}/shim/contentBridge.ts`, `${srcPath}/cast/contentBridge.ts`,
// UI // UI
`${srcPath}/ui/popup/index.tsx`, `${srcPath}/ui/popup/index.tsx`,
`${srcPath}/ui/options/index.tsx` `${srcPath}/ui/options/index.tsx`

View File

@@ -17,7 +17,7 @@ import receiverDevices from "./receiverDevices";
type AnyPort = Port | MessagePort; type AnyPort = Port | MessagePort;
export interface Shim { export interface CastInstance {
bridgePort: Port; bridgePort: Port;
contentPort: AnyPort; contentPort: AnyPort;
contentTabId?: number; contentTabId?: number;
@@ -25,109 +25,109 @@ export interface Shim {
appId?: string; appId?: string;
} }
export default new (class ShimManager { export default new (class CastManager {
private activeShims = new Set<Shim>(); private activeInstances = new Set<CastInstance>();
public async init() { public async init() {
// Wait for "shim" ports // Wait for "cast" ports
messaging.onConnect.addListener(async port => { messaging.onConnect.addListener(async port => {
if (port.name === "shim") { if (port.name === "cast") {
this.createShim(port); this.createInstance(port);
} }
}); });
receiverDevices.addEventListener("receiverDeviceUp", ev => { receiverDevices.addEventListener("receiverDeviceUp", ev => {
for (const shim of this.activeShims) { for (const instance of this.activeInstances) {
shim.contentPort.postMessage({ instance.contentPort.postMessage({
subject: "shim:serviceUp", subject: "cast:serviceUp",
data: { receiverDevice: ev.detail.receiverDevice } data: { receiverDevice: ev.detail.deviceInfo }
}); });
} }
}); });
receiverDevices.addEventListener("receiverDeviceDown", ev => { receiverDevices.addEventListener("receiverDeviceDown", ev => {
for (const shim of this.activeShims) { for (const instance of this.activeInstances) {
shim.contentPort.postMessage({ instance.contentPort.postMessage({
subject: "shim:serviceDown", subject: "cast:serviceDown",
data: { receiverDeviceId: ev.detail.receiverDeviceId } data: { receiverDeviceId: ev.detail.deviceId }
}); });
} }
}); });
} }
public getShim(tabId: number, frameId?: number) { public getInstance(tabId: number, frameId?: number) {
for (const activeShim of this.activeShims) { for (const instance of this.activeInstances) {
if (activeShim.contentTabId === tabId) { if (instance.contentTabId === tabId) {
if (frameId && activeShim.contentFrameId !== frameId) { if (frameId && instance.contentFrameId !== frameId) {
continue; continue;
} }
return activeShim; return instance;
} }
} }
} }
public async createShim(port: AnyPort) { public async createInstance(port: AnyPort) {
const shim = await (port instanceof MessagePort const instance = await (port instanceof MessagePort
? this.createShimFromBackground(port) ? this.createInstanceFromBackground(port)
: this.createShimFromContent(port)); : this.createInstanceFromContent(port));
shim.contentPort.postMessage({ instance.contentPort.postMessage({
subject: "shim:initialized", subject: "cast:initialized",
data: await bridge.getInfo() data: await bridge.getInfo()
}); });
this.activeShims.add(shim); this.activeInstances.add(instance);
} }
private async createShimFromBackground( private async createInstanceFromBackground(
contentPort: MessagePort contentPort: MessagePort
): Promise<Shim> { ): Promise<CastInstance> {
const shim: Shim = { const instance: CastInstance = {
bridgePort: await bridge.connect(), bridgePort: await bridge.connect(),
contentPort contentPort
}; };
shim.bridgePort.onDisconnect.addListener(() => { instance.bridgePort.onDisconnect.addListener(() => {
contentPort.close(); contentPort.close();
this.activeShims.delete(shim); this.activeInstances.delete(instance);
}); });
shim.bridgePort.onMessage.addListener(message => { instance.bridgePort.onMessage.addListener(message => {
contentPort.postMessage(message); contentPort.postMessage(message);
}); });
contentPort.addEventListener("message", ev => { contentPort.addEventListener("message", ev => {
this.handleContentMessage(shim, ev.data); this.handleContentMessage(instance, ev.data);
}); });
return shim; return instance;
} }
private async createShimFromContent(contentPort: Port): Promise<Shim> { private async createInstanceFromContent(contentPort: Port): Promise<CastInstance> {
if ( if (
contentPort.sender?.tab?.id === undefined || contentPort.sender?.tab?.id === undefined ||
contentPort.sender?.frameId === undefined contentPort.sender?.frameId === undefined
) { ) {
throw logger.error( throw logger.error(
"Content shim created with an invalid port context." "Cast instance created from content with an invalid port context."
); );
} }
/** /**
* If there's already an active shim for the sender * If there's already an active instance for the sender
* tab/frame ID, disconnect it. * tab/frame ID, disconnect it.
*/ */
for (const activeShim of this.activeShims) { for (const instance of this.activeInstances) {
if ( if (
activeShim.contentTabId === contentPort.sender.tab.id && instance.contentTabId === contentPort.sender.tab.id &&
activeShim.contentFrameId === contentPort.sender.frameId instance.contentFrameId === contentPort.sender.frameId
) { ) {
activeShim.bridgePort.disconnect(); instance.bridgePort.disconnect();
} }
} }
const shim: Shim = { const instance: CastInstance = {
bridgePort: await bridge.connect(), bridgePort: await bridge.connect(),
contentPort, contentPort,
contentTabId: contentPort.sender.tab.id, contentTabId: contentPort.sender.tab.id,
@@ -135,7 +135,7 @@ export default new (class ShimManager {
}; };
const onContentPortMessage = (message: Message) => { const onContentPortMessage = (message: Message) => {
this.handleContentMessage(shim, message); this.handleContentMessage(instance, message);
}; };
const onBridgePortMessage = (message: Message) => { const onBridgePortMessage = (message: Message) => {
@@ -143,37 +143,37 @@ export default new (class ShimManager {
}; };
const onDisconnect = () => { const onDisconnect = () => {
shim.bridgePort.onMessage.removeListener(onBridgePortMessage); instance.bridgePort.onMessage.removeListener(onBridgePortMessage);
contentPort.onMessage.removeListener(onContentPortMessage); contentPort.onMessage.removeListener(onContentPortMessage);
shim.bridgePort.disconnect(); instance.bridgePort.disconnect();
contentPort.disconnect(); contentPort.disconnect();
this.activeShims.delete(shim); this.activeInstances.delete(instance);
}; };
shim.bridgePort.onDisconnect.addListener(onDisconnect); instance.bridgePort.onDisconnect.addListener(onDisconnect);
shim.bridgePort.onMessage.addListener(onBridgePortMessage); instance.bridgePort.onMessage.addListener(onBridgePortMessage);
contentPort.onDisconnect.addListener(onDisconnect); contentPort.onDisconnect.addListener(onDisconnect);
contentPort.onMessage.addListener(onContentPortMessage); contentPort.onMessage.addListener(onContentPortMessage);
return shim; return instance;
} }
private async handleContentMessage(shim: Shim, message: Message) { private async handleContentMessage(instance: CastInstance, message: Message) {
const [destination] = message.subject.split(":"); const [destination] = message.subject.split(":");
if (destination === "bridge") { if (destination === "bridge") {
shim.bridgePort.postMessage(message); instance.bridgePort.postMessage(message);
} }
switch (message.subject) { switch (message.subject) {
case "main:shimReady": { case "main:castReady": {
shim.appId = message.data.appId; instance.appId = message.data.appId;
for (const receiverDevice of receiverDevices.getDevices()) { for (const receiverDevice of receiverDevices.getDevices()) {
shim.contentPort.postMessage({ instance.contentPort.postMessage({
subject: "shim:serviceUp", subject: "cast:serviceUp",
data: { receiverDevice } data: { receiverDevice }
}); });
} }
@@ -183,25 +183,25 @@ export default new (class ShimManager {
case "main:selectReceiver": { case "main:selectReceiver": {
if ( if (
shim.contentTabId === undefined || instance.contentTabId === undefined ||
shim.contentFrameId === undefined instance.contentFrameId === undefined
) { ) {
throw logger.error( throw logger.error(
"Shim associated with content sender missing tab/frame ID" "Cast instance associated with content sender missing tab/frame ID"
); );
} }
try { try {
const selection = const selection =
await ReceiverSelectorManager.getSelection( await ReceiverSelectorManager.getSelection(
shim.contentTabId, instance.contentTabId,
shim.contentFrameId instance.contentFrameId
); );
// Handle cancellation // Handle cancellation
if (!selection) { if (!selection) {
shim.contentPort.postMessage({ instance.contentPort.postMessage({
subject: "shim:selectReceiver/cancelled" subject: "cast:selectReceiver/cancelled"
}); });
break; break;
@@ -218,21 +218,21 @@ export default new (class ShimManager {
selection.mediaType !== selection.mediaType !==
ReceiverSelectorMediaType.App ReceiverSelectorMediaType.App
) { ) {
shim.contentPort.postMessage({ instance.contentPort.postMessage({
subject: "shim:selectReceiver/cancelled" subject: "cast:selectReceiver/cancelled"
}); });
loadSender({ loadSender({
tabId: shim.contentTabId, tabId: instance.contentTabId,
frameId: shim.contentFrameId, frameId: instance.contentFrameId,
selection selection
}); });
break; break;
} }
shim.contentPort.postMessage({ instance.contentPort.postMessage({
subject: "shim:selectReceiver/selected", subject: "cast:selectReceiver/selected",
data: selection data: selection
}); });
@@ -240,8 +240,8 @@ export default new (class ShimManager {
} }
case ReceiverSelectionActionType.Stop: { case ReceiverSelectionActionType.Stop: {
shim.contentPort.postMessage({ instance.contentPort.postMessage({
subject: "shim:selectReceiver/stopped", subject: "cast:selectReceiver/stopped",
data: selection data: selection
}); });
@@ -250,8 +250,8 @@ export default new (class ShimManager {
} }
} catch (err) { } catch (err) {
// TODO: Report errors properly // TODO: Report errors properly
shim.contentPort.postMessage({ instance.contentPort.postMessage({
subject: "shim:selectReceiver/cancelled" subject: "cast:selectReceiver/cancelled"
}); });
} }

View File

@@ -3,13 +3,12 @@
import defaultOptions from "../defaultOptions"; import defaultOptions from "../defaultOptions";
import loadSender from "../lib/loadSender"; import loadSender from "../lib/loadSender";
import logger from "../lib/logger"; import logger from "../lib/logger";
import messaging from "../messaging";
import options from "../lib/options"; import options from "../lib/options";
import bridge, { BridgeInfo } from "../lib/bridge"; import bridge, { BridgeInfo } from "../lib/bridge";
import ReceiverSelectorManager from "./receiverSelector/ReceiverSelectorManager"; import ReceiverSelectorManager from "./receiverSelector/ReceiverSelectorManager";
import ShimManager from "./ShimManager"; import CastManager from "./CastManager";
import receiverDevices from "./receiverDevices"; import receiverDevices from "./receiverDevices";
@@ -150,7 +149,7 @@ async function init() {
await notifyBridgeCompat(); await notifyBridgeCompat();
await receiverDevices.init(); await receiverDevices.init();
await ShimManager.init(); await CastManager.init();
await initMenus(); await initMenus();
await initWhitelist(); await initWhitelist();

View File

@@ -6,7 +6,7 @@ import { TypedEventTarget } from "../lib/TypedEventTarget";
import { Message, Port } from "../messaging"; import { Message, Port } from "../messaging";
import { ReceiverDevice } from "../types"; import { ReceiverDevice } from "../types";
import { ReceiverStatus } from "../shim/cast/types"; import { ReceiverStatus } from "../cast/api/types";
interface EventMap { interface EventMap {
receiverDeviceUp: { deviceInfo: ReceiverDevice }; receiverDeviceUp: { deviceInfo: ReceiverDevice };

View File

@@ -3,7 +3,7 @@
import options from "../../lib/options"; import options from "../../lib/options";
import logger from "../../lib/logger"; import logger from "../../lib/logger";
import ShimManager from "../ShimManager"; import CastManager from "../CastManager";
import receiverDevices from "../receiverDevices"; import receiverDevices from "../receiverDevices";
import { getMediaTypesForPageUrl } from "../../lib/utils"; import { getMediaTypesForPageUrl } from "../../lib/utils";
@@ -50,14 +50,17 @@ async function getSelection(
withMediaSender = false withMediaSender = false
): Promise<ReceiverSelection | null> { ): Promise<ReceiverSelection | null> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
let currentShim = ShimManager.getShim(contextTabId, contextFrameId); let castInstance = CastManager.getInstance(
contextTabId,
contextFrameId
);
/** /**
* If the current context is running the mirroring app, pretend * If the current context is running the mirroring app, pretend
* it doesn't exist because it shouldn't be launched like this. * it doesn't exist because it shouldn't be launched like this.
*/ */
if (currentShim?.appId === (await options.get("mirroringAppId"))) { if (castInstance?.appId === (await options.get("mirroringAppId"))) {
currentShim = undefined; castInstance = undefined;
} }
let defaultMediaType = ReceiverSelectorMediaType.Tab; let defaultMediaType = ReceiverSelectorMediaType.Tab;
@@ -78,7 +81,7 @@ async function getSelection(
} }
// Enable app media type if initialized sender app is found // Enable app media type if initialized sender app is found
if (currentShim || withMediaSender) { if (castInstance || withMediaSender) {
defaultMediaType = ReceiverSelectorMediaType.App; defaultMediaType = ReceiverSelectorMediaType.App;
availableMediaTypes |= ReceiverSelectorMediaType.App; availableMediaTypes |= ReceiverSelectorMediaType.App;
} }
@@ -215,7 +218,7 @@ async function getSelection(
receiverDevices.getDevices(), receiverDevices.getDevices(),
defaultMediaType, defaultMediaType,
availableMediaTypes, availableMediaTypes,
currentShim?.appId castInstance?.appId
); );
}); });
} }

View File

@@ -141,7 +141,7 @@ function onWhitelistedChildBeforeSendHeaders(
* hosted script. * hosted script.
* *
* We can redirect this and inject our own script to setup * We can redirect this and inject our own script to setup
* the API shim. * the API.
*/ */
async function onBeforeCastSDKRequest(details: OnBeforeRequestDetails) { async function onBeforeCastSDKRequest(details: OnBeforeRequestDetails) {
if (!details.originUrl || details.tabId === -1) { if (!details.originUrl || details.tabId === -1) {
@@ -179,13 +179,13 @@ async function onBeforeCastSDKRequest(details: OnBeforeRequestDetails) {
}); });
await browser.tabs.executeScript(details.tabId, { await browser.tabs.executeScript(details.tabId, {
file: "shim/contentBridge.js", file: "cast/contentBridge.js",
frameId: details.frameId, frameId: details.frameId,
runAt: "document_start" runAt: "document_start"
}); });
return { return {
redirectUrl: browser.runtime.getURL("shim/index.js") redirectUrl: browser.runtime.getURL("cast/index.js")
}; };
} }

View File

View File

@@ -133,7 +133,7 @@ export function initialize(
apiConfig = newApiConfig; apiConfig = newApiConfig;
sendMessageResponse({ sendMessageResponse({
subject: "main:shimReady", subject: "main:castReady",
data: { appId: apiConfig.sessionRequest.appId } data: { appId: apiConfig.sessionRequest.appId }
}); });
@@ -243,7 +243,7 @@ export function precache(_data: string) {
onMessage(message => { onMessage(message => {
switch (message.subject) { switch (message.subject) {
case "shim:initialized": { case "cast:initialized": {
isAvailable = true; isAvailable = true;
break; break;
} }
@@ -252,7 +252,7 @@ onMessage(message => {
* Once the bridge detects a session creation, session info * Once the bridge detects a session creation, session info
* and data needed to create cast API objects is sent. * and data needed to create cast API objects is sent.
*/ */
case "shim:castSessionCreated": { case "cast:sessionCreated": {
// Notify background to close UI // Notify background to close UI
sendMessageResponse({ sendMessageResponse({
subject: "main:sessionCreated" subject: "main:sessionCreated"
@@ -282,7 +282,7 @@ onMessage(message => {
sessions.set(session.sessionId, session); sessions.set(session.sessionId, session);
} }
// eslint-disable-next-line no-fallthrough // eslint-disable-next-line no-fallthrough
case "shim:castSessionUpdated": { case "cast:sessionUpdated": {
const status = message.data; const status = message.data;
const session = sessions.get(status.sessionId); const session = sessions.get(status.sessionId);
if (!session) { if (!session) {
@@ -303,7 +303,7 @@ onMessage(message => {
break; break;
} }
case "shim:castSessionStopped": { case "cast:sessionStopped": {
const { sessionId } = message.data; const { sessionId } = message.data;
const session = sessions.get(sessionId); const session = sessions.get(sessionId);
if (session) { if (session) {
@@ -320,7 +320,7 @@ onMessage(message => {
break; break;
} }
case "shim:receivedCastSessionMessage": { case "cast:receivedSessionMessage": {
const { sessionId, namespace, messageData } = message.data; const { sessionId, namespace, messageData } = message.data;
const session = sessions.get(sessionId); const session = sessions.get(sessionId);
if (session) { if (session) {
@@ -337,7 +337,7 @@ onMessage(message => {
break; break;
} }
case "shim:impl_sendCastMessage": { case "cast:impl_sendMessage": {
const { sessionId, messageId, error } = message.data; const { sessionId, messageId, error } = message.data;
const session = sessions.get(sessionId); const session = sessions.get(sessionId);
@@ -360,7 +360,7 @@ onMessage(message => {
break; break;
} }
case "shim:serviceUp": { case "cast:serviceUp": {
const { receiverDevice } = message.data; const { receiverDevice } = message.data;
if (receiverDevices.has(receiverDevice.id)) { if (receiverDevices.has(receiverDevice.id)) {
break; break;
@@ -376,7 +376,7 @@ onMessage(message => {
break; break;
} }
case "shim:serviceDown": { case "cast:serviceDown": {
const { receiverDeviceId } = message.data; const { receiverDeviceId } = message.data;
receiverDevices.delete(receiverDeviceId); receiverDevices.delete(receiverDeviceId);
@@ -392,7 +392,7 @@ onMessage(message => {
break; break;
} }
case "shim:selectReceiver/selected": { case "cast:selectReceiver/selected": {
logger.info("Selected receiver"); logger.info("Selected receiver");
if (!sessionRequest) { if (!sessionRequest) {
@@ -403,7 +403,7 @@ onMessage(message => {
break; break;
} }
case "shim:selectReceiver/stopped": { case "cast:selectReceiver/stopped": {
const { receiver } = message.data; const { receiver } = message.data;
logger.info("Stopped receiver"); logger.info("Stopped receiver");
@@ -427,7 +427,7 @@ onMessage(message => {
/** /**
* Popup closed before session established. * Popup closed before session established.
*/ */
case "shim:selectReceiver/cancelled": { case "cast:selectReceiver/cancelled": {
if (sessionRequest) { if (sessionRequest) {
sessionRequest = null; sessionRequest = null;

View File

View File

View File

@@ -1,22 +1,21 @@
"use strict"; "use strict";
import { loadScript } from "../lib/utils";
import { onMessageResponse, sendMessage } from "./eventMessageChannel"; import { onMessageResponse, sendMessage } from "./eventMessageChannel";
import messaging, { Message } from "../messaging"; import messaging, { Message } from "../messaging";
// Message port to background script // Message port to background script
export const backgroundPort = messaging.connect({ name: "shim" }); export const backgroundPort = messaging.connect({ name: "cast" });
const forwardToShim = (message: Message) => sendMessage(message); const forwardToCast = (message: Message) => sendMessage(message);
const forwardToMain = (message: Message) => backgroundPort.postMessage(message); const forwardToMain = (message: Message) => backgroundPort.postMessage(message);
// Add message listeners // Add message listeners
backgroundPort.onMessage.addListener(forwardToShim); backgroundPort.onMessage.addListener(forwardToCast);
const listener = onMessageResponse(forwardToMain); const listener = onMessageResponse(forwardToMain);
// Remove listeners // Remove listeners
backgroundPort.onDisconnect.addListener(() => { backgroundPort.onDisconnect.addListener(() => {
backgroundPort.onMessage.removeListener(forwardToShim); backgroundPort.onMessage.removeListener(forwardToCast);
listener.disconnect(); listener.disconnect();
}); });

View File

@@ -1,6 +1,6 @@
"use strict"; "use strict";
import * as cast from "./cast"; import * as cast from "./api";
import { Message } from "../messaging"; import { Message } from "../messaging";
import { BridgeInfo } from "../lib/bridge"; import { BridgeInfo } from "../lib/bridge";
@@ -18,9 +18,9 @@ let initializedBackgroundPort: MessagePort;
/** /**
* To support exporting an API from a module, we need to * To support exporting an API from a module, we need to
* retain the event-based message passing despite not * retain the event-based message passing despite not
* actually crossing any context boundaries. The shim listens * actually crossing any context boundaries. The cast instance
* for and emits these messages, and changing that behavior * listens for and emits these messages, and changing that
* is too messy. * behavior is too messy.
*/ */
export function ensureInit(): Promise<TypedMessagePort<Message>> { export function ensureInit(): Promise<TypedMessagePort<Message>> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
@@ -45,24 +45,24 @@ export function ensureInit(): Promise<TypedMessagePort<Message>> {
* URL. * URL.
*/ */
if (window.location.protocol === "moz-extension:") { if (window.location.protocol === "moz-extension:") {
const { default: ShimManager } = await import( const { default: CastManager } = await import(
"../background/ShimManager" "../background/CastManager"
); );
// port2 will post bridge messages to port 1 // port2 will post bridge messages to port 1
await ShimManager.init(); await CastManager.init();
await ShimManager.createShim(channel.port2); await CastManager.createInstance(channel.port2);
// bridge -> shim // bridge -> cast instance
channel.port1.onmessage = ev => { channel.port1.onmessage = ev => {
const message = ev.data as Message; const message = ev.data as Message;
// Send message to shim // Send message to cast instance
sendMessage(message); sendMessage(message);
handleIncomingMessageToShim(message); handleIncomingMessageToCast(message);
}; };
// shim -> bridge // cast instance -> bridge
onMessageResponse(message => { onMessageResponse(message => {
channel.port1.postMessage(message); channel.port1.postMessage(message);
}); });
@@ -85,13 +85,13 @@ export function ensureInit(): Promise<TypedMessagePort<Message>> {
backgroundPort.postMessage(message); backgroundPort.postMessage(message);
}; };
// Handle shim messages // Handle cast messages
onMessage(handleIncomingMessageToShim); onMessage(handleIncomingMessageToCast);
} }
function handleIncomingMessageToShim(message: Message) { function handleIncomingMessageToCast(message: Message) {
switch (message.subject) { switch (message.subject) {
case "shim:initialized": { case "cast:initialized": {
initializedBridgeInfo = message.data; initializedBridgeInfo = message.data;
if (initializedBridgeInfo.isVersionCompatible) { if (initializedBridgeInfo.isVersionCompatible) {

View File

@@ -1,6 +1,6 @@
"use strict"; "use strict";
import * as cast from "../../cast"; import * as cast from "../../api";
export default class ApplicationMetadata { export default class ApplicationMetadata {
public applicationId: string; public applicationId: string;

View File

@@ -1,6 +1,6 @@
"use strict"; "use strict";
import * as cast from "../../cast"; import * as cast from "../../api";
export default class CastOptions { export default class CastOptions {
public autoJoinPolicy: string = cast.AutoJoinPolicy.TAB_AND_ORIGIN_SCOPED; public autoJoinPolicy: string = cast.AutoJoinPolicy.TAB_AND_ORIGIN_SCOPED;

View File

@@ -2,7 +2,7 @@
import logger from "../../../lib/logger"; import logger from "../../../lib/logger";
import * as cast from "../../cast"; import * as cast from "../../api";
import ApplicationMetadata from "./ApplicationMetadata"; import ApplicationMetadata from "./ApplicationMetadata";
@@ -91,17 +91,17 @@ export default class CastSession extends EventTarget {
_namespace: string, _namespace: string,
// @ts-ignore // @ts-ignore
_data: any _data: any
): Promise<string> { ): Promise<void> {
logger.info("STUB :: CastSession#sendMessage"); logger.info("STUB :: CastSession#sendMessage");
} }
// @ts-ignore // @ts-ignore
public setMute(_isMute: boolean): Promise<string> { public setMute(_isMute: boolean): Promise<void> {
logger.info("STUB :: CastSession#setMute"); logger.info("STUB :: CastSession#setMute");
} }
// @ts-ignore // @ts-ignore
public setVolume(_volume: number): Promise<string> { public setVolume(_volume: number): Promise<void> {
logger.info("STUB :: CastSession#setVolume"); logger.info("STUB :: CastSession#setVolume");
} }
} }

View File

@@ -1,6 +1,6 @@
"use strict"; "use strict";
import * as cast from "../../cast"; import * as cast from "../../api";
import EventData from "./EventData"; import EventData from "./EventData";

View File

@@ -1,6 +1,6 @@
"use strict"; "use strict";
import * as cast from "../../cast"; import * as cast from "../../api";
import RemotePlayerController from "./RemotePlayerController"; import RemotePlayerController from "./RemotePlayerController";

4
ext/src/shim/index.ts → ext/src/cast/index.ts Executable file → Normal file
View File

@@ -1,6 +1,6 @@
"use strict"; "use strict";
import * as cast from "./cast"; import * as cast from "./api";
import { CAST_FRAMEWORK_SCRIPT_URL } from "../lib/endpoints"; import { CAST_FRAMEWORK_SCRIPT_URL } from "../lib/endpoints";
import { loadScript } from "../lib/utils"; import { loadScript } from "../lib/utils";
@@ -60,7 +60,7 @@ if (document.currentScript) {
onMessage(message => { onMessage(message => {
switch (message.subject) { switch (message.subject) {
case "shim:initialized": { case "cast:initialized": {
bridgeInfo = message.data; bridgeInfo = message.data;
if (!isFramework) { if (!isFramework) {

View File

@@ -1,7 +1,7 @@
"use strict"; "use strict";
import { Error as Error_ } from "./cast/dataClasses"; import { Error as Error_ } from "./api/dataClasses";
import { Media } from "./cast/media"; import { Media } from "./api/media";
export type SuccessCallback = () => void; export type SuccessCallback = () => void;
export type ErrorCallback = (err: Error_) => void; export type ErrorCallback = (err: Error_) => void;

View File

@@ -9,7 +9,7 @@ import {
ReceiverSelectorMediaType ReceiverSelectorMediaType
} from "../background/receiverSelector"; } from "../background/receiverSelector";
import ShimManager from "../background/ShimManager"; import CastManager from "../background/CastManager";
interface LoadSenderOptions { interface LoadSenderOptions {
tabId: number; tabId: number;
@@ -33,15 +33,15 @@ export default async function loadSender(opts: LoadSenderOptions) {
switch (opts.selection.mediaType) { switch (opts.selection.mediaType) {
case ReceiverSelectorMediaType.App: { case ReceiverSelectorMediaType.App: {
const shim = ShimManager.getShim(opts.tabId, opts.frameId); const instance = CastManager.getInstance(opts.tabId, opts.frameId);
if (!shim) { if (!instance) {
throw logger.error( throw logger.error(
`Shim not found at tabId ${opts.tabId} / frameId ${opts.frameId}` `Cast instance not found at tabId ${opts.tabId} / frameId ${opts.frameId}`
); );
} }
shim.contentPort.postMessage({ instance.contentPort.postMessage({
subject: "shim:launchApp", subject: "cast:launchApp",
data: { receiver: opts.selection.receiver } data: { receiver: opts.selection.receiver }
}); });

View File

@@ -32,7 +32,7 @@
{ {
"all_frames": true "all_frames": true
, "js": [ , "js": [
"shim/content.js" "cast/content.js"
] ]
, "matches": [ "<all_urls>" ] , "matches": [ "<all_urls>" ]
, "run_at": "document_start" , "run_at": "document_start"
@@ -65,7 +65,7 @@
, "<all_urls>" , "<all_urls>"
] ]
, "web_accessible_resources": [ , "web_accessible_resources": [
"shim/index.js" "cast/index.js"
, "senders/media/overlay/overlayContent.js" , "senders/media/overlay/overlayContent.js"
, "senders/media/overlay/AirPlay_Audio.svg" , "senders/media/overlay/AirPlay_Audio.svg"
, "senders/media/overlay/AirPlay_Video.svg" , "senders/media/overlay/AirPlay_Video.svg"

View File

@@ -16,7 +16,7 @@ import {
MediaStatus, MediaStatus,
ReceiverStatus, ReceiverStatus,
SenderMessage SenderMessage
} from "./shim/cast/types"; } from "./cast/api/types";
import { ReceiverDevice } from "./types"; import { ReceiverDevice } from "./types";
@@ -47,18 +47,23 @@ type ExtMessageDefinitions = {
availableMediaTypes?: ReceiverSelectorMediaType; availableMediaTypes?: ReceiverSelectorMediaType;
}; };
"popup:close": {}; "popup:close": {};
"receiverSelector:selected": ReceiverSelection; "receiverSelector:selected": ReceiverSelection;
"receiverSelector:stop": ReceiverSelection; "receiverSelector:stop": ReceiverSelection;
"main:shimReady": { appId: string };
"main:castReady": { appId: string };
"main:selectReceiver": {}; "main:selectReceiver": {};
"shim:selectReceiver/selected": ReceiverSelectionCast; "cast:selectReceiver/selected": ReceiverSelectionCast;
"shim:selectReceiver/stopped": ReceiverSelectionStop; "cast:selectReceiver/stopped": ReceiverSelectionStop;
"shim:selectReceiver/cancelled": {}; "cast:selectReceiver/cancelled": {};
"main:sessionCreated": {}; "main:sessionCreated": {};
"shim:initialized": BridgeInfo;
"shim:serviceUp": { receiverDevice: ReceiverDevice }; "cast:initialized": BridgeInfo;
"shim:serviceDown": { receiverDeviceId: ReceiverDevice["id"] }; "cast:serviceUp": { receiverDevice: ReceiverDevice };
"shim:launchApp": { receiver: ReceiverDevice }; "cast:serviceDown": { receiverDeviceId: ReceiverDevice["id"] };
"cast:launchApp": { receiver: ReceiverDevice };
}; };
/** /**
@@ -67,17 +72,17 @@ type ExtMessageDefinitions = {
* app/src/bridge/messaging.ts > MessageDefinitions * app/src/bridge/messaging.ts > MessageDefinitions
*/ */
type AppMessageDefinitions = { type AppMessageDefinitions = {
"shim:castSessionCreated": CastSessionCreated; "cast:sessionCreated": CastSessionCreated;
"shim:castSessionUpdated": CastSessionUpdated; "cast:sessionUpdated": CastSessionUpdated;
"shim:castSessionStopped": { "cast:sessionStopped": {
sessionId: string; sessionId: string;
}; };
"shim:receivedCastSessionMessage": { "cast:receivedSessionMessage": {
sessionId: string; sessionId: string;
namespace: string; namespace: string;
messageData: string; messageData: string;
}; };
"shim:impl_sendCastMessage": { "cast:impl_sendMessage": {
sessionId: string; sessionId: string;
messageId: string; messageId: string;
error?: string; error?: string;

View File

@@ -2,7 +2,7 @@
import logger from "../../lib/logger"; import logger from "../../lib/logger";
import options from "../../lib/options"; import options from "../../lib/options";
import cast, { ensureInit } from "../../shim/export"; import cast, { ensureInit } from "../../cast/export";
import { Message } from "../../messaging"; import { Message } from "../../messaging";
import { ReceiverDevice } from "../../types"; import { ReceiverDevice } from "../../types";
@@ -363,7 +363,7 @@ export async function init(opts: InitOptions) {
if (targetElement instanceof HTMLMediaElement) { if (targetElement instanceof HTMLMediaElement) {
registerMediaElementListeners(targetElement); registerMediaElementListeners(targetElement);
if (options.get("mediaOverlayEnabled")) { if (await options.get("mediaOverlayEnabled")) {
// TODO: Un-hide overlay here // TODO: Un-hide overlay here
} }
} }

View File

@@ -1,7 +1,7 @@
"use strict"; "use strict";
import options from "../lib/options"; import options from "../lib/options";
import cast, { ensureInit } from "../shim/export"; import cast, { ensureInit } from "../cast/export";
import { ReceiverSelectorMediaType } from "../background/receiverSelector"; import { ReceiverSelectorMediaType } from "../background/receiverSelector";
import { ReceiverDevice } from "../types"; import { ReceiverDevice } from "../types";

View File

@@ -1,6 +1,6 @@
"use strict"; "use strict";
import { ReceiverStatus } from "./shim/cast/types"; import { ReceiverStatus } from "./cast/api/types";
export interface ReceiverDevice { export interface ReceiverDevice {
host: string; host: string;