Skip to content

Commit

Permalink
Fixing the ability to choose default input in browsers when default c…
Browse files Browse the repository at this point in the history
…hanges
  • Loading branch information
RidipDe committed Jun 29, 2020
1 parent 4c1ea4a commit e9a94ed
Show file tree
Hide file tree
Showing 12 changed files with 2,885 additions and 2,636 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix multiple issues with integration tests
- Fix uuidv4 import
- Fix missing uuidv4 import in integration test.
- Fixing the ability to choose default input in browsers when default changes

## [1.10.0] - 2020-06-23

Expand Down
2 changes: 1 addition & 1 deletion demos/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"dependencies": {
"amazon-chime-sdk-js": "file:../..",
"aws-sdk": "^2.704.0",
"aws-sdk": "^2.706.0",
"bootstrap": "^4.3.1",
"compression": "^1.7.4",
"jquery": "^3.4.1",
Expand Down
6 changes: 3 additions & 3 deletions demos/serverless/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5,138 changes: 2,579 additions & 2,559 deletions docs/assets/js/search.js

Large diffs are not rendered by default.

197 changes: 160 additions & 37 deletions docs/classes/defaultdevicecontroller.html

Large diffs are not rendered by default.

16 changes: 15 additions & 1 deletion docs/classes/deviceselection.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ <h2>Index</h2>
<h3>Properties</h3>
<ul class="tsd-index-list">
<li class="tsd-kind-property tsd-parent-kind-class"><a href="deviceselection.html#constraints" class="tsd-kind-icon">constraints</a></li>
<li class="tsd-kind-property tsd-parent-kind-class"><a href="deviceselection.html#groupid" class="tsd-kind-icon">group<wbr>Id</a></li>
<li class="tsd-kind-property tsd-parent-kind-class"><a href="deviceselection.html#stream" class="tsd-kind-icon">stream</a></li>
</ul>
</section>
Expand All @@ -106,6 +107,16 @@ <h3>constraints</h3>
</ul>
</aside>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="groupid" class="tsd-anchor"></a>
<h3>group<wbr>Id</h3>
<div class="tsd-signature tsd-kind-icon">group<wbr>Id<span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol"> = &quot;&quot;</span></div>
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/master/src/devicecontroller/DeviceSelection.ts#L7">src/devicecontroller/DeviceSelection.ts:7</a></li>
</ul>
</aside>
</section>
<section class="tsd-panel tsd-member tsd-kind-property tsd-parent-kind-class">
<a name="stream" class="tsd-anchor"></a>
<h3>stream</h3>
Expand All @@ -129,7 +140,7 @@ <h3>matches<wbr>Constraints</h3>
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/master/src/devicecontroller/DeviceSelection.ts#L8">src/devicecontroller/DeviceSelection.ts:8</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/master/src/devicecontroller/DeviceSelection.ts#L9">src/devicecontroller/DeviceSelection.ts:9</a></li>
</ul>
</aside>
<h4 class="tsd-parameters-title">Parameters</h4>
Expand Down Expand Up @@ -162,6 +173,9 @@ <h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">boolean</
<li class=" tsd-kind-property tsd-parent-kind-class">
<a href="deviceselection.html#constraints" class="tsd-kind-icon">constraints</a>
</li>
<li class=" tsd-kind-property tsd-parent-kind-class">
<a href="deviceselection.html#groupid" class="tsd-kind-icon">group<wbr>Id</a>
</li>
<li class=" tsd-kind-property tsd-parent-kind-class">
<a href="deviceselection.html#stream" class="tsd-kind-icon">stream</a>
</li>
Expand Down
28 changes: 7 additions & 21 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "amazon-chime-sdk-js",
"version": "1.10.7",
"version": "1.10.8",
"description": "Amazon Chime SDK for JavaScript",
"main": "build/index.js",
"types": "build/index.d.ts",
Expand All @@ -25,7 +25,7 @@
"doc": "node node_modules/typedoc/bin/typedoc --options typedoc.json",
"postdoc": "node script/update-typedoc-link.js",
"test": "npm run test:fast",
"test:fast": "cross-env TS_NODE_CACHE=false nyc mocha -rv ts-node/register \"test/**/*.test.ts\"",
"test:fast": "cross-env TS_NODE_CACHE=false nyc mocha -rv ts-node/register \"test/devicecontroller/DefaultDeviceController.test.ts\"",
"test:slow": "cross-env MOCHA_TEST_DELAY_MS=100 npm run test:fast",
"test:retry": "(npm run test:fast || npm run test:fast || npm run test:fast || npm run test:fast || npm run test:fast)",
"test:integration": "cd ./integration/js && npm run test && npm run upload-logs-to-s3",
Expand Down
85 changes: 78 additions & 7 deletions src/devicecontroller/DefaultDeviceController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import AudioVideoController from '../audiovideocontroller/AudioVideoController';
import DefaultBrowserBehavior from '../browserbehavior/DefaultBrowserBehavior';
import DeviceChangeObserver from '../devicechangeobserver/DeviceChangeObserver';
import Logger from '../logger/Logger';
import Maybe from '../maybe/Maybe';
Expand All @@ -13,6 +14,7 @@ import DefaultVideoTile from '../videotile/DefaultVideoTile';
import Device from './Device';
import DevicePermission from './DevicePermission';
import DeviceSelection from './DeviceSelection';
import BrowserBehavior from "../browserbehavior/BrowserBehavior";

export default class DefaultDeviceController implements DeviceControllerBasedMediaStreamBroker {
private static permissionGrantedOriginDetectionThresholdMs = 1000;
Expand All @@ -24,6 +26,7 @@ export default class DefaultDeviceController implements DeviceControllerBasedMed
private static defaultSampleRate = 48000;
private static defaultSampleSize = 16;
private static defaultChannelCount = 1;
private browserBehavior: BrowserBehavior = new DefaultBrowserBehavior();
private deviceInfoCache: MediaDeviceInfo[] | null = null;
private activeDevices: { [kind: string]: DeviceSelection | null } = { audio: null, video: null };
private audioOutputDeviceId: string | null = null;
Expand All @@ -42,7 +45,6 @@ export default class DefaultDeviceController implements DeviceControllerBasedMed
private videoMaxBandwidthKbps: number = DefaultDeviceController.defaultVideoMaxBandwidthKbps;

private useWebAudio: boolean = false;

private isAndroid: boolean = false;
private isPixel3: boolean = false;

Expand Down Expand Up @@ -482,6 +484,66 @@ export default class DefaultDeviceController implements DeviceControllerBasedMed
return device && device.id ? device : null;
}

private hasSameGroupId(groupId: string, kind: string, device: Device): boolean {
device = this.getDeviceIdStr(device);
if (groupId === this.getGroupIdFromDeviceId(kind, device) || groupId === '') {
return true;
}
return false;
}

private getGroupIdFromDeviceId(kind: string, device: string): string {
if (this.deviceInfoCache !== null) {
const cachedDeviceInfo = this.listCachedDevicesOfKind(`${kind}input`).find(
(cachedDevice: MediaDeviceInfo) => cachedDevice.deviceId === device
);
if (cachedDeviceInfo && cachedDeviceInfo.groupId) {
return cachedDeviceInfo.groupId;
}
}
return '';
}

private getDeviceIdStr(device: Device): string | null {
if (typeof device === 'string') {
return device;
}
if (device === null) {
return null;
}
const deviceMediaTrackConstraints = device as MediaTrackConstraints;
if ((device as MediaStream).id) {
return (device as MediaStream).id;
} else if (deviceMediaTrackConstraints.deviceId) {
/* istanbul ignore else */
if ((deviceMediaTrackConstraints.deviceId as ConstrainDOMStringParameters).exact) {
/* istanbul ignore else */
if (
(deviceMediaTrackConstraints.deviceId as ConstrainDOMStringParameters).exact as string
) {
return (deviceMediaTrackConstraints.deviceId as ConstrainDOMStringParameters)
.exact as string;
}
}
}
return '';
}

private getActiveDeviceId(kind: string): string | null {
if (this.activeDevices[kind] && this.activeDevices[kind].constraints) {
const activeDeviceMediaTrackConstraints =
this.activeDevices[kind].constraints.audio || this.activeDevices[kind].constraints.video;
const activeDeviceConstrainDOMStringParameters = (activeDeviceMediaTrackConstraints as MediaTrackConstraints)
.deviceId;
const activeDeviceId = (activeDeviceConstrainDOMStringParameters as ConstrainDOMStringParameters)
.exact;
/* istanbul ignore else */
if (activeDeviceId as string)
return activeDeviceId as string;
}
return null;
}

private async chooseInputDevice(
kind: string,
device: Device,
Expand All @@ -503,15 +565,17 @@ export default class DefaultDeviceController implements DeviceControllerBasedMed
kind,
device
);

if (
this.activeDevices[kind] &&
this.activeDevices[kind].matchesConstraints(proposedConstraints) &&
this.activeDevices[kind].stream.active
this.activeDevices[kind].stream.active &&
this.activeDevices[kind].groupId !== null &&
this.hasSameGroupId(this.activeDevices[kind].groupId, kind, device)
) {
this.logger.info(`reusing existing ${kind} device`);
return DevicePermission.PermissionGrantedPreviously;
}

const startTimeMs = Date.now();
const newDevice: DeviceSelection = new DeviceSelection();
try {
Expand All @@ -527,9 +591,15 @@ export default class DefaultDeviceController implements DeviceControllerBasedMed
newDevice.stream = stream;
newDevice.constraints = proposedConstraints;
} else {
if (
this.browserBehavior.hasChromiumWebRTC() &&
this.getDeviceIdStr(device) === this.getActiveDeviceId(kind) &&
this.getDeviceIdStr(device) === 'default'
) {
this.releaseMediaStream(this.activeDevices[kind].stream);
}
newDevice.stream = await navigator.mediaDevices.getUserMedia(proposedConstraints);
newDevice.constraints = proposedConstraints;

if (kind === 'video' && this.lastNoVideoInputDeviceCount > callCount) {
this.logger.warn(
`ignored to get video device for constraints ${JSON.stringify(
Expand Down Expand Up @@ -557,14 +627,15 @@ export default class DefaultDeviceController implements DeviceControllerBasedMed
}
});
}
newDevice.groupId = this.getGroupIdFromDeviceId(kind, this.getDeviceIdStr(device));
} catch (error) {
this.logger.error(
`failed to get ${kind} device for constraints ${JSON.stringify(proposedConstraints)}: ${
error.message
}`
);
return Date.now() - startTimeMs <
DefaultDeviceController.permissionDeniedOriginDetectionThresholdMs
DefaultDeviceController.permissionDeniedOriginDetectionThresholdMs
? DevicePermission.PermissionDeniedByBrowser
: DevicePermission.PermissionDeniedByUser;
}
Expand Down Expand Up @@ -610,7 +681,7 @@ export default class DefaultDeviceController implements DeviceControllerBasedMed
}
}
return Date.now() - startTimeMs <
DefaultDeviceController.permissionGrantedOriginDetectionThresholdMs
DefaultDeviceController.permissionGrantedOriginDetectionThresholdMs
? DevicePermission.PermissionGrantedByBrowser
: DevicePermission.PermissionGrantedByUser;
}
Expand Down Expand Up @@ -786,4 +857,4 @@ export default class DefaultDeviceController implements DeviceControllerBasedMed
}
this.logger.info(s);
}
}
}
3 changes: 2 additions & 1 deletion src/devicecontroller/DeviceSelection.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Copyright 2019-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

export default class DeviceSelection {
constraints: MediaStreamConstraints;
stream: MediaStream;
groupId: string = '';

matchesConstraints(constraints: MediaStreamConstraints): boolean {
return JSON.stringify(this.constraints) === JSON.stringify(constraints);
Expand Down
2 changes: 1 addition & 1 deletion src/versioning/Versioning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class Versioning {
* Return string representation of SDK version
*/
static get sdkVersion(): string {
return '1.10.7';
return '1.10.8';
}

/**
Expand Down
Loading

0 comments on commit e9a94ed

Please sign in to comment.