mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-12 02:29:59 +00:00
Filter receiver list depending on capabilities in session request
This commit is contained in:
@@ -6,7 +6,7 @@ import { TypedEventTarget } from "../lib/TypedEventTarget";
|
|||||||
|
|
||||||
import { Message, Port } from "../messaging";
|
import { Message, Port } from "../messaging";
|
||||||
import { ReceiverDevice, ReceiverDeviceCapabilities } from "../types";
|
import { ReceiverDevice, ReceiverDeviceCapabilities } from "../types";
|
||||||
import { ReceiverStatus } from "../cast/api/types";
|
import { ReceiverStatus } from "../cast/sdk/types";
|
||||||
|
|
||||||
interface EventMap {
|
interface EventMap {
|
||||||
receiverDeviceUp: { deviceInfo: ReceiverDevice };
|
receiverDeviceUp: { deviceInfo: ReceiverDevice };
|
||||||
@@ -84,16 +84,6 @@ export default new (class extends TypedEventTarget<EventMap> {
|
|||||||
case "main:receiverDeviceUp": {
|
case "main:receiverDeviceUp": {
|
||||||
const { deviceId, deviceInfo } = message.data;
|
const { deviceId, deviceInfo } = message.data;
|
||||||
|
|
||||||
// TODO: Add proper support for Chromecast Audio devices
|
|
||||||
if (
|
|
||||||
!(
|
|
||||||
deviceInfo.capabilities &
|
|
||||||
ReceiverDeviceCapabilities.VIDEO_OUT
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.receiverDevices.set(deviceId, deviceInfo);
|
this.receiverDevices.set(deviceId, deviceInfo);
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent("receiverDeviceUp", {
|
new CustomEvent("receiverDeviceUp", {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import options from "../../lib/options";
|
|||||||
|
|
||||||
import { TypedEventTarget } from "../../lib/TypedEventTarget";
|
import { TypedEventTarget } from "../../lib/TypedEventTarget";
|
||||||
import { ReceiverDevice } from "../../types";
|
import { ReceiverDevice } from "../../types";
|
||||||
|
import { SessionRequest } from "../../cast/sdk/classes";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ReceiverSelectionCast,
|
ReceiverSelectionCast,
|
||||||
@@ -26,6 +27,7 @@ export interface PageInfo {
|
|||||||
url: string;
|
url: string;
|
||||||
tabId: number;
|
tabId: number;
|
||||||
frameId: number;
|
frameId: number;
|
||||||
|
sessionRequest?: SessionRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import options from "../../lib/options";
|
|||||||
import logger from "../../lib/logger";
|
import logger from "../../lib/logger";
|
||||||
|
|
||||||
import CastManager from "../../cast/CastManager";
|
import CastManager from "../../cast/CastManager";
|
||||||
|
import { SessionRequest } from "../../cast/sdk/classes";
|
||||||
import receiverDevices from "../receiverDevices";
|
import receiverDevices from "../receiverDevices";
|
||||||
|
|
||||||
import { getMediaTypesForPageUrl } from "../../lib/utils";
|
import { getMediaTypesForPageUrl } from "../../lib/utils";
|
||||||
@@ -47,7 +48,10 @@ async function getSelector() {
|
|||||||
async function getSelection(
|
async function getSelection(
|
||||||
contextTabId: number,
|
contextTabId: number,
|
||||||
contextFrameId = 0,
|
contextFrameId = 0,
|
||||||
selectionOpts?: { withMediaSender?: boolean }
|
selectionOpts?: {
|
||||||
|
sessionRequest: SessionRequest;
|
||||||
|
withMediaSender?: boolean;
|
||||||
|
}
|
||||||
): Promise<ReceiverSelection | null> {
|
): Promise<ReceiverSelection | null> {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
let castInstance = CastManager.getInstance(
|
let castInstance = CastManager.getInstance(
|
||||||
@@ -220,7 +224,8 @@ async function getSelection(
|
|||||||
? {
|
? {
|
||||||
url: pageUrl,
|
url: pageUrl,
|
||||||
tabId: contextTabId,
|
tabId: contextTabId,
|
||||||
frameId: contextFrameId
|
frameId: contextFrameId,
|
||||||
|
sessionRequest: selectionOpts?.sessionRequest
|
||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
|
|||||||
@@ -227,7 +227,8 @@ export default new (class CastManager {
|
|||||||
const selection =
|
const selection =
|
||||||
await ReceiverSelectorManager.getSelection(
|
await ReceiverSelectorManager.getSelection(
|
||||||
instance.contentTabId,
|
instance.contentTabId,
|
||||||
instance.contentFrameId
|
instance.contentFrameId,
|
||||||
|
{ sessionRequest: message.data.sessionRequest }
|
||||||
);
|
);
|
||||||
|
|
||||||
// Handle cancellation
|
// Handle cancellation
|
||||||
|
|||||||
@@ -466,7 +466,8 @@ export default class {
|
|||||||
} else {
|
} else {
|
||||||
// Open receiver selector UI
|
// Open receiver selector UI
|
||||||
sendMessageResponse({
|
sendMessageResponse({
|
||||||
subject: "main:selectReceiver"
|
subject: "main:selectReceiver",
|
||||||
|
data: { sessionRequest: this.#sessionRequest }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
ReceiverStatus,
|
ReceiverStatus,
|
||||||
SenderMessage
|
SenderMessage
|
||||||
} from "./cast/sdk/types";
|
} from "./cast/sdk/types";
|
||||||
|
import { SessionRequest } from "./cast/sdk/classes";
|
||||||
|
|
||||||
import { ReceiverDevice } from "./types";
|
import { ReceiverDevice } from "./types";
|
||||||
|
|
||||||
@@ -56,7 +57,9 @@ type ExtMessageDefinitions = {
|
|||||||
"receiverSelector:selected": ReceiverSelection;
|
"receiverSelector:selected": ReceiverSelection;
|
||||||
"receiverSelector:stop": ReceiverSelection;
|
"receiverSelector:stop": ReceiverSelection;
|
||||||
|
|
||||||
"main:selectReceiver": {};
|
"main:selectReceiver": {
|
||||||
|
sessionRequest: SessionRequest;
|
||||||
|
};
|
||||||
"cast:selectReceiver/selected": ReceiverSelectionCast;
|
"cast:selectReceiver/selected": ReceiverSelectionCast;
|
||||||
"cast:selectReceiver/stopped": ReceiverSelectionStop;
|
"cast:selectReceiver/stopped": ReceiverSelectionStop;
|
||||||
"cast:selectReceiver/cancelled": {};
|
"cast:selectReceiver/cancelled": {};
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import messaging, { Message, Port } from "../../messaging";
|
|||||||
import { getNextEllipsis } from "../../lib/utils";
|
import { getNextEllipsis } from "../../lib/utils";
|
||||||
import { RemoteMatchPattern } from "../../lib/matchPattern";
|
import { RemoteMatchPattern } from "../../lib/matchPattern";
|
||||||
|
|
||||||
import { ReceiverDevice } from "../../types";
|
import { ReceiverDevice, ReceiverDeviceCapabilities } from "../../types";
|
||||||
import { Capability } from "../../cast/sdk/enums";
|
import { Capability } from "../../cast/sdk/enums";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -32,6 +32,38 @@ browser.runtime.getPlatformInfo().then(platformInfo => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check receiver device capabilities bitflags against array of
|
||||||
|
* capability strings requested by the sender application.
|
||||||
|
*/
|
||||||
|
function hasRequiredCapabilities(
|
||||||
|
receiverDevice: ReceiverDevice,
|
||||||
|
capabilities: Capability[] = []
|
||||||
|
) {
|
||||||
|
const { capabilities: deviceCapabilities } = receiverDevice;
|
||||||
|
return capabilities.every(capability => {
|
||||||
|
switch (capability) {
|
||||||
|
case Capability.AUDIO_IN:
|
||||||
|
return deviceCapabilities & ReceiverDeviceCapabilities.AUDIO_IN;
|
||||||
|
case Capability.AUDIO_OUT:
|
||||||
|
return (
|
||||||
|
deviceCapabilities & ReceiverDeviceCapabilities.AUDIO_OUT
|
||||||
|
);
|
||||||
|
case Capability.MULTIZONE_GROUP:
|
||||||
|
return (
|
||||||
|
deviceCapabilities &
|
||||||
|
ReceiverDeviceCapabilities.MULTIZONE_GROUP
|
||||||
|
);
|
||||||
|
case Capability.VIDEO_IN:
|
||||||
|
return deviceCapabilities & ReceiverDeviceCapabilities.VIDEO_IN;
|
||||||
|
case Capability.VIDEO_OUT:
|
||||||
|
return (
|
||||||
|
deviceCapabilities & ReceiverDeviceCapabilities.VIDEO_OUT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
interface PopupAppProps {}
|
interface PopupAppProps {}
|
||||||
interface PopupAppState {
|
interface PopupAppState {
|
||||||
receiverDevices: ReceiverDevice[];
|
receiverDevices: ReceiverDevice[];
|
||||||
@@ -114,12 +146,26 @@ class PopupApp extends Component<PopupAppProps, PopupAppState> {
|
|||||||
|
|
||||||
case "popup:update": {
|
case "popup:update": {
|
||||||
const {
|
const {
|
||||||
receiverDevices: receivers,
|
receiverDevices,
|
||||||
availableMediaTypes,
|
availableMediaTypes,
|
||||||
defaultMediaType
|
defaultMediaType
|
||||||
} = message.data;
|
} = message.data;
|
||||||
|
|
||||||
this.setState({ receiverDevices: receivers });
|
this.setState({
|
||||||
|
/**
|
||||||
|
* Filter receiver devices without the required
|
||||||
|
* capabilities.
|
||||||
|
*/
|
||||||
|
receiverDevices: receiverDevices.filter(
|
||||||
|
receiverDevice => {
|
||||||
|
return hasRequiredCapabilities(
|
||||||
|
receiverDevice,
|
||||||
|
this.state.pageInfo?.sessionRequest
|
||||||
|
?.capabilities
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
if (
|
if (
|
||||||
availableMediaTypes !== undefined &&
|
availableMediaTypes !== undefined &&
|
||||||
@@ -543,9 +589,3 @@ class ReceiverEntry extends Component<ReceiverEntryProps, ReceiverEntryState> {
|
|||||||
window.addEventListener("load", () => {
|
window.addEventListener("load", () => {
|
||||||
ReactDOM.render(<PopupApp />, document.querySelector("#root"));
|
ReactDOM.render(<PopupApp />, document.querySelector("#root"));
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("contextmenu", () => {
|
|
||||||
browser.menus.overrideContext({
|
|
||||||
showDefaults: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
Reference in New Issue
Block a user