Add availableMediaTypes bitmask to receiver selector open method

This commit is contained in:
hensm
2019-07-09 10:56:55 +01:00
parent 43fcd5b351
commit 70e05566fa
14 changed files with 100 additions and 29 deletions

View File

@@ -66,14 +66,43 @@ class ViewController : NSViewController {
self.mediaTypePopUpButton = NSPopUpButton()
self.mediaTypePopUpButton.autoenablesItems = false
self.mediaTypePopUpButton.addItems(withTitles: [
initData.i18n_mediaTypeApp
, initData.i18n_mediaTypeTab
, initData.i18n_mediaTypeScreen
])
let appItem = self.mediaTypePopUpButton
.item(withTitle: initData.i18n_mediaTypeApp)!
let tabItem = self.mediaTypePopUpButton
.item(withTitle: initData.i18n_mediaTypeTab)!
let screenItem = self.mediaTypePopUpButton
.item(withTitle: initData.i18n_mediaTypeScreen)!
// Set tags to enum value
appItem.tag = MediaType.app.rawValue
tabItem.tag = MediaType.tab.rawValue
screenItem.tag = MediaType.screen.rawValue
if (initData.availableMediaTypes & appItem.tag) == 0 {
self.mediaTypePopUpButton
.item(withTitle: initData.i18n_mediaTypeApp)?
.isEnabled = false
}
if (initData.availableMediaTypes & tabItem.tag) == 0 {
self.mediaTypePopUpButton
.item(withTitle: initData.i18n_mediaTypeTab)?
.isEnabled = false
}
if (initData.availableMediaTypes & screenItem.tag) == 0 {
self.mediaTypePopUpButton
.item(withTitle: initData.i18n_mediaTypeScreen)?
.isEnabled = false
}
self.mediaTypePopUpButton.selectItem(
at: initData.defaultMediaType.rawValue)
withTag: initData.defaultMediaType.rawValue)
let mediaTypeStackView = NSStackView(views: [
@@ -140,7 +169,7 @@ extension ViewController : ReceiverViewDelegate {
do {
let mediaType = MediaType(
rawValue: self.mediaTypePopUpButton.indexOfSelectedItem)!
rawValue: self.mediaTypePopUpButton.selectedItem!.tag)!
let selection = ReceiverSelection(
receiver: receiver

View File

@@ -1,6 +1,7 @@
struct InitData : Codable {
let receivers: [Receiver]
let defaultMediaType: MediaType
let availableMediaTypes: Int
let i18n_extensionName: String
let i18n_castButtonTitle: String

View File

@@ -1,3 +1,8 @@
enum MediaType : Int, Codable {
case app, tab, screen
import Foundation
enum MediaType: Int, Codable {
case app = 1
case tab = 2
case screen = 4
}

3
ext/src/global.d.ts vendored
View File

@@ -37,7 +37,8 @@ declare interface RTCPeerConnection {
}
declare interface MediaDevices {
getDisplayMedia(constraints: MediaStreamConstraints): Promise<MediaStream>;
getDisplayMedia (constraints: MediaStreamConstraints)
: Promise<MediaStream>;
}

View File

@@ -541,7 +541,7 @@ async function initCreateStatusBridge (opts: Options) {
*/
function onStatusBridgeDisconnect () {
// Notify shims for receiver availability
for (const [ , receiver ] of statusBridgeReceivers) {
for (const [, receiver ] of statusBridgeReceivers) {
for (const [, shim ] of shimMap) {
shim.port.postMessage({
subject: "shim:/serviceDown"
@@ -752,7 +752,8 @@ async function onConnectShim (port: browser.runtime.Port) {
case "main:/selectReceiverBegin": {
receiverSelector.open(
Array.from(statusBridgeReceivers.values())
, message.data.defaultMediaType);
, message.data.defaultMediaType
, message.data.availableMediaTypes);
break;
}

View File

@@ -28,7 +28,8 @@ export default class NativeMacReceiverSelector
public async open (
receivers: Receiver[]
, defaultMediaType: ReceiverSelectorMediaType): Promise<void> {
, defaultMediaType: ReceiverSelectorMediaType
, availableMediaTypes: ReceiverSelectorMediaType): Promise<void> {
const applicationName = await options.get("bridgeApplicationName");
this.bridgePort = nativeMessaging.connectNative(applicationName);
@@ -62,6 +63,7 @@ export default class NativeMacReceiverSelector
, data: JSON.stringify({
receivers
, defaultMediaType
, availableMediaTypes
, i18n_extensionName: _("extensionName")
, i18n_castButtonTitle: _("popupCastButtonTitle")

View File

@@ -17,6 +17,7 @@ export default class PopupReceiverSelector
private receivers: Receiver[];
private defaultMediaType: ReceiverSelectorMediaType;
private availableMediaTypes: ReceiverSelectorMediaType;
private wasReceiverSelected: boolean = false;
@@ -53,6 +54,7 @@ export default class PopupReceiverSelector
, data: {
receivers: this.receivers
, defaultMediaType: this.defaultMediaType
, availableMediaTypes: this.availableMediaTypes
}
});
});
@@ -61,7 +63,8 @@ export default class PopupReceiverSelector
public async open (
receivers: Receiver[]
, defaultMediaType: ReceiverSelectorMediaType): Promise<void> {
, defaultMediaType: ReceiverSelectorMediaType
, availableMediaTypes: ReceiverSelectorMediaType): Promise<void> {
// If popup already exists, close it
if (this.windowId) {
@@ -70,6 +73,7 @@ export default class PopupReceiverSelector
this.receivers = receivers;
this.defaultMediaType = defaultMediaType;
this.availableMediaTypes = availableMediaTypes;
// Current window to base centered position on
const openerWindow = await browser.windows.getCurrent();

View File

@@ -4,9 +4,9 @@ import { Receiver } from "../types";
export enum ReceiverSelectorMediaType {
App
, Tab
, Screen
App = 1
, Tab = 2
, Screen = 4
}
export interface ReceiverSelection {
@@ -21,7 +21,8 @@ export type ReceiverSelectorCancelledEvent = CustomEvent;
export default interface ReceiverSelector extends EventTarget {
open (receivers: Receiver[]
, defaultMediaType: ReceiverSelectorMediaType): void;
, defaultMediaType: ReceiverSelectorMediaType
, availableMediaTypes: ReceiverSelectorMediaType): void;
close (): void;
}

View File

@@ -22,6 +22,21 @@ let peerConnection: RTCPeerConnection;
let drawWindowIntervalId: number;
let availableMediaTypes =
ReceiverSelectorMediaType.Screen
| ReceiverSelectorMediaType.Tab;
/**
* Remove "Screen" option when on an insecure origin as
* MediaDevices.getDisplayMedia will not exist (and legacy
* MediaDevices.getUserMedia mediaSource constraint will
* fail).
*/
if (typeof navigator.mediaDevices.getDisplayMedia === "undefined") {
availableMediaTypes &= ~ReceiverSelectorMediaType.Screen;
}
/**
* Sends a message to the fx_cast app running on the
* receiver device.
@@ -70,7 +85,6 @@ async function onRequestSessionSuccess (
switch (newSelectedMedia) {
case ReceiverSelectorMediaType.Tab: {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
@@ -118,7 +132,6 @@ async function onRequestSessionSuccess (
}
case ReceiverSelectorMediaType.Screen: {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: { cursor: "motion" }
, audio: false
@@ -142,8 +155,11 @@ async function onRequestSessionSuccess (
function receiverListener (availability: string) {
cast.logMessage("receiverListener");
if (!wasSessionRequested
&& availability === cast.ReceiverAvailability.AVAILABLE) {
if (wasSessionRequested) {
return;
}
if (availability === cast.ReceiverAvailability.AVAILABLE) {
wasSessionRequested = true;
cast.requestSession(
onRequestSessionSuccess
@@ -181,7 +197,8 @@ init().then(async bridgeInfo => {
, sessionListener
, receiverListener
, undefined, undefined
, selectedMedia);
, selectedMedia
, availableMediaTypes);
cast.initialize(apiConfig
, onInitializeSuccess

View File

@@ -26,7 +26,11 @@ export default class ApiConfig {
= DefaultActionPolicy.CREATE_SESSION
// TODO: Remove awful hack for mirror casting
, public _selectedMedia: ReceiverSelectorMediaType
= ReceiverSelectorMediaType.App) {
, public _defaultMediaType: ReceiverSelectorMediaType
= ReceiverSelectorMediaType.App
, public _availableMediaTypes: ReceiverSelectorMediaType
= ReceiverSelectorMediaType.App
| ReceiverSelectorMediaType.Tab
| ReceiverSelectorMediaType.Screen) {
}
}

View File

@@ -160,7 +160,8 @@ export function requestSession (
sendMessageResponse({
subject: "main:/selectReceiverBegin"
, data: {
defaultMediaType: apiConfig._selectedMedia
defaultMediaType: apiConfig._defaultMediaType
, availableMediaTypes: apiConfig._availableMediaTypes
}
});
}

View File

@@ -1,7 +1,7 @@
"use strict";
import { onMessageResponse, sendMessage } from "./eventMessageChannel";
import { loadScript } from "../lib/utils";
import { onMessageResponse, sendMessage } from "./eventMessageChannel";
const { isFramework }

View File

@@ -28,6 +28,7 @@ browser.runtime.getPlatformInfo()
interface PopupAppState {
receivers: Receiver[];
mediaType: ReceiverSelectorMediaType;
availableMediaTypes: ReceiverSelectorMediaType;
isLoading: boolean;
}
@@ -41,6 +42,7 @@ class PopupApp extends Component<{}, PopupAppState> {
this.state = {
receivers: []
, mediaType: ReceiverSelectorMediaType.App
, availableMediaTypes: ReceiverSelectorMediaType.App
, isLoading: false
};
@@ -64,6 +66,7 @@ class PopupApp extends Component<{}, PopupAppState> {
this.setState({
receivers: message.data.receivers
, mediaType: message.data.defaultMediaType
, availableMediaTypes: message.data.availableMediaTypes
});
break;
@@ -90,10 +93,6 @@ class PopupApp extends Component<{}, PopupAppState> {
}
public render () {
const shareMedia =
this.state.mediaType === ReceiverSelectorMediaType.Tab
|| this.state.mediaType === ReceiverSelectorMediaType.Screen;
return (
<div>
<div className="media-select">
@@ -102,15 +101,18 @@ class PopupApp extends Component<{}, PopupAppState> {
onChange={ this.onSelectChange }
className="media-select-dropdown">
<option value={ ReceiverSelectorMediaType.App }
disabled={ shareMedia }>
disabled={ !(this.state.availableMediaTypes
& ReceiverSelectorMediaType.App) }>
{ _("popupMediaTypeApp") }
</option>
<option value={ ReceiverSelectorMediaType.Tab }
disabled={ !shareMedia }>
disabled={ !(this.state.availableMediaTypes
& ReceiverSelectorMediaType.Tab) }>
{ _("popupMediaTypeTab") }
</option>
<option value={ ReceiverSelectorMediaType.Screen }
disabled={ !shareMedia }>
disabled={ !(this.state.availableMediaTypes
& ReceiverSelectorMediaType.Screen) }>
{ _("popupMediaTypeScreen") }
</option>
</select>

View File

@@ -2,4 +2,7 @@
"extends": [
"../common/tslint.json"
]
, "rules": {
"no-bitwise": false
}
}