mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-08 08:39:59 +00:00
Implement chrome.cast.requestSessionById
This commit is contained in:
@@ -48,7 +48,7 @@ interface CastSession {
|
|||||||
deviceId: string;
|
deviceId: string;
|
||||||
appId: string;
|
appId: string;
|
||||||
sessionId?: string;
|
sessionId?: string;
|
||||||
initialContentContext?: ContentContext;
|
autoJoinContexts: ContentContext[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a cast session object and sets up messaging. */
|
/** Creates a cast session object and sets up messaging. */
|
||||||
@@ -71,9 +71,13 @@ async function createCastSession(opts: {
|
|||||||
bridgePort: await bridge.connect(),
|
bridgePort: await bridge.connect(),
|
||||||
deviceId: opts.deviceId,
|
deviceId: opts.deviceId,
|
||||||
appId: opts.appId,
|
appId: opts.appId,
|
||||||
initialContentContext: opts.instance.contentContext
|
autoJoinContexts: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (opts.instance.contentContext) {
|
||||||
|
session.autoJoinContexts.push(opts.instance.contentContext);
|
||||||
|
}
|
||||||
|
|
||||||
opts.instance.session = session;
|
opts.instance.session = session;
|
||||||
opts.instance.bridgeMessageListener = message => {
|
opts.instance.bridgeMessageListener = message => {
|
||||||
handleBridgeMessage(opts.instance, message);
|
handleBridgeMessage(opts.instance, message);
|
||||||
@@ -96,6 +100,56 @@ async function createCastSession(opts: {
|
|||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function joinSession(instance: CastInstance, session: CastSession) {
|
||||||
|
if (!session.sessionId) return;
|
||||||
|
|
||||||
|
instance.session = session;
|
||||||
|
instance.bridgeMessageListener = message =>
|
||||||
|
handleBridgeMessage(instance, message);
|
||||||
|
|
||||||
|
session.bridgePort.onMessage.addListener(instance.bridgeMessageListener);
|
||||||
|
session.bridgePort.onDisconnect.addListener(() =>
|
||||||
|
destroyCastInstance(instance)
|
||||||
|
);
|
||||||
|
|
||||||
|
const device = deviceManager.getDeviceById(session.deviceId);
|
||||||
|
if (!device?.status?.applications?.length) {
|
||||||
|
throw logger.error("Invalid device state!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-create sessionCreated message. Since the
|
||||||
|
* sender app hasn't requested a session, this
|
||||||
|
* will be handled by calling the session
|
||||||
|
* listener.
|
||||||
|
*/
|
||||||
|
const application = device?.status?.applications[0];
|
||||||
|
instance.contentPort.postMessage({
|
||||||
|
subject: "cast:sessionCreated",
|
||||||
|
data: {
|
||||||
|
appId: application.appId,
|
||||||
|
appImages: [],
|
||||||
|
displayName: application.displayName,
|
||||||
|
namespaces: application.namespaces,
|
||||||
|
receiver: createReceiver(device),
|
||||||
|
receiverFriendlyName: device.friendlyName,
|
||||||
|
receiverId: device.id,
|
||||||
|
senderApps: [],
|
||||||
|
sessionId: session.sessionId,
|
||||||
|
statusText: application.statusText,
|
||||||
|
transportId: session.sessionId,
|
||||||
|
volume: device.status.volume
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (instance.contentContext?.tabId) {
|
||||||
|
updateActionState(
|
||||||
|
ActionState.Connected,
|
||||||
|
instance.contentContext?.tabId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface CastInstance {
|
export interface CastInstance {
|
||||||
contentPort: AnyPort;
|
contentPort: AnyPort;
|
||||||
contentContext?: ContentContext;
|
contentContext?: ContentContext;
|
||||||
@@ -180,6 +234,7 @@ function destroyCastInstance(instance: CastInstance) {
|
|||||||
const allowedContentMessages: Array<Message["subject"]> = [
|
const allowedContentMessages: Array<Message["subject"]> = [
|
||||||
"main:initializeCastSdk",
|
"main:initializeCastSdk",
|
||||||
"main:requestSession",
|
"main:requestSession",
|
||||||
|
"main:requestSessionById",
|
||||||
"bridge:sendCastReceiverMessage",
|
"bridge:sendCastReceiverMessage",
|
||||||
"bridge:sendCastSessionMessage"
|
"bridge:sendCastSessionMessage"
|
||||||
];
|
];
|
||||||
@@ -493,75 +548,29 @@ async function handleContentMessage(instance: CastInstance, message: Message) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (instance.apiConfig.autoJoinPolicy) {
|
// Check for valid auto join sessions
|
||||||
case AutoJoinPolicy.TAB_AND_ORIGIN_SCOPED:
|
const { autoJoinPolicy } = instance.apiConfig;
|
||||||
// Ensure matching content tontext
|
if (
|
||||||
|
autoJoinPolicy === AutoJoinPolicy.ORIGIN_SCOPED ||
|
||||||
|
autoJoinPolicy === AutoJoinPolicy.TAB_AND_ORIGIN_SCOPED
|
||||||
|
) {
|
||||||
|
for (const context of session.autoJoinContexts) {
|
||||||
|
// Check same origin
|
||||||
if (
|
if (
|
||||||
!isSameContext(
|
context.origin !== instance.contentContext?.origin
|
||||||
instance.contentContext,
|
) {
|
||||||
session.initialContentContext
|
continue;
|
||||||
)
|
}
|
||||||
)
|
// Check same context for tab scoped
|
||||||
break;
|
|
||||||
// eslint-disable-next-line no-fallthrough
|
|
||||||
case AutoJoinPolicy.ORIGIN_SCOPED: {
|
|
||||||
// Ensure matching origin
|
|
||||||
if (
|
if (
|
||||||
instance.contentContext?.origin !==
|
autoJoinPolicy ===
|
||||||
session.initialContentContext?.origin
|
AutoJoinPolicy.TAB_AND_ORIGIN_SCOPED &&
|
||||||
)
|
!isSameContext(context, instance.contentContext)
|
||||||
break;
|
) {
|
||||||
|
continue;
|
||||||
instance.session = session;
|
|
||||||
instance.bridgeMessageListener = message =>
|
|
||||||
handleBridgeMessage(instance, message);
|
|
||||||
|
|
||||||
session.bridgePort.onMessage.addListener(
|
|
||||||
instance.bridgeMessageListener
|
|
||||||
);
|
|
||||||
session.bridgePort.onDisconnect.addListener(() =>
|
|
||||||
destroyCastInstance(instance)
|
|
||||||
);
|
|
||||||
|
|
||||||
const device = deviceManager.getDeviceById(
|
|
||||||
session.deviceId
|
|
||||||
);
|
|
||||||
if (!device?.status?.applications?.length) {
|
|
||||||
throw logger.error("Invalid device state");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-create sessionCreated message. Since the
|
|
||||||
* sender app hasn't requested a session, this
|
|
||||||
* will be handled by calling the session
|
|
||||||
* listener.
|
|
||||||
*/
|
|
||||||
const application = device?.status?.applications[0];
|
|
||||||
instance.contentPort.postMessage({
|
|
||||||
subject: "cast:sessionCreated",
|
|
||||||
data: {
|
|
||||||
appId: application.appId,
|
|
||||||
appImages: [],
|
|
||||||
displayName: application.displayName,
|
|
||||||
namespaces: application.namespaces,
|
|
||||||
receiver: createReceiver(device),
|
|
||||||
receiverFriendlyName: device.friendlyName,
|
|
||||||
receiverId: device.id,
|
|
||||||
senderApps: [],
|
|
||||||
sessionId: session.sessionId,
|
|
||||||
statusText: application.statusText,
|
|
||||||
transportId: session.sessionId,
|
|
||||||
volume: device.status.volume
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (instance.contentContext?.tabId) {
|
|
||||||
updateActionState(
|
|
||||||
ActionState.Connected,
|
|
||||||
instance.contentContext?.tabId
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
joinSession(instance, session);
|
||||||
break sessionLoop;
|
break sessionLoop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -666,6 +675,27 @@ async function handleContentMessage(instance: CastInstance, message: Message) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "main:requestSessionById": {
|
||||||
|
const session = activeSessions.get(message.data.sessionId);
|
||||||
|
if (!session) {
|
||||||
|
logger.log(
|
||||||
|
`Session not found! (id: ${message.data.sessionId})`
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance.apiConfig?.sessionRequest.appId === session.appId) {
|
||||||
|
joinSession(instance, session);
|
||||||
|
|
||||||
|
// If requesting by ID, add to the list of auto join contexts
|
||||||
|
if (instance.contentContext) {
|
||||||
|
session.autoJoinContexts.push(instance.contentContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -349,8 +349,11 @@ export default class {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
requestSessionById(_sessionId: string) {
|
requestSessionById(sessionId: string) {
|
||||||
logger.info("STUB :: cast.requestSessionById");
|
pageMessaging.page.sendMessage({
|
||||||
|
subject: "main:requestSessionById",
|
||||||
|
data: { sessionId }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setCustomReceivers(
|
setCustomReceivers(
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ type ExtMessageDefinitions = {
|
|||||||
/** Return message to the cast API when a selection is cancelled. */
|
/** Return message to the cast API when a selection is cancelled. */
|
||||||
"cast:sessionRequestCancelled": undefined;
|
"cast:sessionRequestCancelled": undefined;
|
||||||
|
|
||||||
|
"main:requestSessionById": { sessionId: string };
|
||||||
|
|
||||||
"cast:instanceCreated": { isAvailable: boolean };
|
"cast:instanceCreated": { isAvailable: boolean };
|
||||||
"cast:receiverAvailabilityUpdated": { isAvailable: boolean };
|
"cast:receiverAvailabilityUpdated": { isAvailable: boolean };
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user